Commited Gustavo Hime's NT patches/fixes.

git-svn-id: file:///fltk/svn/fltk/trunk@7 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Michael R Sweet 1998-10-06 18:46:47 +00:00
parent f9039b2ae2
commit e7d805a88c
12 changed files with 2793 additions and 2723 deletions

View File

@ -74,6 +74,7 @@ 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

@ -14,13 +14,16 @@
#endif
// some random X equivalents
#define Window HWND
#define XPoint POINT
typedef HWND Window;
typedef POINT XPoint;
struct XRectangle {int x, y, width, height;};
struct Region {int x, y, r, b; void operator=(int x) {r = x;}};
inline void XClipBox(Region& i, XRectangle* o) {
o->x = i.x; o->y = i.y; o->width = i.r-i.x; o->height = i.b-i.y;}
#define fl_clip_region(R) fl_clip((R).x,(R).y,(R).r-(R).x,(R).b-(R).y)
typedef HRGN Region;
void fl_clip_region(Region);
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);}
#define XDestroyWindow(a,b) DestroyWindow(b)
#define XMapWindow(a,b) ShowWindow(b, SW_RESTORE)
#define XUnmapWindow(a,b) ShowWindow(b, SW_HIDE)
@ -64,16 +67,22 @@ 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_DC(Window);
extern HDC fl_GetDC(Window);
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);
#define fl_begin_offscreen(b) HDC _sw=fl_gc; fl_switch_offscreen(b)
#define fl_end_offscreen() fl_gc = _sw
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);
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);

View File

@ -506,9 +506,8 @@ void Fl_Window::hide() {
#ifdef WIN32
if (x->private_dc) ReleaseDC(x->xid,x->private_dc);
if (x->xid == fl_window) fl_GetDC(0); // releases dc belonging to window
#else
if (x->region) XDestroyRegion(x->region);
#endif
if (x->region) XDestroyRegion(x->region);
XDestroyWindow(fl_display, x->xid);
delete x;

View File

@ -51,29 +51,27 @@ void Fl_Double_Window::show() {
#ifdef WIN32
// Code to switch output to an off-screen window:
// this is lame, I allow two to exist...
// I've removed the second one (never understool why
// it was there to begin with).
static HDC blt_gc[2];
static HDC blt_gc;
void fl_switch_offscreen(HBITMAP bitmap) {
if (!blt_gc[0]) for (int i = 0; i < 2; i++) {
blt_gc[i] = CreateCompatibleDC(fl_gc);
SetTextAlign(blt_gc[i], TA_BASELINE|TA_LEFT);
SetBkMode(blt_gc[i], TRANSPARENT);
if (!blt_gc) {
blt_gc = CreateCompatibleDC(fl_gc);
SetTextAlign(blt_gc, TA_BASELINE|TA_LEFT);
SetBkMode(blt_gc, TRANSPARENT);
#if USE_COLORMAP
if (fl_palette) SelectPalette(blt_gc[i], fl_palette, FALSE);
if (fl_palette) SelectPalette(blt_gc, fl_palette, FALSE);
#endif
}
int which = 0; if (fl_gc == blt_gc[0]) which = 1;
SelectObject(blt_gc[which], bitmap);
fl_gc = blt_gc[which];
SelectObject(blt_gc, bitmap);
fl_gc = blt_gc;
}
void fl_copy_offscreen(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) {
int which = 0; if (fl_gc == blt_gc[0]) which = 1;
SelectObject(blt_gc[which], bitmap);
BitBlt(fl_gc, x, y, w, h, blt_gc[which], srcx, srcy, SRCCOPY);
SelectObject(blt_gc, bitmap);
BitBlt(window_dc, x, y, w, h, blt_gc, srcx, srcy, SRCCOPY);
}
#endif
@ -93,27 +91,35 @@ void Fl_Double_Window::_flush(int eraseoverlay) {
}
XRectangle rect = {0,0,w(),h()};
if (damage()) {
if (i->region && !eraseoverlay) XClipBox(i->region, &rect);
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;
draw();
fl_end_offscreen();
#else
*/
#ifdef WIN32
fl_begin_offscreen(i->other_xid);
#endif
fl_window = i->other_xid;
fl_clip_region(i->region); i->region = 0;
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) {
XdbeSwapInfo s;
s.swap_window = fl_xid(this);

View File

@ -38,13 +38,19 @@
////////////////////////////////////////////////////////////////
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);
/*
Is this necessary? Don't all windows have the same
support for pixel formats?
HWND w = GetDesktopWindow();
HDC dc = GetDC(w);
int r = ChoosePixelFormat(dc, &g->pfd);
ReleaseDC(w,dc);
*/
if (!fl_gc) fl_GetDC(0);
int r = ChoosePixelFormat(fl_gc, &g->pfd);
return r != 0;
#else
return Fl_Gl_Choice::find(a,b) != 0;

View File

@ -8,10 +8,11 @@
#ifdef WIN32
int Fl::visual(int flags) {
fl_GetDC(0);
if (flags & FL_DOUBLE) return 0;
if (!(flags & FL_INDEX) &&
GetDeviceCaps(fl_GetDC(0),BITSPIXEL) <= 8) return 0;
if ((flags & FL_RGB8) && GetDeviceCaps(fl_GetDC(0),BITSPIXEL)<24) return 0;
GetDeviceCaps(fl_gc,BITSPIXEL) <= 8) return 0;
if ((flags & FL_RGB8) && GetDeviceCaps(fl_gc,BITSPIXEL)<24) return 0;
return 1;
}
#else

View File

@ -158,7 +158,7 @@ static int mouse_event(Fl_Window *window, int what, int button,
}
}
// convert a Micro$oft VK_x to an Fltk (X) Keysym:
// 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[] = {
@ -209,7 +209,7 @@ static const struct {unsigned short vk, fltk;} vktab[] = {
static int ms2fltk(int vk, int extended) {
static unsigned short vklut[256];
if (!vklut[1]) { // init the table
int i;
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);
@ -224,9 +224,6 @@ static int ms2fltk(int vk, int extended) {
return vklut[vk];
}
char fl_direct_paint;
static HDC direct_paint_dc;
#if USE_COLORMAP
extern HPALETTE fl_select_palette(); // in fl_color_win32.C
#endif
@ -256,17 +253,41 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
// 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;
// if (!(window->damage())) fl_direct_paint = 1;
PAINTSTRUCT ps;
direct_paint_dc = BeginPaint(hWnd, &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);
window->expose(2, ps.rcPaint.left, ps.rcPaint.top,
ps.rcPaint.right-ps.rcPaint.left,
ps.rcPaint.bottom-ps.rcPaint.top);
if (!fl_direct_paint) {EndPaint(hWnd,&ps);ReleaseDC(hWnd,direct_paint_dc);}
Fl_X::i(window)->flush();
window->clear_damage();
Fl_X::i(window)->region = 0;
if (fl_direct_paint) {EndPaint(hWnd, &ps); fl_direct_paint = 0;}
//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;
}
EndPaint(hWnd, &ps);
fl_gc = 0;
fl_window = (HWND)-1;
} break;
case WM_LBUTTONDOWN: mouse_event(window, 0, 1, wParam, lParam); return 0;
@ -639,16 +660,26 @@ void Fl_Window::show() {
}
Fl_Window *Fl_Window::current_;
HDC fl_gc; // the current context
HWND fl_window; // the current window
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;
// Make sure we always ReleaseDC every DC we allocate...
// Here we ensure only one GetDC is ever in place. There is a little
// workaround for the case of direct_paint.
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);
}
fl_gc = fl_direct_paint ? direct_paint_dc : GetDC(w);
fl_gc = GetDC(w);
fl_window = w;
// calling GetDC seems to always reset these: (?)
SetTextAlign(fl_gc, TA_BASELINE|TA_LEFT);
@ -665,23 +696,63 @@ void Fl_Window::make_current() {
// WM_PAINT events and cropped damage call this:
void Fl_Window::expose(uchar flags,int X,int Y,int W,int H) {
if (i) {
if (!i->region.r) {
i->region.x = X;
i->region.y = Y;
i->region.r = X+W;
i->region.b = Y+H;
} else {
if (X < i->region.x) i->region.x = X;
if (Y < i->region.y) i->region.y = Y;
if (X+W > i->region.r) i->region.r = X+W;
if (Y+H > i->region.b) i->region.b = Y+H;
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);
}
#include <FL/fl_draw.H>
void Fl_Widget::damage(uchar flags) {
if (type() < FL_WINDOW) {
damage(flags, x(), y(), w(), h());
} else {
Fl_X* i = Fl_X::i((Fl_Window*)this);
if (i) {
if (i->region) {DeleteObject((HGDIOBJ)i->region); i->region = 0;}
damage_ |= flags;
Fl::damage(1);
}
}
}
void Fl_Widget::redraw() {damage(~0);}
Region XRectangleRegion(int x, int y, int w, int h); // in fl_rect.C
void Fl_Widget::damage(uchar flags, int X, int Y, int W, int H) {
if (type() < FL_WINDOW) {
damage_ |= flags;
if (parent()) parent()->damage(1,X,Y,W,H);
} else {
// see if damage covers entire window:
if (X<=0 && Y<=0 && W>=w() && H>=h()) {damage(flags); return;}
Fl_X* i = Fl_X::i((Fl_Window*)this);
if (i) {
if (damage()) {
// if we already have damage we must merge with existing region:
if (i->region) {
Region r = XRectangleRegion(X,Y,W,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;
}
Fl::damage(1);
}
}
}
void Fl_Window::flush() {
make_current();
if (damage() & ~6) {

View File

@ -36,7 +36,7 @@ Fl_XFont::Fl_XFont(const char *name, int size, int num) {
DEFAULT_PITCH, // pitch and family
name // pointer to typeface name string
);
if (!fl_gc) fl_gc = fl_GetDC(0);
if (!fl_gc) fl_GetDC(0);
SelectObject(fl_gc, fid);
GetTextMetrics(fl_gc, &metr);
// BOOL ret = GetCharWidthFloat(fl_gc, metr.tmFirstChar, metr.tmLastChar, font->width+metr.tmFirstChar);
@ -109,7 +109,7 @@ static Fl_XFont *find(int fnum, int size) {
int fl_font_;
int fl_size_;
static HDC font_gc;
//static HDC font_gc;
void fl_font(int fnum, int size) {
if (fnum == fl_font_ && size == fl_size_) return;

View File

@ -208,82 +208,13 @@ void fl_point(int x, int y) {
////////////////////////////////////////////////////////////////
#ifdef WIN32
static struct rect {int notnull, x, y, r, b;} rstack[10];
static Region rstack[10];
static int rstackptr;
int fl_clip_state_number; // used by gl_begin.C to update GL clip
extern char fl_direct_paint; // in Fl_win32.C
void fl_clip(int x, int y, int w, int h) {
fl_clip_state_number++;
int r = x+w;
int b = y+h;
rect& current = rstack[rstackptr];
if (current.notnull) {
if (current.x > x) x = current.x;
if (current.y > y) y = current.y;
if (current.r < r) r = current.r;
if (current.b < b) b = current.b;
}
rect& newrect = rstack[++rstackptr];
newrect.notnull = 1;
newrect.x = x;
newrect.y = y;
newrect.r = r;
newrect.b = b;
if (rstackptr == 1 && fl_direct_paint) return;
HRGN R = CreateRectRgn(x,y,r,b);
SelectClipRgn(fl_gc, R);
DeleteObject(R);
}
void fl_push_no_clip() {
fl_clip_state_number++;
if (rstack[rstackptr].notnull) SelectClipRgn(fl_gc, 0);
rstack[++rstackptr].notnull = 0;
}
void fl_pop_clip() {
fl_clip_state_number++;
rect& r = rstack[--rstackptr];
if (r.notnull) {
HRGN R = CreateRectRgn(r.x, r.y, r.r, r.b);
SelectClipRgn(fl_gc, R);
DeleteObject(R);
} else {
SelectClipRgn(fl_gc, 0);
}
}
// does this rectangle intersect current clip?
int fl_not_clipped(int x, int y, int w, int h) {
rect& r = rstack[rstackptr];
if (!r.notnull) return 2;
return (x < r.r && x+w > r.x && y < r.b && y+h > r.y);
}
// return rectangle surrounding intersection of this rectangle and clip:
int fl_clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){
X = x; Y = y; W = w; H = h;
rect& r = rstack[rstackptr];
if (!r.notnull) return 0;
int R = x+w;
int B = y+h;
int ret = 0;
if (r.x > x) {X = r.x; ret = 1;}
if (r.y > y) {Y = r.y; ret = 1;}
if (r.r < R) {R = r.r; ret = 1;}
if (r.b < B) {B = r.b; ret = 1;}
if (B <= Y || R <= X) {W = H = 0; return 2;}
W = R-X;
H = B-Y;
return ret;
}
#else
int fl_clip_state_number=0; // used by gl_begin.C to update GL clip
#ifndef WIN32
// Missing X call: (is this the fastest way to init a 1-rectangle region?)
// MSWindows equivalent exists, implemented inline in win32.H
Region XRectangleRegion(int x, int y, int w, int h) {
XRectangle R;
R.x = x; R.y = y; R.width = w; R.height = h;
@ -291,17 +222,18 @@ Region XRectangleRegion(int x, int y, int w, int h) {
XUnionRectWithRegion(&R, r, r);
return r;
}
static Region rstack[10];
static int rstackptr;
int fl_clip_state_number; // used by gl_begin.C to update GL clip
#endif
// undo any clobbering of clip done by your program:
void fl_restore_clip() {
fl_clip_state_number++;
Region r = rstack[rstackptr];
#ifdef WIN32
SelectClipRgn(fl_gc, r); //if r is NULL, clip is automatically cleared
#else
if (r) XSetRegion(fl_display, fl_gc, r);
else XSetClipMask(fl_display, fl_gc, 0);
#endif
}
// Replace the top of the clip stack:
@ -319,13 +251,21 @@ void fl_clip(int x, int y, int w, int h) {
r = XRectangleRegion(x,y,w,h);
Region current = rstack[rstackptr];
if (current) {
#ifndef WIN32
Region temp = XCreateRegion();
XIntersectRegion(current, r, temp);
XDestroyRegion(r);
r = temp;
#else
CombineRgn(r,r,current,RGN_AND);
#endif
}
} else { // make empty clip region:
#ifndef WIN32
r = XCreateRegion();
#else
r = 0; //whatever, for win32 this is the same as having 0 for HRGN
#endif
}
rstack[++rstackptr] = r;
fl_restore_clip();
@ -347,7 +287,14 @@ void fl_pop_clip() {
// does this rectangle intersect current clip?
int fl_not_clipped(int x, int y, int w, int h) {
Region r = rstack[rstackptr];
#ifndef WIN32
return r ? XRectInRegion(r, x, y, w, h) : 1;
#else
if (!r) return 1;
RECT rect;
rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h;
return RectInRegion(r,&rect);
#endif
}
// return rectangle surrounding intersection of this rectangle and clip:
@ -355,6 +302,7 @@ int fl_clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){
X = x; Y = y; W = w; H = h;
Region r = rstack[rstackptr];
if (!r) return 0;
#ifndef WIN32
switch (XRectInRegion(r, x, y, w, h)) {
case 0: // completely outside
W = H = 0;
@ -364,6 +312,24 @@ 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);
@ -372,9 +338,14 @@ 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;
}
#endif
// end of fl_rect.C

View File

@ -26,7 +26,7 @@ extern GLXContext fl_first_context; // in Fl_Gl_Choice.C
extern int fl_clip_state_number; // in fl_rect.C
static GLXContext context;
static int clip_state_number;
static int clip_state_number=-1;
static int pw, ph;
#ifdef WIN32

View File

@ -25,6 +25,9 @@
#endif
#endif
#ifdef __cplusplus
extern "C"
#endif
int numericsort(const struct dirent **A, const struct dirent **B) {
const char* a = (*A)->d_name;
const char* b = (*B)->d_name;

View File

@ -7,6 +7,9 @@
#include <string.h>
#include <windows.h>
#ifdef __cplusplus
extern "C"
#endif
int scandir(const char *dirname, struct dirent ***namelist,
int (*select)(const struct dirent *),
int (*compar)(const struct dirent **, const struct dirent **)) {