Author: jimtabor
Date: Wed Apr 6 12:53:52 2011
New Revision: 51265
URL:
http://svn.reactos.org/svn/reactos?rev=51265&view=rev
Log:
[User32|Win32k]
- Pass all the wine test_capture_1/2/3/4.
- Fix the menu tracking pop up hang issue by looking for deceased windows that pass on
while in the start of tracking. This could be a fix for other wine tests.
- ReactOS is not Linux and wine is not enough!
Modified:
trunk/reactos/dll/win32/user32/windows/menu.c
trunk/reactos/dll/win32/user32/windows/message.c
trunk/reactos/subsystems/win32/win32k/include/focus.h
trunk/reactos/subsystems/win32/win32k/ntuser/focus.c
trunk/reactos/subsystems/win32/win32k/ntuser/message.c
trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c
Modified: trunk/reactos/dll/win32/user32/windows/menu.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/m…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/menu.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/user32/windows/menu.c [iso-8859-1] Wed Apr 6 12:53:52 2011
@@ -1576,6 +1576,11 @@
MenuInfo.FocusedItem = NO_SELECTED_ITEM;
}
+ /* ReactOS Check */
+ if (!ValidateHwnd(hwndOwner))
+ { // This window maybe already DEAD!!!
+ return FALSE;
+ }
/* store the owner for DrawItem */
MenuInfo.WndOwner = hwndOwner;
MenuSetRosMenuInfo(&MenuInfo);
@@ -3208,14 +3213,16 @@
fEndMenu = !fRemove;
}
+ if (wFlags & TF_ENDMENU) fEndMenu = TRUE;
+
/* owner may not be visible when tracking a popup, so use the menu itself */
capture_win = (wFlags & TPM_POPUPMENU) ? MenuInfo.Wnd : mt.OwnerWnd;
(void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, capture_win); // 1
SetCapture(capture_win); // 2
- FIXME("MenuTrackMenu 1\n");
while (! fEndMenu)
{
+ BOOL ErrorExit = FALSE;
PVOID menu = ValidateHandle(mt.CurrentMenu, VALIDATE_TYPE_MENU);
if (!menu) /* sometimes happens if I do a window manager close */
break;
@@ -3233,6 +3240,12 @@
}
else
{
+ /* ReactOS Check */
+ if (!ValidateHwnd(mt.OwnerWnd) || !ValidateHwnd(MenuInfo.Wnd))
+ {
+ ErrorExit = TRUE; // Do not wait on dead windows, now test_capture_4
works.
+ break;
+ }
if (!enterIdleSent)
{
HWND win = MenuInfo.Flags & MF_POPUP ? MenuInfo.Wnd : NULL;
@@ -3241,8 +3254,9 @@
}
WaitMessage();
}
- //FIXME("MenuTrackMenu loop 1\n");
- }
+ }
+
+ if (ErrorExit) break; // Gracefully dropout.
/* check if EndMenu() tried to cancel us, by posting this message */
if (msg.message == WM_CANCELMODE)
@@ -3449,7 +3463,6 @@
{
PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
DispatchMessageW( &msg );
- //FIXME("MenuTrackMenu loop 2\n");
continue;
}
@@ -3460,9 +3473,7 @@
if (fRemove && !(mt.TrackFlags & TF_SKIPREMOVE) )
PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
else mt.TrackFlags &= ~TF_SKIPREMOVE;
- //FIXME("MenuTrackMenu loop 3\n");
- }
- FIXME("MenuTrackMenu 2\n");
+ }
(void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, NULL);
SetCapture(NULL); /* release the capture */
@@ -3521,12 +3532,11 @@
HideCaret(0);
- MenuGetRosMenuInfo(&MenuInfo, hMenu);
/* This makes the menus of applications built with Delphi work.
* It also enables menus to be displayed in more than one window,
* but there are some bugs left that need to be fixed in this case.
*/
- if(MenuInfo.Self == hMenu)
+ if (MenuGetRosMenuInfo(&MenuInfo, hMenu))
{
MenuInfo.Wnd = hWnd;
MenuSetRosMenuInfo(&MenuInfo);
@@ -3658,13 +3668,7 @@
MenuSelectItem( hwnd, &MenuInfo, uItem, TRUE, 0 );
- if (wParam & HTSYSMENU)
- {
- /* prevent sysmenu activation for managed windows on Alt down/up */
-// if (GetPropA( hwnd, "__wine_x11_managed" ))
- wFlags |= TF_ENDMENU; /* schedule end of menu tracking */
- }
- else
+ if (!(wParam & HTSYSMENU) || wChar == ' ')
{
if( uItem == NO_SELECTED_ITEM )
MenuMoveSelection( hwnd, &MenuInfo, ITEM_NEXT );
@@ -3691,6 +3695,12 @@
{
SetLastError( ERROR_INVALID_MENU_HANDLE );
return FALSE;
+ }
+
+ /* ReactOS Check */
+ if (!ValidateHwnd(Wnd))
+ {
+ return FALSE;
}
MenuGetRosMenuInfo(&MenuInfo, Menu);
Modified: trunk/reactos/dll/win32/user32/windows/message.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/m…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/message.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/user32/windows/message.c [iso-8859-1] Wed Apr 6 12:53:52
2011
@@ -2380,9 +2380,7 @@
BOOL WINAPI
ReleaseCapture(VOID)
{
- HWND hwndPrev = NtUserSetCapture(NULL);
- return(hwndPrev ? TRUE : FALSE);
-// return (BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_RELEASECAPTURE);
+ return (BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_RELEASECAPTURE);
}
Modified: trunk/reactos/subsystems/win32/win32k/include/focus.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/focus.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/focus.h [iso-8859-1] Wed Apr 6 12:53:52
2011
@@ -7,6 +7,10 @@
IntGetCaptureWindow(VOID);
HWND FASTCALL
IntGetFocusWindow(VOID);
+HWND FASTCALL
+co_UserSetCapture(HWND hWnd);
+BOOL FASTCALL
+IntReleaseCapture(VOID);
/*
* These functions take the window handles from current thread queue.
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/focus.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/focus.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/focus.c [iso-8859-1] Wed Apr 6 12:53:52
2011
@@ -580,15 +580,42 @@
ThreadQueue->CaptureWindow = hWnd;
+ if (hWnd == NULL) // Release mode.
+ {
+ MOUSEINPUT mi;
/// These are hacks!
- /* also remove other windows if not capturing anymore */
- if (hWnd == NULL)
- {
+ /* also remove other windows if not capturing anymore */
MsqSetStateWindow(ThreadQueue, MSQ_STATE_MENUOWNER, NULL);
MsqSetStateWindow(ThreadQueue, MSQ_STATE_MOVESIZE, NULL);
- }
///
+ /* Somebody may have missed some mouse movements */
+ mi.dx = 0;
+ mi.dy = 0;
+ mi.mouseData = 0;
+ mi.dwFlags = MOUSEEVENTF_MOVE;
+ mi.time = 0;
+ mi.dwExtraInfo = 0;
+ IntMouseInput(&mi);
+ }
return hWndPrev;
+}
+
+BOOL
+FASTCALL
+IntReleaseCapture(VOID)
+{
+ PTHREADINFO pti;
+ PUSER_MESSAGE_QUEUE ThreadQueue;
+
+ pti = PsGetCurrentThreadWin32Thread();
+ ThreadQueue = pti->MessageQueue;
+
+ // Can not release inside WM_CAPTURECHANGED!!
+ if (ThreadQueue->QF_flags & QF_CAPTURELOCKED) return FALSE;
+
+ co_UserSetCapture(NULL);
+
+ return TRUE;
}
/*
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/message.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/message.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/message.c [iso-8859-1] Wed Apr 6
12:53:52 2011
@@ -16,7 +16,6 @@
#include <debug.h>
BOOLEAN NTAPI PsGetProcessExitProcessCalled(PEPROCESS Process);
-HWND FASTCALL co_UserSetCapture(HWND hWnd);
#define PM_BADMSGFLAGS ~((QS_RAWINPUT <<
16)|PM_QS_SENDMESSAGE|PM_QS_PAINT|PM_QS_POSTMESSAGE|PM_QS_INPUT|PM_NOYIELD|PM_REMOVE)
@@ -861,7 +860,6 @@
{
SetLastNtError(Status);
DPRINT1("Exit co_IntWaitMessage on error!\n");
-
return FALSE;
}
if (Status == STATUS_USER_APC || Status == STATUS_TIMEOUT)
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c [iso-8859-1] Wed Apr 6
12:53:52 2011
@@ -118,6 +118,9 @@
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
RETURN( (DWORD_PTR)MAKELONG(pti->ptLast.x, pti->ptLast.y));
}
+
+ case NOPARAM_ROUTINE_RELEASECAPTURE:
+ RETURN( (DWORD_PTR)IntReleaseCapture());
default:
DPRINT1("Calling invalid routine number 0x%x in NtUserCallNoParam\n",
Routine);
@@ -251,7 +254,6 @@
case ONEPARAM_ROUTINE_GETCURSORPOSITION:
{
BOOL ret = TRUE;
-
_SEH2_TRY
{