Author: fireball Date: Tue Jul 28 16:33:16 2009 New Revision: 42273
URL: http://svn.reactos.org/svn/reactos?rev=42273&view=rev Log: Giannis Adamopoulos - Add minimal mouse input support to the gdi/user driver: * Implement SendInput and SetCursor * Bring in some helper functions from winex11.drv driver
Added: branches/arwinss/reactos/dll/win32/winent.drv/mouse.c (with props) Modified: branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c branches/arwinss/reactos/dll/win32/winent.drv/winent.h branches/arwinss/reactos/dll/win32/winent.drv/winent.rbuild
Added: branches/arwinss/reactos/dll/win32/winent.drv/mouse.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent... ============================================================================== --- branches/arwinss/reactos/dll/win32/winent.drv/mouse.c (added) +++ branches/arwinss/reactos/dll/win32/winent.drv/mouse.c [iso-8859-1] Tue Jul 28 16:33:16 2009 @@ -1,0 +1,272 @@ +/* + * X11 mouse driver + * + * Copyright 1998 Ulrich Weigand + * Copyright 2007 Henri Verbeet + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stdarg.h> +#include <stdio.h> +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "wingdi.h" +#define NTOS_USER_MODE +#include <ndk/ntndk.h> +#include "ntrosgdi.h" +#include "win32k/rosuser.h" +#include "winent.h" +#include "wine/server.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(cursor); + +/**********************************************************************/ + +#define NB_BUTTONS 9 /* Windows can handle 5 buttons and the wheel too */ + +static const UINT button_down_flags[NB_BUTTONS] = +{ + MOUSEEVENTF_LEFTDOWN, + MOUSEEVENTF_MIDDLEDOWN, + MOUSEEVENTF_RIGHTDOWN, + MOUSEEVENTF_WHEEL, + MOUSEEVENTF_WHEEL, + MOUSEEVENTF_XDOWN, /* FIXME: horizontal wheel */ + MOUSEEVENTF_XDOWN, + MOUSEEVENTF_XDOWN, + MOUSEEVENTF_XDOWN +}; + +static const UINT button_up_flags[NB_BUTTONS] = +{ + MOUSEEVENTF_LEFTUP, + MOUSEEVENTF_MIDDLEUP, + MOUSEEVENTF_RIGHTUP, + 0, + 0, + MOUSEEVENTF_XUP, + MOUSEEVENTF_XUP, + MOUSEEVENTF_XUP, + MOUSEEVENTF_XUP +}; + +BYTE key_state_table[256]; + +/*********************************************************************** + * clip_point_to_rect + * + * Clip point to the provided rectangle + */ +static inline void clip_point_to_rect( LPCRECT rect, LPPOINT pt ) +{ + if (pt->x < rect->left) pt->x = rect->left; + else if (pt->x >= rect->right) pt->x = rect->right - 1; + if (pt->y < rect->top) pt->y = rect->top; + else if (pt->y >= rect->bottom) pt->y = rect->bottom - 1; +} + +/*********************************************************************** + * get_key_state + */ +static WORD get_key_state(void) +{ + WORD ret = 0; + + if (GetSystemMetrics( SM_SWAPBUTTON )) + { + if (key_state_table[VK_RBUTTON] & 0x80) ret |= MK_LBUTTON; + if (key_state_table[VK_LBUTTON] & 0x80) ret |= MK_RBUTTON; + } + else + { + if (key_state_table[VK_LBUTTON] & 0x80) ret |= MK_LBUTTON; + if (key_state_table[VK_RBUTTON] & 0x80) ret |= MK_RBUTTON; + } + if (key_state_table[VK_MBUTTON] & 0x80) ret |= MK_MBUTTON; + if (key_state_table[VK_SHIFT] & 0x80) ret |= MK_SHIFT; + if (key_state_table[VK_CONTROL] & 0x80) ret |= MK_CONTROL; + if (key_state_table[VK_XBUTTON1] & 0x80) ret |= MK_XBUTTON1; + if (key_state_table[VK_XBUTTON2] & 0x80) ret |= MK_XBUTTON2; + return ret; +} + + +/*********************************************************************** + * queue_raw_mouse_message + */ +static void queue_raw_mouse_message( UINT message, HWND hwnd, DWORD x, DWORD y, + DWORD data, DWORD time, DWORD extra_info, UINT injected_flags ) +{ + MSLLHOOKSTRUCT hook; + + hook.pt.x = x; + hook.pt.y = y; + hook.mouseData = MAKELONG( 0, data ); + hook.flags = injected_flags; + hook.time = time; + hook.dwExtraInfo = extra_info; + + if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, message, (LPARAM)&hook, TRUE )) return; + + SERVER_START_REQ( send_hardware_message ) + { + req->id = (injected_flags & LLMHF_INJECTED) ? 0 : GetCurrentThreadId(); + req->win = wine_server_user_handle( hwnd ); + req->msg = message; + req->wparam = MAKEWPARAM( get_key_state(), data ); + req->lparam = 0; + req->x = x; + req->y = y; + req->time = time; + req->info = extra_info; + wine_server_call( req ); + } + SERVER_END_REQ; + +} + + +/*********************************************************************** + * X11DRV_send_mouse_input + */ +void RosDrv_send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y, + DWORD data, DWORD time, DWORD extra_info, UINT injected_flags ) +{ + POINT pt; + POINT cursor_pos; + + if (flags & MOUSEEVENTF_MOVE && flags & MOUSEEVENTF_ABSOLUTE) + { + if (injected_flags & LLMHF_INJECTED) + { + pt.x = (x * GetSystemMetrics(SM_CXVIRTUALSCREEN)) >> 16; + pt.y = (y * GetSystemMetrics(SM_CYVIRTUALSCREEN)) >> 16; + } + else + { + pt.x = x; + pt.y = y; + + GetCursorPos(&cursor_pos); + if (cursor_pos.x == x && cursor_pos.y == y && + (flags & ~(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE))) + flags &= ~MOUSEEVENTF_MOVE; + + } + } + else if (flags & MOUSEEVENTF_MOVE) + { + int accel[3], xMult = 1, yMult = 1; + + /* dx and dy can be negative numbers for relative movements */ + SystemParametersInfoW(SPI_GETMOUSE, 0, accel, 0); + + if (abs(x) > accel[0] && accel[2] != 0) + { + xMult = 2; + if ((abs(x) > accel[1]) && (accel[2] == 2)) xMult = 4; + } + if (abs(y) > accel[0] && accel[2] != 0) + { + yMult = 2; + if ((abs(y) > accel[1]) && (accel[2] == 2)) yMult = 4; + } + + GetCursorPos(&cursor_pos); + pt.x = cursor_pos.x + (long)x * xMult; + pt.y = cursor_pos.y + (long)y * yMult; + } + else + { + GetCursorPos(&pt); + } + + if (flags & MOUSEEVENTF_MOVE) + { + queue_raw_mouse_message( WM_MOUSEMOVE, hwnd, pt.x, pt.y, data, time, + extra_info, injected_flags ); + RosDrv_SetCursorPos(pt.x, pt.y); + //if ((injected_flags & LLMHF_INJECTED) && + // ((flags & MOUSEEVENTF_ABSOLUTE) || x || y)) /* we have to actually move the cursor */ + //{ + // X11DRV_SetCursorPos( pt.x, pt.y ); + //} + //else + //{ + // wine_tsx11_lock(); + // clip_point_to_rect( &cursor_clip, &pt); + // cursor_pos = pt; + // wine_tsx11_unlock(); + //} + } + if (flags & MOUSEEVENTF_LEFTDOWN) + { + key_state_table[VK_LBUTTON] |= 0xc0; + queue_raw_mouse_message( GetSystemMetrics(SM_SWAPBUTTON) ? WM_RBUTTONDOWN : WM_LBUTTONDOWN, + hwnd, pt.x, pt.y, data, time, extra_info, injected_flags ); + } + if (flags & MOUSEEVENTF_LEFTUP) + { + key_state_table[VK_LBUTTON] &= ~0x80; + queue_raw_mouse_message( GetSystemMetrics(SM_SWAPBUTTON) ? WM_RBUTTONUP : WM_LBUTTONUP, + hwnd, pt.x, pt.y, data, time, extra_info, injected_flags ); + } + if (flags & MOUSEEVENTF_RIGHTDOWN) + { + key_state_table[VK_RBUTTON] |= 0xc0; + queue_raw_mouse_message( GetSystemMetrics(SM_SWAPBUTTON) ? WM_LBUTTONDOWN : WM_RBUTTONDOWN, + hwnd, pt.x, pt.y, data, time, extra_info, injected_flags ); + } + if (flags & MOUSEEVENTF_RIGHTUP) + { + key_state_table[VK_RBUTTON] &= ~0x80; + queue_raw_mouse_message( GetSystemMetrics(SM_SWAPBUTTON) ? WM_LBUTTONUP : WM_RBUTTONUP, + hwnd, pt.x, pt.y, data, time, extra_info, injected_flags ); + } + if (flags & MOUSEEVENTF_MIDDLEDOWN) + { + key_state_table[VK_MBUTTON] |= 0xc0; + queue_raw_mouse_message( WM_MBUTTONDOWN, hwnd, pt.x, pt.y, data, time, + extra_info, injected_flags ); + } + if (flags & MOUSEEVENTF_MIDDLEUP) + { + key_state_table[VK_MBUTTON] &= ~0x80; + queue_raw_mouse_message( WM_MBUTTONUP, hwnd, pt.x, pt.y, data, time, + extra_info, injected_flags ); + } + if (flags & MOUSEEVENTF_WHEEL) + { + queue_raw_mouse_message( WM_MOUSEWHEEL, hwnd, pt.x, pt.y, data, time, + extra_info, injected_flags ); + } + if (flags & MOUSEEVENTF_XDOWN) + { + key_state_table[VK_XBUTTON1 + data - 1] |= 0xc0; + queue_raw_mouse_message( WM_XBUTTONDOWN, hwnd, pt.x, pt.y, data, time, + extra_info, injected_flags ); + } + if (flags & MOUSEEVENTF_XUP) + { + key_state_table[VK_XBUTTON1 + data - 1] &= ~0x80; + queue_raw_mouse_message( WM_XBUTTONUP, hwnd, pt.x, pt.y, data, time, + extra_info, injected_flags ); + } +} +
Propchange: branches/arwinss/reactos/dll/win32/winent.drv/mouse.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent... ============================================================================== --- branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c [iso-8859-1] (original) +++ branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c [iso-8859-1] Tue Jul 28 16:33:16 2009 @@ -19,6 +19,7 @@ #define NTOS_USER_MODE #include <ndk/ntndk.h> #include "ntrosgdi.h" +#include "win32k/rosuser.h" #include "winent.h" #include "wine/server.h" #include "wine/debug.h" @@ -129,8 +130,26 @@
UINT CDECL RosDrv_SendInput( UINT count, LPINPUT inputs, int size ) { - UNIMPLEMENTED; - return 0; + UINT i; + + for (i = 0; i < count; i++, inputs++) + { + switch(inputs->type) + { + case INPUT_MOUSE: + RosDrv_send_mouse_input( 0, inputs->mi.dwFlags, inputs->mi.dx, inputs->mi.dy, + inputs->mi.mouseData, inputs->mi.time, + inputs->mi.dwExtraInfo, LLMHF_INJECTED ); + break; + case INPUT_KEYBOARD: + FIXME( "INPUT_KEYBOARD not supported\n" ); + break; + case INPUT_HARDWARE: + FIXME( "INPUT_HARDWARE not supported\n" ); + break; + } + } + return count; }
INT CDECL RosDrv_ToUnicodeEx( UINT virt, UINT scan, const BYTE *state, LPWSTR str, @@ -152,27 +171,45 @@ return -1; }
-void CDECL RosDrv_SetCursor( CURSORICONINFO *info ) -{ - UNIMPLEMENTED; +void CDECL RosDrv_SetCursor( HCURSOR hCursor ) +{ + ICONINFO IconInfo; + BITMAP bitmap; + + if (hCursor == NULL) + { + RosUserSetCursor(NULL); + } + else + { + if( GetIconInfo(hCursor, &IconInfo) ) + { + /* Create handle mappings for IconInfo.hbmMask and + IconInfo.hbmColor in kernel mode */ + if( GetObjectW(IconInfo.hbmMask, sizeof(bitmap), &bitmap)) + RosGdiCreateBitmap(NULL, IconInfo.hbmMask, &bitmap, bitmap.bmBits); + + if( GetObjectW(IconInfo.hbmColor, sizeof(bitmap), &bitmap)) + RosGdiCreateBitmap(NULL, IconInfo.hbmColor, &bitmap, bitmap.bmBits); + + RosUserSetCursor( &IconInfo ); + } + } }
BOOL CDECL RosDrv_GetCursorPos( LPPOINT pt ) { - UNIMPLEMENTED; - return FALSE; + return RosUserGetCursorPos( pt ); }
BOOL CDECL RosDrv_SetCursorPos( INT x, INT y ) { - UNIMPLEMENTED; - return FALSE; + return RosUserSetCursorPos( x, y ); }
BOOL CDECL RosDrv_ClipCursor( LPCRECT clip ) { - UNIMPLEMENTED; - return FALSE; + return RosUserClipCursor( clip ); }
BOOL CDECL RosDrv_GetScreenSaveActive(void)
Modified: branches/arwinss/reactos/dll/win32/winent.drv/winent.h URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent... ============================================================================== --- branches/arwinss/reactos/dll/win32/winent.drv/winent.h [iso-8859-1] (original) +++ branches/arwinss/reactos/dll/win32/winent.drv/winent.h [iso-8859-1] Tue Jul 28 16:33:16 2009 @@ -38,3 +38,11 @@ const RECT *lprect, LPCWSTR wstr, UINT count, const INT *lpDx );
+void RosDrv_send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y, + DWORD data, DWORD time, DWORD extra_info, UINT injected_flags ); + +BOOL CDECL RosDrv_SetCursorPos( INT x, INT y ); + +LRESULT HOOK_CallHooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL unicode ); + +BOOL CDECL RosDrv_GetCursorPos( LPPOINT pt );
Modified: branches/arwinss/reactos/dll/win32/winent.drv/winent.rbuild URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent... ============================================================================== --- branches/arwinss/reactos/dll/win32/winent.drv/winent.rbuild [iso-8859-1] (original) +++ branches/arwinss/reactos/dll/win32/winent.drv/winent.rbuild [iso-8859-1] Tue Jul 28 16:33:16 2009 @@ -9,6 +9,7 @@ <file>gdidrv.c</file> <file>main.c</file> <file>userdrv.c</file> + <file>mouse.c</file>
<file>winent.rc</file>