Added missing configuration #if:s and #includes:s.
[wine/dcerpc.git] / windows / dinput.c
bloba8b0175ce42b97541a1295fe92185ca37c630c9b
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 "keyboard.h"
45 #include "message.h"
46 #include "mouse.h"
47 #include "sysmetrics.h"
48 #include "winbase.h"
49 #include "winerror.h"
50 #include "winuser.h"
52 DEFAULT_DEBUG_CHANNEL(dinput)
55 extern BYTE InputKeyStateTable[256];
56 extern int min_keycode, max_keycode;
57 extern WORD keyc2vkey[256];
59 static ICOM_VTABLE(IDirectInputA) ddiavt;
60 static ICOM_VTABLE(IDirectInputDevice2A) SysKeyboardAvt;
61 static ICOM_VTABLE(IDirectInputDevice2A) SysMouseAvt;
63 typedef struct IDirectInputAImpl IDirectInputAImpl;
64 typedef struct IDirectInputDevice2AImpl IDirectInputDevice2AImpl;
65 typedef struct SysKeyboardAImpl SysKeyboardAImpl;
66 typedef struct SysMouseAImpl SysMouseAImpl;
68 struct IDirectInputDevice2AImpl
70 ICOM_VFIELD(IDirectInputDevice2A);
71 DWORD ref;
72 GUID guid;
75 struct SysKeyboardAImpl
77 /* IDirectInputDevice2AImpl */
78 ICOM_VFIELD(IDirectInputDevice2A);
79 DWORD ref;
80 GUID guid;
81 /* SysKeyboardAImpl */
82 BYTE keystate[256];
85 #ifdef HAVE_LINUX_22_JOYSTICK_API
86 typedef struct JoystickAImpl JoystickAImpl;
87 static ICOM_VTABLE(IDirectInputDevice2A) JoystickAvt;
88 struct JoystickAImpl
90 /* IDirectInputDevice2AImpl */
91 ICOM_VFIELD(IDirectInputDevice2A);
92 DWORD ref;
93 GUID guid;
95 /* joystick private */
96 int joyfd;
97 LPDIDATAFORMAT df;
98 HANDLE hEvent;
99 LONG lMin,lMax,deadzone;
100 LPDIDEVICEOBJECTDATA data_queue;
101 int queue_pos, queue_len;
102 DIJOYSTATE js;
104 #endif
106 struct SysMouseAImpl
108 /* IDirectInputDevice2AImpl */
109 ICOM_VFIELD(IDirectInputDevice2A);
110 DWORD ref;
111 GUID guid;
113 LPDIDATAFORMAT df;
114 /* SysMouseAImpl */
115 BYTE absolute;
116 /* Previous position for relative moves */
117 LONG prevX, prevY;
118 LPMOUSE_EVENT_PROC prev_handler;
119 HWND win;
120 DWORD win_centerX, win_centerY;
121 LPDIDEVICEOBJECTDATA data_queue;
122 int queue_pos, queue_len;
123 int need_warp;
124 int acquired;
125 HANDLE hEvent;
126 CRITICAL_SECTION crit;
129 static int evsequence=0;
132 /* UIDs for Wine "drivers".
133 When enumerating each device supporting DInput, they have two UIDs :
134 - the 'windows' UID
135 - a vendor UID */
136 #ifdef HAVE_LINUX_22_JOYSTICK_API
137 static GUID DInput_Wine_Joystick_GUID = { /* 9e573ed9-7734-11d2-8d4a-23903fb6bdf7 */
138 0x9e573ed9,
139 0x7734,
140 0x11d2,
141 {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
143 #endif
144 static GUID DInput_Wine_Mouse_GUID = { /* 9e573ed8-7734-11d2-8d4a-23903fb6bdf7 */
145 0x9e573ed8,
146 0x7734,
147 0x11d2,
148 {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
150 static GUID DInput_Wine_Keyboard_GUID = { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */
151 0x0ab8648a,
152 0x7735,
153 0x11d2,
154 {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41}
157 /* FIXME: This is ugly and not thread safe :/ */
158 static IDirectInputDevice2A* current_lock = NULL;
160 /******************************************************************************
161 * Various debugging tools
163 static void _dump_cooperativelevel(DWORD dwFlags) {
164 int i;
165 const struct {
166 DWORD mask;
167 char *name;
168 } flags[] = {
169 #define FE(x) { x, #x},
170 FE(DISCL_BACKGROUND)
171 FE(DISCL_EXCLUSIVE)
172 FE(DISCL_FOREGROUND)
173 FE(DISCL_NONEXCLUSIVE)
175 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
176 if (flags[i].mask & dwFlags)
177 DPRINTF("%s ",flags[i].name);
178 DPRINTF("\n");
181 struct IDirectInputAImpl
183 ICOM_VFIELD(IDirectInputA);
184 DWORD ref;
187 /******************************************************************************
188 * DirectInputCreate32A
190 HRESULT WINAPI DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA *ppDI, LPUNKNOWN punkOuter)
192 IDirectInputAImpl* This;
193 TRACE("(0x%08lx,%04lx,%p,%p)\n",
194 (DWORD)hinst,dwVersion,ppDI,punkOuter
196 This = (IDirectInputAImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl));
197 This->ref = 1;
198 ICOM_VTBL(This) = &ddiavt;
199 *ppDI=(IDirectInputA*)This;
200 return 0;
202 /******************************************************************************
203 * IDirectInputA_EnumDevices
205 static HRESULT WINAPI IDirectInputAImpl_EnumDevices(
206 LPDIRECTINPUTA iface, DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback,
207 LPVOID pvRef, DWORD dwFlags
210 ICOM_THIS(IDirectInputAImpl,iface);
211 DIDEVICEINSTANCEA devInstance;
212 int ret;
214 TRACE("(this=%p,0x%04lx,%p,%p,%04lx)\n", This, dwDevType, lpCallback, pvRef, dwFlags);
216 devInstance.dwSize = sizeof(DIDEVICEINSTANCEA);
217 if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_KEYBOARD)) {
218 /* Return keyboard */
219 devInstance.guidInstance = GUID_SysKeyboard;/* DInput's GUID */
220 devInstance.guidProduct = DInput_Wine_Keyboard_GUID; /* Vendor's GUID */
221 devInstance.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8);
222 strcpy(devInstance.tszInstanceName, "Keyboard");
223 strcpy(devInstance.tszProductName, "Wine Keyboard");
225 ret = lpCallback(&devInstance, pvRef);
226 TRACE("Keyboard registered\n");
227 if (ret == DIENUM_STOP)
228 return 0;
231 if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_MOUSE)) {
232 /* Return mouse */
233 devInstance.guidInstance = GUID_SysMouse;/* DInput's GUID */
234 devInstance.guidProduct = DInput_Wine_Mouse_GUID; /* Vendor's GUID */
235 devInstance.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_UNKNOWN << 8);
236 strcpy(devInstance.tszInstanceName, "Mouse");
237 strcpy(devInstance.tszProductName, "Wine Mouse");
239 ret = lpCallback(&devInstance, pvRef);
240 TRACE("Mouse registered\n");
241 if (ret == DIENUM_STOP)
242 return 0;
244 if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_JOYSTICK)) {
245 /* check whether we have a joystick */
246 #ifdef HAVE_LINUX_22_JOYSTICK_API
247 if ( (access(JOYDEV,O_RDONLY)!=-1) ||
248 (errno!=ENODEV && errno!=ENOENT)
250 /* Return joystick */
251 devInstance.guidInstance = GUID_Joystick;
252 devInstance.guidProduct = DInput_Wine_Joystick_GUID;
253 /* we only support traditional joysticks for now */
254 devInstance.dwDevType = DIDEVTYPE_JOYSTICK | DIDEVTYPEJOYSTICK_TRADITIONAL;
255 strcpy(devInstance.tszInstanceName, "Joystick");
256 /* ioctl JSIOCGNAME(len) */
257 strcpy(devInstance.tszProductName, "Wine Joystick");
259 ret = lpCallback(&devInstance,pvRef);
260 TRACE("Joystick registered\n");
261 if (ret == DIENUM_STOP)
262 return 0;
264 #endif
266 return 0;
269 static ULONG WINAPI IDirectInputAImpl_AddRef(LPDIRECTINPUTA iface)
271 ICOM_THIS(IDirectInputAImpl,iface);
272 return ++(This->ref);
275 static ULONG WINAPI IDirectInputAImpl_Release(LPDIRECTINPUTA iface)
277 ICOM_THIS(IDirectInputAImpl,iface);
278 if (!(--This->ref)) {
279 HeapFree(GetProcessHeap(),0,This);
280 return 0;
282 return This->ref;
285 static HRESULT WINAPI IDirectInputAImpl_CreateDevice(
286 LPDIRECTINPUTA iface,REFGUID rguid,LPDIRECTINPUTDEVICEA* pdev,
287 LPUNKNOWN punk
289 ICOM_THIS(IDirectInputAImpl,iface);
290 char xbuf[50];
292 WINE_StringFromCLSID(rguid,xbuf);
293 FIXME("(this=%p,%s,%p,%p): stub\n",This,xbuf,pdev,punk);
294 if ((!memcmp(&GUID_SysKeyboard,rguid,sizeof(GUID_SysKeyboard))) || /* Generic Keyboard */
295 (!memcmp(&DInput_Wine_Keyboard_GUID,rguid,sizeof(GUID_SysKeyboard)))) { /* Wine Keyboard */
296 SysKeyboardAImpl* newDevice;
297 newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysKeyboardAImpl));
298 newDevice->ref = 1;
299 ICOM_VTBL(newDevice) = &SysKeyboardAvt;
300 memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
301 memset(newDevice->keystate,0,256);
302 *pdev=(IDirectInputDeviceA*)newDevice;
303 return DI_OK;
305 if ((!memcmp(&GUID_SysMouse,rguid,sizeof(GUID_SysMouse))) || /* Generic Mouse */
306 (!memcmp(&DInput_Wine_Mouse_GUID,rguid,sizeof(GUID_SysMouse)))) { /* Wine Mouse */
307 SysMouseAImpl* newDevice;
308 newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysMouseAImpl));
309 newDevice->ref = 1;
310 ICOM_VTBL(newDevice) = &SysMouseAvt;
311 InitializeCriticalSection(&(newDevice->crit));
312 MakeCriticalSectionGlobal(&(newDevice->crit));
313 memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
314 *pdev=(IDirectInputDeviceA*)newDevice;
315 return DI_OK;
317 #ifdef HAVE_LINUX_22_JOYSTICK_API
318 if ((!memcmp(&GUID_Joystick,rguid,sizeof(GUID_Joystick))) ||
319 (!memcmp(&DInput_Wine_Joystick_GUID,rguid,sizeof(GUID_Joystick)))) {
320 JoystickAImpl* newDevice;
321 newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(JoystickAImpl));
322 newDevice->ref = 1;
323 ICOM_VTBL(newDevice) = &JoystickAvt;
324 newDevice->joyfd = -1;
325 memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
326 *pdev=(IDirectInputDeviceA*)newDevice;
327 return DI_OK;
329 #endif
330 return E_FAIL;
333 static HRESULT WINAPI IDirectInputAImpl_QueryInterface(
334 LPDIRECTINPUTA iface,REFIID riid,LPVOID *ppobj
336 ICOM_THIS(IDirectInputAImpl,iface);
337 char xbuf[50];
339 WINE_StringFromCLSID(riid,xbuf);
340 TRACE("(this=%p,%s,%p)\n",This,xbuf,ppobj);
341 if (!memcmp(&IID_IUnknown,riid,sizeof(*riid))) {
342 IDirectInputA_AddRef(iface);
343 *ppobj = This;
344 return 0;
346 if (!memcmp(&IID_IDirectInputA,riid,sizeof(*riid))) {
347 IDirectInputA_AddRef(iface);
348 *ppobj = This;
349 return 0;
351 return E_FAIL;
354 static HRESULT WINAPI IDirectInputAImpl_Initialize(
355 LPDIRECTINPUTA iface,HINSTANCE hinst,DWORD x
357 return DIERR_ALREADYINITIALIZED;
360 static HRESULT WINAPI IDirectInputAImpl_GetDeviceStatus(LPDIRECTINPUTA iface,
361 REFGUID rguid) {
362 ICOM_THIS(IDirectInputAImpl,iface);
363 char xbuf[50];
365 WINE_StringFromCLSID(rguid,xbuf);
366 FIXME("(%p)->(%s): stub\n",This,xbuf);
368 return DI_OK;
371 static HRESULT WINAPI IDirectInputAImpl_RunControlPanel(LPDIRECTINPUTA iface,
372 HWND hwndOwner,
373 DWORD dwFlags) {
374 ICOM_THIS(IDirectInputAImpl,iface);
375 FIXME("(%p)->(%08lx,%08lx): stub\n",This, (DWORD) hwndOwner, dwFlags);
377 return DI_OK;
380 static ICOM_VTABLE(IDirectInputA) ddiavt =
382 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
383 IDirectInputAImpl_QueryInterface,
384 IDirectInputAImpl_AddRef,
385 IDirectInputAImpl_Release,
386 IDirectInputAImpl_CreateDevice,
387 IDirectInputAImpl_EnumDevices,
388 IDirectInputAImpl_GetDeviceStatus,
389 IDirectInputAImpl_RunControlPanel,
390 IDirectInputAImpl_Initialize
393 /******************************************************************************
394 * IDirectInputDeviceA
397 static HRESULT WINAPI IDirectInputDevice2AImpl_SetDataFormat(
398 LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df
401 int i;
402 TRACE(dinput,"(this=%p,%p)\n",This,df);
404 TRACE(dinput,"df.dwSize=%ld\n",df->dwSize);
405 TRACE(dinput,"(df.dwObjsize=%ld)\n",df->dwObjSize);
406 TRACE(dinput,"(df.dwFlags=0x%08lx)\n",df->dwFlags);
407 TRACE(dinput,"(df.dwDataSize=%ld)\n",df->dwDataSize);
408 TRACE(dinput,"(df.dwNumObjs=%ld)\n",df->dwNumObjs);
410 for (i=0;i<df->dwNumObjs;i++) {
411 char xbuf[50];
413 if (df->rgodf[i].pguid)
414 WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
415 else
416 strcpy(xbuf,"<no guid>");
417 TRACE(dinput,"df.rgodf[%d].guid %s\n",i,xbuf);
418 TRACE(dinput,"df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
419 TRACE(dinput,"dwType 0x%02lx,dwInstance %ld\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
420 TRACE(dinput,"df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
423 return 0;
426 static HRESULT WINAPI IDirectInputDevice2AImpl_SetCooperativeLevel(
427 LPDIRECTINPUTDEVICE2A iface,HWND hwnd,DWORD dwflags
429 ICOM_THIS(IDirectInputDevice2AImpl,iface);
430 FIXME("(this=%p,0x%08lx,0x%08lx): stub\n",This,(DWORD)hwnd,dwflags);
431 if (TRACE_ON(dinput))
432 _dump_cooperativelevel(dwflags);
433 return 0;
436 static HRESULT WINAPI IDirectInputDevice2AImpl_SetEventNotification(
437 LPDIRECTINPUTDEVICE2A iface,HANDLE hnd
439 ICOM_THIS(IDirectInputDevice2AImpl,iface);
440 FIXME("(this=%p,0x%08lx): stub\n",This,(DWORD)hnd);
441 return 0;
444 static ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE2A iface)
446 ICOM_THIS(IDirectInputDevice2AImpl,iface);
447 This->ref--;
448 if (This->ref)
449 return This->ref;
450 HeapFree(GetProcessHeap(),0,This);
451 return 0;
454 static HRESULT WINAPI SysKeyboardAImpl_SetProperty(
455 LPDIRECTINPUTDEVICE2A iface,REFGUID rguid,LPCDIPROPHEADER ph
458 ICOM_THIS(SysKeyboardAImpl,iface);
459 char xbuf[50];
461 if (HIWORD(rguid))
462 WINE_StringFromCLSID(rguid,xbuf);
463 else
464 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
465 TRACE("(this=%p,%s,%p)\n",This,xbuf,ph);
466 TRACE("(size=%ld,headersize=%ld,obj=%ld,how=%ld\n",
467 ph->dwSize,ph->dwHeaderSize,ph->dwObj,ph->dwHow);
468 if (!HIWORD(rguid)) {
469 switch ((DWORD)rguid) {
470 case (DWORD) DIPROP_BUFFERSIZE: {
471 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
473 TRACE("(buffersize=%ld)\n",pd->dwData);
474 break;
476 default:
477 WARN("Unknown type %ld\n",(DWORD)rguid);
478 break;
481 return 0;
484 static HRESULT WINAPI SysKeyboardAImpl_GetDeviceState(
485 LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr
488 return KEYBOARD_Driver->pGetDIState(len, ptr)?DI_OK:E_FAIL;
491 static HRESULT WINAPI SysKeyboardAImpl_GetDeviceData(
492 LPDIRECTINPUTDEVICE2A iface,DWORD dodsize,LPDIDEVICEOBJECTDATA dod,
493 LPDWORD entries,DWORD flags
496 ICOM_THIS(SysKeyboardAImpl,iface);
497 HRESULT ret;
498 int i;
500 TRACE("(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n",
501 This,dodsize,dod,entries,entries?*entries:0,flags);
503 ret=KEYBOARD_Driver->pGetDIData(
504 This->keystate, dodsize, dod, entries, flags)?DI_OK:E_FAIL;
505 for (i=0;i<*entries;i++) {
506 dod[i].dwTimeStamp = time(NULL);
507 dod[i].dwSequence = evsequence++;
509 return ret;
512 static HRESULT WINAPI SysKeyboardAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface)
514 ICOM_THIS(SysKeyboardAImpl,iface);
515 TRACE("(this=%p): stub\n",This);
516 return 0;
519 static HRESULT WINAPI SysKeyboardAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface)
521 ICOM_THIS(SysKeyboardAImpl,iface);
522 TRACE("(this=%p): stub\n",This);
523 return 0;
526 static HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface(
527 LPDIRECTINPUTDEVICE2A iface,REFIID riid,LPVOID *ppobj
530 ICOM_THIS(IDirectInputDevice2AImpl,iface);
531 char xbuf[50];
533 WINE_StringFromCLSID(riid,xbuf);
534 TRACE("(this=%p,%s,%p)\n",This,xbuf,ppobj);
535 if (!memcmp(&IID_IUnknown,riid,sizeof(*riid))) {
536 IDirectInputDevice2_AddRef(iface);
537 *ppobj = This;
538 return 0;
540 if (!memcmp(&IID_IDirectInputDeviceA,riid,sizeof(*riid))) {
541 IDirectInputDevice2_AddRef(iface);
542 *ppobj = This;
543 return 0;
545 if (!memcmp(&IID_IDirectInputDevice2A,riid,sizeof(*riid))) {
546 IDirectInputDevice2_AddRef(iface);
547 *ppobj = This;
548 return 0;
550 return E_FAIL;
553 static ULONG WINAPI IDirectInputDevice2AImpl_AddRef(
554 LPDIRECTINPUTDEVICE2A iface)
556 ICOM_THIS(IDirectInputDevice2AImpl,iface);
557 return ++This->ref;
560 static HRESULT WINAPI IDirectInputDevice2AImpl_GetCapabilities(
561 LPDIRECTINPUTDEVICE2A iface,
562 LPDIDEVCAPS lpDIDevCaps)
564 lpDIDevCaps->dwFlags = DIDC_ATTACHED;
565 FIXME("stub!\n");
566 return DI_OK;
569 static HRESULT WINAPI IDirectInputDevice2AImpl_EnumObjects(
570 LPDIRECTINPUTDEVICE2A iface,
571 LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback,
572 LPVOID lpvRef,
573 DWORD dwFlags)
575 FIXME("stub!\n");
576 #if 0
577 if (lpCallback)
578 lpCallback(NULL, lpvRef);
579 #endif
580 return DI_OK;
583 static HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty(
584 LPDIRECTINPUTDEVICE2A iface,
585 REFGUID rguid,
586 LPDIPROPHEADER pdiph)
588 FIXME("stub!\n");
589 return DI_OK;
592 static HRESULT WINAPI IDirectInputDevice2AImpl_GetObjectInfo(
593 LPDIRECTINPUTDEVICE2A iface,
594 LPDIDEVICEOBJECTINSTANCEA pdidoi,
595 DWORD dwObj,
596 DWORD dwHow)
598 FIXME("stub!\n");
599 return DI_OK;
602 static HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceInfo(
603 LPDIRECTINPUTDEVICE2A iface,
604 LPDIDEVICEINSTANCEA pdidi)
606 FIXME("stub!\n");
607 return DI_OK;
610 static HRESULT WINAPI IDirectInputDevice2AImpl_RunControlPanel(
611 LPDIRECTINPUTDEVICE2A iface,
612 HWND hwndOwner,
613 DWORD dwFlags)
615 FIXME("stub!\n");
616 return DI_OK;
619 static HRESULT WINAPI IDirectInputDevice2AImpl_Initialize(
620 LPDIRECTINPUTDEVICE2A iface,
621 HINSTANCE hinst,
622 DWORD dwVersion,
623 REFGUID rguid)
625 FIXME("stub!\n");
626 return DI_OK;
629 /******************************************************************************
630 * IDirectInputDevice2A
633 static HRESULT WINAPI IDirectInputDevice2AImpl_CreateEffect(
634 LPDIRECTINPUTDEVICE2A iface,
635 REFGUID rguid,
636 LPCDIEFFECT lpeff,
637 LPDIRECTINPUTEFFECT *ppdef,
638 LPUNKNOWN pUnkOuter)
640 FIXME("stub!\n");
641 return DI_OK;
644 static HRESULT WINAPI IDirectInputDevice2AImpl_EnumEffects(
645 LPDIRECTINPUTDEVICE2A iface,
646 LPDIENUMEFFECTSCALLBACKA lpCallback,
647 LPVOID lpvRef,
648 DWORD dwFlags)
650 FIXME("stub!\n");
651 if (lpCallback)
652 lpCallback(NULL, lpvRef);
653 return DI_OK;
656 static HRESULT WINAPI IDirectInputDevice2AImpl_GetEffectInfo(
657 LPDIRECTINPUTDEVICE2A iface,
658 LPDIEFFECTINFOA lpdei,
659 REFGUID rguid)
661 FIXME("stub!\n");
662 return DI_OK;
665 static HRESULT WINAPI IDirectInputDevice2AImpl_GetForceFeedbackState(
666 LPDIRECTINPUTDEVICE2A iface,
667 LPDWORD pdwOut)
669 FIXME("stub!\n");
670 return DI_OK;
673 static HRESULT WINAPI IDirectInputDevice2AImpl_SendForceFeedbackCommand(
674 LPDIRECTINPUTDEVICE2A iface,
675 DWORD dwFlags)
677 FIXME("stub!\n");
678 return DI_OK;
681 static HRESULT WINAPI IDirectInputDevice2AImpl_EnumCreatedEffectObjects(
682 LPDIRECTINPUTDEVICE2A iface,
683 LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback,
684 LPVOID lpvRef,
685 DWORD dwFlags)
687 FIXME("stub!\n");
688 if (lpCallback)
689 lpCallback(NULL, lpvRef);
690 return DI_OK;
693 static HRESULT WINAPI IDirectInputDevice2AImpl_Escape(
694 LPDIRECTINPUTDEVICE2A iface,
695 LPDIEFFESCAPE lpDIEEsc)
697 FIXME("stub!\n");
698 return DI_OK;
701 static HRESULT WINAPI IDirectInputDevice2AImpl_Poll(
702 LPDIRECTINPUTDEVICE2A iface)
704 FIXME("stub!\n");
705 return DI_OK;
708 static HRESULT WINAPI IDirectInputDevice2AImpl_SendDeviceData(
709 LPDIRECTINPUTDEVICE2A iface,
710 DWORD cbObjectData,
711 LPDIDEVICEOBJECTDATA rgdod,
712 LPDWORD pdwInOut,
713 DWORD dwFlags)
715 FIXME("stub!\n");
716 return DI_OK;
719 /******************************************************************************
720 * SysMouseA (DInput Mouse support)
723 /******************************************************************************
724 * Release : release the mouse buffer.
726 static ULONG WINAPI SysMouseAImpl_Release(LPDIRECTINPUTDEVICE2A iface)
728 ICOM_THIS(SysMouseAImpl,iface);
730 This->ref--;
731 if (This->ref)
732 return This->ref;
734 /* Free the data queue */
735 if (This->data_queue != NULL)
736 HeapFree(GetProcessHeap(),0,This->data_queue);
738 /* Install the previous event handler (in case of releasing an aquired
739 mouse device) */
740 if (This->prev_handler != NULL)
741 MOUSE_Enable(This->prev_handler);
742 DeleteCriticalSection(&(This->crit));
744 HeapFree(GetProcessHeap(),0,This);
745 return 0;
749 /******************************************************************************
750 * SetCooperativeLevel : store the window in which we will do our
751 * grabbing.
753 static HRESULT WINAPI SysMouseAImpl_SetCooperativeLevel(
754 LPDIRECTINPUTDEVICE2A iface,HWND hwnd,DWORD dwflags
757 ICOM_THIS(SysMouseAImpl,iface);
759 TRACE("(this=%p,0x%08lx,0x%08lx): stub\n",This,(DWORD)hwnd,dwflags);
761 if (TRACE_ON(dinput))
762 _dump_cooperativelevel(dwflags);
764 /* Store the window which asks for the mouse */
765 This->win = hwnd;
767 return 0;
771 /******************************************************************************
772 * SetDataFormat : the application can choose the format of the data
773 * the device driver sends back with GetDeviceState.
775 * For the moment, only the "standard" configuration (c_dfDIMouse) is supported
776 * in absolute and relative mode.
778 static HRESULT WINAPI SysMouseAImpl_SetDataFormat(
779 LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df
782 ICOM_THIS(SysMouseAImpl,iface);
783 int i;
785 TRACE("(this=%p,%p)\n",This,df);
787 TRACE("(df.dwSize=%ld)\n",df->dwSize);
788 TRACE("(df.dwObjsize=%ld)\n",df->dwObjSize);
789 TRACE("(df.dwFlags=0x%08lx)\n",df->dwFlags);
790 TRACE("(df.dwDataSize=%ld)\n",df->dwDataSize);
791 TRACE("(df.dwNumObjs=%ld)\n",df->dwNumObjs);
793 for (i=0;i<df->dwNumObjs;i++) {
794 char xbuf[50];
796 if (df->rgodf[i].pguid)
797 WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
798 else
799 strcpy(xbuf,"<no guid>");
800 TRACE("df.rgodf[%d].guid %s (%p)\n",i,xbuf, df->rgodf[i].pguid);
801 TRACE("df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
802 TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
803 TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
806 /* Check size of data format to prevent crashes if the applications
807 sends a smaller buffer */
808 if (df->dwDataSize != sizeof(struct DIMOUSESTATE)) {
809 FIXME("non-standard mouse configuration not supported yet.");
810 return DIERR_INVALIDPARAM;
813 /* For the moment, ignore these fields and return always as if
814 c_dfDIMouse was passed as format... */
816 /* Check if the mouse is in absolute or relative mode */
817 if (df->dwFlags == DIDF_ABSAXIS)
818 This->absolute = 1;
819 else if (df->dwFlags == DIDF_RELAXIS)
820 This->absolute = 0;
821 else
822 ERR("Neither absolute nor relative flag set.");
824 This->df = HeapAlloc(GetProcessHeap(),0,df->dwSize+(df->dwNumObjs*df->dwObjSize));
825 memcpy(This->df,df,df->dwSize+(df->dwNumObjs*df->dwObjSize));
826 return 0;
829 #define GEN_EVENT(offset,data,xtime,seq) \
831 if (This->queue_pos < This->queue_len) { \
832 This->data_queue[This->queue_pos].dwOfs = offset; \
833 This->data_queue[This->queue_pos].dwData = data; \
834 This->data_queue[This->queue_pos].dwTimeStamp = xtime; \
835 This->data_queue[This->queue_pos].dwSequence = seq; \
836 This->queue_pos++; \
841 /* Our private mouse event handler */
842 static void WINAPI dinput_mouse_event( DWORD dwFlags, DWORD dx, DWORD dy,
843 DWORD cButtons, DWORD dwExtraInfo )
845 DWORD posX, posY, keyState, xtime, extra;
846 SysMouseAImpl* This = (SysMouseAImpl*) current_lock;
848 EnterCriticalSection(&(This->crit));
849 /* Mouse moved -> send event if asked */
850 if (This->hEvent)
851 SetEvent(This->hEvent);
853 if ( !IsBadReadPtr( (LPVOID)dwExtraInfo, sizeof(WINE_MOUSEEVENT) )
854 && ((WINE_MOUSEEVENT *)dwExtraInfo)->magic == WINE_MOUSEEVENT_MAGIC ) {
855 WINE_MOUSEEVENT *wme = (WINE_MOUSEEVENT *)dwExtraInfo;
856 keyState = wme->keyState;
857 xtime = wme->time;
858 extra = (DWORD)wme->hWnd;
860 assert( dwFlags & MOUSEEVENTF_ABSOLUTE );
861 posX = (dx * GetSystemMetrics(SM_CXSCREEN)) >> 16;
862 posY = (dy * GetSystemMetrics(SM_CYSCREEN)) >> 16;
863 } else {
864 ERR("Mouse event not supported...\n");
865 LeaveCriticalSection(&(This->crit));
866 return ;
869 TRACE(" %ld %ld ", posX, posY);
871 if ( dwFlags & MOUSEEVENTF_MOVE ) {
872 if (This->absolute) {
873 if (posX != This->prevX)
874 GEN_EVENT(DIMOFS_X, posX, xtime, 0);
875 if (posY != This->prevY)
876 GEN_EVENT(DIMOFS_Y, posY, xtime, 0);
877 } else {
878 /* Relative mouse input : the real fun starts here... */
879 if (This->need_warp) {
880 if (posX != This->prevX)
881 GEN_EVENT(DIMOFS_X, posX - This->prevX, xtime, evsequence++);
882 if (posY != This->prevY)
883 GEN_EVENT(DIMOFS_Y, posY - This->prevY, xtime, evsequence++);
884 } else {
885 /* This is the first time the event handler has been called after a
886 GetData of GetState. */
887 if (posX != This->win_centerX) {
888 GEN_EVENT(DIMOFS_X, posX - This->win_centerX, xtime, evsequence++);
889 This->need_warp = 1;
892 if (posY != This->win_centerY) {
893 GEN_EVENT(DIMOFS_Y, posY - This->win_centerY, xtime, evsequence++);
894 This->need_warp = 1;
899 if ( dwFlags & MOUSEEVENTF_LEFTDOWN ) {
900 if (TRACE_ON(dinput))
901 DPRINTF(" LD ");
903 GEN_EVENT(DIMOFS_BUTTON0, 0xFF, xtime, evsequence++);
905 if ( dwFlags & MOUSEEVENTF_LEFTUP ) {
906 if (TRACE_ON(dinput))
907 DPRINTF(" LU ");
909 GEN_EVENT(DIMOFS_BUTTON0, 0x00, xtime, evsequence++);
911 if ( dwFlags & MOUSEEVENTF_RIGHTDOWN ) {
912 if (TRACE_ON(dinput))
913 DPRINTF(" RD ");
915 GEN_EVENT(DIMOFS_BUTTON1, 0xFF, xtime, evsequence++);
917 if ( dwFlags & MOUSEEVENTF_RIGHTUP ) {
918 if (TRACE_ON(dinput))
919 DPRINTF(" RU ");
921 GEN_EVENT(DIMOFS_BUTTON1, 0x00, xtime, evsequence++);
923 if ( dwFlags & MOUSEEVENTF_MIDDLEDOWN ) {
924 if (TRACE_ON(dinput))
925 DPRINTF(" MD ");
927 GEN_EVENT(DIMOFS_BUTTON2, 0xFF, xtime, evsequence++);
929 if ( dwFlags & MOUSEEVENTF_MIDDLEUP ) {
930 if (TRACE_ON(dinput))
931 DPRINTF(" MU ");
933 GEN_EVENT(DIMOFS_BUTTON2, 0x00, xtime, evsequence++);
935 if (TRACE_ON(dinput))
936 DPRINTF("\n");
938 This->prevX = posX;
939 This->prevY = posY;
940 LeaveCriticalSection(&(This->crit));
944 /******************************************************************************
945 * Acquire : gets exclusive control of the mouse
947 static HRESULT WINAPI SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface)
949 ICOM_THIS(SysMouseAImpl,iface);
950 RECT rect;
952 TRACE("(this=%p)\n",This);
954 if (This->acquired == 0) {
955 POINT point;
957 /* This stores the current mouse handler. */
958 This->prev_handler = mouse_event;
960 /* Store (in a global variable) the current lock */
961 current_lock = (IDirectInputDevice2A*)This;
963 /* Install our own mouse event handler */
964 MOUSE_Enable(dinput_mouse_event);
966 /* Get the window dimension and find the center */
967 GetWindowRect(This->win, &rect);
968 This->win_centerX = (rect.right - rect.left) / 2;
969 This->win_centerY = (rect.bottom - rect.top ) / 2;
971 /* Warp the mouse to the center of the window */
972 TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY);
973 point.x = This->win_centerX;
974 point.y = This->win_centerY;
975 MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
976 DISPLAY_MoveCursor(point.x, point.y);
978 This->acquired = 1;
980 return 0;
983 /******************************************************************************
984 * Unacquire : frees the mouse
986 static HRESULT WINAPI SysMouseAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface)
988 ICOM_THIS(SysMouseAImpl,iface);
990 TRACE("(this=%p)\n",This);
992 /* Reinstall previous mouse event handler */
993 MOUSE_Enable(This->prev_handler);
994 This->prev_handler = NULL;
996 /* No more locks */
997 current_lock = NULL;
999 /* Unacquire device */
1000 This->acquired = 0;
1002 return 0;
1005 /******************************************************************************
1006 * GetDeviceState : returns the "state" of the mouse.
1008 * For the moment, only the "standard" return structure (DIMOUSESTATE) is
1009 * supported.
1011 static HRESULT WINAPI SysMouseAImpl_GetDeviceState(
1012 LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr
1014 ICOM_THIS(SysMouseAImpl,iface);
1015 DWORD rx, ry, state;
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 /* Get the mouse position */
1027 EVENT_QueryPointer(&rx, &ry, &state);
1028 TRACE("(X:%ld - Y:%ld)\n", rx, ry);
1030 /* Fill the mouse state structure */
1031 if (This->absolute) {
1032 mstate->lX = rx;
1033 mstate->lY = ry;
1034 } else {
1035 mstate->lX = rx - This->win_centerX;
1036 mstate->lY = ry - This->win_centerY;
1038 if ((mstate->lX != 0) || (mstate->lY != 0))
1039 This->need_warp = 1;
1041 mstate->lZ = 0;
1042 mstate->rgbButtons[0] = (state & MK_LBUTTON ? 0xFF : 0x00);
1043 mstate->rgbButtons[1] = (state & MK_RBUTTON ? 0xFF : 0x00);
1044 mstate->rgbButtons[2] = (state & MK_MBUTTON ? 0xFF : 0x00);
1045 mstate->rgbButtons[3] = 0x00;
1047 /* Check if we need to do a mouse warping */
1048 if (This->need_warp) {
1049 POINT point;
1051 TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY);
1052 point.x = This->win_centerX;
1053 point.y = This->win_centerY;
1054 MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
1055 DISPLAY_MoveCursor(point.x, point.y);
1057 This->need_warp = 0;
1060 TRACE("(X: %ld - Y: %ld L: %02x M: %02x R: %02x)\n",
1061 mstate->lX, mstate->lY,
1062 mstate->rgbButtons[0], mstate->rgbButtons[2], mstate->rgbButtons[1]);
1064 return 0;
1067 /******************************************************************************
1068 * GetDeviceState : gets buffered input data.
1070 static HRESULT WINAPI SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE2A iface,
1071 DWORD dodsize,
1072 LPDIDEVICEOBJECTDATA dod,
1073 LPDWORD entries,
1074 DWORD flags
1076 ICOM_THIS(SysMouseAImpl,iface);
1078 EnterCriticalSection(&(This->crit));
1079 TRACE("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx)\n",This,dodsize,*entries,flags);
1081 if (flags & DIGDD_PEEK)
1082 FIXME("DIGDD_PEEK\n");
1084 if (dod == NULL) {
1085 *entries = This->queue_pos;
1086 This->queue_pos = 0;
1087 } else {
1088 /* Check for buffer overflow */
1089 if (This->queue_pos > *entries) {
1090 WARN("Buffer overflow not handled properly yet...\n");
1091 This->queue_pos = *entries;
1093 if (dodsize != sizeof(DIDEVICEOBJECTDATA)) {
1094 ERR("Wrong structure size !\n");
1095 LeaveCriticalSection(&(This->crit));
1096 return DIERR_INVALIDPARAM;
1099 if (This->queue_pos)
1100 TRACE("Application retrieving %d event(s).\n", This->queue_pos);
1102 /* Copy the buffered data into the application queue */
1103 memcpy(dod, This->data_queue, This->queue_pos * dodsize);
1104 *entries = This->queue_pos;
1106 /* Reset the event queue */
1107 This->queue_pos = 0;
1109 LeaveCriticalSection(&(This->crit));
1111 #if 0 /* FIXME: seems to create motion events, which fire back at us. */
1112 /* Check if we need to do a mouse warping */
1113 if (This->need_warp) {
1114 POINT point;
1116 TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY);
1117 point.x = This->win_centerX;
1118 point.y = This->win_centerY;
1119 MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
1121 DISPLAY_MoveCursor(point.x, point.y);
1123 This->need_warp = 0;
1125 #endif
1126 return 0;
1129 /******************************************************************************
1130 * SetProperty : change input device properties
1132 static HRESULT WINAPI SysMouseAImpl_SetProperty(LPDIRECTINPUTDEVICE2A iface,
1133 REFGUID rguid,
1134 LPCDIPROPHEADER ph)
1136 ICOM_THIS(SysMouseAImpl,iface);
1137 char xbuf[50];
1139 if (HIWORD(rguid))
1140 WINE_StringFromCLSID(rguid,xbuf);
1141 else
1142 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
1144 TRACE("(this=%p,%s,%p)\n",This,xbuf,ph);
1146 if (!HIWORD(rguid)) {
1147 switch ((DWORD)rguid) {
1148 case (DWORD) DIPROP_BUFFERSIZE: {
1149 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
1151 TRACE("buffersize = %ld\n",pd->dwData);
1153 This->data_queue = (LPDIDEVICEOBJECTDATA)HeapAlloc(GetProcessHeap(),0,
1154 pd->dwData * sizeof(DIDEVICEOBJECTDATA));
1155 This->queue_pos = 0;
1156 This->queue_len = pd->dwData;
1157 break;
1159 default:
1160 FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,xbuf);
1161 break;
1165 return 0;
1168 /******************************************************************************
1169 * SetEventNotification : specifies event to be sent on state change
1171 static HRESULT WINAPI SysMouseAImpl_SetEventNotification(LPDIRECTINPUTDEVICE2A iface,
1172 HANDLE hnd) {
1173 ICOM_THIS(SysMouseAImpl,iface);
1175 TRACE("(this=%p,0x%08lx)\n",This,(DWORD)hnd);
1177 This->hEvent = hnd;
1179 return DI_OK;
1182 #ifdef HAVE_LINUX_22_JOYSTICK_API
1183 /******************************************************************************
1184 * Joystick
1186 static ULONG WINAPI JoystickAImpl_Release(LPDIRECTINPUTDEVICE2A iface)
1188 ICOM_THIS(JoystickAImpl,iface);
1190 This->ref--;
1191 if (This->ref)
1192 return This->ref;
1193 HeapFree(GetProcessHeap(),0,This);
1194 return 0;
1197 /******************************************************************************
1198 * SetDataFormat : the application can choose the format of the data
1199 * the device driver sends back with GetDeviceState.
1201 static HRESULT WINAPI JoystickAImpl_SetDataFormat(
1202 LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df
1205 ICOM_THIS(JoystickAImpl,iface);
1206 int i;
1208 TRACE("(this=%p,%p)\n",This,df);
1210 TRACE("(df.dwSize=%ld)\n",df->dwSize);
1211 TRACE("(df.dwObjsize=%ld)\n",df->dwObjSize);
1212 TRACE("(df.dwFlags=0x%08lx)\n",df->dwFlags);
1213 TRACE("(df.dwDataSize=%ld)\n",df->dwDataSize);
1214 TRACE("(df.dwNumObjs=%ld)\n",df->dwNumObjs);
1216 for (i=0;i<df->dwNumObjs;i++) {
1217 char xbuf[50];
1219 if (df->rgodf[i].pguid)
1220 WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
1221 else
1222 strcpy(xbuf,"<no guid>");
1223 TRACE("df.rgodf[%d].guid %s (%p)\n",i,xbuf, df->rgodf[i].pguid);
1224 TRACE("df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
1225 TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
1226 TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
1228 This->df = HeapAlloc(GetProcessHeap(),0,df->dwSize+(df->dwNumObjs*df->dwObjSize));
1229 memcpy(This->df,df,df->dwSize+(df->dwNumObjs*df->dwObjSize));
1230 return 0;
1233 /******************************************************************************
1234 * Acquire : gets exclusive control of the joystick
1236 static HRESULT WINAPI JoystickAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface)
1238 ICOM_THIS(JoystickAImpl,iface);
1240 TRACE("(this=%p)\n",This);
1241 if (This->joyfd!=-1)
1242 return 0;
1243 This->joyfd=open(JOYDEV,O_RDONLY);
1244 if (This->joyfd==-1)
1245 return DIERR_NOTFOUND;
1246 return 0;
1249 /******************************************************************************
1250 * Unacquire : frees the joystick
1252 static HRESULT WINAPI JoystickAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface)
1254 ICOM_THIS(JoystickAImpl,iface);
1256 TRACE("(this=%p)\n",This);
1257 if (This->joyfd!=-1) {
1258 close(This->joyfd);
1259 This->joyfd = -1;
1261 return 0;
1264 #define map_axis(val) ((val+32768)*(This->lMax-This->lMin)/65536+This->lMin)
1266 static void joy_polldev(JoystickAImpl *This) {
1267 struct timeval tv;
1268 fd_set readfds;
1269 struct js_event jse;
1271 if (This->joyfd==-1)
1272 return;
1273 while (1) {
1274 memset(&tv,0,sizeof(tv));
1275 FD_ZERO(&readfds);FD_SET(This->joyfd,&readfds);
1276 if (1>select(This->joyfd+1,&readfds,NULL,NULL,&tv))
1277 return;
1278 /* we have one event, so we can read */
1279 if (sizeof(jse)!=read(This->joyfd,&jse,sizeof(jse))) {
1280 return;
1282 TRACE("js_event: type 0x%x, number %d, value %d\n",jse.type,jse.number,jse.value);
1283 if (jse.type & JS_EVENT_BUTTON) {
1284 GEN_EVENT(DIJOFS_BUTTON(jse.number),jse.value?0x80:0x00,jse.time,evsequence++);
1285 This->js.rgbButtons[jse.number] = jse.value?0x80:0x00;
1287 if (jse.type & JS_EVENT_AXIS) {
1288 switch (jse.number) {
1289 case 0:
1290 GEN_EVENT(jse.number*4,jse.value,jse.time,evsequence++);
1291 This->js.lX = map_axis(jse.value);
1292 break;
1293 case 1:
1294 GEN_EVENT(jse.number*4,jse.value,jse.time,evsequence++);
1295 This->js.lY = map_axis(jse.value);
1296 break;
1297 case 2:
1298 GEN_EVENT(jse.number*4,jse.value,jse.time,evsequence++);
1299 This->js.lZ = map_axis(jse.value);
1300 break;
1301 default:
1302 FIXME("more then 3 axes (%d) not handled!\n",jse.number);
1303 break;
1309 /******************************************************************************
1310 * GetDeviceState : returns the "state" of the joystick.
1313 static HRESULT WINAPI JoystickAImpl_GetDeviceState(
1314 LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr
1316 ICOM_THIS(JoystickAImpl,iface);
1318 joy_polldev(This);
1319 TRACE("(this=%p,0x%08lx,%p)\n",This,len,ptr);
1320 if (len != sizeof(DIJOYSTATE)) {
1321 FIXME("len %ld is not sizeof(DIJOYSTATE), unsupported format.\n",len);
1323 memcpy(ptr,&(This->js),len);
1324 This->queue_pos = 0;
1325 return 0;
1328 /******************************************************************************
1329 * GetDeviceState : gets buffered input data.
1331 static HRESULT WINAPI JoystickAImpl_GetDeviceData(LPDIRECTINPUTDEVICE2A iface,
1332 DWORD dodsize,
1333 LPDIDEVICEOBJECTDATA dod,
1334 LPDWORD entries,
1335 DWORD flags
1337 ICOM_THIS(JoystickAImpl,iface);
1339 FIXME("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx),STUB!\n",This,dodsize,*entries,flags);
1341 joy_polldev(This);
1342 if (flags & DIGDD_PEEK)
1343 FIXME("DIGDD_PEEK\n");
1345 if (dod == NULL) {
1346 } else {
1348 return 0;
1351 /******************************************************************************
1352 * SetProperty : change input device properties
1354 static HRESULT WINAPI JoystickAImpl_SetProperty(LPDIRECTINPUTDEVICE2A iface,
1355 REFGUID rguid,
1356 LPCDIPROPHEADER ph)
1358 ICOM_THIS(JoystickAImpl,iface);
1359 char xbuf[50];
1361 if (HIWORD(rguid))
1362 WINE_StringFromCLSID(rguid,xbuf);
1363 else
1364 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
1366 FIXME("(this=%p,%s,%p)\n",This,xbuf,ph);
1367 FIXME("ph.dwSize = %ld, ph.dwHeaderSize =%ld, ph.dwObj = %ld, ph.dwHow= %ld\n",ph->dwSize, ph->dwHeaderSize,ph->dwObj,ph->dwHow);
1369 if (!HIWORD(rguid)) {
1370 switch ((DWORD)rguid) {
1371 case (DWORD) DIPROP_BUFFERSIZE: {
1372 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
1374 FIXME("buffersize = %ld\n",pd->dwData);
1375 break;
1377 case (DWORD)DIPROP_RANGE: {
1378 LPCDIPROPRANGE pr = (LPCDIPROPRANGE)ph;
1380 FIXME("proprange(%ld,%ld)\n",pr->lMin,pr->lMax);
1381 This->lMin = pr->lMin;
1382 This->lMax = pr->lMax;
1383 break;
1385 case (DWORD)DIPROP_DEADZONE: {
1386 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
1388 FIXME("deadzone(%ld)\n",pd->dwData);
1389 This->deadzone = pd->dwData;
1390 break;
1392 default:
1393 FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,xbuf);
1394 break;
1397 return 0;
1400 /******************************************************************************
1401 * SetEventNotification : specifies event to be sent on state change
1403 static HRESULT WINAPI JoystickAImpl_SetEventNotification(
1404 LPDIRECTINPUTDEVICE2A iface, HANDLE hnd
1406 ICOM_THIS(JoystickAImpl,iface);
1408 TRACE("(this=%p,0x%08lx)\n",This,(DWORD)hnd);
1409 This->hEvent = hnd;
1410 return DI_OK;
1413 static HRESULT WINAPI JoystickAImpl_GetCapabilities(
1414 LPDIRECTINPUTDEVICE2A iface,
1415 LPDIDEVCAPS lpDIDevCaps)
1417 ICOM_THIS(JoystickAImpl,iface);
1418 BYTE axes,buttons;
1419 int xfd = This->joyfd;
1421 TRACE("%p->(%p)\n",iface,lpDIDevCaps);
1422 if (xfd==-1)
1423 xfd = open(JOYDEV,O_RDONLY);
1424 lpDIDevCaps->dwFlags = DIDC_ATTACHED;
1425 lpDIDevCaps->dwDevType = DIDEVTYPE_JOYSTICK;
1426 #ifdef JSIOCGAXES
1427 if (-1==ioctl(xfd,JSIOCGAXES,&axes))
1428 axes = 2;
1429 lpDIDevCaps->dwAxes = axes;
1430 #endif
1431 #ifdef JSIOCGBUTTONS
1432 if (-1==ioctl(xfd,JSIOCGAXES,&buttons))
1433 buttons = 2;
1434 lpDIDevCaps->dwButtons = buttons;
1435 #endif
1436 if (xfd!=This->joyfd)
1437 close(xfd);
1438 return DI_OK;
1440 static HRESULT WINAPI JoystickAImpl_Poll(LPDIRECTINPUTDEVICE2A iface) {
1441 ICOM_THIS(JoystickAImpl,iface);
1442 TRACE("(),stub!\n");
1444 joy_polldev(This);
1445 return DI_OK;
1447 #endif
1449 /****************************************************************************/
1450 /****************************************************************************/
1452 static ICOM_VTABLE(IDirectInputDevice2A) SysKeyboardAvt =
1454 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1455 IDirectInputDevice2AImpl_QueryInterface,
1456 IDirectInputDevice2AImpl_AddRef,
1457 IDirectInputDevice2AImpl_Release,
1458 IDirectInputDevice2AImpl_GetCapabilities,
1459 IDirectInputDevice2AImpl_EnumObjects,
1460 IDirectInputDevice2AImpl_GetProperty,
1461 SysKeyboardAImpl_SetProperty,
1462 SysKeyboardAImpl_Acquire,
1463 SysKeyboardAImpl_Unacquire,
1464 SysKeyboardAImpl_GetDeviceState,
1465 SysKeyboardAImpl_GetDeviceData,
1466 IDirectInputDevice2AImpl_SetDataFormat,
1467 IDirectInputDevice2AImpl_SetEventNotification,
1468 IDirectInputDevice2AImpl_SetCooperativeLevel,
1469 IDirectInputDevice2AImpl_GetObjectInfo,
1470 IDirectInputDevice2AImpl_GetDeviceInfo,
1471 IDirectInputDevice2AImpl_RunControlPanel,
1472 IDirectInputDevice2AImpl_Initialize,
1473 IDirectInputDevice2AImpl_CreateEffect,
1474 IDirectInputDevice2AImpl_EnumEffects,
1475 IDirectInputDevice2AImpl_GetEffectInfo,
1476 IDirectInputDevice2AImpl_GetForceFeedbackState,
1477 IDirectInputDevice2AImpl_SendForceFeedbackCommand,
1478 IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
1479 IDirectInputDevice2AImpl_Escape,
1480 IDirectInputDevice2AImpl_Poll,
1481 IDirectInputDevice2AImpl_SendDeviceData,
1484 static ICOM_VTABLE(IDirectInputDevice2A) SysMouseAvt =
1486 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1487 IDirectInputDevice2AImpl_QueryInterface,
1488 IDirectInputDevice2AImpl_AddRef,
1489 SysMouseAImpl_Release,
1490 IDirectInputDevice2AImpl_GetCapabilities,
1491 IDirectInputDevice2AImpl_EnumObjects,
1492 IDirectInputDevice2AImpl_GetProperty,
1493 SysMouseAImpl_SetProperty,
1494 SysMouseAImpl_Acquire,
1495 SysMouseAImpl_Unacquire,
1496 SysMouseAImpl_GetDeviceState,
1497 SysMouseAImpl_GetDeviceData,
1498 SysMouseAImpl_SetDataFormat,
1499 SysMouseAImpl_SetEventNotification,
1500 SysMouseAImpl_SetCooperativeLevel,
1501 IDirectInputDevice2AImpl_GetObjectInfo,
1502 IDirectInputDevice2AImpl_GetDeviceInfo,
1503 IDirectInputDevice2AImpl_RunControlPanel,
1504 IDirectInputDevice2AImpl_Initialize,
1505 IDirectInputDevice2AImpl_CreateEffect,
1506 IDirectInputDevice2AImpl_EnumEffects,
1507 IDirectInputDevice2AImpl_GetEffectInfo,
1508 IDirectInputDevice2AImpl_GetForceFeedbackState,
1509 IDirectInputDevice2AImpl_SendForceFeedbackCommand,
1510 IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
1511 IDirectInputDevice2AImpl_Escape,
1512 IDirectInputDevice2AImpl_Poll,
1513 IDirectInputDevice2AImpl_SendDeviceData,
1516 #ifdef HAVE_LINUX_22_JOYSTICK_API
1517 static ICOM_VTABLE(IDirectInputDevice2A) JoystickAvt =
1519 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1520 IDirectInputDevice2AImpl_QueryInterface,
1521 IDirectInputDevice2AImpl_AddRef,
1522 JoystickAImpl_Release,
1523 JoystickAImpl_GetCapabilities,
1524 IDirectInputDevice2AImpl_EnumObjects,
1525 IDirectInputDevice2AImpl_GetProperty,
1526 JoystickAImpl_SetProperty,
1527 JoystickAImpl_Acquire,
1528 JoystickAImpl_Unacquire,
1529 JoystickAImpl_GetDeviceState,
1530 JoystickAImpl_GetDeviceData,
1531 JoystickAImpl_SetDataFormat,
1532 JoystickAImpl_SetEventNotification,
1533 IDirectInputDevice2AImpl_SetCooperativeLevel,
1534 IDirectInputDevice2AImpl_GetObjectInfo,
1535 IDirectInputDevice2AImpl_GetDeviceInfo,
1536 IDirectInputDevice2AImpl_RunControlPanel,
1537 IDirectInputDevice2AImpl_Initialize,
1538 IDirectInputDevice2AImpl_CreateEffect,
1539 IDirectInputDevice2AImpl_EnumEffects,
1540 IDirectInputDevice2AImpl_GetEffectInfo,
1541 IDirectInputDevice2AImpl_GetForceFeedbackState,
1542 IDirectInputDevice2AImpl_SendForceFeedbackCommand,
1543 IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
1544 IDirectInputDevice2AImpl_Escape,
1545 JoystickAImpl_Poll,
1546 IDirectInputDevice2AImpl_SendDeviceData,
1548 #endif