ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

mouse.c
Go to the documentation of this file.
00001 /*      DirectInput Mouse device
00002  *
00003  * Copyright 1998 Marcus Meissner
00004  * Copyright 1998,1999 Lionel Ulmer
00005  * Copyright 2000-2001 TransGaming Technologies Inc.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00020  */
00021 
00022 #include "config.h"
00023 #include "wine/port.h"
00024 
00025 #include <stdarg.h>
00026 #include <string.h>
00027 
00028 #include "windef.h"
00029 #include "winbase.h"
00030 #include "wingdi.h"
00031 #include "winuser.h"
00032 #include "winerror.h"
00033 #include "winreg.h"
00034 #include "dinput.h"
00035 
00036 #include "dinput_private.h"
00037 #include "device_private.h"
00038 #include "wine/debug.h"
00039 #include "wine/unicode.h"
00040 
00041 WINE_DEFAULT_DEBUG_CHANNEL(dinput);
00042 
00043 /* Wine mouse driver object instances */
00044 #define WINE_MOUSE_X_AXIS_INSTANCE   0
00045 #define WINE_MOUSE_Y_AXIS_INSTANCE   1
00046 #define WINE_MOUSE_Z_AXIS_INSTANCE   2
00047 #define WINE_MOUSE_BUTTONS_INSTANCE  3
00048 
00049 static const IDirectInputDevice8AVtbl SysMouseAvt;
00050 static const IDirectInputDevice8WVtbl SysMouseWvt;
00051 
00052 typedef struct SysMouseImpl SysMouseImpl;
00053 
00054 typedef enum
00055 {
00056     WARP_DEFAULT,
00057     WARP_DISABLE,
00058     WARP_FORCE_ON
00059 } WARP_MOUSE;
00060 
00061 struct SysMouseImpl
00062 {
00063     struct IDirectInputDevice2AImpl base;
00064     
00065     /* SysMouseAImpl */
00066     /* These are used in case of relative -> absolute transitions */
00067     POINT                           org_coords;
00068     POINT                   mapped_center;
00069     DWORD               win_centerX, win_centerY;
00070     /* warping: whether we need to move mouse back to middle once we
00071      * reach window borders (for e.g. shooters, "surface movement" games) */
00072     BOOL                            need_warp;
00073     DWORD                           last_warped;
00074 
00075     /* This is for mouse reporting. */
00076     DIMOUSESTATE2                   m_state;
00077 
00078     WARP_MOUSE                      warp_override;
00079 };
00080 
00081 static void dinput_mouse_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam );
00082 
00083 const GUID DInput_Wine_Mouse_GUID = { /* 9e573ed8-7734-11d2-8d4a-23903fb6bdf7 */
00084     0x9e573ed8, 0x7734, 0x11d2, {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
00085 };
00086 
00087 static void _dump_mouse_state(DIMOUSESTATE2 *m_state)
00088 {
00089     int i;
00090 
00091     if (!TRACE_ON(dinput)) return;
00092 
00093     TRACE("(X: %d Y: %d Z: %d", m_state->lX, m_state->lY, m_state->lZ);
00094     for (i = 0; i < 5; i++) TRACE(" B%d: %02x", i, m_state->rgbButtons[i]);
00095     TRACE(")\n");
00096 }
00097 
00098 static void fill_mouse_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, DWORD version) {
00099     DWORD dwSize;
00100     DIDEVICEINSTANCEA ddi;
00101     
00102     dwSize = lpddi->dwSize;
00103 
00104     TRACE("%d %p\n", dwSize, lpddi);
00105     
00106     memset(lpddi, 0, dwSize);
00107     memset(&ddi, 0, sizeof(ddi));
00108 
00109     ddi.dwSize = dwSize;
00110     ddi.guidInstance = GUID_SysMouse;/* DInput's GUID */
00111     ddi.guidProduct = DInput_Wine_Mouse_GUID; /* Vendor's GUID */
00112     if (version >= 0x0800)
00113         ddi.dwDevType = DI8DEVTYPE_MOUSE | (DI8DEVTYPEMOUSE_TRADITIONAL << 8);
00114     else
00115         ddi.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_TRADITIONAL << 8);
00116     strcpy(ddi.tszInstanceName, "Mouse");
00117     strcpy(ddi.tszProductName, "Wine Mouse");
00118 
00119     memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi)));
00120 }
00121 
00122 static void fill_mouse_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD version) {
00123     DWORD dwSize;
00124     DIDEVICEINSTANCEW ddi;
00125     
00126     dwSize = lpddi->dwSize;
00127 
00128     TRACE("%d %p\n", dwSize, lpddi);
00129     
00130     memset(lpddi, 0, dwSize);
00131     memset(&ddi, 0, sizeof(ddi));
00132 
00133     ddi.dwSize = dwSize;
00134     ddi.guidInstance = GUID_SysMouse;/* DInput's GUID */
00135     ddi.guidProduct = DInput_Wine_Mouse_GUID; /* Vendor's GUID */
00136     if (version >= 0x0800)
00137         ddi.dwDevType = DI8DEVTYPE_MOUSE | (DI8DEVTYPEMOUSE_TRADITIONAL << 8);
00138     else
00139         ddi.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_TRADITIONAL << 8);
00140     MultiByteToWideChar(CP_ACP, 0, "Mouse", -1, ddi.tszInstanceName, MAX_PATH);
00141     MultiByteToWideChar(CP_ACP, 0, "Wine Mouse", -1, ddi.tszProductName, MAX_PATH);
00142 
00143     memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi)));
00144 }
00145 
00146 static BOOL mousedev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id)
00147 {
00148     if (id != 0)
00149         return FALSE;
00150 
00151     if ((dwDevType == 0) ||
00152     ((dwDevType == DIDEVTYPE_MOUSE) && (version < 0x0800)) ||
00153     (((dwDevType == DI8DEVCLASS_POINTER) || (dwDevType == DI8DEVTYPE_MOUSE)) && (version >= 0x0800))) {
00154     TRACE("Enumerating the mouse device\n");
00155     
00156     fill_mouse_dideviceinstanceA(lpddi, version);
00157     
00158     return TRUE;
00159     }
00160     
00161     return FALSE;
00162 }
00163 
00164 static BOOL mousedev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
00165 {
00166     if (id != 0)
00167         return FALSE;
00168 
00169     if ((dwDevType == 0) ||
00170     ((dwDevType == DIDEVTYPE_MOUSE) && (version < 0x0800)) ||
00171     (((dwDevType == DI8DEVCLASS_POINTER) || (dwDevType == DI8DEVTYPE_MOUSE)) && (version >= 0x0800))) {
00172     TRACE("Enumerating the mouse device\n");
00173     
00174     fill_mouse_dideviceinstanceW(lpddi, version);
00175     
00176     return TRUE;
00177     }
00178     
00179     return FALSE;
00180 }
00181 
00182 static SysMouseImpl *alloc_device(REFGUID rguid, const void *mvt, IDirectInputImpl *dinput)
00183 {
00184     SysMouseImpl* newDevice;
00185     LPDIDATAFORMAT df = NULL;
00186     unsigned i;
00187     char buffer[20];
00188     HKEY hkey, appkey;
00189 
00190     newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysMouseImpl));
00191     if (!newDevice) return NULL;
00192     newDevice->base.lpVtbl = mvt;
00193     newDevice->base.ref = 1;
00194     newDevice->base.dwCoopLevel = DISCL_NONEXCLUSIVE | DISCL_BACKGROUND;
00195     newDevice->base.guid = *rguid;
00196     InitializeCriticalSection(&newDevice->base.crit);
00197     newDevice->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SysMouseImpl*->base.crit");
00198     newDevice->base.dinput = dinput;
00199     newDevice->base.event_proc = dinput_mouse_hook;
00200 
00201     get_app_key(&hkey, &appkey);
00202     if (!get_config_key(hkey, appkey, "MouseWarpOverride", buffer, sizeof(buffer)))
00203     {
00204         if (!strcasecmp(buffer, "disable"))
00205             newDevice->warp_override = WARP_DISABLE;
00206         else if (!strcasecmp(buffer, "force"))
00207             newDevice->warp_override = WARP_FORCE_ON;
00208     }
00209     if (appkey) RegCloseKey(appkey);
00210     if (hkey) RegCloseKey(hkey);
00211 
00212     /* Create copy of default data format */
00213     if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIMouse2.dwSize))) goto failed;
00214     memcpy(df, &c_dfDIMouse2, c_dfDIMouse2.dwSize);
00215     if (!(df->rgodf = HeapAlloc(GetProcessHeap(), 0, df->dwNumObjs * df->dwObjSize))) goto failed;
00216     memcpy(df->rgodf, c_dfDIMouse2.rgodf, df->dwNumObjs * df->dwObjSize);
00217 
00218     /* Because we don't do any detection yet just modify instance and type */
00219     for (i = 0; i < df->dwNumObjs; i++)
00220         if (DIDFT_GETTYPE(df->rgodf[i].dwType) & DIDFT_AXIS)
00221             df->rgodf[i].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_RELAXIS;
00222         else
00223             df->rgodf[i].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_PSHBUTTON;
00224 
00225     newDevice->base.data_format.wine_df = df;
00226     IDirectInput_AddRef((LPDIRECTINPUTDEVICE8A)newDevice->base.dinput);
00227     return newDevice;
00228 
00229 failed:
00230     if (df) HeapFree(GetProcessHeap(), 0, df->rgodf);
00231     HeapFree(GetProcessHeap(), 0, df);
00232     HeapFree(GetProcessHeap(), 0, newDevice);
00233     return NULL;
00234 }
00235 
00236 static HRESULT mousedev_create_deviceA(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev)
00237 {
00238     if ((IsEqualGUID(&GUID_SysMouse,rguid)) ||             /* Generic Mouse */
00239     (IsEqualGUID(&DInput_Wine_Mouse_GUID,rguid))) { /* Wine Mouse */
00240     if ((riid == NULL) ||
00241         IsEqualGUID(&IID_IDirectInputDeviceA,riid) ||
00242         IsEqualGUID(&IID_IDirectInputDevice2A,riid) ||
00243         IsEqualGUID(&IID_IDirectInputDevice7A,riid) ||
00244         IsEqualGUID(&IID_IDirectInputDevice8A,riid)) {
00245         *pdev = (IDirectInputDeviceA*) alloc_device(rguid, &SysMouseAvt, dinput);
00246         TRACE("Creating a Mouse device (%p)\n", *pdev);
00247             if (!*pdev) return DIERR_OUTOFMEMORY;
00248         return DI_OK;
00249     } else
00250         return DIERR_NOINTERFACE;
00251     }
00252     
00253     return DIERR_DEVICENOTREG;
00254 }
00255 
00256 static HRESULT mousedev_create_deviceW(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev)
00257 {
00258     if ((IsEqualGUID(&GUID_SysMouse,rguid)) ||             /* Generic Mouse */
00259     (IsEqualGUID(&DInput_Wine_Mouse_GUID,rguid))) { /* Wine Mouse */
00260     if ((riid == NULL) ||
00261         IsEqualGUID(&IID_IDirectInputDeviceW,riid) ||
00262         IsEqualGUID(&IID_IDirectInputDevice2W,riid) ||
00263         IsEqualGUID(&IID_IDirectInputDevice7W,riid) ||
00264         IsEqualGUID(&IID_IDirectInputDevice8W,riid)) {
00265         *pdev = (IDirectInputDeviceW*) alloc_device(rguid, &SysMouseWvt, dinput);
00266         TRACE("Creating a Mouse device (%p)\n", *pdev);
00267             if (!*pdev) return DIERR_OUTOFMEMORY;
00268         return DI_OK;
00269     } else
00270         return DIERR_NOINTERFACE;
00271     }
00272     
00273     return DIERR_DEVICENOTREG;
00274 }
00275 
00276 const struct dinput_device mouse_device = {
00277     "Wine mouse driver",
00278     mousedev_enum_deviceA,
00279     mousedev_enum_deviceW,
00280     mousedev_create_deviceA,
00281     mousedev_create_deviceW
00282 };
00283 
00284 /******************************************************************************
00285  *  SysMouseA (DInput Mouse support)
00286  */
00287 
00288 /* low-level mouse hook */
00289 static void dinput_mouse_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam )
00290 {
00291     MSLLHOOKSTRUCT *hook = (MSLLHOOKSTRUCT *)lparam;
00292     SysMouseImpl* This = (SysMouseImpl*) iface;
00293     DWORD dwCoop;
00294     int wdata = 0, inst_id = -1;
00295 
00296     TRACE("msg %lx @ (%d %d)\n", wparam, hook->pt.x, hook->pt.y);
00297 
00298     EnterCriticalSection(&This->base.crit);
00299     dwCoop = This->base.dwCoopLevel;
00300 
00301     switch(wparam) {
00302         case WM_MOUSEMOVE:
00303         {
00304             POINT pt, pt1;
00305 
00306             GetCursorPos(&pt);
00307             This->m_state.lX += pt.x = hook->pt.x - pt.x;
00308             This->m_state.lY += pt.y = hook->pt.y - pt.y;
00309 
00310             if (This->base.data_format.user_df->dwFlags & DIDF_ABSAXIS)
00311             {
00312                 pt1.x = This->m_state.lX;
00313                 pt1.y = This->m_state.lY;
00314             } else
00315                 pt1 = pt;
00316 
00317             if (pt.x)
00318             {
00319                 inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS;
00320                 wdata = pt1.x;
00321             }
00322             if (pt.y)
00323             {
00324                 /* Already have X, need to queue it */
00325                 if (inst_id != -1)
00326                     queue_event((LPDIRECTINPUTDEVICE8A)This, id_to_offset(&This->base.data_format, inst_id),
00327                                 wdata, GetCurrentTime(), This->base.dinput->evsequence);
00328                 inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS;
00329                 wdata = pt1.y;
00330             }
00331 
00332             This->need_warp = This->warp_override != WARP_DISABLE &&
00333                               (pt.x || pt.y) &&
00334                               (dwCoop & DISCL_EXCLUSIVE || This->warp_override == WARP_FORCE_ON);
00335             break;
00336         }
00337         case WM_MOUSEWHEEL:
00338             inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_Z_AXIS_INSTANCE) | DIDFT_RELAXIS;
00339             This->m_state.lZ += wdata = (short)HIWORD(hook->mouseData);
00340             break;
00341         case WM_LBUTTONDOWN:
00342             inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 0) | DIDFT_PSHBUTTON;
00343             This->m_state.rgbButtons[0] = wdata = 0x80;
00344         break;
00345     case WM_LBUTTONUP:
00346             inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 0) | DIDFT_PSHBUTTON;
00347             This->m_state.rgbButtons[0] = wdata = 0x00;
00348         break;
00349     case WM_RBUTTONDOWN:
00350             inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 1) | DIDFT_PSHBUTTON;
00351             This->m_state.rgbButtons[1] = wdata = 0x80;
00352         break;
00353     case WM_RBUTTONUP:
00354             inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 1) | DIDFT_PSHBUTTON;
00355             This->m_state.rgbButtons[1] = wdata = 0x00;
00356         break;
00357     case WM_MBUTTONDOWN:
00358             inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2) | DIDFT_PSHBUTTON;
00359             This->m_state.rgbButtons[2] = wdata = 0x80;
00360         break;
00361     case WM_MBUTTONUP:
00362             inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2) | DIDFT_PSHBUTTON;
00363             This->m_state.rgbButtons[2] = wdata = 0x00;
00364         break;
00365         case WM_XBUTTONDOWN:
00366             inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2 + HIWORD(hook->mouseData)) | DIDFT_PSHBUTTON;
00367             This->m_state.rgbButtons[2 + HIWORD(hook->mouseData)] = wdata = 0x80;
00368             break;
00369         case WM_XBUTTONUP:
00370             inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2 + HIWORD(hook->mouseData)) | DIDFT_PSHBUTTON;
00371             This->m_state.rgbButtons[2 + HIWORD(hook->mouseData)] = wdata = 0x00;
00372             break;
00373     }
00374 
00375 
00376     if (inst_id != -1)
00377     {
00378         _dump_mouse_state(&This->m_state);
00379         queue_event((LPDIRECTINPUTDEVICE8A)This, id_to_offset(&This->base.data_format, inst_id),
00380                     wdata, GetCurrentTime(), This->base.dinput->evsequence++);
00381     }
00382 
00383     LeaveCriticalSection(&This->base.crit);
00384 }
00385 
00386 static BOOL dinput_window_check(SysMouseImpl* This) {
00387     RECT rect;
00388     DWORD centerX, centerY;
00389 
00390     /* make sure the window hasn't moved */
00391     if(!GetWindowRect(This->base.win, &rect))
00392         return FALSE;
00393     centerX = (rect.right  - rect.left) / 2;
00394     centerY = (rect.bottom - rect.top ) / 2;
00395     if (This->win_centerX != centerX || This->win_centerY != centerY) {
00396     This->win_centerX = centerX;
00397     This->win_centerY = centerY;
00398     }
00399     This->mapped_center.x = This->win_centerX;
00400     This->mapped_center.y = This->win_centerY;
00401     MapWindowPoints(This->base.win, HWND_DESKTOP, &This->mapped_center, 1);
00402     return TRUE;
00403 }
00404 
00405 
00406 /******************************************************************************
00407   *     Acquire : gets exclusive control of the mouse
00408   */
00409 static HRESULT WINAPI SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
00410 {
00411     SysMouseImpl *This = (SysMouseImpl *)iface;
00412     RECT  rect;
00413     POINT point;
00414     HRESULT res;
00415     
00416     TRACE("(this=%p)\n",This);
00417 
00418     if ((res = IDirectInputDevice2AImpl_Acquire(iface)) != DI_OK) return res;
00419 
00420     /* Init the mouse state */
00421     GetCursorPos( &point );
00422     if (This->base.data_format.user_df->dwFlags & DIDF_ABSAXIS)
00423     {
00424       This->m_state.lX = point.x;
00425       This->m_state.lY = point.y;
00426     } else {
00427       This->m_state.lX = 0;
00428       This->m_state.lY = 0;
00429       This->org_coords = point;
00430     }
00431     This->m_state.lZ = 0;
00432     This->m_state.rgbButtons[0] = GetKeyState(VK_LBUTTON) & 0x80;
00433     This->m_state.rgbButtons[1] = GetKeyState(VK_RBUTTON) & 0x80;
00434     This->m_state.rgbButtons[2] = GetKeyState(VK_MBUTTON) & 0x80;
00435     
00436     /* Install our mouse hook */
00437     if (This->base.dwCoopLevel & DISCL_EXCLUSIVE)
00438     {
00439       RECT rc;
00440 
00441       ShowCursor(FALSE); /* hide cursor */
00442       if (GetWindowRect(This->base.win, &rc))
00443       {
00444         FIXME("Clipping cursor to %s\n", wine_dbgstr_rect( &rc ));
00445         ClipCursor(&rc);
00446       }
00447       else
00448         ERR("Failed to get RECT: %d\n", GetLastError());
00449     }
00450 
00451     /* Need a window to warp mouse in. */
00452     if (This->warp_override == WARP_FORCE_ON && !This->base.win)
00453         This->base.win = GetDesktopWindow();
00454 
00455     /* Get the window dimension and find the center */
00456     GetWindowRect(This->base.win, &rect);
00457     This->win_centerX = (rect.right  - rect.left) / 2;
00458     This->win_centerY = (rect.bottom - rect.top ) / 2;
00459 
00460     /* Warp the mouse to the center of the window */
00461     if (This->base.dwCoopLevel & DISCL_EXCLUSIVE || This->warp_override == WARP_FORCE_ON)
00462     {
00463       This->mapped_center.x = This->win_centerX;
00464       This->mapped_center.y = This->win_centerY;
00465       MapWindowPoints(This->base.win, HWND_DESKTOP, &This->mapped_center, 1);
00466       TRACE("Warping mouse to %d - %d\n", This->mapped_center.x, This->mapped_center.y);
00467       SetCursorPos( This->mapped_center.x, This->mapped_center.y );
00468       This->last_warped = GetCurrentTime();
00469 
00470       This->need_warp = FALSE;
00471     }
00472 
00473     return DI_OK;
00474 }
00475 
00476 /******************************************************************************
00477   *     Unacquire : frees the mouse
00478   */
00479 static HRESULT WINAPI SysMouseAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface)
00480 {
00481     SysMouseImpl *This = (SysMouseImpl *)iface;
00482     HRESULT res;
00483     
00484     TRACE("(this=%p)\n",This);
00485 
00486     if ((res = IDirectInputDevice2AImpl_Unacquire(iface)) != DI_OK) return res;
00487 
00488     if (This->base.dwCoopLevel & DISCL_EXCLUSIVE)
00489     {
00490         ClipCursor(NULL);
00491         ShowCursor(TRUE); /* show cursor */
00492     }
00493 
00494     /* And put the mouse cursor back where it was at acquire time */
00495     if (This->base.dwCoopLevel & DISCL_EXCLUSIVE || This->warp_override == WARP_FORCE_ON)
00496     {
00497       TRACE(" warping mouse back to (%d , %d)\n", This->org_coords.x, This->org_coords.y);
00498       SetCursorPos(This->org_coords.x, This->org_coords.y);
00499     }
00500     
00501     return DI_OK;
00502 }
00503 
00504 /******************************************************************************
00505   *     GetDeviceState : returns the "state" of the mouse.
00506   *
00507   *   For the moment, only the "standard" return structure (DIMOUSESTATE) is
00508   *   supported.
00509   */
00510 static HRESULT WINAPI SysMouseAImpl_GetDeviceState(
00511     LPDIRECTINPUTDEVICE8A iface,DWORD len,LPVOID ptr
00512 ) {
00513     SysMouseImpl *This = (SysMouseImpl *)iface;
00514 
00515     if(This->base.acquired == 0) return DIERR_NOTACQUIRED;
00516 
00517     TRACE("(this=%p,0x%08x,%p):\n", This, len, ptr);
00518     _dump_mouse_state(&This->m_state);
00519 
00520     EnterCriticalSection(&This->base.crit);
00521     /* Copy the current mouse state */
00522     fill_DataFormat(ptr, len, &This->m_state, &This->base.data_format);
00523 
00524     /* Initialize the buffer when in relative mode */
00525     if (!(This->base.data_format.user_df->dwFlags & DIDF_ABSAXIS))
00526     {
00527     This->m_state.lX = 0;
00528     This->m_state.lY = 0;
00529     This->m_state.lZ = 0;
00530     }
00531     LeaveCriticalSection(&This->base.crit);
00532 
00533     /* Check if we need to do a mouse warping */
00534     if (This->need_warp && (GetCurrentTime() - This->last_warped > 10))
00535     {
00536         if(!dinput_window_check(This))
00537             return DIERR_GENERIC;
00538     TRACE("Warping mouse to %d - %d\n", This->mapped_center.x, This->mapped_center.y);
00539     SetCursorPos( This->mapped_center.x, This->mapped_center.y );
00540         This->last_warped = GetCurrentTime();
00541 
00542         This->need_warp = FALSE;
00543     }
00544     
00545     return DI_OK;
00546 }
00547 
00548 /******************************************************************************
00549   *     GetDeviceData : gets buffered input data.
00550   */
00551 static HRESULT WINAPI SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE8A iface,
00552         DWORD dodsize, LPDIDEVICEOBJECTDATA dod, LPDWORD entries, DWORD flags)
00553 {
00554     SysMouseImpl *This = (SysMouseImpl *)iface;
00555     HRESULT res;
00556 
00557     res = IDirectInputDevice2AImpl_GetDeviceData(iface, dodsize, dod, entries, flags);
00558     if (FAILED(res)) return res;
00559 
00560     /* Check if we need to do a mouse warping */
00561     if (This->need_warp && (GetCurrentTime() - This->last_warped > 10))
00562     {
00563         if(!dinput_window_check(This))
00564             return DIERR_GENERIC;
00565     TRACE("Warping mouse to %d - %d\n", This->mapped_center.x, This->mapped_center.y);
00566     SetCursorPos( This->mapped_center.x, This->mapped_center.y );
00567         This->last_warped = GetCurrentTime();
00568 
00569         This->need_warp = FALSE;
00570     }
00571     return res;
00572 }
00573 
00574 /******************************************************************************
00575   *     GetProperty : get input device properties
00576   */
00577 static HRESULT WINAPI SysMouseAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface,
00578                         REFGUID rguid,
00579                         LPDIPROPHEADER pdiph)
00580 {
00581     SysMouseImpl *This = (SysMouseImpl *)iface;
00582     
00583     TRACE("(%p) %s,%p\n", This, debugstr_guid(rguid), pdiph);
00584     _dump_DIPROPHEADER(pdiph);
00585     
00586     if (!HIWORD(rguid)) {
00587     switch (LOWORD(rguid)) {
00588         case (DWORD_PTR) DIPROP_GRANULARITY: {
00589         LPDIPROPDWORD pr = (LPDIPROPDWORD) pdiph;
00590         
00591         /* We'll just assume that the app asks about the Z axis */
00592         pr->dwData = WHEEL_DELTA;
00593         
00594         break;
00595         }
00596           
00597         case (DWORD_PTR) DIPROP_RANGE: {
00598         LPDIPROPRANGE pr = (LPDIPROPRANGE) pdiph;
00599         
00600         if ((pdiph->dwHow == DIPH_BYID) &&
00601             ((pdiph->dwObj == (DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS)) ||
00602              (pdiph->dwObj == (DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS)))) {
00603             /* Querying the range of either the X or the Y axis.  As I do
00604                not know the range, do as if the range were
00605                unrestricted...*/
00606             pr->lMin = DIPROPRANGE_NOMIN;
00607             pr->lMax = DIPROPRANGE_NOMAX;
00608         }
00609         
00610         break;
00611         }
00612 
00613         default:
00614                 return IDirectInputDevice2AImpl_GetProperty(iface, rguid, pdiph);
00615         }
00616     }
00617     
00618     return DI_OK;
00619 }
00620 
00621 /******************************************************************************
00622   *     GetCapabilities : get the device capabilities
00623   */
00624 static HRESULT WINAPI SysMouseAImpl_GetCapabilities(
00625     LPDIRECTINPUTDEVICE8A iface,
00626     LPDIDEVCAPS lpDIDevCaps)
00627 {
00628     SysMouseImpl *This = (SysMouseImpl *)iface;
00629     DIDEVCAPS devcaps;
00630 
00631     TRACE("(this=%p,%p)\n",This,lpDIDevCaps);
00632 
00633     if ((lpDIDevCaps->dwSize != sizeof(DIDEVCAPS)) && (lpDIDevCaps->dwSize != sizeof(DIDEVCAPS_DX3))) {
00634         WARN("invalid parameter\n");
00635         return DIERR_INVALIDPARAM;
00636     }
00637 
00638     devcaps.dwSize = lpDIDevCaps->dwSize;
00639     devcaps.dwFlags = DIDC_ATTACHED;
00640     if (This->base.dinput->dwVersion >= 0x0800)
00641     devcaps.dwDevType = DI8DEVTYPE_MOUSE | (DI8DEVTYPEMOUSE_TRADITIONAL << 8);
00642     else
00643     devcaps.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_TRADITIONAL << 8);
00644     devcaps.dwAxes = 3;
00645     devcaps.dwButtons = 8;
00646     devcaps.dwPOVs = 0;
00647     devcaps.dwFFSamplePeriod = 0;
00648     devcaps.dwFFMinTimeResolution = 0;
00649     devcaps.dwFirmwareRevision = 100;
00650     devcaps.dwHardwareRevision = 100;
00651     devcaps.dwFFDriverVersion = 0;
00652 
00653     memcpy(lpDIDevCaps, &devcaps, lpDIDevCaps->dwSize);
00654     
00655     return DI_OK;
00656 }
00657 
00658 /******************************************************************************
00659   *     GetObjectInfo : get information about a device object such as a button
00660   *                     or axis
00661   */
00662 static HRESULT WINAPI SysMouseWImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface,
00663         LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow)
00664 {
00665     static const WCHAR x_axisW[] = {'X','-','A','x','i','s',0};
00666     static const WCHAR y_axisW[] = {'Y','-','A','x','i','s',0};
00667     static const WCHAR wheelW[] = {'W','h','e','e','l',0};
00668     static const WCHAR buttonW[] = {'B','u','t','t','o','n',' ','%','d',0};
00669     HRESULT res;
00670 
00671     res = IDirectInputDevice2WImpl_GetObjectInfo(iface, pdidoi, dwObj, dwHow);
00672     if (res != DI_OK) return res;
00673 
00674     if      (IsEqualGUID(&pdidoi->guidType, &GUID_XAxis)) strcpyW(pdidoi->tszName, x_axisW);
00675     else if (IsEqualGUID(&pdidoi->guidType, &GUID_YAxis)) strcpyW(pdidoi->tszName, y_axisW);
00676     else if (IsEqualGUID(&pdidoi->guidType, &GUID_ZAxis)) strcpyW(pdidoi->tszName, wheelW);
00677     else if (pdidoi->dwType & DIDFT_BUTTON)
00678         wsprintfW(pdidoi->tszName, buttonW, DIDFT_GETINSTANCE(pdidoi->dwType) - 3);
00679 
00680     _dump_OBJECTINSTANCEW(pdidoi);
00681     return res;
00682 }
00683 
00684 static HRESULT WINAPI SysMouseAImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8A iface,
00685         LPDIDEVICEOBJECTINSTANCEA pdidoi, DWORD dwObj, DWORD dwHow)
00686 {
00687     HRESULT res;
00688     DIDEVICEOBJECTINSTANCEW didoiW;
00689     DWORD dwSize = pdidoi->dwSize;
00690 
00691     didoiW.dwSize = sizeof(didoiW);
00692     res = SysMouseWImpl_GetObjectInfo((LPDIRECTINPUTDEVICE8W)iface, &didoiW, dwObj, dwHow);
00693     if (res != DI_OK) return res;
00694 
00695     memset(pdidoi, 0, pdidoi->dwSize);
00696     memcpy(pdidoi, &didoiW, FIELD_OFFSET(DIDEVICEOBJECTINSTANCEW, tszName));
00697     pdidoi->dwSize = dwSize;
00698     WideCharToMultiByte(CP_ACP, 0, didoiW.tszName, -1, pdidoi->tszName,
00699                         sizeof(pdidoi->tszName), NULL, NULL);
00700 
00701     return res;
00702 }
00703 
00704 /******************************************************************************
00705   *     GetDeviceInfo : get information about a device's identity
00706   */
00707 static HRESULT WINAPI SysMouseAImpl_GetDeviceInfo(
00708     LPDIRECTINPUTDEVICE8A iface,
00709     LPDIDEVICEINSTANCEA pdidi)
00710 {
00711     SysMouseImpl *This = (SysMouseImpl *)iface;
00712     TRACE("(this=%p,%p)\n", This, pdidi);
00713 
00714     if (pdidi->dwSize != sizeof(DIDEVICEINSTANCEA)) {
00715         WARN(" dinput3 not supporte yet...\n");
00716     return DI_OK;
00717     }
00718 
00719     fill_mouse_dideviceinstanceA(pdidi, This->base.dinput->dwVersion);
00720     
00721     return DI_OK;
00722 }
00723 
00724 static HRESULT WINAPI SysMouseWImpl_GetDeviceInfo(LPDIRECTINPUTDEVICE8W iface, LPDIDEVICEINSTANCEW pdidi)
00725 {
00726     SysMouseImpl *This = (SysMouseImpl *)iface;
00727     TRACE("(this=%p,%p)\n", This, pdidi);
00728 
00729     if (pdidi->dwSize != sizeof(DIDEVICEINSTANCEW)) {
00730         WARN(" dinput3 not supporte yet...\n");
00731     return DI_OK;
00732     }
00733 
00734     fill_mouse_dideviceinstanceW(pdidi, This->base.dinput->dwVersion);
00735     
00736     return DI_OK;
00737 }
00738 
00739 
00740 static const IDirectInputDevice8AVtbl SysMouseAvt =
00741 {
00742     IDirectInputDevice2AImpl_QueryInterface,
00743     IDirectInputDevice2AImpl_AddRef,
00744     IDirectInputDevice2AImpl_Release,
00745     SysMouseAImpl_GetCapabilities,
00746     IDirectInputDevice2AImpl_EnumObjects,
00747     SysMouseAImpl_GetProperty,
00748     IDirectInputDevice2AImpl_SetProperty,
00749     SysMouseAImpl_Acquire,
00750     SysMouseAImpl_Unacquire,
00751     SysMouseAImpl_GetDeviceState,
00752     SysMouseAImpl_GetDeviceData,
00753     IDirectInputDevice2AImpl_SetDataFormat,
00754     IDirectInputDevice2AImpl_SetEventNotification,
00755     IDirectInputDevice2AImpl_SetCooperativeLevel,
00756     SysMouseAImpl_GetObjectInfo,
00757     SysMouseAImpl_GetDeviceInfo,
00758     IDirectInputDevice2AImpl_RunControlPanel,
00759     IDirectInputDevice2AImpl_Initialize,
00760     IDirectInputDevice2AImpl_CreateEffect,
00761     IDirectInputDevice2AImpl_EnumEffects,
00762     IDirectInputDevice2AImpl_GetEffectInfo,
00763     IDirectInputDevice2AImpl_GetForceFeedbackState,
00764     IDirectInputDevice2AImpl_SendForceFeedbackCommand,
00765     IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
00766     IDirectInputDevice2AImpl_Escape,
00767     IDirectInputDevice2AImpl_Poll,
00768     IDirectInputDevice2AImpl_SendDeviceData,
00769     IDirectInputDevice7AImpl_EnumEffectsInFile,
00770     IDirectInputDevice7AImpl_WriteEffectToFile,
00771     IDirectInputDevice8AImpl_BuildActionMap,
00772     IDirectInputDevice8AImpl_SetActionMap,
00773     IDirectInputDevice8AImpl_GetImageInfo
00774 };
00775 
00776 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
00777 # define XCAST(fun) (typeof(SysMouseWvt.fun))
00778 #else
00779 # define XCAST(fun) (void*)
00780 #endif
00781 
00782 static const IDirectInputDevice8WVtbl SysMouseWvt =
00783 {
00784     IDirectInputDevice2WImpl_QueryInterface,
00785     XCAST(AddRef)IDirectInputDevice2AImpl_AddRef,
00786     XCAST(Release)IDirectInputDevice2AImpl_Release,
00787     XCAST(GetCapabilities)SysMouseAImpl_GetCapabilities,
00788     IDirectInputDevice2WImpl_EnumObjects,
00789     XCAST(GetProperty)SysMouseAImpl_GetProperty,
00790     XCAST(SetProperty)IDirectInputDevice2AImpl_SetProperty,
00791     XCAST(Acquire)SysMouseAImpl_Acquire,
00792     XCAST(Unacquire)SysMouseAImpl_Unacquire,
00793     XCAST(GetDeviceState)SysMouseAImpl_GetDeviceState,
00794     XCAST(GetDeviceData)SysMouseAImpl_GetDeviceData,
00795     XCAST(SetDataFormat)IDirectInputDevice2AImpl_SetDataFormat,
00796     XCAST(SetEventNotification)IDirectInputDevice2AImpl_SetEventNotification,
00797     XCAST(SetCooperativeLevel)IDirectInputDevice2AImpl_SetCooperativeLevel,
00798     SysMouseWImpl_GetObjectInfo,
00799     SysMouseWImpl_GetDeviceInfo,
00800     XCAST(RunControlPanel)IDirectInputDevice2AImpl_RunControlPanel,
00801     XCAST(Initialize)IDirectInputDevice2AImpl_Initialize,
00802     XCAST(CreateEffect)IDirectInputDevice2AImpl_CreateEffect,
00803     IDirectInputDevice2WImpl_EnumEffects,
00804     IDirectInputDevice2WImpl_GetEffectInfo,
00805     XCAST(GetForceFeedbackState)IDirectInputDevice2AImpl_GetForceFeedbackState,
00806     XCAST(SendForceFeedbackCommand)IDirectInputDevice2AImpl_SendForceFeedbackCommand,
00807     XCAST(EnumCreatedEffectObjects)IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
00808     XCAST(Escape)IDirectInputDevice2AImpl_Escape,
00809     XCAST(Poll)IDirectInputDevice2AImpl_Poll,
00810     XCAST(SendDeviceData)IDirectInputDevice2AImpl_SendDeviceData,
00811     IDirectInputDevice7WImpl_EnumEffectsInFile,
00812     IDirectInputDevice7WImpl_WriteEffectToFile,
00813     IDirectInputDevice8WImpl_BuildActionMap,
00814     IDirectInputDevice8WImpl_SetActionMap,
00815     IDirectInputDevice8WImpl_GetImageInfo
00816 };
00817 #undef XCAST

Generated on Mon May 28 2012 04:17:01 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.