Group commit for recovery after disk crash.
[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 "config.h"
22 #include <string.h>
23 #include <unistd.h>
24 #include <assert.h>
25 #include <sys/signal.h>
26
27 #include "windows.h"
28 #include "winerror.h"
29 #include "shell.h"
30 #include "gdi.h"
31 #include "heap.h"
32 #include "win.h"
33 #include "dinput.h"
34 #include "objbase.h"
35 #include "debug.h"
36 #include "message.h"
37
38 extern BYTE InputKeyStateTable[256];
39 extern int min_keycode, max_keycode;
40 extern WORD keyc2vkey[256];
41
42 static IDirectInputA_VTable ddiavt;
43 static IDirectInputDeviceA_VTable SysKeyboardAvt;
44 static IDirectInputDeviceA_VTable SysMouseAvt;
45
46 /* UIDs for Wine "drivers".
47    When enumerating each device supporting DInput, they have two UIDs :
48     - the 'windows' UID
49     - a vendor UID */
50 static GUID DInput_Wine_Mouse_GUID = { /* 9e573ed8-7734-11d2-8d4a-23903fb6bdf7 */
51   0x9e573ed8,
52   0x7734,
53   0x11d2,
54   {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
55 };
56 static GUID DInput_Wine_Keyboard_GUID = { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */
57   0x0ab8648a,
58   0x7735,
59   0x11d2,
60   {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41}
61 };
62
63 /******************************************************************************
64  *      DirectInputCreate32A
65  */
66 HRESULT WINAPI DirectInputCreate32A(HINSTANCE32 hinst, DWORD dwVersion, LPDIRECTINPUT32A *ppDI, LPUNKNOWN punkOuter) {
67         TRACE(dinput, "(0x%08lx,%04lx,%p,%p)\n",
68                 (DWORD)hinst,dwVersion,ppDI,punkOuter
69         );
70         (*ppDI) = (LPDIRECTINPUT32A)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInput32A));
71         (*ppDI)->ref = 1;
72         (*ppDI)->lpvtbl = &ddiavt;
73         return 0;
74 }
75 /******************************************************************************
76  *      IDirectInputA_EnumDevices
77  */
78 static HRESULT WINAPI IDirectInputA_EnumDevices(
79         LPDIRECTINPUT32A this, DWORD dwDevType, LPDIENUMDEVICESCALLBACK32A lpCallback,
80         LPVOID pvRef, DWORD dwFlags
81 ) {
82   DIDEVICEINSTANCE32A devInstance;
83   int ret;
84
85   TRACE(dinput, "(this=%p,0x%04lx,%p,%p,%04lx)\n", this, dwDevType, lpCallback, pvRef, dwFlags);
86
87   devInstance.dwSize = sizeof(DIDEVICEINSTANCE32A);
88   
89   if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_KEYBOARD)) {
90   /* Return keyboard */
91     devInstance.guidInstance = GUID_SysKeyboard;         /* DInput's GUID */
92     devInstance.guidProduct = DInput_Wine_Keyboard_GUID; /* Vendor's GUID */
93     devInstance.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8);
94   strcpy(devInstance.tszInstanceName, "Keyboard");
95   strcpy(devInstance.tszProductName, "Wine Keyboard");
96   
97   ret = lpCallback(&devInstance, pvRef);
98     TRACE(dinput, "Keyboard registered\n");
99   
100     if (ret == DIENUM_STOP)
101     return 0;
102   }
103   
104   if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_KEYBOARD)) {
105   /* Return mouse */
106     devInstance.guidInstance = GUID_SysMouse;         /* DInput's GUID */
107     devInstance.guidProduct = DInput_Wine_Mouse_GUID; /* Vendor's GUID */
108     devInstance.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_UNKNOWN << 8);
109   strcpy(devInstance.tszInstanceName, "Mouse");
110   strcpy(devInstance.tszProductName, "Wine Mouse");
111   
112   ret = lpCallback(&devInstance, pvRef);
113     TRACE(dinput, "Mouse registered\n");
114   }
115
116   /* Should also do joystick enumerations.... */
117   
118         return 0;
119 }
120
121 static ULONG WINAPI IDirectInputA_AddRef(LPDIRECTINPUT32A this) {
122         return ++(this->ref);
123 }
124
125 static ULONG WINAPI IDirectInputA_Release(LPDIRECTINPUT32A this) {
126         if (!(--this->ref)) {
127                 HeapFree(GetProcessHeap(),0,this);
128                 return 0;
129         }
130         return this->ref;
131 }
132
133 static HRESULT WINAPI IDirectInputA_CreateDevice(
134         LPDIRECTINPUT32A this,REFGUID rguid,LPDIRECTINPUTDEVICE32A* pdev,
135         LPUNKNOWN punk
136 ) {
137         char    xbuf[50];
138         
139         WINE_StringFromCLSID(rguid,xbuf);
140         FIXME(dinput,"(this=%p,%s,%p,%p): stub\n",this,xbuf,pdev,punk);
141         if ((!memcmp(&GUID_SysKeyboard,rguid,sizeof(GUID_SysKeyboard))) ||          /* Generic Keyboard */
142             (!memcmp(&DInput_Wine_Keyboard_GUID,rguid,sizeof(GUID_SysKeyboard)))) { /* Wine Keyboard */
143                 *pdev = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysKeyboard32A));
144                 (*pdev)->ref = 1;
145                 (*pdev)->lpvtbl = &SysKeyboardAvt;
146                 memcpy(&((*pdev)->guid),rguid,sizeof(*rguid));
147                 memset(((LPSYSKEYBOARD32A)(*pdev))->keystate,0,256);
148                 return 0;
149         }
150         if ((!memcmp(&GUID_SysMouse,rguid,sizeof(GUID_SysMouse))) ||             /* Generic Mouse */
151             (!memcmp(&DInput_Wine_Mouse_GUID,rguid,sizeof(GUID_SysKeyboard)))) { /* Wine Mouse */
152                 *pdev = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysMouse32A));
153                 (*pdev)->ref = 1;
154                 (*pdev)->lpvtbl = &SysMouseAvt;
155                 memcpy(&((*pdev)->guid),rguid,sizeof(*rguid));
156                 return 0;
157         }
158         return E_FAIL;
159 }
160
161 static HRESULT WINAPI IDirectInputA_QueryInterface(
162         LPDIRECTINPUT32A this,REFIID riid,LPVOID *ppobj
163 ) {
164         char    xbuf[50];
165
166         WINE_StringFromCLSID(riid,xbuf);
167         TRACE(dinput,"(this=%p,%s,%p)\n",this,xbuf,ppobj);
168         if (!memcmp(&IID_IUnknown,riid,sizeof(*riid))) {
169                 this->lpvtbl->fnAddRef(this);
170                 *ppobj = this;
171                 return 0;
172         }
173         if (!memcmp(&IID_IDirectInputA,riid,sizeof(*riid))) {
174                 this->lpvtbl->fnAddRef(this);
175                 *ppobj = this;
176                 return 0;
177         }
178         return E_FAIL;
179 }
180
181 static HRESULT WINAPI IDirectInputA_Initialize(
182         LPDIRECTINPUT32A this,HINSTANCE32 hinst,DWORD x
183 ) {
184         return DIERR_ALREADYINITIALIZED;
185 }
186
187 static IDirectInputA_VTable ddiavt= {
188         IDirectInputA_QueryInterface,
189         IDirectInputA_AddRef,
190         IDirectInputA_Release,
191         IDirectInputA_CreateDevice,
192         IDirectInputA_EnumDevices,
193         (void*)6,
194         (void*)7,
195         IDirectInputA_Initialize
196 };
197
198 /******************************************************************************
199  *      IDirectInputDeviceA
200  */
201 static HRESULT WINAPI IDirectInputDeviceA_SetDataFormat(
202         LPDIRECTINPUTDEVICE32A this,LPCDIDATAFORMAT df
203 ) {
204         /*
205         int i;
206         TRACE(dinput,"(this=%p,%p)\n",this,df);
207
208         TRACE(dinput,"df.dwSize=%ld\n",df->dwSize);
209         TRACE(dinput,"(df.dwObjsize=%ld)\n",df->dwObjSize);
210         TRACE(dinput,"(df.dwFlags=0x%08lx)\n",df->dwFlags);
211         TRACE(dinput,"(df.dwDataSize=%ld)\n",df->dwDataSize);
212         TRACE(dinput,"(df.dwNumObjs=%ld)\n",df->dwNumObjs);
213
214         for (i=0;i<df->dwNumObjs;i++) {
215                 char    xbuf[50];
216
217                 if (df->rgodf[i].pguid)
218                         WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
219                 else
220                         strcpy(xbuf,"<no guid>");
221                 TRACE(dinput,"df.rgodf[%d].guid %s\n",i,xbuf);
222                 TRACE(dinput,"df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
223                 TRACE(dinput,"dwType 0x%02lx,dwInstance %ld\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
224                 TRACE(dinput,"df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
225         }
226         */
227         return 0;
228 }
229
230 static HRESULT WINAPI IDirectInputDeviceA_SetCooperativeLevel(
231         LPDIRECTINPUTDEVICE32A this,HWND32 hwnd,DWORD dwflags
232 ) {
233         FIXME(dinput,"(this=%p,0x%08lx,0x%08lx): stub\n",this,(DWORD)hwnd,dwflags);
234         return 0;
235 }
236
237 static HRESULT WINAPI IDirectInputDeviceA_SetProperty(
238         LPDIRECTINPUTDEVICE32A this,REFGUID rguid,LPCDIPROPHEADER ph
239 ) {
240         char    xbuf[50];
241
242         if (HIWORD(rguid))
243                 WINE_StringFromCLSID(rguid,xbuf);
244         else
245                 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
246         TRACE(dinput,"(this=%p,%s,%p)\n",this,xbuf,ph);
247         if (!HIWORD(rguid)) {
248                 switch ((DWORD)rguid) {
249                 case DIPROP_BUFFERSIZE: {
250                         LPCDIPROPDWORD  pd = (LPCDIPROPDWORD)ph;
251
252                         TRACE(dinput,"buffersize = %ld\n",pd->dwData);
253                         break;
254                 }
255                 default:
256                         WARN(dinput,"Unknown type %ld\n",(DWORD)rguid);
257                         break;
258                 }
259         }
260         return 0;
261 }
262
263 static HRESULT WINAPI IDirectInputDeviceA_SetEventNotification(
264         LPDIRECTINPUTDEVICE32A this,HANDLE32 hnd
265 ) {
266         FIXME(dinput,"(this=%p,0x%08lx): stub\n",this,(DWORD)hnd);
267         return 0;
268 }
269
270 static HRESULT WINAPI IDirectInputDeviceA_GetDeviceData(
271         LPDIRECTINPUTDEVICE32A this,DWORD dodsize,LPDIDEVICEOBJECTDATA dod,
272         LPDWORD entries,DWORD flags
273 ) {
274   TRACE(dinput,"IDirectInputDeviceA(%p)->GetDeviceData(%ld,%p,%p(0x%08lx),0x%08lx)\n",
275         this,dodsize,dod,entries,*entries,flags);
276         return 0;
277 }
278
279
280 static HRESULT WINAPI IDirectInputDeviceA_Acquire(LPDIRECTINPUTDEVICE32A this) {
281         TRACE(dinput,"(this=%p): stub\n",this);
282         return 0;
283 }
284
285 static HRESULT WINAPI IDirectInputDeviceA_Unacquire(LPDIRECTINPUTDEVICE32A this) {
286         TRACE(dinput,"(this=%p): stub\n",this);
287         return 0;
288 }
289
290 static ULONG WINAPI IDirectInputDeviceA_Release(LPDIRECTINPUTDEVICE32A this) {
291         this->ref--;
292         if (this->ref)
293                 return this->ref;
294         HeapFree(GetProcessHeap(),0,this);
295         return 0;
296 }
297
298 static HRESULT WINAPI SysKeyboardA_SetProperty(
299         LPDIRECTINPUTDEVICE32A this,REFGUID rguid,LPCDIPROPHEADER ph
300 ) {
301         char                    xbuf[50];
302
303         if (HIWORD(rguid))
304                 WINE_StringFromCLSID(rguid,xbuf);
305         else
306                 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
307         TRACE(dinput,"(this=%p,%s,%p)\n",this,xbuf,ph);
308         TRACE(dinput,"(size=%ld,headersize=%ld,obj=%ld,how=%ld\n",
309             ph->dwSize,ph->dwHeaderSize,ph->dwObj,ph->dwHow);
310         if (!HIWORD(rguid)) {
311                 switch ((DWORD)rguid) {
312                 case DIPROP_BUFFERSIZE: {
313                         LPCDIPROPDWORD  pd = (LPCDIPROPDWORD)ph;
314
315                         TRACE(dinput,"(buffersize=%ld)\n",pd->dwData);
316                         break;
317                 }
318                 default:
319                         WARN(dinput,"Unknown type %ld\n",(DWORD)rguid);
320                         break;
321                 }
322         }
323         return 0;
324 }
325
326 static HRESULT WINAPI SysKeyboardA_GetDeviceState(
327         LPDIRECTINPUTDEVICE32A this,DWORD len,LPVOID ptr
328 ) {
329         if (len==256) {
330                 int keyc,vkey;
331
332                 memset(ptr,0,256);
333                 for (keyc=min_keycode;keyc<max_keycode;keyc++)
334                 {
335                     /* X keycode to virtual key */
336                     vkey = keyc2vkey[keyc] & 0xFF;
337                     /* The windows scancode is keyc-min_keycode */
338                     if (InputKeyStateTable[vkey]&0x80) {
339                         ((LPBYTE)ptr)[keyc-min_keycode]=0x80;
340                         ((LPBYTE)ptr)[(keyc-min_keycode)|0x80]=0x80;
341                     }
342                 }
343                 return 0;
344         }
345         WARN(dinput,"whoops, SysKeyboardA_GetDeviceState got len %ld?\n",len);
346         return 0;
347 }
348
349 static HRESULT WINAPI SysKeyboardA_GetDeviceData(
350         LPDIRECTINPUTDEVICE32A this,DWORD dodsize,LPDIDEVICEOBJECTDATA dod,
351         LPDWORD entries,DWORD flags
352 ) {
353         int                     keyc,n,vkey,xentries;
354         LPSYSKEYBOARD32A        kthis = (LPSYSKEYBOARD32A)this;
355
356         TRACE(dinput,"(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n",
357                 this,dodsize,dod,entries,entries?*entries:0,flags);
358         EVENT_WaitNetEvent(FALSE,TRUE);
359         if (entries)
360                 xentries = *entries; 
361         else
362                 xentries = 1;
363
364         n = 0;
365
366         for (keyc=min_keycode;(keyc<max_keycode) && (n<*entries);keyc++)
367         {
368                     /* X keycode to virtual key */
369                     vkey = keyc2vkey[keyc] & 0xFF;
370                     if (kthis->keystate[vkey] == (InputKeyStateTable[vkey]&0x80))
371                         continue;
372                 if (dod) {
373                         /* add an entry */
374                         dod[n].dwOfs            = keyc-min_keycode; /* scancode */
375                         dod[n].dwData           = InputKeyStateTable[vkey]&0x80;
376                         dod[n].dwTimeStamp      = 0; /* umm */
377                         dod[n].dwSequence       = 0; /* umm */
378                         n++;
379                 }
380                 if (!(flags & DIGDD_PEEK))
381                         kthis->keystate[vkey] = InputKeyStateTable[vkey]&0x80;
382                     
383         }
384         
385         if (n) fprintf(stderr,"%d entries\n",n);
386         *entries = n;
387         return 0;
388 }
389
390 static HRESULT WINAPI SysKeyboardA_Acquire(LPDIRECTINPUTDEVICE32A this) {
391         TRACE(dinput,"(this=%p): stub\n",this);
392         return 0;
393 }
394
395 static HRESULT WINAPI SysKeyboardA_Unacquire(LPDIRECTINPUTDEVICE32A this) {
396         TRACE(dinput,"(this=%p): stub\n",this);
397         return 0;
398 }
399
400 static HRESULT WINAPI IDirectInputDeviceA_QueryInterface(
401         LPDIRECTINPUTDEVICE32A this,REFIID riid,LPVOID *ppobj
402 ) {
403         char    xbuf[50];
404
405         WINE_StringFromCLSID(riid,xbuf);
406         TRACE(dinput,"(this=%p,%s,%p)\n",this,xbuf,ppobj);
407         if (!memcmp(&IID_IUnknown,riid,sizeof(*riid))) {
408                 this->lpvtbl->fnAddRef(this);
409                 *ppobj = this;
410                 return 0;
411         }
412         if (!memcmp(&IID_IDirectInputDeviceA,riid,sizeof(*riid))) {
413                 this->lpvtbl->fnAddRef(this);
414                 *ppobj = this;
415                 return 0;
416         }
417         if (!memcmp(&IID_IDirectInputDevice2A,riid,sizeof(*riid))) {
418                 this->lpvtbl->fnAddRef(this);
419                 *ppobj = this;
420                 return 0;
421         }
422         return E_FAIL;
423 }
424
425 static ULONG WINAPI IDirectInputDeviceA_AddRef(
426         LPDIRECTINPUTDEVICE32A this)
427 {
428         return ++this->ref;
429 }
430
431 static HRESULT WINAPI IDirectInputDeviceA_GetCapabilities(
432         LPDIRECTINPUTDEVICE32A this,
433         LPDIDEVCAPS lpDIDevCaps)
434 {
435         FIXME(dinput, "stub!\n");
436         return DI_OK;
437 }
438
439 static HRESULT WINAPI IDirectInputDeviceA_EnumObjects(
440         LPDIRECTINPUTDEVICE32A this,
441         LPDIENUMDEVICEOBJECTSCALLBACK32A lpCallback,
442         LPVOID lpvRef,
443         DWORD dwFlags)
444 {
445         FIXME(dinput, "stub!\n");
446 #if 0
447         if (lpCallback)
448                 lpCallback(NULL, lpvRef);
449 #endif
450         return DI_OK;
451 }
452         
453 static HRESULT WINAPI IDirectInputDeviceA_GetProperty(
454         LPDIRECTINPUTDEVICE32A this,
455         REFGUID rguid,
456         LPDIPROPHEADER pdiph)
457 {
458         FIXME(dinput, "stub!\n");
459         return DI_OK;
460 }
461
462 static HRESULT WINAPI IDirectInputDeviceA_GetObjectInfo(
463         LPDIRECTINPUTDEVICE32A this,
464         LPDIDEVICEOBJECTINSTANCE32A pdidoi,
465         DWORD dwObj,
466         DWORD dwHow)
467 {
468         FIXME(dinput, "stub!\n");
469         return DI_OK;
470 }
471         
472 static HRESULT WINAPI IDirectInputDeviceA_GetDeviceInfo(
473         LPDIRECTINPUTDEVICE32A this,
474         LPDIDEVICEINSTANCE32A pdidi)
475 {
476         FIXME(dinput, "stub!\n");
477         return DI_OK;
478 }
479         
480 static HRESULT WINAPI IDirectInputDeviceA_RunControlPanel(
481         LPDIRECTINPUTDEVICE32A this,
482         HWND32 hwndOwner,
483         DWORD dwFlags)
484 {
485         FIXME(dinput, "stub!\n");
486         return DI_OK;
487 }
488         
489 static HRESULT WINAPI IDirectInputDeviceA_Initialize(
490         LPDIRECTINPUTDEVICE32A this,
491         HINSTANCE32 hinst,
492         DWORD dwVersion,
493         REFGUID rguid)
494 {
495         FIXME(dinput, "stub!\n");
496         return DI_OK;
497 }
498         
499 /******************************************************************************
500  *      IDirectInputDevice2A
501  */
502
503 static HRESULT WINAPI IDirectInputDevice2A_CreateEffect(
504         LPDIRECTINPUTDEVICE32A this,
505         REFGUID rguid,
506         LPCDIEFFECT lpeff,
507         LPDIRECTINPUTEFFECT *ppdef,
508         LPUNKNOWN pUnkOuter)
509 {
510         FIXME(dinput, "stub!\n");
511         return DI_OK;
512 }
513
514 static HRESULT WINAPI IDirectInputDevice2A_EnumEffects(
515         LPDIRECTINPUTDEVICE32A this,
516         LPDIENUMEFFECTSCALLBACKA lpCallback,
517         LPVOID lpvRef,
518         DWORD dwFlags)
519 {
520         FIXME(dinput, "stub!\n");
521         if (lpCallback)
522                 lpCallback(NULL, lpvRef);
523         return DI_OK;
524 }
525
526 static HRESULT WINAPI IDirectInputDevice2A_GetEffectInfo(
527         LPDIRECTINPUTDEVICE32A this,
528         LPDIEFFECTINFOA lpdei,
529         REFGUID rguid)
530 {
531         FIXME(dinput, "stub!\n");
532         return DI_OK;
533 }
534
535 static HRESULT WINAPI IDirectInputDevice2A_GetForceFeedbackState(
536         LPDIRECTINPUTDEVICE32A this,
537         LPDWORD pdwOut)
538 {
539         FIXME(dinput, "stub!\n");
540         return DI_OK;
541 }
542
543 static HRESULT WINAPI IDirectInputDevice2A_SendForceFeedbackCommand(
544         LPDIRECTINPUTDEVICE32A this,
545         DWORD dwFlags)
546 {
547         FIXME(dinput, "stub!\n");
548         return DI_OK;
549 }
550
551 static HRESULT WINAPI IDirectInputDevice2A_EnumCreatedEffectObjects(
552         LPDIRECTINPUTDEVICE32A this,
553         LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback,
554         LPVOID lpvRef,
555         DWORD dwFlags)
556 {
557         FIXME(dinput, "stub!\n");
558         if (lpCallback)
559                 lpCallback(NULL, lpvRef);
560         return DI_OK;
561 }
562
563 static HRESULT WINAPI IDirectInputDevice2A_Escape(
564         LPDIRECTINPUTDEVICE32A this,
565         LPDIEFFESCAPE lpDIEEsc)
566 {
567         FIXME(dinput, "stub!\n");
568         return DI_OK;
569 }
570
571 static HRESULT WINAPI IDirectInputDevice2A_Poll(
572         LPDIRECTINPUTDEVICE32A this)
573 {
574         FIXME(dinput, "stub!\n");
575         return DI_OK;
576 }
577
578 static HRESULT WINAPI IDirectInputDevice2A_SendDeviceData(
579         LPDIRECTINPUTDEVICE32A this,
580         DWORD cbObjectData,
581         LPDIDEVICEOBJECTDATA rgdod,
582         LPDWORD pdwInOut,
583         DWORD dwFlags)
584 {
585         FIXME(dinput, "stub!\n");
586         return DI_OK;
587 }
588
589 /******************************************************************************
590  *      SysMouseA (DInput Mouse support)
591  */
592
593 /******************************************************************************
594   *     SetDataFormat : the application can choose the format of the data
595   *   the device driver sends back with GetDeviceState.
596   *
597   *   For the moment, only the "standard" configuration (c_dfDIMouse) is supported
598   *   in absolute and relative mode.
599   */
600 static HRESULT WINAPI SysMouseA_SetDataFormat(
601         LPDIRECTINPUTDEVICE32A this,LPCDIDATAFORMAT df
602 ) {
603   int i;
604   LPSYSMOUSE32A mthis = (LPSYSMOUSE32A) this;
605   
606   TRACE(dinput,"(this=%p,%p)\n",this,df);
607
608   TRACE(dinput,"(df.dwSize=%ld)\n",df->dwSize);
609   TRACE(dinput,"(df.dwObjsize=%ld)\n",df->dwObjSize);
610   TRACE(dinput,"(df.dwFlags=0x%08lx)\n",df->dwFlags);
611   TRACE(dinput,"(df.dwDataSize=%ld)\n",df->dwDataSize);
612   TRACE(dinput,"(df.dwNumObjs=%ld)\n",df->dwNumObjs);
613
614   for (i=0;i<df->dwNumObjs;i++) {
615     char        xbuf[50];
616     
617     if (df->rgodf[i].pguid)
618       WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
619     else
620       strcpy(xbuf,"<no guid>");
621     TRACE(dinput,"df.rgodf[%d].guid %s (%p)\n",i,xbuf, df->rgodf[i].pguid);
622     TRACE(dinput,"df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
623     TRACE(dinput,"dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
624     TRACE(dinput,"df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
625   }
626
627   /* Check size of data format to prevent crashes if the applications
628      sends a smaller buffer */
629   if (df->dwDataSize != sizeof(struct DIMOUSESTATE)) {
630     FIXME(dinput, "non-standard mouse configuration not supported yet.");
631     return DIERR_INVALIDPARAM;
632   }
633   
634   /* For the moment, ignore these fields and return always as if
635      c_dfDIMouse was passed as format... */
636   if (df->dwFlags == DIDF_ABSAXIS)
637     mthis->absolute = 1;
638   else {
639     DWORD rx, ry;
640     
641     /* We need to get the initial "previous" position to be able
642        to return deltas */
643     mthis->absolute = 0;
644   
645     /* Get the mouse position */
646     EVENT_QueryPointer(&rx, &ry, NULL);
647
648     /* Fill the initial mouse state structure */
649     mthis->prevX = rx;
650     mthis->prevY = ry;
651   }
652   
653   return 0;
654 }
655
656 /******************************************************************************
657   *     GetDeviceState : returns the "state" of the mouse.
658   *
659   *   For the moment, only the "standard" return structure (DIMOUSESTATE) is
660   *   supported.
661   */
662 static HRESULT WINAPI SysMouseA_GetDeviceState(
663         LPDIRECTINPUTDEVICE32A this,DWORD len,LPVOID ptr
664 ) {
665   DWORD rx, ry, state;
666   struct DIMOUSESTATE *mstate = (struct DIMOUSESTATE *) ptr;
667   LPSYSMOUSE32A mthis = (LPSYSMOUSE32A) this;
668   
669   TRACE(dinput,"(this=%p,0x%08lx,%p): \n",this,len,ptr);
670   
671   /* Check if the buffer is big enough */
672   if (len < sizeof(struct DIMOUSESTATE)) {
673     FIXME(dinput, "unsupported state structure.");
674     return DIERR_INVALIDPARAM;
675   }
676   
677   /* Get the mouse position */
678   EVENT_QueryPointer(&rx, &ry, &state);
679   TRACE(dinput,"(X:%d - Y:%d)\n", rx, ry);
680
681   /* Fill the mouse state structure */
682   if (mthis->absolute) {
683     mstate->lX = rx;
684     mstate->lY = ry;
685   } else {
686     mstate->lX = rx - mthis->prevX;
687     mstate->lY = ry - mthis->prevY;
688     /* Fill the previous positions */
689     mthis->prevX = rx;
690     mthis->prevY = ry;
691   }
692   mstate->lZ = 0;
693   mstate->rgbButtons[0] = (state & MK_LBUTTON ? 0xFF : 0x00);
694   mstate->rgbButtons[1] = (state & MK_RBUTTON ? 0xFF : 0x00);
695   mstate->rgbButtons[2] = (state & MK_MBUTTON ? 0xFF : 0x00);
696   mstate->rgbButtons[3] = 0x00;
697   
698   return 0;
699 }
700
701
702
703 static IDirectInputDeviceA_VTable SysKeyboardAvt={
704         IDirectInputDeviceA_QueryInterface,
705         IDirectInputDeviceA_AddRef,
706         IDirectInputDeviceA_Release,
707         IDirectInputDeviceA_GetCapabilities,
708         IDirectInputDeviceA_EnumObjects,
709         IDirectInputDeviceA_GetProperty,
710         SysKeyboardA_SetProperty,
711         SysKeyboardA_Acquire,
712         SysKeyboardA_Unacquire,
713         SysKeyboardA_GetDeviceState,
714         SysKeyboardA_GetDeviceData,
715         IDirectInputDeviceA_SetDataFormat,
716         IDirectInputDeviceA_SetEventNotification,
717         IDirectInputDeviceA_SetCooperativeLevel,
718         IDirectInputDeviceA_GetObjectInfo,
719         IDirectInputDeviceA_GetDeviceInfo,
720         IDirectInputDeviceA_RunControlPanel,
721         IDirectInputDeviceA_Initialize,
722         IDirectInputDevice2A_CreateEffect,
723         IDirectInputDevice2A_EnumEffects,
724         IDirectInputDevice2A_GetEffectInfo,
725         IDirectInputDevice2A_GetForceFeedbackState,
726         IDirectInputDevice2A_SendForceFeedbackCommand,
727         IDirectInputDevice2A_EnumCreatedEffectObjects,
728         IDirectInputDevice2A_Escape,
729         IDirectInputDevice2A_Poll,
730         IDirectInputDevice2A_SendDeviceData,
731 };
732
733 static IDirectInputDeviceA_VTable SysMouseAvt={
734         IDirectInputDeviceA_QueryInterface,
735         IDirectInputDeviceA_AddRef,
736         IDirectInputDeviceA_Release,
737         IDirectInputDeviceA_GetCapabilities,
738         IDirectInputDeviceA_EnumObjects,
739         IDirectInputDeviceA_GetProperty,
740         IDirectInputDeviceA_SetProperty,
741         IDirectInputDeviceA_Acquire,
742         IDirectInputDeviceA_Unacquire,
743         SysMouseA_GetDeviceState,
744         IDirectInputDeviceA_GetDeviceData,
745         SysMouseA_SetDataFormat,
746         IDirectInputDeviceA_SetEventNotification,
747         IDirectInputDeviceA_SetCooperativeLevel,
748         IDirectInputDeviceA_GetObjectInfo,
749         IDirectInputDeviceA_GetDeviceInfo,
750         IDirectInputDeviceA_RunControlPanel,
751         IDirectInputDeviceA_Initialize,
752         IDirectInputDevice2A_CreateEffect,
753         IDirectInputDevice2A_EnumEffects,
754         IDirectInputDevice2A_GetEffectInfo,
755         IDirectInputDevice2A_GetForceFeedbackState,
756         IDirectInputDevice2A_SendForceFeedbackCommand,
757         IDirectInputDevice2A_EnumCreatedEffectObjects,
758         IDirectInputDevice2A_Escape,
759         IDirectInputDevice2A_Poll,
760         IDirectInputDevice2A_SendDeviceData,
761 };