Added registry support to the server.
[wine.git] / windows / dinput.c
blobc2c4f565eac8988999e47463af102e97cc339771
1 /* DirectInput
3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998,1999 Lionel Ulmer
6 */
7 /* Status:
9 * - Tomb Raider 2 Demo:
10 * Playable using keyboard only.
11 * - WingCommander Prophecy Demo:
12 * Doesn't get Input Focus.
14 * - Fallout : works great in X and DGA mode
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.)
21 #include "config.h"
22 #include <string.h>
23 #include <time.h>
24 #include <unistd.h>
25 #include <assert.h>
26 #ifdef HAVE_SYS_SIGNAL_H
27 # include <sys/signal.h>
28 #endif
29 #include <sys/time.h>
30 #include <sys/fcntl.h>
31 #include <sys/ioctl.h>
32 #include <errno.h>
33 #ifdef HAVE_SYS_ERRNO_H
34 # include <sys/errno.h>
35 #endif
36 #ifdef HAVE_LINUX_JOYSTICK_H
37 # include <linux/joystick.h>
38 # define JOYDEV "/dev/js0"
39 #endif
40 #include "wine/obj_base.h"
41 #include "debugtools.h"
42 #include "dinput.h"
43 #include "display.h"
44 #include "input.h"
45 #include "keyboard.h"
46 #include "message.h"
47 #include "mouse.h"
48 #include "sysmetrics.h"
49 #include "winbase.h"
50 #include "winerror.h"
51 #include "winuser.h"
53 DEFAULT_DEBUG_CHANNEL(dinput)
56 extern BYTE InputKeyStateTable[256];
57 extern int min_keycode, max_keycode;
58 extern WORD keyc2vkey[256];
60 static ICOM_VTABLE(IDirectInputA) ddiavt;
61 static ICOM_VTABLE(IDirectInputDevice2A) SysKeyboardAvt;
62 static ICOM_VTABLE(IDirectInputDevice2A) SysMouseAvt;
64 typedef struct IDirectInputAImpl IDirectInputAImpl;
65 typedef struct IDirectInputDevice2AImpl IDirectInputDevice2AImpl;
66 typedef struct SysKeyboardAImpl SysKeyboardAImpl;
67 typedef struct SysMouseAImpl SysMouseAImpl;
69 struct IDirectInputDevice2AImpl
71 ICOM_VFIELD(IDirectInputDevice2A);
72 DWORD ref;
73 GUID guid;
76 struct SysKeyboardAImpl
78 /* IDirectInputDevice2AImpl */
79 ICOM_VFIELD(IDirectInputDevice2A);
80 DWORD ref;
81 GUID guid;
82 /* SysKeyboardAImpl */
83 BYTE keystate[256];
86 #ifdef HAVE_LINUX_22_JOYSTICK_API
87 typedef struct JoystickAImpl JoystickAImpl;
88 static ICOM_VTABLE(IDirectInputDevice2A) JoystickAvt;
89 struct JoystickAImpl
91 /* IDirectInputDevice2AImpl */
92 ICOM_VFIELD(IDirectInputDevice2A);
93 DWORD ref;
94 GUID guid;
96 /* joystick private */
97 int joyfd;
98 LPDIDATAFORMAT df;
99 HANDLE hEvent;
100 LONG lMin,lMax,deadzone;
101 LPDIDEVICEOBJECTDATA data_queue;
102 int queue_pos, queue_len;
103 DIJOYSTATE js;
105 #endif
107 struct SysMouseAImpl
109 /* IDirectInputDevice2AImpl */
110 ICOM_VFIELD(IDirectInputDevice2A);
111 DWORD ref;
112 GUID guid;
114 LPDIDATAFORMAT df;
115 /* SysMouseAImpl */
116 BYTE absolute;
117 /* Previous position for relative moves */
118 LONG prevX, prevY;
119 LPMOUSE_EVENT_PROC prev_handler;
120 HWND win;
121 DWORD win_centerX, win_centerY;
122 LPDIDEVICEOBJECTDATA data_queue;
123 int queue_pos, queue_len;
124 int need_warp;
125 int acquired;
126 HANDLE hEvent;
127 CRITICAL_SECTION crit;
130 static int evsequence=0;
133 /* UIDs for Wine "drivers".
134 When enumerating each device supporting DInput, they have two UIDs :
135 - the 'windows' UID
136 - a vendor UID */
137 #ifdef HAVE_LINUX_22_JOYSTICK_API
138 static GUID DInput_Wine_Joystick_GUID = { /* 9e573ed9-7734-11d2-8d4a-23903fb6bdf7 */
139 0x9e573ed9,
140 0x7734,
141 0x11d2,
142 {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
144 #endif
145 static GUID DInput_Wine_Mouse_GUID = { /* 9e573ed8-7734-11d2-8d4a-23903fb6bdf7 */
146 0x9e573ed8,
147 0x7734,
148 0x11d2,
149 {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
151 static GUID DInput_Wine_Keyboard_GUID = { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */
152 0x0ab8648a,
153 0x7735,
154 0x11d2,
155 {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41}
158 /* FIXME: This is ugly and not thread safe :/ */
159 static IDirectInputDevice2A* current_lock = NULL;
161 /******************************************************************************
162 * Various debugging tools
164 static void _dump_cooperativelevel(DWORD dwFlags) {
165 int i;
166 const struct {
167 DWORD mask;
168 char *name;
169 } flags[] = {
170 #define FE(x) { x, #x},
171 FE(DISCL_BACKGROUND)
172 FE(DISCL_EXCLUSIVE)
173 FE(DISCL_FOREGROUND)
174 FE(DISCL_NONEXCLUSIVE)
176 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
177 if (flags[i].mask & dwFlags)
178 DPRINTF("%s ",flags[i].name);
179 DPRINTF("\n");
182 struct IDirectInputAImpl
184 ICOM_VFIELD(IDirectInputA);
185 DWORD ref;
188 /******************************************************************************
189 * DirectInputCreate32A
191 HRESULT WINAPI DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA *ppDI, LPUNKNOWN punkOuter)
193 IDirectInputAImpl* This;
194 TRACE("(0x%08lx,%04lx,%p,%p)\n",
195 (DWORD)hinst,dwVersion,ppDI,punkOuter
197 This = (IDirectInputAImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl));
198 This->ref = 1;
199 ICOM_VTBL(This) = &ddiavt;
200 *ppDI=(IDirectInputA*)This;
201 return 0;
203 /******************************************************************************
204 * IDirectInputA_EnumDevices
206 static HRESULT WINAPI IDirectInputAImpl_EnumDevices(
207 LPDIRECTINPUTA iface, DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback,
208 LPVOID pvRef, DWORD dwFlags
211 ICOM_THIS(IDirectInputAImpl,iface);
212 DIDEVICEINSTANCEA devInstance;
213 int ret;
215 TRACE("(this=%p,0x%04lx,%p,%p,%04lx)\n", This, dwDevType, lpCallback, pvRef, dwFlags);
217 devInstance.dwSize = sizeof(DIDEVICEINSTANCEA);
218 if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_KEYBOARD)) {
219 /* Return keyboard */
220 devInstance.guidInstance = GUID_SysKeyboard;/* DInput's GUID */
221 devInstance.guidProduct = DInput_Wine_Keyboard_GUID; /* Vendor's GUID */
222 devInstance.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8);
223 strcpy(devInstance.tszInstanceName, "Keyboard");
224 strcpy(devInstance.tszProductName, "Wine Keyboard");
226 ret = lpCallback(&devInstance, pvRef);
227 TRACE("Keyboard registered\n");
228 if (ret == DIENUM_STOP)
229 return 0;
232 if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_MOUSE)) {
233 /* Return mouse */
234 devInstance.guidInstance = GUID_SysMouse;/* DInput's GUID */
235 devInstance.guidProduct = DInput_Wine_Mouse_GUID; /* Vendor's GUID */
236 devInstance.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_UNKNOWN << 8);
237 strcpy(devInstance.tszInstanceName, "Mouse");
238 strcpy(devInstance.tszProductName, "Wine Mouse");
240 ret = lpCallback(&devInstance, pvRef);
241 TRACE("Mouse registered\n");
242 if (ret == DIENUM_STOP)
243 return 0;
245 if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_JOYSTICK)) {
246 /* check whether we have a joystick */
247 #ifdef HAVE_LINUX_22_JOYSTICK_API
248 if ( (access(JOYDEV,O_RDONLY)!=-1) ||
249 (errno!=ENODEV && errno!=ENOENT)
251 /* Return joystick */
252 devInstance.guidInstance = GUID_Joystick;
253 devInstance.guidProduct = DInput_Wine_Joystick_GUID;
254 /* we only support traditional joysticks for now */
255 devInstance.dwDevType = DIDEVTYPE_JOYSTICK | DIDEVTYPEJOYSTICK_TRADITIONAL;
256 strcpy(devInstance.tszInstanceName, "Joystick");
257 /* ioctl JSIOCGNAME(len) */
258 strcpy(devInstance.tszProductName, "Wine Joystick");
260 ret = lpCallback(&devInstance,pvRef);
261 TRACE("Joystick registered\n");
262 if (ret == DIENUM_STOP)
263 return 0;
265 #endif
267 return 0;
270 static ULONG WINAPI IDirectInputAImpl_AddRef(LPDIRECTINPUTA iface)
272 ICOM_THIS(IDirectInputAImpl,iface);
273 return ++(This->ref);
276 static ULONG WINAPI IDirectInputAImpl_Release(LPDIRECTINPUTA iface)
278 ICOM_THIS(IDirectInputAImpl,iface);
279 if (!(--This->ref)) {
280 HeapFree(GetProcessHeap(),0,This);
281 return 0;
283 return This->ref;
286 static HRESULT WINAPI IDirectInputAImpl_CreateDevice(
287 LPDIRECTINPUTA iface,REFGUID rguid,LPDIRECTINPUTDEVICEA* pdev,
288 LPUNKNOWN punk
290 ICOM_THIS(IDirectInputAImpl,iface);
291 char xbuf[50];
293 WINE_StringFromCLSID(rguid,xbuf);
294 FIXME("(this=%p,%s,%p,%p): stub\n",This,xbuf,pdev,punk);
295 if ((!memcmp(&GUID_SysKeyboard,rguid,sizeof(GUID_SysKeyboard))) || /* Generic Keyboard */
296 (!memcmp(&DInput_Wine_Keyboard_GUID,rguid,sizeof(GUID_SysKeyboard)))) { /* Wine Keyboard */
297 SysKeyboardAImpl* newDevice;
298 newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysKeyboardAImpl));
299 newDevice->ref = 1;
300 ICOM_VTBL(newDevice) = &SysKeyboardAvt;
301 memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
302 memset(newDevice->keystate,0,256);
303 *pdev=(IDirectInputDeviceA*)newDevice;
304 return DI_OK;
306 if ((!memcmp(&GUID_SysMouse,rguid,sizeof(GUID_SysMouse))) || /* Generic Mouse */
307 (!memcmp(&DInput_Wine_Mouse_GUID,rguid,sizeof(GUID_SysMouse)))) { /* Wine Mouse */
308 SysMouseAImpl* newDevice;
309 newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysMouseAImpl));
310 newDevice->ref = 1;
311 ICOM_VTBL(newDevice) = &SysMouseAvt;
312 InitializeCriticalSection(&(newDevice->crit));
313 MakeCriticalSectionGlobal(&(newDevice->crit));
314 memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
315 *pdev=(IDirectInputDeviceA*)newDevice;
316 return DI_OK;
318 #ifdef HAVE_LINUX_22_JOYSTICK_API
319 if ((!memcmp(&GUID_Joystick,rguid,sizeof(GUID_Joystick))) ||
320 (!memcmp(&DInput_Wine_Joystick_GUID,rguid,sizeof(GUID_Joystick)))) {
321 JoystickAImpl* newDevice;
322 newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(JoystickAImpl));
323 newDevice->ref = 1;
324 ICOM_VTBL(newDevice) = &JoystickAvt;
325 newDevice->joyfd = -1;
326 memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
327 *pdev=(IDirectInputDeviceA*)newDevice;
328 return DI_OK;
330 #endif
331 return E_FAIL;
334 static HRESULT WINAPI IDirectInputAImpl_QueryInterface(
335 LPDIRECTINPUTA iface,REFIID riid,LPVOID *ppobj
337 ICOM_THIS(IDirectInputAImpl,iface);
338 char xbuf[50];
340 WINE_StringFromCLSID(riid,xbuf);
341 TRACE("(this=%p,%s,%p)\n",This,xbuf,ppobj);
342 if (!memcmp(&IID_IUnknown,riid,sizeof(*riid))) {
343 IDirectInputA_AddRef(iface);
344 *ppobj = This;
345 return 0;
347 if (!memcmp(&IID_IDirectInputA,riid,sizeof(*riid))) {
348 IDirectInputA_AddRef(iface);
349 *ppobj = This;
350 return 0;
352 return E_FAIL;
355 static HRESULT WINAPI IDirectInputAImpl_Initialize(
356 LPDIRECTINPUTA iface,HINSTANCE hinst,DWORD x
358 return DIERR_ALREADYINITIALIZED;
361 static HRESULT WINAPI IDirectInputAImpl_GetDeviceStatus(LPDIRECTINPUTA iface,
362 REFGUID rguid) {
363 ICOM_THIS(IDirectInputAImpl,iface);
364 char xbuf[50];
366 WINE_StringFromCLSID(rguid,xbuf);
367 FIXME("(%p)->(%s): stub\n",This,xbuf);
369 return DI_OK;
372 static HRESULT WINAPI IDirectInputAImpl_RunControlPanel(LPDIRECTINPUTA iface,
373 HWND hwndOwner,
374 DWORD dwFlags) {
375 ICOM_THIS(IDirectInputAImpl,iface);
376 FIXME("(%p)->(%08lx,%08lx): stub\n",This, (DWORD) hwndOwner, dwFlags);
378 return DI_OK;
381 static ICOM_VTABLE(IDirectInputA) ddiavt =
383 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
384 IDirectInputAImpl_QueryInterface,
385 IDirectInputAImpl_AddRef,
386 IDirectInputAImpl_Release,
387 IDirectInputAImpl_CreateDevice,
388 IDirectInputAImpl_EnumDevices,
389 IDirectInputAImpl_GetDeviceStatus,
390 IDirectInputAImpl_RunControlPanel,
391 IDirectInputAImpl_Initialize
394 /******************************************************************************
395 * IDirectInputDeviceA
398 static HRESULT WINAPI IDirectInputDevice2AImpl_SetDataFormat(
399 LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df
402 int i;
403 TRACE(dinput,"(this=%p,%p)\n",This,df);
405 TRACE(dinput,"df.dwSize=%ld\n",df->dwSize);
406 TRACE(dinput,"(df.dwObjsize=%ld)\n",df->dwObjSize);
407 TRACE(dinput,"(df.dwFlags=0x%08lx)\n",df->dwFlags);
408 TRACE(dinput,"(df.dwDataSize=%ld)\n",df->dwDataSize);
409 TRACE(dinput,"(df.dwNumObjs=%ld)\n",df->dwNumObjs);
411 for (i=0;i<df->dwNumObjs;i++) {
412 char xbuf[50];
414 if (df->rgodf[i].pguid)
415 WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
416 else
417 strcpy(xbuf,"<no guid>");
418 TRACE(dinput,"df.rgodf[%d].guid %s\n",i,xbuf);
419 TRACE(dinput,"df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
420 TRACE(dinput,"dwType 0x%02lx,dwInstance %ld\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
421 TRACE(dinput,"df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
424 return 0;
427 static HRESULT WINAPI IDirectInputDevice2AImpl_SetCooperativeLevel(
428 LPDIRECTINPUTDEVICE2A iface,HWND hwnd,DWORD dwflags
430 ICOM_THIS(IDirectInputDevice2AImpl,iface);
431 FIXME("(this=%p,0x%08lx,0x%08lx): stub\n",This,(DWORD)hwnd,dwflags);
432 if (TRACE_ON(dinput))
433 _dump_cooperativelevel(dwflags);
434 return 0;
437 static HRESULT WINAPI IDirectInputDevice2AImpl_SetEventNotification(
438 LPDIRECTINPUTDEVICE2A iface,HANDLE hnd
440 ICOM_THIS(IDirectInputDevice2AImpl,iface);
441 FIXME("(this=%p,0x%08lx): stub\n",This,(DWORD)hnd);
442 return 0;
445 static ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE2A iface)
447 ICOM_THIS(IDirectInputDevice2AImpl,iface);
448 This->ref--;
449 if (This->ref)
450 return This->ref;
451 HeapFree(GetProcessHeap(),0,This);
452 return 0;
455 static HRESULT WINAPI SysKeyboardAImpl_SetProperty(
456 LPDIRECTINPUTDEVICE2A iface,REFGUID rguid,LPCDIPROPHEADER ph
459 ICOM_THIS(SysKeyboardAImpl,iface);
460 char xbuf[50];
462 if (HIWORD(rguid))
463 WINE_StringFromCLSID(rguid,xbuf);
464 else
465 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
466 TRACE("(this=%p,%s,%p)\n",This,xbuf,ph);
467 TRACE("(size=%ld,headersize=%ld,obj=%ld,how=%ld\n",
468 ph->dwSize,ph->dwHeaderSize,ph->dwObj,ph->dwHow);
469 if (!HIWORD(rguid)) {
470 switch ((DWORD)rguid) {
471 case (DWORD) DIPROP_BUFFERSIZE: {
472 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
474 TRACE("(buffersize=%ld)\n",pd->dwData);
475 break;
477 default:
478 WARN("Unknown type %ld\n",(DWORD)rguid);
479 break;
482 return 0;
485 static HRESULT WINAPI SysKeyboardAImpl_GetDeviceState(
486 LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr
489 return KEYBOARD_Driver->pGetDIState(len, ptr)?DI_OK:E_FAIL;
492 static HRESULT WINAPI SysKeyboardAImpl_GetDeviceData(
493 LPDIRECTINPUTDEVICE2A iface,DWORD dodsize,LPDIDEVICEOBJECTDATA dod,
494 LPDWORD entries,DWORD flags
497 ICOM_THIS(SysKeyboardAImpl,iface);
498 HRESULT ret;
499 int i;
501 TRACE("(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n",
502 This,dodsize,dod,entries,entries?*entries:0,flags);
504 ret=KEYBOARD_Driver->pGetDIData(
505 This->keystate, dodsize, dod, entries, flags)?DI_OK:E_FAIL;
506 for (i=0;i<*entries;i++) {
507 dod[i].dwTimeStamp = time(NULL);
508 dod[i].dwSequence = evsequence++;
510 return ret;
513 static HRESULT WINAPI SysKeyboardAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface)
515 ICOM_THIS(SysKeyboardAImpl,iface);
516 TRACE("(this=%p): stub\n",This);
517 return 0;
520 static HRESULT WINAPI SysKeyboardAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface)
522 ICOM_THIS(SysKeyboardAImpl,iface);
523 TRACE("(this=%p): stub\n",This);
524 return 0;
527 static HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface(
528 LPDIRECTINPUTDEVICE2A iface,REFIID riid,LPVOID *ppobj
531 ICOM_THIS(IDirectInputDevice2AImpl,iface);
532 char xbuf[50];
534 WINE_StringFromCLSID(riid,xbuf);
535 TRACE("(this=%p,%s,%p)\n",This,xbuf,ppobj);
536 if (!memcmp(&IID_IUnknown,riid,sizeof(*riid))) {
537 IDirectInputDevice2_AddRef(iface);
538 *ppobj = This;
539 return 0;
541 if (!memcmp(&IID_IDirectInputDeviceA,riid,sizeof(*riid))) {
542 IDirectInputDevice2_AddRef(iface);
543 *ppobj = This;
544 return 0;
546 if (!memcmp(&IID_IDirectInputDevice2A,riid,sizeof(*riid))) {
547 IDirectInputDevice2_AddRef(iface);
548 *ppobj = This;
549 return 0;
551 return E_FAIL;
554 static ULONG WINAPI IDirectInputDevice2AImpl_AddRef(
555 LPDIRECTINPUTDEVICE2A iface)
557 ICOM_THIS(IDirectInputDevice2AImpl,iface);
558 return ++This->ref;
561 static HRESULT WINAPI IDirectInputDevice2AImpl_GetCapabilities(
562 LPDIRECTINPUTDEVICE2A iface,
563 LPDIDEVCAPS lpDIDevCaps)
565 lpDIDevCaps->dwFlags = DIDC_ATTACHED;
566 FIXME("stub!\n");
567 return DI_OK;
570 static HRESULT WINAPI IDirectInputDevice2AImpl_EnumObjects(
571 LPDIRECTINPUTDEVICE2A iface,
572 LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback,
573 LPVOID lpvRef,
574 DWORD dwFlags)
576 FIXME("stub!\n");
577 #if 0
578 if (lpCallback)
579 lpCallback(NULL, lpvRef);
580 #endif
581 return DI_OK;
584 static HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty(
585 LPDIRECTINPUTDEVICE2A iface,
586 REFGUID rguid,
587 LPDIPROPHEADER pdiph)
589 FIXME("stub!\n");
590 return DI_OK;
593 static HRESULT WINAPI IDirectInputDevice2AImpl_GetObjectInfo(
594 LPDIRECTINPUTDEVICE2A iface,
595 LPDIDEVICEOBJECTINSTANCEA pdidoi,
596 DWORD dwObj,
597 DWORD dwHow)
599 FIXME("stub!\n");
600 return DI_OK;
603 static HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceInfo(
604 LPDIRECTINPUTDEVICE2A iface,
605 LPDIDEVICEINSTANCEA pdidi)
607 FIXME("stub!\n");
608 return DI_OK;
611 static HRESULT WINAPI IDirectInputDevice2AImpl_RunControlPanel(
612 LPDIRECTINPUTDEVICE2A iface,
613 HWND hwndOwner,
614 DWORD dwFlags)
616 FIXME("stub!\n");
617 return DI_OK;
620 static HRESULT WINAPI IDirectInputDevice2AImpl_Initialize(
621 LPDIRECTINPUTDEVICE2A iface,
622 HINSTANCE hinst,
623 DWORD dwVersion,
624 REFGUID rguid)
626 FIXME("stub!\n");
627 return DI_OK;
630 /******************************************************************************
631 * IDirectInputDevice2A
634 static HRESULT WINAPI IDirectInputDevice2AImpl_CreateEffect(
635 LPDIRECTINPUTDEVICE2A iface,
636 REFGUID rguid,
637 LPCDIEFFECT lpeff,
638 LPDIRECTINPUTEFFECT *ppdef,
639 LPUNKNOWN pUnkOuter)
641 FIXME("stub!\n");
642 return DI_OK;
645 static HRESULT WINAPI IDirectInputDevice2AImpl_EnumEffects(
646 LPDIRECTINPUTDEVICE2A iface,
647 LPDIENUMEFFECTSCALLBACKA lpCallback,
648 LPVOID lpvRef,
649 DWORD dwFlags)
651 FIXME("stub!\n");
652 if (lpCallback)
653 lpCallback(NULL, lpvRef);
654 return DI_OK;
657 static HRESULT WINAPI IDirectInputDevice2AImpl_GetEffectInfo(
658 LPDIRECTINPUTDEVICE2A iface,
659 LPDIEFFECTINFOA lpdei,
660 REFGUID rguid)
662 FIXME("stub!\n");
663 return DI_OK;
666 static HRESULT WINAPI IDirectInputDevice2AImpl_GetForceFeedbackState(
667 LPDIRECTINPUTDEVICE2A iface,
668 LPDWORD pdwOut)
670 FIXME("stub!\n");
671 return DI_OK;
674 static HRESULT WINAPI IDirectInputDevice2AImpl_SendForceFeedbackCommand(
675 LPDIRECTINPUTDEVICE2A iface,
676 DWORD dwFlags)
678 FIXME("stub!\n");
679 return DI_OK;
682 static HRESULT WINAPI IDirectInputDevice2AImpl_EnumCreatedEffectObjects(
683 LPDIRECTINPUTDEVICE2A iface,
684 LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback,
685 LPVOID lpvRef,
686 DWORD dwFlags)
688 FIXME("stub!\n");
689 if (lpCallback)
690 lpCallback(NULL, lpvRef);
691 return DI_OK;
694 static HRESULT WINAPI IDirectInputDevice2AImpl_Escape(
695 LPDIRECTINPUTDEVICE2A iface,
696 LPDIEFFESCAPE lpDIEEsc)
698 FIXME("stub!\n");
699 return DI_OK;
702 static HRESULT WINAPI IDirectInputDevice2AImpl_Poll(
703 LPDIRECTINPUTDEVICE2A iface)
705 FIXME("stub!\n");
706 return DI_OK;
709 static HRESULT WINAPI IDirectInputDevice2AImpl_SendDeviceData(
710 LPDIRECTINPUTDEVICE2A iface,
711 DWORD cbObjectData,
712 LPDIDEVICEOBJECTDATA rgdod,
713 LPDWORD pdwInOut,
714 DWORD dwFlags)
716 FIXME("stub!\n");
717 return DI_OK;
720 /******************************************************************************
721 * SysMouseA (DInput Mouse support)
724 /******************************************************************************
725 * Release : release the mouse buffer.
727 static ULONG WINAPI SysMouseAImpl_Release(LPDIRECTINPUTDEVICE2A iface)
729 ICOM_THIS(SysMouseAImpl,iface);
731 This->ref--;
732 if (This->ref)
733 return This->ref;
735 /* Free the data queue */
736 if (This->data_queue != NULL)
737 HeapFree(GetProcessHeap(),0,This->data_queue);
739 /* Install the previous event handler (in case of releasing an aquired
740 mouse device) */
741 if (This->prev_handler != NULL)
742 MOUSE_Enable(This->prev_handler);
743 DeleteCriticalSection(&(This->crit));
745 HeapFree(GetProcessHeap(),0,This);
746 return 0;
750 /******************************************************************************
751 * SetCooperativeLevel : store the window in which we will do our
752 * grabbing.
754 static HRESULT WINAPI SysMouseAImpl_SetCooperativeLevel(
755 LPDIRECTINPUTDEVICE2A iface,HWND hwnd,DWORD dwflags
758 ICOM_THIS(SysMouseAImpl,iface);
760 TRACE("(this=%p,0x%08lx,0x%08lx): stub\n",This,(DWORD)hwnd,dwflags);
762 if (TRACE_ON(dinput))
763 _dump_cooperativelevel(dwflags);
765 /* Store the window which asks for the mouse */
766 This->win = hwnd;
768 return 0;
772 /******************************************************************************
773 * SetDataFormat : the application can choose the format of the data
774 * the device driver sends back with GetDeviceState.
776 * For the moment, only the "standard" configuration (c_dfDIMouse) is supported
777 * in absolute and relative mode.
779 static HRESULT WINAPI SysMouseAImpl_SetDataFormat(
780 LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df
783 ICOM_THIS(SysMouseAImpl,iface);
784 int i;
786 TRACE("(this=%p,%p)\n",This,df);
788 TRACE("(df.dwSize=%ld)\n",df->dwSize);
789 TRACE("(df.dwObjsize=%ld)\n",df->dwObjSize);
790 TRACE("(df.dwFlags=0x%08lx)\n",df->dwFlags);
791 TRACE("(df.dwDataSize=%ld)\n",df->dwDataSize);
792 TRACE("(df.dwNumObjs=%ld)\n",df->dwNumObjs);
794 for (i=0;i<df->dwNumObjs;i++) {
795 char xbuf[50];
797 if (df->rgodf[i].pguid)
798 WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
799 else
800 strcpy(xbuf,"<no guid>");
801 TRACE("df.rgodf[%d].guid %s (%p)\n",i,xbuf, df->rgodf[i].pguid);
802 TRACE("df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
803 TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
804 TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
807 /* Check size of data format to prevent crashes if the applications
808 sends a smaller buffer */
809 if (df->dwDataSize != sizeof(struct DIMOUSESTATE)) {
810 FIXME("non-standard mouse configuration not supported yet.");
811 return DIERR_INVALIDPARAM;
814 /* For the moment, ignore these fields and return always as if
815 c_dfDIMouse was passed as format... */
817 /* Check if the mouse is in absolute or relative mode */
818 if (df->dwFlags == DIDF_ABSAXIS)
819 This->absolute = 1;
820 else if (df->dwFlags == DIDF_RELAXIS)
821 This->absolute = 0;
822 else
823 ERR("Neither absolute nor relative flag set.");
825 This->df = HeapAlloc(GetProcessHeap(),0,df->dwSize+(df->dwNumObjs*df->dwObjSize));
826 memcpy(This->df,df,df->dwSize+(df->dwNumObjs*df->dwObjSize));
827 return 0;
830 #define GEN_EVENT(offset,data,xtime,seq) \
832 if (This->queue_pos < This->queue_len) { \
833 This->data_queue[This->queue_pos].dwOfs = offset; \
834 This->data_queue[This->queue_pos].dwData = data; \
835 This->data_queue[This->queue_pos].dwTimeStamp = xtime; \
836 This->data_queue[This->queue_pos].dwSequence = seq; \
837 This->queue_pos++; \
842 /* Our private mouse event handler */
843 static void WINAPI dinput_mouse_event( DWORD dwFlags, DWORD dx, DWORD dy,
844 DWORD cButtons, DWORD dwExtraInfo )
846 DWORD posX, posY, keyState, xtime, extra;
847 SysMouseAImpl* This = (SysMouseAImpl*) current_lock;
849 EnterCriticalSection(&(This->crit));
850 /* Mouse moved -> send event if asked */
851 if (This->hEvent)
852 SetEvent(This->hEvent);
854 if ( !IsBadReadPtr( (LPVOID)dwExtraInfo, sizeof(WINE_MOUSEEVENT) )
855 && ((WINE_MOUSEEVENT *)dwExtraInfo)->magic == WINE_MOUSEEVENT_MAGIC ) {
856 WINE_MOUSEEVENT *wme = (WINE_MOUSEEVENT *)dwExtraInfo;
857 keyState = wme->keyState;
858 xtime = wme->time;
859 extra = (DWORD)wme->hWnd;
861 assert( dwFlags & MOUSEEVENTF_ABSOLUTE );
862 posX = (dx * GetSystemMetrics(SM_CXSCREEN)) >> 16;
863 posY = (dy * GetSystemMetrics(SM_CYSCREEN)) >> 16;
864 } else {
865 ERR("Mouse event not supported...\n");
866 LeaveCriticalSection(&(This->crit));
867 return ;
870 TRACE(" %ld %ld ", posX, posY);
872 if ( dwFlags & MOUSEEVENTF_MOVE ) {
873 if (This->absolute) {
874 if (posX != This->prevX)
875 GEN_EVENT(DIMOFS_X, posX, xtime, 0);
876 if (posY != This->prevY)
877 GEN_EVENT(DIMOFS_Y, posY, xtime, 0);
878 } else {
879 /* Relative mouse input : the real fun starts here... */
880 if (This->need_warp) {
881 if (posX != This->prevX)
882 GEN_EVENT(DIMOFS_X, posX - This->prevX, xtime, evsequence++);
883 if (posY != This->prevY)
884 GEN_EVENT(DIMOFS_Y, posY - This->prevY, xtime, evsequence++);
885 } else {
886 /* This is the first time the event handler has been called after a
887 GetData of GetState. */
888 if (posX != This->win_centerX) {
889 GEN_EVENT(DIMOFS_X, posX - This->win_centerX, xtime, evsequence++);
890 This->need_warp = 1;
893 if (posY != This->win_centerY) {
894 GEN_EVENT(DIMOFS_Y, posY - This->win_centerY, xtime, evsequence++);
895 This->need_warp = 1;
900 if ( dwFlags & MOUSEEVENTF_LEFTDOWN ) {
901 if (TRACE_ON(dinput))
902 DPRINTF(" LD ");
904 GEN_EVENT(DIMOFS_BUTTON0, 0xFF, xtime, evsequence++);
906 if ( dwFlags & MOUSEEVENTF_LEFTUP ) {
907 if (TRACE_ON(dinput))
908 DPRINTF(" LU ");
910 GEN_EVENT(DIMOFS_BUTTON0, 0x00, xtime, evsequence++);
912 if ( dwFlags & MOUSEEVENTF_RIGHTDOWN ) {
913 if (TRACE_ON(dinput))
914 DPRINTF(" RD ");
916 GEN_EVENT(DIMOFS_BUTTON1, 0xFF, xtime, evsequence++);
918 if ( dwFlags & MOUSEEVENTF_RIGHTUP ) {
919 if (TRACE_ON(dinput))
920 DPRINTF(" RU ");
922 GEN_EVENT(DIMOFS_BUTTON1, 0x00, xtime, evsequence++);
924 if ( dwFlags & MOUSEEVENTF_MIDDLEDOWN ) {
925 if (TRACE_ON(dinput))
926 DPRINTF(" MD ");
928 GEN_EVENT(DIMOFS_BUTTON2, 0xFF, xtime, evsequence++);
930 if ( dwFlags & MOUSEEVENTF_MIDDLEUP ) {
931 if (TRACE_ON(dinput))
932 DPRINTF(" MU ");
934 GEN_EVENT(DIMOFS_BUTTON2, 0x00, xtime, evsequence++);
936 if (TRACE_ON(dinput))
937 DPRINTF("\n");
939 This->prevX = posX;
940 This->prevY = posY;
941 LeaveCriticalSection(&(This->crit));
945 /******************************************************************************
946 * Acquire : gets exclusive control of the mouse
948 static HRESULT WINAPI SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface)
950 ICOM_THIS(SysMouseAImpl,iface);
951 RECT rect;
953 TRACE("(this=%p)\n",This);
955 if (This->acquired == 0) {
956 POINT point;
958 /* This stores the current mouse handler. */
959 This->prev_handler = mouse_event;
961 /* Store (in a global variable) the current lock */
962 current_lock = (IDirectInputDevice2A*)This;
964 /* Install our own mouse event handler */
965 MOUSE_Enable(dinput_mouse_event);
967 /* Get the window dimension and find the center */
968 GetWindowRect(This->win, &rect);
969 This->win_centerX = (rect.right - rect.left) / 2;
970 This->win_centerY = (rect.bottom - rect.top ) / 2;
972 /* Warp the mouse to the center of the window */
973 TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY);
974 point.x = This->win_centerX;
975 point.y = This->win_centerY;
976 MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
977 DISPLAY_MoveCursor(point.x, point.y);
979 This->acquired = 1;
981 return 0;
984 /******************************************************************************
985 * Unacquire : frees the mouse
987 static HRESULT WINAPI SysMouseAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface)
989 ICOM_THIS(SysMouseAImpl,iface);
991 TRACE("(this=%p)\n",This);
993 /* Reinstall previous mouse event handler */
994 MOUSE_Enable(This->prev_handler);
995 This->prev_handler = NULL;
997 /* No more locks */
998 current_lock = NULL;
1000 /* Unacquire device */
1001 This->acquired = 0;
1003 return 0;
1006 /******************************************************************************
1007 * GetDeviceState : returns the "state" of the mouse.
1009 * For the moment, only the "standard" return structure (DIMOUSESTATE) is
1010 * supported.
1012 static HRESULT WINAPI SysMouseAImpl_GetDeviceState(
1013 LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr
1015 ICOM_THIS(SysMouseAImpl,iface);
1016 struct DIMOUSESTATE *mstate = (struct DIMOUSESTATE *) ptr;
1018 TRACE("(this=%p,0x%08lx,%p): \n",This,len,ptr);
1020 /* Check if the buffer is big enough */
1021 if (len < sizeof(struct DIMOUSESTATE)) {
1022 FIXME("unsupported state structure.");
1023 return DIERR_INVALIDPARAM;
1026 TRACE("(X:%ld - Y:%ld)\n", PosX, PosY);
1028 /* Fill the mouse state structure */
1029 if (This->absolute) {
1030 mstate->lX = PosX;
1031 mstate->lY = PosY;
1032 } else {
1033 mstate->lX = PosX - This->win_centerX;
1034 mstate->lY = PosY - This->win_centerY;
1036 if ((mstate->lX != 0) || (mstate->lY != 0))
1037 This->need_warp = 1;
1039 mstate->lZ = 0;
1040 /* WARNING : this supposes that DInput takes into account the 'SwapButton' option */
1041 mstate->rgbButtons[0] = (MouseButtonsStates[0] ? 0xFF : 0x00);
1042 mstate->rgbButtons[1] = (MouseButtonsStates[1] ? 0xFF : 0x00);
1043 mstate->rgbButtons[2] = (MouseButtonsStates[2] ? 0xFF : 0x00);
1044 mstate->rgbButtons[3] = 0x00;
1046 /* Check if we need to do a mouse warping */
1047 if (This->need_warp) {
1048 POINT point;
1050 TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY);
1051 point.x = This->win_centerX;
1052 point.y = This->win_centerY;
1053 MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
1054 DISPLAY_MoveCursor(point.x, point.y);
1056 This->need_warp = 0;
1059 TRACE("(X: %ld - Y: %ld L: %02x M: %02x R: %02x)\n",
1060 mstate->lX, mstate->lY,
1061 mstate->rgbButtons[0], mstate->rgbButtons[2], mstate->rgbButtons[1]);
1063 return 0;
1066 /******************************************************************************
1067 * GetDeviceState : gets buffered input data.
1069 static HRESULT WINAPI SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE2A iface,
1070 DWORD dodsize,
1071 LPDIDEVICEOBJECTDATA dod,
1072 LPDWORD entries,
1073 DWORD flags
1075 ICOM_THIS(SysMouseAImpl,iface);
1077 EnterCriticalSection(&(This->crit));
1078 TRACE("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx)\n",This,dodsize,*entries,flags);
1080 if (flags & DIGDD_PEEK)
1081 FIXME("DIGDD_PEEK\n");
1083 if (dod == NULL) {
1084 *entries = This->queue_pos;
1085 This->queue_pos = 0;
1086 } else {
1087 /* Check for buffer overflow */
1088 if (This->queue_pos > *entries) {
1089 WARN("Buffer overflow not handled properly yet...\n");
1090 This->queue_pos = *entries;
1092 if (dodsize != sizeof(DIDEVICEOBJECTDATA)) {
1093 ERR("Wrong structure size !\n");
1094 LeaveCriticalSection(&(This->crit));
1095 return DIERR_INVALIDPARAM;
1098 if (This->queue_pos)
1099 TRACE("Application retrieving %d event(s).\n", This->queue_pos);
1101 /* Copy the buffered data into the application queue */
1102 memcpy(dod, This->data_queue, This->queue_pos * dodsize);
1103 *entries = This->queue_pos;
1105 /* Reset the event queue */
1106 This->queue_pos = 0;
1108 LeaveCriticalSection(&(This->crit));
1110 #if 0 /* FIXME: seems to create motion events, which fire back at us. */
1111 /* Check if we need to do a mouse warping */
1112 if (This->need_warp) {
1113 POINT point;
1115 TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY);
1116 point.x = This->win_centerX;
1117 point.y = This->win_centerY;
1118 MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
1120 DISPLAY_MoveCursor(point.x, point.y);
1122 This->need_warp = 0;
1124 #endif
1125 return 0;
1128 /******************************************************************************
1129 * SetProperty : change input device properties
1131 static HRESULT WINAPI SysMouseAImpl_SetProperty(LPDIRECTINPUTDEVICE2A iface,
1132 REFGUID rguid,
1133 LPCDIPROPHEADER ph)
1135 ICOM_THIS(SysMouseAImpl,iface);
1136 char xbuf[50];
1138 if (HIWORD(rguid))
1139 WINE_StringFromCLSID(rguid,xbuf);
1140 else
1141 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
1143 TRACE("(this=%p,%s,%p)\n",This,xbuf,ph);
1145 if (!HIWORD(rguid)) {
1146 switch ((DWORD)rguid) {
1147 case (DWORD) DIPROP_BUFFERSIZE: {
1148 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
1150 TRACE("buffersize = %ld\n",pd->dwData);
1152 This->data_queue = (LPDIDEVICEOBJECTDATA)HeapAlloc(GetProcessHeap(),0,
1153 pd->dwData * sizeof(DIDEVICEOBJECTDATA));
1154 This->queue_pos = 0;
1155 This->queue_len = pd->dwData;
1156 break;
1158 default:
1159 FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,xbuf);
1160 break;
1164 return 0;
1167 /******************************************************************************
1168 * SetEventNotification : specifies event to be sent on state change
1170 static HRESULT WINAPI SysMouseAImpl_SetEventNotification(LPDIRECTINPUTDEVICE2A iface,
1171 HANDLE hnd) {
1172 ICOM_THIS(SysMouseAImpl,iface);
1174 TRACE("(this=%p,0x%08lx)\n",This,(DWORD)hnd);
1176 This->hEvent = hnd;
1178 return DI_OK;
1181 #ifdef HAVE_LINUX_22_JOYSTICK_API
1182 /******************************************************************************
1183 * Joystick
1185 static ULONG WINAPI JoystickAImpl_Release(LPDIRECTINPUTDEVICE2A iface)
1187 ICOM_THIS(JoystickAImpl,iface);
1189 This->ref--;
1190 if (This->ref)
1191 return This->ref;
1192 HeapFree(GetProcessHeap(),0,This);
1193 return 0;
1196 /******************************************************************************
1197 * SetDataFormat : the application can choose the format of the data
1198 * the device driver sends back with GetDeviceState.
1200 static HRESULT WINAPI JoystickAImpl_SetDataFormat(
1201 LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df
1204 ICOM_THIS(JoystickAImpl,iface);
1205 int i;
1207 TRACE("(this=%p,%p)\n",This,df);
1209 TRACE("(df.dwSize=%ld)\n",df->dwSize);
1210 TRACE("(df.dwObjsize=%ld)\n",df->dwObjSize);
1211 TRACE("(df.dwFlags=0x%08lx)\n",df->dwFlags);
1212 TRACE("(df.dwDataSize=%ld)\n",df->dwDataSize);
1213 TRACE("(df.dwNumObjs=%ld)\n",df->dwNumObjs);
1215 for (i=0;i<df->dwNumObjs;i++) {
1216 char xbuf[50];
1218 if (df->rgodf[i].pguid)
1219 WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
1220 else
1221 strcpy(xbuf,"<no guid>");
1222 TRACE("df.rgodf[%d].guid %s (%p)\n",i,xbuf, df->rgodf[i].pguid);
1223 TRACE("df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
1224 TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
1225 TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
1227 This->df = HeapAlloc(GetProcessHeap(),0,df->dwSize+(df->dwNumObjs*df->dwObjSize));
1228 memcpy(This->df,df,df->dwSize+(df->dwNumObjs*df->dwObjSize));
1229 return 0;
1232 /******************************************************************************
1233 * Acquire : gets exclusive control of the joystick
1235 static HRESULT WINAPI JoystickAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface)
1237 ICOM_THIS(JoystickAImpl,iface);
1239 TRACE("(this=%p)\n",This);
1240 if (This->joyfd!=-1)
1241 return 0;
1242 This->joyfd=open(JOYDEV,O_RDONLY);
1243 if (This->joyfd==-1)
1244 return DIERR_NOTFOUND;
1245 return 0;
1248 /******************************************************************************
1249 * Unacquire : frees the joystick
1251 static HRESULT WINAPI JoystickAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface)
1253 ICOM_THIS(JoystickAImpl,iface);
1255 TRACE("(this=%p)\n",This);
1256 if (This->joyfd!=-1) {
1257 close(This->joyfd);
1258 This->joyfd = -1;
1260 return 0;
1263 #define map_axis(val) ((val+32768)*(This->lMax-This->lMin)/65536+This->lMin)
1265 static void joy_polldev(JoystickAImpl *This) {
1266 struct timeval tv;
1267 fd_set readfds;
1268 struct js_event jse;
1270 if (This->joyfd==-1)
1271 return;
1272 while (1) {
1273 memset(&tv,0,sizeof(tv));
1274 FD_ZERO(&readfds);FD_SET(This->joyfd,&readfds);
1275 if (1>select(This->joyfd+1,&readfds,NULL,NULL,&tv))
1276 return;
1277 /* we have one event, so we can read */
1278 if (sizeof(jse)!=read(This->joyfd,&jse,sizeof(jse))) {
1279 return;
1281 TRACE("js_event: type 0x%x, number %d, value %d\n",jse.type,jse.number,jse.value);
1282 if (jse.type & JS_EVENT_BUTTON) {
1283 GEN_EVENT(DIJOFS_BUTTON(jse.number),jse.value?0x80:0x00,jse.time,evsequence++);
1284 This->js.rgbButtons[jse.number] = jse.value?0x80:0x00;
1286 if (jse.type & JS_EVENT_AXIS) {
1287 switch (jse.number) {
1288 case 0:
1289 GEN_EVENT(jse.number*4,jse.value,jse.time,evsequence++);
1290 This->js.lX = map_axis(jse.value);
1291 break;
1292 case 1:
1293 GEN_EVENT(jse.number*4,jse.value,jse.time,evsequence++);
1294 This->js.lY = map_axis(jse.value);
1295 break;
1296 case 2:
1297 GEN_EVENT(jse.number*4,jse.value,jse.time,evsequence++);
1298 This->js.lZ = map_axis(jse.value);
1299 break;
1300 default:
1301 FIXME("more then 3 axes (%d) not handled!\n",jse.number);
1302 break;
1308 /******************************************************************************
1309 * GetDeviceState : returns the "state" of the joystick.
1312 static HRESULT WINAPI JoystickAImpl_GetDeviceState(
1313 LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr
1315 ICOM_THIS(JoystickAImpl,iface);
1317 joy_polldev(This);
1318 TRACE("(this=%p,0x%08lx,%p)\n",This,len,ptr);
1319 if (len != sizeof(DIJOYSTATE)) {
1320 FIXME("len %ld is not sizeof(DIJOYSTATE), unsupported format.\n",len);
1322 memcpy(ptr,&(This->js),len);
1323 This->queue_pos = 0;
1324 return 0;
1327 /******************************************************************************
1328 * GetDeviceState : gets buffered input data.
1330 static HRESULT WINAPI JoystickAImpl_GetDeviceData(LPDIRECTINPUTDEVICE2A iface,
1331 DWORD dodsize,
1332 LPDIDEVICEOBJECTDATA dod,
1333 LPDWORD entries,
1334 DWORD flags
1336 ICOM_THIS(JoystickAImpl,iface);
1338 FIXME("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx),STUB!\n",This,dodsize,*entries,flags);
1340 joy_polldev(This);
1341 if (flags & DIGDD_PEEK)
1342 FIXME("DIGDD_PEEK\n");
1344 if (dod == NULL) {
1345 } else {
1347 return 0;
1350 /******************************************************************************
1351 * SetProperty : change input device properties
1353 static HRESULT WINAPI JoystickAImpl_SetProperty(LPDIRECTINPUTDEVICE2A iface,
1354 REFGUID rguid,
1355 LPCDIPROPHEADER ph)
1357 ICOM_THIS(JoystickAImpl,iface);
1358 char xbuf[50];
1360 if (HIWORD(rguid))
1361 WINE_StringFromCLSID(rguid,xbuf);
1362 else
1363 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
1365 FIXME("(this=%p,%s,%p)\n",This,xbuf,ph);
1366 FIXME("ph.dwSize = %ld, ph.dwHeaderSize =%ld, ph.dwObj = %ld, ph.dwHow= %ld\n",ph->dwSize, ph->dwHeaderSize,ph->dwObj,ph->dwHow);
1368 if (!HIWORD(rguid)) {
1369 switch ((DWORD)rguid) {
1370 case (DWORD) DIPROP_BUFFERSIZE: {
1371 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
1373 FIXME("buffersize = %ld\n",pd->dwData);
1374 break;
1376 case (DWORD)DIPROP_RANGE: {
1377 LPCDIPROPRANGE pr = (LPCDIPROPRANGE)ph;
1379 FIXME("proprange(%ld,%ld)\n",pr->lMin,pr->lMax);
1380 This->lMin = pr->lMin;
1381 This->lMax = pr->lMax;
1382 break;
1384 case (DWORD)DIPROP_DEADZONE: {
1385 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
1387 FIXME("deadzone(%ld)\n",pd->dwData);
1388 This->deadzone = pd->dwData;
1389 break;
1391 default:
1392 FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,xbuf);
1393 break;
1396 return 0;
1399 /******************************************************************************
1400 * SetEventNotification : specifies event to be sent on state change
1402 static HRESULT WINAPI JoystickAImpl_SetEventNotification(
1403 LPDIRECTINPUTDEVICE2A iface, HANDLE hnd
1405 ICOM_THIS(JoystickAImpl,iface);
1407 TRACE("(this=%p,0x%08lx)\n",This,(DWORD)hnd);
1408 This->hEvent = hnd;
1409 return DI_OK;
1412 static HRESULT WINAPI JoystickAImpl_GetCapabilities(
1413 LPDIRECTINPUTDEVICE2A iface,
1414 LPDIDEVCAPS lpDIDevCaps)
1416 ICOM_THIS(JoystickAImpl,iface);
1417 BYTE axes,buttons;
1418 int xfd = This->joyfd;
1420 TRACE("%p->(%p)\n",iface,lpDIDevCaps);
1421 if (xfd==-1)
1422 xfd = open(JOYDEV,O_RDONLY);
1423 lpDIDevCaps->dwFlags = DIDC_ATTACHED;
1424 lpDIDevCaps->dwDevType = DIDEVTYPE_JOYSTICK;
1425 #ifdef JSIOCGAXES
1426 if (-1==ioctl(xfd,JSIOCGAXES,&axes))
1427 axes = 2;
1428 lpDIDevCaps->dwAxes = axes;
1429 #endif
1430 #ifdef JSIOCGBUTTONS
1431 if (-1==ioctl(xfd,JSIOCGAXES,&buttons))
1432 buttons = 2;
1433 lpDIDevCaps->dwButtons = buttons;
1434 #endif
1435 if (xfd!=This->joyfd)
1436 close(xfd);
1437 return DI_OK;
1439 static HRESULT WINAPI JoystickAImpl_Poll(LPDIRECTINPUTDEVICE2A iface) {
1440 ICOM_THIS(JoystickAImpl,iface);
1441 TRACE("(),stub!\n");
1443 joy_polldev(This);
1444 return DI_OK;
1446 #endif
1448 /****************************************************************************/
1449 /****************************************************************************/
1451 static ICOM_VTABLE(IDirectInputDevice2A) SysKeyboardAvt =
1453 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1454 IDirectInputDevice2AImpl_QueryInterface,
1455 IDirectInputDevice2AImpl_AddRef,
1456 IDirectInputDevice2AImpl_Release,
1457 IDirectInputDevice2AImpl_GetCapabilities,
1458 IDirectInputDevice2AImpl_EnumObjects,
1459 IDirectInputDevice2AImpl_GetProperty,
1460 SysKeyboardAImpl_SetProperty,
1461 SysKeyboardAImpl_Acquire,
1462 SysKeyboardAImpl_Unacquire,
1463 SysKeyboardAImpl_GetDeviceState,
1464 SysKeyboardAImpl_GetDeviceData,
1465 IDirectInputDevice2AImpl_SetDataFormat,
1466 IDirectInputDevice2AImpl_SetEventNotification,
1467 IDirectInputDevice2AImpl_SetCooperativeLevel,
1468 IDirectInputDevice2AImpl_GetObjectInfo,
1469 IDirectInputDevice2AImpl_GetDeviceInfo,
1470 IDirectInputDevice2AImpl_RunControlPanel,
1471 IDirectInputDevice2AImpl_Initialize,
1472 IDirectInputDevice2AImpl_CreateEffect,
1473 IDirectInputDevice2AImpl_EnumEffects,
1474 IDirectInputDevice2AImpl_GetEffectInfo,
1475 IDirectInputDevice2AImpl_GetForceFeedbackState,
1476 IDirectInputDevice2AImpl_SendForceFeedbackCommand,
1477 IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
1478 IDirectInputDevice2AImpl_Escape,
1479 IDirectInputDevice2AImpl_Poll,
1480 IDirectInputDevice2AImpl_SendDeviceData,
1483 static ICOM_VTABLE(IDirectInputDevice2A) SysMouseAvt =
1485 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1486 IDirectInputDevice2AImpl_QueryInterface,
1487 IDirectInputDevice2AImpl_AddRef,
1488 SysMouseAImpl_Release,
1489 IDirectInputDevice2AImpl_GetCapabilities,
1490 IDirectInputDevice2AImpl_EnumObjects,
1491 IDirectInputDevice2AImpl_GetProperty,
1492 SysMouseAImpl_SetProperty,
1493 SysMouseAImpl_Acquire,
1494 SysMouseAImpl_Unacquire,
1495 SysMouseAImpl_GetDeviceState,
1496 SysMouseAImpl_GetDeviceData,
1497 SysMouseAImpl_SetDataFormat,
1498 SysMouseAImpl_SetEventNotification,
1499 SysMouseAImpl_SetCooperativeLevel,
1500 IDirectInputDevice2AImpl_GetObjectInfo,
1501 IDirectInputDevice2AImpl_GetDeviceInfo,
1502 IDirectInputDevice2AImpl_RunControlPanel,
1503 IDirectInputDevice2AImpl_Initialize,
1504 IDirectInputDevice2AImpl_CreateEffect,
1505 IDirectInputDevice2AImpl_EnumEffects,
1506 IDirectInputDevice2AImpl_GetEffectInfo,
1507 IDirectInputDevice2AImpl_GetForceFeedbackState,
1508 IDirectInputDevice2AImpl_SendForceFeedbackCommand,
1509 IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
1510 IDirectInputDevice2AImpl_Escape,
1511 IDirectInputDevice2AImpl_Poll,
1512 IDirectInputDevice2AImpl_SendDeviceData,
1515 #ifdef HAVE_LINUX_22_JOYSTICK_API
1516 static ICOM_VTABLE(IDirectInputDevice2A) JoystickAvt =
1518 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1519 IDirectInputDevice2AImpl_QueryInterface,
1520 IDirectInputDevice2AImpl_AddRef,
1521 JoystickAImpl_Release,
1522 JoystickAImpl_GetCapabilities,
1523 IDirectInputDevice2AImpl_EnumObjects,
1524 IDirectInputDevice2AImpl_GetProperty,
1525 JoystickAImpl_SetProperty,
1526 JoystickAImpl_Acquire,
1527 JoystickAImpl_Unacquire,
1528 JoystickAImpl_GetDeviceState,
1529 JoystickAImpl_GetDeviceData,
1530 JoystickAImpl_SetDataFormat,
1531 JoystickAImpl_SetEventNotification,
1532 IDirectInputDevice2AImpl_SetCooperativeLevel,
1533 IDirectInputDevice2AImpl_GetObjectInfo,
1534 IDirectInputDevice2AImpl_GetDeviceInfo,
1535 IDirectInputDevice2AImpl_RunControlPanel,
1536 IDirectInputDevice2AImpl_Initialize,
1537 IDirectInputDevice2AImpl_CreateEffect,
1538 IDirectInputDevice2AImpl_EnumEffects,
1539 IDirectInputDevice2AImpl_GetEffectInfo,
1540 IDirectInputDevice2AImpl_GetForceFeedbackState,
1541 IDirectInputDevice2AImpl_SendForceFeedbackCommand,
1542 IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
1543 IDirectInputDevice2AImpl_Escape,
1544 JoystickAImpl_Poll,
1545 IDirectInputDevice2AImpl_SendDeviceData,
1547 #endif