Author: jimtabor Date: Fri Apr 8 19:29:15 2011 New Revision: 51283
URL: http://svn.reactos.org/svn/reactos?rev=51283&view=rev Log: [User32|Win32k] - Fix TrackMouseEvent! Keyboard and Mouse pass all the right flags. Update to accelerator code. Fixed recursion in global hooks. Hack-implement GetMouseMovePointsEx due to slack time and boredom, it passes the input tests but does nothing. Pass all the test_TrackMouseEvent!!! test_accelerators and test_menu_messages work too, so far no hangs.
Modified: trunk/reactos/dll/win32/user32/include/user32p.h trunk/reactos/dll/win32/user32/misc/dllmain.c trunk/reactos/dll/win32/user32/user32.pspec trunk/reactos/dll/win32/user32/windows/input.c trunk/reactos/subsystems/win32/win32k/include/cursoricon.h trunk/reactos/subsystems/win32/win32k/include/desktop.h trunk/reactos/subsystems/win32/win32k/include/input.h trunk/reactos/subsystems/win32/win32k/include/msgqueue.h trunk/reactos/subsystems/win32/win32k/include/timer.h trunk/reactos/subsystems/win32/win32k/ntuser/accelerator.c trunk/reactos/subsystems/win32/win32k/ntuser/callback.c trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c trunk/reactos/subsystems/win32/win32k/ntuser/focus.c trunk/reactos/subsystems/win32/win32k/ntuser/hook.c trunk/reactos/subsystems/win32/win32k/ntuser/input.c trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c trunk/reactos/subsystems/win32/win32k/ntuser/menu.c trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c trunk/reactos/subsystems/win32/win32k/ntuser/timer.c trunk/reactos/subsystems/win32/win32k/ntuser/window.c
Modified: trunk/reactos/dll/win32/user32/include/user32p.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/include/us... ============================================================================== --- trunk/reactos/dll/win32/user32/include/user32p.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/user32/include/user32p.h [iso-8859-1] Fri Apr 8 19:29:15 2011 @@ -112,19 +112,6 @@ /* Critical Section*/ extern RTL_CRITICAL_SECTION User32Crit;
-typedef struct _USER32_TRACKINGLIST { - TRACKMOUSEEVENT tme; - POINT pos; /* center of hover rectangle */ - UINT_PTR timer; -} USER32_TRACKINGLIST,*PUSER32_TRACKINGLIST; - -typedef struct _USER32_THREAD_DATA -{ - USER32_TRACKINGLIST tracking_info; /* TrackMouseEvent stuff */ -} USER32_THREAD_DATA, *PUSER32_THREAD_DATA; - -PUSER32_THREAD_DATA User32GetThreadData(VOID); - /* FIXME: Belongs to some header. */ BOOL WINAPI GdiDllInitialize(HANDLE, DWORD, LPVOID); void InitStockObjects(void);
Modified: trunk/reactos/dll/win32/user32/misc/dllmain.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/misc/dllma... ============================================================================== --- trunk/reactos/dll/win32/user32/misc/dllmain.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/user32/misc/dllmain.c [iso-8859-1] Fri Apr 8 19:29:15 2011 @@ -16,13 +16,6 @@ BOOL gfServerProcess = FALSE;
WCHAR szAppInit[KEY_LENGTH]; - -PUSER32_THREAD_DATA -User32GetThreadData() -{ - return ((PUSER32_THREAD_DATA)TlsGetValue(User32TlsIndex)); -} -
BOOL GetDllList() @@ -192,25 +185,12 @@ BOOL InitThread(VOID) { - PUSER32_THREAD_DATA ThreadData; - - ThreadData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(USER32_THREAD_DATA)); - if (ThreadData == NULL) - return FALSE; - if (!TlsSetValue(User32TlsIndex, ThreadData)) - return FALSE; return TRUE; }
VOID CleanupThread(VOID) { - PUSER32_THREAD_DATA ThreadData; - - ThreadData = (PUSER32_THREAD_DATA)TlsGetValue(User32TlsIndex); - HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, ThreadData); - TlsSetValue(User32TlsIndex, 0); }
BOOL
Modified: trunk/reactos/dll/win32/user32/user32.pspec URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/user32.psp... ============================================================================== --- trunk/reactos/dll/win32/user32/user32.pspec [iso-8859-1] (original) +++ trunk/reactos/dll/win32/user32/user32.pspec [iso-8859-1] Fri Apr 8 19:29:15 2011 @@ -690,7 +690,7 @@ @ stdcall ToAsciiEx(long long ptr ptr long long) @ stdcall ToUnicode(long long ptr ptr long long) @ stdcall ToUnicodeEx(long long ptr ptr long long long) -@ stdcall TrackMouseEvent(ptr) ; Direct call NtUserTrackMouseEvent +@ stdcall TrackMouseEvent(ptr) NtUserTrackMouseEvent @ stdcall TrackPopupMenu(long long long long long long ptr) @ stdcall TrackPopupMenuEx(long long long long long ptr) ; Direct call NtUserTrackPopupMenuEx @ stdcall TranslateAccelerator(long long ptr) TranslateAcceleratorA
Modified: trunk/reactos/dll/win32/user32/windows/input.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/in... ============================================================================== --- trunk/reactos/dll/win32/user32/windows/input.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/user32/windows/input.c [iso-8859-1] Fri Apr 8 19:29:15 2011 @@ -530,242 +530,4 @@ NtUserSendInput(1, &Input, sizeof(INPUT)); }
- -/*********************************************************************** - * get_key_state - */ -static WORD get_key_state(void) -{ - WORD ret = 0; - - if (GetSystemMetrics( SM_SWAPBUTTON )) - { - if (GetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_LBUTTON; - if (GetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_RBUTTON; - } - else - { - if (GetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_LBUTTON; - if (GetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_RBUTTON; - } - if (GetAsyncKeyState(VK_MBUTTON) & 0x80) ret |= MK_MBUTTON; - if (GetAsyncKeyState(VK_SHIFT) & 0x80) ret |= MK_SHIFT; - if (GetAsyncKeyState(VK_CONTROL) & 0x80) ret |= MK_CONTROL; - if (GetAsyncKeyState(VK_XBUTTON1) & 0x80) ret |= MK_XBUTTON1; - if (GetAsyncKeyState(VK_XBUTTON2) & 0x80) ret |= MK_XBUTTON2; - return ret; -} - -static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR idEvent, - DWORD dwTime) -{ - POINT pos; - POINT posClient; - HWND hwnd; - INT hoverwidth = 0, hoverheight = 0; - RECT client; - PUSER32_TRACKINGLIST ptracking_info; - - ptracking_info = & User32GetThreadData()->tracking_info; - - GetCursorPos(&pos); - hwnd = WindowFromPoint(pos); - - SystemParametersInfoW(SPI_GETMOUSEHOVERWIDTH, 0, &hoverwidth, 0); - SystemParametersInfoW(SPI_GETMOUSEHOVERHEIGHT, 0, &hoverheight, 0); - - /* see if this tracking event is looking for TME_LEAVE and that the */ - /* mouse has left the window */ - if (ptracking_info->tme.dwFlags & TME_LEAVE) - { - if (ptracking_info->tme.hwndTrack != hwnd) - { - if (ptracking_info->tme.dwFlags & TME_NONCLIENT) - { - PostMessageW(ptracking_info->tme.hwndTrack, WM_NCMOUSELEAVE, 0, 0); - } - else - { - PostMessageW(ptracking_info->tme.hwndTrack, WM_MOUSELEAVE, 0, 0); - } - - /* remove the TME_LEAVE flag */ - ptracking_info->tme.dwFlags &= ~TME_LEAVE; - } - else - { - GetClientRect(hwnd, &client); - MapWindowPoints(hwnd, NULL, (LPPOINT)&client, 2); - if (PtInRect(&client, pos)) - { - if (ptracking_info->tme.dwFlags & TME_NONCLIENT) - { - PostMessageW(ptracking_info->tme.hwndTrack, WM_NCMOUSELEAVE, 0, 0); - /* remove the TME_LEAVE flag */ - ptracking_info->tme.dwFlags &= ~TME_LEAVE; - } - } - else - { - if (!(ptracking_info->tme.dwFlags & TME_NONCLIENT)) - { - PostMessageW(ptracking_info->tme.hwndTrack, WM_MOUSELEAVE, 0, 0); - /* remove the TME_LEAVE flag */ - ptracking_info->tme.dwFlags &= ~TME_LEAVE; - } - } - } - } - - /* see if we are tracking hovering for this hwnd */ - if (ptracking_info->tme.dwFlags & TME_HOVER) - { - /* has the cursor moved outside the rectangle centered around pos? */ - if ((abs(pos.x - ptracking_info->pos.x) > (hoverwidth / 2.0)) || - (abs(pos.y - ptracking_info->pos.y) > (hoverheight / 2.0))) - { - /* record this new position as the current position and reset */ - /* the iHoverTime variable to 0 */ - ptracking_info->pos = pos; - } - else - { - posClient.x = pos.x; - posClient.y = pos.y; - ScreenToClient(hwnd, &posClient); - - if (ptracking_info->tme.dwFlags & TME_NONCLIENT) - { - PostMessageW(ptracking_info->tme.hwndTrack, WM_NCMOUSEHOVER, - get_key_state(), MAKELPARAM( posClient.x, posClient.y )); - } - else - { - PostMessageW(ptracking_info->tme.hwndTrack, WM_MOUSEHOVER, - get_key_state(), MAKELPARAM( posClient.x, posClient.y )); - } - - /* stop tracking mouse hover */ - ptracking_info->tme.dwFlags &= ~TME_HOVER; - } - } - - /* stop the timer if the tracking list is empty */ - if (!(ptracking_info->tme.dwFlags & (TME_HOVER | TME_LEAVE))) - { - KillTimer(0, ptracking_info->timer); - RtlZeroMemory(ptracking_info,sizeof(USER32_TRACKINGLIST)); - } -} - - -/*********************************************************************** - * TrackMouseEvent [USER32] - * - * Requests notification of mouse events - * - * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted - * to the hwnd specified in the ptme structure. After the event message - * is posted to the hwnd, the entry in the queue is removed. - * - * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely - * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted - * immediately and the TME_LEAVE flag being ignored. - * - * PARAMS - * ptme [I,O] pointer to TRACKMOUSEEVENT information structure. - * - * RETURNS - * Success: non-zero - * Failure: zero - * - */ -/* - * @implemented - */ -BOOL -WINAPI -TrackMouseEvent( - LPTRACKMOUSEEVENT ptme) -{ - HWND hwnd; - POINT pos; - DWORD hover_time; - PUSER32_TRACKINGLIST ptracking_info; - - TRACE("%lx, %lx, %p, %lx\n", ptme->cbSize, ptme->dwFlags, ptme->hwndTrack, ptme->dwHoverTime); - - if (ptme->cbSize != sizeof(TRACKMOUSEEVENT)) { - WARN("wrong TRACKMOUSEEVENT size from app\n"); - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - ptracking_info = & User32GetThreadData()->tracking_info; - - /* fill the TRACKMOUSEEVENT struct with the current tracking for the given hwnd */ - if (ptme->dwFlags & TME_QUERY ) - { - *ptme = ptracking_info->tme; - ptme->cbSize = sizeof(TRACKMOUSEEVENT); - - return TRUE; /* return here, TME_QUERY is retrieving information */ - } - - if (!IsWindow(ptme->hwndTrack)) - { - SetLastError(ERROR_INVALID_WINDOW_HANDLE); - return FALSE; - } - - hover_time = ptme->dwHoverTime; - - /* if HOVER_DEFAULT was specified replace this with the systems current value */ - if (hover_time == HOVER_DEFAULT || hover_time == 0) - { - SystemParametersInfoW(SPI_GETMOUSEHOVERTIME, 0, &hover_time, 0); - } - - GetCursorPos(&pos); - hwnd = WindowFromPoint(pos); - - if (ptme->dwFlags & ~(TME_CANCEL | TME_HOVER | TME_LEAVE | TME_NONCLIENT)) - { - FIXME("Unknown flag(s) %08lx\n", ptme->dwFlags & ~(TME_CANCEL | TME_HOVER | TME_LEAVE | TME_NONCLIENT)); - } - - if (ptme->dwFlags & TME_CANCEL) - { - if (ptracking_info->tme.hwndTrack == ptme->hwndTrack) - { - ptracking_info->tme.dwFlags &= ~(ptme->dwFlags & ~TME_CANCEL); - - /* if we aren't tracking on hover or leave remove this entry */ - if (!(ptracking_info->tme.dwFlags & (TME_HOVER | TME_LEAVE))) - { - KillTimer(0, ptracking_info->timer); - RtlZeroMemory(ptracking_info,sizeof(USER32_TRACKINGLIST)); - } - } - } else { - if (ptme->hwndTrack == hwnd) - { - /* Adding new mouse event to the tracking list */ - ptracking_info->tme = *ptme; - ptracking_info->tme.dwHoverTime = hover_time; - - /* Initialize HoverInfo variables even if not hover tracking */ - ptracking_info->pos = pos; - - if (!ptracking_info->timer) - { - ptracking_info->timer = SetTimer(0, 0, hover_time, TrackMouseEventProc); - } - } - } - - return TRUE; - -} - /* EOF */
Modified: trunk/reactos/subsystems/win32/win32k/include/cursoricon.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/include/cursoricon.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/include/cursoricon.h [iso-8859-1] Fri Apr 8 19:29:15 2011 @@ -69,7 +69,7 @@ INT cyHeight, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags); PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon);
-BOOL UserSetCursorPos( INT x, INT y, BOOL SendMouseMoveMsg); +BOOL UserSetCursorPos( INT x, INT y);
int UserShowCursor(BOOL bShow);
Modified: trunk/reactos/subsystems/win32/win32k/include/desktop.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/include/desktop.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/include/desktop.h [iso-8859-1] Fri Apr 8 19:29:15 2011 @@ -9,6 +9,7 @@ LIST_ENTRY ListEntry; /* Pointer to the associated window station. */ struct _WINSTATION_OBJECT *rpwinstaParent; + DWORD dwDTFlags; PWND spwndForeground; PWND spwndTray; PWND spwndMessage; @@ -27,11 +28,19 @@ /* Pointer to the active queue. */ PVOID ActiveMessageQueue; /* Handle of the desktop window. */ - HANDLE DesktopWindow; + HWND DesktopWindow; /* Thread blocking input */ PVOID BlockInputThread; LIST_ENTRY ShellHookWindows; } DESKTOP, *PDESKTOP; + +// Desktop flags +#define DF_TME_HOVER 0x00000400 +#define DF_TME_LEAVE 0x00000800 +#define DF_DESTROYED 0x00008000 +#define DF_DESKWNDDESTROYED 0x00010000 +#define DF_DYING 0x00020000 +
extern PDESKTOP InputDesktop; extern HDESK InputDesktopHandle; @@ -125,6 +134,7 @@ BOOL IntDeRegisterShellHookWindow(HWND hWnd); VOID co_IntShellHookNotify(WPARAM Message, LPARAM lParam); HDC FASTCALL UserGetDesktopDC(ULONG,BOOL,BOOL); +BOOL FASTCALL IntPaintDesktop(HDC hDC);
#define IntIsActiveDesktop(Desktop) \ ((Desktop)->rpwinstaParent->ActiveDesktop == (Desktop))
Modified: trunk/reactos/subsystems/win32/win32k/include/input.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/include/input.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/include/input.h [iso-8859-1] Fri Apr 8 19:29:15 2011 @@ -42,8 +42,8 @@ PKBL W32kGetDefaultKeyLayout(VOID); VOID FASTCALL W32kKeyProcessMessage(LPMSG Msg, PKBDTABLES KeyLayout, BYTE Prefix); BOOL FASTCALL IntBlockInput(PTHREADINFO W32Thread, BOOL BlockIt); -BOOL FASTCALL IntMouseInput(MOUSEINPUT *mi); -BOOL FASTCALL IntKeyboardInput(KEYBDINPUT *ki); +BOOL FASTCALL IntMouseInput(MOUSEINPUT *mi, BOOL Injected); +BOOL FASTCALL IntKeyboardInput(KEYBDINPUT *ki, BOOL Injected);
BOOL UserInitDefaultKeyboardLayout(VOID); PKBL UserHklToKbl(HKL hKl);
Modified: trunk/reactos/subsystems/win32/win32k/include/msgqueue.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/include/msgqueue.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/include/msgqueue.h [iso-8859-1] Fri Apr 8 19:29:15 2011 @@ -242,7 +242,7 @@ VOID FASTCALL MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam); VOID FASTCALL -co_MsqInsertMouseMessage(MSG* Msg); +co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo); BOOL FASTCALL MsqIsClkLck(LPMSG Msg, BOOL Remove); BOOL FASTCALL
Modified: trunk/reactos/subsystems/win32/win32k/include/timer.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/include/timer.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/include/timer.h [iso-8859-1] Fri Apr 8 19:29:15 2011 @@ -24,6 +24,12 @@ #define TMRF_WAITING 0x0020 #define TMRF_TIFROMWND 0x0040
+#define ID_EVENT_SYSTIMER_MOUSEHOVER (-6) +#define ID_EVENT_SYSTIMER_FLASHWIN (-8) +#define ID_EVENT_SYSTIMER_TRACKWIN (-9) +#define ID_EVENT_SYSTIMER_ANIMATEDFADE (-10) +#define ID_EVENT_SYSTIMER_INVALIDATEDCES (-11) + extern PKTIMER MasterTimer;
INIT_FUNCTION
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/accelerator.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/accelerator.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/accelerator.c [iso-8859-1] Fri Apr 8 19:29:15 2011 @@ -1,27 +1,8 @@ /* - * ReactOS W32 Subsystem - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -/* $Id$ - * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * PURPOSE: Window classes - * FILE: subsys/win32k/ntuser/class.c + * PURPOSE: Window accelerator + * FILE: subsystems/win32/win32k/ntuser/accelerator.c * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net) * REVISION HISTORY: * 06-06-2001 CSH Created @@ -105,9 +86,13 @@ WORD key, WORD cmd) { + INT mask = 0; UINT mesg = 0; + HWND hWnd;
ASSERT_REFS_CO(Window); + + hWnd = Window->head.h;
DPRINT("IntTranslateAccelerator(hwnd %x, message %x, wParam %x, lParam %x, fVirt %d, key %x, cmd %x)\n", Window->head.h, message, wParam, lParam, fVirt, key, cmd); @@ -117,37 +102,33 @@ return FALSE; }
- if (message == WM_CHAR) - { - if (!(fVirt & FALT) && !(fVirt & FVIRTKEY)) - { - DPRINT("found accel for WM_CHAR: ('%c')\n", wParam & 0xff); + DPRINT("NtUserGetKeyState(VK_SHIFT) = 0x%x\n", + UserGetKeyState(VK_SHIFT)); + DPRINT("NtUserGetKeyState(VK_CONTROL) = 0x%x\n", + UserGetKeyState(VK_CONTROL)); + DPRINT("NtUserGetKeyState(VK_MENU) = 0x%x\n", + UserGetKeyState(VK_MENU)); + + if (UserGetKeyState(VK_CONTROL) & 0x8000) mask |= FCONTROL; + if (UserGetKeyState(VK_MENU) & 0x8000) mask |= FALT; + if (UserGetKeyState(VK_SHIFT) & 0x8000) mask |= FSHIFT; + + if (message == WM_CHAR || message == WM_SYSCHAR) + { + if ( !(fVirt & FVIRTKEY) && (mask & FALT) == (fVirt & FALT) ) + { + DPRINT("found accel for WM_CHAR: ('%c')\n", LOWORD(wParam) & 0xff); goto found; } } else { - if ((fVirt & FVIRTKEY) > 0) - { - INT mask = 0; + if (fVirt & FVIRTKEY) + { DPRINT("found accel for virt_key %04x (scan %04x)\n", - wParam, 0xff & HIWORD(lParam)); - - DPRINT("NtUserGetKeyState(VK_SHIFT) = 0x%x\n", - UserGetKeyState(VK_SHIFT)); - DPRINT("NtUserGetKeyState(VK_CONTROL) = 0x%x\n", - UserGetKeyState(VK_CONTROL)); - DPRINT("NtUserGetKeyState(VK_MENU) = 0x%x\n", - UserGetKeyState(VK_MENU)); - - if (UserGetKeyState(VK_SHIFT) & 0x8000) - mask |= FSHIFT; - if (UserGetKeyState(VK_CONTROL) & 0x8000) - mask |= FCONTROL; - if (UserGetKeyState(VK_MENU) & 0x8000) - mask |= FALT; - if (mask == (fVirt & (FSHIFT | FCONTROL | FALT))) - goto found; + wParam, 0xff & HIWORD(lParam)); + + if (mask == (fVirt & (FSHIFT | FCONTROL | FALT))) goto found; DPRINT("but incorrect SHIFT/CTRL/ALT-state\n"); } else @@ -156,7 +137,7 @@ { if ((fVirt & FALT) && (lParam & 0x20000000)) { /* ^^ ALT pressed */ - DPRINT("found accel for Alt-%c\n", wParam & 0xff); + DPRINT("found accel for Alt-%c\n", LOWORD(wParam) & 0xff); goto found; } } @@ -173,80 +154,120 @@ mesg = 1; else if (IntGetCaptureWindow()) mesg = 2; - else if (!IntIsWindowVisible(Window)) /* FIXME: WINE IsWindowEnabled == IntIsWindowVisible? */ + else if (Window->style & WS_DISABLED) mesg = 3; else { #if 0 HMENU hMenu, hSubMenu, hSysMenu; UINT uSysStat = (UINT)-1, uStat = (UINT)-1, nPos; - - hMenu = (UserGetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD) ? 0 : GetMenu(hWnd); - hSysMenu = get_win_sys_menu(hWnd); + PMENU_OBJECT MenuObject, SubMenu; + MENU_ITEM MenuItem; + +// hMenu = (UserGetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD) ? 0 : GetMenu(hWnd); +// hSysMenu = get_win_sys_menu(hWnd); + hMenu = (Window->style & WS_CHILD) ? 0 : (HMENU)Window->IDMenu; + hSysMenu = Window->SystemMenu; + MenuObject = IntGetMenuObject(Window->SystemMenu);
/* find menu item and ask application to initialize it */ /* 1. in the system menu */ hSubMenu = hSysMenu; - nPos = cmd; - if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND)) - { - co_IntSendMessage(hWnd, WM_INITMENU, (WPARAM)hSysMenu, 0L); - if(hSubMenu != hSysMenu) +// nPos = cmd; +// if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND)) + nPos = IntGetMenuItemByFlag( MenuObject, + cmd, + MF_BYCOMMAND, + &SubMenu, + &MenuItem, + NULL); + + if (MenuItem && (nPos != (UINT)-1)) + { + hSubMenu = MenuItem.hSubMenu; + + if (IntGetCaptureWindow()) + mesg = 2; + if (Window->style & WS_DISABLED) + mesg = 3; + else + { + co_IntSendMessage(hWnd, WM_INITMENU, (WPARAM)hSysMenu, 0L); + if(hSubMenu != hSysMenu) + { + nPos = MENU_FindSubMenu(&hSysMenu, hSubMenu); + DPRINT("hSysMenu = %p, hSubMenu = %p, nPos = %d\n", hSysMenu, hSubMenu, nPos); + co_IntSendMessage(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, TRUE)); + } + uSysStat = GetMenuState(GetSubMenu(hSysMenu, 0), cmd, MF_BYCOMMAND); + } + } + else /* 2. in the window's menu */ + { + MenuObject = IntGetMenuObject(hMenu); + hSubMenu = hMenu; +// nPos = cmd; +// if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND)) + nPos = IntGetMenuItemByFlag( MenuObject, + cmd, + MF_BYCOMMAND, + &SubMenu, + &MenuItem, + NULL); + + if (MenuItem && (nPos != (UINT)-1)) { - nPos = MENU_FindSubMenu(&hSysMenu, hSubMenu); - TRACE_(accel)("hSysMenu = %p, hSubMenu = %p, nPos = %d\n", hSysMenu, hSubMenu, nPos); - co_IntSendMessage(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, TRUE)); - } - uSysStat = GetMenuState(GetSubMenu(hSysMenu, 0), cmd, MF_BYCOMMAND); - } - else /* 2. in the window's menu */ - { - hSubMenu = hMenu; - nPos = cmd; - if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND)) - { - co_IntSendMessage(hWnd, WM_INITMENU, (WPARAM)hMenu, 0L); - if(hSubMenu != hMenu) - { - nPos = MENU_FindSubMenu(&hMenu, hSubMenu); - TRACE_(accel)("hMenu = %p, hSubMenu = %p, nPos = %d\n", hMenu, hSubMenu, nPos); - co_IntSendMessage(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, FALSE)); - } - uStat = GetMenuState(hMenu, cmd, MF_BYCOMMAND); - } - } - - if (uSysStat != (UINT)-1) - { - if (uSysStat & (MF_DISABLED|MF_GRAYED)) - mesg=4; - else - mesg=WM_SYSCOMMAND; - } - else - { - if (uStat != (UINT)-1) - { - if (IsIconic(hWnd)) - mesg=5; + if (IntGetCaptureWindow()) + mesg = 2; + if (Window->style & WS_DISABLED) + mesg = 3; else { - if (uStat & (MF_DISABLED|MF_GRAYED)) - mesg=6; - else - mesg=WM_COMMAND; + co_IntSendMessage(hWnd, WM_INITMENU, (WPARAM)hMenu, 0L); + if(hSubMenu != hMenu) + { + nPos = MENU_FindSubMenu(&hMenu, hSubMenu); + DPRINT("hMenu = %p, hSubMenu = %p, nPos = %d\n", hMenu, hSubMenu, nPos); + co_IntSendMessage(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, FALSE)); + } + uStat = GetMenuState(hMenu, cmd, MF_BYCOMMAND); } + } + } + + if (mesg == 0) + { + if (uSysStat != (UINT)-1) + { + if (uSysStat & (MF_DISABLED|MF_GRAYED)) + mesg=4; + else + mesg=WM_SYSCOMMAND; } else { - mesg=WM_COMMAND; + if (uStat != (UINT)-1) + { + if (Window->style & WS_MINIMIZE) + mesg=5; + else + { + if (uStat & (MF_DISABLED|MF_GRAYED)) + mesg=6; + else + mesg=WM_COMMAND; + } + } + else + { + mesg=WM_COMMAND; + } } } #else DPRINT1("Menu search not implemented\n"); mesg = WM_COMMAND; #endif - }
if (mesg == WM_COMMAND)
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/callback.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/callback.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/callback.c [iso-8859-1] Fri Apr 8 19:29:15 2011 @@ -510,18 +510,25 @@
UserEnterCo();
- _SEH2_TRY - { - ProbeForRead(ResultPointer, sizeof(LRESULT), 1); - /* Simulate old behaviour: copy into our local buffer */ - Result = *(LRESULT*)ResultPointer; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Result = 0; - Hit = TRUE; - } - _SEH2_END; + if (ResultPointer) + { + _SEH2_TRY + { + ProbeForRead(ResultPointer, sizeof(LRESULT), 1); + /* Simulate old behaviour: copy into our local buffer */ + Result = *(LRESULT*)ResultPointer; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Result = 0; + Hit = TRUE; + } + _SEH2_END; + } + else + { + DPRINT1("ERROR: Hook ResultPointer 0x%x ResultLength %d\n",ResultPointer,ResultLength); + }
if (!NT_SUCCESS(Status)) {
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c [iso-8859-1] Fri Apr 8 19:29:15 2011 @@ -159,7 +159,7 @@ return OldCursor; }
-BOOL UserSetCursorPos( INT x, INT y, BOOL SendMouseMoveMsg) +BOOL UserSetCursorPos( INT x, INT y) { PWND DesktopWindow; PSYSTEM_CURSORINFO CurInfo; @@ -194,21 +194,17 @@ pt.x = x; pt.y = y;
- - if (SendMouseMoveMsg) - { - /* Generate a mouse move message */ - Msg.message = WM_MOUSEMOVE; - Msg.wParam = CurInfo->ButtonsDown; - Msg.lParam = MAKELPARAM(x, y); - Msg.pt = pt; - co_MsqInsertMouseMessage(&Msg); - } - - /* Store the new cursor position */ + /* 3. Generate a mouse move message, this sets the htEx. */ + Msg.message = WM_MOUSEMOVE; + Msg.wParam = CurInfo->ButtonsDown; + Msg.lParam = MAKELPARAM(x, y); + Msg.pt = pt; + co_MsqInsertMouseMessage(&Msg, 0, 0); + + /* 1. Store the new cursor position */ gpsi->ptCursor = pt;
- /* Move the mouse pointer */ + /* 2. Move the mouse pointer */ GreMovePointer(hDC, x, y);
return TRUE; @@ -681,7 +677,7 @@ { CurInfo->bClipped = TRUE; RECTL_bIntersectRect(&CurInfo->rcClip, prcl, &DesktopWindow->rcWindow); - UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y, FALSE); + UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y); } else {
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/focus.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/focus.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/focus.c [iso-8859-1] Fri Apr 8 19:29:15 2011 @@ -595,7 +595,7 @@ mi.dwFlags = MOUSEEVENTF_MOVE; mi.time = 0; mi.dwExtraInfo = 0; - IntMouseInput(&mi); + IntMouseInput(&mi,FALSE); } return hWndPrev; }
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/hook.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/hook.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/hook.c [iso-8859-1] Fri Apr 8 19:29:15 2011 @@ -1003,6 +1003,10 @@
ClientInfo = pti->pClientInfo; SaveHook = pti->sphkCurrent; + /* Note: Setting pti->sphkCurrent will also lock the next hook to this + * hook ID. So, the CallNextHookEx will only call to that hook ID + * chain anyway. For Thread Hooks.... + */
/* Load it for the next call. */ pti->sphkCurrent = Hook; @@ -1042,7 +1046,7 @@ ObDereferenceObject(Hook->Thread); }
- if ( Global ) + if ( Global && !pti->sphkCurrent) { PTHREADINFO ptiHook;
@@ -1057,6 +1061,7 @@ * hook ID, this will have to post to each of the thread message queues * or make a direct call. */ + pti->sphkCurrent = Hook; // Prevent recursion within this thread. do { /* Hook->Thread is null, we hax around this with Hook->head.pti. */ @@ -1104,6 +1109,7 @@ } while ( Hook ); DPRINT("Ret: Global HookId %d Result 0x%x\n", HookId,Result); + pti->sphkCurrent = NULL; } Exit: return Result;
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/input.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/input.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/input.c [iso-8859-1] Fri Apr 8 19:29:15 2011 @@ -53,7 +53,7 @@ if(mi.dx != 0 || mi.dy != 0) \ mi.dwFlags |= MOUSEEVENTF_MOVE; \ if(mi.dwFlags) \ - IntMouseInput(&mi); \ + IntMouseInput(&mi,FALSE); \ ClearMouseInput(mi);
@@ -481,6 +481,7 @@ static VOID APIENTRY co_IntKeyboardSendAltKeyMsg() { + DPRINT1("co_IntKeyboardSendAltKeyMsg\n"); co_MsqPostKeyboardMessage(WM_SYSCOMMAND,SC_KEYMENU,0); }
@@ -1073,7 +1074,7 @@ }
BOOL FASTCALL -IntMouseInput(MOUSEINPUT *mi) +IntMouseInput(MOUSEINPUT *mi, BOOL Injected) { const UINT SwapBtnMsg[2][2] = { @@ -1137,7 +1138,7 @@
if(mi->dwFlags & MOUSEEVENTF_MOVE) { - UserSetCursorPos(MousePos.x, MousePos.y, TRUE); + UserSetCursorPos(MousePos.x, MousePos.y); } if(mi->dwFlags & MOUSEEVENTF_LEFTDOWN) { @@ -1145,7 +1146,7 @@ Msg.message = SwapBtnMsg[0][SwapButtons]; CurInfo->ButtonsDown |= SwapBtn[SwapButtons]; Msg.wParam |= CurInfo->ButtonsDown; - co_MsqInsertMouseMessage(&Msg); + co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo); } else if(mi->dwFlags & MOUSEEVENTF_LEFTUP) { @@ -1153,7 +1154,7 @@ Msg.message = SwapBtnMsg[1][SwapButtons]; CurInfo->ButtonsDown &= ~SwapBtn[SwapButtons]; Msg.wParam |= CurInfo->ButtonsDown; - co_MsqInsertMouseMessage(&Msg); + co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo); } if(mi->dwFlags & MOUSEEVENTF_MIDDLEDOWN) { @@ -1161,7 +1162,7 @@ Msg.message = WM_MBUTTONDOWN; CurInfo->ButtonsDown |= MK_MBUTTON; Msg.wParam |= CurInfo->ButtonsDown; - co_MsqInsertMouseMessage(&Msg); + co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo); } else if(mi->dwFlags & MOUSEEVENTF_MIDDLEUP) { @@ -1169,7 +1170,7 @@ Msg.message = WM_MBUTTONUP; CurInfo->ButtonsDown &= ~MK_MBUTTON; Msg.wParam |= CurInfo->ButtonsDown; - co_MsqInsertMouseMessage(&Msg); + co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo); } if(mi->dwFlags & MOUSEEVENTF_RIGHTDOWN) { @@ -1177,7 +1178,7 @@ Msg.message = SwapBtnMsg[0][!SwapButtons]; CurInfo->ButtonsDown |= SwapBtn[!SwapButtons]; Msg.wParam |= CurInfo->ButtonsDown; - co_MsqInsertMouseMessage(&Msg); + co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo); } else if(mi->dwFlags & MOUSEEVENTF_RIGHTUP) { @@ -1185,7 +1186,7 @@ Msg.message = SwapBtnMsg[1][!SwapButtons]; CurInfo->ButtonsDown &= ~SwapBtn[!SwapButtons]; Msg.wParam |= CurInfo->ButtonsDown; - co_MsqInsertMouseMessage(&Msg); + co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo); }
if((mi->dwFlags & (MOUSEEVENTF_XDOWN | MOUSEEVENTF_XUP)) && @@ -1203,14 +1204,14 @@ gQueueKeyStateTable[VK_XBUTTON1] |= 0xc0; CurInfo->ButtonsDown |= MK_XBUTTON1; Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1); - co_MsqInsertMouseMessage(&Msg); + co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo); } if(mi->mouseData & XBUTTON2) { gQueueKeyStateTable[VK_XBUTTON2] |= 0xc0; CurInfo->ButtonsDown |= MK_XBUTTON2; Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2); - co_MsqInsertMouseMessage(&Msg); + co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo); } } else if(mi->dwFlags & MOUSEEVENTF_XUP) @@ -1221,28 +1222,28 @@ gQueueKeyStateTable[VK_XBUTTON1] &= ~0x80; CurInfo->ButtonsDown &= ~MK_XBUTTON1; Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1); - co_MsqInsertMouseMessage(&Msg); + co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo); } if(mi->mouseData & XBUTTON2) { gQueueKeyStateTable[VK_XBUTTON2] &= ~0x80; CurInfo->ButtonsDown &= ~MK_XBUTTON2; Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2); - co_MsqInsertMouseMessage(&Msg); + co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo); } } if(mi->dwFlags & MOUSEEVENTF_WHEEL) { Msg.message = WM_MOUSEWHEEL; Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, mi->mouseData); - co_MsqInsertMouseMessage(&Msg); + co_MsqInsertMouseMessage(&Msg, Injected, mi->dwExtraInfo); }
return TRUE; }
BOOL FASTCALL -IntKeyboardInput(KEYBDINPUT *ki) +IntKeyboardInput(KEYBDINPUT *ki, BOOL Injected) { PUSER_MESSAGE_QUEUE FocusMessageQueue; MSG Msg; @@ -1346,6 +1347,7 @@ KbdHookData.vkCode = vk_hook; KbdHookData.scanCode = ki->wScan; KbdHookData.flags = flags >> 8; + if (Injected) KbdHookData.flags |= LLKHF_INJECTED; KbdHookData.time = Msg.time; KbdHookData.dwExtraInfo = ki->dwExtraInfo; if (co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, Msg.message, (LPARAM) &KbdHookData)) @@ -1510,13 +1512,13 @@ switch(SafeInput.type) { case INPUT_MOUSE: - if(IntMouseInput(&SafeInput.mi)) + if(IntMouseInput(&SafeInput.mi, TRUE)) { cnt++; } break; case INPUT_KEYBOARD: - if(IntKeyboardInput(&SafeInput.ki)) + if(IntKeyboardInput(&SafeInput.ki, TRUE)) { cnt++; } @@ -1541,4 +1543,280 @@ END_CLEANUP; }
+BOOL +FASTCALL +IntQueryTrackMouseEvent( + LPTRACKMOUSEEVENT lpEventTrack) +{ + PDESKTOP pDesk; + PTHREADINFO pti; + + pti = PsGetCurrentThreadWin32Thread(); + pDesk = pti->rpdesk; + + /* Always cleared with size set and return true. */ + RtlZeroMemory(lpEventTrack ,sizeof(TRACKMOUSEEVENT)); + lpEventTrack->cbSize = sizeof(TRACKMOUSEEVENT); + + if ( pDesk->dwDTFlags & (DF_TME_LEAVE|DF_TME_HOVER) && + pDesk->spwndTrack && + pti->MessageQueue == pDesk->spwndTrack->head.pti->MessageQueue ) + { + if ( pDesk->htEx != HTCLIENT ) + lpEventTrack->dwFlags |= TME_NONCLIENT; + + if ( pDesk->dwDTFlags & DF_TME_LEAVE ) + lpEventTrack->dwFlags |= TME_LEAVE; + + if ( pDesk->dwDTFlags & DF_TME_HOVER ) + { + lpEventTrack->dwFlags |= TME_HOVER; + lpEventTrack->dwHoverTime = pDesk->dwMouseHoverTime; + } + lpEventTrack->hwndTrack = UserHMGetHandle(pDesk->spwndTrack); + } + return TRUE; +} + +BOOL +FASTCALL +IntTrackMouseEvent( + LPTRACKMOUSEEVENT lpEventTrack) +{ + PDESKTOP pDesk; + PTHREADINFO pti; + PWND pWnd; + POINT point; + + pti = PsGetCurrentThreadWin32Thread(); + pDesk = pti->rpdesk; + + if (!(pWnd = UserGetWindowObject(lpEventTrack->hwndTrack))) + return FALSE; + + if ( pDesk->spwndTrack != pWnd || + (pDesk->htEx != HTCLIENT) ^ !!(lpEventTrack->dwFlags & TME_NONCLIENT) ) + { + if ( lpEventTrack->dwFlags & TME_LEAVE && !(lpEventTrack->dwFlags & TME_CANCEL) ) + { + UserPostMessage( lpEventTrack->hwndTrack, + lpEventTrack->dwFlags & TME_NONCLIENT ? WM_NCMOUSELEAVE : WM_MOUSELEAVE, + 0, 0); + } + DPRINT("IntTrackMouseEvent spwndTrack 0x%x pwnd 0x%x\n", pDesk->spwndTrack,pWnd); + return TRUE; + } + + /* Tracking spwndTrack same as pWnd */ + if ( lpEventTrack->dwFlags & TME_CANCEL ) // Canceled mode. + { + if ( lpEventTrack->dwFlags & TME_LEAVE ) + pDesk->dwDTFlags &= ~DF_TME_LEAVE; + + if ( lpEventTrack->dwFlags & TME_HOVER ) + { + if ( pDesk->dwDTFlags & DF_TME_HOVER ) + { // Kill hover timer. + IntKillTimer(pWnd, ID_EVENT_SYSTIMER_MOUSEHOVER, TRUE); + pDesk->dwDTFlags &= ~DF_TME_HOVER; + } + } + } + else // Not Canceled. + { + if ( lpEventTrack->dwFlags & TME_LEAVE ) + pDesk->dwDTFlags |= DF_TME_LEAVE; + + if ( lpEventTrack->dwFlags & TME_HOVER ) + { + pDesk->dwDTFlags |= DF_TME_HOVER; + + if ( !lpEventTrack->dwHoverTime || lpEventTrack->dwHoverTime == HOVER_DEFAULT ) + pDesk->dwMouseHoverTime = gspv.iMouseHoverTime; // use the system default hover time-out. + else + pDesk->dwMouseHoverTime = lpEventTrack->dwHoverTime; + // Start timer for the hover period. + IntSetTimer( pWnd, ID_EVENT_SYSTIMER_MOUSEHOVER, pDesk->dwMouseHoverTime, SystemTimerProc, TMRF_SYSTEM); + // Get windows thread message points. + point = pWnd->head.pti->ptLast; + // Set desktop mouse hover from the system default hover rectangle. + RECTL_vSetRect(&pDesk->rcMouseHover, + point.x - gspv.iMouseHoverWidth / 2, + point.y - gspv.iMouseHoverHeight / 2, + point.x + gspv.iMouseHoverWidth / 2, + point.y + gspv.iMouseHoverHeight / 2); + } + } + return TRUE; +} + +BOOL +APIENTRY +NtUserTrackMouseEvent( + LPTRACKMOUSEEVENT lpEventTrack) +{ + TRACKMOUSEEVENT saveTME; + BOOL Ret = FALSE; + + DPRINT("Enter NtUserTrackMouseEvent\n"); + UserEnterExclusive(); + + _SEH2_TRY + { + ProbeForRead(lpEventTrack, sizeof(TRACKMOUSEEVENT), 1); + RtlCopyMemory(&saveTME, lpEventTrack, sizeof(TRACKMOUSEEVENT)); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + SetLastNtError(_SEH2_GetExceptionCode()); + _SEH2_YIELD(goto Exit;) + } + _SEH2_END; + + if ( saveTME.cbSize != sizeof(TRACKMOUSEEVENT) ) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + goto Exit; + } + + if (saveTME.dwFlags & ~(TME_CANCEL|TME_QUERY|TME_NONCLIENT|TME_LEAVE|TME_HOVER) ) + { + EngSetLastError(ERROR_INVALID_FLAGS); + goto Exit; + } + + if ( saveTME.dwFlags & TME_QUERY ) + { + Ret = IntQueryTrackMouseEvent(&saveTME); + _SEH2_TRY + { + ProbeForWrite(lpEventTrack, sizeof(TRACKMOUSEEVENT), 1); + RtlCopyMemory(lpEventTrack, &saveTME, sizeof(TRACKMOUSEEVENT)); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + SetLastNtError(_SEH2_GetExceptionCode()); + Ret = FALSE; + } + _SEH2_END; + } + else + { + Ret = IntTrackMouseEvent(&saveTME); + } + +Exit: + DPRINT("Leave NtUserTrackMouseEvent, ret=%i\n",Ret); + UserLeave(); + return Ret; +} + +extern MOUSEMOVEPOINT MouseHistoryOfMoves[]; +extern INT gcur_count; + +DWORD +APIENTRY +NtUserGetMouseMovePointsEx( + UINT cbSize, + LPMOUSEMOVEPOINT lpptIn, + LPMOUSEMOVEPOINT lpptOut, + int nBufPoints, + DWORD resolution) +{ + MOUSEMOVEPOINT Safeppt; + BOOL Hit; + INT Count = -1; + DECLARE_RETURN(DWORD); + + DPRINT("Enter NtUserGetMouseMovePointsEx\n"); + UserEnterExclusive(); + + if ((cbSize != sizeof(MOUSEMOVEPOINT)) || (nBufPoints < 0) || (nBufPoints > 64)) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + RETURN( -1); + } + + if (!lpptIn || (!lpptOut && nBufPoints)) + { + EngSetLastError(ERROR_NOACCESS); + RETURN( -1); + } + + _SEH2_TRY + { + ProbeForRead( lpptIn, cbSize, 1); + RtlCopyMemory(&Safeppt, lpptIn, cbSize); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + SetLastNtError(_SEH2_GetExceptionCode()); + _SEH2_YIELD(RETURN( -1)) + } + _SEH2_END; + + // http://msdn.microsoft.com/en-us/library/ms646259(v=vs.85).aspx + // This explains the math issues in transforming points. + Count = gcur_count; // FIFO is forward so retrieve backward. + Hit = FALSE; + do + { + if (Safeppt.x == 0 && Safeppt.y == 0) + break; // No test. + // Finds the point, it returns the last nBufPoints prior to and including the supplied point. + if (MouseHistoryOfMoves[Count].x == Safeppt.x && MouseHistoryOfMoves[Count].y == Safeppt.y) + { + if ( Safeppt.time ) // Now test time and it seems to be absolute. + { + if (Safeppt.time == MouseHistoryOfMoves[Count].time) + { + Hit = TRUE; + break; + } + else + { + if (--Count < 0) Count = 63; + continue; + } + } + Hit = TRUE; + break; + } + if (--Count < 0) Count = 63; + } + while ( Count != gcur_count); + + switch(resolution) + { + case GMMP_USE_DISPLAY_POINTS: + if (nBufPoints) + { + _SEH2_TRY + { + ProbeForWrite(lpptOut, cbSize, 1); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + SetLastNtError(_SEH2_GetExceptionCode()); + _SEH2_YIELD(RETURN( -1)) + } + _SEH2_END; + } + Count = nBufPoints; + break; + case GMMP_USE_HIGH_RESOLUTION_POINTS: + break; + default: + EngSetLastError(ERROR_POINT_NOT_FOUND); + RETURN( -1); + } + + RETURN( Count); + +CLEANUP: + DPRINT("Leave NtUserGetMouseMovePointsEx, ret=%i\n",_ret_); + UserLeave(); + END_CLEANUP; +} + /* EOF */
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c [iso-8859-1] Fri Apr 8 19:29:15 2011 @@ -400,7 +400,30 @@ return ret; }
- +/*********************************************************************** + * get_key_state + */ +WORD FASTCALL get_key_state(void) +{ + WORD ret = 0; + + if (gpsi->aiSysMet[SM_SWAPBUTTON]) + { + if (UserGetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_LBUTTON; + if (UserGetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_RBUTTON; + } + else + { + if (UserGetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_LBUTTON; + if (UserGetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_RBUTTON; + } + if (UserGetAsyncKeyState(VK_MBUTTON) & 0x80) ret |= MK_MBUTTON; + if (UserGetAsyncKeyState(VK_SHIFT) & 0x80) ret |= MK_SHIFT; + if (UserGetAsyncKeyState(VK_CONTROL) & 0x80) ret |= MK_CONTROL; + if (UserGetAsyncKeyState(VK_XBUTTON1) & 0x80) ret |= MK_XBUTTON1; + if (UserGetAsyncKeyState(VK_XBUTTON2) & 0x80) ret |= MK_XBUTTON2; + return ret; +}
SHORT APIENTRY
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/menu.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/menu.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/menu.c [iso-8859-1] Fri Apr 8 19:29:15 2011 @@ -709,14 +709,14 @@ { return FALSE; } - if( lpmii->fType & ~fTypeMask) + if (lpmii->fType & ~fTypeMask) { DbgPrint("IntSetMenuItemInfo invalid fType flags %x\n", lpmii->fType & ~fTypeMask); lpmii->fMask &= ~(MIIM_TYPE | MIIM_FTYPE); } - if(lpmii->fMask & MIIM_TYPE) - { - if(lpmii->fMask & ( MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP)) + if (lpmii->fMask & MIIM_TYPE) + { + if (lpmii->fMask & ( MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP)) { DbgPrint("IntSetMenuItemInfo: Invalid combination of fMask bits used\n"); /* this does not happen on Win9x/ME */ @@ -2056,11 +2056,13 @@
if(!(Window = UserGetWindowObject(hWnd))) { + EngSetLastError(ERROR_INVALID_WINDOW_HANDLE); RETURN(FALSE); }
if(!(Menu = UserGetMenuObject(hMenu))) { + EngSetLastError(ERROR_INVALID_MENU_HANDLE); RETURN(FALSE); }
@@ -2228,6 +2230,9 @@ NULL, &MenuItem, NULL) < 0) { EngSetLastError(ERROR_INVALID_PARAMETER); +// This will crash menu (line 80) correct_behavior test! +// "NT4 and below can't handle a bigger MENUITEMINFO struct" + //EngSetLastError(ERROR_MENU_ITEM_NOT_FOUND); return( FALSE); }
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c [iso-8859-1] Fri Apr 8 19:29:15 2011 @@ -20,6 +20,8 @@ /* GLOBALS *******************************************************************/
static PAGED_LOOKASIDE_LIST MessageLookasideList; +MOUSEMOVEPOINT MouseHistoryOfMoves[64]; +INT gcur_count = 0;
/* FUNCTIONS *****************************************************************/
@@ -189,7 +191,7 @@ }
VOID FASTCALL -co_MsqInsertMouseMessage(MSG* Msg) +co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo) { LARGE_INTEGER LargeTickCount; MSLLHOOKSTRUCT MouseHookData; @@ -219,9 +221,9 @@ break; }
- MouseHookData.flags = 0; + MouseHookData.flags = flags; // LLMHF_INJECTED MouseHookData.time = Msg->time; - MouseHookData.dwExtraInfo = 0; + MouseHookData.dwExtraInfo = dwExtraInfo;
/* If the hook procedure returned non zero, dont send the message */ if (co_HOOK_CallHooks(WH_MOUSE_LL, HC_ACTION, Msg->message, (LPARAM) &MouseHookData)) @@ -232,11 +234,22 @@ if(!pwndDesktop) return;
+ /* Set hit somewhere on the desktop */ + pDesk = pwndDesktop->head.rpdesk; + pDesk->htEx = HTNOWHERE; + pDesk->spwndTrack = pwndDesktop; + /* Check if the mouse is captured */ Msg->hwnd = IntGetCaptureWindow(); if(Msg->hwnd != NULL) { pwnd = UserGetWindowObject(Msg->hwnd); + if ((pwnd->style & WS_VISIBLE) && + IntPtInWindow(pwnd, Msg->pt.x, Msg->pt.y)) + { + pDesk->htEx = HTCLIENT; + pDesk->spwndTrack = pwnd; + } } else { @@ -255,7 +268,6 @@ IntPtInWindow(pwnd, Msg->pt.x, Msg->pt.y)) { Msg->hwnd = pwnd->head.h; - pDesk = pwnd->head.rpdesk; pDesk->htEx = HTCLIENT; pDesk->spwndTrack = pwnd; break; @@ -277,6 +289,13 @@ MsqPostMessage(pwnd->head.pti->MessageQueue, Msg, TRUE, QS_MOUSEBUTTON); } } + + /* Do GetMouseMovePointsEx FIFO. */ + MouseHistoryOfMoves[gcur_count].x = Msg->pt.x; + MouseHistoryOfMoves[gcur_count].y = Msg->pt.y; + MouseHistoryOfMoves[gcur_count].time = Msg->time; + MouseHistoryOfMoves[gcur_count].dwExtraInfo = 0; // need to be passed from IntMouseInput mi.dwExtraInfo. + if (gcur_count++ == 64) gcur_count = 0; // 0 - 63 is 64, FIFO forwards. }
// @@ -1276,7 +1295,7 @@ if (Remove) { RemoveEntryList(&CurrentMessage->ListEntry); - ClearMsgBitsMask(MessageQueue, CurrentMessage->QS_Flags); + ClearMsgBitsMask(MessageQueue, QS_INPUT); MsqDestroyMessage(CurrentMessage); }
@@ -1336,7 +1355,7 @@ if (Remove) { RemoveEntryList(&CurrentMessage->ListEntry); - ClearMsgBitsMask(MessageQueue, CurrentMessage->QS_Flags); + ClearMsgBitsMask(MessageQueue, QS_POSTMESSAGE); MsqDestroyMessage(CurrentMessage); } return(TRUE);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c [iso-8859-1] Fri Apr 8 19:29:15 2011 @@ -277,56 +277,6 @@ return 0; }
- -DWORD -APIENTRY -NtUserGetMouseMovePointsEx( - UINT cbSize, - LPMOUSEMOVEPOINT lppt, - LPMOUSEMOVEPOINT lpptBuf, - int nBufPoints, - DWORD resolution) -{ - UserEnterExclusive(); - - if ((cbSize != sizeof(MOUSEMOVEPOINT)) || (nBufPoints < 0) || (nBufPoints > 64)) - { - UserLeave(); - EngSetLastError(ERROR_INVALID_PARAMETER); - return -1; - } - - _SEH2_TRY - { - ProbeForRead(lppt, cbSize, 1); - ProbeForWrite(lpptBuf, cbSize, 1); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - SetLastNtError(_SEH2_GetExceptionCode()); - EngSetLastError(ERROR_NOACCESS); - } - _SEH2_END; - -/* - Call a subfunction of GetMouseMovePointsEx! - switch(resolution) - { - case GMMP_USE_DISPLAY_POINTS: - case GMMP_USE_HIGH_RESOLUTION_POINTS: - break; - default: - EngSetLastError(GMMP_ERR_POINT_NOT_FOUND); - return GMMP_ERR_POINT_NOT_FOUND; - } - */ - UNIMPLEMENTED - UserLeave(); - return -1; -} - - - BOOL APIENTRY NtUserImpersonateDdeClientWindow( @@ -585,17 +535,6 @@
return 0; } - -BOOL -APIENTRY -NtUserTrackMouseEvent( - LPTRACKMOUSEEVENT lpEventTrack) -{ - UNIMPLEMENTED - - return 0; -} -
DWORD APIENTRY
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c [iso-8859-1] Fri Apr 8 19:29:15 2011 @@ -473,7 +473,7 @@ RETURN( (DWORD_PTR)co_IntRegisterLogonProcess((HANDLE)Param1, (BOOL)Param2));
case TWOPARAM_ROUTINE_SETCURSORPOS: - RETURN( (DWORD_PTR)UserSetCursorPos((int)Param1, (int)Param2, FALSE)); + RETURN( (DWORD_PTR)UserSetCursorPos((int)Param1, (int)Param2));
case TWOPARAM_ROUTINE_UNHOOKWINDOWSHOOK: RETURN( IntUnhookWindowsHook((int)Param1, (HOOKPROC)Param2));
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/timer.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/timer.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/timer.c [iso-8859-1] Fri Apr 8 19:29:15 2011 @@ -17,6 +17,8 @@ #define NDEBUG #include <debug.h>
+WORD FASTCALL get_key_state(void); + /* GLOBALS *******************************************************************/
static LIST_ENTRY TimersListHead; @@ -82,7 +84,7 @@ { /* Set the flag, it will be removed when ready */ RemoveEntryList(&pTmr->ptmrList); - if ((pTmr->pWnd == NULL) && (!(pTmr->flags & TMRF_SYSTEM))) + if ((pTmr->pWnd == NULL) && (!(pTmr->flags & TMRF_SYSTEM))) // System timers are reusable. { UINT_PTR IDEvent;
@@ -287,7 +289,73 @@ UINT_PTR idEvent, DWORD dwTime) { - DPRINT( "Timer Running!\n" ); + PDESKTOP pDesk; + PWND pWnd = NULL; + + if (hwnd) + { + pWnd = UserGetWindowObject(hwnd); + if (!pWnd) + { + DPRINT1( "System Timer Proc has invalid window handle! 0x%x Id: %d\n", hwnd, idEvent); + return; + } + } + else + { + DPRINT( "Windowless Timer Running!\n" ); + return; + } + + switch (idEvent) + { +/* + Used in NtUserTrackMouseEvent. + */ + case ID_EVENT_SYSTIMER_MOUSEHOVER: + { + POINT Point; + UINT Msg; + WPARAM wParam; + + pDesk = pWnd->head.rpdesk; + if ( pDesk->dwDTFlags & DF_TME_HOVER && + pWnd == pDesk->spwndTrack ) + { + Point = gpsi->ptCursor; + if ( IntPtInRect(&pDesk->rcMouseHover, Point) ) + { + if (pDesk->htEx == HTCLIENT) // In a client area. + { + wParam = get_key_state(); + Msg = WM_MOUSEHOVER; + + if (pWnd->ExStyle & WS_EX_LAYOUTRTL) + { + Point.x = pWnd->rcClient.right - Point.x - 1; + } + else + Point.x -= pWnd->rcClient.left; + Point.y -= pWnd->rcClient.top; + } + else + { + wParam = pDesk->htEx; // Need to support all HTXYZ hits. + Msg = WM_NCMOUSEHOVER; + } + UserPostMessage(hwnd, Msg, wParam, MAKELPARAM(Point.x, Point.y)); + pDesk->dwDTFlags &= ~DF_TME_HOVER; + break; // Kill this timer. + } + } + } + return; // Not this window so just return. + + default: + DPRINT1( "System Timer Proc invalid id %d!\n", idEvent ); + break; + } + IntKillTimer(pWnd, idEvent, TRUE); }
VOID @@ -296,7 +364,9 @@ { // Need to start gdi syncro timers then start timer with Hang App proc // that calles Idle process so the screen savers will know to run...... - IntSetTimer(NULL, 0, 1000, SystemTimerProc, TMRF_RIT); + IntSetTimer(NULL, 0, 1000, HungAppSysTimerProc, TMRF_RIT); +// Test Timers +// IntSetTimer(NULL, 0, 1000, SystemTimerProc, TMRF_RIT); }
UINT_PTR @@ -347,6 +417,13 @@ pTmr->flags &= ~TMRF_READY; pti->cTimersReady++; Hit = TRUE; + // Now move this entry to the end of the list so it will not be + // called again in the next msg loop. + if (pLE != &TimersListHead) + { + RemoveEntryList(&pTmr->ptmrList); + InsertTailList(&TimersListHead, &pTmr->ptmrList); + } break; }
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/window.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/window.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/window.c [iso-8859-1] Fri Apr 8 19:29:15 2011 @@ -1692,7 +1692,7 @@ DPRINT("Created object with handle %X\n", hWnd);
if (NULL == pti->rpdesk->DesktopWindow) - { + { /*HACK! Helper for win32csr/desktopbg.c */ /* If there is no desktop window yet, we must be creating it */ pti->rpdesk->DesktopWindow = hWnd; pti->rpdesk->pDeskInfo->spwnd = pWnd; @@ -1891,7 +1891,7 @@ return pWnd;
AllocError: - + DPRINT1("IntCreateWindow Allocation Error.\n"); if(pWnd) UserDereferenceObject(pWnd);
@@ -2575,7 +2575,7 @@ msg.wParam = IntGetSysCursorInfo()->ButtonsDown; msg.lParam = MAKELPARAM(gpsi->ptCursor.x, gpsi->ptCursor.y); msg.pt = gpsi->ptCursor; - co_MsqInsertMouseMessage(&msg); + co_MsqInsertMouseMessage(&msg, 0, 0);
if (!IntIsWindow(Window->head.h)) {