STR #1007: Applied second patch by hand. OP: could you please check if all changes were made correctly? Thanks!
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@4563 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
55380298b5
commit
2b6586f64d
1
CHANGES
1
CHANGES
@ -3,6 +3,7 @@ CHANGES IN FLTK 1.1.7
|
||||
- Documentation fixes (STR #571, STR #648, STR #692, STR
|
||||
#730, STR #744, STR #745, STR #931, STR #942, STR #960,
|
||||
STR #969)
|
||||
- Fixed handling of Win32 Device Contexts (STR #1007)
|
||||
- Fixed C Plus Plus style comments in C files (STR #997)
|
||||
- Fixed signednes of scanf argument (STR #996)
|
||||
- Fixed cross-compiling (host: *-linux-* , target: *-mingw32)
|
||||
|
||||
10
FL/win32.H
10
FL/win32.H
@ -70,6 +70,7 @@ inline void XClipBox(Fl_Region r,XRectangle* rect) {
|
||||
// Warning: this object is highly subject to change!
|
||||
class FL_EXPORT Fl_X {
|
||||
public:
|
||||
// member variables - add new variables only at the end of this block
|
||||
Window xid;
|
||||
HBITMAP other_xid; // for double-buffered windows
|
||||
Fl_Window* w;
|
||||
@ -78,6 +79,8 @@ public:
|
||||
int wait_for_expose;
|
||||
HDC private_dc; // used for OpenGL
|
||||
HCURSOR cursor;
|
||||
HDC saved_hdc; // saves the handle of the DC currently loaded
|
||||
// static variables, static functions and member functions
|
||||
static Fl_X* first;
|
||||
static Fl_X* i(const Fl_Window* w) {return w->i;}
|
||||
static int fake_X_wm(const Fl_Window* w,int &X, int &Y,
|
||||
@ -104,6 +107,7 @@ extern FL_EXPORT struct Fl_XMap {
|
||||
inline COLORREF fl_RGB() {return fl_current_xmap->rgb;}
|
||||
inline HPEN fl_pen() {return fl_current_xmap->pen;}
|
||||
FL_EXPORT HBRUSH fl_brush(); // allocates a brush if necessary
|
||||
FL_EXPORT HBRUSH fl_brush_action(int); // now does the real work
|
||||
|
||||
extern FL_EXPORT HINSTANCE fl_display;
|
||||
extern FL_EXPORT Window fl_window;
|
||||
@ -111,6 +115,8 @@ extern FL_EXPORT HDC fl_gc;
|
||||
extern FL_EXPORT HPALETTE fl_palette; // non-zero only on 8-bit displays!
|
||||
extern FL_EXPORT HDC fl_GetDC(Window);
|
||||
extern FL_EXPORT MSG fl_msg;
|
||||
extern FL_EXPORT void fl_release_dc(HWND w, HDC dc);
|
||||
extern FL_EXPORT void fl_save_dc( HWND w, HDC dc);
|
||||
|
||||
// off-screen pixmaps: create, destroy, draw into, copy to window
|
||||
typedef HBITMAP Fl_Offscreen;
|
||||
@ -119,10 +125,10 @@ typedef HBITMAP Fl_Offscreen;
|
||||
extern FL_EXPORT HDC fl_makeDC(HBITMAP);
|
||||
#define fl_begin_offscreen(b) \
|
||||
HDC _sgc=fl_gc; Window _sw=fl_window; \
|
||||
fl_gc=fl_makeDC(b); fl_window=(HWND)b; fl_push_no_clip()
|
||||
fl_gc=fl_makeDC(b); int _savedc = SaveDC(fl_gc); fl_window=(HWND)b; fl_push_no_clip()
|
||||
|
||||
#define fl_end_offscreen() \
|
||||
fl_pop_clip(); DeleteDC(fl_gc); fl_window=_sw; fl_gc = _sgc
|
||||
fl_pop_clip(); RestoreDC(fl_gc, _savedc); DeleteDC(fl_gc); fl_window=_sw; fl_gc = _sgc
|
||||
|
||||
FL_EXPORT void fl_copy_offscreen(int x,int y,int w,int h,HBITMAP pixmap,int srcx,int srcy);
|
||||
#define fl_delete_offscreen(bitmap) DeleteObject(bitmap);
|
||||
|
||||
24
src/Fl.cxx
24
src/Fl.cxx
@ -42,6 +42,14 @@
|
||||
# include <stdio.h>
|
||||
#endif // DEBUG
|
||||
|
||||
#ifdef WIN32
|
||||
# include <ole2.h>
|
||||
void fl_free_fonts(void);
|
||||
HBRUSH fl_brush_action(int action);
|
||||
void fl_cleanup_pens(void);
|
||||
void fl_release_dc(HWND,HDC);
|
||||
void fl_cleanup_dc_list(void);
|
||||
#endif // WIN32
|
||||
|
||||
//
|
||||
// Globals...
|
||||
@ -298,6 +306,13 @@ double Fl::wait(double time_to_wait) {
|
||||
|
||||
int Fl::run() {
|
||||
while (Fl_X::first) wait(FOREVER);
|
||||
#ifdef WIN32
|
||||
fl_free_fonts(); // do some WIN32 cleanup
|
||||
fl_cleanup_pens();
|
||||
OleUninitialize();
|
||||
fl_brush_action(1);
|
||||
fl_cleanup_dc_list();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -836,9 +851,9 @@ void Fl_Window::hide() {
|
||||
#ifdef WIN32
|
||||
// Send a message to myself so that I'll get out of the event loop...
|
||||
PostMessage(ip->xid, WM_APP, 0, 0);
|
||||
if (ip->private_dc) ReleaseDC(ip->xid,ip->private_dc);
|
||||
if (ip->xid == fl_window && fl_gc) {
|
||||
ReleaseDC(fl_window, fl_gc);
|
||||
if (ip->private_dc) fl_release_dc(ip->xid, ip->private_dc);
|
||||
if (ip->xid == fl_window && fl_gc) {
|
||||
fl_release_dc(fl_window, fl_gc);
|
||||
fl_window = (HWND)-1;
|
||||
fl_gc = 0;
|
||||
}
|
||||
@ -871,6 +886,9 @@ void Fl_Window::hide() {
|
||||
# if USE_XFT
|
||||
fl_destroy_xft_draw(ip->xid);
|
||||
# endif
|
||||
#ifdef WIN32
|
||||
fl_release_dc(ip->xid, fl_gc);
|
||||
#endif
|
||||
XDestroyWindow(fl_display, ip->xid);
|
||||
#endif
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// but WITHOUT ANY WARRANTY; without even 79the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
@ -372,10 +372,12 @@ void Fl_Bitmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
if (!id) id = fl_create_bitmap(w(), h(), array);
|
||||
|
||||
HDC tempdc = CreateCompatibleDC(fl_gc);
|
||||
int save = SaveDC(tempdc);
|
||||
SelectObject(tempdc, (HGDIOBJ)id);
|
||||
SelectObject(fl_gc, fl_brush());
|
||||
// secret bitblt code found in old MSWindows reference manual:
|
||||
BitBlt(fl_gc, X, Y, W, H, tempdc, cx, cy, 0xE20746L);
|
||||
RestoreDC(tempdc, save);
|
||||
DeleteDC(tempdc);
|
||||
#elif defined(__APPLE_QD__)
|
||||
if (!id) id = fl_create_bitmask(w(), h(), array);
|
||||
|
||||
@ -89,8 +89,10 @@ HDC fl_makeDC(HBITMAP bitmap) {
|
||||
|
||||
void fl_copy_offscreen(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) {
|
||||
HDC new_gc = CreateCompatibleDC(fl_gc);
|
||||
int save = SaveDC(new_gc);
|
||||
SelectObject(new_gc, bitmap);
|
||||
BitBlt(fl_gc, x, y, w, h, new_gc, srcx, srcy, SRCCOPY);
|
||||
RestoreDC(new_gc, save);
|
||||
DeleteDC(new_gc);
|
||||
}
|
||||
|
||||
@ -303,8 +305,10 @@ void Fl_Double_Window::flush(int eraseoverlay) {
|
||||
#ifdef WIN32
|
||||
HDC _sgc = fl_gc;
|
||||
fl_gc = fl_makeDC(myi->other_xid);
|
||||
int save = SaveDC(fl_gc);
|
||||
fl_restore_clip(); // duplicate region into new gc
|
||||
draw();
|
||||
RestoreDC(fl_gc, save);
|
||||
DeleteDC(fl_gc);
|
||||
fl_gc = _sgc;
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
@ -39,6 +39,10 @@
|
||||
# include <FL/Fl_Window.H>
|
||||
# endif
|
||||
|
||||
# ifdef WIN32
|
||||
void fl_save_dc(HWND, HDC);
|
||||
# endif
|
||||
|
||||
static Fl_Gl_Choice *first;
|
||||
|
||||
// this assummes one of the two arguments is zero:
|
||||
@ -311,6 +315,7 @@ GLContext fl_create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int lay
|
||||
HDC hdc = i->private_dc;
|
||||
if (!hdc) {
|
||||
hdc = i->private_dc = GetDCEx(i->xid, 0, DCX_CACHE);
|
||||
fl_save_dc(i->xid, hdc);
|
||||
SetPixelFormat(hdc, g->pixelformat, (PIXELFORMATDESCRIPTOR*)(&g->pfd));
|
||||
# if USE_COLORMAP
|
||||
if (fl_palette) SelectPalette(hdc, fl_palette, FALSE);
|
||||
|
||||
@ -33,6 +33,9 @@
|
||||
#include <FL/Fl_Image.H>
|
||||
#include "flstring.h"
|
||||
|
||||
#ifdef WIN32
|
||||
void fl_release_dc(HWND, HDC); // from Fl_win32.cxx
|
||||
#endif
|
||||
|
||||
void fl_restore_clip(); // from fl_rect.cxx
|
||||
|
||||
@ -347,10 +350,12 @@ void Fl_RGB_Image::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
#ifdef WIN32
|
||||
if (mask) {
|
||||
HDC new_gc = CreateCompatibleDC(fl_gc);
|
||||
int save = SaveDC(new_gc);
|
||||
SelectObject(new_gc, (void*)mask);
|
||||
BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCAND);
|
||||
SelectObject(new_gc, (void*)id);
|
||||
BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCPAINT);
|
||||
RestoreDC(new_gc,save);
|
||||
DeleteDC(new_gc);
|
||||
} else {
|
||||
fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy);
|
||||
|
||||
@ -319,6 +319,7 @@ menuwindow::menuwindow(const Fl_Menu_Item* m, int X, int Y, int Wp, int Hp,
|
||||
}
|
||||
|
||||
menuwindow::~menuwindow() {
|
||||
hide();
|
||||
delete title;
|
||||
}
|
||||
|
||||
|
||||
@ -43,6 +43,10 @@
|
||||
#include "flstring.h"
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef WIN32
|
||||
extern void fl_release_dc(HWND, HDC); // located in Fl_win32.cxx
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE_QUARTZ__
|
||||
extern Fl_Offscreen fl_create_offscreen_with_alpha(int w, int h);
|
||||
#endif
|
||||
@ -108,10 +112,12 @@ void Fl_Pixmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
#ifdef WIN32
|
||||
if (mask) {
|
||||
HDC new_gc = CreateCompatibleDC(fl_gc);
|
||||
int save = SaveDC(new_gc);
|
||||
SelectObject(new_gc, (void*)mask);
|
||||
BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCAND);
|
||||
SelectObject(new_gc, (void*)id);
|
||||
BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCPAINT);
|
||||
RestoreDC(new_gc,save);
|
||||
DeleteDC(new_gc);
|
||||
} else {
|
||||
fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy);
|
||||
|
||||
153
src/Fl_win32.cxx
153
src/Fl_win32.cxx
@ -34,6 +34,7 @@
|
||||
#include <FL/Fl_Window.H>
|
||||
#include <FL/Enumerations.H>
|
||||
#include "flstring.h"
|
||||
#include "Fl_Font.H"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
@ -1101,6 +1102,7 @@ char fl_show_iconic; // hack for Fl_Window::iconic()
|
||||
HCURSOR fl_default_cursor;
|
||||
UINT fl_wake_msg = 0;
|
||||
int fl_disable_transient_for; // secret method of removing TRANSIENT_FOR
|
||||
WNDCLASSEX wc;
|
||||
|
||||
Fl_X* Fl_X::make(Fl_Window* w) {
|
||||
Fl_Group::current(0); // get rid of very common user bug: forgot end()
|
||||
@ -1115,26 +1117,38 @@ Fl_X* Fl_X::make(Fl_Window* w) {
|
||||
|
||||
const char* message_name = "FLTK::ThreadWakeup";
|
||||
|
||||
WNDCLASSEX wc;
|
||||
// Documentation states a device context consumes about 800 bytes
|
||||
// of memory... so who cares? If 800 bytes per window is what it
|
||||
// takes to speed things up, I'm game.
|
||||
//wc.style = CS_HREDRAW | CS_VREDRAW | CS_CLASSDC | CS_DBLCLKS;
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
|
||||
wc.lpfnWndProc = (WNDPROC)WndProc;
|
||||
wc.cbClsExtra = wc.cbWndExtra = 0;
|
||||
wc.hInstance = fl_display;
|
||||
if (!w->icon())
|
||||
w->icon((void *)LoadIcon(NULL, IDI_APPLICATION));
|
||||
wc.hIcon = wc.hIconSm = (HICON)w->icon();
|
||||
wc.hCursor = fl_default_cursor = LoadCursor(NULL, IDC_ARROW);
|
||||
//uchar r,g,b; Fl::get_color(FL_GRAY,r,g,b);
|
||||
//wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(r,g,b));
|
||||
wc.hbrBackground = NULL;
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = class_name;
|
||||
wc.cbSize = sizeof(WNDCLASSEX);
|
||||
RegisterClassEx(&wc);
|
||||
// Register the first (or default FLTK) class only once.
|
||||
// If the user creates mutiple new windows using other class names, they will
|
||||
// be registered multiple times. This is not correct and should be fixed by
|
||||
// keeping a list of registered window classes. Anyway, Windows is
|
||||
// quite forgiving here,
|
||||
static int first_time = 1;
|
||||
if (first_time || strcmp(class_name, first_class_name)) {
|
||||
WNDCLASSEX lwc;
|
||||
// Documentation states a device context consumes about 800 bytes
|
||||
// of memory... so who cares? If 800 bytes per window is what it
|
||||
// takes to speed things up, I'm game.
|
||||
//wc.style = CS_HREDRAW | CS_VREDRAW | CS_CLASSDC | CS_DBLCLKS;
|
||||
lwc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
|
||||
lwc.lpfnWndProc = (WNDPROC)WndProc;
|
||||
lwc.cbClsExtra = wc.cbWndExtra = 0;
|
||||
lwc.hInstance = fl_display;
|
||||
if (!w->icon())
|
||||
w->icon((void *)LoadIcon(NULL, IDI_APPLICATION));
|
||||
lwc.hIcon = lwc.hIconSm = (HICON)w->icon();
|
||||
lwc.hCursor = fl_default_cursor = LoadCursor(NULL, IDC_ARROW);
|
||||
//uchar r,g,b; Fl::get_color(FL_GRAY,r,g,b);
|
||||
//wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(r,g,b));
|
||||
lwc.hbrBackground = NULL;
|
||||
lwc.lpszMenuName = NULL;
|
||||
lwc.lpszClassName = class_name;
|
||||
lwc.cbSize = sizeof(WNDCLASSEX);
|
||||
RegisterClassEx(&lwc);
|
||||
if (first_time) {
|
||||
memcpy(&wc, &lwc, lwc.cbSize);
|
||||
first_time = 0;
|
||||
}
|
||||
}
|
||||
if (!fl_wake_msg) fl_wake_msg = RegisterWindowMessage(message_name);
|
||||
|
||||
HWND parent;
|
||||
@ -1346,9 +1360,10 @@ HWND fl_window = NULL;
|
||||
HDC fl_GetDC(HWND w) {
|
||||
if (fl_gc) {
|
||||
if (w == fl_window && fl_window != NULL) return fl_gc;
|
||||
ReleaseDC(fl_window, fl_gc);
|
||||
if (fl_window) fl_release_dc(fl_window, fl_gc); // ReleaseDC
|
||||
}
|
||||
fl_gc = GetDC(w);
|
||||
fl_save_dc(w, fl_gc);
|
||||
fl_window = w;
|
||||
// calling GetDC seems to always reset these: (?)
|
||||
SetTextAlign(fl_gc, TA_BASELINE|TA_LEFT);
|
||||
@ -1373,6 +1388,102 @@ void Fl_Window::make_current() {
|
||||
fl_clip_region(0);
|
||||
}
|
||||
|
||||
/* Make sure that all allocated fonts are released. This works only if
|
||||
Fl::run() is allowed to exit by closing all windows. Calling 'exit(int)'
|
||||
will not automatically free any fonts. */
|
||||
void fl_free_fonts(void)
|
||||
{
|
||||
// remove the Fl_FontSize chains
|
||||
int i;
|
||||
Fl_Fontdesc * s;
|
||||
Fl_FontSize * f;
|
||||
Fl_FontSize * ff;
|
||||
for (i=0; i<FL_FREE_FONT; i++) {
|
||||
s = fl_fonts + i;
|
||||
for (f=s->first; f; f=ff) {
|
||||
ff = f->next;
|
||||
delete(f);
|
||||
s->first = ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The following routines help fix a problem with the leaking of Windows
|
||||
// Device Context (DC) objects. The 'proper' protocol is for a program to
|
||||
// acquire a DC, save its state, do the modifications needed for drawing,
|
||||
// perform the drawing, restore the initial state, and release the DC. In
|
||||
// FLTK, the save and restore steps have previously been omitted and DCs are
|
||||
// not properly released, leading to a great number of DC leaks. As some
|
||||
// Windows "OSs" will hang when any process exceeds roughly 10,000 GDI objects,
|
||||
// it is important to control GDI leaks, which are much more important than memory
|
||||
// leaks. The following struct, global variable, and routines help implement
|
||||
// the above protocol for those cases where the GetDC and RestoreDC are not in
|
||||
// the same routine. For each GetDC, fl_save_dc is used to create an entry in
|
||||
// a linked list that saves the window handle, the DC handle, and the initial
|
||||
// state. When the DC is to be released, 'fl_release_dc' is called. It restores
|
||||
// the initial state and releases the DC. When the program exits, 'fl_cleanup_dc_list'
|
||||
// frees any remaining nodes in the list.
|
||||
|
||||
struct Win_DC_List { // linked list
|
||||
HWND window; // window handle
|
||||
HDC dc; // device context handle
|
||||
int saved_dc; // initial state of DC
|
||||
Win_DC_List * next; // pointer to next item
|
||||
};
|
||||
|
||||
static Win_DC_List * win_DC_list = 0;
|
||||
|
||||
void fl_save_dc( HWND w, HDC dc) {
|
||||
Win_DC_List * t;
|
||||
t = new Win_DC_List;
|
||||
t->window = w;
|
||||
t->dc = dc;
|
||||
t->saved_dc = SaveDC(dc);
|
||||
if (win_DC_list)
|
||||
t->next = win_DC_list;
|
||||
else
|
||||
t->next = NULL;
|
||||
win_DC_list = t;
|
||||
}
|
||||
|
||||
void fl_release_dc(HWND w, HDC dc) {
|
||||
Win_DC_List * t= win_DC_list;
|
||||
Win_DC_List * prev = 0;
|
||||
if (!t)
|
||||
return;
|
||||
do {
|
||||
if (t->dc == dc) {
|
||||
RestoreDC(dc, t->saved_dc);
|
||||
ReleaseDC(w, dc);
|
||||
if (!prev) {
|
||||
win_DC_list = t->next; // delete first item
|
||||
} else {
|
||||
prev->next = t->next; // one in the middle
|
||||
}
|
||||
delete (t);
|
||||
return;
|
||||
}
|
||||
prev = t;
|
||||
t = t->next;
|
||||
} while (t);
|
||||
}
|
||||
|
||||
void fl_cleanup_dc_list(void) { // clean up the list
|
||||
Win_DC_List * t = win_DC_list;
|
||||
if (!t)return;
|
||||
do {
|
||||
RestoreDC(t->dc, t->saved_dc);
|
||||
ReleaseDC(t->window, t->dc);
|
||||
win_DC_list = t->next;
|
||||
delete (t);
|
||||
t = win_DC_list;
|
||||
} while(t);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
//
|
||||
|
||||
@ -49,10 +49,15 @@ Fl_XMap fl_xmap[256];
|
||||
Fl_XMap* fl_current_xmap;
|
||||
|
||||
HPALETTE fl_palette;
|
||||
static HPEN tmppen=0;
|
||||
static HBRUSH tmpbrush=0;
|
||||
static HGDIOBJ tmppen=0;
|
||||
static HPEN savepen=0;
|
||||
|
||||
void fl_cleanup_pens(void) {
|
||||
for (int i=0; i<256; i++) {
|
||||
if (fl_xmap[i].pen) DeleteObject(fl_xmap[i].pen);
|
||||
}
|
||||
}
|
||||
|
||||
void fl_save_pen(void) {
|
||||
if(!tmppen) tmppen = CreatePen(PS_SOLID, 1, 0);
|
||||
savepen = (HPEN)SelectObject(fl_gc, tmppen);
|
||||
@ -60,17 +65,16 @@ void fl_save_pen(void) {
|
||||
|
||||
void fl_restore_pen(void) {
|
||||
if (savepen) SelectObject(fl_gc, savepen);
|
||||
DeleteObject(tmppen);
|
||||
tmppen = 0;
|
||||
savepen = 0;
|
||||
}
|
||||
|
||||
static void clear_xmap(Fl_XMap& xmap) {
|
||||
if (xmap.pen) {
|
||||
if(!tmppen) tmppen = CreatePen(PS_SOLID, 1, 0);
|
||||
if(!tmpbrush) tmpbrush = CreateSolidBrush(0);
|
||||
HPEN oldpen = (HPEN)SelectObject(fl_gc, tmppen); // Push out the current pen of the gc
|
||||
HGDIOBJ tmppen = GetStockObject(BLACK_PEN);
|
||||
HGDIOBJ oldpen = SelectObject(fl_gc, tmppen); // Push out the current pen of the gc
|
||||
if(oldpen != xmap.pen) SelectObject(fl_gc, oldpen); // Put it back if it is not the one we are about to delete
|
||||
SelectObject(fl_gc, tmpbrush); // Push out the old pen of the gc
|
||||
//fl_current_xmap = 0;
|
||||
DeleteObject((HGDIOBJ)(xmap.pen));
|
||||
xmap.pen = 0;
|
||||
xmap.brush = -1;
|
||||
@ -79,7 +83,12 @@ static void clear_xmap(Fl_XMap& xmap) {
|
||||
|
||||
static void set_xmap(Fl_XMap& xmap, COLORREF c) {
|
||||
xmap.rgb = c;
|
||||
xmap.pen = CreatePen(PS_SOLID, 1, xmap.rgb);
|
||||
if (xmap.pen) {
|
||||
HGDIOBJ oldpen = SelectObject(fl_gc,GetStockObject(BLACK_PEN)); // replace current pen with safe one
|
||||
if (oldpen != xmap.pen)SelectObject(fl_gc,oldpen); // if old one not xmap.pen, need to put it back
|
||||
DeleteObject(xmap.pen); // delete pen
|
||||
}
|
||||
xmap.pen = CreatePen(PS_SOLID, 1, xmap.rgb); // get a pen into xmap.pen
|
||||
xmap.brush = -1;
|
||||
}
|
||||
|
||||
@ -122,6 +131,10 @@ void fl_color(uchar r, uchar g, uchar b) {
|
||||
}
|
||||
|
||||
HBRUSH fl_brush() {
|
||||
return fl_brush_action(0);
|
||||
}
|
||||
|
||||
HBRUSH fl_brush_action(int action) {
|
||||
Fl_XMap *xmap = fl_current_xmap;
|
||||
// Wonko: we use some statistics to cache only a limited number
|
||||
// of brushes:
|
||||
@ -132,6 +145,15 @@ HBRUSH fl_brush() {
|
||||
Fl_XMap* backref;
|
||||
} brushes[FL_N_BRUSH];
|
||||
|
||||
if (action) {
|
||||
SelectObject(fl_gc, GetStockObject(BLACK_BRUSH)); // Load stock object
|
||||
for (int i=0; i<FL_N_BRUSH; i++) {
|
||||
if (brushes[i].brush)
|
||||
DeleteObject(brushes[i].brush); // delete all brushes in array
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int i = xmap->brush; // find the associated brush
|
||||
if (i != -1) { // if the brush was allready allocated
|
||||
if (brushes[i].brush == NULL) goto CREATE_BRUSH;
|
||||
@ -154,7 +176,10 @@ HBRUSH fl_brush() {
|
||||
}
|
||||
}
|
||||
i = imin;
|
||||
DeleteObject(brushes[i].brush);
|
||||
HGDIOBJ tmpbrush = GetStockObject(BLACK_BRUSH); // get a stock brush
|
||||
HGDIOBJ oldbrush = SelectObject(fl_gc,tmpbrush); // load in into current context
|
||||
if (oldbrush != brushes[i].brush) SelectObject(fl_gc,oldbrush); // reload old one
|
||||
DeleteObject(brushes[i].brush); // delete the one in list
|
||||
brushes[i].brush = NULL;
|
||||
brushes[i].backref->brush = -1;
|
||||
}
|
||||
|
||||
@ -69,6 +69,7 @@ void fl_line_style(int style, int width, char* dashes) {
|
||||
}
|
||||
HPEN oldpen = (HPEN)SelectObject(fl_gc, newpen);
|
||||
DeleteObject(oldpen);
|
||||
DeleteObject(fl_current_xmap->pen);
|
||||
fl_current_xmap->pen = newpen;
|
||||
#elif defined(__APPLE_QD__)
|
||||
// QuickDraw supports pen size and pattern, but no arbitrary line styles.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user