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/winen…
==============================================================================
--- 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/winen…
==============================================================================
--- 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/winen…
==============================================================================
--- 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/winen…
==============================================================================
--- 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>