[ros-diffs] [fireball] 42273: 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

fireball at svn.reactos.org fireball at svn.reactos.org
Tue Jul 28 16:33:16 CEST 2009


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.drv/mouse.c?rev=42273&view=auto
==============================================================================
--- 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.drv/userdrv.c?rev=42273&r1=42272&r2=42273&view=diff
==============================================================================
--- 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.drv/winent.h?rev=42273&r1=42272&r2=42273&view=diff
==============================================================================
--- 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.drv/winent.rbuild?rev=42273&r1=42272&r2=42273&view=diff
==============================================================================
--- 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>
 




More information about the Ros-diffs mailing list