Moved more code to the X11 driver.
[wine] / windows / dinput.c
1 /*              DirectInput
2  *
3  * Copyright 1998 Marcus Meissner
4  *
5  * Additions (mouse support) Copyright 1998 Lionel Ulmer
6  */
7 /* Status:
8  *
9  * - Tomb Raider 2 Demo:
10  *   Playable using keyboard only.
11  * - WingCommander Prophecy Demo:
12  *   Doesn't get Input Focus.
13  * 
14  * - Fallout : works great in X and DGA mode
15  *
16  * FIXME: The keyboard handling needs to (and will) be merged into keyboard.c
17  *        (The current implementation is currently only a proof of concept and
18  *         an utter mess.)
19  */
20
21 #include "ts_xlib.h"
22
23 #include "config.h"
24 #include <string.h>
25 #include <unistd.h>
26 #include <assert.h>
27 #include <sys/signal.h>
28
29 #include "windows.h"
30 #include "winerror.h"
31 #include "shell.h"
32 #include "ole.h"
33 #include "compobj.h"
34 #include "interfaces.h"
35 #include "gdi.h"
36 #include "heap.h"
37 #include "win.h"
38 #include "dinput.h"
39 #include "debug.h"
40 #include "message.h"
41
42 extern BYTE InputKeyStateTable[256];
43 extern int min_keycode, max_keycode;
44 extern WORD keyc2vkey[256];
45
46 static IDirectInputA_VTable ddiavt;
47 static IDirectInputDeviceA_VTable SysKeyboardAvt;
48 static IDirectInputDeviceA_VTable SysMouseAvt;
49
50 /* UIDs for Wine "drivers".
51    When enumerating each device supporting DInput, they have two UIDs :
52     - the 'windows' UID
53     - a vendor UID */
54 static GUID DInput_Wine_Mouse_GUID = { /* 9e573ed8-7734-11d2-8d4a-23903fb6bdf7 */
55   0x9e573ed8,
56   0x7734,
57   0x11d2,
58   {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
59 };
60 static GUID DInput_Wine_Keyboard_GUID = { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */
61   0x0ab8648a,
62   0x7735,
63   0x11d2,
64   {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41}
65 };
66
67 /******************************************************************************
68  *      DirectInputCreate32A
69  */
70 HRESULT WINAPI DirectInputCreate32A(HINSTANCE32 hinst, DWORD dwVersion, LPDIRECTINPUT32A *ppDI, LPUNKNOWN punkOuter) {
71         TRACE(dinput, "(0x%08lx,%04lx,%p,%p)\n",
72                 (DWORD)hinst,dwVersion,ppDI,punkOuter
73         );
74         (*ppDI) = (LPDIRECTINPUT32A)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInput32A));
75         (*ppDI)->ref = 1;
76         (*ppDI)->lpvtbl = &ddiavt;
77         return 0;
78 }
79 /******************************************************************************
80  *      IDirectInputA_EnumDevices
81  */
82 static HRESULT WINAPI IDirectInputA_EnumDevices(
83         LPDIRECTINPUT32A this, DWORD dwDevType, LPDIENUMDEVICESCALLBACK32A lpCallback,
84         LPVOID pvRef, DWORD dwFlags
85 ) {
86   DIDEVICEINSTANCE32A devInstance;
87   int ret;
88
89   TRACE(dinput, "(this=%p,0x%04lx,%p,%p,%04lx)\n", this, dwDevType, lpCallback, pvRef, dwFlags);
90
91   devInstance.dwSize = sizeof(DIDEVICEINSTANCE32A);
92   
93   if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_KEYBOARD)) {
94   /* Return keyboard */
95     devInstance.guidInstance = GUID_SysKeyboard;         /* DInput's GUID */
96     devInstance.guidProduct = DInput_Wine_Keyboard_GUID; /* Vendor's GUID */
97     devInstance.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8);
98   strcpy(devInstance.tszInstanceName, "Keyboard");
99   strcpy(devInstance.tszProductName, "Wine Keyboard");
100   
101   ret = lpCallback(&devInstance, pvRef);
102     TRACE(dinput, "Keyboard registered\n");
103   
104     if (ret == DIENUM_STOP)
105     return 0;
106   }
107   
108   if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_KEYBOARD)) {
109   /* Return mouse */
110     devInstance.guidInstance = GUID_SysMouse;         /* DInput's GUID */
111     devInstance.guidProduct = DInput_Wine_Mouse_GUID; /* Vendor's GUID */
112     devInstance.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_UNKNOWN << 8);
113   strcpy(devInstance.tszInstanceName, "Mouse");
114   strcpy(devInstance.tszProductName, "Wine Mouse");
115   
116   ret = lpCallback(&devInstance, pvRef);
117     TRACE(dinput, "Mouse registered\n");
118   }
119
120   /* Should also do joystick enumerations.... */
121   
122         return 0;
123 }
124
125 static ULONG WINAPI IDirectInputA_AddRef(LPDIRECTINPUT32A this) {
126         return ++(this->ref);
127 }
128
129 static ULONG WINAPI IDirectInputA_Release(LPDIRECTINPUT32A this) {
130         if (!(--this->ref)) {
131                 HeapFree(GetProcessHeap(),0,this);
132                 return 0;
133         }
134         return this->ref;
135 }
136
137 static HRESULT WINAPI IDirectInputA_CreateDevice(
138         LPDIRECTINPUT32A this,REFGUID rguid,LPDIRECTINPUTDEVICE32A* pdev,
139         LPUNKNOWN punk
140 ) {
141         char    xbuf[50];
142         
143         WINE_StringFromCLSID(rguid,xbuf);
144         FIXME(dinput,"(this=%p,%s,%p,%p): stub\n",this,xbuf,pdev,punk);
145         if ((!memcmp(&GUID_SysKeyboard,rguid,sizeof(GUID_SysKeyboard))) ||          /* Generic Keyboard */
146             (!memcmp(&DInput_Wine_Keyboard_GUID,rguid,sizeof(GUID_SysKeyboard)))) { /* Wine Keyboard */
147                 *pdev = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysKeyboard32A));
148                 (*pdev)->ref = 1;
149                 (*pdev)->lpvtbl = &SysKeyboardAvt;
150                 memcpy(&((*pdev)->guid),rguid,sizeof(*rguid));
151                 memset(((LPSYSKEYBOARD32A)(*pdev))->keystate,0,256);
152                 return 0;
153         }
154         if ((!memcmp(&GUID_SysMouse,rguid,sizeof(GUID_SysMouse))) ||             /* Generic Mouse */
155             (!memcmp(&DInput_Wine_Mouse_GUID,rguid,sizeof(GUID_SysKeyboard)))) { /* Wine Mouse */
156                 *pdev = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysMouse32A));
157                 (*pdev)->ref = 1;
158                 (*pdev)->lpvtbl = &SysMouseAvt;
159                 memcpy(&((*pdev)->guid),rguid,sizeof(*rguid));
160                 return 0;
161         }
162         return E_FAIL;
163 }
164
165 static HRESULT WINAPI IDirectInputA_QueryInterface(
166         LPDIRECTINPUT32A this,REFIID riid,LPVOID *ppobj
167 ) {
168         char    xbuf[50];
169
170         WINE_StringFromCLSID(riid,xbuf);
171         TRACE(dinput,"(this=%p,%s,%p)\n",this,xbuf,ppobj);
172         if (!memcmp(&IID_IUnknown,riid,sizeof(*riid))) {
173                 this->lpvtbl->fnAddRef(this);
174                 *ppobj = this;
175                 return 0;
176         }
177         if (!memcmp(&IID_IDirectInputA,riid,sizeof(*riid))) {
178                 this->lpvtbl->fnAddRef(this);
179                 *ppobj = this;
180                 return 0;
181         }
182         return E_FAIL;
183 }
184
185 static HRESULT WINAPI IDirectInputA_Initialize(
186         LPDIRECTINPUT32A this,HINSTANCE32 hinst,DWORD x
187 ) {
188         return DIERR_ALREADYINITIALIZED;
189 }
190
191 static IDirectInputA_VTable ddiavt= {
192         IDirectInputA_QueryInterface,
193         IDirectInputA_AddRef,
194         IDirectInputA_Release,
195         IDirectInputA_CreateDevice,
196         IDirectInputA_EnumDevices,
197         (void*)6,
198         (void*)7,
199         IDirectInputA_Initialize
200 };
201
202 /******************************************************************************
203  *      IDirectInputDeviceA
204  */
205 static HRESULT WINAPI IDirectInputDeviceA_SetDataFormat(
206         LPDIRECTINPUTDEVICE32A this,LPCDIDATAFORMAT df
207 ) {
208         /*
209         int i;
210         TRACE(dinput,"(this=%p,%p)\n",this,df);
211
212         TRACE(dinput,"df.dwSize=%ld\n",df->dwSize);
213         TRACE(dinput,"(df.dwObjsize=%ld)\n",df->dwObjSize);
214         TRACE(dinput,"(df.dwFlags=0x%08lx)\n",df->dwFlags);
215         TRACE(dinput,"(df.dwDataSize=%ld)\n",df->dwDataSize);
216         TRACE(dinput,"(df.dwNumObjs=%ld)\n",df->dwNumObjs);
217
218         for (i=0;i<df->dwNumObjs;i++) {
219                 char    xbuf[50];
220
221                 if (df->rgodf[i].pguid)
222                         WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
223                 else
224                         strcpy(xbuf,"<no guid>");
225                 TRACE(dinput,"df.rgodf[%d].guid %s\n",i,xbuf);
226                 TRACE(dinput,"df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
227                 TRACE(dinput,"dwType 0x%02lx,dwInstance %ld\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
228                 TRACE(dinput,"df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
229         }
230         */
231         return 0;
232 }
233
234 static HRESULT WINAPI IDirectInputDeviceA_SetCooperativeLevel(
235         LPDIRECTINPUTDEVICE32A this,HWND32 hwnd,DWORD dwflags
236 ) {
237         FIXME(dinput,"(this=%p,0x%08lx,0x%08lx): stub\n",this,(DWORD)hwnd,dwflags);
238         return 0;
239 }
240
241 static HRESULT WINAPI IDirectInputDeviceA_SetProperty(
242         LPDIRECTINPUTDEVICE32A this,REFGUID rguid,LPCDIPROPHEADER ph
243 ) {
244         char    xbuf[50];
245
246         if (HIWORD(rguid))
247                 WINE_StringFromCLSID(rguid,xbuf);
248         else
249                 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
250         TRACE(dinput,"(this=%p,%s,%p)\n",this,xbuf,ph);
251         if (!HIWORD(rguid)) {
252                 switch ((DWORD)rguid) {
253                 case DIPROP_BUFFERSIZE: {
254                         LPCDIPROPDWORD  pd = (LPCDIPROPDWORD)ph;
255
256                         TRACE(dinput,"buffersize = %ld\n",pd->dwData);
257                         break;
258                 }
259                 default:
260                         WARN(dinput,"Unknown type %ld\n",(DWORD)rguid);
261                         break;
262                 }
263         }
264         return 0;
265 }
266
267 static HRESULT WINAPI IDirectInputDeviceA_SetEventNotification(
268         LPDIRECTINPUTDEVICE32A this,HANDLE32 hnd
269 ) {
270         FIXME(dinput,"(this=%p,0x%08lx): stub\n",this,(DWORD)hnd);
271         return 0;
272 }
273
274 static HRESULT WINAPI IDirectInputDeviceA_GetDeviceData(
275         LPDIRECTINPUTDEVICE32A this,DWORD dodsize,LPDIDEVICEOBJECTDATA dod,
276         LPDWORD entries,DWORD flags
277 ) {
278   TRACE(dinput,"IDirectInputDeviceA(%p)->GetDeviceData(%ld,%p,%p(0x%08lx),0x%08lx)\n",
279         this,dodsize,dod,entries,*entries,flags);
280         return 0;
281 }
282
283
284 static HRESULT WINAPI IDirectInputDeviceA_Acquire(LPDIRECTINPUTDEVICE32A this) {
285         TRACE(dinput,"(this=%p): stub\n",this);
286         return 0;
287 }
288
289 static HRESULT WINAPI IDirectInputDeviceA_Unacquire(LPDIRECTINPUTDEVICE32A this) {
290         TRACE(dinput,"(this=%p): stub\n",this);
291         return 0;
292 }
293
294 static ULONG WINAPI IDirectInputDeviceA_Release(LPDIRECTINPUTDEVICE32A this) {
295         this->ref--;
296         if (this->ref)
297                 return this->ref;
298         HeapFree(GetProcessHeap(),0,this);
299         return 0;
300 }
301
302 static HRESULT WINAPI SysKeyboardA_SetProperty(
303         LPDIRECTINPUTDEVICE32A this,REFGUID rguid,LPCDIPROPHEADER ph
304 ) {
305         char                    xbuf[50];
306
307         if (HIWORD(rguid))
308                 WINE_StringFromCLSID(rguid,xbuf);
309         else
310                 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
311         TRACE(dinput,"(this=%p,%s,%p)\n",this,xbuf,ph);
312         TRACE(dinput,"(size=%ld,headersize=%ld,obj=%ld,how=%ld\n",
313             ph->dwSize,ph->dwHeaderSize,ph->dwObj,ph->dwHow);
314         if (!HIWORD(rguid)) {
315                 switch ((DWORD)rguid) {
316                 case DIPROP_BUFFERSIZE: {
317                         LPCDIPROPDWORD  pd = (LPCDIPROPDWORD)ph;
318
319                         TRACE(dinput,"(buffersize=%ld)\n",pd->dwData);
320                         break;
321                 }
322                 default:
323                         WARN(dinput,"Unknown type %ld\n",(DWORD)rguid);
324                         break;
325                 }
326         }
327         return 0;
328 }
329
330 static HRESULT WINAPI SysKeyboardA_GetDeviceState(
331         LPDIRECTINPUTDEVICE32A this,DWORD len,LPVOID ptr
332 ) {
333         if (len==256) {
334                 int keyc,vkey;
335
336                 memset(ptr,0,256);
337                 for (keyc=min_keycode;keyc<max_keycode;keyc++)
338                 {
339                     /* X keycode to virtual key */
340                     vkey = keyc2vkey[keyc] & 0xFF;
341                     /* The windows scancode is keyc-min_keycode */
342                     if (InputKeyStateTable[vkey]&0x80) {
343                         ((LPBYTE)ptr)[keyc-min_keycode]=0x80;
344                         ((LPBYTE)ptr)[(keyc-min_keycode)|0x80]=0x80;
345                     }
346                 }
347                 return 0;
348         }
349         WARN(dinput,"whoops, SysKeyboardA_GetDeviceState got len %ld?\n",len);
350         return 0;
351 }
352
353 static HRESULT WINAPI SysKeyboardA_GetDeviceData(
354         LPDIRECTINPUTDEVICE32A this,DWORD dodsize,LPDIDEVICEOBJECTDATA dod,
355         LPDWORD entries,DWORD flags
356 ) {
357         int                     keyc,n,vkey,xentries;
358         LPSYSKEYBOARD32A        kthis = (LPSYSKEYBOARD32A)this;
359
360         TRACE(dinput,"(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n",
361                 this,dodsize,dod,entries,entries?*entries:0,flags);
362         EVENT_WaitNetEvent(FALSE,TRUE);
363         if (entries)
364                 xentries = *entries; 
365         else
366                 xentries = 1;
367
368         n = 0;
369
370         for (keyc=min_keycode;(keyc<max_keycode) && (n<*entries);keyc++)
371         {
372                     /* X keycode to virtual key */
373                     vkey = keyc2vkey[keyc] & 0xFF;
374                     if (kthis->keystate[vkey] == (InputKeyStateTable[vkey]&0x80))
375                         continue;
376                 if (dod) {
377                         /* add an entry */
378                         dod[n].dwOfs            = keyc-min_keycode; /* scancode */
379                         dod[n].dwData           = InputKeyStateTable[vkey]&0x80;
380                         dod[n].dwTimeStamp      = 0; /* umm */
381                         dod[n].dwSequence       = 0; /* umm */
382                         n++;
383                 }
384                 if (!(flags & DIGDD_PEEK))
385                         kthis->keystate[vkey] = InputKeyStateTable[vkey]&0x80;
386                     
387         }
388         
389         if (n) fprintf(stderr,"%d entries\n",n);
390         *entries = n;
391         return 0;
392 }
393
394 static HRESULT WINAPI SysKeyboardA_Acquire(LPDIRECTINPUTDEVICE32A this) {
395         TRACE(dinput,"(this=%p): stub\n",this);
396         return 0;
397 }
398
399 static HRESULT WINAPI SysKeyboardA_Unacquire(LPDIRECTINPUTDEVICE32A this) {
400         TRACE(dinput,"(this=%p): stub\n",this);
401         return 0;
402 }
403
404 static HRESULT WINAPI IDirectInputDeviceA_QueryInterface(
405         LPDIRECTINPUTDEVICE32A this,REFIID riid,LPVOID *ppobj
406 ) {
407         char    xbuf[50];
408
409         WINE_StringFromCLSID(riid,xbuf);
410         TRACE(dinput,"(this=%p,%s,%p)\n",this,xbuf,ppobj);
411         if (!memcmp(&IID_IUnknown,riid,sizeof(*riid))) {
412                 this->lpvtbl->fnAddRef(this);
413                 *ppobj = this;
414                 return 0;
415         }
416         if (!memcmp(&IID_IDirectInputDeviceA,riid,sizeof(*riid))) {
417                 this->lpvtbl->fnAddRef(this);
418                 *ppobj = this;
419                 return 0;
420         }
421         return E_FAIL;
422 }
423
424 /******************************************************************************
425  *      SysMouseA (DInput Mouse support)
426  */
427
428 /******************************************************************************
429   *     SetDataFormat : the application can choose the format of the data
430   *   the device driver sends back with GetDeviceState.
431   *
432   *   For the moment, only the "standard" configuration (c_dfDIMouse) is supported
433   *   in absolute and relative mode.
434   */
435 static HRESULT WINAPI SysMouseA_SetDataFormat(
436         LPDIRECTINPUTDEVICE32A this,LPCDIDATAFORMAT df
437 ) {
438   int i;
439   LPSYSMOUSE32A mthis = (LPSYSMOUSE32A) this;
440   
441   TRACE(dinput,"(this=%p,%p)\n",this,df);
442
443   TRACE(dinput,"(df.dwSize=%ld)\n",df->dwSize);
444   TRACE(dinput,"(df.dwObjsize=%ld)\n",df->dwObjSize);
445   TRACE(dinput,"(df.dwFlags=0x%08lx)\n",df->dwFlags);
446   TRACE(dinput,"(df.dwDataSize=%ld)\n",df->dwDataSize);
447   TRACE(dinput,"(df.dwNumObjs=%ld)\n",df->dwNumObjs);
448
449   for (i=0;i<df->dwNumObjs;i++) {
450     char        xbuf[50];
451     
452     if (df->rgodf[i].pguid)
453       WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
454     else
455       strcpy(xbuf,"<no guid>");
456     TRACE(dinput,"df.rgodf[%d].guid %s (%p)\n",i,xbuf, df->rgodf[i].pguid);
457     TRACE(dinput,"df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
458     TRACE(dinput,"dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
459     TRACE(dinput,"df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
460   }
461
462   /* Check size of data format to prevent crashes if the applications
463      sends a smaller buffer */
464   if (df->dwDataSize != sizeof(struct DIMOUSESTATE)) {
465     FIXME(dinput, "non-standard mouse configuration not supported yet.");
466     return DIERR_INVALIDPARAM;
467   }
468   
469   /* For the moment, ignore these fields and return always as if
470      c_dfDIMouse was passed as format... */
471   if (df->dwFlags == DIDF_ABSAXIS)
472     mthis->absolute = 1;
473   else {
474     DWORD rx, ry;
475     
476     /* We need to get the initial "previous" position to be able
477        to return deltas */
478     mthis->absolute = 0;
479   
480     /* Get the mouse position */
481     EVENT_QueryPointer(&rx, &ry, NULL);
482
483     /* Fill the initial mouse state structure */
484     mthis->prevX = rx;
485     mthis->prevY = ry;
486   }
487   
488   return 0;
489 }
490
491 /******************************************************************************
492   *     GetDeviceState : returns the "state" of the mouse.
493   *
494   *   For the moment, only the "standard" return structure (DIMOUSESTATE) is
495   *   supported.
496   */
497 static HRESULT WINAPI SysMouseA_GetDeviceState(
498         LPDIRECTINPUTDEVICE32A this,DWORD len,LPVOID ptr
499 ) {
500   DWORD rx, ry, state;
501   struct DIMOUSESTATE *mstate = (struct DIMOUSESTATE *) ptr;
502   LPSYSMOUSE32A mthis = (LPSYSMOUSE32A) this;
503   
504   TRACE(dinput,"(this=%p,0x%08lx,%p): \n",this,len,ptr);
505   
506   /* Check if the buffer is big enough */
507   if (len < sizeof(struct DIMOUSESTATE)) {
508     FIXME(dinput, "unsupported state structure.");
509     return DIERR_INVALIDPARAM;
510   }
511   
512   /* Get the mouse position */
513   EVENT_QueryPointer(&rx, &ry, &state);
514   TRACE(dinput,"(X:%d - Y:%d)\n", rx, ry);
515
516   /* Fill the mouse state structure */
517   if (mthis->absolute) {
518     mstate->lX = rx;
519     mstate->lY = ry;
520   } else {
521     mstate->lX = rx - mthis->prevX;
522     mstate->lY = ry - mthis->prevY;
523     /* Fill the previous positions */
524     mthis->prevX = rx;
525     mthis->prevY = ry;
526   }
527   mstate->lZ = 0;
528   mstate->rgbButtons[0] = (state & MK_LBUTTON ? 0xFF : 0x00);
529   mstate->rgbButtons[1] = (state & MK_RBUTTON ? 0xFF : 0x00);
530   mstate->rgbButtons[2] = (state & MK_MBUTTON ? 0xFF : 0x00);
531   mstate->rgbButtons[3] = 0x00;
532   
533   return 0;
534 }
535
536
537
538 static IDirectInputDeviceA_VTable SysKeyboardAvt={
539         IDirectInputDeviceA_QueryInterface,
540         (void*)2,
541         IDirectInputDeviceA_Release,
542         (void*)4,
543         (void*)5,
544         (void*)6,
545         SysKeyboardA_SetProperty,
546         SysKeyboardA_Acquire,
547         SysKeyboardA_Unacquire,
548         SysKeyboardA_GetDeviceState,
549         SysKeyboardA_GetDeviceData,
550         IDirectInputDeviceA_SetDataFormat,
551         IDirectInputDeviceA_SetEventNotification,
552         IDirectInputDeviceA_SetCooperativeLevel,
553         (void*)15,
554         (void*)16,
555         (void*)17,
556         (void*)18,
557 };
558
559 static IDirectInputDeviceA_VTable SysMouseAvt={
560         IDirectInputDeviceA_QueryInterface,
561         (void*)2,
562         IDirectInputDeviceA_Release,
563         (void*)4,
564         (void*)5,
565         (void*)6,
566         IDirectInputDeviceA_SetProperty,
567         IDirectInputDeviceA_Acquire,
568         IDirectInputDeviceA_Unacquire,
569         SysMouseA_GetDeviceState,
570         IDirectInputDeviceA_GetDeviceData,
571         SysMouseA_SetDataFormat,
572         IDirectInputDeviceA_SetEventNotification,
573         IDirectInputDeviceA_SetCooperativeLevel,
574         (void*)15,
575         (void*)16,
576         (void*)17,
577         (void*)18,
578 };