Release 0.5
Sun Jan 2 12:38:53 1994 David Metcalfe <david@prism.demon.co.uk>
* [windows/class.c]
Implemented GetClassName and GetClassInfo.
* [windows/caret.c]
Various improvements to text caret code.
Fri Dec 31 15:22:22 1993 John Brezak <brezak@apollo.hp.com>
* [misc/comm.c]
Patches to work with NetBSD.
Thu Dec 30 12:11:55 1993 John Richardson <jrichard@cs.uml.edu>
* [objects/bitblt.c] Added StretchBlt().
Tue Jan 4 05:22:07 1994 julliard@di.epfl.ch (Alexandre Julliard)
* [misc/user.c]
Added creation of system message queue.
* [objects/bitmap.c] [objects/dcvalues.c] [windows/dc.c]
Added DC size fields into DC structure.
* [objects/clipping.c]
Bug fix in CLIPPING_IntersectRect().
* [windows/class.c]
Allocate a DCE instead of a DC for CS_CLASSDC classes.
* [windows/clipping.c]
Fixed GetUpdateRect() and GetUpdateRgn() to clip to the client area.
* [windows/dce.c]
Implemented GetDCEx() and GetWindowDC().
* [windows/defwnd.c]
Implemented WM_WINDOWPOSCHANGED handling.
* [windows/event.c]
Preliminary support for Xlib event handling instead of Xt callbacks.
Changed MSG_AddMsg() calls to hardware_event() or PostMessage().
* [windows/message.c]
Preliminary support for multiple message queues.
Implemented hardware_event() to store messages into the system queue.
Implemented Get/SetTaskQueue().
Better WM_PAINT and WM_TIMER handling.
Changes to use Xlib instead of Xt for events.
* [windows/painting.c]
Use GetDCEx() to retrieve the DC, to get a correct visible region.
* [windows/timer.c]
Moved the timer procedure callback into DispatchMessage().
Changed implementation to get rid of Xt timeouts. Timer checking
is now done inside GetMessage().
* [windows/win.c]
Allocate a DCE instead of a DC for CS_OWNDC windows.
Replaced Xt calls with Xlib calls.
Moved window positioning functions into windows/winpos.c
* [windows/winpos.c] (New file)
Rewritten most of the window positioning functions.
Implemented SetWindowPos() and MapWindowPoints().
Jan 3, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)
* [if1632/user.spec]
Bad arguments description for function SetDlgItemText.
* [objects/text.c]
Function DrawText now handle DT_CALCRECT request.
* [misc/message.c]
Message boxes now use DrawText with DT_CALCRECT.
* [windows/graphics.c]
Bug fix in function FrameRect, (it was using PEN instead of BRUSH).
* [windows/win.c]
Bug fix for flags in function ShowWindow.
More accurate WM_SIZE generated by function ShowWindow.
* [controls/listbox.c]
More code for LBS_MULTIPLESEL.
More code for LBS_MULTICOLUMN.
* [include/windows.h]
Bad define for MF_SEPARATOR.
* [controls/menu.c]
New functions: PopMenuWndProc() with 'glues',
CreatePopupMenu(), AppendMenu(), InsertMenu(), RemoveMenu(),
DeleteMenu(), ModifyMenu(), TrackPopupMenu().
Code in stubs: CreateMenu(), DestroyMenu().
Sat Jan 1 10:22:43 1994 Bob Amstadt (bob@pooh)
* loader/wine.c: Added support for relocation types 5 and 6.
Mon Dec 27 11:06:03 1993 Erik Bos (erik@trashcan.hacktic.nl)
* [misc/comm.c]
new functions: BuildCommDCB(), OpenComm(), CloseComm(),
SetCommBreak(), ClearCommBreak(), EscapeCommFunction(), FlushComm(),
GetCommError(), SetCommEventMask(), GetCommEventMask(),
SetCommState(), GetCommState(), TransmitCommChar(), ReadComm(),
WriteComm().
Wed Dec 22 13:00:15 1993 David Metcalfe <david@prism.demon.co.uk>
* [windows/caret.c]
Implemented text caret functions.
Tue Dec 21 06:13:58 1993 julliard@di.epfl.ch (Alexandre Julliard)
* [loader/wine.c]
Bug fix in LoadImage().
* [objects/bitblt.c] [objects/clipping.c] [objects/text.c]
[windows/dc.c] [windows/dce.c] [windows/graphics.c]
Modified graphics calls to take into account the DC origin.
* [windows/defwnd.c]
Added preliminary WM_NCCALCSIZE handling.
* [windows/event.c]
Send WM_NCCALCSIZE message on resize event.
* [windows/win.c]
Send WM_NCCALCSIZE message in CreateWindow().
Realize widgets at creation time (should prevent problems with
unrealized widgets).
Dec 19, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)
* [controls/static.c]
Send mouse & keyboard message received to its parent.
* [controls/scroll.c]
Send keyboard message received to its parent.
* [controls/listbox.c]
Add Navigation keys .
ListBox now use VSCROLL & HSCROLL instead of children.
Alpha version of LBS_MULTIPLESEL.
Alpha version of LBS_MULTICOLUMN.
* [controls/combo.c]
Add Navigation keys on closed ComboBox.
Remove useless 'COMBOBOX_CreateComboBox' function.
Mon Dec 19 20:39:34 1993 Erik Bos (erik@trashcan.hacktic.nl)
* [loader/wine.
LoadImage() modified to use FindFile().
* [misc/file.c]
SetErrorMode added
* [misc/dos_fs.c]
bug fixes.
Dec 13, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)
* [memory/global.c]
bug fix in GlobalGetFreeSegment : good ptr in 'g_prev'.
* [sysres.dll]
preliminary version of a 'glass of wine' bitmap
* [windows/event.c]
New function 'GetCapture'.
* [controls/scroll.c]
Remove useless 'SCROLLBAR_CreateScrollBar' function.
* [controls/listbox.c]
Remove useless 'LISTBOX_CreateListBox' function.
Mon Dec 13 13:51:00 1993 David Metcalfe <david@prism.demon.co.uk>
* [objects/font.c]
Corrected bugs in GetCharWidth().
* [windows/event.c]
Modified EVENT_key to send Windows virtual key codes for
WM_KEYDOWN and WM_KEYUP messages, and a WM_CHAR message
for printable characters.
Wed Dec 08 19:20:00 1993 Karl Guenter Wuensch (hn324wu@unidui.uni-duisburg.de)
* [windows/graphics.c]
Added Polyline and Polygon
Mon Dec 13 14:51:54 1993 Erik Bos (erik@trashcan.hacktic.nl)
* [controls/listbox.c]
ListBoxDirectory() modified to use dos_fs.c's functions to
access files&|drives.
Sat Dec 04 17:04:23 1993 Erik Bos (erik@trashcan.hacktic.nl)
* [misc/dos_fs.c]
Added FindFile() to search a file in a dos/unix style path.
* [misc/file.c]
New Win31 functions: OpenFile, _lcreate, _llseek, GetTempDrive,
GetTempFileName, GetWindowsDirectory, GetSystemDirectory,
GetDriveType.
* [misc/int21.c]
Modified.
Wed Dec 1 16:20:45 1993 Miguel de Icaza (miguel@roxanne.nuclecu.unam.mx)
* [misc/profile.c]
The Profile functions now return the correct values. They now
implement all the features described in the SDK.
Tue Nov 30 13:55:27 1993 Bob Amstadt (bob at amscons)
* [loader/selector.c]
Rewrote selector aliasing routines to use System V IPC
routine to alias memory segments.
Nov 28, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)
* [controls/listbox.c]
More consistency in functions using wIndexes
* [controls/scroll.c]
New function : ShowScrollBar().
* [loader/cursor.c] ... New file
Move cursor functions from [loader/resource.c].
New function : ClipCursor().
New function : GetClipCursor().
New function : CreateCursor().
SetCursor() now working using gloabal variable 'winHasCursor'.
*[object/palette.c]
New stub only : SelectPalette().
New stub only : RealizePalette().
*[win/event.c]
New function : EVENT_enter_notify(),
update 'winHasCursor' and send WM_SETCURSOR.
*[win/defwnd.c]
Add processing of WM_SETCURSOR message.
*[win/win.c]
New members in WND structure : hCursor, hWndVScroll & hWndHScroll.
CreateWindowEx() now create children for WM_HSCROLL & WM_VSCROLL.
New function ClientToScreen().
New function ScreenToClient().
Mon Nov 25 18:25:40 1993 Erik Bos (erik@trashcan.hacktic.nl)
* [files.h / regfunc.h / misc/dos.c]
Removed.
* [misc/dos_fs.c]
Added support for loading dosdrive cfg from wine.ini.
* [misc/int21.c]
Modified.
Wed Nov 24 11:37:33 1993 julliard@disuns2.epfl.ch (Alexandre Julliard)
* [include/atom.h] [memory/atom.c]
Implemented atoms.
* [windows/class.c]
Modified RegisterClass() to use atoms.
Implemented CS_GLOBALCLASS style.
* [windows/message.c]
Implemented RegisterWindowMessage().
* [loader/resource.c]
Bug fix in LoadResource().
* [windows/dialog.c]
Modified CreateDialogParam() to use Find/LoadResource().
diff --git a/windows/Imakefile b/windows/Imakefile
new file mode 100644
index 0000000..b16652f
--- /dev/null
+++ b/windows/Imakefile
@@ -0,0 +1,53 @@
+#include "../Wine.tmpl"
+
+MODULE = windows
+
+SRCS = \
+ class.c \
+ dc.c \
+ dce.c \
+ event.c \
+ message.c \
+ win.c \
+ timer.c \
+ graphics.c \
+ clipping.c \
+ mapping.c \
+ painting.c \
+ keyboard.c \
+ utility.c \
+ syscolor.c \
+ defwnd.c \
+ defdlg.c \
+ dialog.c \
+ focus.c \
+ scroll.c
+
+OBJS = \
+ class.o \
+ dc.o \
+ dce.o \
+ event.o \
+ message.o \
+ win.o \
+ timer.o \
+ graphics.o \
+ clipping.o \
+ mapping.o \
+ painting.o \
+ keyboard.o \
+ utility.o \
+ syscolor.o \
+ defwnd.o \
+ defdlg.o \
+ dialog.o \
+ focus.o \
+ scroll.o
+
+WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS))
+DependTarget()
+CleanTarget()
+
+includes::
+
+install::
diff --git a/windows/Makefile b/windows/Makefile
index 0c5d34a..30570a1 100644
--- a/windows/Makefile
+++ b/windows/Makefile
@@ -2,7 +2,7 @@
OBJS=class.o dc.o dce.o event.o message.o win.o timer.o graphics.o \
clipping.o mapping.o painting.o keyboard.o utility.o syscolor.o \
- defwnd.o defdlg.o dialog.o focus.o scroll.o
+ defwnd.o defdlg.o dialog.o focus.o scroll.o caret.o winpos.o
default: windows.o
diff --git a/windows/caret.c b/windows/caret.c
new file mode 100644
index 0000000..eb78dc8
--- /dev/null
+++ b/windows/caret.c
@@ -0,0 +1,250 @@
+/*
+ * Caret functions
+ *
+ * Copyright 1993 David Metcalfe
+ */
+
+static char Copyright[] = "Copyright David Metcalfe, 1993";
+
+#include <X11/Intrinsic.h>
+
+#include "windows.h"
+
+extern XtAppContext XT_app_context;
+
+typedef struct
+{
+ HWND hwnd;
+ short hidden;
+ BOOL on;
+ short x;
+ short y;
+ short width;
+ short height;
+ COLORREF color;
+ WORD timeout;
+ XtIntervalId xtid;
+} CARET;
+
+static CARET Caret;
+static BOOL LockCaret;
+
+static void CARET_Callback(XtPointer data, XtIntervalId *xtid);
+static void CARET_HideCaret(CARET *pCaret);
+
+
+/*****************************************************************
+ * CARET_Callback
+ */
+
+static void CARET_Callback(XtPointer data, XtIntervalId *xtid)
+{
+ CARET *pCaret = (CARET *)data;
+ HDC hdc;
+ HBRUSH hBrush;
+ HRGN rgn;
+
+#ifdef DEBUG_CARET
+ printf("CARET_Callback: LockCaret=%d, hidden=%d, on=%d\n",
+ LockCaret, pCaret->hidden, pCaret->on);
+#endif
+ if (!LockCaret && (!pCaret->hidden || pCaret->on))
+ {
+ pCaret->on = (pCaret->on ? FALSE : TRUE);
+ hdc = GetDC(pCaret->hwnd);
+ hBrush = CreateSolidBrush(pCaret->color);
+ SelectObject(hdc, (HANDLE)hBrush);
+ SetROP2(hdc, R2_XORPEN);
+ rgn = CreateRectRgn(pCaret->x, pCaret->y,
+ pCaret->x + pCaret->width,
+ pCaret->y + pCaret->height);
+ FillRgn(hdc, rgn, hBrush);
+ DeleteObject((HANDLE)rgn);
+ DeleteObject((HANDLE)hBrush);
+ ReleaseDC(pCaret->hwnd, hdc);
+ }
+
+ pCaret->xtid = XtAppAddTimeOut(XT_app_context, pCaret->timeout,
+ CARET_Callback, pCaret);
+}
+
+
+/*****************************************************************
+ * CARET_HideCaret
+ */
+
+static void CARET_HideCaret(CARET *pCaret)
+{
+ HDC hdc;
+ HBRUSH hBrush;
+ HRGN rgn;
+
+ pCaret->on = FALSE;
+ hdc = GetDC(pCaret->hwnd);
+ hBrush = CreateSolidBrush(pCaret->color);
+ SelectObject(hdc, (HANDLE)hBrush);
+ SetROP2(hdc, R2_XORPEN);
+ rgn = CreateRectRgn(pCaret->x, pCaret->y,
+ pCaret->x + pCaret->width,
+ pCaret->y + pCaret->height);
+ FillRgn(hdc, rgn, hBrush);
+ DeleteObject((HANDLE)rgn);
+ DeleteObject((HANDLE)hBrush);
+ ReleaseDC(pCaret->hwnd, hdc);
+}
+
+
+/*****************************************************************
+ * CreateCaret (USER.163)
+ */
+
+void CreateCaret(HWND hwnd, HBITMAP bitmap, short width, short height)
+{
+ if (!hwnd) return;
+
+ /* if cursor already exists, destroy it */
+/* if (Caret.hwnd)
+ DestroyCaret();
+*/
+ if (bitmap)
+ {
+ printf("CreateCaret: Bitmaps are currently not supported\n");
+ return;
+ }
+
+ if (width)
+ Caret.width = width;
+ else
+ Caret.width = 3; /* should be SM_CXBORDER */
+
+ if (height)
+ Caret.height = height;
+ else
+ Caret.height = 3; /* should be SM_CYBORDER */
+
+ Caret.hwnd = hwnd;
+ Caret.hidden = 1;
+ Caret.on = FALSE;
+ Caret.x = 0;
+ Caret.y = 0;
+ Caret.color = GetSysColor(COLOR_WINDOWTEXT);
+ Caret.timeout = 750;
+ LockCaret = FALSE;
+
+ Caret.xtid = XtAppAddTimeOut(XT_app_context, Caret.timeout,
+ CARET_Callback, &Caret);
+}
+
+
+/*****************************************************************
+ * DestroyCaret (USER.164)
+ */
+
+void DestroyCaret()
+{
+/* if (!Caret.hwnd) return;
+*/
+ XtRemoveTimeOut(Caret.xtid);
+
+ if (Caret.on)
+ CARET_HideCaret(&Caret);
+
+ Caret.hwnd = 0; /* cursor marked as not existing */
+}
+
+
+/*****************************************************************
+ * SetCaretPos (USER.165)
+ */
+
+void SetCaretPos(short x, short y)
+{
+ HDC hdc;
+ HBRUSH hBrush;
+ HRGN rgn;
+
+ if (!Caret.hwnd) return;
+
+#ifdef DEBUG_CARET
+ printf("SetCaretPos: x=%d, y=%d\n", x, y);
+#endif
+
+ LockCaret = TRUE;
+ if (Caret.on)
+ CARET_HideCaret(&Caret);
+
+ Caret.x = x;
+ Caret.y = y;
+ LockCaret = FALSE;
+}
+
+/*****************************************************************
+ * HideCaret (USER.166)
+ */
+
+void HideCaret(HWND hwnd)
+{
+ if (!Caret.hwnd) return;
+ if (hwnd && (Caret.hwnd != hwnd)) return;
+
+ LockCaret = TRUE;
+ if (Caret.on)
+ CARET_HideCaret(&Caret);
+
+ ++Caret.hidden;
+ LockCaret = FALSE;
+}
+
+
+/*****************************************************************
+ * ShowCaret (USER.167)
+ */
+
+void ShowCaret(HWND hwnd)
+{
+ if (!Caret.hwnd) return;
+ if (hwnd && (Caret.hwnd != hwnd)) return;
+
+#ifdef DEBUG_CARET
+ printf("ShowCaret: hidden=%d\n", Caret.hidden);
+#endif
+ if (Caret.hidden)
+ --Caret.hidden;
+}
+
+
+/*****************************************************************
+ * SetCaretBlinkTime (USER.168)
+ */
+
+void SetCaretBlinkTime(WORD msecs)
+{
+ if (!Caret.hwnd) return;
+
+ Caret.timeout = msecs;
+}
+
+
+/*****************************************************************
+ * GetCaretBlinkTime (USER.169)
+ */
+
+WORD GetCaretBlinkTime()
+{
+ if (!Caret.hwnd) return;
+
+ return Caret.timeout;
+}
+
+
+/*****************************************************************
+ * GetCaretPos (USER.183)
+ */
+
+void GetCaretPos(LPPOINT pt)
+{
+ if (!Caret.hwnd || !pt) return;
+
+ pt->x = Caret.x;
+ pt->y = Caret.y;
+}
diff --git a/windows/class.c b/windows/class.c
index 23a2c49..4ca2d9f 100644
--- a/windows/class.c
+++ b/windows/class.c
@@ -9,6 +9,7 @@
#include "class.h"
#include "user.h"
#include "win.h"
+#include "dce.h"
static HCLASS firstClass = 0;
@@ -18,19 +19,50 @@
* CLASS_FindClassByName
*
* Return a handle and a pointer to the class.
+ * 'ptr' can be NULL if the pointer is not needed.
*/
HCLASS CLASS_FindClassByName( char * name, CLASS **ptr )
{
- HCLASS class = firstClass;
- while(class)
+ ATOM atom;
+ HCLASS class;
+ CLASS * classPtr;
+
+ /* First search task-specific classes */
+
+ if ((atom = FindAtom( name )) != 0)
{
- *ptr = (CLASS *) USER_HEAP_ADDR(class);
- if (!strcasecmp( (*ptr)->wc.lpszClassName, name )) return class;
- class = (*ptr)->hNext;
+ for (class = firstClass; (class); class = classPtr->hNext)
+ {
+ classPtr = (CLASS *) USER_HEAP_ADDR(class);
+ if (classPtr->wc.style & CS_GLOBALCLASS) continue;
+ if (classPtr->atomName == atom)
+ {
+ if (ptr) *ptr = classPtr;
+ return class;
+ }
+ }
}
+
+ /* Then search global classes */
+
+ if ((atom = GlobalFindAtom( name )) != 0)
+ {
+ for (class = firstClass; (class); class = classPtr->hNext)
+ {
+ classPtr = (CLASS *) USER_HEAP_ADDR(class);
+ if (!(classPtr->wc.style & CS_GLOBALCLASS)) continue;
+ if (classPtr->atomName == atom)
+ {
+ if (ptr) *ptr = classPtr;
+ return class;
+ }
+ }
+ }
+
return 0;
}
+
/***********************************************************************
* CLASS_FindClassPtr
*
@@ -52,37 +84,50 @@
*/
ATOM RegisterClass( LPWNDCLASS class )
{
- CLASS * newClass;
- HCLASS handle;
+ CLASS * newClass, * prevClassPtr;
+ HCLASS handle, prevClass;
#ifdef DEBUG_CLASS
printf( "RegisterClass: wndproc=%08x hinst=%d name='%s'\n",
class->lpfnWndProc, class->hInstance, class->lpszClassName );
#endif
+ /* Check if a class with this name already exists */
+
+ prevClass = CLASS_FindClassByName( class->lpszClassName, &prevClassPtr );
+ if (prevClass)
+ {
+ /* Class can be created only if it is local and */
+ /* if the class with the same name is global. */
+
+ if (class->style & CS_GLOBALCLASS) return 0;
+ if (!(prevClassPtr->wc.style & CS_GLOBALCLASS)) return 0;
+ }
+
+ /* Create class */
+
handle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(CLASS)+class->cbClsExtra );
if (!handle) return 0;
newClass = (CLASS *) USER_HEAP_ADDR( handle );
newClass->hNext = firstClass;
newClass->wMagic = CLASS_MAGIC;
- newClass->atomName = handle; /* Should be an atom */
newClass->cWindows = 0;
newClass->wc = *class;
- if (newClass->wc.style & CS_CLASSDC)
- newClass->hdc = CreateDC( "DISPLAY", NULL, NULL, NULL );
- else newClass->hdc = 0;
+ if (newClass->wc.style & CS_GLOBALCLASS)
+ newClass->atomName = GlobalAddAtom( class->lpszClassName );
+ else newClass->atomName = AddAtom( class->lpszClassName );
- /* Class name should also be set to zero. For now we need the
- * name because we don't have atoms.
- */
- newClass->wc.lpszClassName = (char *)malloc(strlen(class->lpszClassName)+1);
- strcpy( newClass->wc.lpszClassName, class->lpszClassName );
+ if (newClass->wc.style & CS_CLASSDC)
+ newClass->hdce = DCE_AllocDCE( DCE_CLASS_DC );
+ else newClass->hdce = 0;
+
+ /* Menu name should also be set to zero. */
+ newClass->wc.lpszClassName = NULL;
if (class->cbClsExtra) memset( newClass->wExtra, 0, class->cbClsExtra );
-
firstClass = handle;
- return handle; /* Should be an atom */
+ return newClass->atomName;
}
@@ -118,8 +163,10 @@
}
/* Delete the class */
- if (classPtr->hdc) DeleteDC( classPtr->hdc );
+ if (classPtr->hdce) DCE_FreeDCE( classPtr->hdce );
if (classPtr->wc.hbrBackground) DeleteObject( classPtr->wc.hbrBackground );
+ if (classPtr->wc.style & CS_GLOBALCLASS) GlobalDeleteAtom( classPtr->atomName );
+ else DeleteAtom( classPtr->atomName );
USER_HEAP_FREE( class );
return TRUE;
}
@@ -182,3 +229,34 @@
*ptr = newval;
return retval;
}
+
+
+/***********************************************************************
+ * GetClassName (USER.58)
+ */
+int GetClassName(HWND hwnd, LPSTR lpClassName, short maxCount)
+{
+ WND *wndPtr;
+ CLASS *classPtr;
+
+ if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
+ if (!(classPtr = CLASS_FindClassPtr(wndPtr->hClass))) return 0;
+
+ return (GetAtomName(classPtr->atomName, lpClassName, maxCount));
+}
+
+
+/***********************************************************************
+ * GetClassInfo (USER.404)
+ */
+BOOL GetClassInfo(HANDLE hInstance, LPSTR lpClassName,
+ LPWNDCLASS lpWndClass)
+{
+ CLASS *classPtr;
+
+ if (!(CLASS_FindClassByName(lpClassName, &classPtr))) return FALSE;
+ if (hInstance && (hInstance != classPtr->wc.hInstance)) return FALSE;
+
+ memcpy(lpWndClass, &(classPtr->wc), sizeof(WNDCLASS));
+ return TRUE;
+}
diff --git a/windows/clipping.c b/windows/clipping.c
index 2126c28..3c759a6 100644
--- a/windows/clipping.c
+++ b/windows/clipping.c
@@ -10,6 +10,7 @@
#include "windows.h"
#include "win.h"
+#include "message.h"
/***********************************************************************
@@ -34,6 +35,7 @@
else CombineRgn( newRgn, wndPtr->hrgnUpdate, hrgn, RGN_OR );
}
if (wndPtr->hrgnUpdate) DeleteObject( wndPtr->hrgnUpdate );
+ else MSG_IncPaintCount( wndPtr->hmemTaskQ );
wndPtr->hrgnUpdate = newRgn;
if (erase) wndPtr->flags |= WIN_ERASE_UPDATERGN;
}
@@ -112,17 +114,14 @@
if (rect)
{
- if (wndPtr->hrgnUpdate) GetRgnBox( wndPtr->hrgnUpdate, rect );
- else SetRectEmpty( rect );
- if (erase && wndPtr->hrgnUpdate)
+ if (wndPtr->hrgnUpdate)
{
- HDC hdc = GetDC( hwnd );
- if (hdc)
- {
- SendMessage( hwnd, WM_ERASEBKGND, hdc, 0 );
- ReleaseDC( hwnd, hdc );
- }
+ HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
+ if (GetUpdateRgn( hwnd, hrgn, erase ) == ERROR) return FALSE;
+ GetRgnBox( hrgn, rect );
+ DeleteObject( hrgn );
}
+ else SetRectEmpty( rect );
}
return (wndPtr->hrgnUpdate != 0);
}
@@ -133,17 +132,34 @@
*/
int GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
{
+ HRGN hrgnClip;
+ int retval;
WND * wndPtr = WIN_FindWndPtr( hwnd );
if (!wndPtr) return ERROR;
- if (erase && wndPtr->hrgnUpdate)
+ if (!wndPtr->hrgnUpdate)
{
- HDC hdc = GetDC( hwnd );
- if (hdc)
- {
- SendMessage( hwnd, WM_ERASEBKGND, hdc, 0 );
- ReleaseDC( hwnd, hdc );
- }
+ if (!(hrgnClip = CreateRectRgn( 0, 0, 0, 0 ))) return ERROR;
+ retval = CombineRgn( hrgn, hrgnClip, 0, RGN_COPY );
}
- return CombineRgn( hrgn, wndPtr->hrgnUpdate, 0, RGN_COPY );
+ else
+ {
+ hrgnClip = CreateRectRgn( 0, 0,
+ wndPtr->rectClient.right-wndPtr->rectClient.left,
+ wndPtr->rectClient.bottom-wndPtr->rectClient.top );
+ if (!hrgnClip) return ERROR;
+ retval = CombineRgn( hrgn, wndPtr->hrgnUpdate, hrgnClip, RGN_AND );
+ if (erase)
+ {
+ HDC hdc = GetDCEx( hwnd, wndPtr->hrgnUpdate,
+ DCX_INTERSECTRGN | DCX_USESTYLE );
+ if (hdc)
+ {
+ SendMessage( hwnd, WM_ERASEBKGND, hdc, 0 );
+ ReleaseDC( hwnd, hdc );
+ }
+ }
+ }
+ DeleteObject( hrgnClip );
+ return retval;
}
diff --git a/windows/dc.c b/windows/dc.c
index 1a65b41..4224b3a 100644
--- a/windows/dc.c
+++ b/windows/dc.c
@@ -7,7 +7,6 @@
static char Copyright[] = "Copyright Alexandre Julliard, 1993";
#include <stdlib.h>
-#include <X11/Intrinsic.h>
#include "gdi.h"
@@ -17,6 +16,8 @@
extern const WIN_DC_INFO DCVAL_defaultValues;
+extern void CLIPPING_SetDeviceClipping( DC * dc ); /* in objects/clipping.c */
+
/* ROP code to GC function conversion */
const int DC_XROPfunction[16] =
@@ -100,18 +101,8 @@
SelectObject( hdc, dc->w.hBrush );
SelectObject( hdc, dc->w.hFont );
- if (dc->w.hGCClipRgn)
- {
- RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr(dc->w.hGCClipRgn, REGION_MAGIC);
- XSetClipMask( XT_display, dc->u.x.gc, obj->region.pixmap );
- XSetClipOrigin( XT_display, dc->u.x.gc,
- obj->region.box.left, obj->region.box.top );
- }
- else
- {
- XSetClipMask( XT_display, dc->u.x.gc, None );
- XSetClipOrigin( XT_display, dc->u.x.gc, 0, 0 );
- }
+ XSetGraphicsExposures( XT_display, dc->u.x.gc, False );
+ CLIPPING_SetDeviceClipping( dc );
}
@@ -145,8 +136,11 @@
XSetFillStyle( XT_display, dc->u.x.gc,
(dc->w.backgroundMode == OPAQUE) ?
FillOpaqueStippled : FillStippled );
- XSetTSOrigin( XT_display, dc->u.x.gc, dc->w.brushOrgX, dc->w.brushOrgY );
+ XSetTSOrigin( XT_display, dc->u.x.gc, dc->w.DCOrgX + dc->w.brushOrgX,
+ dc->w.DCOrgY + dc->w.brushOrgY );
XSetFunction( XT_display, dc->u.x.gc, DC_XROPfunction[dc->w.ROPmode-1] );
+ XSetFillRule( XT_display, dc->u.x.gc,
+ (dc->w.polyFillMode == WINDING) ? WindingRule : EvenOddRule );
return 1;
}
@@ -226,8 +220,7 @@
if (dc->w.hVisRgn)
{
newdc->w.hVisRgn = CreateRectRgn( 0, 0, 0, 0 );
- CombineRgn( newdc->w.hVisRgn, dc->w.hVisRgn, 0, RGN_COPY );
-
+ CombineRgn( newdc->w.hVisRgn, dc->w.hVisRgn, 0, RGN_COPY );
}
newdc->w.hGCClipRgn = 0;
return handle;
@@ -255,7 +248,7 @@
dc->w.flags &= ~DC_SAVED;
DC_SetDeviceInfo( hdc, dc );
SelectClipRgn( hdc, dcs->w.hClipRgn );
- SelectVisRgn( hdc, dcs->w.hGCClipRgn );
+ SelectVisRgn( hdc, dcs->w.hVisRgn );
}
@@ -337,6 +330,8 @@
dc->w.devCaps = displayDevCaps;
dc->w.planes = displayDevCaps->planes;
dc->w.bitsPerPixel = displayDevCaps->bitsPixel;
+ dc->w.DCSizeX = displayDevCaps->horzRes;
+ dc->w.DCSizeY = displayDevCaps->vertRes;
DC_SetDeviceInfo( handle, dc );
@@ -372,6 +367,8 @@
dc->w.planes = 1;
dc->w.bitsPerPixel = 1;
dc->w.devCaps = displayDevCaps;
+ dc->w.DCSizeX = 1;
+ dc->w.DCSizeY = 1;
SelectObject( handle, BITMAP_hbitmapMemDC );
DC_SetDeviceInfo( handle, dc );
diff --git a/windows/dce.c b/windows/dce.c
index aaea4b0..7b24f1d 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -23,6 +23,53 @@
/***********************************************************************
+ * DCE_AllocDCE
+ *
+ * Allocate a new DCE.
+ */
+HANDLE DCE_AllocDCE( DCE_TYPE type )
+{
+ DCE * dce;
+ HANDLE handle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(DCE) );
+ if (!handle) return 0;
+ dce = (DCE *) USER_HEAP_ADDR( handle );
+ if (!(dce->hdc = CreateDC( "DISPLAY", NULL, NULL, NULL )))
+ {
+ USER_HEAP_FREE( handle );
+ return 0;
+ }
+ dce->hwndCurrent = 0;
+ dce->type = type;
+ dce->inUse = (type != DCE_CACHE_DC);
+ dce->xOrigin = 0;
+ dce->yOrigin = 0;
+ dce->hNext = firstDCE;
+ firstDCE = handle;
+ return handle;
+}
+
+
+/***********************************************************************
+ * DCE_FreeDCE
+ */
+void DCE_FreeDCE( HANDLE hdce )
+{
+ DCE * dce;
+ HANDLE *handle = &firstDCE;
+
+ if (!(dce = (DCE *) USER_HEAP_ADDR( hdce ))) return;
+ while (*handle && (*handle != hdce))
+ {
+ DCE * prev = (DCE *) USER_HEAP_ADDR( *handle );
+ handle = &prev->hNext;
+ }
+ if (*handle == hdce) *handle = dce->hNext;
+ DeleteDC( dce->hdc );
+ USER_HEAP_FREE( hdce );
+}
+
+
+/***********************************************************************
* DCE_Init
*/
void DCE_Init()
@@ -33,84 +80,133 @@
for (i = 0; i < NB_DCE; i++)
{
- handle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(DCE) );
- if (!handle) return;
- dce = (DCE *) USER_HEAP_ADDR( handle );
- dce->hdc = CreateDC( "DISPLAY", NULL, NULL, NULL );
- if (!dce->hdc)
- {
- USER_HEAP_FREE( handle );
- return;
- }
- dce->hwndCurrent = 0;
- dce->flags = 0;
- dce->inUse = FALSE;
- dce->xOrigin = 0;
- dce->yOrigin = 0;
- dce->hNext = firstDCE;
- firstDCE = handle;
+ if (!(handle = DCE_AllocDCE( DCE_CACHE_DC ))) return;
+ dce = (DCE *) USER_HEAP_ADDR( handle );
if (!defaultDCstate) defaultDCstate = GetDCState( dce->hdc );
}
}
/***********************************************************************
+ * GetDCEx (USER.359)
+ */
+/* Unimplemented flags: DCX_CLIPSIBLINGS, DCX_LOCKWINDOWUPDATE, DCX_PARENTCLIP
+ */
+HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
+{
+ HANDLE hdce;
+ HDC hdc = 0;
+ DCE * dce;
+ DC * dc;
+ WND * wndPtr;
+
+ if (hwnd)
+ {
+ if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
+ }
+ else wndPtr = NULL;
+
+ if (flags & DCX_USESTYLE)
+ {
+ /* Not sure if this is the real meaning of the DCX_USESTYLE flag... */
+ flags &= ~(DCX_CACHE | DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS);
+ if (wndPtr)
+ {
+ if (!(wndPtr->flags & (WIN_CLASS_DC | WIN_OWN_DC)))
+ flags |= DCX_CACHE;
+ if (wndPtr->dwStyle & WS_CLIPCHILDREN) flags |= DCX_CLIPCHILDREN;
+ if (wndPtr->dwStyle & WS_CLIPSIBLINGS) flags |= DCX_CLIPSIBLINGS;
+ }
+ else flags |= DCX_CACHE;
+ }
+
+ if (flags & DCX_CACHE)
+ {
+ for (hdce = firstDCE; (hdce); hdce = dce->hNext)
+ {
+ if (!(dce = (DCE *) USER_HEAP_ADDR( hdce ))) return 0;
+ if ((dce->type == DCE_CACHE_DC) && (!dce->inUse)) break;
+ }
+ }
+ else hdce = wndPtr->hdce;
+
+ if (!hdce) return 0;
+ dce = (DCE *) USER_HEAP_ADDR( hdce );
+ dce->hwndCurrent = hwnd;
+ dce->inUse = TRUE;
+ hdc = dce->hdc;
+
+ /* Initialize DC */
+
+ if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
+
+ if (wndPtr)
+ {
+ dc->u.x.drawable = wndPtr->window;
+ if (flags & DCX_WINDOW)
+ {
+ dc->w.DCOrgX = 0;
+ dc->w.DCOrgY = 0;
+ dc->w.DCSizeX = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
+ dc->w.DCSizeY = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
+ }
+ else
+ {
+ dc->w.DCOrgX = wndPtr->rectClient.left - wndPtr->rectWindow.left;
+ dc->w.DCOrgY = wndPtr->rectClient.top - wndPtr->rectWindow.top;
+ dc->w.DCSizeX = wndPtr->rectClient.right - wndPtr->rectClient.left;
+ dc->w.DCSizeY = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
+ IntersectVisRect( hdc, 0, 0, dc->w.DCSizeX, dc->w.DCSizeY );
+ }
+ }
+ else dc->u.x.drawable = DefaultRootWindow( XT_display );
+
+ if (flags & DCX_CLIPCHILDREN)
+ XSetSubwindowMode( XT_display, dc->u.x.gc, ClipByChildren );
+ else XSetSubwindowMode( XT_display, dc->u.x.gc, IncludeInferiors);
+
+ if ((flags & DCX_INTERSECTRGN) || (flags & DCX_EXCLUDERGN))
+ {
+ HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
+ if (hrgn)
+ {
+ if (CombineRgn( hrgn, InquireVisRgn(hdc), hrgnClip,
+ (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF ))
+ SelectVisRgn( hdc, hrgn );
+ DeleteObject( hrgn );
+ }
+ }
+
+#ifdef DEBUG_DC
+ printf( "GetDCEx(%d,%d,0x%x): returning %d\n", hwnd, hrgnClip, flags, hdc);
+#endif
+ return hdc;
+}
+
+
+/***********************************************************************
* GetDC (USER.66)
*/
HDC GetDC( HWND hwnd )
{
- HANDLE hdce;
- HDC hdc = 0;
- DCE * dce;
- DC * dc;
- WND * wndPtr = NULL;
- CLASS * classPtr;
-
+ return GetDCEx( hwnd, 0, DCX_USESTYLE );
+}
+
+
+/***********************************************************************
+ * GetWindowDC (USER.67)
+ */
+HDC GetWindowDC( HWND hwnd )
+{
+ int flags = DCX_CACHE | DCX_WINDOW;
if (hwnd)
{
+ WND * wndPtr;
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
- if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
- if (wndPtr->hdc) hdc = wndPtr->hdc;
- else if (classPtr->hdc) hdc = classPtr->hdc;
+ if (wndPtr->dwStyle & WS_CLIPCHILDREN) flags |= DCX_CLIPCHILDREN;
+ if (wndPtr->dwStyle & WS_CLIPSIBLINGS) flags |= DCX_CLIPSIBLINGS;
}
-
- if (!hdc)
- {
- for (hdce = firstDCE; (hdce); hdce = dce->hNext)
- {
- dce = (DCE *) USER_HEAP_ADDR( hdce );
- if (!dce) return 0;
- if (!dce->inUse) break;
- }
- if (!hdce) return 0;
- dce->hwndCurrent = hwnd;
- dce->inUse = TRUE;
- hdc = dce->hdc;
- }
-
- /* Initialize DC */
-
- if (!(dc = (DC *) GDI_GetObjPtr( dce->hdc, DC_MAGIC ))) return 0;
-
- if (wndPtr)
- {
- dc->u.x.drawable = XtWindow( wndPtr->winWidget );
- dc->u.x.widget = wndPtr->winWidget;
- if (wndPtr->dwStyle & WS_CLIPCHILDREN)
- XSetSubwindowMode( XT_display, dc->u.x.gc, ClipByChildren );
- else XSetSubwindowMode( XT_display, dc->u.x.gc, IncludeInferiors);
- }
- else
- {
- dc->u.x.drawable = DefaultRootWindow( XT_display );
- dc->u.x.widget = 0;
- XSetSubwindowMode( XT_display, dc->u.x.gc, IncludeInferiors );
- }
-
-#ifdef DEBUG_WIN
- printf( "GetDC(%d): returning %d\n", hwnd, hdc );
-#endif
- return hdc;
+ return GetDCEx( hwnd, 0, flags );
}
@@ -119,33 +215,23 @@
*/
int ReleaseDC( HWND hwnd, HDC hdc )
{
- HANDLE hdce, next;
+ HANDLE hdce;
DCE * dce;
- WND * wndPtr = NULL;
- CLASS * classPtr;
-#ifdef DEBUG_WIN
+#ifdef DEBUG_DC
printf( "ReleaseDC: %d %d\n", hwnd, hdc );
#endif
- if (hwnd)
- {
- if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
- if (wndPtr->hdc && (wndPtr->hdc == hdc)) return 1;
- if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
- if (classPtr->hdc && (classPtr->hdc == hdc)) return 1;
- }
-
for (hdce = firstDCE; (hdce); hdce = dce->hNext)
{
if (!(dce = (DCE *) USER_HEAP_ADDR( hdce ))) return 0;
if (dce->inUse && (dce->hdc == hdc)) break;
}
- if (hdce)
+ if (dce->type == DCE_CACHE_DC)
{
SetDCState( dce->hdc, defaultDCstate );
dce->inUse = FALSE;
- }
+ }
return (hdce != 0);
}
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 3d3a280..e2f9a39 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -6,24 +6,27 @@
static char Copyright[] = "Copyright Alexandre Julliard, 1993";
+#ifndef USE_XLIB
#include <X11/Intrinsic.h>
#include <X11/Shell.h>
+#endif
#include "windows.h"
#include "win.h"
#include "class.h"
#include "user.h"
+extern Display * XT_display;
/***********************************************************************
* DefWindowProc (USER.107)
*/
LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam )
{
- WND * wndPtr;
CLASS * classPtr;
LPSTR textPtr;
int len;
+ WND * wndPtr = WIN_FindWndPtr( hwnd );
#ifdef DEBUG_MESSAGE
printf( "DefWindowProc: %d %d %d %08x\n", hwnd, msg, wParam, lParam );
@@ -34,24 +37,57 @@
case WM_NCCREATE:
{
CREATESTRUCT * createStruct = (CREATESTRUCT *)lParam;
- wndPtr = WIN_FindWndPtr(hwnd);
if (createStruct->lpszName)
{
/* Allocate space for window text */
wndPtr->hText = USER_HEAP_ALLOC(GMEM_MOVEABLE,
- strlen(createStruct->lpszName) + 1);
+ strlen(createStruct->lpszName) + 2);
textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText);
strcpy(textPtr, createStruct->lpszName);
+ *(textPtr + strlen(createStruct->lpszName) + 1) = '\0';
+ /* for use by edit control */
}
return 1;
}
+
+ case WM_NCCALCSIZE:
+ {
+#ifdef USE_XLIB
+ NCCALCSIZE_PARAMS *params = (NCCALCSIZE_PARAMS *)lParam;
+ if (wndPtr->dwStyle & WS_CHILD)
+ {
+ if (wndPtr->dwStyle & WS_BORDER)
+ {
+ params->rgrc[0].left += 1; /* SM_CXBORDER */
+ params->rgrc[0].top += 1; /* SM_CYBORDER */
+ params->rgrc[0].right -= 1; /* SM_CXBORDER */
+ params->rgrc[0].bottom -= 1; /* SM_CYBORDER */
+ }
+ }
+ else
+ {
+ params->rgrc[0].left += 4; /* SM_CXFRAME */
+ params->rgrc[0].top += 30; /* SM_CYFRAME+SM_CYCAPTION */
+ params->rgrc[0].right -= 4; /* SM_CXFRAME */
+ params->rgrc[0].bottom -= 4; /* SM_CYFRAME */
+ if (wndPtr->dwStyle & WS_VSCROLL)
+ {
+ params->rgrc[0].right -= 16; /* SM_CXVSCROLL */
+ }
+ if (wndPtr->dwStyle & WS_HSCROLL)
+ {
+ params->rgrc[0].bottom += 16; /* SM_CYHSCROLL */
+ }
+ }
+#endif
+ return 0;
+ }
case WM_CREATE:
return 0;
case WM_NCDESTROY:
{
- wndPtr = WIN_FindWndPtr(hwnd);
if (wndPtr->hText) USER_HEAP_FREE(wndPtr->hText);
wndPtr->hText = 0;
return 0;
@@ -69,10 +105,23 @@
DestroyWindow( hwnd );
return 0;
+ case WM_WINDOWPOSCHANGED:
+ {
+ WINDOWPOS * winPos = (WINDOWPOS *)lParam;
+ if (!(winPos->flags & SWP_NOMOVE))
+ SendMessage( hwnd, WM_MOVE, 0,
+ MAKELONG( wndPtr->rectClient.left,
+ wndPtr->rectClient.top ));
+ if (!(winPos->flags & SWP_NOSIZE))
+ SendMessage( hwnd, WM_SIZE, SIZE_RESTORED,
+ MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
+ wndPtr->rectClient.bottom-wndPtr->rectClient.top));
+ return 0;
+ }
+
case WM_ERASEBKGND:
case WM_ICONERASEBKGND:
{
- if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 1;
if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 1;
if (!classPtr->wc.hbrBackground) return 1;
FillWindow( GetParent(hwnd), hwnd, (HDC)wParam,
@@ -106,7 +155,6 @@
{
if (wParam)
{
- wndPtr = WIN_FindWndPtr(hwnd);
if (wndPtr->hText)
{
textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText);
@@ -123,7 +171,6 @@
case WM_GETTEXTLENGTH:
{
- wndPtr = WIN_FindWndPtr(hwnd);
if (wndPtr->hText)
{
textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText);
@@ -134,7 +181,6 @@
case WM_SETTEXT:
{
- wndPtr = WIN_FindWndPtr(hwnd);
if (wndPtr->hText)
USER_HEAP_FREE(wndPtr->hText);
@@ -142,10 +188,18 @@
strlen((LPSTR)lParam) + 1);
textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText);
strcpy(textPtr, (LPSTR)lParam);
+#ifdef USE_XLIB
+ XStoreName( XT_display, wndPtr->window, textPtr );
+#else
if (wndPtr->shellWidget)
XtVaSetValues( wndPtr->shellWidget, XtNtitle, textPtr, NULL );
+#endif
return (0L);
}
+ case WM_SETCURSOR:
+ if (wndPtr->hCursor != (HCURSOR)NULL)
+ SetCursor(wndPtr->hCursor);
+ return 0L;
}
return 0;
}
diff --git a/windows/dialog.c b/windows/dialog.c
index 108c964..83a0389 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -8,7 +8,6 @@
#include "windows.h"
#include "dialog.h"
-#include "prototypes.h"
#include "win.h"
@@ -149,25 +148,19 @@
HWND hwnd = 0;
HANDLE hres, hmem;
LPCSTR data;
- int size;
#ifdef DEBUG_DIALOG
printf( "CreateDialogParam: %d,'%s',%d,%p,%d\n",
hInst, dlgTemplate, owner, dlgProc, param );
#endif
-
-#if 0
- if (!(hres = FindResource( hInst, dlgTemplate, RT_DIALOG ))) return 0;
+
+ /* FIXME: MAKEINTRESOURCE should be replaced by RT_DIALOG */
+ if (!(hres = FindResource( hInst, dlgTemplate, MAKEINTRESOURCE(0x8005) )))
+ return 0;
if (!(hmem = LoadResource( hInst, hres ))) return 0;
if (!(data = LockResource( hmem ))) hwnd = 0;
else hwnd = CreateDialogIndirectParam(hInst, data, owner, dlgProc, param);
FreeResource( hmem );
-#else
- hmem = RSC_LoadResource( hInst, dlgTemplate, NE_RSCTYPE_DIALOG, &size );
- data = (LPCSTR) GlobalLock( hmem );
- hwnd = CreateDialogIndirectParam( hInst, data, owner, dlgProc, param );
- GlobalFree( hmem );
-#endif
return hwnd;
}
@@ -314,8 +307,8 @@
if (dlgInfo->hUserFont)
SendMessage( hwnd, WM_SETFONT, dlgInfo->hUserFont, 0);
SendMessage( hwnd, WM_INITDIALOG, dlgInfo->hwndFocus, param );
- if (SendMessage( hwnd, WM_INITDIALOG, dlgInfo->hwndFocus, param ))
- SetFocus( dlgInfo->hwndFocus );
+/* if (SendMessage( hwnd, WM_INITDIALOG, dlgInfo->hwndFocus, param ))
+ SetFocus( dlgInfo->hwndFocus ); */
return hwnd;
}
diff --git a/windows/event.c b/windows/event.c
index 3130189..5f3aa3d 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -18,6 +18,8 @@
#define NB_BUTTONS 3 /* Windows can handle 3 buttons */
static WORD dblclick_time = 300; /* Max. time for a double click (milliseconds) */
+extern Display * XT_display;
+
/* Event handlers */
static void EVENT_expose();
static void EVENT_key();
@@ -25,17 +27,175 @@
static void EVENT_mouse_button();
static void EVENT_structure();
static void EVENT_focus_change();
+static void EVENT_enter_notify();
+
+ /* X context to associate a hwnd to an X window */
+static XContext winContext = 0;
/* State variables */
static HWND captureWnd = 0;
-
+Window winHasCursor = 0;
extern HWND hWndFocus;
+/* Keyboard translation tables */
+static int special_key[] =
+{
+ VK_BACK, VK_TAB, 0, VK_CLEAR, 0, VK_RETURN, 0, 0, /* FF08 */
+ 0, 0, 0, VK_PAUSE, VK_SCROLL, 0, 0, 0, /* FF10 */
+ 0, 0, 0, VK_ESCAPE /* FF18 */
+};
+
+static cursor_key[] =
+{
+ VK_HOME, VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN, VK_PRIOR,
+ VK_NEXT, VK_END /* FF50 */
+};
+
+static misc_key[] =
+{
+ VK_SELECT, VK_SNAPSHOT, VK_EXECUTE, VK_INSERT, 0, 0, 0, 0, /* FF60 */
+ VK_CANCEL, VK_HELP, VK_CANCEL, VK_MENU /* FF68 */
+};
+
+static keypad_key[] =
+{
+ VK_MENU, VK_NUMLOCK, /* FF7E */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* FF80 */
+ 0, 0, 0, 0, 0, VK_RETURN, 0, 0, /* FF88 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* FF90 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* FF98 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* FFA0 */
+ 0, 0, VK_MULTIPLY, VK_ADD, VK_SEPARATOR, VK_SUBTRACT,
+ VK_DECIMAL, VK_DIVIDE, /* FFA8 */
+ VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD4,
+ VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7, /* FFB0 */
+ VK_NUMPAD8, VK_NUMPAD9 /* FFB8 */
+};
+
+static function_key[] =
+{
+ VK_F1, VK_F2, /* FFBE */
+ VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_F10, /* FFC0 */
+ VK_F11, VK_F12, VK_F13, VK_F14, VK_F15, VK_F16 /* FFC8 */
+};
+
+static modifier_key[] =
+{
+ VK_SHIFT, VK_SHIFT, VK_CONTROL, VK_CONTROL, VK_CAPITAL,
+ 0, 0, /* FFE1 */
+ 0, VK_MENU, VK_MENU /* FFE8 */
+};
+
+typedef union
+{
+ struct
+ {
+ unsigned long count : 16;
+ unsigned long code : 8;
+ unsigned long extended : 1;
+ unsigned long : 4;
+ unsigned long context : 1;
+ unsigned long previous : 1;
+ unsigned long transition : 1;
+ } lp1;
+ unsigned long lp2;
+} KEYLP;
+
+static BOOL KeyDown = FALSE;
+
+
+#ifdef DEBUG_EVENT
+static char *event_names[] =
+{
+ "", "", "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease",
+ "MotionNotify", "EnterNotify", "LeaveNotify", "FocusIn", "FocusOut",
+ "KeymapNotify", "Expose", "GraphicsExpose", "NoExpose", "VisibilityNotify",
+ "CreateNotify", "DestroyNotify", "UnmapNotify", "MapNotify", "MapRequest",
+ "ReparentNotify", "ConfigureNotify", "ConfigureRequest", "GravityNotify",
+ "ResizeRequest", "CirculateNotify", "CirculateRequest", "PropertyNotify",
+ "SelectionClear", "SelectionRequest", "SelectionNotify", "ColormapNotify",
+ "ClientMessage", "MappingNotify"
+};
+#endif
+
+
+/***********************************************************************
+ * EVENT_ProcessEvent
+ *
+ * Process an X event.
+ */
+void EVENT_ProcessEvent( XEvent *event )
+{
+ HWND hwnd;
+ XPointer ptr;
+ Boolean cont_dispatch = TRUE;
+
+ XFindContext( XT_display, ((XAnyEvent *)event)->window, winContext, &ptr );
+ hwnd = (HWND)ptr & 0xffff;
+
+#ifdef DEBUG_EVENT
+ printf( "Got event %s for hwnd %d\n",
+ event_names[event->type], hwnd );
+#endif
+
+ switch(event->type)
+ {
+ case Expose:
+ EVENT_expose( 0, hwnd, event, &cont_dispatch );
+ break;
+
+ case KeyPress:
+ case KeyRelease:
+ EVENT_key( 0, hwnd, event, &cont_dispatch );
+ break;
+
+ case MotionNotify:
+ EVENT_mouse_motion( 0, hwnd, event, &cont_dispatch );
+ break;
+
+ case ButtonPress:
+ case ButtonRelease:
+ EVENT_mouse_button( 0, hwnd, event, &cont_dispatch );
+ break;
+
+ case CirculateNotify:
+ case ConfigureNotify:
+ case MapNotify:
+ case UnmapNotify:
+ EVENT_structure( 0, hwnd, event, &cont_dispatch );
+ break;
+
+ case FocusIn:
+ case FocusOut:
+ EVENT_focus_change( 0, hwnd, event, &cont_dispatch );
+ break;
+
+ case EnterNotify:
+ EVENT_enter_notify( 0, hwnd, event, &cont_dispatch );
+ break;
+
+#ifdef DEBUG_EVENT
+ default:
+ printf( "Unprocessed event %s for hwnd %d\n",
+ event_names[event->type], hwnd );
+ break;
+#endif
+ }
+}
+
+
/***********************************************************************
* EVENT_AddHandlers
*
* Add the event handlers to the given window
*/
+#ifdef USE_XLIB
+void EVENT_AddHandlers( Window w, int hwnd )
+{
+ if (!winContext) winContext = XUniqueContext();
+ XSaveContext( XT_display, w, winContext, (XPointer)hwnd );
+}
+#else
void EVENT_AddHandlers( Widget w, int hwnd )
{
XtAddEventHandler(w, ExposureMask, FALSE,
@@ -50,7 +210,10 @@
EVENT_structure, (XtPointer)hwnd );
XtAddEventHandler(w, FocusChangeMask, FALSE,
EVENT_focus_change, (XtPointer)hwnd );
+ XtAddEventHandler(w, EnterWindowMask, FALSE,
+ EVENT_enter_notify, (XtPointer)hwnd );
}
+#endif
/***********************************************************************
@@ -60,6 +223,7 @@
*/
void EVENT_RemoveHandlers( Widget w, int hwnd )
{
+#ifndef USE_XLIB
XtRemoveEventHandler(w, ExposureMask, FALSE,
EVENT_expose, (XtPointer)hwnd );
XtRemoveEventHandler(w, KeyPressMask | KeyReleaseMask, FALSE,
@@ -72,6 +236,9 @@
EVENT_structure, (XtPointer)hwnd );
XtRemoveEventHandler(w, FocusChangeMask, FALSE,
EVENT_focus_change, (XtPointer)hwnd );
+ XtRemoveEventHandler(w, EnterWindowMask, FALSE,
+ EVENT_enter_notify, (XtPointer)hwnd );
+#endif
}
@@ -103,10 +270,14 @@
Boolean *cont_dispatch )
{
RECT rect;
- rect.left = event->x;
- rect.top = event->y;
- rect.right = event->x + event->width;
- rect.bottom = event->y + event->height;
+ WND * wndPtr = WIN_FindWndPtr( hwnd );
+ if (!wndPtr) return;
+ /* Make position relative to client area instead of window */
+ rect.left = event->x - (wndPtr->rectClient.left - wndPtr->rectWindow.left);
+ rect.top = event->y - (wndPtr->rectClient.top - wndPtr->rectWindow.top);
+ rect.right = rect.left + event->width;
+ rect.bottom = rect.top + event->height;
+ winHasCursor = event->window;
InvalidateRect( hwnd, &rect, TRUE );
}
@@ -121,24 +292,128 @@
Boolean *cont_dispatch )
{
MSG msg;
-
char Str[24];
XComposeStatus cs;
- KeySym key;
- int count = XLookupString(event, Str, 1, &key, &cs);
+ KeySym keysym;
+ WORD xkey, vkey, key_type, key;
+ KEYLP keylp;
+ BOOL extended = FALSE;
+ WND * wndPtr = WIN_FindWndPtr( hwnd );
+ int count = XLookupString(event, Str, 1, &keysym, &cs);
Str[count] = '\0';
#ifdef DEBUG_KEY
- printf("WM_KEY??? : count=%u / %X / '%s'\n",count, Str[0], Str);
-#endif
- msg.hwnd = hwnd;
- msg.message = (event->type == KeyRelease) ? WM_KEYUP : WM_KEYDOWN;
- msg.wParam = Str[0];
- msg.lParam = (event->x & 0xffff) | (event->y << 16);
- msg.time = event->time;
- msg.pt.x = event->x & 0xffff;
- msg.pt.y = event->y & 0xffff;
+ printf("WM_KEY??? : keysym=%lX, count=%u / %X / '%s'\n",
+ keysym, count, Str[0], Str);
+#endif
+
+ xkey = LOWORD(keysym);
+ key_type = HIBYTE(xkey);
+ key = LOBYTE(xkey);
+#ifdef DEBUG_KEY
+ printf(" key_type=%X, key=%X\n", key_type, key);
+#endif
+
+ /* Position must be relative to client area */
+ event->x -= wndPtr->rectClient.left - wndPtr->rectWindow.left;
+ event->y -= wndPtr->rectClient.top - wndPtr->rectWindow.top;
+
+ if (key_type == 0xFF) /* non-character key */
+ {
+ if (key >= 0x08 && key <= 0x1B) /* special key */
+ vkey = special_key[key - 0x08];
+ else if (key >= 0x50 && key <= 0x57) /* cursor key */
+ vkey = cursor_key[key - 0x50];
+ else if (key >= 0x60 && key <= 0x6B) /* miscellaneous key */
+ vkey = misc_key[key - 0x60];
+ else if (key >= 0x7E && key <= 0xB9) /* keypad key */
+ {
+ vkey = keypad_key[key - 0x7E];
+ extended = TRUE;
+ }
+ else if (key >= 0xBE && key <= 0xCD) /* function key */
+ {
+ vkey = function_key[key - 0xBE];
+ extended = TRUE;
+ }
+ else if (key >= 0xE1 && key <= 0xEA) /* modifier key */
+ vkey = modifier_key[key - 0xE1];
+ else if (key == 0xFF) /* DEL key */
+ vkey = VK_DELETE;
+ }
+ else if (key_type == 0) /* character key */
+ {
+ if (key >= 0x61 && key <= 0x7A)
+ vkey = key - 0x20; /* convert lower to uppercase */
+ else
+ vkey = key;
+ }
+
+ if (event->type == KeyPress)
+ {
+ msg.hwnd = hwnd;
+ msg.message = WM_KEYDOWN;
+ msg.wParam = vkey;
+ keylp.lp1.count = 1;
+ keylp.lp1.code = LOBYTE(event->keycode);
+ keylp.lp1.extended = (extended ? 1 : 0);
+ keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0);
+ keylp.lp1.previous = (KeyDown ? 0 : 1);
+ keylp.lp1.transition = 0;
+ msg.lParam = keylp.lp2;
+#ifdef DEBUG_KEY
+ printf(" wParam=%X, lParam=%lX\n", msg.wParam, msg.lParam);
+#endif
+ msg.time = event->time;
+ msg.pt.x = event->x & 0xffff;
+ msg.pt.y = event->y & 0xffff;
- MSG_AddMsg( &msg );
+ hardware_event( hwnd, WM_KEYDOWN, vkey, keylp.lp2,
+ event->x & 0xffff, event->y & 0xffff, event->time, 0 );
+ KeyDown = TRUE;
+
+ /* The key translation ought to take place in TranslateMessage().
+ * However, there is no way of passing the required information
+ * in a Windows message, so TranslateMessage does not currently
+ * do anything and the translation is done here.
+ */
+ if (count == 1) /* key has an ASCII representation */
+ {
+ msg.hwnd = hwnd;
+ msg.message = WM_CHAR;
+ msg.wParam = (WORD)Str[0];
+ msg.lParam = keylp.lp2;
+#ifdef DEBUG_KEY
+ printf("WM_CHAR : wParam=%X\n", msg.wParam);
+#endif
+ msg.time = event->time;
+ msg.pt.x = event->x & 0xffff;
+ msg.pt.y = event->y & 0xffff;
+ PostMessage( hwnd, WM_CHAR, (WORD)Str[0], keylp.lp2 );
+ }
+ }
+ else
+ {
+ msg.hwnd = hwnd;
+ msg.message = WM_KEYUP;
+ msg.wParam = vkey;
+ keylp.lp1.count = 1;
+ keylp.lp1.code = LOBYTE(event->keycode);
+ keylp.lp1.extended = (extended ? 1 : 0);
+ keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0);
+ keylp.lp1.previous = 1;
+ keylp.lp1.transition = 1;
+ msg.lParam = keylp.lp2;
+#ifdef DEBUG_KEY
+ printf(" wParam=%X, lParam=%lX\n", msg.wParam, msg.lParam);
+#endif
+ msg.time = event->time;
+ msg.pt.x = event->x & 0xffff;
+ msg.pt.y = event->y & 0xffff;
+
+ hardware_event( hwnd, WM_KEYUP, vkey, keylp.lp2,
+ event->x & 0xffff, event->y & 0xffff, event->time, 0 );
+ KeyDown = FALSE;
+ }
}
@@ -150,17 +425,17 @@
static void EVENT_mouse_motion( Widget w, int hwnd, XMotionEvent *event,
Boolean *cont_dispatch )
{
- MSG msg;
-
- msg.hwnd = hwnd;
- msg.message = WM_MOUSEMOVE;
- msg.wParam = EVENT_XStateToKeyState( event->state );
- msg.lParam = (event->x & 0xffff) | (event->y << 16);
- msg.time = event->time;
- msg.pt.x = event->x & 0xffff;
- msg.pt.y = event->y & 0xffff;
-
- MSG_AddMsg( &msg );
+ WND * wndPtr = WIN_FindWndPtr( hwnd );
+ if (!wndPtr) return;
+
+ /* Position must be relative to client area */
+ event->x -= wndPtr->rectClient.left - wndPtr->rectWindow.left;
+ event->y -= wndPtr->rectClient.top - wndPtr->rectWindow.top;
+
+ hardware_event( hwnd, WM_MOUSEMOVE, EVENT_XStateToKeyState( event->state ),
+ (event->x & 0xffff) | (event->y << 16),
+ event->x & 0xffff, event->y & 0xffff,
+ event->time, 0 );
}
@@ -180,9 +455,15 @@
};
static unsigned long lastClickTime[NB_BUTTONS] = { 0, 0, 0 };
- MSG msg;
int buttonNum, prevTime, type;
-
+
+ WND * wndPtr = WIN_FindWndPtr( hwnd );
+ if (!wndPtr) return;
+
+ /* Position must be relative to client area */
+ event->x -= wndPtr->rectClient.left - wndPtr->rectWindow.left;
+ event->y -= wndPtr->rectClient.top - wndPtr->rectWindow.top;
+
buttonNum = event->button-1;
if (buttonNum >= NB_BUTTONS) return;
if (event->type == ButtonRelease) type = 1;
@@ -201,15 +482,13 @@
else type = 0;
}
- msg.hwnd = hwnd;
- msg.message = messages[type][buttonNum];
- msg.wParam = EVENT_XStateToKeyState( event->state );
- msg.lParam = (event->x & 0xffff) | (event->y << 16);
- msg.time = event->time;
- msg.pt.x = event->x & 0xffff;
- msg.pt.y = event->y & 0xffff;
+ winHasCursor = event->window;
- MSG_AddMsg( &msg );
+ hardware_event( hwnd, messages[type][buttonNum],
+ EVENT_XStateToKeyState( event->state ),
+ (event->x & 0xffff) | (event->y << 16),
+ event->x & 0xffff, event->y & 0xffff,
+ event->time, 0 );
}
@@ -232,13 +511,31 @@
{
case ConfigureNotify:
{
+ HANDLE handle;
+ NCCALCSIZE_PARAMS *params;
XConfigureEvent * evt = (XConfigureEvent *)event;
WND * wndPtr = WIN_FindWndPtr( hwnd );
if (!wndPtr) return;
- wndPtr->rectClient.right = wndPtr->rectClient.left + evt->width;
- wndPtr->rectClient.bottom = wndPtr->rectClient.top + evt->height;
+ wndPtr->rectWindow.left = evt->x;
+ wndPtr->rectWindow.top = evt->y;
+ wndPtr->rectWindow.right = evt->x + evt->width;
+ wndPtr->rectWindow.bottom = evt->y + evt->height;
+
+ /* Send WM_NCCALCSIZE message */
+ handle = GlobalAlloc( GMEM_MOVEABLE, sizeof(*params) );
+ params = (NCCALCSIZE_PARAMS *)GlobalLock( handle );
+ params->rgrc[0] = wndPtr->rectWindow;
+ params->lppos = NULL; /* Should be WINDOWPOS struct */
+ SendMessage( hwnd, WM_NCCALCSIZE, FALSE, params );
+ wndPtr->rectClient = params->rgrc[0];
+ PostMessage( hwnd, WM_MOVE, 0,
+ MAKELONG( wndPtr->rectClient.left,
+ wndPtr->rectClient.top ));
PostMessage( hwnd, WM_SIZE, SIZE_RESTORED,
- (evt->width & 0xffff) | (evt->height << 16) );
+ MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
+ wndPtr->rectClient.bottom-wndPtr->rectClient.top));
+ GlobalUnlock( handle );
+ GlobalFree( handle );
}
break;
@@ -254,21 +551,12 @@
static void EVENT_focus_change( Widget w, int hwnd, XEvent *event,
Boolean *cont_dispatch )
{
- MSG msg;
-
- msg.hwnd = hwnd;
- msg.time = GetTickCount();
- msg.pt.x = 0;
- msg.pt.y = 0;
-
switch(event->type)
{
case FocusIn:
{
- msg.message = WM_SETFOCUS;
- msg.wParam = hwnd;
+ PostMessage( hwnd, WM_SETFOCUS, hwnd, 0 );
hWndFocus = hwnd;
-
}
break;
@@ -276,13 +564,32 @@
{
if (hWndFocus)
{
- msg.message = WM_KILLFOCUS;
- msg.wParam = hwnd;
+ PostMessage( hwnd, WM_KILLFOCUS, hwnd, 0 );
hWndFocus = 0;
}
}
}
- MSG_AddMsg( &msg );
+}
+
+
+/**********************************************************************
+ * EVENT_enter_notify
+ *
+ * Handle an X EnterNotify event
+ */
+static void EVENT_enter_notify( Widget w, int hwnd, XCrossingEvent *event,
+ Boolean *cont_dispatch )
+{
+ if (captureWnd != 0) return;
+
+ winHasCursor = event->window;
+
+ switch(event->type)
+ {
+ case EnterNotify:
+ PostMessage( hwnd, WM_SETCURSOR, hwnd, 0 );
+ break;
+ }
}
@@ -297,9 +604,15 @@
if (wnd_p == NULL)
return 0;
+#ifdef USE_XLIB
+ rv = XGrabPointer(XT_display, wnd_p->window, False,
+ ButtonPressMask | ButtonReleaseMask | ButtonMotionMask,
+ GrabModeAsync, GrabModeSync, None, None, CurrentTime);
+#else
rv = XtGrabPointer(wnd_p->winWidget, False,
ButtonPressMask | ButtonReleaseMask | ButtonMotionMask,
GrabModeAsync, GrabModeSync, None, None, CurrentTime);
+#endif
if (rv == GrabSuccess)
{
@@ -324,12 +637,24 @@
if (wnd_p == NULL)
return;
+#ifdef USE_XLIB
+ XUngrabPointer( XT_display, CurrentTime );
+#else
XtUngrabPointer(wnd_p->winWidget, CurrentTime);
+#endif
captureWnd = 0;
}
/**********************************************************************
+ * GetCapture (USER.236)
+ */
+HWND GetCapture()
+{
+ return captureWnd;
+}
+
+/**********************************************************************
* SetDoubleClickTime (USER.20)
*/
void SetDoubleClickTime (WORD interval)
diff --git a/windows/focus.c b/windows/focus.c
index ce1a91a2..639b2df 100644
--- a/windows/focus.c
+++ b/windows/focus.c
@@ -32,7 +32,7 @@
else
{
wndPtr = WIN_FindWndPtr(hwnd);
- XSetInputFocus(XT_display, XtWindow(wndPtr->winWidget),
+ XSetInputFocus(XT_display, wndPtr->window,
RevertToParent, CurrentTime);
}
diff --git a/windows/graphics.c b/windows/graphics.c
index a2a1e32..9fd5d27 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -23,8 +23,10 @@
if (!dc) return FALSE;
if (DC_SetupGCForPen( dc ))
XDrawLine(XT_display, dc->u.x.drawable, dc->u.x.gc,
- XLPTODP( dc, dc->w.CursPosX ), YLPTODP( dc, dc->w.CursPosY ),
- XLPTODP( dc, x ), YLPTODP( dc, y ) );
+ dc->w.DCOrgX + XLPTODP( dc, dc->w.CursPosX ),
+ dc->w.DCOrgY + YLPTODP( dc, dc->w.CursPosY ),
+ dc->w.DCOrgX + XLPTODP( dc, x ),
+ dc->w.DCOrgY + YLPTODP( dc, y ) );
dc->w.CursPosX = x;
dc->w.CursPosY = y;
return TRUE;
@@ -97,20 +99,21 @@
if (diff_angle < 0.0) diff_angle += 2*PI;
XDrawArc( XT_display, dc->u.x.drawable, dc->u.x.gc,
- left, top, right-left-1, bottom-top-1,
+ dc->w.DCOrgX + left, dc->w.DCOrgY + top,
+ right-left-1, bottom-top-1,
(int)(start_angle * 180 * 64 / PI),
(int)(diff_angle * 180 * 64 / PI) );
if (!lines) return TRUE;
- points[0].x = xcenter + (int)(cos(start_angle) * (right-left) / 2);
- points[0].y = ycenter - (int)(sin(start_angle) * (bottom-top) / 2);
- points[1].x = xcenter + (int)(cos(end_angle) * (right-left) / 2);
- points[1].y = ycenter - (int)(sin(end_angle) * (bottom-top) / 2);
+ points[0].x = dc->w.DCOrgX + xcenter + (int)(cos(start_angle) * (right-left) / 2);
+ points[0].y = dc->w.DCOrgY + ycenter - (int)(sin(start_angle) * (bottom-top) / 2);
+ points[1].x = dc->w.DCOrgX + xcenter + (int)(cos(end_angle) * (right-left) / 2);
+ points[1].y = dc->w.DCOrgY + ycenter - (int)(sin(end_angle) * (bottom-top) / 2);
if (lines == 2)
{
points[2] = points[1];
- points[1].x = xcenter;
- points[1].y = ycenter;
+ points[1].x = dc->w.DCOrgX + xcenter;
+ points[1].y = dc->w.DCOrgY + ycenter;
}
XDrawLines( XT_display, dc->u.x.drawable, dc->u.x.gc,
points, lines+1, CoordModeOrigin );
@@ -167,10 +170,12 @@
if (DC_SetupGCForBrush( dc ))
XFillArc( XT_display, dc->u.x.drawable, dc->u.x.gc,
- left, top, right-left-1, bottom-top-1, 0, 360*64 );
+ dc->w.DCOrgX + left, dc->w.DCOrgY + top,
+ right-left-1, bottom-top-1, 0, 360*64 );
if (DC_SetupGCForPen( dc ))
XDrawArc( XT_display, dc->u.x.drawable, dc->u.x.gc,
- left, top, right-left-1, bottom-top-1, 0, 360*64 );
+ dc->w.DCOrgX + left, dc->w.DCOrgY + top,
+ right-left-1, bottom-top-1, 0, 360*64 );
return TRUE;
}
@@ -190,10 +195,12 @@
if (DC_SetupGCForBrush( dc ))
XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
- left, top, right-left-1, bottom-top-1 );
+ dc->w.DCOrgX + left, dc->w.DCOrgY + top,
+ right-left-1, bottom-top-1 );
if (DC_SetupGCForPen( dc ))
XDrawRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
- left, top, right-left-1, bottom-top-1 );
+ dc->w.DCOrgX + left, dc->w.DCOrgY + top,
+ right-left-1, bottom-top-1 );
return TRUE;
}
@@ -244,10 +251,16 @@
right = XLPTODP( dc, rect->right );
bottom = YLPTODP( dc, rect->bottom );
- if (DC_SetupGCForBrush( dc ))
- XDrawRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
- left, top, right-left-1, bottom-top-1 );
-
+ if (DC_SetupGCForBrush( dc )) {
+ PatBlt( hdc, rect->left, rect->top, 1,
+ rect->bottom - rect->top, PATCOPY );
+ PatBlt( hdc, rect->right - 1, rect->top, 1,
+ rect->bottom - rect->top, PATCOPY );
+ PatBlt( hdc, rect->left, rect->top,
+ rect->right - rect->left, 1, PATCOPY );
+ PatBlt( hdc, rect->left, rect->bottom - 1,
+ rect->right - rect->left, 1, PATCOPY );
+ }
SelectObject( hdc, prevBrush );
return 1;
}
@@ -264,8 +277,8 @@
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return 0;
- x = XLPTODP( dc, x );
- y = YLPTODP( dc, y );
+ x = dc->w.DCOrgX + XLPTODP( dc, x );
+ y = dc->w.DCOrgY + YLPTODP( dc, y );
pixel = GetNearestPaletteIndex( dc->w.hPalette, color );
GetPaletteEntries( dc->w.hPalette, pixel, 1, &entry );
@@ -288,15 +301,14 @@
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return 0;
- x = XLPTODP( dc, x );
- y = YLPTODP( dc, y );
+ x = dc->w.DCOrgX + XLPTODP( dc, x );
+ y = dc->w.DCOrgY + YLPTODP( dc, y );
if ((x < 0) || (y < 0)) return 0;
- if (dc->u.x.widget)
+ if (!(dc->w.flags & DC_MEMORY))
{
XWindowAttributes win_attr;
- if (!XtIsRealized(dc->u.x.widget)) return 0;
if (!XGetWindowAttributes( XT_display, dc->u.x.drawable, &win_attr ))
return 0;
if (win_attr.map_state != IsViewable) return 0;
@@ -342,7 +354,7 @@
GetClipBox( hdc, &box );
if (DC_SetupGCForBrush( dc ))
XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
- box.left, box.top,
+ dc->w.DCOrgX + box.left, dc->w.DCOrgY + box.top,
box.right-box.left, box.bottom-box.top );
/* Restore the visible region */
@@ -385,15 +397,16 @@
hPen = CreatePen(PS_DOT, 1, GetSysColor(COLOR_WINDOWTEXT));
hOldPen = (HPEN)SelectObject(hdc, (HANDLE)hPen);
-/* oldDrawMode = SetROP2(hdc, R2_XORPEN); */
+ oldDrawMode = SetROP2(hdc, R2_XORPEN);
oldBkMode = SetBkMode(hdc, TRANSPARENT);
if (DC_SetupGCForPen( dc ))
XDrawRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
- left, top, right-left-1, bottom-top-1 );
+ dc->w.DCOrgX + left, dc->w.DCOrgY + top,
+ right-left-1, bottom-top-1 );
SetBkMode(hdc, oldBkMode);
-/* SetROP2(hdc, oldDrawMode); */
+ SetROP2(hdc, oldDrawMode);
SelectObject(hdc, (HANDLE)hOldPen);
DeleteObject((HANDLE)hPen);
}
@@ -441,3 +454,64 @@
SelectObject(hDC, hOldPen);
DeleteObject(hDKGRAYPen);
}
+
+/**********************************************************************
+ * Polyline (GDI.37)
+ */
+BOOL Polyline (HDC hdc, LPPOINT pt, int count)
+{
+ register int i;
+ DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+
+ if (DC_SetupGCForPen( dc ))
+ {
+ for (i = 0; i < count-1; i ++)
+ XDrawLine (XT_display, dc->u.x.drawable, dc->u.x.gc,
+ dc->w.DCOrgX + XLPTODP(dc, pt [i].x),
+ dc->w.DCOrgY + YLPTODP(dc, pt [i].y),
+ dc->w.DCOrgX + XLPTODP(dc, pt [i+1].x),
+ dc->w.DCOrgY + YLPTODP(dc, pt [i+1].y));
+ XDrawLine (XT_display, dc->u.x.drawable, dc->u.x.gc,
+ dc->w.DCOrgX + XLPTODP(dc, pt [count-1].x),
+ dc->w.DCOrgY + YLPTODP(dc, pt [count-1].y),
+ dc->w.DCOrgX + XLPTODP(dc, pt [0].x),
+ dc->w.DCOrgY + YLPTODP(dc, pt [0].y));
+ }
+
+ return (TRUE);
+}
+
+
+/**********************************************************************
+ * Polygon (GDI.36)
+ */
+BOOL Polygon (HDC hdc, LPPOINT pt, int count)
+{
+ register int i;
+ DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+ XPoint *points = (XPoint *) malloc (sizeof (XPoint) * count+1);
+
+ if (DC_SetupGCForBrush( dc ))
+ {
+
+ for (i = 0; i < count; i++)
+ {
+ points [i].x = dc->w.DCOrgX + XLPTODP(dc, pt [i].x);
+ points [i].y = dc->w.DCOrgY + YLPTODP(dc, pt [i].y);
+ }
+ points [count] = points [0];
+
+ XFillPolygon( XT_display, dc->u.x.drawable, dc->u.x.gc,
+ points, count, Complex, CoordModeOrigin);
+
+ if (DC_SetupGCForPen ( dc ))
+ {
+ XDrawLines( XT_display, dc->u.x.drawable, dc->u.x.gc,
+ points, count, CoordModeOrigin );
+ }
+ }
+ free ((void *) points);
+ return (TRUE);
+}
+
+
diff --git a/windows/message.c b/windows/message.c
index 7307461..09b49e7 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -12,10 +12,8 @@
static char Copyright[] = "Copyright Alexandre Julliard, 1993";
#include <stdlib.h>
-
-#ifdef __NetBSD__
-#define HZ 100
-#endif
+#include <sys/time.h>
+#include <sys/types.h>
#include "message.h"
#include "win.h"
@@ -23,30 +21,72 @@
#define MAX_QUEUE_SIZE 120 /* Max. size of a message queue */
-extern HWND WIN_FindWinToRepaint( HWND hwnd );
+extern BOOL TIMER_CheckTimer( DWORD *next ); /* timer.c */
extern Display * XT_display;
extern Screen * XT_screen;
extern XtAppContext XT_app_context;
-static MESSAGEQUEUE * msgQueue = NULL;
+ /* System message queue (for hardware events) */
+static HANDLE hmemSysMsgQueue = 0;
+static MESSAGEQUEUE * sysMsgQueue = NULL;
+
+ /* Application message queue (should be a list, one queue per task) */
+static HANDLE hmemAppMsgQueue = 0;
+static MESSAGEQUEUE * appMsgQueue = NULL;
+
+/***********************************************************************
+ * MSG_CreateMsgQueue
+ *
+ * Create a message queue.
+ */
+static HANDLE MSG_CreateMsgQueue( int size )
+{
+ HANDLE hQueue;
+ MESSAGEQUEUE * msgQueue;
+ int queueSize;
+
+ queueSize = sizeof(MESSAGEQUEUE) + size * sizeof(QMSG);
+ if (!(hQueue = GlobalAlloc( GMEM_FIXED, queueSize ))) return 0;
+ msgQueue = (MESSAGEQUEUE *) GlobalLock( hQueue );
+ msgQueue->next = 0;
+ msgQueue->hTask = 0;
+ msgQueue->msgSize = sizeof(QMSG);
+ msgQueue->msgCount = 0;
+ msgQueue->nextMessage = 0;
+ msgQueue->nextFreeMessage = 0;
+ msgQueue->queueSize = size;
+ msgQueue->GetMessageTimeVal = 0;
+ msgQueue->GetMessagePosVal = 0;
+ msgQueue->GetMessageExtraInfoVal = 0;
+ msgQueue->lParam = 0;
+ msgQueue->wParam = 0;
+ msgQueue->msg = 0;
+ msgQueue->hWnd = 0;
+ msgQueue->wPostQMsg = 0;
+ msgQueue->wExitCode = 0;
+ msgQueue->InSendMessageHandle = 0;
+ msgQueue->wPaintCount = 0;
+ msgQueue->wTimerCount = 0;
+ msgQueue->tempStatus = 0;
+ msgQueue->status = 0;
+ GlobalUnlock( hQueue );
+ return hQueue;
+}
/***********************************************************************
- * MSG_GetMessageType
+ * MSG_CreateSysMsgQueue
*
+ * Create the system message queue. Must be called only once.
*/
-int MSG_GetMessageType( int msg )
+BOOL MSG_CreateSysMsgQueue( int size )
{
- if ((msg >= WM_KEYFIRST) && (msg <= WM_KEYLAST)) return QS_KEY;
- else if ((msg >= WM_MOUSEFIRST) && (msg <= WM_MOUSELAST))
- {
- if (msg == WM_MOUSEMOVE) return QS_MOUSEMOVE;
- else return QS_MOUSEBUTTON;
- }
- else if (msg == WM_PAINT) return QS_PAINT;
- else if (msg == WM_TIMER) return QS_TIMER;
- return QS_POSTMESSAGE;
+ if (size > MAX_QUEUE_SIZE) size = MAX_QUEUE_SIZE;
+ else if (size <= 0) size = 1;
+ if (!(hmemSysMsgQueue = MSG_CreateMsgQueue( size ))) return FALSE;
+ sysMsgQueue = (MESSAGEQUEUE *) GlobalLock( hmemSysMsgQueue );
+ return TRUE;
}
@@ -55,16 +95,13 @@
*
* Add a message to the queue. Return FALSE if queue is full.
*/
-int MSG_AddMsg( MSG * msg, DWORD extraInfo )
+static int MSG_AddMsg( MESSAGEQUEUE * msgQueue, MSG * msg, DWORD extraInfo )
{
- int pos, type;
+ int pos;
if (!msgQueue) return FALSE;
pos = msgQueue->nextFreeMessage;
- /* No need to store WM_PAINT messages */
- if (msg->message == WM_PAINT) return TRUE;
-
/* Check if queue is full */
if ((pos == msgQueue->nextMessage) && (msgQueue->msgCount > 0))
return FALSE;
@@ -72,17 +109,12 @@
/* Store message */
msgQueue->messages[pos].msg = *msg;
msgQueue->messages[pos].extraInfo = extraInfo;
-
- /* Store message type */
- type = MSG_GetMessageType( msg->message );
- msgQueue->status |= type;
- msgQueue->tempStatus |= type;
-
if (pos < msgQueue->queueSize-1) pos++;
else pos = 0;
msgQueue->nextFreeMessage = pos;
msgQueue->msgCount++;
-
+ msgQueue->status |= QS_POSTMESSAGE;
+ msgQueue->tempStatus |= QS_POSTMESSAGE;
return TRUE;
}
@@ -92,7 +124,7 @@
*
* Find a message matching the given parameters. Return -1 if none available.
*/
-int MSG_FindMsg( HWND hwnd, int first, int last )
+static int MSG_FindMsg(MESSAGEQUEUE * msgQueue, HWND hwnd, int first, int last)
{
int i, pos = msgQueue->nextMessage;
@@ -120,9 +152,8 @@
*
* Remove a message from the queue (pos must be a valid position).
*/
-void MSG_RemoveMsg( int pos )
+static void MSG_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos )
{
- int i, type;
QMSG * qmsg;
if (!msgQueue) return;
@@ -147,56 +178,118 @@
else msgQueue->nextFreeMessage = msgQueue->queueSize-1;
}
msgQueue->msgCount--;
-
- /* Recalc status */
- type = 0;
- pos = msgQueue->nextMessage;
- for (i = 0; i < msgQueue->msgCount; i++)
- {
- type |= MSG_GetMessageType( msgQueue->messages[pos].msg.message );
- if (++pos >= msgQueue->queueSize-1) pos = 0;
- }
- msgQueue->status = (msgQueue->status & QS_SENDMESSAGE) | type;
+ if (!msgQueue->msgCount) msgQueue->status &= ~QS_POSTMESSAGE;
msgQueue->tempStatus = 0;
}
/***********************************************************************
+ * MSG_IncPaintCount
+ */
+void MSG_IncPaintCount( HANDLE hQueue )
+{
+ if (hQueue != hmemAppMsgQueue) return;
+ appMsgQueue->wPaintCount++;
+ appMsgQueue->status |= QS_PAINT;
+ appMsgQueue->tempStatus |= QS_PAINT;
+}
+
+
+/***********************************************************************
+ * MSG_DecPaintCount
+ */
+void MSG_DecPaintCount( HANDLE hQueue )
+{
+ if (hQueue != hmemAppMsgQueue) return;
+ appMsgQueue->wPaintCount--;
+ if (!appMsgQueue->wPaintCount) appMsgQueue->status &= ~QS_PAINT;
+}
+
+
+/***********************************************************************
+ * MSG_IncTimerCount
+ */
+void MSG_IncTimerCount( HANDLE hQueue )
+{
+ if (hQueue != hmemAppMsgQueue) return;
+ appMsgQueue->wTimerCount++;
+ appMsgQueue->status |= QS_TIMER;
+ appMsgQueue->tempStatus |= QS_TIMER;
+}
+
+
+/***********************************************************************
+ * MSG_DecTimerCount
+ */
+void MSG_DecTimerCount( HANDLE hQueue )
+{
+ if (hQueue != hmemAppMsgQueue) return;
+ appMsgQueue->wTimerCount--;
+ if (!appMsgQueue->wTimerCount) appMsgQueue->status &= ~QS_TIMER;
+}
+
+
+/***********************************************************************
+ * hardware_event
+ *
+ * Add an event to the system message queue.
+ */
+void hardware_event( HWND hwnd, WORD message, WORD wParam, LONG lParam,
+ WORD xPos, WORD yPos, DWORD time, DWORD extraInfo )
+{
+ MSG msg;
+
+ msg.hwnd = hwnd;
+ msg.message = message;
+ msg.wParam = wParam;
+ msg.lParam = lParam;
+ msg.time = time;
+ msg.pt.x = xPos;
+ msg.pt.y = yPos;
+ if (!MSG_AddMsg( sysMsgQueue, &msg, extraInfo ))
+ printf( "hardware_event: Queue is full\n" );
+}
+
+
+/***********************************************************************
+ * SetTaskQueue (KERNEL.34)
+ */
+WORD SetTaskQueue( HANDLE hTask, HANDLE hQueue )
+{
+ HANDLE prev = hmemAppMsgQueue;
+ hmemAppMsgQueue = hQueue;
+ return prev;
+}
+
+
+/***********************************************************************
+ * GetTaskQueue (KERNEL.35)
+ */
+WORD GetTaskQueue( HANDLE hTask )
+{
+ return hmemAppMsgQueue;
+}
+
+
+/***********************************************************************
* SetMessageQueue (USER.266)
*/
BOOL SetMessageQueue( int size )
{
- int queueSize;
-
+ HANDLE hQueue;
+
+ if ((size > MAX_QUEUE_SIZE) || (size <= 0)) return TRUE;
+
/* Free the old message queue */
- if (msgQueue) free(msgQueue);
+ if ((hQueue = GetTaskQueue(0)) != 0)
+ {
+ GlobalUnlock( hQueue );
+ GlobalFree( hQueue );
+ }
- if ((size > MAX_QUEUE_SIZE) || (size <= 0)) return FALSE;
-
- queueSize = sizeof(MESSAGEQUEUE) + size * sizeof(QMSG);
- msgQueue = (MESSAGEQUEUE *) malloc(queueSize);
- if (!msgQueue) return FALSE;
-
- msgQueue->next = 0;
- msgQueue->hTask = 0;
- msgQueue->msgSize = sizeof(QMSG);
- msgQueue->msgCount = 0;
- msgQueue->nextMessage = 0;
- msgQueue->nextFreeMessage = 0;
- msgQueue->queueSize = size;
- msgQueue->GetMessageTimeVal = 0;
- msgQueue->GetMessagePosVal = 0;
- msgQueue->GetMessageExtraInfoVal = 0;
- msgQueue->lParam = 0;
- msgQueue->wParam = 0;
- msgQueue->msg = 0;
- msgQueue->hWnd = 0;
- msgQueue->wPostQMsg = 0;
- msgQueue->wExitCode = 0;
- msgQueue->InSendMessageHandle = 0;
- msgQueue->tempStatus = 0;
- msgQueue->status = 0;
-
+ if (!(hQueue = MSG_CreateMsgQueue( size ))) return FALSE;
+ SetTaskQueue( 0, hQueue );
+ appMsgQueue = (MESSAGEQUEUE *)GlobalLock( hQueue );
return TRUE;
}
@@ -206,9 +299,9 @@
*/
void PostQuitMessage( int exitCode )
{
- if (!msgQueue) return;
- msgQueue->wPostQMsg = TRUE;
- msgQueue->wExitCode = exitCode;
+ if (!appMsgQueue) return;
+ appMsgQueue->wPostQMsg = TRUE;
+ appMsgQueue->wExitCode = exitCode;
}
@@ -217,12 +310,8 @@
*/
DWORD GetQueueStatus( int flags )
{
- unsigned long ret = (msgQueue->status << 16) | msgQueue->tempStatus;
- if (flags & QS_PAINT)
- {
- if (WIN_FindWinToRepaint(0)) ret |= QS_PAINT | (QS_PAINT << 16);
- }
- msgQueue->tempStatus = 0;
+ unsigned long ret = (appMsgQueue->status << 16) | appMsgQueue->tempStatus;
+ appMsgQueue->tempStatus = 0;
return ret & ((flags << 16) | flags);
}
@@ -232,70 +321,169 @@
*/
BOOL GetInputState()
{
- return msgQueue->status & (QS_KEY | QS_MOUSEBUTTON);
+ return appMsgQueue->status & (QS_KEY | QS_MOUSEBUTTON);
}
+#ifndef USE_XLIB
+static XtIntervalId xt_timer = 0;
+
+/***********************************************************************
+ * MSG_TimerCallback
+ */
+static void MSG_TimerCallback( XtPointer data, XtIntervalId * xtid )
+{
+ DWORD nextExp;
+ TIMER_CheckTimer( &nextExp );
+ if (nextExp != (DWORD)-1)
+ xt_timer = XtAppAddTimeOut( XT_app_context, nextExp,
+ MSG_TimerCallback, NULL );
+ else xt_timer = 0;
+}
+#endif /* USE_XLIB */
+
+
/***********************************************************************
* MSG_PeekMessage
*/
-BOOL MSG_PeekMessage( LPMSG msg, HWND hwnd, WORD first, WORD last, WORD flags )
+static BOOL MSG_PeekMessage( MESSAGEQUEUE * msgQueue, LPMSG msg, HWND hwnd,
+ WORD first, WORD last, WORD flags, BOOL peek )
{
- int pos;
+ int pos, mask;
+ DWORD nextExp; /* Next timer expiration time */
+#ifdef USE_XLIB
+ XEvent event;
+#endif
- /* First handle a WM_QUIT message */
- if (msgQueue->wPostQMsg)
+ if (first || last)
{
- msg->hwnd = hwnd;
- msg->message = WM_QUIT;
- msg->wParam = msgQueue->wExitCode;
- msg->lParam = 0;
- return TRUE;
+ mask = QS_POSTMESSAGE; /* Always selectioned */
+ if ((first <= WM_KEYLAST) && (last >= WM_KEYFIRST)) mask |= QS_KEY;
+ if ((first <= WM_MOUSELAST) && (last >= WM_MOUSEFIRST)) mask |= QS_MOUSE;
+ if ((first <= WM_TIMER) && (last >= WM_TIMER)) mask |= WM_TIMER;
+ if ((first <= WM_SYSTIMER) && (last >= WM_SYSTIMER)) mask |= WM_TIMER;
+ if ((first <= WM_PAINT) && (last >= WM_PAINT)) mask |= WM_PAINT;
}
+ else mask = QS_MOUSE | QS_KEY | QS_POSTMESSAGE | QS_TIMER | QS_PAINT;
- /* Then handle a message put by SendMessage() */
- if (msgQueue->status & QS_SENDMESSAGE)
+#ifdef USE_XLIB
+ while (XPending( XT_display ))
{
- if (!hwnd || (msgQueue->hWnd == hwnd))
+ XNextEvent( XT_display, &event );
+ EVENT_ProcessEvent( &event );
+ }
+#else
+ while (XtAppPending( XT_app_context ))
+ XtAppProcessEvent( XT_app_context, XtIMAll );
+#endif
+
+ while(1)
+ {
+ /* First handle a WM_QUIT message */
+ if (msgQueue->wPostQMsg)
{
- if ((!first && !last) ||
- ((msgQueue->msg >= first) && (msgQueue->msg <= last)))
+ msg->hwnd = hwnd;
+ msg->message = WM_QUIT;
+ msg->wParam = msgQueue->wExitCode;
+ msg->lParam = 0;
+ break;
+ }
+
+ /* Then handle a message put by SendMessage() */
+ if (msgQueue->status & QS_SENDMESSAGE)
+ {
+ if (!hwnd || (msgQueue->hWnd == hwnd))
{
- msg->hwnd = msgQueue->hWnd;
- msg->message = msgQueue->msg;
- msg->wParam = msgQueue->wParam;
- msg->lParam = msgQueue->lParam;
- if (flags & PM_REMOVE) msgQueue->status &= ~QS_SENDMESSAGE;
- return TRUE;
+ if ((!first && !last) ||
+ ((msgQueue->msg >= first) && (msgQueue->msg <= last)))
+ {
+ msg->hwnd = msgQueue->hWnd;
+ msg->message = msgQueue->msg;
+ msg->wParam = msgQueue->wParam;
+ msg->lParam = msgQueue->lParam;
+ if (flags & PM_REMOVE) msgQueue->status &= ~QS_SENDMESSAGE;
+ break;
+ }
}
}
-
- }
- /* Now find a normal message */
- pos = MSG_FindMsg( hwnd, first, last );
- if (pos != -1)
- {
- QMSG *qmsg = &msgQueue->messages[pos];
- *msg = qmsg->msg;
- msgQueue->GetMessageTimeVal = msg->time;
- msgQueue->GetMessagePosVal = *(DWORD *)&msg->pt;
- msgQueue->GetMessageExtraInfoVal = qmsg->extraInfo;
+ /* Now find a normal message */
+ pos = MSG_FindMsg( msgQueue, hwnd, first, last );
+ if (pos != -1)
+ {
+ QMSG *qmsg = &msgQueue->messages[pos];
+ *msg = qmsg->msg;
+ msgQueue->GetMessageTimeVal = msg->time;
+ msgQueue->GetMessagePosVal = *(DWORD *)&msg->pt;
+ msgQueue->GetMessageExtraInfoVal = qmsg->extraInfo;
- if (flags & PM_REMOVE) MSG_RemoveMsg(pos);
- return TRUE;
+ if (flags & PM_REMOVE) MSG_RemoveMsg( msgQueue, pos );
+ break;
+ }
+
+ /* Now find a hardware event */
+ pos = MSG_FindMsg( sysMsgQueue, hwnd, first, last );
+ if (pos != -1)
+ {
+ QMSG *qmsg = &sysMsgQueue->messages[pos];
+ *msg = qmsg->msg;
+ msgQueue->GetMessageTimeVal = msg->time;
+ msgQueue->GetMessagePosVal = *(DWORD *)&msg->pt;
+ msgQueue->GetMessageExtraInfoVal = qmsg->extraInfo;
+
+ if (flags & PM_REMOVE) MSG_RemoveMsg( sysMsgQueue, pos );
+ break;
+ }
+
+ /* Now find a WM_PAINT message */
+ if ((msgQueue->status & QS_PAINT) && (mask & QS_PAINT))
+ {
+ msg->hwnd = WIN_FindWinToRepaint( hwnd );
+ msg->message = WM_PAINT;
+ msg->wParam = 0;
+ msg->lParam = 0;
+ if (msg->hwnd != 0) break;
+ }
+
+ /* Finally handle WM_TIMER messages */
+ if ((msgQueue->status & QS_TIMER) && (mask & QS_TIMER))
+ {
+ BOOL posted = TIMER_CheckTimer( &nextExp );
+#ifndef USE_XLIB
+ if (xt_timer) XtRemoveTimeOut( xt_timer );
+ if (nextExp != (DWORD)-1)
+ xt_timer = XtAppAddTimeOut( XT_app_context, nextExp,
+ MSG_TimerCallback, NULL );
+ else xt_timer = 0;
+#endif
+ if (posted) continue; /* Restart the whole thing */
+ }
+
+ /* Wait until something happens */
+ if (peek) return FALSE;
+#ifdef USE_XLIB
+ if (!XPending( XT_display ) && (nextExp != -1))
+ {
+ fd_set read_set;
+ struct timeval timeout;
+ int fd = ConnectionNumber(XT_display);
+ FD_ZERO( &read_set );
+ FD_SET( fd, &read_set );
+ timeout.tv_sec = nextExp / 1000;
+ timeout.tv_usec = (nextExp % 1000) * 1000;
+ if (select( fd+1, &read_set, NULL, NULL, &timeout ) != 1)
+ continue; /* On timeout or error, restart from the start */
+ }
+ XNextEvent( XT_display, &event );
+ EVENT_ProcessEvent( &event );
+#else
+ XtAppProcessEvent( XT_app_context, XtIMAll );
+#endif
}
- /* If nothing else, return a WM_PAINT message */
- if ((!first && !last) || ((first <= WM_PAINT) && (last >= WM_PAINT)))
- {
- msg->hwnd = WIN_FindWinToRepaint( hwnd );
- msg->message = WM_PAINT;
- msg->wParam = 0;
- msg->lParam = 0;
- return (msg->hwnd != 0);
- }
- return FALSE;
+ /* We got a message */
+ if (peek) return TRUE;
+ else return (msg->message != WM_QUIT);
}
@@ -304,10 +492,7 @@
*/
BOOL PeekMessage( LPMSG msg, HWND hwnd, WORD first, WORD last, WORD flags )
{
- while (XtAppPending( XT_app_context ))
- XtAppProcessEvent( XT_app_context, XtIMAll );
-
- return MSG_PeekMessage( msg, hwnd, first, last, flags );
+ return MSG_PeekMessage( appMsgQueue, msg, hwnd, first, last, flags, TRUE );
}
@@ -316,13 +501,7 @@
*/
BOOL GetMessage( LPMSG msg, HWND hwnd, WORD first, WORD last )
{
- while(1)
- {
- if (MSG_PeekMessage( msg, hwnd, first, last, PM_REMOVE )) break;
- XtAppProcessEvent( XT_app_context, XtIMAll );
- }
-
- return (msg->message != WM_QUIT);
+ return MSG_PeekMessage( appMsgQueue, msg, hwnd, first, last, PM_REMOVE, FALSE );
}
@@ -341,7 +520,7 @@
msg.pt.x = 0;
msg.pt.y = 0;
- return MSG_AddMsg( &msg, 0 );
+ return MSG_AddMsg( appMsgQueue, &msg, 0 );
}
@@ -380,16 +559,39 @@
*/
LONG DispatchMessage( LPMSG msg )
{
- WND * wndPtr = WIN_FindWndPtr( msg->hwnd );
-
+ WND * wndPtr;
+ LONG retval;
+ int painting;
+
#ifdef DEBUG_MSG
printf( "Dispatch message hwnd=%08x msg=%d w=%d l=%d time=%u pt=%d,%d\n",
msg->hwnd, msg->message, msg->wParam, msg->lParam,
msg->time, msg->pt.x, msg->pt.y );
#endif
- if (!wndPtr) return 0;
- return CallWindowProc( wndPtr->lpfnWndProc, msg->hwnd, msg->message,
- msg->wParam, msg->lParam );
+
+ /* Process timer messages */
+ if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
+ {
+ if (msg->lParam)
+ return CallWindowProc( (FARPROC)msg->lParam, msg->hwnd,
+ msg->message, msg->wParam, GetTickCount() );
+ }
+
+ if (!msg->hwnd) return 0;
+ if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0;
+ if (!wndPtr->lpfnWndProc) return 0;
+ painting = (msg->message == WM_PAINT);
+ if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
+ retval = CallWindowProc( wndPtr->lpfnWndProc, msg->hwnd, msg->message,
+ msg->wParam, msg->lParam );
+ if (painting && (wndPtr->flags & WIN_NEEDS_BEGINPAINT))
+ {
+#ifdef DEBUG_WIN
+ printf( "BeginPaint not called on WM_PAINT!\n" );
+#endif
+ wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
+ }
+ return retval;
}
@@ -398,7 +600,7 @@
*/
DWORD GetMessagePos(void)
{
- return msgQueue->GetMessagePosVal;
+ return appMsgQueue->GetMessagePosVal;
}
@@ -407,14 +609,27 @@
*/
LONG GetMessageTime(void)
{
- return msgQueue->GetMessageTimeVal;
+ return appMsgQueue->GetMessageTimeVal;
}
+
/***********************************************************************
* GetMessageExtraInfo (USER.288)
*/
LONG GetMessageExtraInfo(void)
{
- return msgQueue->GetMessageExtraInfoVal;
+ return appMsgQueue->GetMessageExtraInfoVal;
+}
+
+
+/***********************************************************************
+ * RegisterWindowMessage (USER.118)
+ */
+WORD RegisterWindowMessage( LPCSTR str )
+{
+#ifdef DEBUG_MSG
+ printf( "RegisterWindowMessage: '%s'\n", str );
+#endif
+ return GlobalAddAtom( str );
}
diff --git a/windows/painting.c b/windows/painting.c
index 4f21b13..5a8e60a 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -10,6 +10,7 @@
#include <X11/Xlib.h>
#include "win.h"
+#include "message.h"
/* Last CTLCOLOR id */
#define CTLCOLOR_MAX CTLCOLOR_STATIC
@@ -23,27 +24,21 @@
WND * wndPtr = WIN_FindWndPtr( hwnd );
if (!wndPtr) return 0;
- lps->hdc = GetDC( hwnd );
- if (!lps->hdc) return 0;
-
- SelectVisRgn( lps->hdc, wndPtr->hrgnUpdate );
+ if (!(lps->hdc = GetDCEx( hwnd, wndPtr->hrgnUpdate,
+ DCX_INTERSECTRGN | DCX_USESTYLE ))) return 0;
+ GetRgnBox( InquireVisRgn(lps->hdc), &lps->rcPaint );
+
if (wndPtr->hrgnUpdate)
{
- GetRgnBox( wndPtr->hrgnUpdate, &lps->rcPaint );
DeleteObject( wndPtr->hrgnUpdate );
wndPtr->hrgnUpdate = 0;
+ MSG_DecPaintCount( wndPtr->hmemTaskQ );
}
- else
- {
- lps->rcPaint.left = 0;
- lps->rcPaint.top = 0;
- lps->rcPaint.right = wndPtr->rectClient.right-wndPtr->rectClient.left;
- lps->rcPaint.bottom = wndPtr->rectClient.bottom-wndPtr->rectClient.top;
- }
-
+ wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
+
if (!(wndPtr->flags & WIN_ERASE_UPDATERGN)) lps->fErase = TRUE;
else lps->fErase = !SendMessage( hwnd, WM_ERASEBKGND, lps->hdc, 0 );
-
+
return lps->hdc;
}
@@ -63,12 +58,7 @@
void FillWindow( HWND hwndParent, HWND hwnd, HDC hdc, HBRUSH hbrush )
{
RECT rect;
- WND * wndPtr = WIN_FindWndPtr( hwnd );
- if (!wndPtr) return;
- rect.left = 0;
- rect.top = 0;
- rect.right = wndPtr->rectClient.right - wndPtr->rectClient.left;
- rect.bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
+ GetClientRect( hwnd, &rect );
PaintRect( hwndParent, hwnd, hdc, hbrush, &rect );
}
diff --git a/windows/timer.c b/windows/timer.c
index 2aeb88ee..da64961 100644
--- a/windows/timer.c
+++ b/windows/timer.c
@@ -6,21 +6,19 @@
static char Copyright[] = "Copyright Alexandre Julliard, 1993";
-#include <X11/Intrinsic.h>
-
#include "windows.h"
-
-extern XtAppContext XT_app_context;
+#include "message.h"
-typedef struct
+typedef struct tagTIMER
{
- HWND hwnd;
- WORD msg; /* WM_TIMER or WM_SYSTIMER */
- WORD id;
- WORD timeout;
- FARPROC proc;
- XtIntervalId xtid;
+ HWND hwnd;
+ WORD msg; /* WM_TIMER or WM_SYSTIMER */
+ WORD id;
+ WORD timeout;
+ struct tagTIMER *next;
+ DWORD expires;
+ FARPROC proc;
} TIMER;
#define NB_TIMERS 34
@@ -28,39 +26,100 @@
static TIMER TimersArray[NB_TIMERS];
+static TIMER * pNextTimer = NULL; /* Next timer to expire */
+
/***********************************************************************
- * TIMER_callback
+ * TIMER_InsertTimer
+ *
+ * Insert the timer at its place in the chain.
*/
-static void TIMER_callback( XtPointer data, XtIntervalId * xtid )
+static void TIMER_InsertTimer( TIMER * pTimer )
{
- TIMER * pTimer = (TIMER *) data;
-
- pTimer->xtid = 0; /* In case the timer procedure calls KillTimer */
-
- if (pTimer->proc)
+ if (!pNextTimer || (pTimer->expires < pNextTimer->expires))
{
- CallWindowProc(pTimer->proc, pTimer->hwnd, pTimer->msg,
- pTimer->id, GetTickCount());
+ pTimer->next = pNextTimer;
+ pNextTimer = pTimer;
}
- else
- PostMessage( pTimer->hwnd, pTimer->msg, pTimer->id, 0 );
+ else
+ {
+ TIMER * ptr = pNextTimer;
+ while (ptr->next && (pTimer->expires >= ptr->next->expires))
+ ptr = ptr->next;
+ pTimer->next = ptr;
+ ptr->next = pTimer;
+ }
+}
+
+
+/***********************************************************************
+ * TIMER_RemoveTimer
+ *
+ * Remove the timer from the chain.
+ */
+static void TIMER_RemoveTimer( TIMER * pTimer )
+{
+ if (pTimer == pNextTimer) pNextTimer = pTimer->next;
+ else
+ {
+ TIMER * ptr = pNextTimer;
+ while (ptr && (ptr->next != pTimer)) ptr = ptr->next;
+ if (ptr) ptr->next = pTimer->next;
+ }
+ pTimer->next = NULL;
+}
+
+
+/***********************************************************************
+ * TIMER_NextExpire
+ *
+ * Return time until next timer expiration (-1 if none).
+ */
+static DWORD TIMER_NextExpire( DWORD curTime )
+{
+ if (!pNextTimer) return -1;
+ if (pNextTimer->expires <= curTime) return 0;
+ return pNextTimer->expires - curTime;
+}
+
+
+/***********************************************************************
+ * TIMER_CheckTimer
+ *
+ * Check whether a timer has expired, and post a message if necessary.
+ * Return TRUE if msg posted, and return time until next expiration in 'next'.
+ */
+BOOL TIMER_CheckTimer( DWORD *next )
+{
+ TIMER * pTimer = pNextTimer;
+ DWORD curTime = GetTickCount();
+
+ if ((*next = TIMER_NextExpire( curTime )) != 0) return FALSE;
+
+ PostMessage( pTimer->hwnd, pTimer->msg, pTimer->id, (LONG)pTimer->proc );
+ TIMER_RemoveTimer( pTimer );
/* If timeout == 0, the timer has been removed by KillTimer */
if (pTimer->timeout)
- pTimer->xtid = XtAppAddTimeOut( XT_app_context, pTimer->timeout,
- TIMER_callback, pTimer );
+ {
+ /* Restart the timer */
+ pTimer->expires = curTime + pTimer->timeout;
+ TIMER_InsertTimer( pTimer );
+ }
+ *next = TIMER_NextExpire( curTime );
+ return TRUE;
}
/***********************************************************************
* TIMER_SetTimer
*/
-WORD TIMER_SetTimer( HWND hwnd, WORD id, WORD timeout, FARPROC proc, BOOL sys )
+static WORD TIMER_SetTimer( HWND hwnd, WORD id, WORD timeout,
+ FARPROC proc, BOOL sys )
{
int i;
TIMER * pTimer;
-
+
if (!timeout) return 0;
if (!hwnd && !proc) return 0;
@@ -79,9 +138,10 @@
pTimer->msg = sys ? WM_SYSTIMER : WM_TIMER;
pTimer->id = id;
pTimer->timeout = timeout;
+ pTimer->expires = GetTickCount() + timeout;
pTimer->proc = proc;
- pTimer->xtid = XtAppAddTimeOut( XT_app_context, timeout,
- TIMER_callback, pTimer );
+ TIMER_InsertTimer( pTimer );
+ MSG_IncTimerCount( GetTaskQueue(0) );
return id;
}
@@ -89,7 +149,7 @@
/***********************************************************************
* TIMER_KillTimer
*/
-BOOL TIMER_KillTimer( HWND hwnd, WORD id, BOOL sys )
+static BOOL TIMER_KillTimer( HWND hwnd, WORD id, BOOL sys )
{
int i;
TIMER * pTimer;
@@ -106,13 +166,13 @@
/* Delete the timer */
- if (pTimer->xtid) XtRemoveTimeOut( pTimer->xtid );
pTimer->hwnd = 0;
pTimer->msg = 0;
pTimer->id = 0;
pTimer->timeout = 0;
pTimer->proc = 0;
- pTimer->xtid = 0;
+ TIMER_RemoveTimer( pTimer );
+ MSG_DecTimerCount( GetTaskQueue(0) );
return TRUE;
}
@@ -123,7 +183,7 @@
WORD SetTimer( HWND hwnd, WORD id, WORD timeout, FARPROC proc )
{
#ifdef DEBUG_TIMER
- printf( "SetTimer: %d %d %d %08x\n", hwnd, id, timeout, proc );
+ printf( "SetTimer: %d %d %d %p\n", hwnd, id, timeout, proc );
#endif
return TIMER_SetTimer( hwnd, id, timeout, proc, FALSE );
}
@@ -135,7 +195,7 @@
WORD SetSystemTimer( HWND hwnd, WORD id, WORD timeout, FARPROC proc )
{
#ifdef DEBUG_TIMER
- printf( "SetSystemTimer: %d %d %d %08x\n", hwnd, id, timeout, proc );
+ printf( "SetSystemTimer: %d %d %d %p\n", hwnd, id, timeout, proc );
#endif
return TIMER_SetTimer( hwnd, id, timeout, proc, TRUE );
}
diff --git a/windows/win.c b/windows/win.c
index d7fe3a2..8411e48 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -10,11 +10,11 @@
#include <X11/StringDefs.h>
#include <X11/Core.h>
#include <X11/Shell.h>
-#include <X11/Xaw/Box.h>
#include "class.h"
#include "win.h"
#include "user.h"
+#include "dce.h"
extern Display * XT_display;
extern Screen * XT_screen;
@@ -22,10 +22,6 @@
static HWND firstWindow = 0;
-void SCROLLBAR_CreateScrollBar(LPSTR className, LPSTR Label, HWND hwnd);
-void LISTBOX_CreateListBox(LPSTR className, LPSTR Label, HWND hwnd);
-void COMBOBOX_CreateComboBox(LPSTR className, LPSTR Label, HWND hwnd);
-
/***********************************************************************
* WIN_FindWndPtr
*
@@ -43,6 +39,76 @@
/***********************************************************************
+ * WIN_UnlinkWindow
+ *
+ * Remove a window from the siblings linked list.
+ */
+BOOL WIN_UnlinkWindow( HWND hwnd )
+{
+ HWND * curWndPtr;
+ WND * wndPtr = WIN_FindWndPtr( hwnd );
+
+ if (!wndPtr) return FALSE;
+ if (wndPtr->hwndParent)
+ {
+ WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent );
+ curWndPtr = &parentPtr->hwndChild;
+ }
+ else curWndPtr = &firstWindow;
+
+ while (*curWndPtr != hwnd)
+ {
+ WND * curPtr = WIN_FindWndPtr( *curWndPtr );
+ curWndPtr = &curPtr->hwndNext;
+ }
+ *curWndPtr = wndPtr->hwndNext;
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * WIN_LinkWindow
+ *
+ * Insert a window into the siblings linked list.
+ * The window is inserted after the specified window, which can also
+ * be specified as HWND_TOP or HWND_BOTTOM.
+ */
+BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter )
+{
+ HWND * hwndPtr = NULL; /* pointer to hwnd to change */
+
+ WND * wndPtr = WIN_FindWndPtr( hwnd );
+ if (!wndPtr) return FALSE;
+
+ if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
+ {
+ /* Make hwndPtr point to the first sibling hwnd */
+ if (wndPtr->hwndParent)
+ {
+ WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent );
+ if (parentPtr) hwndPtr = &parentPtr->hwndChild;
+ }
+ else hwndPtr = &firstWindow;
+ if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
+ while (*hwndPtr)
+ {
+ WND * nextPtr = WIN_FindWndPtr( *hwndPtr );
+ hwndPtr = &nextPtr->hwndNext;
+ }
+ }
+ else /* Normal case */
+ {
+ WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
+ if (afterPtr) hwndPtr = &afterPtr->hwndNext;
+ }
+ if (!hwndPtr) return FALSE;
+ wndPtr->hwndNext = *hwndPtr;
+ *hwndPtr = hwnd;
+ return TRUE;
+}
+
+
+/***********************************************************************
* WIN_FindWinToRepaint
*
* Find a window that needs repaint.
@@ -55,8 +121,6 @@
for ( ; hwnd != 0; hwnd = wndPtr->hwndNext )
{
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
- if (!wndPtr || !wndPtr->winWidget) continue;
- if (!XtIsRealized( wndPtr->winWidget )) continue;
if (wndPtr->hrgnUpdate) return hwnd;
if (wndPtr->hwndChild)
{
@@ -114,9 +178,11 @@
CREATESTRUCT *createStruct;
HANDLE hcreateStruct;
int wmcreate;
+ short newwidth, newheight;
#ifdef DEBUG_WIN
- printf( "CreateWindowEx: %s %s %d,%d %dx%d\n", className, windowName, x, y, width, height );
+ printf( "CreateWindowEx: %s %s %d,%d %dx%d %08x\n",
+ className, windowName, x, y, width, height, style );
#endif
if (x == CW_USEDEFAULT) x = 0;
@@ -155,11 +221,12 @@
wndPtr->hwndOwner = parent; /* What else? */
wndPtr->hClass = class;
wndPtr->hInstance = instance;
- wndPtr->rectClient.left = x;
- wndPtr->rectClient.top = y;
- wndPtr->rectClient.right = x + width;
- wndPtr->rectClient.bottom = y + height;
- wndPtr->rectWindow = wndPtr->rectClient;
+ wndPtr->rectWindow.left = x;
+ wndPtr->rectWindow.top = y;
+ wndPtr->rectWindow.right = x + width;
+ wndPtr->rectWindow.bottom = y + height;
+ wndPtr->rectClient = wndPtr->rectWindow;
+ wndPtr->hmemTaskQ = GetTaskQueue(0);
wndPtr->hrgnUpdate = 0;
wndPtr->hwndLastActive = 0;
wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc;
@@ -169,43 +236,70 @@
wndPtr->wIDmenu = menu;
wndPtr->hText = 0;
wndPtr->flags = 0;
+ wndPtr->hCursor = 0;
+ wndPtr->hWndVScroll = 0;
+ wndPtr->hWndHScroll = 0;
if (classPtr->wc.cbWndExtra)
memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra );
- if (classPtr->wc.style & CS_OWNDC)
- wndPtr->hdc = CreateDC( "DISPLAY", NULL, NULL, NULL);
- else wndPtr->hdc = 0;
classPtr->cWindows++;
+ /* Get class or window DC if needed */
+ if (classPtr->wc.style & CS_OWNDC)
+ {
+ wndPtr->flags |= WIN_OWN_DC;
+ wndPtr->hdce = DCE_AllocDCE( DCE_WINDOW_DC );
+ }
+ else if (classPtr->wc.style & CS_CLASSDC)
+ {
+ wndPtr->flags |= WIN_CLASS_DC;
+ wndPtr->hdce = classPtr->hdce;
+ }
+ else wndPtr->hdce = 0;
+
/* Insert the window in the linked list */
- if (parent)
- {
- wndPtr->hwndNext = parentPtr->hwndChild;
- parentPtr->hwndChild = hwnd;
- }
- else /* Top-level window */
- {
- wndPtr->hwndNext = firstWindow;
- firstWindow = hwnd;
- }
-
- if (!strcasecmp(className, "SCROLLBAR"))
- {
- SCROLLBAR_CreateScrollBar(className, windowName, hwnd);
- goto WinCreated;
- }
- if (!strcasecmp(className, "LISTBOX"))
- {
- LISTBOX_CreateListBox(className, windowName, hwnd);
- goto WinCreated;
- }
+ WIN_LinkWindow( hwnd, HWND_TOP );
+
if (!strcasecmp(className, "COMBOBOX"))
{
- COMBOBOX_CreateComboBox(className, windowName, hwnd);
- goto WinCreated;
+ height = 16;
}
- /* Create the widgets */
+
+#ifdef USE_XLIB
+ {
+ XSetWindowAttributes win_attr;
+ Window parentWindow;
+ int x_rel, y_rel;
+
+ win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
+ PointerMotionMask | ButtonPressMask |
+ ButtonReleaseMask | StructureNotifyMask |
+ FocusChangeMask | EnterWindowMask;
+ win_attr.override_redirect = /*True*/ False;
+ win_attr.colormap = COLOR_WinColormap;
+ if (style & WS_CHILD)
+ {
+ parentWindow = parentPtr->window;
+ x_rel = x + parentPtr->rectClient.left-parentPtr->rectWindow.left;
+ y_rel = y + parentPtr->rectClient.top-parentPtr->rectWindow.top;
+ }
+ else
+ {
+ parentWindow = DefaultRootWindow( XT_display );
+ x_rel = x;
+ y_rel = y;
+ }
+ wndPtr->window = XCreateWindow( XT_display, parentWindow,
+ x_rel, y_rel, width, height, 0,
+ CopyFromParent, InputOutput,
+ CopyFromParent,
+ CWEventMask | CWOverrideRedirect |
+ CWColormap, &win_attr );
+ XStoreName( XT_display, wndPtr->window, windowName );
+ }
+#else
+ /* Create the widgets */
if (style & WS_CHILD)
{
@@ -223,6 +317,7 @@
XtNwidth, width,
XtNheight, height,
XtNborderColor, borderCol,
+ XtNmappedWhenManaged, FALSE,
NULL );
}
else
@@ -235,6 +330,7 @@
XtNwidth, width,
XtNheight, height,
XtNborderWidth, 0,
+ XtNmappedWhenManaged, FALSE,
NULL );
}
}
@@ -247,6 +343,7 @@
XtNx, x,
XtNy, y,
XtNcolormap, COLOR_WinColormap,
+ XtNmappedWhenManaged, FALSE,
NULL );
wndPtr->compositeWidget = XtVaCreateManagedWidget(className,
formWidgetClass,
@@ -296,8 +393,24 @@
NULL );
}
}
+ if (wndPtr->shellWidget) XtRealizeWidget( wndPtr->shellWidget );
+ if (wndPtr->compositeWidget) XtRealizeWidget( wndPtr->compositeWidget );
+ XtRealizeWidget( wndPtr->winWidget );
+ wndPtr->window = XtWindow( wndPtr->winWidget );
+#endif /* USE_XLIB */
-WinCreated:
+ if ((style & WS_VSCROLL) == WS_VSCROLL) {
+ newheight = height - (((style & WS_HSCROLL) == WS_HSCROLL) ? 16 : 0);
+ wndPtr->hWndVScroll = CreateWindow("SCROLLBAR", "",
+ WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_VERT,
+ width - 16, 0, 16, newheight, hwnd, 2, instance, 0L);
+ }
+ if ((style & WS_HSCROLL) == WS_HSCROLL) {
+ newwidth = width - (((style & WS_VSCROLL) == WS_VSCROLL) ? 16 : 0);
+ wndPtr->hWndHScroll = CreateWindow("SCROLLBAR", "",
+ WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_HORZ,
+ 0, height - 16, newwidth, 16, hwnd, 3, instance, 0L);
+ }
/* Send the WM_CREATE message */
@@ -318,7 +431,24 @@
wmcreate = SendMessage( hwnd, WM_NCCREATE, 0, (LONG)createStruct );
if (!wmcreate) wmcreate = -1;
- else wmcreate = SendMessage( hwnd, WM_CREATE, 0, (LONG)createStruct );
+ else
+ {
+ /* Send WM_NCCALCSIZE message */
+ NCCALCSIZE_PARAMS *params;
+ HANDLE hparams;
+ hparams = GlobalAlloc( GMEM_MOVEABLE, sizeof(*params) );
+ if (hparams)
+ {
+ params = (NCCALCSIZE_PARAMS *) GlobalLock( hparams );
+ params->rgrc[0] = wndPtr->rectWindow;
+ params->lppos = NULL;
+ SendMessage( hwnd, WM_NCCALCSIZE, FALSE, (LONG)params );
+ wndPtr->rectClient = params->rgrc[0];
+ GlobalUnlock( hparams );
+ GlobalFree( hparams );
+ }
+ wmcreate = SendMessage( hwnd, WM_CREATE, 0, (LONG)createStruct );
+ }
GlobalUnlock( hcreateStruct );
GlobalFree( hcreateStruct );
@@ -329,18 +459,27 @@
if (parent) parentPtr->hwndChild = wndPtr->hwndNext;
else firstWindow = wndPtr->hwndNext;
+#ifdef USE_XLIB
+ XDestroyWindow( XT_display, wndPtr->window );
+#else
if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget );
else XtDestroyWidget( wndPtr->winWidget );
- if (wndPtr->hdc) DeleteDC( wndPtr->hdc );
+#endif
+ if (wndPtr->flags & WIN_OWN_DC) DCE_FreeDCE( wndPtr->hdce );
classPtr->cWindows--;
USER_HEAP_FREE( hwnd );
return 0;
}
-
- EVENT_AddHandlers( wndPtr->winWidget, hwnd );
- if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
+#ifdef USE_XLIB
+ EVENT_AddHandlers( wndPtr->window, hwnd );
+#else
+ EVENT_AddHandlers( wndPtr->winWidget, hwnd );
+#endif
+
WIN_SendParentNotify( hwnd, wndPtr, WM_CREATE );
+
+ if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
return hwnd;
}
@@ -350,7 +489,6 @@
BOOL DestroyWindow( HWND hwnd )
{
WND * wndPtr;
- HWND * curWndPtr;
CLASS * classPtr;
/* Initialisation */
@@ -366,30 +504,24 @@
/* Destroy all children */
+ if (wndPtr->hWndVScroll) DestroyWindow(wndPtr->hWndVScroll);
+ if (wndPtr->hWndHScroll) DestroyWindow(wndPtr->hWndHScroll);
while (wndPtr->hwndChild) /* The child removes itself from the list */
DestroyWindow( wndPtr->hwndChild );
/* Remove the window from the linked list */
- if (wndPtr->hwndParent)
- {
- WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent );
- curWndPtr = &parentPtr->hwndChild;
- }
- else curWndPtr = &firstWindow;
-
- while (*curWndPtr != hwnd)
- {
- WND * curPtr = WIN_FindWndPtr( *curWndPtr );
- curWndPtr = &curPtr->hwndNext;
- }
- *curWndPtr = wndPtr->hwndNext;
+ WIN_UnlinkWindow( hwnd );
/* Destroy the window */
+#ifdef USE_XLIB
+ XDestroyWindow( XT_display, wndPtr->window );
+#else
if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget );
else XtDestroyWidget( wndPtr->winWidget );
- if (wndPtr->hdc) DeleteDC( wndPtr->hdc );
+#endif
+ if (wndPtr->flags & WIN_OWN_DC) DCE_FreeDCE( wndPtr->hdce );
classPtr->cWindows--;
USER_HEAP_FREE( hwnd );
return TRUE;
@@ -397,100 +529,6 @@
/***********************************************************************
- * GetWindowRect (USER.32)
- */
-void GetWindowRect( HWND hwnd, LPRECT rect )
-{
- int x, y, width, height;
- WND * wndPtr = WIN_FindWndPtr( hwnd );
-
- if (wndPtr)
- {
- XtVaGetValues(wndPtr->winWidget,
- XtNx, &x, XtNy, &y,
- XtNwidth, &width,
- XtNheight, &height,
- NULL );
- rect->left = x & 0xffff;
- rect->top = y & 0xffff;
- rect->right = width & 0xffff;
- rect->bottom = height & 0xffff;
- }
-}
-
-
-/***********************************************************************
- * GetClientRect (USER.33)
- */
-void GetClientRect( HWND hwnd, LPRECT rect )
-{
- int width, height;
- WND * wndPtr = WIN_FindWndPtr( hwnd );
-
- rect->left = rect->top = rect->right = rect->bottom = 0;
- if (wndPtr)
- {
- XtVaGetValues(wndPtr->winWidget,
- XtNwidth, &width,
- XtNheight, &height,
- NULL );
- rect->right = width & 0xffff;
- rect->bottom = height & 0xffff;
- }
-}
-
-
-/***********************************************************************
- * ShowWindow (USER.42)
- */
-BOOL ShowWindow( HWND hwnd, int cmd )
-{
- int width, height;
-
- WND * wndPtr = WIN_FindWndPtr( hwnd );
- if (wndPtr)
- {
- if (wndPtr->shellWidget) XtRealizeWidget( wndPtr->shellWidget );
- XtVaGetValues(wndPtr->winWidget,
- XtNwidth, &width,
- XtNheight, &height,
- NULL );
- switch(cmd)
- {
- case SW_HIDE:
- XtSetMappedWhenManaged(wndPtr->winWidget, FALSE);
- wndPtr->dwStyle &= (WS_VISIBLE ^ 0xFFFFFFFL);
- SendMessage( hwnd, WM_SHOWWINDOW, FALSE, 0 );
- break;
- case SW_SHOWMINNOACTIVE:
- case SW_SHOWMINIMIZED:
- case SW_MINIMIZE:
- wndPtr->dwStyle |= WS_ICONIC;
- goto WINVisible;
- case SW_SHOWNA:
- case SW_SHOWNOACTIVATE:
- case SW_MAXIMIZE:
- case SW_SHOWMAXIMIZED:
- case SW_SHOW:
- case SW_NORMAL:
- case SW_SHOWNORMAL:
- wndPtr->dwStyle &= (WS_ICONIC ^ 0xFFFFFFFL);
-WINVisible:
- XtSetMappedWhenManaged(wndPtr->winWidget, TRUE);
- wndPtr->dwStyle |= WS_VISIBLE;
- SendMessage( hwnd, WM_SIZE, SIZE_RESTORED,
- (width & 0xffff) | (height << 16) );
- SendMessage( hwnd, WM_SHOWWINDOW, TRUE, 0 );
- break;
- default:
- break;
- }
- }
- return TRUE;
-}
-
-
-/***********************************************************************
* CloseWindow (USER.43)
*/
void CloseWindow(HWND hWnd)
@@ -498,7 +536,6 @@
WND * wndPtr = WIN_FindWndPtr(hWnd);
if (wndPtr->dwStyle & WS_CHILD) return;
ShowWindow(hWnd, SW_MINIMIZE);
- PostMessage(hWnd, WM_CLOSE, 0, 0L);
}
@@ -508,7 +545,6 @@
*/
BOOL OpenIcon(HWND hWnd)
{
- WND * wndPtr = WIN_FindWndPtr(hWnd);
if (!IsIconic(hWnd)) return FALSE;
ShowWindow(hWnd, SW_SHOWNORMAL);
return(TRUE);
@@ -523,35 +559,9 @@
{
return((HWND)NULL);
}
-
/***********************************************************************
- * MoveWindow (USER.56)
- */
-void MoveWindow(HWND hWnd, short x, short y, short w, short h, BOOL bRepaint)
-{
- WND * wndPtr = WIN_FindWndPtr( hWnd );
- if (wndPtr)
- {
- wndPtr->rectClient.left = x;
- wndPtr->rectClient.top = y;
- wndPtr->rectClient.right = x + w;
- wndPtr->rectClient.bottom = y + h;
- XtVaSetValues(wndPtr->winWidget, XtNx, x, XtNy, y,
- XtNwidth, w, XtNheight, h, NULL );
- SendMessage(hWnd, WM_MOVE, 0, MAKELONG(x, y));
- printf("MoveWindow(%X, %d, %d, %d, %d, %d); !\n",
- hWnd, x, y, w, h, bRepaint);
- if (bRepaint) {
- InvalidateRect(hWnd, NULL, TRUE);
- UpdateWindow(hWnd);
- }
- }
-}
-
-
-/***********************************************************************
* UpdateWindow (USER.124)
*/
void UpdateWindow( HWND hwnd )
@@ -578,8 +588,10 @@
*/
BOOL SetMenu(HWND hwnd, HMENU hmenu)
{
+#ifdef USE_XLIB
+ return FALSE;
+#else
WND *wndPtr;
-
wndPtr = WIN_FindWndPtr(hwnd);
if (wndPtr == NULL)
return FALSE;
@@ -618,44 +630,7 @@
}
return TRUE;
-}
-
-
-/***********************************************************************
- * SetWindowPos (USER.232)
- */
-void SetWindowPos(HWND hWnd, HWND hWndInsertAfter, short x, short y, short w, short h, WORD wFlag)
-{
- WND * wndPtr = WIN_FindWndPtr( hWnd );
- if (wndPtr)
- {
- if ((wFlag & SWP_NOMOVE) != SWP_NOMOVE) {
- wndPtr->rectClient.left = x;
- wndPtr->rectClient.top = y;
- XtVaSetValues(wndPtr->winWidget, XtNx, x, XtNy, y, NULL );
- }
- if ((wFlag & SWP_NOSIZE) != SWP_NOSIZE) {
- wndPtr->rectClient.right = x + w;
- wndPtr->rectClient.bottom = y + h;
- XtVaSetValues(wndPtr->winWidget, XtNwidth, w, XtNheight, h, NULL );
- }
- if ((wFlag & SWP_NOREDRAW) != SWP_NOREDRAW) {
- InvalidateRect(hWnd, NULL, TRUE);
- UpdateWindow(hWnd);
- }
- if ((wFlag & SWP_HIDEWINDOW) == SWP_HIDEWINDOW)
- ShowWindow(hWnd, SW_HIDE);
- if ((wFlag & SWP_SHOWWINDOW) == SWP_SHOWWINDOW)
- ShowWindow(hWnd, SW_SHOW);
-/*
- if ((wFlag & SWP_NOACTIVATE) != SWP_NOACTIVATE)
- SetActiveWindow(hWnd);
- if ((wFlag & SWP_NOZORDER) != SWP_NOZORDER)
- { }
-*/
- printf("SetWindowPos(%X, %X, %d, %d, %d, %d, %X); !\n",
- hWnd, hWndInsertAfter, x, y, w, h, wFlag);
- }
+#endif /* USE_XLIB */
}
@@ -748,21 +723,6 @@
}
-/***********************************************************************
- * IsIconic (USER.31)
- */
-BOOL IsIconic(HWND hWnd)
-{
- WND * wndPtr;
- if (hWnd == 0) return(FALSE);
- wndPtr = WIN_FindWndPtr(hWnd);
- if (wndPtr == 0) return(FALSE);
- if (wndPtr->dwStyle & WS_ICONIC) return(TRUE);
- return(FALSE);
-}
-
-
-
/*******************************************************************
* GetWindowText (USER.36)
*/
@@ -796,7 +756,7 @@
BOOL IsWindow( HWND hwnd )
{
WND * wndPtr = WIN_FindWndPtr( hwnd );
- return (wndPtr->dwMagic == WND_MAGIC);
+ return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
}
@@ -806,6 +766,7 @@
HWND GetParent(HWND hwnd)
{
WND *wndPtr = WIN_FindWndPtr(hwnd);
+ if (!wndPtr) return 0;
return wndPtr->hwndParent;
}
@@ -838,14 +799,9 @@
*/
BOOL IsWindowVisible(HWND hWnd)
{
- WND * wndPtr;
- if (hWnd == 0) return(FALSE);
- wndPtr = WIN_FindWndPtr(hWnd);
+ WND * wndPtr = WIN_FindWndPtr(hWnd);
if (wndPtr == 0) return(FALSE);
- if (wndPtr->dwStyle & WS_VISIBLE) {
- if (XtIsRealized(wndPtr->winWidget)) return(TRUE);
- }
- return(FALSE);
+ else return ((wndPtr->dwStyle & WS_VISIBLE) != 0);
}
diff --git a/windows/winpos.c b/windows/winpos.c
new file mode 100644
index 0000000..0b474e2
--- /dev/null
+++ b/windows/winpos.c
@@ -0,0 +1,389 @@
+/*
+ * Window position related functions.
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright Alexandre Julliard, 1993";
+
+#include "win.h"
+
+extern Display * XT_display;
+extern Screen * XT_screen;
+
+
+/***********************************************************************
+ * GetWindowRect (USER.32)
+ */
+void GetWindowRect( HWND hwnd, LPRECT rect )
+{
+ WND * wndPtr = WIN_FindWndPtr( hwnd );
+ if (!wndPtr) return;
+
+ *rect = wndPtr->rectWindow;
+ if (wndPtr->hwndParent)
+ MapWindowPoints( wndPtr->hwndParent, 0, (POINT *)rect, 2 );
+}
+
+
+/***********************************************************************
+ * GetClientRect (USER.33)
+ */
+void GetClientRect( HWND hwnd, LPRECT rect )
+{
+ WND * wndPtr = WIN_FindWndPtr( hwnd );
+
+ rect->left = rect->top = rect->right = rect->bottom = 0;
+ if (wndPtr)
+ {
+ rect->right = wndPtr->rectClient.right - wndPtr->rectClient.left;
+ rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
+ }
+}
+
+
+/*******************************************************************
+ * ClientToScreen (USER.28)
+ */
+void ClientToScreen( HWND hwnd, LPPOINT lppnt )
+{
+ MapWindowPoints( hwnd, 0, lppnt, 1 );
+}
+
+
+/*******************************************************************
+ * ScreenToClient (USER.29)
+ */
+void ScreenToClient( HWND hwnd, LPPOINT lppnt )
+{
+ MapWindowPoints( 0, hwnd, lppnt, 1 );
+}
+
+
+/*******************************************************************
+ * MapWindowPoints (USER.258)
+ */
+void MapWindowPoints( HWND hwndFrom, HWND hwndTo, LPPOINT lppt, WORD count )
+{
+ WND * wndPtr;
+ POINT * curpt;
+ POINT origin = { 0, 0 };
+ WORD i;
+
+ /* Translate source window origin to screen coords */
+ while(hwndFrom)
+ {
+ wndPtr = WIN_FindWndPtr( hwndFrom );
+ origin.x += wndPtr->rectClient.left;
+ origin.y += wndPtr->rectClient.top;
+ hwndFrom = wndPtr->hwndParent;
+ }
+
+ /* Translate origin to destination window coords */
+ while(hwndTo)
+ {
+ wndPtr = WIN_FindWndPtr( hwndTo );
+ origin.x -= wndPtr->rectClient.left;
+ origin.y -= wndPtr->rectClient.top;
+ hwndTo = wndPtr->hwndParent;
+ }
+
+ /* Translate points */
+ for (i = 0, curpt = lppt; i < count; i++, curpt++)
+ {
+ curpt->x += origin.x;
+ curpt->y += origin.y;
+ }
+}
+
+
+/***********************************************************************
+ * IsIconic (USER.31)
+ */
+BOOL IsIconic(HWND hWnd)
+{
+ WND * wndPtr = WIN_FindWndPtr(hWnd);
+ if (wndPtr == NULL) return FALSE;
+ return (wndPtr->dwStyle & WS_MINIMIZE) != 0;
+}
+
+
+/***********************************************************************
+ * IsZoomed (USER.272)
+ */
+BOOL IsZoomed(HWND hWnd)
+{
+ WND * wndPtr = WIN_FindWndPtr(hWnd);
+ if (wndPtr == NULL) return FALSE;
+ return (wndPtr->dwStyle & WS_MAXIMIZE) != 0;
+}
+
+
+/***********************************************************************
+ * MoveWindow (USER.56)
+ */
+BOOL MoveWindow( HWND hwnd, short x, short y, short cx, short cy, BOOL repaint)
+{
+ int flags = SWP_NOZORDER | SWP_NOACTIVATE;
+ if (!repaint) flags |= SWP_NOREDRAW;
+#ifdef DEBUG_WIN
+ printf( "MoveWindow: %d %d,%d %dx%d %d\n", hwnd, x, y, cx, cy, repaint );
+#endif
+ return SetWindowPos( hwnd, 0, x, y, cx, cy, flags );
+}
+
+
+/***********************************************************************
+ * ShowWindow (USER.42)
+ */
+BOOL ShowWindow( HWND hwnd, int cmd )
+{
+ WND * wndPtr = WIN_FindWndPtr( hwnd );
+ BOOL wasVisible;
+ int swpflags = 0;
+
+#ifdef DEBUG_WIN
+ printf("ShowWindow: hwnd=%d, cmd=%d\n", hwnd, cmd);
+#endif
+
+ if (!wndPtr) return FALSE;
+ wasVisible = (wndPtr->dwStyle & WS_VISIBLE) != 0;
+ switch(cmd)
+ {
+ case SW_HIDE:
+ if (!wasVisible) return FALSE; /* Nothing to do */
+ swpflags |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE |
+ SWP_NOACTIVATE | SWP_NOZORDER;
+ break;
+
+ case SW_SHOWMINNOACTIVE:
+ case SW_SHOWMINIMIZED:
+ case SW_MINIMIZE:
+ wndPtr->dwStyle |= WS_MINIMIZE;
+ swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE |
+ SWP_NOACTIVATE | SWP_NOZORDER;
+ break;
+
+ case SW_SHOWNA:
+ case SW_SHOWNOACTIVATE:
+ case SW_MAXIMIZE:
+ case SW_SHOWMAXIMIZED:
+ case SW_SHOW:
+ case SW_NORMAL:
+ case SW_SHOWNORMAL:
+ wndPtr->dwStyle &= ~WS_MINIMIZE;
+ swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE |
+ SWP_NOACTIVATE | SWP_NOZORDER;
+ break;
+ }
+ SendMessage( hwnd, WM_SHOWWINDOW, (cmd != SW_HIDE), 0 );
+ SetWindowPos( hwnd, 0, 0, 0, 0, 0, swpflags );
+
+ /* Send WM_SIZE and WM_MOVE messages if not already done */
+ if (!(wndPtr->flags & WIN_GOT_SIZEMSG))
+ {
+ int wParam = SIZE_RESTORED;
+ if (wndPtr->dwStyle & WS_MAXIMIZE) wParam = SIZE_MAXIMIZED;
+ else if (wndPtr->dwStyle & WS_MINIMIZE) wParam = SIZE_MINIMIZED;
+ wndPtr->flags |= WIN_GOT_SIZEMSG;
+ SendMessage( hwnd, WM_SIZE, wParam,
+ MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
+ wndPtr->rectClient.bottom-wndPtr->rectClient.top));
+ SendMessage( hwnd, WM_MOVE, 0,
+ MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) );
+ }
+ return wasVisible;
+}
+
+
+/***********************************************************************
+ * SetWindowPos (USER.232)
+ */
+/* Unimplemented flags: SWP_NOREDRAW, SWP_NOACTIVATE
+ */
+/* Note: all this code should be in the DeferWindowPos() routines,
+ * and SetWindowPos() should simply call them. This will be implemented
+ * some day...
+ */
+BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, short x, short y,
+ short cx, short cy, WORD flags )
+{
+ WINDOWPOS *winPos;
+ HANDLE hmem = 0;
+ RECT newWindowRect, newClientRect;
+ WND *wndPtr;
+ int calcsize_result = 0;
+#ifdef USE_XLIB
+ XWindowChanges winChanges;
+ int changeMask = 0;
+#endif
+
+#ifdef DEBUG_WIN
+ printf( "SetWindowPos: %d %d %d,%d %dx%d 0x%x\n",
+ hwnd, hwndInsertAfter, x, y, cx, cy, flags );
+#endif
+
+ if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
+ if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW))
+ flags |= SWP_NOMOVE | SWP_NOSIZE;
+
+ /* Send WM_WINDOWPOSCHANGING message */
+
+ if (!(hmem = GlobalAlloc( GMEM_MOVEABLE,sizeof(WINDOWPOS) ))) return FALSE;
+ winPos = (WINDOWPOS *)GlobalLock( hmem );
+ winPos->hwnd = hwnd;
+ winPos->hwndInsertAfter = hwndInsertAfter;
+ winPos->x = x;
+ winPos->y = y;
+ winPos->cx = cx;
+ winPos->cy = cy;
+ winPos->flags = flags;
+ SendMessage( hwnd, WM_WINDOWPOSCHANGING, 0, (LONG)winPos );
+
+ /* Calculate new position and size */
+
+ newWindowRect = wndPtr->rectWindow;
+ newClientRect = wndPtr->rectClient;
+
+ if (!(winPos->flags & SWP_NOSIZE))
+ {
+ newWindowRect.right = newWindowRect.left + winPos->cx;
+ newWindowRect.bottom = newWindowRect.top + winPos->cy;
+ }
+
+ if (!(winPos->flags & SWP_NOMOVE))
+ {
+ newWindowRect.left = winPos->x;
+ newWindowRect.top = winPos->y;
+ newWindowRect.right += winPos->x - wndPtr->rectWindow.left;
+ newWindowRect.bottom += winPos->y - wndPtr->rectWindow.top;
+ }
+
+ /* Reposition window in Z order */
+
+ if (!(winPos->flags & SWP_NOZORDER))
+ {
+ hwndInsertAfter = winPos->hwndInsertAfter;
+
+ /* TOPMOST not supported yet */
+ if ((hwndInsertAfter == HWND_TOPMOST) ||
+ (hwndInsertAfter == HWND_NOTOPMOST)) hwndInsertAfter = HWND_TOP;
+
+ /* Make sure hwndInsertAfter is a sibling of hwnd */
+ if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM))
+ if (wndPtr->hwndParent != GetParent(hwndInsertAfter)) goto Abort;
+
+ WIN_UnlinkWindow( hwnd );
+ WIN_LinkWindow( hwnd, hwndInsertAfter );
+ }
+
+ /* Recalculate client area position */
+
+ if (winPos->flags & SWP_FRAMECHANGED)
+ {
+ /* Send WM_NCCALCSIZE message */
+ NCCALCSIZE_PARAMS *params;
+ HANDLE hparams;
+
+ if (!(hparams = GlobalAlloc( GMEM_MOVEABLE, sizeof(*params) )))
+ goto Abort;
+ params = (NCCALCSIZE_PARAMS *) GlobalLock( hparams );
+ params->rgrc[0] = newWindowRect;
+ params->rgrc[1] = wndPtr->rectWindow;
+ params->rgrc[2] = wndPtr->rectClient;
+ params->lppos = winPos;
+ calcsize_result = SendMessage(hwnd, WM_NCCALCSIZE, TRUE, (LONG)params);
+ GlobalUnlock( hparams );
+ GlobalFree( hparams );
+ newClientRect = params->rgrc[0];
+ /* Handle result here */
+ }
+ else
+ {
+ newClientRect.left = newWindowRect.left + wndPtr->rectClient.left
+ - wndPtr->rectWindow.left;
+ newClientRect.top = newWindowRect.top + wndPtr->rectClient.top
+ - wndPtr->rectWindow.top;
+ newClientRect.right = newWindowRect.right + wndPtr->rectClient.right
+ - wndPtr->rectWindow.right;
+ newClientRect.bottom = newWindowRect.bottom + wndPtr->rectClient.bottom
+ - wndPtr->rectWindow.bottom;
+ }
+
+ /* Perform the moving and resizing */
+#ifdef USE_XLIB
+ if (!(winPos->flags & SWP_NOMOVE))
+ {
+ WND * parentPtr;
+ winChanges.x = newWindowRect.left;
+ winChanges.y = newWindowRect.top;
+ if (wndPtr->hwndParent)
+ {
+ parentPtr = WIN_FindWndPtr(wndPtr->hwndParent);
+ winChanges.x += parentPtr->rectClient.left-parentPtr->rectWindow.left;
+ winChanges.y += parentPtr->rectClient.top-parentPtr->rectWindow.top;
+ }
+ changeMask |= CWX | CWY;
+ }
+ if (!(winPos->flags & SWP_NOSIZE))
+ {
+ winChanges.width = newWindowRect.right - newWindowRect.left;
+ winChanges.height = newWindowRect.bottom - newWindowRect.top;
+ changeMask |= CWWidth | CWHeight;
+ }
+ if (!(winPos->flags & SWP_NOZORDER))
+ {
+ if (hwndInsertAfter == HWND_TOP) winChanges.stack_mode = Above;
+ else winChanges.stack_mode = Below;
+ if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM))
+ {
+ WND * insertPtr = WIN_FindWndPtr( hwndInsertAfter );
+ winChanges.sibling = insertPtr->window;
+ changeMask |= CWSibling;
+ }
+ changeMask |= CWStackMode;
+ }
+ if (changeMask) XConfigureWindow( XT_display, wndPtr->window,
+ changeMask, &winChanges );
+#endif
+
+ if (winPos->flags & SWP_SHOWWINDOW)
+ {
+ wndPtr->dwStyle |= WS_VISIBLE;
+#ifdef USE_XLIB
+ XMapWindow( XT_display, wndPtr->window );
+#else
+ if (wndPtr->shellWidget) XtMapWidget( wndPtr->shellWidget );
+ else XtMapWidget( wndPtr->winWidget );
+#endif
+ }
+ else if (winPos->flags & SWP_HIDEWINDOW)
+ {
+ wndPtr->dwStyle &= ~WS_VISIBLE;
+#ifdef USE_XLIB
+ XUnmapWindow( XT_display, wndPtr->window );
+#else
+ if (wndPtr->shellWidget) XtUnmapWidget( wndPtr->shellWidget );
+ else XtUnmapWidget( wndPtr->winWidget );
+#endif
+ }
+
+ /* Finally send the WM_WINDOWPOSCHANGED message */
+ wndPtr->rectWindow = newWindowRect;
+ wndPtr->rectClient = newClientRect;
+ SendMessage( hwnd, WM_WINDOWPOSCHANGED, 0, (LONG)winPos );
+ GlobalUnlock( hmem );
+ GlobalFree( hmem );
+
+ return TRUE;
+
+ Abort: /* Fatal error encountered */
+ if (hmem)
+ {
+ GlobalUnlock( hmem );
+ GlobalFree( hmem );
+ }
+ return FALSE;
+}
+
+