Commited WIN32 patches from Bill Spitzak and Gustavo Hime.

git-svn-id: file:///fltk/svn/fltk/trunk@11 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Michael R Sweet 1998-10-15 14:06:16 +00:00
parent 8b880adac6
commit 45bb73a9bf
20 changed files with 253 additions and 280 deletions

View File

@ -6,8 +6,6 @@
#include "Fl_Window.H"
class Fl_Double_Window : public Fl_Window {
protected:
void _flush(int); // used by Fl_Overlay_Window
public:
void show();
void show(int a, char **b) {Fl_Window::show(a,b);}

View File

@ -74,7 +74,6 @@ public:
void fullscreen();
void fullscreen_off(int,int,int,int);
void iconize();
void expose(uchar flags,int X,int Y,int W,int H);
int x_root() const ;
int y_root() const ;

View File

@ -23,7 +23,13 @@ inline Region XRectangleRegion(int x, int y, int w, int h) {
return CreateRectRgn(x,y,x+w,y+h);
}
inline void XDestroyRegion(Region r) {DeleteObject(r);}
inline void XClipBox(Region r,XRectangle* rect) {
RECT win_rect; GetRgnBox(r,&win_rect);
rect->x=win_rect.left;
rect->y=win_rect.top;
rect->width=win_rect.right-win_rect.left;
rect->height=win_rect.bottom-win_rect.top;
}
#define XDestroyWindow(a,b) DestroyWindow(b)
#define XMapWindow(a,b) ShowWindow(b, SW_RESTORE)
#define XUnmapWindow(a,b) ShowWindow(b, SW_HIDE)
@ -67,7 +73,6 @@ HBRUSH fl_brush(); // allocates a brush if necessary
extern HINSTANCE fl_display;
extern Window fl_window;
extern HDC fl_gc;
extern HDC window_dc; // for double-buffered windows
extern HPALETTE fl_palette; // non-zero only on 8-bit displays!
extern HDC fl_GetDC(Window);
extern MSG fl_msg;
@ -75,15 +80,13 @@ extern MSG fl_msg;
// off-screen pixmaps: create, destroy, draw into, copy to window
#define Fl_Offscreen HBITMAP
#define fl_create_offscreen(w, h) CreateCompatibleBitmap(fl_gc, w, h)
extern void fl_switch_offscreen(HBITMAP);
inline void fl_begin_offscreen(HBITMAP b) {
window_dc = fl_gc; fl_switch_offscreen(b);
}
inline void fl_end_offscreen() {
fl_gc = window_dc;
}
void fl_make_current(HBITMAP bitmap);
extern HDC fl_makeDC(HBITMAP);
#define fl_begin_offscreen(b) \
HDC _sgc=fl_gc; Window _sw=fl_window; fl_gc=fl_makeDC(b); fl_window=b;
#define fl_end_offscreen() \
ReleaseDC(fl_window,fl_gc); fl_window=_sw; fl_gc = _sgc
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);

8
FL/x.H
View File

@ -48,8 +48,12 @@ extern ulong fl_event_time;
#define Fl_Offscreen ulong
#define fl_create_offscreen(w,h) \
XCreatePixmap(fl_display, fl_window, w, h, fl_visual->depth)
#define fl_begin_offscreen(pixmap) Window _sw=fl_window;fl_window=pixmap;fl_push_no_clip()
#define fl_end_offscreen() fl_pop_clip();fl_window = _sw
// begin/end are macros that save the old state in local variables:
#define fl_begin_offscreen(pixmap) \
Window _sw=fl_window; fl_window=pixmap; fl_push_no_clip()
#define fl_end_offscreen() \
fl_pop_clip(); fl_window = _sw
#define fl_copy_offscreen(x,y,w,h,pixmap,srcx,srcy) \
XCopyArea(fl_display, pixmap, fl_window, fl_gc, srcx, srcy, w, h, x, y)
#define fl_delete_offscreen(pixmap) XFreePixmap(fl_display, pixmap)

View File

@ -11,7 +11,10 @@
#include <FL/Fl_Menu_Item.H>
#include <FL/Fl_Bitmap.H>
void Fl_Bitmap::draw(int X, int Y, int W, int H, int cx,int cy) {
void Fl_Bitmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
// account for current clip region (faster on Irix):
int X,Y,W,H; fl_clip_box(XP,YP,WP,HP,X,Y,W,H);
cx += X-XP; cy += Y-YP;
// clip the box down to the size of image, quit if empty:
if (cx < 0) {W += cx; X -= cx; cx = 0;}
if (cx+W > w) W = w-cx;

View File

@ -36,6 +36,9 @@ static int can_xdbe() {
}
return use_xdbe;
}
#define DAMAGE_TEST() (damage() && (use_xdbe || damage() != 2))
#else
#define DAMAGE_TEST() (damage() & ~2)
#endif
void Fl_Double_Window::show() {
@ -51,33 +54,35 @@ void Fl_Double_Window::show() {
#ifdef WIN32
// I've removed the second one (never understool why
// it was there to begin with).
// Code used to switch output to an off-screen window. See macros in
// win32.H which save the old state in local variables.
static HDC blt_gc;
void fl_switch_offscreen(HBITMAP bitmap) {
if (!blt_gc) {
blt_gc = CreateCompatibleDC(fl_gc);
SetTextAlign(blt_gc, TA_BASELINE|TA_LEFT);
SetBkMode(blt_gc, TRANSPARENT);
HDC fl_makeDC(HBITMAP bitmap) {
HDC new_gc = CreateCompatibleDC(fl_gc);
SetTextAlign(new_gc, TA_BASELINE|TA_LEFT);
SetBkMode(new_gc, TRANSPARENT);
#if USE_COLORMAP
if (fl_palette) SelectPalette(blt_gc, fl_palette, FALSE);
if (fl_palette) SelectPalette(new_gc, fl_palette, FALSE);
#endif
}
SelectObject(blt_gc, bitmap);
fl_gc = blt_gc;
SelectObject(new_gc, bitmap);
return new_gc;
}
void fl_copy_offscreen(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) {
SelectObject(blt_gc, bitmap);
BitBlt(window_dc, x, y, w, h, blt_gc, srcx, srcy, SRCCOPY);
HDC new_gc = CreateCompatibleDC(fl_gc);
SelectObject(new_gc, bitmap);
BitBlt(fl_gc, x, y, w, h, new_gc, srcx, srcy, SRCCOPY);
ReleaseDC(bitmap, new_gc);
}
extern void fl_restore_clip();
#endif
// protected method used by Fl_Overlay_Window to fake overlay:
void Fl_Double_Window::_flush(int eraseoverlay) {
// Fl_Overlay_Window relies on flush() copying the back buffer to the
// front even if damage() == 0, thus erasing the overlay inside the region:
void Fl_Double_Window::flush() {
make_current(); // make sure fl_gc is non-zero
Fl_X *i = Fl_X::i(this);
if (!i->other_xid) {
@ -89,49 +94,46 @@ void Fl_Double_Window::_flush(int eraseoverlay) {
i->other_xid = fl_create_offscreen(w(), h());
clear_damage(~0);
}
XRectangle rect = {0,0,w(),h()};
if (damage()) {
if ( // don't draw if back buffer is ok
#if USE_XDBE
use_xdbe ||
#endif
damage() != 2) {
/*
#ifdef WIN32
fl_begin_offscreen(i->other_xid);
fl_clip_region(i->region); i->region = 0;
if (DAMAGE_TEST()) {
HDC _sgc = fl_gc;
fl_gc = fl_makeDC(i->other_xid);
fl_restore_clip(); // duplicate region into new gc
draw();
fl_end_offscreen();
#else
*/
#ifdef WIN32
fl_begin_offscreen(i->other_xid);
ReleaseDC(i->other_xid, fl_gc);
fl_gc = _sgc;
}
#else // X:
#if USE_XDBE
int clipped = i->region != 0;
#endif
fl_window = i->other_xid;
fl_clip_region(i->region); i->region = 0;
if (DAMAGE_TEST()) {
fl_window = i->other_xid;
draw();
fl_window = i->xid;
#ifdef WIN32
fl_end_offscreen();
#endif
//#endif
}
}
fl_clip_region(0);
#if USE_XDBE
if (i->region && !eraseoverlay) XClipBox(i->region, &rect);
if (use_xdbe) {
// It appears that swapbuffers ignores the clip region (it has to
// as the gc is not passed as an argument to it). This causes it
// to erase parts of the overlay that won't be redrawn, and (at least
// on XFree86) it is slower. So I don't use it unless the entire
// window is being redrawn. Sigh.
if (use_xdbe && !clipped) {
XdbeSwapInfo s;
s.swap_window = fl_xid(this);
s.swap_action = XdbeCopied;
XdbeSwapBuffers(fl_display, &s, 1);
} else
#endif
fl_copy_offscreen(rect.x, rect.y, rect.width, rect.height,
i->other_xid, rect.x, rect.y);
// fl_clip_region(0); older fix for clipping problem but overlay blinked
return;
}
#endif
#endif
// on Irix (at least) it is faster to reduce the area copied to
// the current clip region:
int X,Y,W,H; fl_clip_box(0,0,w(),h(),X,Y,W,H);
fl_copy_offscreen(X, Y, W, H, i->other_xid, X, Y);
}
void Fl_Double_Window::flush() {_flush(0);}
void Fl_Double_Window::resize(int X,int Y,int W,int H) {
int ow = w();

View File

@ -38,8 +38,6 @@
////////////////////////////////////////////////////////////////
HDC fl_GetDC(HWND);
int Fl_Gl_Window::can_do(int a, const int *b) {
#ifdef WIN32
Fl_Gl_Choice *g = Fl_Gl_Choice::find(a,b);
@ -99,10 +97,6 @@ int Fl_Gl_Window::mode(int m, const int *a) {
return 1;
}
#ifdef WIN32
extern char fl_direct_paint; // true when responding to WM_PAINT
#endif
void Fl_Gl_Window::make_current() {
#ifdef WIN32
HDC hdc = fl_private_dc(this, mode_,&g);

View File

@ -9,7 +9,10 @@
#include <FL/Fl_Menu_Item.H>
#include <FL/Fl_Image.H>
void Fl_Image::draw(int X, int Y, int W, int H, int cx,int cy) {
void Fl_Image::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
// account for current clip region (faster on Irix):
int X,Y,W,H; fl_clip_box(XP,YP,WP,HP,X,Y,W,H);
cx += X-XP; cy += Y-YP;
// clip the box down to the size of image, quit if empty:
if (cx < 0) {W += cx; X -= cx; cx = 0;}
if (cx+W > w) W = w-cx;

View File

@ -81,16 +81,20 @@ Fl_Menu_Window::~Fl_Menu_Window() {
// The system is also told to "grab" events and send them to this app.
extern void fl_fix_focus();
#ifdef WIN32
HWND fl_capture; // for some reason we must keep forcing it back on!
// We have to keep track of whether we have captured the mouse, since
// MSWindows shows little respect for this... Grep for fl_capture to
// see where and how this is used.
HWND fl_capture;
#endif
void Fl::grab(Fl_Window& w) {
grab_ = &w;
fl_fix_focus();
#ifdef WIN32
// this seems to have no effect...
SetCapture(fl_capture = fl_xid(first_window()));
SetActiveWindow(fl_capture = fl_xid(first_window()));
SetCapture(fl_capture);
#else
XGrabPointer(fl_display,
fl_xid(first_window()),

View File

@ -20,10 +20,13 @@ void Fl_Overlay_Window::hide() {
}
void Fl_Overlay_Window::flush() {
// a non-zero argument copies entire back buffer to window, erasing
// the overlay. We should only do this if fake overlay needs redraw:
uchar overlay_damage = damage()&8; clear_damage(damage()&~8);
_flush(overlay_damage);
// turn off the bit set by redraw_overlay:
clear_damage(damage()&~8);
// even if damage() == 0, flush() will erase the fake overlay by
// copying back buffer over it. It will also set the clip to the
// region made by all the expose events:
Fl_Double_Window::flush();
// Now draw the fake overlay, if any, using the current clip:
if (overlay_ == this) draw_overlay();
}

View File

@ -17,9 +17,13 @@
extern uchar **fl_mask_bitmap; // used by fl_draw_pixmap.C to store mask
void fl_restore_clip(); // in fl_rect.C
void Fl_Pixmap::draw(int X, int Y, int W, int H, int cx,int cy) {
void Fl_Pixmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
// ignore empty or bad pixmap data:
if (w<0) fl_measure_pixmap(data, w, h);
if (!w) return;
// account for current clip region (faster on Irix):
int X,Y,W,H; fl_clip_box(XP,YP,WP,HP,X,Y,W,H);
cx += X-XP; cy += Y-YP;
// clip the box down to the size of image, quit if empty:
if (cx < 0) {W += cx; X -= cx; cx = 0;}
if (cx+W > w) W = w-cx;

View File

@ -11,7 +11,7 @@ void Fl_Window::iconize() {
show();
} else {
#ifdef WIN32
ShowWindow(i->xid, SW_MINIMIZE);
ShowWindow(i->xid, SW_SHOWMINNOACTIVE);
#else
XIconifyWindow(fl_display, i->xid, fl_screen);
#endif

View File

@ -161,29 +161,29 @@ static int mouse_event(Fl_Window *window, int what, int button,
// convert a MSWindows VK_x to an Fltk (X) Keysym:
// See also the inverse converter in Fl_get_key_win32.C
// This table is in numeric order by VK:
static const struct {unsigned short vk, fltk;} vktab[] = {
static const struct {unsigned short vk, fltk, extended;} vktab[] = {
{VK_BACK, FL_BackSpace},
{VK_TAB, FL_Tab},
{VK_CLEAR, FL_KP+'5'},
{VK_RETURN, FL_Enter},
{VK_SHIFT, FL_Shift_L},
{VK_CONTROL, FL_Control_L},
{VK_MENU, FL_Alt_L},
{VK_RETURN, FL_Enter, FL_KP_Enter},
{VK_SHIFT, FL_Shift_L, FL_Shift_R},
{VK_CONTROL, FL_Control_L, FL_Control_R},
{VK_MENU, FL_Alt_L, FL_Alt_R},
{VK_PAUSE, FL_Pause},
{VK_CAPITAL, FL_Caps_Lock},
{VK_ESCAPE, FL_Escape},
{VK_SPACE, ' '},
{VK_PRIOR, FL_Page_Up},
{VK_NEXT, FL_Page_Down},
{VK_END, FL_End},
{VK_HOME, FL_Home},
{VK_LEFT, FL_Left},
{VK_UP, FL_Up},
{VK_RIGHT, FL_Right},
{VK_DOWN, FL_Down},
{VK_PRIOR, FL_KP+'9', FL_Page_Up},
{VK_NEXT, FL_KP+'3', FL_Page_Down},
{VK_END, FL_KP+'1', FL_End},
{VK_HOME, FL_KP+'7', FL_Home},
{VK_LEFT, FL_KP+'4', FL_Left},
{VK_UP, FL_KP+'8', FL_Up},
{VK_RIGHT, FL_KP+'6', FL_Right},
{VK_DOWN, FL_KP+'2', FL_Down},
{VK_SNAPSHOT, FL_Print}, // does not work on NT
{VK_INSERT, FL_Insert},
{VK_DELETE, FL_Delete},
{VK_INSERT, FL_KP+'0', FL_Insert},
{VK_DELETE, FL_KP+'.', FL_Delete},
{VK_LWIN, FL_Meta_L},
{VK_RWIN, FL_Meta_R},
{VK_APPS, FL_Menu},
@ -208,20 +208,19 @@ static const struct {unsigned short vk, fltk;} vktab[] = {
};
static int ms2fltk(int vk, int extended) {
static unsigned short vklut[256];
static unsigned short extendedlut[256];
if (!vklut[1]) { // init the table
unsigned int i;
for (i = 0; i < 256; i++) vklut[i] = tolower(i);
for (i=VK_F1; i<=VK_F16; i++) vklut[i] = i+(FL_F-(VK_F1-1));
for (i=VK_NUMPAD0; i<=VK_NUMPAD9; i++) vklut[i] = i+(FL_KP+'0'-VK_NUMPAD0);
for (i = 0; i < sizeof(vktab)/sizeof(*vktab); i++)
for (i = 0; i < sizeof(vktab)/sizeof(*vktab); i++) {
vklut[vktab[i].vk] = vktab[i].fltk;
extendedlut[vktab[i].vk] = vktab[i].extended;
}
if (extended) switch (vk) {
case VK_CONTROL : return FL_Control_R;
case VK_MENU: return FL_Alt_R;
case VK_RETURN: return FL_KP_Enter;
for (i = 0; i < 256; i++) if (!extendedlut[i]) extendedlut[i] = vklut[i];
}
return vklut[vk];
return extended ? extendedlut[vk] : vklut[vk];
}
#if USE_COLORMAP
@ -249,45 +248,29 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
return 0;
case WM_PAINT: {
// MSWindows has already set the clip region! Fltk does not like this,
// since it wants to draw it's own damage at the same time, and
// this damage may be outside the clip region. I kludge around
// this, grep for fl_direct_paint to find the kludges...
// if (!(window->damage())) fl_direct_paint = 1;
PAINTSTRUCT ps;
// I think MSWindows refuses to allocate two DCs for the same hWnd,
// so it may kludge the way the DCs are being handled. Works for now,
// the "final" solution can wait... Whatever the behaviour of the win32
// API, there is bound to be some small memory leak here.
// If anyone knows EXACTLY how DCs are allocated, please fix.
fl_window = hWnd;
fl_gc = BeginPaint(hWnd, &ps);
// A bug popped up because of the two following lines, which according to
// the original code's comments GetDC always resets. I just don't get
// why the problem hadn't manifested itself here earlier (well, probably
// because MSWindows was not allocating a new DC, but using the old one)
// Anyway, these followed the original GetDC calls, but for some reason
// were not here with the BeginPaint
SetTextAlign(fl_gc, TA_BASELINE|TA_LEFT);
SetBkMode(fl_gc, TRANSPARENT);
// This might be a better alternative, where we fully ignore NT's
// "facilities" for painting. MS expects applications to paint according
// to a very restrictive paradigm, and this is the way I found of
// working around it. In a sense, we are using WM_PAINT simply as an
// "exposure alert", like the X event.
window->expose(2, ps.rcPaint.left, ps.rcPaint.top,
ps.rcPaint.right-ps.rcPaint.left,
ps.rcPaint.bottom-ps.rcPaint.top);
Fl_X::i(window)->flush();
window->clear_damage();
//Since damage has been reset, we can dispose of the clip region
Region &r=Fl_X::i(window)->region;
if (r) {
DeleteObject(r);
r = 0;
Fl_X *i = Fl_X::i(window);
if (window->damage()) {
if (i->region) {
InvalidateRgn(hWnd,i->region,FALSE);
GetUpdateRgn(hWnd,i->region,0);
}
EndPaint(hWnd, &ps);
fl_gc = 0;
fl_window = (HWND)-1;
} else {
if (!i->region) i->region = CreateRectRgn(0,0,0,0);
GetUpdateRgn(hWnd,i->region,0);
}
window->clear_damage(window->damage()|2);
i->flush();
window->clear_damage();
// This convinces MSWindows we have painted whatever they wanted
// us to paint, and stops it from sending WM_PAINT messages.
ValidateRgn(hWnd,NULL);
} break;
case WM_LBUTTONDOWN: mouse_event(window, 0, 1, wParam, lParam); return 0;
@ -301,20 +284,6 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
case WM_RBUTTONUP: mouse_event(window, 2, 3, wParam, lParam); return 0;
case WM_MOUSEMOVE: mouse_event(window, 3, 0, wParam, lParam); return 0;
// kludges so the pop-up menus work. Title bar still blinks, sigh...
case WM_CAPTURECHANGED:
if (fl_capture && lParam != (LPARAM)fl_capture) {
SetCapture(fl_capture);
return 0;
}
break;
case WM_ACTIVATE:
if (fl_capture && wParam && hWnd!=fl_capture) {
SetActiveWindow(fl_capture);
return 0;
}
break;
case WM_SETFOCUS:
Fl::handle(FL_FOCUS, window);
break;
@ -350,16 +319,8 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
// otherwise use it as a 0-character key...
case WM_DEADCHAR:
case WM_SYSDEADCHAR:
buffer[0] = 0;
Fl::e_text = buffer;
Fl::e_length = 0;
goto GETSTATE;
case WM_CHAR:
case WM_SYSCHAR:
buffer[0] = char(wParam);
Fl::e_text = buffer;
Fl::e_length = 1;
GETSTATE:
{ulong state = Fl::e_state & 0xff000000; // keep the mouse button state
// if GetKeyState is expensive we might want to comment some of these out:
if (GetKeyState(VK_SHIFT)&~1) state |= FL_SHIFT;
@ -374,6 +335,17 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
if (GetKeyState(VK_SCROLL)) state |= FL_SCROLL_LOCK;
Fl::e_state = state;}
if (lParam & (1<<31)) goto DEFAULT; // ignore up events after fixing shift
if (uMsg == WM_CHAR || uMsg == WM_SYSCHAR) {
buffer[0] = char(wParam);
Fl::e_length = 1;
} else if (Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last) {
buffer[0] = Fl::e_keysym-FL_KP;
Fl::e_length = 1;
} else {
buffer[0] = 0;
Fl::e_length = 0;
}
Fl::e_text = buffer;
// for (int i = lParam&0xff; i--;)
while (window->parent()) window = window->window();
if (Fl::handle(FL_KEYBOARD,window)) return 0;
@ -472,7 +444,11 @@ Fl_X* Fl_X::make(Fl_Window* w) {
if (!class_name) { // create a single WNDCLASS used for everything:
class_name = "FLTK";
WNDCLASSEX wc;
wc.style = CS_HREDRAW | CS_VREDRAW | CS_CLASSDC | CS_DBLCLKS;
// 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;
@ -564,7 +540,10 @@ Fl_X* Fl_X::make(Fl_Window* w) {
w->set_visible();
w->handle(FL_SHOW); // get child windows to appear
ShowWindow(x->xid, fl_show_iconic ? SW_MINIMIZE : SW_SHOW);
// If we've captured the mouse, we dont want do activate any
// other windows from the code, or we loose the capture.
ShowWindow(x->xid, fl_show_iconic ? SW_SHOWMINNOACTIVE :
fl_capture? SW_SHOWNOACTIVATE : SW_SHOWNORMAL);
fl_show_iconic = 0;
fl_fix_focus();
return x;
@ -654,27 +633,20 @@ void Fl_Window::show() {
// if (can_boxcheat(box())) fl_background_pixel = fl_xpixel(color());
Fl_X::make(this);
} else {
ShowWindow(i->xid, SW_RESTORE);
SetActiveWindow(i->xid);
// Once again, we would lose the capture if we activated the window.
ShowWindow(i->xid,fl_capture?SW_SHOWNOACTIVATE:SW_RESTORE);
}
}
Fl_Window *Fl_Window::current_;
HDC window_dc;
// the current context
HDC fl_gc = 0;
// the current window handle, initially set to -1 so we can correctly
// allocate fl_GetDC(0)
HWND fl_window = (HWND)-1;
// Here we ensure only one GetDC is ever in place. There is a little
// workaround for the case of direct_paint.
// Here we ensure only one GetDC is ever in place.
HDC fl_GetDC(HWND w) {
/*
if (fl_direct_paint) {
if (w == direct_paint_window) return direct_paint_dc;
}
*/
if (fl_gc) {
if (w == fl_window) return fl_gc;
ReleaseDC(fl_window, fl_gc);
@ -691,19 +663,7 @@ HDC fl_GetDC(HWND w) {
void Fl_Window::make_current() {
fl_GetDC(fl_xid(this));
current_ = this;
}
// WM_PAINT events and cropped damage call this:
void Fl_Window::expose(uchar flags,int X,int Y,int W,int H) {
if (i) {
Region temp= XRectangleRegion(X,Y,W,H);
if (i->region) {
CombineRgn(temp,temp,i->region,RGN_AND);
DeleteObject((HGDIOBJ)i->region);
}
i->region=temp;
}
damage(flags);
fl_clip_region(0);
}
#include <FL/fl_draw.H>
@ -714,7 +674,8 @@ void Fl_Widget::damage(uchar flags) {
} else {
Fl_X* i = Fl_X::i((Fl_Window*)this);
if (i) {
if (i->region) {DeleteObject((HGDIOBJ)i->region); i->region = 0;}
if (i->region) {DeleteObject(i->region);}
i->region = 0;
damage_ |= flags;
Fl::damage(1);
}
@ -741,13 +702,12 @@ void Fl_Widget::damage(uchar flags, int X, int Y, int W, int H) {
CombineRgn(i->region,i->region,r,RGN_OR);
DeleteObject(r);
}
damage_ |= flags;
} else {
// create a new region:
if (i->region) DeleteObject(i->region);
i->region = XRectangleRegion(X,Y,W,H);
damage_ = flags;
}
damage_ |= flags;
Fl::damage(1);
}
}
@ -755,13 +715,8 @@ void Fl_Widget::damage(uchar flags, int X, int Y, int W, int H) {
void Fl_Window::flush() {
make_current();
if (damage() & ~6) {
fl_clip_region(i->region);i->region=0;
draw();
} else {
fl_clip_region(i->region);
draw();
fl_pop_clip();
}
}
// End of Fl_win32.C //

View File

@ -137,7 +137,7 @@ $(LIBRARY) : $(OBJECTS)
@$(CC) -I.. $(CFLAGS) -c -o $@ $<
clean :
-@ rm -f *.o *.do $(LIBRARY) $(CLEAN) core *~ makedepend
-@ rm -f *.o *.do $(LIBRARY) $(CLEAN) core *~ ../include/*~ makedepend cmap
@touch makedepend
depend:

View File

@ -5,9 +5,7 @@
#include <config.h>
#include <FL/filename.H>
#if !defined(WIN32) || defined(__GNUC__)
extern "C" {
#endif
int numericsort(const dirent **, const dirent **);
#if HAVE_SCANDIR
#else
@ -16,9 +14,7 @@ extern "C" {
int (*select)(const dirent *),
int (*compar)(const dirent **, const dirent **));
#endif
#if !defined(WIN32) || defined(__GNUC__)
}
#endif
int filename_list(const char *d, dirent ***list) {
#if defined(_AIX) || defined(CRAY)

View File

@ -25,45 +25,48 @@ static uchar inactive_ramp[24] = {
48, 48, 48, 49,
49, 49, 50, 50,
51, 51, 52, 52};
uchar* Fl_Gray_Ramp = (uchar*)active_ramp-'A';
static int draw_it_active;
uchar *fl_gray_ramp() {return (draw_it_active?active_ramp:inactive_ramp)-'A';}
void fl_frame(const char* s, int x, int y, int w, int h) {
uchar *g = fl_gray_ramp();
if (h > 0 && w > 0) for (;*s;) {
// draw top line:
fl_color(Fl_Gray_Ramp[*s++]);
fl_color(g[*s++]);
fl_xyline(x, y, x+w-1);
y++; if (--h <= 0) break;
// draw left line:
fl_color(Fl_Gray_Ramp[*s++]);
fl_color(g[*s++]);
fl_yxline(x, y+h-1, y);
x++; if (--w <= 0) break;
// draw bottom line:
fl_color(Fl_Gray_Ramp[*s++]);
fl_color(g[*s++]);
fl_xyline(x, y+h-1, x+w-1);
if (--h <= 0) break;
// draw right line:
fl_color(Fl_Gray_Ramp[*s++]);
fl_color(g[*s++]);
fl_yxline(x+w-1, y+h-1, y);
if (--w <= 0) break;
}
}
void fl_frame2(const char* s, int x, int y, int w, int h) {
uchar *g = fl_gray_ramp();
if (h > 0 && w > 0) for (;*s;) {
// draw bottom line:
fl_color(Fl_Gray_Ramp[*s++]);
fl_color(g[*s++]);
fl_xyline(x, y+h-1, x+w-1);
if (--h <= 0) break;
// draw right line:
fl_color(Fl_Gray_Ramp[*s++]);
fl_color(g[*s++]);
fl_yxline(x+w-1, y+h-1, y);
if (--w <= 0) break;
// draw top line:
fl_color(Fl_Gray_Ramp[*s++]);
fl_color(g[*s++]);
fl_xyline(x, y, x+w-1);
y++; if (--h <= 0) break;
// draw left line:
fl_color(Fl_Gray_Ramp[*s++]);
fl_color(g[*s++]);
fl_yxline(x, y+h-1, y);
x++; if (--w <= 0) break;
}
@ -250,7 +253,7 @@ void Fl_Widget::draw_box(Fl_Boxtype b, Fl_Color c) const {
void Fl_Widget::draw_box(Fl_Boxtype b, int x, int y, int w, int h, Fl_Color c)
const {
if (!active_r()) Fl_Gray_Ramp = inactive_ramp-'A';
draw_it_active = active_r();
fl_box_table[b].f(x, y, w, h, c);
Fl_Gray_Ramp = active_ramp-'A';
draw_it_active = 1;
}

View File

@ -9,7 +9,7 @@
#include <FL/Fl.H>
#include <FL/fl_draw.H>
extern uchar* Fl_Gray_Ramp;
extern uchar* fl_gray_ramp();
static void fl_diamond_up_box(int x,int y,int w,int h,Fl_Color bgcolor) {
w &= -2;
@ -17,13 +17,14 @@ static void fl_diamond_up_box(int x,int y,int w,int h,Fl_Color bgcolor) {
int x1 = x+w/2;
int y1 = y+h/2;
fl_color(bgcolor); fl_polygon(x+3, y1, x1,y+3, x+w-3,y1, x1,y+h-3);
fl_color(Fl_Gray_Ramp['W']); fl_line(x+1, y1, x1, y+1, x+w-1, y1);
fl_color(Fl_Gray_Ramp['U']); fl_line(x+2, y1, x1, y+2, x+w-2, y1);
fl_color(Fl_Gray_Ramp['S']); fl_line(x+3, y1, x1, y+3, x+w-3, y1);
fl_color(Fl_Gray_Ramp['P']); fl_line(x+3, y1, x1, y+h-3, x+w-3, y1);
fl_color(Fl_Gray_Ramp['N']); fl_line(x+2, y1, x1, y+h-2, x+w-2, y1);
fl_color(Fl_Gray_Ramp['H']); fl_line(x+1, y1, x1, y+h-1, x+w-1, y1);
fl_color(Fl_Gray_Ramp['A']); fl_loop(x, y1, x1, y, x+w, y1, x1, y+h);
uchar *g = fl_gray_ramp();
fl_color(g['W']); fl_line(x+1, y1, x1, y+1, x+w-1, y1);
fl_color(g['U']); fl_line(x+2, y1, x1, y+2, x+w-2, y1);
fl_color(g['S']); fl_line(x+3, y1, x1, y+3, x+w-3, y1);
fl_color(g['P']); fl_line(x+3, y1, x1, y+h-3, x+w-3, y1);
fl_color(g['N']); fl_line(x+2, y1, x1, y+h-2, x+w-2, y1);
fl_color(g['H']); fl_line(x+1, y1, x1, y+h-1, x+w-1, y1);
fl_color(g['A']); fl_loop(x, y1, x1, y, x+w, y1, x1, y+h);
}
static void fl_diamond_down_box(int x,int y,int w,int h,Fl_Color bgcolor) {
@ -31,14 +32,15 @@ static void fl_diamond_down_box(int x,int y,int w,int h,Fl_Color bgcolor) {
h &= -2;
int x1 = x+w/2;
int y1 = y+h/2;
fl_color(Fl_Gray_Ramp['P']); fl_line(x+0, y1, x1, y+0, x+w-0, y1);
fl_color(Fl_Gray_Ramp['N']); fl_line(x+1, y1, x1, y+1, x+w-1, y1);
fl_color(Fl_Gray_Ramp['H']); fl_line(x+2, y1, x1, y+2, x+w-2, y1);
fl_color(Fl_Gray_Ramp['W']); fl_line(x+2, y1, x1, y+h-2, x+w-2, y1);
fl_color(Fl_Gray_Ramp['U']); fl_line(x+1, y1, x1, y+h-1, x+w-1, y1);
fl_color(Fl_Gray_Ramp['S']); fl_line(x+0, y1, x1, y+h-0, x+w-0, y1);
uchar *g = fl_gray_ramp();
fl_color(g['P']); fl_line(x+0, y1, x1, y+0, x+w-0, y1);
fl_color(g['N']); fl_line(x+1, y1, x1, y+1, x+w-1, y1);
fl_color(g['H']); fl_line(x+2, y1, x1, y+2, x+w-2, y1);
fl_color(g['W']); fl_line(x+2, y1, x1, y+h-2, x+w-2, y1);
fl_color(g['U']); fl_line(x+1, y1, x1, y+h-1, x+w-1, y1);
fl_color(g['S']); fl_line(x+0, y1, x1, y+h-0, x+w-0, y1);
fl_color(bgcolor); fl_polygon(x+3, y1, x1,y+3, x+w-3,y1, x1,y+h-3);
fl_color(Fl_Gray_Ramp['A']); fl_loop(x+3, y1, x1, y+3, x+w-3, y1, x1, y+h-3);
fl_color(g['A']); fl_loop(x+3, y1, x1, y+3, x+w-3, y1, x1, y+h-3);
}
extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);

View File

@ -264,7 +264,7 @@ void fl_clip(int x, int y, int w, int h) {
#ifndef WIN32
r = XCreateRegion();
#else
r = 0; //whatever, for win32 this is the same as having 0 for HRGN
r = CreateRectRgn(0,0,0,0);
#endif
}
rstack[++rstackptr] = r;
@ -312,24 +312,6 @@ int fl_clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){
default: // partial:
break;
}
#else
// The win32 API makes no distinction between partial and complete
// intersection, so we have to check for partial intersection ourselves.
RECT rect;
rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h;
if (!RectInRegion(r,&rect)) {
W = H = 0;
return 2;
} else {
if (PtInRegion(r, rect.left, rect.top) &&
PtInRegion(r, rect.left, rect.top) &&
PtInRegion(r, rect.right, rect.bottom) &&
PtInRegion(r, rect.right, rect.bottom))
return 0;
}
#endif
#ifndef WIN32
Region rr = XRectangleRegion(x,y,w,h);
Region temp = XCreateRegion();
XIntersectRegion(r, rr, temp);
@ -338,14 +320,30 @@ int fl_clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){
X = rect.x; Y = rect.y; W = rect.width; H = rect.height;
XDestroyRegion(temp);
XDestroyRegion(rr);
#else
Region rr = XRectangleRegion(x,y,w,h);
CombineRgn(rr, rr, r,RGN_AND);
GetRgnBox(rr, &rect);
X = rect.left; Y = rect.top; W = rect.right - X; H = rect.bottom - Y;
DeleteObject(rr);
#endif
return 1;
#else
// The win32 API makes no distinction between partial and complete
// intersection, so we have to check for partial intersection ourselves.
// However, given that the regions may be composite, we have to do
// some voodoo stuff...
Region rr = XRectangleRegion(x,y,w,h);
Region temp = CreateRectRgn(0,0,0,0);
int ret;
if (CombineRgn(temp, rr, r, RGN_AND) == NULLREGION) { // disjoint
W = H = 0;
ret = 2;
} else if (EqualRgn(temp, rr)) { // complete
ret = 0;
} else { // parital intersection
RECT rect;
GetRgnBox(temp, &rect);
X = rect.left; Y = rect.top; W = rect.right - X; H = rect.bottom - Y;
ret = 1;
}
DeleteObject(temp);
DeleteObject(rr);
return ret;
#endif
}
// end of fl_rect.C

View File

@ -58,32 +58,34 @@ static void draw(int which, int x,int y,int w,int h, int inset, uchar color)
}
}
extern uchar* Fl_Gray_Ramp;
extern uchar* fl_gray_ramp();
static void fl_round_down_box(int x, int y, int w, int h, Fl_Color bgcolor) {
uchar *g = fl_gray_ramp();
draw(FILL, x, y, w, h, 2, bgcolor);
draw(UPPER_LEFT, x+1, y, w-2, h, 0, Fl_Gray_Ramp['N']);
draw(UPPER_LEFT, x+1, y, w-2, h, 1, Fl_Gray_Ramp['H']);
draw(UPPER_LEFT, x, y, w, h, 0, Fl_Gray_Ramp['N']);
draw(UPPER_LEFT, x, y, w, h, 1, Fl_Gray_Ramp['H']);
draw(LOWER_RIGHT, x, y, w, h, 0, Fl_Gray_Ramp['S']);
draw(LOWER_RIGHT, x+1, y, w-2, h, 0, Fl_Gray_Ramp['U']);
draw(LOWER_RIGHT, x, y, w, h, 1, Fl_Gray_Ramp['U']);
draw(LOWER_RIGHT, x+1, y, w-2, h, 1, Fl_Gray_Ramp['W']);
draw(CLOSED, x, y, w, h, 2, Fl_Gray_Ramp['A']);
draw(UPPER_LEFT, x+1, y, w-2, h, 0, g['N']);
draw(UPPER_LEFT, x+1, y, w-2, h, 1, g['H']);
draw(UPPER_LEFT, x, y, w, h, 0, g['N']);
draw(UPPER_LEFT, x, y, w, h, 1, g['H']);
draw(LOWER_RIGHT, x, y, w, h, 0, g['S']);
draw(LOWER_RIGHT, x+1, y, w-2, h, 0, g['U']);
draw(LOWER_RIGHT, x, y, w, h, 1, g['U']);
draw(LOWER_RIGHT, x+1, y, w-2, h, 1, g['W']);
draw(CLOSED, x, y, w, h, 2, g['A']);
}
static void fl_round_up_box(int x, int y, int w, int h, Fl_Color bgcolor) {
uchar *g = fl_gray_ramp();
draw(FILL, x, y, w, h, 2, bgcolor);
draw(LOWER_RIGHT, x+1, y, w-2, h, 0, Fl_Gray_Ramp['H']);
draw(LOWER_RIGHT, x+1, y, w-2, h, 1, Fl_Gray_Ramp['N']);
draw(LOWER_RIGHT, x, y, w, h, 1, Fl_Gray_Ramp['H']);
draw(LOWER_RIGHT, x, y, w, h, 2, Fl_Gray_Ramp['N']);
draw(UPPER_LEFT, x, y, w, h, 2, Fl_Gray_Ramp['U']);
draw(UPPER_LEFT, x+1, y, w-2, h, 1, Fl_Gray_Ramp['S']);
draw(UPPER_LEFT, x, y, w, h, 1, Fl_Gray_Ramp['W']);
draw(UPPER_LEFT, x+1, y, w-2, h, 0, Fl_Gray_Ramp['U']);
draw(CLOSED, x, y, w, h, 0, Fl_Gray_Ramp['A']);
draw(LOWER_RIGHT, x+1, y, w-2, h, 0, g['H']);
draw(LOWER_RIGHT, x+1, y, w-2, h, 1, g['N']);
draw(LOWER_RIGHT, x, y, w, h, 1, g['H']);
draw(LOWER_RIGHT, x, y, w, h, 2, g['N']);
draw(UPPER_LEFT, x, y, w, h, 2, g['U']);
draw(UPPER_LEFT, x+1, y, w-2, h, 1, g['S']);
draw(UPPER_LEFT, x, y, w, h, 1, g['W']);
draw(UPPER_LEFT, x+1, y, w-2, h, 0, g['U']);
draw(CLOSED, x, y, w, h, 0, g['A']);
}
extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);

View File

@ -48,4 +48,4 @@ jpeg_image: jpeg_image.C
@${CXX} -I.. ${CXXFLAGS} -I../../../local/jpeg-6b -L../../../local/jpeg-6b jpeg_image.C -L../lib -lfltk ${LDLIBS} -ljpeg -lXext -o $@
clean:
-rm -f ${ALL} jpeg_image *~
-@ rm -f ${ALL} jpeg_image *.o core *~