Release 960928
Fri Sep 27 14:18:42 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [controls/button.c]
Fixed focus rectangle size and clipping.
* [controls/scroll.c]
Converted to Win32 and added support for scroll page.
Completed SetScrollInfo() and implemented other Win32 functions.
* [files/file.c]
Removed FILE_Read() (use _lread32 instead).
* [objects/dce.c] [include/dce.h]
Allocate DCE on the Win32 heap, and use pointers instead of
handles.
Implemented Win32 version of DC functions.
* [windows/painting.c]
Attempt to make CS_PARENTDC style work again.
Wed Sep 25 23:40:52 1996 Alex Korobka <alex@trantor.pharm.sunysb.edu>
* [windows/dce.c] [windows/winpos.c]
Override SaveUnder attribute when painting took place
in a window below. Force X to raise activated window
in seamless mode.
* [misc/clipboard.c] [windows/event.c]
Translation between DOS and Unix text formats and several
other fixes for the sudden selection loss.
* [windows/message.c]
Apply "first" and "last" when checking for WM_QUIT in
MSG_PeekMessage().
* [windows/win.c]
Rearranged DestroyWindow() to fit "Windows Internals"
description.
* [windows/win.c] [windows/winpos.c] [windows/nonclient.c]
Misc. fixes to CBT hook calls.
* [controls/menu.c] [misc/user.c]
Fixup resident popup menu window so that it doesn't get
destroyed by USER_AppExit().
* [loader/module.c] [loader/task.c] [windows/event.c]
Process "unsafe" X events outside the scheduler to prevent
deadlocks.
* [windows/message.c] [windows/queue.c] [windows/winpos.c]
Lots of fixes for better Win16 multitasking.
Wed Sep 25 20:36:30 1996 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
* [include/windows.h]
Added some missing HOOK defines.
* [misc/shell.c][if1632/shell32.spec][include/shell.h]
SHGetFileInfoA stub added (win95 mplayer.exe /play bla.avi).
* [win32/console.c][include/wincon.h]
GetConsoleScreenBufferInfo, GetLargestConsoleWindowSize added.
* [misc/registry.c]
Some null ptr fixes.
* [loader/pe_image.c]
Fixed exported function lookup. (msvcrt20.dll)
Add debugsyms for entrypoint, exported functions and sections.
* [multimedia/mmsystem.c]
MCIOpen: support for element opens (mplayer.exe /play bla.avi).
* [several]
Added several missing things/stubs/simple thunks from win32
to win16 code.
Sat Sep 21 17:27:44 1996 O.Flebbe <flebbe@science-computing.uni-tuebingen.de>
* [windows/property.c]
Fixed debugging of 16 Bit RemoveProp().
* [debugger/memory.c]
Added DEBUG_checkmap_bad() for linux.
Thu Sep 19 20:48:31 1996 Albrecht Kleine <kleine@ak.sax.de>
* [windows/event.c] [windows/hook.c]
Use EnableHardwareInput() for JournalPlayback hook.
* [controls/listbox.c]
Changed handling of LB_GETITEMRECT in empty listboxes.
Thu Sep 19 13:34:35 1996 Slaven Rezic <eserte@cs.tu-berlin.de>
* [misc/main.c]
Fixes to X resources handling.
Wed Sep 18 00:31:15 1996 Huw D. M. Davies <h.davies1@physics.oxford.ac.uk>
* [objects/metafile.c] [include/gdi.h] [objects/dc.c]
Individual handle table created for each metafile. Fixed
GlobalReAlloc() bug in MF_AddHandleDC() (was MF_AddHandleInternal).
* [windows/graphics.c] [objects/dc.c]
Rectangle() changed to work better with wide pens and PS_NULL.
Use JoinMiter.
* [windows/winpos.c]
Make the whole (non X) window invalid on resize if CS_[VH]REDRAW
is set.
* [windows/nonclient.c]
AdjustWindowRectEx() should perform calculations even if the
window is minimized.
* [windows/mdi.c]
Better handling of system button painting. Maximized windows can
contain scroll bars. Icons now maximize properly.
* [windows/defwnd.c] [windows/nonclient.c] [controls/menu.c]
Improved greying of items in system menu. WM_INITMEMUPOPUP no
longer caught in DefWndProc, DEFWND_InitSysMenuPopup moved to
menu.c.
Mon Sep 16 21:30:00 1996 Uwe Bonnes <bon@elektron.ikp.physik.th-darmstadt.de>
* [several files]
Fix missing includes and wrong printing arguments.
* [controls/listbox.c]
Don't sort drives in ListBoxDirectory().
Sat Sep 14 09:05:47 1996 Petri Tuomola <ptuomola@xs4all.nl>
* [windows/dialog.c]
Fixed handling of Shift-TAB in dialogs.
Thu Sep 12 18:31:00 1996 Thomas Sandford <t.d.g.sandford@prds-grn.demon.co.uk>
* [if1632/gdi32.spec]
Added SelectClipRgn - call win16 version.
* [if1632/user32.spec]
Added GetAsyncKeyState, GetMenuItemID and GetMenuStringA.
* [include/wincon.h]
Added COORD and SMALL_RECT typedefs, moved CONSOLE_SCREEN_BUFFER_INFO
out of #if 0 protected portion of file.
* [loader/pe_image.c]
PE_InitTEB() - Tidy up, bug fix to stack pointer value (Borland
programs now work better)
* [win32/console.c]
Added stub functions for GetConsoleScreenBufferInfo and
GetLargestConsoleWindowSize
* [win32/findfile.c]
FindFirstFile32A() - removed erroneous strcpy
* [windows/keyboard.c]
GetAsyncKeyState() - bug fix - now returns value as per Microsoft
specification. NB - I still have doubts about some other functions
in this file.
diff --git a/windows/caret.c b/windows/caret.c
index e7f4b65..86acfa3 100644
--- a/windows/caret.c
+++ b/windows/caret.c
@@ -49,7 +49,7 @@
*/
static void CARET_DisplayCaret( DISPLAY_CARET status )
{
- HDC16 hdc;
+ HDC32 hdc;
HBRUSH16 hPrevBrush;
if (Caret.on && (status == CARET_ON)) return;
@@ -58,11 +58,11 @@
/* So now it's always a toggle */
Caret.on = !Caret.on;
- if (!(hdc = GetDCEx( Caret.hwnd, 0, DCX_USESTYLE | DCX_CACHE ))) return;
+ if (!(hdc = GetDCEx32( Caret.hwnd, 0, DCX_USESTYLE | DCX_CACHE ))) return;
hPrevBrush = SelectObject( hdc, Caret.hBrush );
PatBlt( hdc, Caret.x, Caret.y, Caret.width, Caret.height, PATINVERT );
SelectObject( hdc, hPrevBrush );
- ReleaseDC( Caret.hwnd, hdc );
+ ReleaseDC32( Caret.hwnd, hdc );
}
diff --git a/windows/class.c b/windows/class.c
index e956801..c89e96f 100644
--- a/windows/class.c
+++ b/windows/class.c
@@ -44,10 +44,10 @@
fprintf( stderr, "Class %p:\n", ptr );
fprintf( stderr,
"next=%p name=%04x '%s' style=%08x wndProc=%08x\n"
- "inst=%04x hdce=%04x icon=%04x cursor=%04x bkgnd=%04x\n"
+ "inst=%04x dce=%08x icon=%04x cursor=%04x bkgnd=%04x\n"
"clsExtra=%d winExtra=%d #windows=%d\n",
ptr->next, ptr->atomName, className, ptr->style,
- (UINT32)ptr->winproc, ptr->hInstance, ptr->hdce,
+ (UINT32)ptr->winproc, ptr->hInstance, (UINT32)ptr->dce,
ptr->hIcon, ptr->hCursor, ptr->hbrBackground,
ptr->cbClsExtra, ptr->cbWndExtra, ptr->cWindows );
if (ptr->cbClsExtra)
@@ -181,7 +181,7 @@
/* Delete the class */
- if (classPtr->hdce) DCE_FreeDCE( classPtr->hdce );
+ if (classPtr->dce) DCE_FreeDCE( classPtr->dce );
if (classPtr->hbrBackground) DeleteObject( classPtr->hbrBackground );
GlobalDeleteAtom( classPtr->atomName );
CLASS_SetMenuNameA( classPtr, NULL );
@@ -288,7 +288,9 @@
classPtr->atomName = atom;
classPtr->menuNameA = 0;
classPtr->menuNameW = 0;
- classPtr->hdce = (style&CS_CLASSDC) ? DCE_AllocDCE(0, DCE_CLASS_DC): 0;
+ classPtr->dce = (style & CS_CLASSDC) ?
+ DCE_AllocDCE( 0, DCE_CLASS_DC ) : NULL;
+
WINPROC_SetProc( &classPtr->winproc, wndProc, wndProcType );
/* Other values must be set by caller */
diff --git a/windows/dce.c b/windows/dce.c
index b52d547..7afa5f7 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -19,7 +19,7 @@
#include "class.h"
#include "win.h"
#include "gdi.h"
-#include "user.h"
+#include "heap.h"
#include "sysmetrics.h"
#include "stddebug.h"
/* #define DEBUG_DC */
@@ -27,7 +27,7 @@
#define NB_DCE 5 /* Number of DCEs created at startup */
-static HANDLE firstDCE = 0;
+static DCE *firstDCE = 0;
static HDC defaultDCstate = 0;
BOOL DCHook(HDC, WORD, DWORD, DWORD);
@@ -37,26 +37,24 @@
*
* Allocate a new DCE.
*/
-HANDLE DCE_AllocDCE( HWND hWnd, DCE_TYPE type )
+DCE *DCE_AllocDCE( HWND32 hWnd, DCE_TYPE type )
{
DCE * dce;
- HANDLE handle = USER_HEAP_ALLOC( sizeof(DCE) );
- if (!handle) return 0;
- dce = (DCE *) USER_HEAP_LIN_ADDR( handle );
+ if (!(dce = HeapAlloc( SystemHeap, 0, sizeof(DCE) ))) return NULL;
if (!(dce->hDC = CreateDC( "DISPLAY", NULL, NULL, NULL )))
{
- USER_HEAP_FREE( handle );
+ HeapFree( SystemHeap, 0, dce );
return 0;
}
/* store DCE handle in DC hook data field */
- SetDCHook(dce->hDC, GDI_GetDefDCHook(), MAKELONG(handle,DC_MAGIC));
+ SetDCHook(dce->hDC, GDI_GetDefDCHook(), (DWORD)dce);
dce->hwndCurrent = hWnd;
- dce->hNext = firstDCE;
- dce->hClipRgn = 0;
- firstDCE = handle;
+ dce->hClipRgn = 0;
+ dce->next = firstDCE;
+ firstDCE = dce;
if( type != DCE_CACHE_DC )
{
@@ -72,77 +70,60 @@
}
else dce->DCXflags = DCX_CACHE;
- return handle;
+ return dce;
}
/***********************************************************************
* DCE_FreeDCE
*/
-void DCE_FreeDCE( HANDLE hdce )
+void DCE_FreeDCE( DCE *dce )
{
- DCE * dce;
- HANDLE *handle = &firstDCE;
+ DCE **ppDCE = &firstDCE;
- if (!(dce = (DCE *) USER_HEAP_LIN_ADDR( hdce ))) return;
- while (*handle && (*handle != hdce))
- {
- DCE * prev = (DCE *) USER_HEAP_LIN_ADDR( *handle );
- handle = &prev->hNext;
- }
- if (*handle == hdce) *handle = dce->hNext;
+ if (!dce) return;
+ while (*ppDCE && (*ppDCE != dce)) ppDCE = &(*ppDCE)->next;
+ if (*ppDCE == dce) *ppDCE = dce->next;
SetDCHook(dce->hDC,(SEGPTR)NULL,0L);
DeleteDC( dce->hDC );
if( dce->hClipRgn && !(dce->DCXflags & DCX_KEEPCLIPRGN) )
DeleteObject(dce->hClipRgn);
- USER_HEAP_FREE( hdce );
+ HeapFree( SystemHeap, 0, dce );
}
-/***********************************************************************
- * DCE_FindDCE
- */
-HANDLE DCE_FindDCE(HDC hDC)
-{
- HANDLE hdce = firstDCE;
- DCE* dce;
-
- while( hdce )
- {
- dce = (DCE *) USER_HEAP_LIN_ADDR(hdce);
- if( dce->hDC == hDC ) break;
- hdce = dce->hNext;
- }
- return hdce;
-}
/**********************************************************************
- * WindowFromDC (USER.117) (USER32.580)
+ * WindowFromDC16 (USER32.580)
*/
-HWND16 WindowFromDC( HDC32 hDC )
+HWND16 WindowFromDC16( HDC16 hDC )
{
- HANDLE16 hdce = DCE_FindDCE(hDC);
-
- if( hdce )
- {
- DCE* dce = (DCE *) USER_HEAP_LIN_ADDR(hdce);
- return dce->hwndCurrent;
- }
-
- return 0;
+ return (HWND16)WindowFromDC32( hDC );
}
+
+/**********************************************************************
+ * WindowFromDC32 (USER32.580)
+ */
+HWND32 WindowFromDC32( HDC32 hDC )
+{
+ DCE *dce = firstDCE;
+ while (dce && (dce->hDC != hDC)) dce = dce->next;
+ return dce ? dce->hwndCurrent : 0;
+}
+
+
/***********************************************************************
* DCE_InvalidateDCE
*
* It is called from SetWindowPos - we have to invalidate all busy
* DCE's for windows whose client rect intersects with update rectangle
*/
-BOOL DCE_InvalidateDCE(WND* wndScope, RECT16* pRectUpdate)
+BOOL32 DCE_InvalidateDCE(WND* wndScope, RECT16* pRectUpdate)
{
- HANDLE hdce;
- DCE* dce;
+ BOOL32 bRet = FALSE;
+ DCE *dce;
if( !wndScope ) return 0;
@@ -151,10 +132,8 @@
pRectUpdate->right,pRectUpdate->bottom);
/* walk all DCE's */
- for( hdce = firstDCE; (hdce); hdce=dce->hNext)
+ for (dce = firstDCE; (dce); dce = dce->next)
{
- dce = (DCE*)USER_HEAP_LIN_ADDR(hdce);
-
if( dce->DCXflags & DCX_DCEBUSY )
{
WND * wndCurrent, * wnd;
@@ -177,12 +156,15 @@
MapWindowPoints16(wndCurrent->parent->hwndSelf, wndScope->hwndSelf,
(LPPOINT16)&wndRect, 2);
if( IntersectRect16(&wndRect,&wndRect,pRectUpdate) )
- SetHookFlags(dce->hDC, DCHF_INVALIDATEVISRGN);
+ {
+ SetHookFlags(dce->hDC, DCHF_INVALIDATEVISRGN);
+ bRet = TRUE;
+ }
break;
}
}
}
- return 1;
+ return bRet;
}
/***********************************************************************
@@ -191,13 +173,11 @@
void DCE_Init()
{
int i;
- HANDLE handle;
DCE * dce;
for (i = 0; i < NB_DCE; i++)
{
- if (!(handle = DCE_AllocDCE( 0, DCE_CACHE_DC ))) return;
- dce = (DCE *) USER_HEAP_LIN_ADDR( handle );
+ if (!(dce = DCE_AllocDCE( 0, DCE_CACHE_DC ))) return;
if (!defaultDCstate) defaultDCstate = GetDCState( dce->hDC );
}
}
@@ -400,14 +380,23 @@
}
}
+
/***********************************************************************
- * GetDCEx (USER.359)
+ * GetDCEx16 (USER.359)
+ */
+HDC16 GetDCEx16( HWND16 hwnd, HRGN16 hrgnClip, DWORD flags )
+{
+ return (HDC16)GetDCEx32( hwnd, hrgnClip, flags );
+}
+
+
+/***********************************************************************
+ * GetDCEx32 (USER32.230)
*
* Unimplemented flags: DCX_LOCKWINDOWUPDATE
*/
-HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
+HDC32 GetDCEx32( HWND32 hwnd, HRGN32 hrgnClip, DWORD flags )
{
- HANDLE hdce;
HRGN hrgnVisible;
HDC hdc = 0;
DCE * dce;
@@ -446,7 +435,8 @@
flags &= ~(DCX_PARENTCLIP | DCX_CLIPCHILDREN);
}
- if (hwnd==GetDesktopWindow() || !(wndPtr->dwStyle & WS_CHILD)) flags &= ~DCX_PARENTCLIP;
+ if (hwnd == GetDesktopWindow32() || !(wndPtr->dwStyle & WS_CHILD))
+ flags &= ~DCX_PARENTCLIP;
if (flags & DCX_WINDOW) flags = (flags & ~DCX_CLIPCHILDREN) | DCX_CACHE;
@@ -464,17 +454,14 @@
if (flags & DCX_CACHE)
{
- for (hdce = firstDCE; (hdce); hdce = dce->hNext)
+ for (dce = firstDCE; (dce); dce = dce->next)
{
- if (!(dce = (DCE *) USER_HEAP_LIN_ADDR( hdce ))) return 0;
if ((dce->DCXflags & DCX_CACHE) && !(dce->DCXflags & DCX_DCEBUSY)) break;
}
}
else
{
- hdce = (wndPtr->class->style & CS_OWNDC)?wndPtr->hdce:wndPtr->class->hdce;
- dce = (DCE *) USER_HEAP_LIN_ADDR( hdce );
-
+ dce = (wndPtr->class->style & CS_OWNDC)?wndPtr->dce:wndPtr->class->dce;
if( dce->hwndCurrent == hwnd )
{
dprintf_dc(stddeb,"\tskipping hVisRgn update\n");
@@ -491,8 +478,7 @@
dcx_flags = flags & ( DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_CACHE | DCX_WINDOW | DCX_WINDOWPAINT);
- if (!hdce) return 0;
- dce = (DCE *) USER_HEAP_LIN_ADDR( hdce );
+ if (!dce) return 0;
dce->hwndCurrent = hwnd;
dce->hClipRgn = 0;
dce->DCXflags = dcx_flags | DCX_DCEBUSY;
@@ -502,7 +488,7 @@
DCE_SetDrawable( wndPtr, dc, flags );
if( need_update || dc->w.flags & DC_DIRTY )
- {
+ {
dprintf_dc(stddeb,"updating hDC anyway\n");
if (flags & DCX_PARENTCLIP)
@@ -521,16 +507,27 @@
}
/* optimize away GetVisRgn for desktop if it isn't there */
- else if ((hwnd == GetDesktopWindow()) &&
+ else if ((hwnd == GetDesktopWindow32()) &&
(rootWindow == DefaultRootWindow(display)))
hrgnVisible = CreateRectRgn( 0, 0, SYSMETRICS_CXSCREEN,
SYSMETRICS_CYSCREEN);
else hrgnVisible = DCE_GetVisRgn( hwnd, flags );
- dc->w.flags &= ~DC_DIRTY;
+ if( wndPtr->parent && wndPtr->window )
+ {
+ WND* wnd = wndPtr->parent->child;
+ RECT16 rect;
+
+ for( ; wnd != wndPtr; wnd = wnd->next )
+ if( wnd->class->style & CS_SAVEBITS &&
+ wnd->dwStyle & WS_VISIBLE &&
+ IntersectRect16(&rect, &wndPtr->rectClient, &wnd->rectClient) )
+ wnd->flags |= WIN_SAVEUNDER_OVERRIDE;
+ }
+ dc->w.flags &= ~DC_DIRTY;
SelectVisRgn( hdc, hrgnVisible );
- }
+ }
else hrgnVisible = CreateRectRgn(0,0,0,0);
if ((flags & DCX_INTERSECTRGN) || (flags & DCX_EXCLUDERGN))
@@ -552,49 +549,67 @@
return hdc;
}
-/***********************************************************************
- * GetDC (USER.66)
- */
-HDC GetDC( HWND hwnd )
-{
- if( !hwnd ) return GetDCEx( GetDesktopWindow(), 0, DCX_CACHE | DCX_WINDOW );
- return GetDCEx( hwnd, 0, DCX_USESTYLE );
+/***********************************************************************
+ * GetDC16 (USER.66)
+ */
+HDC16 GetDC16( HWND16 hwnd )
+{
+ return (HDC16)GetDC32( hwnd );
}
/***********************************************************************
- * GetWindowDC (USER.67)
+ * GetDC32 (USER32.229)
*/
-HDC GetWindowDC( HWND hwnd )
+HDC32 GetDC32( HWND32 hwnd )
{
- if (hwnd)
- {
- WND * wndPtr;
- if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
- }
- else hwnd = GetDesktopWindow();
-
- return GetDCEx( hwnd, 0, DCX_USESTYLE | DCX_WINDOW );
+ if (!hwnd)
+ return GetDCEx32( GetDesktopWindow32(), 0, DCX_CACHE | DCX_WINDOW );
+ return GetDCEx32( hwnd, 0, DCX_USESTYLE );
}
/***********************************************************************
- * ReleaseDC (USER.68)
+ * GetWindowDC16 (USER.67)
*/
-int ReleaseDC( HWND hwnd, HDC hdc )
+HDC16 GetWindowDC16( HWND16 hwnd )
{
- HANDLE hdce;
- DCE * dce = NULL;
+ if (!hwnd) hwnd = GetDesktopWindow16();
+ return GetDCEx16( hwnd, 0, DCX_USESTYLE | DCX_WINDOW );
+}
+
+
+/***********************************************************************
+ * GetWindowDC32 (USER32.)
+ */
+HDC32 GetWindowDC32( HWND32 hwnd )
+{
+ if (!hwnd) hwnd = GetDesktopWindow32();
+ return GetDCEx32( hwnd, 0, DCX_USESTYLE | DCX_WINDOW );
+}
+
+
+/***********************************************************************
+ * ReleaseDC16 (USER.68)
+ */
+INT16 ReleaseDC16( HWND16 hwnd, HDC16 hdc )
+{
+ return (INT32)ReleaseDC32( hwnd, hdc );
+}
+
+
+/***********************************************************************
+ * ReleaseDC32 (USER32.439)
+ */
+INT32 ReleaseDC32( HWND32 hwnd, HDC32 hdc )
+{
+ DCE * dce = firstDCE;
dprintf_dc(stddeb, "ReleaseDC: %04x %04x\n", hwnd, hdc );
- for (hdce = firstDCE; (hdce); hdce = dce->hNext)
- {
- if (!(dce = (DCE *) USER_HEAP_LIN_ADDR( hdce ))) return 0;
- if (dce->hDC == hdc) break;
- }
- if (!hdce) return 0;
+ while (dce && (dce->hDC != hdc)) dce = dce->next;
+ if (!dce) return 0;
if (!(dce->DCXflags & DCX_DCEBUSY) ) return 0;
/* restore previous visible region */
@@ -631,24 +646,18 @@
*/
BOOL DCHook(HDC hDC, WORD code, DWORD data, DWORD lParam)
{
- HANDLE hdce;
- HRGN hVisRgn;
+ HRGN32 hVisRgn;
+ DCE *dce = firstDCE;;
- dprintf_dc(stddeb,"DCHook: hDC = %04x, %i\n", hDC, code);
+ dprintf_dc(stddeb,"DCHook: hDC = %04x, %i\n", hDC, code);
- if( HIWORD(data) == DC_MAGIC )
- hdce = (HANDLE)LOWORD(data);
- else
- hdce = DCE_FindDCE(hDC);
-
- if( !hdce ) return 0;
+ while (dce && (dce->hDC != hDC)) dce = dce->next;
+ if (!dce) return 0;
switch( code )
{
case DCHC_INVALIDVISRGN:
{
- DCE* dce = (DCE*) USER_HEAP_LIN_ADDR(hdce);
-
if( dce->DCXflags & DCX_DCEBUSY )
{
SetHookFlags(hDC, DCHF_VALIDATEVISRGN);
diff --git a/windows/defwnd.c b/windows/defwnd.c
index e1767ae..7284cd1 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -29,31 +29,6 @@
static short iF10Key = 0;
static short iMenuSysKey = 0;
-
-/***********************************************************************
- * DEFWND_InitSysMenuPopup
- *
- * Handle the WM_INITMENUPOPUP message on the system menu.
- */
-static void DEFWND_InitSysMenuPopup( HMENU hmenu, DWORD style, DWORD clsStyle )
-{
- BOOL gray;
-
- gray = !(style & WS_THICKFRAME) || (style & (WS_MAXIMIZE | WS_MINIMIZE));
- EnableMenuItem( hmenu, SC_SIZE, (gray ? MF_GRAYED : MF_ENABLED) );
- gray = ((style & WS_MAXIMIZE) != 0);
- EnableMenuItem( hmenu, SC_MOVE, (gray ? MF_GRAYED : MF_ENABLED) );
- gray = !(style & WS_MINIMIZEBOX) || (style & WS_MINIMIZE);
- EnableMenuItem( hmenu, SC_MINIMIZE, (gray ? MF_GRAYED : MF_ENABLED) );
- gray = !(style & WS_MAXIMIZEBOX) || (style & WS_MAXIMIZE);
- EnableMenuItem( hmenu, SC_MAXIMIZE, (gray ? MF_GRAYED : MF_ENABLED) );
- gray = !(style & (WS_MAXIMIZE | WS_MINIMIZE));
- EnableMenuItem( hmenu, SC_RESTORE, (gray ? MF_GRAYED : MF_ENABLED) );
- gray = (clsStyle & CS_NOCLOSE) != 0;
- EnableMenuItem( hmenu, SC_CLOSE, (gray ? MF_GRAYED : MF_ENABLED) );
-}
-
-
/***********************************************************************
* DEFWND_HandleWindowPosChanged
*
@@ -322,17 +297,10 @@
ShowWindow( wndPtr->hwndSelf, wParam ? SW_SHOWNOACTIVATE : SW_HIDE );
break;
- case WM_INITMENUPOPUP:
- /* Not absolutely sure this belongs here -- AJ */
- if (HIWORD(lParam)) /* system menu */
- DEFWND_InitSysMenuPopup( (HMENU)wParam, wndPtr->dwStyle,
- wndPtr->class->style );
- break;
-
case WM_CANCELMODE:
/* EndMenu() should be called if in menu state but currently it's
impossible to detect - menu code should be updated*/
- if (GetCapture() == wndPtr->hwndSelf) ReleaseCapture();
+ if (GetCapture32() == wndPtr->hwndSelf) ReleaseCapture();
break;
case WM_VKEYTOITEM:
diff --git a/windows/dialog.c b/windows/dialog.c
index 44511b3..fe31129 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -514,13 +514,12 @@
{
TEXTMETRIC16 tm;
HFONT oldFont;
- HDC hdc;
- hdc = GetDC(0);
+ HDC32 hdc = GetDC32(0);
oldFont = SelectObject( hdc, hFont );
GetTextMetrics16( hdc, &tm );
SelectObject( hdc, oldFont );
- ReleaseDC( 0, hdc );
+ ReleaseDC32( 0, hdc );
xUnit = tm.tmAveCharWidth;
yUnit = tm.tmHeight;
if (tm.tmPitchAndFamily & TMPF_FIXED_PITCH)
@@ -744,8 +743,8 @@
if (dlgInfo->fEnd) break;
}
retval = dlgInfo->msgResult;
- DestroyWindow( hwnd );
EnableWindow( owner, TRUE );
+ DestroyWindow( hwnd );
return retval;
}
@@ -897,7 +896,7 @@
if (!(dlgCode & DLGC_WANTTAB))
{
SendMessage16( hwndDlg, WM_NEXTDLGCTL,
- (GetKeyState(VK_SHIFT) & 0x80), 0 );
+ (GetKeyState(VK_SHIFT) & 0x8000), 0 );
return TRUE;
}
break;
diff --git a/windows/event.c b/windows/event.c
index 3759ac0..77532ea 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -22,17 +22,18 @@
#include "windows.h"
#include "gdi.h"
#include "heap.h"
+#include "queue.h"
#include "win.h"
#include "class.h"
#include "clipboard.h"
#include "debugger.h"
-#include "hook.h"
#include "message.h"
#include "module.h"
#include "options.h"
#include "queue.h"
#include "winpos.h"
#include "registers.h"
+#include "xmalloc.h"
#include "stddebug.h"
#include "debug.h"
#include "dde_proc.h"
@@ -52,8 +53,8 @@
WPARAM lastEventChar = 0; /* this will have to be changed once
* ToAscii starts working */
-static HWND captureWnd = 0;
-static BOOL InputEnabled = TRUE;
+static HWND32 captureWnd = 0;
+static BOOL32 InputEnabled = TRUE;
/* Keyboard translation tables */
static const int special_key[] =
@@ -174,17 +175,17 @@
{
case KeyPress:
case KeyRelease:
- if (!HOOK_GetHook(WH_JOURNALPLAYBACK, 0) )
+ if (InputEnabled)
EVENT_key( (XKeyEvent*)event );
break;
case ButtonPress:
- if (!HOOK_GetHook(WH_JOURNALPLAYBACK, 0) )
+ if (InputEnabled)
EVENT_ButtonPress( (XButtonEvent*)event );
break;
case ButtonRelease:
- if (!HOOK_GetHook(WH_JOURNALPLAYBACK, 0) )
+ if (InputEnabled)
EVENT_ButtonRelease( (XButtonEvent*)event );
break;
@@ -197,7 +198,7 @@
problems if the event order is important. I'm not yet seen
of any problems. Jon 7/6/96.
*/
- if (!HOOK_GetHook(WH_JOURNALPLAYBACK, 0) )
+ if (InputEnabled)
{
while (XCheckTypedWindowEvent(display,((XAnyEvent *)event)->window,
MotionNotify, event));
@@ -240,6 +241,7 @@
case ClientMessage:
EVENT_ClientMessage( pWnd, (XClientMessageEvent *) event );
break;
+
/* case EnterNotify:
* EVENT_EnterNotify( pWnd, (XCrossingEvent *) event );
* break;
@@ -287,7 +289,7 @@
* Return TRUE if an event is pending, FALSE on timeout or error
* (for instance lost connection with the server).
*/
-BOOL32 EVENT_WaitXEvent( BOOL32 sleep )
+BOOL32 EVENT_WaitXEvent( BOOL32 sleep, BOOL32 peek )
{
fd_set read_set;
struct timeval timeout;
@@ -335,6 +337,7 @@
}
/* Process the event (and possibly others that occurred in the meantime) */
+
do
{
@@ -346,8 +349,39 @@
}
#endif /* CONFIG_IPC */
- XNextEvent( display, &event );
- EVENT_ProcessEvent( &event );
+ XNextEvent( display, &event );
+
+ if( peek )
+ {
+ WND* pWnd;
+ MESSAGEQUEUE* pQ;
+
+ if( XFindContext( display, ((XAnyEvent *)&event)->window, winContext, (char **)&pWnd)
+ || event.type == NoExpose )
+ continue;
+
+ /* check for the "safe" hardware events */
+
+ if( event.type == MotionNotify ||
+ event.type == ButtonPress || event.type == ButtonRelease ||
+ event.type == KeyPress || event.type == KeyRelease ||
+ event.type == SelectionRequest || event.type == SelectionClear )
+ {
+ EVENT_ProcessEvent( &event );
+ continue;
+ }
+
+ if( pWnd )
+ if( (pQ = (MESSAGEQUEUE*)GlobalLock16(pWnd->hmemTaskQ)) )
+ {
+ pQ->flags |= QUEUE_FLAG_XEVENT;
+ PostEvent(pQ->hTask);
+ XPutBackEvent(display, &event);
+ break;
+ }
+ }
+ else
+ EVENT_ProcessEvent( &event );
}
while (XPending( display ));
return TRUE;
@@ -684,7 +718,7 @@
* window structure is created. WIN_GetDesktop() check is a hack.
*/
- if ( !WIN_GetDesktop() || hwnd == GetDesktopWindow())
+ if ( !WIN_GetDesktop() || hwnd == GetDesktopWindow32())
{
desktopX = event->x;
desktopY = event->y;
@@ -694,7 +728,7 @@
WND *wndPtr;
WINDOWPOS16 *winpos;
RECT16 newWindowRect, newClientRect;
- HRGN hrgnOldPos, hrgnNewPos;
+ HRGN hrgnOldPos, hrgnNewPos;
if (!(wndPtr = WIN_FindWndPtr( hwnd )) ||
!(wndPtr->flags & WIN_MANAGED) )
@@ -702,6 +736,9 @@
if (!(winpos = SEGPTR_NEW(WINDOWPOS16))) return;
+/* XTranslateCoordinates(display, event->window, rootWindow,
+ event->x, event->y, &event->x, &event->y, &child);
+ */
/* Fill WINDOWPOS struct */
winpos->flags = SWP_NOACTIVATE | SWP_NOZORDER;
@@ -764,24 +801,45 @@
if(event->target == XA_STRING)
{
HANDLE hText;
- LPSTR text;
+ LPSTR text;
+ int size,i,j;
rprop = event->property;
if(rprop == None) rprop = event->target;
if(event->selection!=XA_PRIMARY) rprop = None;
- else if(!CLIPBOARD_IsPresent(CF_TEXT)) rprop = None;
- else{
- /* Don't worry if we can't open */
- BOOL couldOpen=OpenClipboard( pWnd->hwndSelf );
- hText=GetClipboardData(CF_TEXT);
- text=GlobalLock16(hText);
- XChangeProperty(display,request,rprop,XA_STRING,
- 8,PropModeReplace,text,strlen(text));
- GlobalUnlock16(hText);
+ else if(!CLIPBOARD_IsPresent(CF_OEMTEXT)) rprop = None;
+ else
+ {
+ /* open to make sure that clipboard is available */
+
+ BOOL couldOpen = OpenClipboard( pWnd->hwndSelf );
+ char* lpstr = 0;
+
+ hText = GetClipboardData(CF_TEXT);
+ text = GlobalLock16(hText);
+ size = GlobalSize16(hText);
+
+ /* remove carriage returns */
+
+ lpstr = (char*)xmalloc(size--);
+ for(i=0,j=0; i < size; i++ )
+ {
+ if( text[i] == '\r' && text[i+1] == '\n' ) continue;
+ lpstr[j++] = text[i];
+ if( text[i] == '\0' ) break;
+ }
+ lpstr[j]='\0';
+
+ XChangeProperty(display, request, rprop,
+ XA_STRING, 8, PropModeReplace,
+ lpstr, j);
+ free(lpstr);
+
/* close only if we opened before */
- if(couldOpen)CloseClipboard();
+
+ if(couldOpen) CloseClipboard();
}
}
@@ -805,8 +863,11 @@
static void EVENT_SelectionNotify( XSelectionEvent *event )
{
if (event->selection != XA_PRIMARY) return;
+
if (event->target != XA_STRING) CLIPBOARD_ReadSelection( 0, None );
- CLIPBOARD_ReadSelection( event->requestor, event->property );
+ else CLIPBOARD_ReadSelection( event->requestor, event->property );
+
+ dprintf_clipboard(stddeb,"\tSelectionNotify done!\n");
}
@@ -816,7 +877,7 @@
static void EVENT_SelectionClear( WND *pWnd, XSelectionClearEvent *event )
{
if (event->selection != XA_PRIMARY) return;
- CLIPBOARD_ReleaseSelection( pWnd->hwndSelf );
+ CLIPBOARD_ReleaseSelection( event->window, pWnd->hwndSelf );
}
@@ -857,6 +918,8 @@
}
*/
+extern void FOCUS_SetXFocus( HWND32 );
+
/**********************************************************************
* EVENT_MapNotify
*/
@@ -865,18 +928,28 @@
HWND32 hwndFocus = GetFocus32();
if (hwndFocus && IsChild( hWnd, hwndFocus ))
- FOCUS_SetXFocus( hwndFocus );
+ FOCUS_SetXFocus( (HWND32)hwndFocus );
return;
}
+
/**********************************************************************
- * SetCapture (USER.18)
+ * SetCapture16 (USER.18)
*/
-HWND SetCapture( HWND hwnd )
+HWND16 SetCapture16( HWND16 hwnd )
+{
+ return (HWND16)SetCapture32( hwnd );
+}
+
+
+/**********************************************************************
+ * SetCapture32 (USER32.463)
+ */
+HWND32 SetCapture32( HWND32 hwnd )
{
Window win;
- HWND old_capture_wnd = captureWnd;
+ HWND32 old_capture_wnd = captureWnd;
if (!hwnd)
{
@@ -898,9 +971,9 @@
/**********************************************************************
- * ReleaseCapture (USER.19)
+ * ReleaseCapture (USER.19) (USER32.438)
*/
-void ReleaseCapture()
+void ReleaseCapture(void)
{
if (captureWnd == 0) return;
XUngrabPointer( display, CurrentTime );
@@ -908,10 +981,20 @@
dprintf_win(stddeb, "ReleaseCapture\n");
}
+
/**********************************************************************
- * GetCapture (USER.236)
+ * GetCapture16 (USER.236)
*/
-HWND GetCapture()
+HWND16 GetCapture16(void)
+{
+ return (HWND16)captureWnd;
+}
+
+
+/**********************************************************************
+ * GetCapture32 (USER32.207)
+ */
+HWND32 GetCapture32(void)
{
return captureWnd;
}
@@ -971,13 +1054,13 @@
/**********************************************************************
- * EnableHardwareInput [USER.331]
+ * EnableHardwareInput (USER.331)
*/
-BOOL EnableHardwareInput(BOOL bEnable)
+BOOL16 EnableHardwareInput(BOOL16 bEnable)
{
- BOOL bOldState = InputEnabled;
- dprintf_event(stdnimp,"EMPTY STUB !!! EnableHardwareInput(%d);\n", bEnable);
+ BOOL16 bOldState = InputEnabled;
+ dprintf_event(stdnimp,"EnableHardwareInput(%d);\n", bEnable);
InputEnabled = bEnable;
- return (bOldState && !bEnable);
+ return bOldState;
}
diff --git a/windows/graphics.c b/windows/graphics.c
index e64aa2f..aca1f6c 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -12,6 +12,7 @@
#ifndef PI
#define PI M_PI
#endif
+#include "graphics.h"
#include "dc.h"
#include "bitmap.h"
#include "callback.h"
@@ -279,6 +280,7 @@
*/
BOOL Rectangle( HDC hdc, INT left, INT top, INT right, INT bottom )
{
+ INT32 width;
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc)
{
@@ -305,21 +307,24 @@
dc->w.DCOrgY + bottom);
return TRUE;
}
-
+ width = dc->u.x.pen.width;
+ if (!width) width = 1;
+ if(dc->u.x.pen.style == PS_NULL) width = 0;
+
if ((dc->u.x.pen.style == PS_INSIDEFRAME) &&
- (dc->u.x.pen.width < right-left) &&
- (dc->u.x.pen.width < bottom-top))
+ (width < right-left) && (width < bottom-top))
{
- left += dc->u.x.pen.width / 2;
- right -= (dc->u.x.pen.width + 1) / 2;
- top += dc->u.x.pen.width / 2;
- bottom -= (dc->u.x.pen.width + 1) / 2;
+ left += width / 2;
+ right -= (width + 1) / 2;
+ top += width / 2;
+ bottom -= (width + 1) / 2;
}
if (DC_SetupGCForBrush( dc ))
XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
- dc->w.DCOrgX + left, dc->w.DCOrgY + top,
- right-left, bottom-top );
+ dc->w.DCOrgX + left + (width + 1) / 2,
+ dc->w.DCOrgY + top + (width + 1) / 2,
+ right-left-width-1, bottom-top-width-1);
if (DC_SetupGCForPen( dc ))
XDrawRectangle( display, dc->u.x.drawable, dc->u.x.gc,
dc->w.DCOrgX + left, dc->w.DCOrgY + top,
@@ -745,8 +750,8 @@
* Short-cut function to blit a bitmap into a device.
* Faster than CreateCompatibleDC() + SelectBitmap() + BitBlt() + DeleteDC().
*/
-BOOL GRAPH_DrawBitmap( HDC hdc, HBITMAP hbitmap, int xdest, int ydest,
- int xsrc, int ysrc, int width, int height )
+BOOL32 GRAPH_DrawBitmap( HDC32 hdc, HBITMAP32 hbitmap, int xdest, int ydest,
+ int xsrc, int ysrc, int width, int height )
{
BITMAPOBJ *bmp;
DC *dc;
@@ -778,8 +783,8 @@
/**********************************************************************
* GRAPH_DrawReliefRect (Not a MSWin Call)
*/
-void GRAPH_DrawReliefRect( HDC hdc, RECT16 *rect, int highlight_size,
- int shadow_size, BOOL pressed )
+void GRAPH_DrawReliefRect( HDC32 hdc, const RECT32 *rect, INT32 highlight_size,
+ INT32 shadow_size, BOOL32 pressed )
{
HBRUSH hbrushOld;
int i;
diff --git a/windows/hook.c b/windows/hook.c
index 6f9f09a..ce58107 100644
--- a/windows/hook.c
+++ b/windows/hook.c
@@ -37,7 +37,7 @@
if (data->next) return data->next;
if (!data->ownerQueue) return 0; /* Already system hook */
/* Now start enumerating the system hooks */
- return HOOK_systemHooks[data->id - WH_FIRST_HOOK];
+ return HOOK_systemHooks[data->id - WH_MINHOOK];
}
@@ -52,8 +52,8 @@
HANDLE16 hook = 0;
if ((queue = (MESSAGEQUEUE *)GlobalLock16( hQueue )) != NULL)
- hook = queue->hooks[id - WH_FIRST_HOOK];
- if (!hook) hook = HOOK_systemHooks[id - WH_FIRST_HOOK];
+ hook = queue->hooks[id - WH_MINHOOK];
+ if (!hook) hook = HOOK_systemHooks[id - WH_MINHOOK];
return hook;
}
@@ -70,7 +70,7 @@
HANDLE16 handle;
HQUEUE16 hQueue = 0;
- if ((id < WH_FIRST_HOOK) || (id > WH_LAST_HOOK)) return 0;
+ if ((id < WH_MINHOOK) || (id > WH_MAXHOOK)) return 0;
if (!(hInst = GetExePtr( hInst ))) return 0;
dprintf_hook( stddeb, "Setting hook %d: %08x %04x %04x\n",
@@ -83,12 +83,19 @@
if (!(hQueue = GetTaskQueue( hTask ))) return 0;
}
- if (id == WH_CBT || id == WH_DEBUG || id == WH_SHELL)
+ if (id == WH_DEBUG)
{
- fprintf( stdnimp, "Unimplemented hook set: (%d,%08lx,%04x,%04x)!\n",
- id, (DWORD)proc, hInst, hTask );
+ fprintf( stdnimp,"WH_DEBUG is broken in 16-bit Windows.\n");
+ return 0;
+ }
+ else if (id == WH_CBT || id == WH_SHELL)
+ {
+ fprintf( stdnimp, "Half-implemented hook set: (%s,%08lx,%04x,%04x)!\n",
+ (id==WH_CBT)?"WH_CBT":"WH_SHELL", (DWORD)proc, hInst, hTask );
}
+ if (id == WH_JOURNALPLAYBACK) EnableHardwareInput(FALSE);
+
/* Create the hook structure */
if (!(handle = USER_HEAP_ALLOC( sizeof(HOOKDATA) ))) return 0;
@@ -105,13 +112,13 @@
if (hQueue)
{
MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
- data->next = queue->hooks[id - WH_FIRST_HOOK];
- queue->hooks[id - WH_FIRST_HOOK] = handle;
+ data->next = queue->hooks[id - WH_MINHOOK];
+ queue->hooks[id - WH_MINHOOK] = handle;
}
else
{
- data->next = HOOK_systemHooks[id - WH_FIRST_HOOK];
- HOOK_systemHooks[id - WH_FIRST_HOOK] = handle;
+ data->next = HOOK_systemHooks[id - WH_MINHOOK];
+ HOOK_systemHooks[id - WH_MINHOOK] = handle;
}
return handle;
}
@@ -138,15 +145,17 @@
return TRUE;
}
+ if (data->id == WH_JOURNALPLAYBACK) EnableHardwareInput(TRUE);
+
/* Remove it from the linked list */
if (data->ownerQueue)
{
MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( data->ownerQueue );
if (!queue) return FALSE;
- prevHook = &queue->hooks[data->id - WH_FIRST_HOOK];
+ prevHook = &queue->hooks[data->id - WH_MINHOOK];
}
- else prevHook = &HOOK_systemHooks[data->id - WH_FIRST_HOOK];
+ else prevHook = &HOOK_systemHooks[data->id - WH_MINHOOK];
while (*prevHook && *prevHook != hook)
prevHook = &((HOOKDATA *)USER_HEAP_LIN_ADDR(*prevHook))->next;
@@ -224,9 +233,9 @@
HHOOK hook, next;
int id;
- for( id = WH_FIRST_HOOK; id <= WH_LAST_HOOK; id++ )
+ for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
{
- hook = HOOK_systemHooks[id - WH_FIRST_HOOK];
+ hook = HOOK_systemHooks[id - WH_MINHOOK];
while( hook )
if( (hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook)) )
{
@@ -253,7 +262,7 @@
HHOOK hook, next;
int id;
- for( id = WH_FIRST_HOOK; id <= WH_LAST_HOOK; id++ )
+ for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
{
hook = HOOK_GetHook( id, hQueue );
while( hook )
@@ -277,15 +286,10 @@
FARPROC16 SetWindowsHook( INT16 id, HOOKPROC16 proc )
{
HINSTANCE16 hInst = __winelib ? 0 : FarGetOwner( HIWORD(proc) );
- /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
- HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
+ HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
+ HANDLE16 handle = HOOK_SetHook( id, proc, hInst, hTask );
- HANDLE16 handle = HOOK_SetHook( id, proc, hInst, hTask );
- if (!handle) return (FARPROC16)-1;
- if (!((HOOKDATA *)USER_HEAP_LIN_ADDR( handle ))->next) return 0;
- /* Not sure if the return value is correct; should not matter much
- * since it's never used (see DefHookProc). -- AJ */
- return (FARPROC16)MAKELONG( handle, HOOK_MAGIC );
+ return (handle) ? (FARPROC16)MAKELONG( handle, HOOK_MAGIC ) : NULL;
}
@@ -343,7 +347,7 @@
HTASK16 hTask )
{
HANDLE16 handle = HOOK_SetHook( id, proc, hInst, hTask );
- return MAKELONG( handle, HOOK_MAGIC );
+ return (handle) ? MAKELONG( handle, HOOK_MAGIC ) : NULL;
}
diff --git a/windows/keyboard.c b/windows/keyboard.c
index ac6cc0f..ccc815b 100644
--- a/windows/keyboard.c
+++ b/windows/keyboard.c
@@ -64,7 +64,7 @@
* GetAsyncKeyState (USER.249)
*
* Determine if a key is or was pressed. retval has high-order
- * byte set to 1 if currently pressed, low-order byte 1 if key has
+ * bit set to 1 if currently pressed, low-order bit set to 1 if key has
* been pressed.
*
* This uses the variable AsyncMouseButtonsStates and
@@ -92,7 +92,7 @@
break;
default:
retval = AsyncKeyStateTable[nKey] |
- (KeyStateTable[nKey] << 8);
+ (KeyStateTable[nKey] ? 0x8000 : 0);
break;
}
diff --git a/windows/mdi.c b/windows/mdi.c
index 19b40a6..40b0d4d 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -406,7 +406,8 @@
MapWindowPoints16(clientWnd->parent->hwndSelf,
((MDICLIENTINFO*)clientWnd->wExtra)->self, (LPPOINT16)&rect, 2);
- AdjustWindowRectEx16( &rect, childWnd->dwStyle, 0, childWnd->dwExStyle );
+ AdjustWindowRectEx16( &rect, childWnd->dwStyle & ~(WS_VSCROLL | WS_HSCROLL),
+ 0, childWnd->dwExStyle );
lpMinMax->ptMaxSize.x = rect.right -= rect.left;
lpMinMax->ptMaxSize.y = rect.bottom -= rect.top;
@@ -539,6 +540,7 @@
/* deactivate prev. active child */
if( wndPrev )
{
+ wndPrev->dwStyle |= WS_SYSMENU;
SendMessage16( prevActiveWnd, WM_NCACTIVATE, FALSE, 0L );
#ifdef WINELIB32
@@ -869,8 +871,6 @@
EnableMenuItem(hSysPopup, SC_MOVE, MF_BYCOMMAND | MF_GRAYED);
EnableMenuItem(hSysPopup, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED);
- child->dwStyle &= ~WS_SYSMENU;
-
/* redraw menu */
DrawMenuBar(frame->hwndSelf);
@@ -882,7 +882,6 @@
*/
BOOL MDI_RestoreFrameMenu( WND *frameWnd, HWND hChild)
{
- WND* child = WIN_FindWndPtr(hChild);
INT nItems = GetMenuItemCount(frameWnd->wIDmenu) - 1;
dprintf_mdi(stddeb,"MDI_RestoreFrameMenu: for child %04x\n",hChild);
@@ -890,7 +889,6 @@
if( GetMenuItemID(frameWnd->wIDmenu,nItems) != SC_RESTORE )
return 0;
- child->dwStyle |= WS_SYSMENU;
RemoveMenu(frameWnd->wIDmenu,0,MF_BYPOSITION);
DeleteMenu(frameWnd->wIDmenu,nItems-1,MF_BYPOSITION);
@@ -1079,7 +1077,7 @@
case WM_MDITILE:
ci->sbNeedUpdate = TRUE;
- ShowScrollBar(hwnd,SB_BOTH,FALSE);
+ ShowScrollBar32(hwnd,SB_BOTH,FALSE);
MDITile(w, ci,wParam);
ci->sbNeedUpdate = FALSE;
return 0;
@@ -1366,10 +1364,15 @@
case SC_MOVE:
if( ci->hwndChildMaximized == hwnd) return 0;
break;
+ case SC_RESTORE:
+ case SC_MINIMIZE:
+ WIN_FindWndPtr(hwnd)->dwStyle |= WS_SYSMENU;
+ break;
case SC_MAXIMIZE:
if( ci->hwndChildMaximized == hwnd)
return SendMessage16( clientWnd->parent->hwndSelf,
message, wParam, lParam);
+ WIN_FindWndPtr(hwnd)->dwStyle &= ~WS_SYSMENU;
break;
case SC_NEXTWINDOW:
SendMessage16( ci->self, WM_MDINEXT, 0, 0);
@@ -1627,15 +1630,15 @@
vpos = clientRect.top - childRect.top;
if( noscroll )
- ShowScrollBar(hwnd, SB_BOTH, FALSE);
+ ShowScrollBar32(hwnd, SB_BOTH, FALSE);
else
switch( scroll )
{
case SB_HORZ:
vpos = hpos; vmin = hmin; vmax = hmax;
case SB_VERT:
- SetScrollPos(hwnd, scroll, vpos, FALSE);
- SetScrollRange(hwnd, scroll, vmin, vmax, TRUE);
+ SetScrollPos32(hwnd, scroll, vpos, FALSE);
+ SetScrollRange32(hwnd, scroll, vmin, vmax, TRUE);
break;
case SB_BOTH:
SCROLL_SetNCSbState( Wnd, vmin, vmax, vpos,
@@ -1654,23 +1657,23 @@
short newPos=-1;
short curPos;
short length;
- INT16 minPos;
- INT16 maxPos;
+ INT32 minPos;
+ INT32 maxPos;
short shift;
if( !wndPtr ) return;
if( uMsg == WM_HSCROLL )
{
- GetScrollRange(hWnd,SB_HORZ,&minPos,&maxPos);
- curPos = GetScrollPos(hWnd,SB_HORZ);
+ GetScrollRange32(hWnd,SB_HORZ,&minPos,&maxPos);
+ curPos = GetScrollPos32(hWnd,SB_HORZ);
length = (wndPtr->rectClient.right - wndPtr->rectClient.left)/2;
shift = SYSMETRICS_CYHSCROLL;
}
else if( uMsg == WM_VSCROLL )
{
- GetScrollRange(hWnd,SB_VERT,&minPos,&maxPos);
- curPos = GetScrollPos(hWnd,SB_VERT);
+ GetScrollRange32(hWnd,SB_VERT,&minPos,&maxPos);
+ curPos = GetScrollPos32(hWnd,SB_VERT);
length = (wndPtr->rectClient.bottom - wndPtr->rectClient.top)/2;
shift = SYSMETRICS_CXVSCROLL;
}
@@ -1714,7 +1717,7 @@
else if( newPos < minPos )
newPos = minPos;
- SetScrollPos(hWnd, (uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ , newPos, TRUE);
+ SetScrollPos32(hWnd, (uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ , newPos, TRUE);
if( uMsg == WM_VSCROLL )
ScrollWindow(hWnd ,0 ,curPos - newPos, NULL, NULL);
diff --git a/windows/message.c b/windows/message.c
index 5dd9fae..2f9cae1 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -34,15 +34,21 @@
#define ASCII_CHAR_HACK 0x0800
+typedef enum { SYSQ_MSG_ABANDON, SYSQ_MSG_SKIP, SYSQ_MSG_ACCEPT } SYSQ_STATUS;
+
extern WPARAM lastEventChar; /* event.c */
extern BOOL MouseButtonsStates[3];
extern BOOL AsyncMouseButtonsStates[3];
extern BYTE KeyStateTable[256];
extern BYTE AsyncKeyStateTable[256];
+extern MESSAGEQUEUE *pCursorQueue; /* queue.c */
+extern MESSAGEQUEUE *pActiveQueue;
+
DWORD MSG_WineStartTicks; /* Ticks at Wine startup */
static WORD doubleClickSpeed = 452;
+static INT32 debugSMRL = 0; /* intertask SendMessage() recursion level */
/***********************************************************************
* MSG_TranslateMouseMsg
@@ -59,7 +65,7 @@
* the coordinates to client coordinates.
* - Send the WM_SETCURSOR message.
*/
-static BOOL MSG_TranslateMouseMsg( MSG16 *msg, BOOL remove )
+static SYSQ_STATUS MSG_TranslateMouseMsg( MSG16 *msg, BOOL remove )
{
WND *pWnd;
BOOL eatMsg = FALSE;
@@ -70,6 +76,7 @@
static WORD lastClickMsg = 0;
static POINT16 lastClickPos = { 0, 0 };
POINT16 pt = msg->pt;
+ MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16(GetTaskQueue(0));
BOOL mouseClick = ((msg->message == WM_LBUTTONDOWN) ||
(msg->message == WM_RBUTTONDOWN) ||
@@ -77,7 +84,7 @@
/* Find the window */
- if ((msg->hwnd = GetCapture()) != 0)
+ if ((msg->hwnd = GetCapture16()) != 0)
{
BOOL32 ret;
@@ -87,7 +94,7 @@
if (!HOOK_GetHook( WH_MOUSE, GetTaskQueue(0)) ||
!(hook = SEGPTR_NEW(MOUSEHOOKSTRUCT16)))
- return TRUE;
+ return SYSQ_MSG_ACCEPT;
hook->pt = msg->pt;
hook->hwnd = msg->hwnd;
hook->wHitTestCode = HTCLIENT;
@@ -95,21 +102,22 @@
ret = !HOOK_CallHooks( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE,
msg->message, (LPARAM)SEGPTR_GET(hook));
SEGPTR_FREE(hook);
- return ret;
+ return ret ? SYSQ_MSG_ACCEPT : SYSQ_MSG_SKIP ;
}
hittest = WINPOS_WindowFromPoint( msg->pt, &pWnd );
if (pWnd->hmemTaskQ != GetTaskQueue(0))
{
/* Not for the current task */
- MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) );
if (queue) QUEUE_ClearWakeBit( queue, QS_MOUSE );
/* Wake up the other task */
queue = (MESSAGEQUEUE *)GlobalLock16( pWnd->hmemTaskQ );
if (queue) QUEUE_SetWakeBit( queue, QS_MOUSE );
- return FALSE;
+ return SYSQ_MSG_ABANDON;
}
- msg->hwnd = pWnd->hwndSelf;
+ pCursorQueue = queue;
+ msg->hwnd = pWnd->hwndSelf;
+
if ((hittest != HTERROR) && mouseClick)
{
HWND hwndTop = WIN_GetTopParent( msg->hwnd );
@@ -121,7 +129,8 @@
/* Activate the window if needed */
- if (msg->hwnd != GetActiveWindow() && msg->hwnd != GetDesktopWindow())
+ if (msg->hwnd != GetActiveWindow() &&
+ msg->hwnd != GetDesktopWindow16())
{
LONG ret = SendMessage16( msg->hwnd, WM_MOUSEACTIVATE, hwndTop,
MAKELONG( hittest, msg->message ) );
@@ -139,7 +148,7 @@
SendMessage16( msg->hwnd, WM_SETCURSOR, (WPARAM)msg->hwnd,
MAKELONG( hittest, msg->message ));
- if (eatMsg) return FALSE;
+ if (eatMsg) return SYSQ_MSG_SKIP;
/* Check for double-click */
@@ -189,7 +198,7 @@
if (!HOOK_GetHook( WH_MOUSE, GetTaskQueue(0)) ||
!(hook = SEGPTR_NEW(MOUSEHOOKSTRUCT16)))
- return TRUE;
+ return SYSQ_MSG_ACCEPT;
hook->pt = msg->pt;
hook->hwnd = msg->hwnd;
@@ -198,7 +207,7 @@
ret = !HOOK_CallHooks( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE,
msg->message, (LPARAM)SEGPTR_GET(hook) );
SEGPTR_FREE(hook);
- return ret;
+ return ret ? SYSQ_MSG_ACCEPT : SYSQ_MSG_SKIP;
}
@@ -209,7 +218,7 @@
* Return value indicates whether the translated message must be passed
* to the user.
*/
-static BOOL MSG_TranslateKeyboardMsg( MSG16 *msg, BOOL remove )
+static SYSQ_STATUS MSG_TranslateKeyboardMsg( MSG16 *msg, BOOL remove )
{
WND *pWnd;
@@ -235,12 +244,14 @@
/* Wake up the other task */
queue = (MESSAGEQUEUE *)GlobalLock16( pWnd->hmemTaskQ );
if (queue) QUEUE_SetWakeBit( queue, QS_KEY );
- return FALSE;
+ return SYSQ_MSG_ABANDON;
}
- return !HOOK_CallHooks( WH_KEYBOARD, remove ? HC_ACTION : HC_NOREMOVE,
- msg->wParam, msg->lParam );
+ return (HOOK_CallHooks( WH_KEYBOARD, remove ? HC_ACTION : HC_NOREMOVE,
+ msg->wParam, msg->lParam ))
+ ? SYSQ_MSG_SKIP : SYSQ_MSG_ACCEPT;
}
+
/***********************************************************************
* MSG_JournalRecordMsg
*
@@ -392,26 +403,30 @@
static BOOL MSG_PeekHardwareMsg( MSG16 *msg, HWND hwnd, WORD first, WORD last,
BOOL remove )
{
+ SYSQ_STATUS status;
MESSAGEQUEUE *sysMsgQueue = QUEUE_GetSysQueue();
int i, pos = sysMsgQueue->nextMessage;
/* If the queue is empty, attempt to fill it */
- if (!sysMsgQueue->msgCount && XPending(display)) EVENT_WaitXEvent( FALSE );
+ if (!sysMsgQueue->msgCount && XPending(display))
+ EVENT_WaitXEvent( FALSE, FALSE );
for (i = 0; i < sysMsgQueue->msgCount; i++, pos++)
{
if (pos >= sysMsgQueue->queueSize) pos = 0;
*msg = sysMsgQueue->messages[pos].msg;
- /* Translate message */
+ /* Translate message; return FALSE immediately on SYSQ_MSG_ABANDON */
if ((msg->message >= WM_MOUSEFIRST) && (msg->message <= WM_MOUSELAST))
{
- if (!MSG_TranslateMouseMsg( msg, remove )) continue;
+ if ((status = MSG_TranslateMouseMsg(msg,remove)) == SYSQ_MSG_ABANDON)
+ return FALSE;
}
else if ((msg->message >= WM_KEYFIRST) && (msg->message <= WM_KEYLAST))
{
- if (!MSG_TranslateKeyboardMsg( msg, remove )) continue;
+ if ((status = MSG_TranslateKeyboardMsg(msg,remove)) == SYSQ_MSG_ABANDON)
+ return FALSE;
}
else /* Non-standard hardware event */
{
@@ -427,21 +442,28 @@
remove ? HC_ACTION : HC_NOREMOVE,
0, (LPARAM)SEGPTR_GET(hook) );
SEGPTR_FREE(hook);
- if (ret) continue;
+ status = ret ? SYSQ_MSG_SKIP : SYSQ_MSG_ACCEPT;
}
}
+ if (status == SYSQ_MSG_SKIP)
+ {
+ if (remove) QUEUE_RemoveMsg( sysMsgQueue, pos );
+ /* FIXME: call CBT_CLICKSKIPPED from here */
+ continue;
+ }
+
/* Check message against filters */
if (hwnd && (msg->hwnd != hwnd)) continue;
if ((first || last) &&
((msg->message < first) || (msg->message > last))) continue;
- if ((msg->hwnd != GetDesktopWindow()) &&
- (GetWindowTask16(msg->hwnd) != GetCurrentTask()))
- continue; /* Not for this task */
- if (remove && HOOK_GetHook( WH_JOURNALRECORD, GetTaskQueue(0) ))
- MSG_JournalRecordMsg( msg );
- if (remove) QUEUE_RemoveMsg( sysMsgQueue, pos );
+ if (remove)
+ {
+ if (HOOK_GetHook( WH_JOURNALRECORD, GetTaskQueue(0) ))
+ MSG_JournalRecordMsg( msg );
+ QUEUE_RemoveMsg( sysMsgQueue, pos );
+ }
return TRUE;
}
return FALSE;
@@ -474,43 +496,71 @@
static LRESULT MSG_SendMessage( HQUEUE16 hDestQueue, HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam )
{
+ INT32 prevSMRL = debugSMRL;
+ QSMCTRL qCtrl = { 0, 1};
MESSAGEQUEUE *queue, *destQ;
if (!(queue = (MESSAGEQUEUE*)GlobalLock16( GetTaskQueue(0) ))) return 0;
if (!(destQ = (MESSAGEQUEUE*)GlobalLock16( hDestQueue ))) return 0;
- if (IsTaskLocked())
+ if (IsTaskLocked() || !IsWindow(hwnd)) return 0;
+
+ debugSMRL+=4;
+ dprintf_sendmsg(stddeb,"%*sSM: %s [%04x] (%04x -> %04x)\n",
+ prevSMRL, "", SPY_GetMsgName(msg), msg, queue->self, hDestQueue );
+
+ if( !(queue->wakeBits & QS_SMPARAMSFREE) )
{
- fprintf( stderr, "SendMessage: task is locked\n" );
- return 0;
+ dprintf_sendmsg(stddeb,"\tIntertask SendMessage: sleeping since unreplied SendMessage pending\n");
+ queue->changeBits &= ~QS_SMPARAMSFREE;
+ QUEUE_WaitBits( QS_SMPARAMSFREE );
}
- if (queue->hWnd)
- {
- fprintf( stderr, "Nested SendMessage(), msg %04x skipped\n", msg );
- return 0;
- }
+ /* resume sending */
+
queue->hWnd = hwnd;
queue->msg = msg;
queue->wParam = wParam;
queue->lParam = lParam;
queue->hPrevSendingTask = destQ->hSendingTask;
destQ->hSendingTask = GetTaskQueue(0);
+
+ queue->wakeBits &= ~QS_SMPARAMSFREE;
+
+ dprintf_sendmsg(stddeb,"%*ssm: smResultInit = %08x\n", prevSMRL, "", (unsigned)&qCtrl);
+
+ queue->smResultInit = &qCtrl;
+
QUEUE_SetWakeBit( destQ, QS_SENDMESSAGE );
- /* Wait for the result */
+ /* perform task switch and wait for the result */
- printf( "SendMessage %04x to %04x\n", msg, hDestQueue );
-
- if (!(queue->wakeBits & QS_SMRESULT))
+ while( qCtrl.bPending )
{
+ if (!(queue->wakeBits & QS_SMRESULT))
+ {
+ queue->changeBits &= ~QS_SMRESULT;
DirectedYield( destQ->hTask );
QUEUE_WaitBits( QS_SMRESULT );
+ dprintf_sendmsg(stddeb,"\tsm: have result!\n");
+ }
+ /* got something */
+
+ dprintf_sendmsg(stddeb,"%*ssm: smResult = %08x\n", prevSMRL, "", (unsigned)queue->smResult );
+
+ queue->smResult->lResult = queue->SendMessageReturn;
+ queue->smResult->bPending = FALSE;
+ queue->wakeBits &= ~QS_SMRESULT;
+
+ if( queue->smResult != &qCtrl )
+ dprintf_msg(stddeb,"%*ssm: weird scenes inside the goldmine!\n", prevSMRL, "");
}
- printf( "SendMessage %04x to %04x: got %08lx\n",
- msg, hDestQueue, queue->SendMessageReturn );
- queue->wakeBits &= ~QS_SMRESULT;
- return queue->SendMessageReturn;
+ queue->smResultInit = NULL;
+
+ dprintf_sendmsg(stddeb,"%*sSM: [%04x] returning %08lx\n", prevSMRL, "", msg, qCtrl.lResult);
+ debugSMRL-=4;
+
+ return qCtrl.lResult;
}
@@ -522,19 +572,33 @@
MESSAGEQUEUE *senderQ;
MESSAGEQUEUE *queue;
- printf( "ReplyMessage\n " );
if (!(queue = (MESSAGEQUEUE*)GlobalLock16( GetTaskQueue(0) ))) return;
- if (!(senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->InSendMessageHandle)))
- return;
- for (;;)
+
+ dprintf_msg(stddeb,"ReplyMessage, queue %04x\n", queue->self);
+
+ while( (senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->InSendMessageHandle)))
{
- if (queue->wakeBits & QS_SENDMESSAGE) QUEUE_ReceiveMessage( queue );
- else if (senderQ->wakeBits & QS_SMRESULT) Yield();
- else break;
- }
- printf( "ReplyMessage: res = %08lx\n", result );
+ dprintf_msg(stddeb,"\trpm: replying to %04x (%04x -> %04x)\n",
+ queue->msg, queue->self, senderQ->self);
+
+ if( queue->wakeBits & QS_SENDMESSAGE )
+ {
+ QUEUE_ReceiveMessage( queue );
+ continue; /* ReceiveMessage() already called us */
+ }
+
+ if(!(senderQ->wakeBits & QS_SMRESULT) ) break;
+ OldYield();
+ }
+ if( !senderQ ) { dprintf_msg(stddeb,"\trpm: done\n"); return; }
+
senderQ->SendMessageReturn = result;
+ dprintf_msg(stddeb,"\trpm: smResult = %08x, result = %08lx\n",
+ (unsigned)queue->smResultCurrent, result );
+
+ senderQ->smResult = queue->smResultCurrent;
queue->InSendMessageHandle = 0;
+
QUEUE_SetWakeBit( senderQ, QS_SMRESULT );
DirectedYield( queue->hSendingTask );
}
@@ -582,6 +646,23 @@
if (msgQueue->wakeBits & QS_SENDMESSAGE)
QUEUE_ReceiveMessage( msgQueue );
+
+ /* Now handle a WM_QUIT message
+ *
+ * FIXME: PostQuitMessage() should post WM_QUIT and
+ * set QS_POSTMESSAGE wakebit instead of this.
+ */
+
+ if (msgQueue->wPostQMsg &&
+ (!first || WM_QUIT >= first) &&
+ (!last || WM_QUIT <= last) )
+ {
+ msg->hwnd = hwnd;
+ msg->message = WM_QUIT;
+ msg->wParam = msgQueue->wExitCode;
+ msg->lParam = 0;
+ break;
+ }
/* Now find a normal message */
@@ -612,17 +693,6 @@
break;
}
- /* Now handle a WM_QUIT message */
-
- if (msgQueue->wPostQMsg)
- {
- msg->hwnd = hwnd;
- msg->message = WM_QUIT;
- msg->wParam = msgQueue->wExitCode;
- msg->lParam = 0;
- break;
- }
-
/* Check again for SendMessage */
if (msgQueue->wakeBits & QS_SENDMESSAGE)
diff --git a/windows/msgbox.c b/windows/msgbox.c
index f019d41..693ccba 100644
--- a/windows/msgbox.c
+++ b/windows/msgbox.c
@@ -23,7 +23,7 @@
LPMSGBOX lpmb;
RECT16 rect, textrect;
HWND hItem;
- HDC hdc;
+ HDC32 hdc;
LONG lRet;
int i, buttons, bwidth, bheight, theight, wwidth, bpos;
int borheight, iheight, tiheight;
@@ -111,12 +111,12 @@
MapWindowPoints16(0, hwnd, (LPPOINT16)&textrect, 2);
GetClientRect16(hItem, &rect);
- hdc = GetDC(hItem);
+ hdc = GetDC32(hItem);
lRet = DrawText16( hdc, lpmb->text, -1, &rect,
DT_LEFT | DT_EXPANDTABS | DT_WORDBREAK | DT_CALCRECT);
theight = rect.bottom - rect.top;
tiheight = 16 + MAX(iheight, theight);
- ReleaseDC(hItem, hdc);
+ ReleaseDC32(hItem, hdc);
/* Position the text */
SetWindowPos(hItem, 0, textrect.left, (tiheight - theight) / 2,
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 64de6c0..fe3148d 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -15,6 +15,7 @@
#include "syscolor.h"
#include "menu.h"
#include "winpos.h"
+#include "hook.h"
#include "scroll.h"
#include "nonclient.h"
#include "graphics.h"
@@ -63,8 +64,6 @@
*/
static void NC_AdjustRect(LPRECT16 rect, DWORD style, BOOL menu, DWORD exStyle)
{
- if (style & WS_ICONIC) return; /* Nothing to change for an icon */
-
/* Decide if the window will be managed (see CreateWindowEx) */
if (!(Options.managed && !(style & WS_CHILD) &&
((style & (WS_DLGFRAME | WS_THICKFRAME)) ||
@@ -233,6 +232,10 @@
LONG NC_HandleNCCalcSize( WND *pWnd, RECT16 *winRect )
{
RECT16 tmpRect = { 0, 0, 0, 0 };
+ LONG result = 0;
+
+ if (pWnd->class->style & CS_VREDRAW) result |= WVR_VREDRAW;
+ if (pWnd->class->style & CS_HREDRAW) result |= WVR_HREDRAW;
if( !( pWnd->dwStyle & WS_MINIMIZE ) )
{
@@ -249,7 +252,7 @@
-tmpRect.left, -tmpRect.top ) + 1;
}
}
- return 0;
+ return result;
}
@@ -668,7 +671,7 @@
*/
void NC_DoNCPaint( HWND hwnd, HRGN clip, BOOL suppress_menupaint )
{
- HDC hdc;
+ HDC32 hdc;
RECT16 rect;
BOOL active;
@@ -681,7 +684,7 @@
dprintf_nonclient(stddeb, "NC_DoNCPaint: %04x %d\n", hwnd, active );
- if (!(hdc = GetDCEx( hwnd, 0, DCX_USESTYLE | DCX_WINDOW ))) return;
+ if (!(hdc = GetDCEx32( hwnd, 0, DCX_USESTYLE | DCX_WINDOW ))) return;
if (ExcludeVisRect( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
wndPtr->rectClient.top-wndPtr->rectWindow.top,
@@ -689,7 +692,7 @@
wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
== NULLREGION)
{
- ReleaseDC( hwnd, hdc );
+ ReleaseDC32( hwnd, hdc );
return;
}
@@ -735,8 +738,10 @@
/* Draw the scroll-bars */
- if (wndPtr->dwStyle & WS_VSCROLL) SCROLL_DrawScrollBar(hwnd, hdc, SB_VERT);
- if (wndPtr->dwStyle & WS_HSCROLL) SCROLL_DrawScrollBar(hwnd, hdc, SB_HORZ);
+ if (wndPtr->dwStyle & WS_VSCROLL)
+ SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE );
+ if (wndPtr->dwStyle & WS_HSCROLL)
+ SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE );
/* Draw the "size-box" */
@@ -748,7 +753,7 @@
FillRect16( hdc, &r, sysColorObjects.hbrushScrollbar );
}
- ReleaseDC( hwnd, hdc );
+ ReleaseDC32( hwnd, hdc );
}
@@ -870,7 +875,8 @@
RECT16 rect;
WND *wndPtr = WIN_FindWndPtr( hwnd );
int iconic = wndPtr->dwStyle & WS_MINIMIZE;
-
+ HMENU hmenu;
+
if (!(wndPtr->dwStyle & WS_SYSMENU)) return;
/* If window has a menu, track the menu bar normally if it not minimized */
@@ -881,7 +887,10 @@
NC_GetSysPopupPos( wndPtr, &rect );
if (!iconic) NC_DrawSysButton( hwnd, hdc, TRUE );
- TrackPopupMenu16( GetSystemMenu(hwnd, 0), TPM_LEFTALIGN | TPM_LEFTBUTTON,
+ hmenu = GetSystemMenu(hwnd, 0);
+ MENU_InitSysMenuPopup(hmenu, wndPtr->dwStyle,
+ wndPtr->class->style);
+ TrackPopupMenu16( hmenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
rect.left, rect.bottom, 0, hwnd, &rect );
if (!iconic) NC_DrawSysButton( hwnd, hdc, FALSE );
}
@@ -920,7 +929,7 @@
}
else /* SC_SIZE */
{
- SetCapture(hwnd);
+ SetCapture32(hwnd);
while(!hittest)
{
MSG_InternalGetMessage( &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE );
@@ -982,7 +991,7 @@
MSG16 msg;
LONG hittest;
RECT16 sizingRect, mouseRect;
- HDC hdc;
+ HDC32 hdc;
BOOL thickframe;
POINT16 minTrack, maxTrack, capturePoint = pt;
WND * wndPtr = WIN_FindWndPtr( hwnd );
@@ -1005,7 +1014,7 @@
if (hittest) hittest += HTLEFT-1;
else
{
- SetCapture(hwnd);
+ SetCapture32(hwnd);
hittest = NC_StartSizeMove( hwnd, wParam, &capturePoint );
if (!hittest)
{
@@ -1044,16 +1053,16 @@
}
SendMessage16( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
- if (GetCapture() != hwnd) SetCapture( hwnd );
+ if (GetCapture32() != hwnd) SetCapture32( hwnd );
if (wndPtr->dwStyle & WS_CHILD)
{
/* Retrieve a default cache DC (without using the window style) */
- hdc = GetDCEx( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
+ hdc = GetDCEx32( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
}
else
{ /* Grab the server only when moving top-level windows without desktop */
- hdc = GetDC( 0 );
+ hdc = GetDC32( 0 );
if (rootWindow == DefaultRootWindow(display)) XGrabServer( display );
}
NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
@@ -1116,12 +1125,28 @@
NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
ReleaseCapture();
- if (wndPtr->dwStyle & WS_CHILD) ReleaseDC( wndPtr->parent->hwndSelf, hdc );
+ if (wndPtr->dwStyle & WS_CHILD)
+ ReleaseDC32( wndPtr->parent->hwndSelf, hdc );
else
{
- ReleaseDC( 0, hdc );
+ ReleaseDC32( 0, hdc );
if (rootWindow == DefaultRootWindow(display)) XUngrabServer( display );
}
+
+ if (HOOK_GetHook( WH_CBT, GetTaskQueue(0) ))
+ {
+ RECT16* pr = SEGPTR_NEW(RECT16);
+ if( pr )
+ {
+ *pr = sizingRect;
+ if( HOOK_CallHooks( WH_CBT, HCBT_MOVESIZE, hwnd,
+ (LPARAM)SEGPTR_GET(pr)) )
+ sizingRect = wndPtr->rectWindow;
+ else
+ sizingRect = *pr;
+ SEGPTR_FREE(pr);
+ }
+ }
SendMessage16( hwnd, WM_EXITSIZEMOVE, 0, 0 );
SendMessage16( hwnd, WM_SETVISIBLE, !IsIconic(hwnd), 0L);
@@ -1154,10 +1179,10 @@
static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
{
MSG16 msg;
- HDC hdc = GetWindowDC( hwnd );
+ HDC32 hdc = GetWindowDC32( hwnd );
BOOL pressed = TRUE;
- SetCapture( hwnd );
+ SetCapture32( hwnd );
if (wParam == HTMINBUTTON) NC_DrawMinButton( hwnd, hdc, TRUE );
else NC_DrawMaxButton( hwnd, hdc, TRUE );
@@ -1178,7 +1203,7 @@
else NC_DrawMaxButton( hwnd, hdc, FALSE );
ReleaseCapture();
- ReleaseDC( hwnd, hdc );
+ ReleaseDC32( hwnd, hdc );
if (!pressed) return;
if (wParam == HTMINBUTTON)
@@ -1194,10 +1219,10 @@
*
* Track a mouse button press on the horizontal or vertical scroll-bar.
*/
-static void NC_TrackScrollBar( HWND hwnd, WORD wParam, POINT16 pt )
+static void NC_TrackScrollBar( HWND32 hwnd, WPARAM32 wParam, POINT32 pt )
{
MSG16 *msg;
- WORD scrollbar;
+ INT32 scrollbar;
WND *wndPtr = WIN_FindWndPtr( hwnd );
if ((wParam & 0xfff0) == SC_HSCROLL)
@@ -1214,7 +1239,7 @@
if (!(msg = SEGPTR_NEW(MSG16))) return;
pt.x -= wndPtr->rectWindow.left;
pt.y -= wndPtr->rectWindow.top;
- SetCapture( hwnd );
+ SetCapture32( hwnd );
SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt );
do
@@ -1252,7 +1277,7 @@
*/
LONG NC_HandleNCLButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam )
{
- HDC hdc = GetWindowDC( hwnd );
+ HDC32 hdc;
switch(wParam) /* Hit test */
{
@@ -1261,7 +1286,9 @@
break;
case HTSYSMENU:
+ hdc = GetWindowDC32( hwnd );
NC_TrackSysMenu( hwnd, hdc, MAKEPOINT16(lParam) );
+ ReleaseDC32( hwnd, hdc );
break;
case HTMENU:
@@ -1295,8 +1322,6 @@
case HTBORDER:
break;
}
-
- ReleaseDC( hwnd, hdc );
return 0;
}
@@ -1345,6 +1370,7 @@
LONG NC_HandleSysCommand( HWND hwnd, WPARAM wParam, POINT16 pt )
{
WND *wndPtr = WIN_FindWndPtr( hwnd );
+ POINT32 pt32;
dprintf_nonclient(stddeb, "Handling WM_SYSCOMMAND %x %d,%d\n",
wParam, pt.x, pt.y );
@@ -1380,7 +1406,8 @@
case SC_VSCROLL:
case SC_HSCROLL:
- NC_TrackScrollBar( hwnd, wParam, pt );
+ CONV_POINT16TO32( &pt, &pt32 );
+ NC_TrackScrollBar( hwnd, wParam, pt32 );
break;
case SC_MOUSEMENU:
diff --git a/windows/painting.c b/windows/painting.c
index c1b3d09..76c5a73 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -114,8 +114,8 @@
* (because rectClient == rectWindow for WS_MINIMIZE windows).
*/
- lps->hdc = GetDCEx( hwnd, hrgnUpdate, DCX_INTERSECTRGN | DCX_WINDOWPAINT |
- DCX_USESTYLE | (bIcon ? DCX_WINDOW : 0) );
+ lps->hdc = GetDCEx16(hwnd, hrgnUpdate, DCX_INTERSECTRGN | DCX_WINDOWPAINT |
+ DCX_USESTYLE | (bIcon ? DCX_WINDOW : 0) );
dprintf_win(stddeb,"hdc = %04x\n", lps->hdc);
@@ -166,7 +166,7 @@
*/
BOOL16 EndPaint16( HWND16 hwnd, const PAINTSTRUCT16* lps )
{
- ReleaseDC( hwnd, lps->hdc );
+ ReleaseDC16( hwnd, lps->hdc );
ShowCaret( hwnd );
return TRUE;
}
@@ -177,7 +177,7 @@
*/
BOOL32 EndPaint32( HWND32 hwnd, const PAINTSTRUCT32 *lps )
{
- ReleaseDC( hwnd, (HDC16)lps->hdc );
+ ReleaseDC32( hwnd, lps->hdc );
ShowCaret( hwnd );
return TRUE;
}
@@ -245,7 +245,7 @@
RECT32 rectClient;
WND* wndPtr;
- if (!hwnd) hwnd = GetDesktopWindow();
+ if (!hwnd) hwnd = GetDesktopWindow32();
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
if (!IsWindowVisible(hwnd) || (wndPtr->flags & WIN_NO_REDRAW))
return TRUE; /* No redraw needed */
@@ -262,7 +262,14 @@
dprintf_win(stddeb, "RedrawWindow: %04x NULL %04x flags=%04x\n",
hwnd, hrgnUpdate, flags);
}
- GetClientRect32( hwnd, &rectClient );
+
+ if (wndPtr->class->style & CS_PARENTDC)
+ {
+ GetClientRect32( wndPtr->parent->hwndSelf, &rectClient );
+ OffsetRect32( &rectClient, -wndPtr->rectClient.left,
+ -wndPtr->rectClient.top );
+ }
+ else GetClientRect32( hwnd, &rectClient );
if (flags & RDW_INVALIDATE) /* Invalidate */
{
@@ -364,17 +371,17 @@
if (wndPtr->flags & WIN_NEEDS_ERASEBKGND)
{
- HDC hdc = GetDCEx( hwnd, wndPtr->hrgnUpdate,
- DCX_INTERSECTRGN | DCX_USESTYLE |
- DCX_KEEPCLIPRGN | DCX_WINDOWPAINT |
- (bIcon ? DCX_WINDOW : 0) );
+ HDC32 hdc = GetDCEx32( hwnd, wndPtr->hrgnUpdate,
+ DCX_INTERSECTRGN | DCX_USESTYLE |
+ DCX_KEEPCLIPRGN | DCX_WINDOWPAINT |
+ (bIcon ? DCX_WINDOW : 0) );
if (hdc)
{
if (SendMessage16( hwnd, (bIcon) ? WM_ICONERASEBKGND
: WM_ERASEBKGND,
(WPARAM)hdc, 0 ))
wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
- ReleaseDC( hwnd, hdc );
+ ReleaseDC32( hwnd, hdc );
}
}
}
@@ -400,18 +407,29 @@
for (wndPtr = wndPtr->child; wndPtr; wndPtr = wndPtr->next)
if( wndPtr->dwStyle & WS_VISIBLE )
{
- SetRectRgn( hrgn, wndPtr->rectWindow.left, wndPtr->rectWindow.top,
- wndPtr->rectWindow.right, wndPtr->rectWindow.bottom);
- if( CombineRgn( hrgn, hrgn, hrgnUpdate, RGN_AND ) != NULLREGION )
- {
- if( control & RDW_C_USEHRGN &&
- wndPtr->dwStyle & WS_CLIPSIBLINGS )
- CombineRgn( hrgnUpdate, hrgnUpdate, hrgn, RGN_DIFF );
+ if (wndPtr->class->style & CS_PARENTDC)
+ {
+ if (!CombineRgn( hrgn, hrgnUpdate, 0, RGN_COPY ))
+ continue;
+ }
+ else
+ {
+ SetRectRgn( hrgn, wndPtr->rectWindow.left,
+ wndPtr->rectWindow.top,
+ wndPtr->rectWindow.right,
+ wndPtr->rectWindow.bottom);
+ if (!CombineRgn( hrgn, hrgn, hrgnUpdate, RGN_AND ))
+ continue;
+ }
+#if 0
+ if( control & RDW_C_USEHRGN &&
+ wndPtr->dwStyle & WS_CLIPSIBLINGS )
+ CombineRgn( hrgnUpdate, hrgnUpdate, hrgn, RGN_DIFF );
+#endif
OffsetRgn( hrgn, -wndPtr->rectClient.left,
-wndPtr->rectClient.top );
PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, hrgn, flags, RDW_C_USEHRGN );
- }
}
DeleteObject( hrgn );
if( control & RDW_C_DELETEHRGN ) DeleteObject( hrgnUpdate );
diff --git a/windows/property.c b/windows/property.c
index 089d35b..876bd58 100644
--- a/windows/property.c
+++ b/windows/property.c
@@ -166,7 +166,12 @@
PROPERTY **pprop, *prop;
WND *pWnd = WIN_FindWndPtr( hwnd );
- dprintf_prop( stddeb, "RemoveProp: %04x '%s'\n", hwnd, str );
+ if (HIWORD(str))
+ dprintf_prop( stddeb, "RemoveProp: %04x '%s'\n", hwnd, str );
+ else
+ dprintf_prop( stddeb, "RemoveProp: %04x #%04x\n", hwnd, LOWORD(str));
+
+
if (!pWnd) return NULL;
if (HIWORD(str))
{
diff --git a/windows/queue.c b/windows/queue.c
index ca6b4d9..aeff35c 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -15,11 +15,15 @@
#define MAX_QUEUE_SIZE 120 /* Max. size of a message queue */
static HQUEUE16 hFirstQueue = 0;
+static HQUEUE16 hDoomedQueue = 0;
static HQUEUE16 hmemSysMsgQueue = 0;
+static MESSAGEQUEUE *sysMsgQueue = NULL;
+
static MESSAGEQUEUE *pMouseQueue = NULL; /* Queue for last mouse message */
static MESSAGEQUEUE *pKbdQueue = NULL; /* Queue for last kbd message */
-static HQUEUE16 hDoomedQueue = 0;
-static MESSAGEQUEUE *sysMsgQueue = NULL;
+
+MESSAGEQUEUE *pCursorQueue = NULL;
+MESSAGEQUEUE *pActiveQueue = NULL;
/***********************************************************************
* QUEUE_DumpQueue
@@ -119,9 +123,10 @@
if (!(hQueue = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, queueSize )))
return 0;
msgQueue = (MESSAGEQUEUE *) GlobalLock16( hQueue );
- msgQueue->self = hQueue;
- msgQueue->msgSize = sizeof(QMSG);
- msgQueue->queueSize = size;
+ msgQueue->self = hQueue;
+ msgQueue->msgSize = sizeof(QMSG);
+ msgQueue->queueSize = size;
+ msgQueue->wakeBits = msgQueue->changeBits = QS_SMPARAMSFREE;
msgQueue->wWinVersion = pTask ? pTask->version : 0;
GlobalUnlock16( hQueue );
return hQueue;
@@ -136,6 +141,7 @@
BOOL32 QUEUE_DeleteMsgQueue( HQUEUE16 hQueue )
{
MESSAGEQUEUE * msgQueue = (MESSAGEQUEUE*)GlobalLock16(hQueue);
+ HQUEUE16 senderQ;
HQUEUE16 *pPrev;
dprintf_msg(stddeb,"Deleting message queue %04x\n", hQueue);
@@ -145,6 +151,19 @@
dprintf_msg(stddeb,"DeleteMsgQueue: invalid argument.\n");
return 0;
}
+ if( pCursorQueue == msgQueue ) pCursorQueue = NULL;
+ if( pActiveQueue == msgQueue ) pActiveQueue = NULL;
+
+ /* flush sent messages */
+ senderQ = msgQueue->hSendingTask;
+ while( senderQ )
+ {
+ MESSAGEQUEUE* sq = (MESSAGEQUEUE*)GlobalLock16(senderQ);
+ if( !sq ) break;
+ sq->SendMessageReturn = 0L;
+ QUEUE_SetWakeBit( sq, QS_SMRESULT );
+ senderQ = sq->hPrevSendingTask;
+ }
pPrev = &hFirstQueue;
while (*pPrev && (*pPrev != hQueue))
@@ -191,6 +210,9 @@
*/
void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD bit )
{
+ dprintf_msg(stddeb,"SetWakeBit: queue = %04x (wm=%04x), bit = %04x\n",
+ queue->self, queue->wakeMask, bit );
+
if (bit & QS_MOUSE) pMouseQueue = queue;
if (bit & QS_KEY) pKbdQueue = queue;
queue->changeBits |= bit;
@@ -222,9 +244,12 @@
{
MESSAGEQUEUE *queue;
+ dprintf_msg(stddeb,"WaitBits: q %04x waiting for %04x\n", GetTaskQueue(0), bits);
+
for (;;)
{
if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return;
+
if (queue->changeBits & bits)
{
/* One of the bits is set; we can return */
@@ -234,9 +259,17 @@
if (queue->wakeBits & QS_SENDMESSAGE)
{
/* Process the sent message immediately */
+
+ queue->wakeMask = 0;
QUEUE_ReceiveMessage( queue );
+ continue; /* nested sm crux */
}
+
queue->wakeMask = bits | QS_SENDMESSAGE;
+ if(queue->changeBits & bits) continue;
+
+ dprintf_msg(stddeb,"wb: (%04x) wakeMask is %04x, waiting\n", queue->self, queue->wakeMask);
+
WaitEvent( 0 );
}
}
@@ -249,57 +282,55 @@
*/
void QUEUE_ReceiveMessage( MESSAGEQUEUE *queue )
{
- MESSAGEQUEUE *senderQ;
- HWND hwnd;
- UINT msg;
- WPARAM wParam;
- LPARAM lParam;
- LRESULT result = 0;
- HQUEUE16 oldSender;
+ MESSAGEQUEUE *senderQ = NULL;
+ HQUEUE16 prevSender = 0;
+ QSMCTRL* prevCtrlPtr = NULL;
+ LRESULT result = 0;
- printf( "ReceiveMessage\n" );
- if (!(queue->wakeBits & QS_SENDMESSAGE)) return;
- if (!(senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->hSendingTask))) return;
+ dprintf_msg(stddeb, "ReceiveMessage, queue %04x\n", queue->self );
+ if (!(queue->wakeBits & QS_SENDMESSAGE) ||
+ !(senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->hSendingTask)))
+ { dprintf_msg(stddeb,"\trcm: nothing to do\n"); return; }
- /* Remove sending queue from the list */
- oldSender = queue->InSendMessageHandle;
queue->InSendMessageHandle = queue->hSendingTask;
- queue->hSendingTask = senderQ->hPrevSendingTask;
- senderQ->hPrevSendingTask = 0;
- if (!queue->hSendingTask)
+ if( !(queue->hSendingTask = senderQ->hPrevSendingTask) )
{
- queue->wakeBits &= ~QS_SENDMESSAGE;
- queue->changeBits &= ~QS_SENDMESSAGE;
+ queue->wakeBits &= ~QS_SENDMESSAGE; /* no more sent messages */
+ queue->changeBits &= ~QS_SENDMESSAGE;
}
- /* Get the parameters from the sending task */
- hwnd = senderQ->hWnd;
- msg = senderQ->msg;
- wParam = senderQ->wParam;
- lParam = senderQ->lParam;
- senderQ->hWnd = 0;
+ /* Remove sending queue from the list */
+ prevSender = queue->InSendMessageHandle;
+ prevCtrlPtr = queue->smResultCurrent;
+ queue->smResultCurrent = senderQ->smResultInit;
+
+ dprintf_msg(stddeb, "\trcm: smResultCurrent = %08x, prevCtrl = %08x\n",
+ (unsigned)queue->smResultCurrent, (unsigned)prevCtrlPtr );
QUEUE_SetWakeBit( senderQ, QS_SMPARAMSFREE );
- printf( "ReceiveMessage: calling wnd proc %04x %04x %04x %08x\n",
- hwnd, msg, wParam, lParam );
+ dprintf_msg(stddeb, "\trcm: calling wndproc - %04x %04x %04x %08x\n",
+ senderQ->hWnd, senderQ->msg, senderQ->wParam, (unsigned)senderQ->lParam );
- /* Call the window procedure */
- /* FIXME: should we use CallWindowProc here? */
- if (IsWindow( hwnd ))
+ if (IsWindow( senderQ->hWnd ))
{
DWORD extraInfo = queue->GetMessageExtraInfoVal;
queue->GetMessageExtraInfoVal = senderQ->GetMessageExtraInfoVal;
- result = SendMessage16( hwnd, msg, wParam, lParam );
- queue->GetMessageExtraInfoVal = extraInfo; /* Restore extra info */
- }
- printf( "ReceiveMessage: wnd proc %04x %04x %04x %08x ret = %08x\n",
- hwnd, msg, wParam, lParam, result );
+ result = CallWindowProc16( (WNDPROC16)GetWindowLong16(senderQ->hWnd, GWL_WNDPROC),
+ senderQ->hWnd, senderQ->msg, senderQ->wParam, senderQ->lParam );
+
+ queue->GetMessageExtraInfoVal = extraInfo; /* Restore extra info */
+ dprintf_msg(stddeb,"\trcm: result = %08x\n", (unsigned)result );
+ }
+ else dprintf_msg(stddeb,"\trcm: bad hWnd\n");
/* Return the result to the sender task */
ReplyMessage( result );
- queue->InSendMessageHandle = oldSender;
+ queue->InSendMessageHandle = prevSender;
+ queue->smResultCurrent = prevCtrlPtr;
+
+ dprintf_msg(stddeb,"ReceiveMessage: done!\n");
}
@@ -399,39 +430,44 @@
*/
static void QUEUE_WakeSomeone( UINT message )
{
- HWND hwnd;
- WORD wakeBit;
- HQUEUE16 hQueue;
- MESSAGEQUEUE *queue = NULL;
+ WND* wndPtr = NULL;
+ HWND hwnd;
+ WORD wakeBit;
+ MESSAGEQUEUE *queue = pCursorQueue;
- if ((message >= WM_KEYFIRST) && (message <= WM_KEYLAST)) wakeBit = QS_KEY;
- else wakeBit = (message == WM_MOUSEMOVE) ? QS_MOUSEMOVE : QS_MOUSEBUTTON;
+ if( (message >= WM_KEYFIRST) && (message <= WM_KEYLAST) )
+ {
+ wakeBit = QS_KEY;
+ if( pActiveQueue ) queue = pActiveQueue;
+ }
+ else
+ {
+ wakeBit = (message == WM_MOUSEMOVE) ? QS_MOUSEMOVE : QS_MOUSEBUTTON;
+ if( (hwnd = GetCapture32()) )
+ if( (wndPtr = WIN_FindWndPtr( hwnd )) )
+ queue = (MESSAGEQUEUE *)GlobalLock16( wndPtr->hmemTaskQ );
+ }
- if (!(hwnd = GetSysModalWindow16()))
+ if( (hwnd = GetSysModalWindow16()) )
+ if( (wndPtr = WIN_FindWndPtr( hwnd )) )
+ queue = (MESSAGEQUEUE *)GlobalLock16( wndPtr->hmemTaskQ );
+
+ if( !queue )
{
- if (wakeBit == QS_KEY)
- {
- if (!(hwnd = GetFocus32())) hwnd = GetActiveWindow();
- }
- else hwnd = GetCapture();
+ queue = GlobalLock16( hFirstQueue );
+ while( queue )
+ {
+ if (queue->wakeMask & wakeBit) break;
+ queue = GlobalLock16( queue->next );
+ }
+ if( !queue )
+ {
+ dprintf_msg(stddeb,"WakeSomeone: couldn't find queue\n");
+ return;
+ }
}
- if (hwnd)
- {
- WND *wndPtr = WIN_FindWndPtr( hwnd );
- if (wndPtr) queue = (MESSAGEQUEUE *)GlobalLock16( wndPtr->hmemTaskQ );
- }
- else if (!(queue = pMouseQueue))
- {
- hQueue = hFirstQueue;
- while (hQueue)
- {
- queue = GlobalLock16( hQueue );
- if (queue->wakeBits & wakeBit) break;
- hQueue = queue->next;
- }
- }
- if (!queue) printf( "WakeSomeone: no one found\n" );
- if (queue) QUEUE_SetWakeBit( queue, wakeBit );
+
+ QUEUE_SetWakeBit( queue, wakeBit );
}
@@ -595,15 +631,23 @@
dprintf_msg(stddeb,"SetMessageQueue: failed!\n");
return FALSE;
}
+ queuePtr = (MESSAGEQUEUE *)GlobalLock16( hNewQueue );
- /* Free the old message queue */
- if ((hQueue = GetTaskQueue(0)) != 0) QUEUE_DeleteMsgQueue( hQueue );
+ /* Copy data and free the old message queue */
+ if ((hQueue = GetTaskQueue(0)) != 0)
+ {
+ MESSAGEQUEUE *oldQ = (MESSAGEQUEUE *)GlobalLock16( hQueue );
+ memcpy( &queuePtr->reserved2, &oldQ->reserved2,
+ (int)oldQ->messages - (int)(&oldQ->reserved2) );
+ QUEUE_DeleteMsgQueue( hQueue );
+ }
/* Link new queue into list */
- queuePtr = (MESSAGEQUEUE *)GlobalLock16( hNewQueue );
queuePtr->hTask = GetCurrentTask();
queuePtr->next = hFirstQueue;
hFirstQueue = hNewQueue;
+
+ if( !queuePtr->next ) pCursorQueue = queuePtr;
SetTaskQueue( 0, hNewQueue );
return TRUE;
diff --git a/windows/scroll.c b/windows/scroll.c
index 9b8d699..f92adf1 100644
--- a/windows/scroll.c
+++ b/windows/scroll.c
@@ -29,7 +29,7 @@
*/
void ScrollWindow(HWND hwnd, short dx, short dy, LPRECT16 rect, LPRECT16 clipRect)
{
- HDC hdc;
+ HDC32 hdc;
HRGN hrgnUpdate,hrgnClip;
RECT16 rc, cliprc;
HWND hCaretWnd = CARET_GetHwnd();
@@ -52,7 +52,7 @@
HideCaret(hCaretWnd);
else hCaretWnd = 0;
- hdc = GetDCEx(hwnd, hrgnClip, DCX_CACHE | DCX_CLIPSIBLINGS);
+ hdc = GetDCEx32(hwnd, hrgnClip, DCX_CACHE | DCX_CLIPSIBLINGS);
DeleteObject(hrgnClip);
}
else /* clip children */
@@ -63,7 +63,7 @@
if (hCaretWnd == hwnd) HideCaret(hCaretWnd);
else hCaretWnd = 0;
- hdc = GetDC(hwnd);
+ hdc = GetDC32(hwnd);
}
if (clipRect == NULL)
@@ -73,7 +73,7 @@
hrgnUpdate = CreateRectRgn(0, 0, 0, 0);
ScrollDC(hdc, dx, dy, &rc, &cliprc, hrgnUpdate, NULL);
- ReleaseDC(hwnd, hdc);
+ ReleaseDC32(hwnd, hdc);
if( !rect ) /* move child windows and update region */
{
@@ -230,12 +230,12 @@
int ScrollWindowEx(HWND hwnd, short dx, short dy, LPRECT16 rect, LPRECT16 clipRect,
HRGN hrgnUpdate, LPRECT16 rcUpdate, WORD flags)
{
- HDC hdc;
+ HDC32 hdc;
RECT16 rc, cliprc;
dprintf_scroll(stddeb,"ScrollWindowEx: dx=%d, dy=%d, wFlags=%04x\n",dx, dy, flags);
- hdc = GetDC(hwnd);
+ hdc = GetDC32(hwnd);
if (rect == NULL)
GetClientRect16(hwnd, &rc);
@@ -254,6 +254,6 @@
((flags & SW_ERASE) ? RDW_ERASENOW : 0), 0 );
}
- ReleaseDC(hwnd, hdc);
+ ReleaseDC32(hwnd, hdc);
return RgnType;
}
diff --git a/windows/win.c b/windows/win.c
index 80debdf..563c788 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -44,6 +44,9 @@
static WORD wDragHeight= 3;
extern HCURSOR16 CURSORICON_IconToCursor(HICON16);
+extern HWND32 CARET_GetHwnd(void);
+extern BOOL32 WINPOS_ActivateOtherWindow(WND* pWnd);
+extern void WINPOS_CheckActive(HWND32);
/***********************************************************************
* WIN_FindWndPtr
@@ -90,13 +93,13 @@
fprintf( stderr, "Window %04x (%p):\n", hwnd, ptr );
fprintf( stderr,
"next=%p child=%p parent=%p owner=%p class=%p '%s'\n"
- "inst=%04x taskQ=%04x updRgn=%04x active=%04x hdce=%04x idmenu=%04x\n"
+ "inst=%04x taskQ=%04x updRgn=%04x active=%04x dce=%p idmenu=%04x\n"
"style=%08lx exstyle=%08lx wndproc=%08x text='%s'\n"
"client=%d,%d-%d,%d window=%d,%d-%d,%d iconpos=%d,%d maxpos=%d,%d\n"
"sysmenu=%04x flags=%04x props=%p vscroll=%p hscroll=%p\n",
ptr->next, ptr->child, ptr->parent, ptr->owner,
ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
- ptr->hrgnUpdate, ptr->hwndLastActive, ptr->hdce, ptr->wIDmenu,
+ ptr->hrgnUpdate, ptr->hwndLastActive, ptr->dce, ptr->wIDmenu,
ptr->dwStyle, ptr->dwExStyle, (UINT32)ptr->winproc,
ptr->text ? ptr->text : "",
ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
@@ -301,37 +304,71 @@
/***********************************************************************
* WIN_DestroyWindow
*
- * Destroy storage associated to a window
+ * Destroy storage associated to a window. "Internals" p.358
*/
-static void WIN_DestroyWindow( HWND hwnd )
+static void WIN_DestroyWindow( WND* wndPtr )
{
- WND *wndPtr = WIN_FindWndPtr( hwnd );
+ HWND hwnd = wndPtr->hwndSelf;
+ WND* pWnd,*pNext;
#ifdef CONFIG_IPC
if (main_block)
- DDE_DestroyWindow(hwnd);
+ DDE_DestroyWindow(wndPtr->hwndSelf);
#endif /* CONFIG_IPC */
- if (!wndPtr) return;
- WIN_UnlinkWindow( hwnd ); /* Remove the window from the linked list */
- TIMER_RemoveWindowTimers( hwnd );
+ /* free child windows */
+
+ pNext = wndPtr->child;
+ while( (pWnd = pNext) )
+ {
+ pNext = pWnd->next;
+ WIN_DestroyWindow( pWnd );
+ }
+
+ SendMessage32A( wndPtr->hwndSelf, WM_NCDESTROY, 0, 0);
+
+ /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
+
+ WINPOS_CheckActive( hwnd );
+ if( hwnd == GetCapture32()) ReleaseCapture();
+
+ /* free resources associated with the window */
+
+ TIMER_RemoveWindowTimers( wndPtr->hwndSelf );
PROPERTY_RemoveWindowProps( wndPtr );
+
wndPtr->dwMagic = 0; /* Mark it as invalid */
wndPtr->hwndSelf = 0;
+
if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
{
if (wndPtr->hrgnUpdate) DeleteObject( wndPtr->hrgnUpdate );
QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
}
- if (!(wndPtr->dwStyle & WS_CHILD))
+
+ /* toss stale messages from the queue */
+
+ if( wndPtr->hmemTaskQ )
{
- if (wndPtr->wIDmenu) DestroyMenu( (HMENU)wndPtr->wIDmenu );
+ int pos;
+ MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) GlobalLock16(wndPtr->hmemTaskQ);
+
+ while( (pos = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != -1 )
+ QUEUE_RemoveMsg(msgQ, pos);
+ wndPtr->hmemTaskQ = 0;
}
+
+ if (!(wndPtr->dwStyle & WS_CHILD))
+ if (wndPtr->wIDmenu) DestroyMenu( (HMENU)wndPtr->wIDmenu );
if (wndPtr->hSysMenu) DestroyMenu( wndPtr->hSysMenu );
if (wndPtr->window) XDestroyWindow( display, wndPtr->window );
- if (wndPtr->class->style & CS_OWNDC) DCE_FreeDCE( wndPtr->hdce );
+ if (wndPtr->class->style & CS_OWNDC) DCE_FreeDCE( wndPtr->dce );
+
WINPROC_FreeProc( wndPtr->winproc );
+
wndPtr->class->cWindows--;
+ wndPtr->class = NULL;
+
USER_HEAP_FREE( hwnd );
}
@@ -398,7 +435,7 @@
pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN |
WS_CLIPSIBLINGS;
pWndDesktop->dwExStyle = 0;
- pWndDesktop->hdce = 0;
+ pWndDesktop->dce = NULL;
pWndDesktop->pVScroll = NULL;
pWndDesktop->pHScroll = NULL;
pWndDesktop->pProp = NULL;
@@ -426,7 +463,7 @@
{
CLASS *classPtr;
WND *wndPtr;
- HWND16 hwnd;
+ HWND16 hwnd, hwndLinkAfter;
POINT16 maxSize, maxPos, minTrack, maxTrack;
LRESULT wmcreate;
@@ -493,12 +530,23 @@
/* Fill the window structure */
wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
- wndPtr->next = NULL;
- wndPtr->child = NULL;
- wndPtr->parent = (cs->style & WS_CHILD) ?
- WIN_FindWndPtr( cs->hwndParent ) : pWndDesktop;
- wndPtr->owner = (cs->style & WS_CHILD) ? NULL :
- WIN_FindWndPtr(WIN_GetTopParent(cs->hwndParent));
+ wndPtr->next = NULL;
+ wndPtr->child = NULL;
+
+ if (cs->style & WS_CHILD)
+ {
+ wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
+ wndPtr->owner = NULL;
+ }
+ else
+ {
+ wndPtr->parent = pWndDesktop;
+ if (!cs->hwndParent || (cs->hwndParent == pWndDesktop->hwndSelf))
+ wndPtr->owner = NULL;
+ else
+ wndPtr->owner = WIN_FindWndPtr(WIN_GetTopParent(cs->hwndParent));
+ }
+
wndPtr->window = 0;
wndPtr->class = classPtr;
wndPtr->winproc = NULL;
@@ -524,10 +572,46 @@
wndPtr->userdata = 0;
if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
- classPtr->cWindows++;
+
+ /* Call the WH_CBT hook */
+
+ hwndLinkAfter = (cs->style & WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
+
+ if (HOOK_GetHook( WH_CBT, GetTaskQueue(0) ))
+ {
+ CBT_CREATEWND16* cbtc;
+
+ if ((cbtc = SEGPTR_NEW(CBT_CREATEWND16)))
+ {
+ /* Dummy message params to use WINPROC_MapMsg functions */
+ UINT16 msg;
+ WPARAM16 wparam;
+ LPARAM lparam;
+
+ /* Map the CREATESTRUCT to 16-bit format */
+ lparam = (LPARAM)cs;
+ if (unicode)
+ WINPROC_MapMsg32WTo16( WM_CREATE, 0, &msg, &wparam, &lparam );
+ else
+ WINPROC_MapMsg32ATo16( WM_CREATE, 0, &msg, &wparam, &lparam );
+ cbtc->lpcs = (CREATESTRUCT16 *)lparam;
+ cbtc->hwndInsertAfter = hwndLinkAfter;
+ wmcreate = !HOOK_CallHooks( WH_CBT, HCBT_CREATEWND, hwnd,
+ (LPARAM)SEGPTR_GET(cbtc) );
+ WINPROC_UnmapMsg32ATo16( WM_CREATE, 0, lparam );
+ SEGPTR_FREE(cbtc);
+ if (!wmcreate)
+ {
+ dprintf_win(stddeb,"CreateWindowEx: CBT-hook returned 0\n" );
+ USER_HEAP_FREE( hwnd );
+ return 0;
+ }
+ }
+ }
/* Set the window procedure */
+ classPtr->cWindows++;
WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)classPtr->winproc, 0 );
/* Correct the window style */
@@ -541,54 +625,13 @@
/* Get class or window DC if needed */
- if (classPtr->style & CS_OWNDC) wndPtr->hdce = DCE_AllocDCE(hwnd, DCE_WINDOW_DC);
- else if (classPtr->style & CS_CLASSDC) wndPtr->hdce = classPtr->hdce;
- else wndPtr->hdce = 0;
+ if (classPtr->style & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
+ else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
+ else wndPtr->dce = NULL;
/* Insert the window in the linked list */
- WIN_LinkWindow( hwnd, (cs->style & WS_CHILD) ? HWND_BOTTOM : HWND_TOP );
-
- /* Call the WH_CBT hook */
-
- if (HOOK_GetHook( WH_CBT, GetTaskQueue(0) ))
- {
- CBT_CREATEWND16* cbtc;
-
- if ((cbtc = SEGPTR_NEW(CBT_CREATEWND16)))
- {
- /* Dummy message params to use WINPROC_MapMsg functions */
- UINT16 msg;
- WPARAM16 wparam;
- LPARAM lparam;
-
- HWND hwndZnew = (cs->style & WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
-
- /* Map the CREATESTRUCT to 16-bit format */
- lparam = (LPARAM)cs;
- if (unicode)
- WINPROC_MapMsg32WTo16( WM_CREATE, 0, &msg, &wparam, &lparam );
- else
- WINPROC_MapMsg32ATo16( WM_CREATE, 0, &msg, &wparam, &lparam );
- cbtc->lpcs = (CREATESTRUCT16 *)lparam;
- cbtc->hwndInsertAfter = hwndZnew;
- wmcreate = !HOOK_CallHooks( WH_CBT, HCBT_CREATEWND, hwnd,
- (LPARAM)SEGPTR_GET(cbtc) );
- WINPROC_UnmapMsg32ATo16( WM_CREATE, 0, lparam );
- if (hwndZnew != cbtc->hwndInsertAfter)
- {
- WIN_UnlinkWindow( hwnd );
- WIN_LinkWindow( hwnd, cbtc->hwndInsertAfter );
- }
- SEGPTR_FREE(cbtc);
- if (!wmcreate)
- {
- dprintf_win(stddeb,"CreateWindowEx: CBT-hook returned 0\n" );
- WIN_DestroyWindow( hwnd );
- return 0;
- }
- }
- }
+ WIN_LinkWindow( hwnd, hwndLinkAfter );
/* Send the WM_GETMINMAXINFO message and fix the size if needed */
@@ -722,7 +765,8 @@
{
/* Abort window creation */
dprintf_win(stddeb,"CreateWindowEx: wmcreate==-1, aborting\n");
- WIN_DestroyWindow( hwnd );
+ WIN_UnlinkWindow( hwnd );
+ WIN_DestroyWindow( wndPtr );
return 0;
}
@@ -884,7 +928,14 @@
if (!(classAtom = GlobalFindAtom32W( className )))
{
- fprintf( stderr, "CreateWindowEx32W: bad class name %p\n", className );
+ if (HIWORD(className))
+ {
+ LPSTR cn = STRING32_DupUniToAnsi(className);
+ fprintf( stderr, "CreateWindowEx32W: bad class name '%s'\n",cn);
+ free(cn);
+ }
+ else
+ fprintf( stderr, "CreateWindowEx32W: bad class name %p\n", className );
return 0;
}
@@ -909,6 +960,45 @@
/***********************************************************************
+ * WIN_CheckFocus
+ */
+static void WIN_CheckFocus( WND* pWnd )
+{
+ if( GetFocus16() == pWnd->hwndSelf )
+ SetFocus16( (pWnd->dwStyle & WS_CHILD) ? pWnd->parent->hwndSelf : 0 );
+}
+
+/***********************************************************************
+ * WIN_SendDestroyMsg
+ */
+static void WIN_SendDestroyMsg( WND* pWnd )
+{
+ WND* pChild;
+
+ WIN_CheckFocus(pWnd);
+
+ if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret();
+ if( !pWnd->window ) CLIPBOARD_DisOwn( pWnd );
+
+ SendMessage32A( pWnd->hwndSelf, WM_DESTROY, 0, 0);
+
+ if( !IsWindow(pWnd->hwndSelf) )
+ {
+ dprintf_win(stddeb,"\tdestroyed itself while in WM_DESTROY!\n");
+ return;
+ }
+
+ pChild = pWnd->child;
+ while( pChild )
+ {
+ WIN_SendDestroyMsg( pChild );
+ pChild = pChild->next;
+ }
+ WIN_CheckFocus(pWnd);
+}
+
+
+/***********************************************************************
* DestroyWindow (USER.53)
*/
BOOL DestroyWindow( HWND hwnd )
@@ -922,7 +1012,10 @@
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
if (wndPtr == pWndDesktop) return FALSE; /* Can't destroy desktop */
- /* Top-level window */
+ /* Call hooks */
+
+ if( HOOK_CallHooks( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
+ return FALSE;
if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
{
@@ -930,41 +1023,61 @@
/* FIXME: clean up palette - see "Internals" p.352 */
}
+ if( !QUEUE_IsDoomedQueue(wndPtr->hmemTaskQ) )
+ WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LPARAM)hwnd );
+ if( !IsWindow(hwnd) ) return TRUE;
+
+ if( wndPtr->window ) CLIPBOARD_DisOwn( wndPtr ); /* before window is unmapped */
+
/* Hide the window */
if (wndPtr->dwStyle & WS_VISIBLE)
- SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOACTIVATE |
- SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE );
- if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
- ReleaseCapture();
- WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LPARAM)hwnd );
-
- CLIPBOARD_DisOwn( hwnd );
+ {
+ SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW |
+ SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE |
+ ((QUEUE_IsDoomedQueue(wndPtr->hmemTaskQ))?SWP_DEFERERASE:0) );
+ if( !IsWindow(hwnd) ) return TRUE;
+ }
/* Recursively destroy owned windows */
- for (;;)
+ if( !(wndPtr->dwStyle & WS_CHILD) )
{
+ for (;;)
+ {
WND *siblingPtr = wndPtr->parent->child; /* First sibling */
while (siblingPtr)
{
- if (siblingPtr->owner == wndPtr) break;
+ if (siblingPtr->owner == wndPtr)
+ if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ)
+ break;
+ else
+ siblingPtr->owner = NULL;
siblingPtr = siblingPtr->next;
}
if (siblingPtr) DestroyWindow( siblingPtr->hwndSelf );
else break;
+ }
+
+ WINPOS_ActivateOtherWindow(wndPtr);
+
+ if( wndPtr->owner &&
+ wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
+ wndPtr->owner->hwndLastActive = wndPtr->owner->hwndSelf;
}
- /* Send destroy messages and destroy children */
+ /* Send destroy messages */
- SendMessage16( hwnd, WM_DESTROY, 0, 0 );
- while (wndPtr->child) /* The child removes itself from the list */
- DestroyWindow( wndPtr->child->hwndSelf );
- SendMessage16( hwnd, WM_NCDESTROY, 0, 0 );
+ WIN_SendDestroyMsg( wndPtr );
+ if( !IsWindow(hwnd) ) return TRUE;
- /* Destroy the window */
+ /* Unlink now so we won't bother with the children later on */
- WIN_DestroyWindow( hwnd );
+ if( wndPtr->parent ) WIN_UnlinkWindow(hwnd);
+
+ /* Destroy the window storage */
+
+ WIN_DestroyWindow( wndPtr );
return TRUE;
}
@@ -1145,9 +1258,18 @@
/**********************************************************************
- * GetDesktopWindow (USER.286)
+ * GetDesktopWindow16 (USER.286)
*/
-HWND GetDesktopWindow(void)
+HWND16 GetDesktopWindow16(void)
+{
+ return (HWND16)pWndDesktop->hwndSelf;
+}
+
+
+/**********************************************************************
+ * GetDesktopWindow32 (USER32.231)
+ */
+HWND32 GetDesktopWindow32(void)
{
return pWndDesktop->hwndSelf;
}
@@ -1159,9 +1281,9 @@
* Exactly the same thing as GetDesktopWindow(), but not documented.
* Don't ask me why...
*/
-HWND GetDesktopHwnd(void)
+HWND16 GetDesktopHwnd(void)
{
- return pWndDesktop->hwndSelf;
+ return (HWND16)pWndDesktop->hwndSelf;
}
@@ -1186,7 +1308,7 @@
wndPtr->dwStyle |= WS_DISABLED;
if ((hwnd == GetFocus32()) || IsChild( hwnd, GetFocus32() ))
SetFocus32( 0 ); /* A disabled window can't have the focus */
- if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
+ if ((hwnd == GetCapture32()) || IsChild( hwnd, GetCapture32() ))
ReleaseCapture(); /* A disabled window can't capture the mouse */
SendMessage16( hwnd, WM_ENABLE, FALSE, 0 );
return FALSE;
@@ -1892,12 +2014,12 @@
{
if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
{
- HDC hDC = GetDC(hWnd);
+ HDC32 hDC = GetDC32(hWnd);
if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM)hDC, (LPARAM)0 ))
wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
- ReleaseDC( hWnd, hDC );
+ ReleaseDC32( hWnd, hDC );
wndPtr->flags |= WIN_NCACTIVATED;
}
else
@@ -2026,7 +2148,7 @@
rect.top = pt.y - wDragHeight;
rect.bottom = pt.y + wDragHeight;
- SetCapture(hWnd);
+ SetCapture32(hWnd);
while(1)
{
@@ -2105,7 +2227,7 @@
lpDragInfo->hOfStruct = hOfStruct;
lpDragInfo->l = 0L;
- SetCapture(hWnd);
+ SetCapture32(hWnd);
ShowCursor(1);
while( !dragDone )
diff --git a/windows/winpos.c b/windows/winpos.c
index 48d43ee..7efd791 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -48,6 +48,21 @@
static HWND hwndActive = 0; /* Currently active window */
static HWND hwndPrevActive = 0; /* Previously active window */
+extern MESSAGEQUEUE* pActiveQueue;
+
+/***********************************************************************
+ * WINPOS_CheckActive
+ */
+void WINPOS_CheckActive( HWND32 hwnd )
+{
+ if( hwnd == hwndPrevActive ) hwndPrevActive = 0;
+ if( hwnd == hwndActive )
+ {
+ hwndActive = 0;
+ dprintf_win(stddeb,"\tattempt to activate destroyed window!\n");
+ }
+}
+
/***********************************************************************
* WINPOS_FindIconPos
*
@@ -483,13 +498,23 @@
/*******************************************************************
* GetActiveWindow (USER.60)
*/
-HWND GetActiveWindow()
+HWND GetActiveWindow(void)
{
return hwndActive;
}
/*******************************************************************
+ * WINPOS_IsGoodEnough
+ */
+static BOOL32 WINPOS_IsGoodEnough(WND* pWnd)
+{
+ return (pWnd) ? ((!(pWnd->dwStyle & WS_DISABLED) &&
+ pWnd->dwStyle & WS_VISIBLE ) ? TRUE : FALSE) : FALSE;
+}
+
+
+/*******************************************************************
* SetActiveWindow (USER.59)
*/
HWND SetActiveWindow( HWND hwnd )
@@ -497,8 +522,7 @@
HWND prev = hwndActive;
WND *wndPtr = WIN_FindWndPtr( hwnd );
- if (!wndPtr || (wndPtr->dwStyle & WS_DISABLED) ||
- !(wndPtr->dwStyle & WS_VISIBLE)) return 0;
+ if ( !WINPOS_IsGoodEnough(wndPtr) ) return 0;
WINPOS_SetActiveWindow( hwnd, 0, 0 );
return prev;
@@ -562,6 +586,9 @@
swpflags |= SWP_FRAMECHANGED;
if (!(wndPtr->dwStyle & WS_MINIMIZE))
{
+ if( HOOK_CallHooks( WH_CBT, HCBT_MINMAX, hwnd, cmd) )
+ return 0;
+
if (wndPtr->dwStyle & WS_MAXIMIZE)
{
wndPtr->flags |= WIN_RESTORE_MAX;
@@ -587,6 +614,9 @@
swpflags |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
if (!(wndPtr->dwStyle & WS_MAXIMIZE))
{
+ if( HOOK_CallHooks( WH_CBT, HCBT_MINMAX, hwnd, cmd) )
+ return 0;
+
/* Store the current position and find the maximized size */
if (!(wndPtr->dwStyle & WS_MINIMIZE))
wndPtr->rectNormal = wndPtr->rectWindow;
@@ -630,6 +660,9 @@
if (wndPtr->dwStyle & WS_MINIMIZE)
{
+ if( HOOK_CallHooks( WH_CBT, HCBT_MINMAX, hwnd, cmd) )
+ return 0;
+
if( !SendMessage16( hwnd, WM_QUERYOPEN, 0, 0L) )
{
swpflags |= SWP_NOSIZE | SWP_NOMOVE;
@@ -660,6 +693,9 @@
}
else if (wndPtr->dwStyle & WS_MAXIMIZE)
{
+ if( HOOK_CallHooks( WH_CBT, HCBT_MINMAX, hwnd, cmd) )
+ return 0;
+
wndPtr->ptMaxPos.x = wndPtr->rectWindow.left;
wndPtr->ptMaxPos.y = wndPtr->rectWindow.top;
wndPtr->dwStyle &= ~WS_MAXIMIZE;
@@ -855,6 +891,43 @@
return TRUE;
}
+/***********************************************************************
+ * WINPOS_ForceXWindowRaise
+ */
+void WINPOS_ForceXWindowRaise( WND* pWnd )
+{
+ XWindowChanges winChanges;
+ WND *wndStop, *wndLast;
+
+ if (!pWnd->window) return;
+
+ wndLast = wndStop = pWnd;
+ winChanges.stack_mode = Above;
+ XReconfigureWMWindow( display, pWnd->window, 0, CWStackMode, &winChanges );
+
+ /* Recursively raise owned popups according to their z-order
+ * (it would be easier with sibling-related Below but it doesn't
+ * work very well with SGI mwm for instance)
+ */
+ while (wndLast)
+ {
+ WND *wnd = WIN_GetDesktop()->child;
+ wndLast = NULL;
+ while (wnd != wndStop)
+ {
+ if (wnd->owner == pWnd &&
+ (wnd->dwStyle & WS_POPUP) &&
+ (wnd->dwStyle & WS_VISIBLE))
+ wndLast = wnd;
+ wnd = wnd->next;
+ }
+ if (wndLast)
+ {
+ WINPOS_ForceXWindowRaise( wndLast );
+ wndStop = wndLast;
+ }
+ }
+}
/*******************************************************************
* WINPOS_SetActiveWindow
@@ -867,20 +940,16 @@
WND *wndTemp = WIN_FindWndPtr(hwndActive);
CBTACTIVATESTRUCT16 *cbtStruct;
WORD wIconized=0;
- HANDLE hNewActiveQueue;
-
- /* FIXME: When proper support for cooperative multitasking is in place
- * hActiveQ will be global
- */
-
- HANDLE hActiveQ = 0;
+ HANDLE hOldActiveQueue = (pActiveQueue)?pActiveQueue->self:0;
+ HANDLE hNewActiveQueue;
/* paranoid checks */
- if( hWnd == GetDesktopWindow() || hWnd == hwndActive )
+ if( hWnd == GetDesktopWindow32() || hWnd == hwndActive )
return 0;
- if (wndPtr && (GetTaskQueue(0) != wndPtr->hmemTaskQ))
+/* if (wndPtr && (GetTaskQueue(0) != wndPtr->hmemTaskQ))
return 0;
+ */
if( wndTemp )
wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
@@ -946,15 +1015,10 @@
if( !IsWindow(hWnd) ) return 0;
}
- if (hwndPrevActive)
- {
- wndTemp = WIN_FindWndPtr( hwndPrevActive );
- if (wndTemp) hActiveQ = wndTemp->hmemTaskQ;
- }
hNewActiveQueue = wndPtr ? wndPtr->hmemTaskQ : 0;
/* send WM_ACTIVATEAPP if necessary */
- if (hActiveQ != hNewActiveQueue)
+ if (hOldActiveQueue != hNewActiveQueue)
{
WND **list, **ppWnd;
@@ -962,24 +1026,27 @@
{
for (ppWnd = list; *ppWnd; ppWnd++)
{
- /* Make sure that the window still exists */
if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
- if ((*ppWnd)->hmemTaskQ != hActiveQ) continue;
- SendMessage16( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP,
- 0, QUEUE_GetQueueTask(hNewActiveQueue) );
+
+ if ((*ppWnd)->hmemTaskQ == hOldActiveQueue)
+ SendMessage16( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP,
+ 0, QUEUE_GetQueueTask(hNewActiveQueue) );
}
HeapFree( SystemHeap, 0, list );
}
+ pActiveQueue = (hNewActiveQueue)
+ ? (MESSAGEQUEUE*) GlobalLock16(hNewActiveQueue) : NULL;
+
if ((list = WIN_BuildWinArray( WIN_GetDesktop() )))
{
for (ppWnd = list; *ppWnd; ppWnd++)
{
- /* Make sure that the window still exists */
if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
- if ((*ppWnd)->hmemTaskQ != hNewActiveQueue) continue;
- SendMessage16( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP,
- 1, QUEUE_GetQueueTask( hActiveQ ) );
+
+ if ((*ppWnd)->hmemTaskQ == hNewActiveQueue)
+ SendMessage16( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP,
+ 1, QUEUE_GetQueueTask( hOldActiveQueue ) );
}
HeapFree( SystemHeap, 0, list );
}
@@ -1009,6 +1076,10 @@
FOCUS_SwitchFocus( GetFocus32(),
(wndPtr->dwStyle & WS_MINIMIZE)? 0: hwndActive);
+ if( !hwndPrevActive && wndPtr &&
+ wndPtr->window && !(wndPtr->flags & WIN_MANAGED) )
+ WINPOS_ForceXWindowRaise(wndPtr);
+
/* if active wnd is minimized redraw icon title
if( hwndActive )
{
@@ -1020,6 +1091,50 @@
return (hWnd == hwndActive);
}
+/*******************************************************************
+ * WINPOS_ActivateOtherWindow
+ *
+ * DestroyWindow() helper. pWnd must be a top-level window.
+ */
+BOOL32 WINPOS_ActivateOtherWindow(WND* pWnd)
+{
+ BOOL32 bRet = 0;
+ WND* pWndTo = NULL;
+
+ if( pWnd->hwndSelf == hwndPrevActive )
+ hwndPrevActive = 0;
+
+ if( hwndActive != pWnd->hwndSelf &&
+ ( hwndActive || QUEUE_IsDoomedQueue(pWnd->hmemTaskQ)) )
+ return 0;
+
+ if( pWnd->dwStyle & WS_POPUP &&
+ WINPOS_IsGoodEnough( pWnd->owner ) ) pWndTo = pWnd->owner;
+ else
+ {
+ WND* pWndPtr = pWnd;
+
+ pWndTo = WIN_FindWndPtr(hwndPrevActive);
+
+ while( !WINPOS_IsGoodEnough(pWndTo) )
+ {
+ /* by now owned windows should've been taken care of */
+
+ pWndTo = pWndPtr->next;
+ pWndPtr = pWndTo;
+ if( !pWndTo ) return 0;
+ }
+ }
+
+ bRet = WINPOS_SetActiveWindow( pWndTo->hwndSelf, FALSE, TRUE );
+
+ /* switch desktop queue to current active */
+ if( pWndTo->parent == WIN_GetDesktop())
+ WIN_GetDesktop()->hmemTaskQ = pWndTo->hmemTaskQ;
+
+ hwndPrevActive = 0;
+ return bRet;
+}
/*******************************************************************
* WINPOS_ChangeActiveWindow
@@ -1219,67 +1334,41 @@
*/
HWND WINPOS_ReorderOwnedPopups(HWND hwndInsertAfter, WND* wndPtr, WORD flags)
{
- WND* w = WIN_GetDesktop();
+ WND* w = WIN_GetDesktop()->child;
- w = w->child;
+ if( wndPtr->dwStyle & WS_POPUP && wndPtr->owner )
+ {
+ /* implement "local z-order" between the top and owner window */
- /* if we are dealing with owned popup...
- */
- if( wndPtr->dwStyle & WS_POPUP && wndPtr->owner && hwndInsertAfter != HWND_TOP )
- {
- BOOL bFound = FALSE;
HWND hwndLocalPrev = HWND_TOP;
- HWND hwndNewAfter = 0;
- while( w )
- {
- if( !bFound && hwndInsertAfter == hwndLocalPrev )
- hwndInsertAfter = HWND_TOP;
+ if( hwndInsertAfter != HWND_TOP )
+ {
+ while( w != wndPtr->owner )
+ {
+ hwndLocalPrev = w->hwndSelf;
+ if( hwndLocalPrev == hwndInsertAfter ) break;
+ w = w->next;
+ }
+ hwndInsertAfter = hwndLocalPrev;
+ }
- if( w->dwStyle & WS_POPUP && w->owner == wndPtr->owner )
- {
- bFound = TRUE;
+ }
+ else if( wndPtr->dwStyle & WS_CHILD ) return hwndInsertAfter;
- if( hwndInsertAfter == HWND_TOP )
- {
- hwndInsertAfter = hwndLocalPrev;
- break;
- }
- hwndNewAfter = hwndLocalPrev;
- }
+ w = WIN_GetDesktop()->child;
+ while( w )
+ {
+ if( w == wndPtr ) break;
- if( w == wndPtr->owner )
- {
- /* basically HWND_BOTTOM */
- hwndInsertAfter = hwndLocalPrev;
-
- if( bFound )
- hwndInsertAfter = hwndNewAfter;
- break;
- }
-
- if( w != wndPtr )
- hwndLocalPrev = w->hwndSelf;
-
- w = w->next;
- }
- }
- else
- /* or overlapped top-level window...
- */
- if( !(wndPtr->dwStyle & WS_CHILD) )
- while( w )
- {
- if( w == wndPtr ) break;
-
- if( w->dwStyle & WS_POPUP && w->owner == wndPtr )
- {
- SetWindowPos(w->hwndSelf, hwndInsertAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE |
- SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_DEFERERASE);
- hwndInsertAfter = w->hwndSelf;
- }
- w = w->next;
- }
+ if( w->dwStyle & WS_POPUP && w->owner == wndPtr )
+ {
+ SetWindowPos(w->hwndSelf, hwndInsertAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE |
+ SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_DEFERERASE);
+ hwndInsertAfter = w->hwndSelf;
+ }
+ w = w->next;
+ }
return hwndInsertAfter;
}
@@ -1343,7 +1432,7 @@
}
else /* bitblt old client area */
{
- HDC hDC;
+ HDC32 hDC;
int update;
HRGN updateRgn;
int xfrom,yfrom,xto,yto,width,height;
@@ -1386,11 +1475,13 @@
OffsetRgn( newVisRgn, Wnd->rectClient.left, Wnd->rectClient.top);
CombineRgn( oldVisRgn, oldVisRgn, newVisRgn, RGN_OR );
- hDC = GetDCEx( Wnd->parent->hwndSelf, oldVisRgn, DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_CACHE | DCX_CLIPSIBLINGS);
+ hDC = GetDCEx32( Wnd->parent->hwndSelf, oldVisRgn,
+ DCX_KEEPCLIPRGN | DCX_INTERSECTRGN |
+ DCX_CACHE | DCX_CLIPSIBLINGS);
BitBlt( hDC, xto, yto, width, height, hDC, xfrom, yfrom, SRCCOPY );
- ReleaseDC( Wnd->parent->hwndSelf, hDC);
+ ReleaseDC32( Wnd->parent->hwndSelf, hDC);
}
if( update != NULLREGION )
@@ -1412,45 +1503,6 @@
/***********************************************************************
- * WINPOS_ForceXWindowRaise
- */
-void WINPOS_ForceXWindowRaise( WND* pWnd )
-{
- XWindowChanges winChanges;
- WND *wndStop, *wndLast;
-
- if (!pWnd->window) return;
-
- wndLast = wndStop = pWnd;
- winChanges.stack_mode = Above;
- XReconfigureWMWindow( display, pWnd->window, 0, CWStackMode, &winChanges );
-
- /* Recursively raise owned popups according to their z-order
- * (it would be easier with sibling-related Below but it doesn't
- * work very well with SGI mwm for instance)
- */
- while (wndLast)
- {
- WND *wnd = WIN_GetDesktop()->child;
- wndLast = NULL;
- while (wnd != wndStop)
- {
- if (wnd->owner == pWnd &&
- (wnd->dwStyle & WS_POPUP) &&
- (wnd->dwStyle & WS_VISIBLE))
- wndLast = wnd;
- wnd = wnd->next;
- }
- if (wndLast)
- {
- WINPOS_ForceXWindowRaise( wndLast );
- wndStop = wndLast;
- }
- }
-}
-
-
-/***********************************************************************
* WINPOS_SetXWindowPos
*
* SetWindowPos() for an X window. Used by the real SetWindowPos().
@@ -1496,22 +1548,27 @@
}
if (!(winpos->flags & SWP_NOZORDER))
{
+ winChanges.stack_mode = Below;
+ changeMask |= CWStackMode;
+
if (winpos->hwndInsertAfter == HWND_TOP) winChanges.stack_mode = Above;
- else winChanges.stack_mode = Below;
- if ((winpos->hwndInsertAfter != HWND_TOP) &&
- (winpos->hwndInsertAfter != HWND_BOTTOM))
+ else if (winpos->hwndInsertAfter != HWND_BOTTOM)
{
- WND * insertPtr = WIN_FindWndPtr( winpos->hwndInsertAfter );
- winChanges.sibling = insertPtr->window;
- changeMask |= CWSibling;
- }
- changeMask |= CWStackMode;
+ WND* insertPtr = WIN_FindWndPtr( winpos->hwndInsertAfter );
+ Window stack[2];
+
+ stack[0] = insertPtr->window;
+ stack[1] = wndPtr->window;
+
+ /* for stupid window managers (i.e. all of them) */
+
+ XRestackWindows(display, stack, 2);
+ changeMask &= ~CWStackMode;
+ }
}
if (!changeMask) return;
- if (wndPtr->flags & WIN_MANAGED)
- XReconfigureWMWindow( display, wndPtr->window, 0,
- changeMask, &winChanges );
- else XConfigureWindow( display, wndPtr->window, changeMask, &winChanges );
+
+ XReconfigureWMWindow( display, wndPtr->window, 0, changeMask, &winChanges );
}
@@ -1533,7 +1590,7 @@
hwnd, x, y, x+cx, y+cy, flags);
/* Check window handle */
- if (hwnd == GetDesktopWindow()) return FALSE;
+ if (hwnd == GetDesktopWindow32()) return FALSE;
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
if (wndPtr->dwStyle & WS_VISIBLE) flags &= ~SWP_SHOWWINDOW;
@@ -1839,7 +1896,7 @@
HWND newActive = hwndPrevActive;
if (!IsWindow(newActive) || (newActive == winpos->hwnd))
{
- newActive = GetTopWindow( GetDesktopWindow() );
+ newActive = GetTopWindow( GetDesktopWindow32() );
if (newActive == winpos->hwnd)
newActive = wndPtr->next ? wndPtr->next->hwndSelf : 0;
}
@@ -1859,7 +1916,14 @@
EVENT_DummyMotionNotify(); /* Simulate a mouse event to set the cursor */
if (!(flags & SWP_DEFERERASE) && !(uFlags & SMC_NOPARENTERASE) )
- PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0, RDW_ALLCHILDREN | RDW_ERASENOW, 0 );
+ {
+ RECT32 rect;
+ CONV_RECT16TO32( &oldWindowRect, &rect );
+ PAINT_RedrawWindow( wndPtr->parent->hwndSelf, (wndPtr->flags & WIN_SAVEUNDER_OVERRIDE)
+ ? &rect : NULL, 0, RDW_ALLCHILDREN | RDW_ERASENOW |
+ ((wndPtr->flags & WIN_SAVEUNDER_OVERRIDE) ? RDW_INVALIDATE : 0), 0 );
+ wndPtr->flags &= ~WIN_SAVEUNDER_OVERRIDE;
+ }
else if( wndPtr->parent == WIN_GetDesktop() && wndPtr->parent->flags & WIN_NEEDS_ERASEBKGND )
PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0, RDW_NOCHILDREN | RDW_ERASENOW, 0 );
@@ -1911,7 +1975,7 @@
pDWP = (DWP *) USER_HEAP_LIN_ADDR( hdwp );
if (!pDWP) return 0;
- if (hwnd == GetDesktopWindow()) return 0;
+ if (hwnd == GetDesktopWindow32()) return 0;
/* All the windows of a DeferWindowPos() must have the same parent */