Stubs for Get/SetProcessDefaultLayout.
[wine.git] / windows / dinput.c
blob40c8a34c927ef784d1dc101dc5d86563ee64b0d1
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;
129 /* This is for mouse reporting. */
130 struct DIMOUSESTATE m_state;
133 static int evsequence=0;
136 /* UIDs for Wine "drivers".
137 When enumerating each device supporting DInput, they have two UIDs :
138 - the 'windows' UID
139 - a vendor UID */
140 #ifdef HAVE_LINUX_22_JOYSTICK_API
141 static GUID DInput_Wine_Joystick_GUID = { /* 9e573ed9-7734-11d2-8d4a-23903fb6bdf7 */
142 0x9e573ed9,
143 0x7734,
144 0x11d2,
145 {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
147 #endif
148 static GUID DInput_Wine_Mouse_GUID = { /* 9e573ed8-7734-11d2-8d4a-23903fb6bdf7 */
149 0x9e573ed8,
150 0x7734,
151 0x11d2,
152 {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
154 static GUID DInput_Wine_Keyboard_GUID = { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */
155 0x0ab8648a,
156 0x7735,
157 0x11d2,
158 {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41}
161 /* FIXME: This is ugly and not thread safe :/ */
162 static IDirectInputDevice2A* current_lock = NULL;
164 /******************************************************************************
165 * Various debugging tools
167 static void _dump_cooperativelevel(DWORD dwFlags) {
168 int i;
169 const struct {
170 DWORD mask;
171 char *name;
172 } flags[] = {
173 #define FE(x) { x, #x},
174 FE(DISCL_BACKGROUND)
175 FE(DISCL_EXCLUSIVE)
176 FE(DISCL_FOREGROUND)
177 FE(DISCL_NONEXCLUSIVE)
179 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
180 if (flags[i].mask & dwFlags)
181 DPRINTF("%s ",flags[i].name);
182 DPRINTF("\n");
185 struct IDirectInputAImpl
187 ICOM_VFIELD(IDirectInputA);
188 DWORD ref;
191 /******************************************************************************
192 * DirectInputCreate32A
194 HRESULT WINAPI DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA *ppDI, LPUNKNOWN punkOuter)
196 IDirectInputAImpl* This;
197 TRACE("(0x%08lx,%04lx,%p,%p)\n",
198 (DWORD)hinst,dwVersion,ppDI,punkOuter
200 This = (IDirectInputAImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl));
201 This->ref = 1;
202 ICOM_VTBL(This) = &ddiavt;
203 *ppDI=(IDirectInputA*)This;
204 return 0;
206 /******************************************************************************
207 * IDirectInputA_EnumDevices
209 static HRESULT WINAPI IDirectInputAImpl_EnumDevices(
210 LPDIRECTINPUTA iface, DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback,
211 LPVOID pvRef, DWORD dwFlags
214 ICOM_THIS(IDirectInputAImpl,iface);
215 DIDEVICEINSTANCEA devInstance;
216 int ret;
218 TRACE("(this=%p,0x%04lx,%p,%p,%04lx)\n", This, dwDevType, lpCallback, pvRef, dwFlags);
220 devInstance.dwSize = sizeof(DIDEVICEINSTANCEA);
221 if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_KEYBOARD)) {
222 /* Return keyboard */
223 devInstance.guidInstance = GUID_SysKeyboard;/* DInput's GUID */
224 devInstance.guidProduct = DInput_Wine_Keyboard_GUID; /* Vendor's GUID */
225 devInstance.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8);
226 strcpy(devInstance.tszInstanceName, "Keyboard");
227 strcpy(devInstance.tszProductName, "Wine Keyboard");
229 ret = lpCallback(&devInstance, pvRef);
230 TRACE("Keyboard registered\n");
231 if (ret == DIENUM_STOP)
232 return 0;
235 if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_MOUSE)) {
236 /* Return mouse */
237 devInstance.guidInstance = GUID_SysMouse;/* DInput's GUID */
238 devInstance.guidProduct = DInput_Wine_Mouse_GUID; /* Vendor's GUID */
239 devInstance.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_UNKNOWN << 8);
240 strcpy(devInstance.tszInstanceName, "Mouse");
241 strcpy(devInstance.tszProductName, "Wine Mouse");
243 ret = lpCallback(&devInstance, pvRef);
244 TRACE("Mouse registered\n");
245 if (ret == DIENUM_STOP)
246 return 0;
248 if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_JOYSTICK)) {
249 /* check whether we have a joystick */
250 #ifdef HAVE_LINUX_22_JOYSTICK_API
251 if ( (access(JOYDEV,O_RDONLY)!=-1) ||
252 (errno!=ENODEV && errno!=ENOENT)
254 /* Return joystick */
255 devInstance.guidInstance = GUID_Joystick;
256 devInstance.guidProduct = DInput_Wine_Joystick_GUID;
257 /* we only support traditional joysticks for now */
258 devInstance.dwDevType = DIDEVTYPE_JOYSTICK | DIDEVTYPEJOYSTICK_TRADITIONAL;
259 strcpy(devInstance.tszInstanceName, "Joystick");
260 /* ioctl JSIOCGNAME(len) */
261 strcpy(devInstance.tszProductName, "Wine Joystick");
263 ret = lpCallback(&devInstance,pvRef);
264 TRACE("Joystick registered\n");
265 if (ret == DIENUM_STOP)
266 return 0;
268 #endif
270 return 0;
273 static ULONG WINAPI IDirectInputAImpl_AddRef(LPDIRECTINPUTA iface)
275 ICOM_THIS(IDirectInputAImpl,iface);
276 return ++(This->ref);
279 static ULONG WINAPI IDirectInputAImpl_Release(LPDIRECTINPUTA iface)
281 ICOM_THIS(IDirectInputAImpl,iface);
282 if (!(--This->ref)) {
283 HeapFree(GetProcessHeap(),0,This);
284 return 0;
286 return This->ref;
289 static HRESULT WINAPI IDirectInputAImpl_CreateDevice(
290 LPDIRECTINPUTA iface,REFGUID rguid,LPDIRECTINPUTDEVICEA* pdev,
291 LPUNKNOWN punk
293 ICOM_THIS(IDirectInputAImpl,iface);
294 char xbuf[50];
296 WINE_StringFromCLSID(rguid,xbuf);
297 FIXME("(this=%p,%s,%p,%p): stub\n",This,xbuf,pdev,punk);
298 if ((!memcmp(&GUID_SysKeyboard,rguid,sizeof(GUID_SysKeyboard))) || /* Generic Keyboard */
299 (!memcmp(&DInput_Wine_Keyboard_GUID,rguid,sizeof(GUID_SysKeyboard)))) { /* Wine Keyboard */
300 SysKeyboardAImpl* newDevice;
301 newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysKeyboardAImpl));
302 newDevice->ref = 1;
303 ICOM_VTBL(newDevice) = &SysKeyboardAvt;
304 memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
305 memset(newDevice->keystate,0,256);
306 *pdev=(IDirectInputDeviceA*)newDevice;
307 return DI_OK;
309 if ((!memcmp(&GUID_SysMouse,rguid,sizeof(GUID_SysMouse))) || /* Generic Mouse */
310 (!memcmp(&DInput_Wine_Mouse_GUID,rguid,sizeof(GUID_SysMouse)))) { /* Wine Mouse */
311 SysMouseAImpl* newDevice;
312 newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysMouseAImpl));
313 newDevice->ref = 1;
314 ICOM_VTBL(newDevice) = &SysMouseAvt;
315 InitializeCriticalSection(&(newDevice->crit));
316 MakeCriticalSectionGlobal(&(newDevice->crit));
317 memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
318 *pdev=(IDirectInputDeviceA*)newDevice;
319 return DI_OK;
321 #ifdef HAVE_LINUX_22_JOYSTICK_API
322 if ((!memcmp(&GUID_Joystick,rguid,sizeof(GUID_Joystick))) ||
323 (!memcmp(&DInput_Wine_Joystick_GUID,rguid,sizeof(GUID_Joystick)))) {
324 JoystickAImpl* newDevice;
325 newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(JoystickAImpl));
326 newDevice->ref = 1;
327 ICOM_VTBL(newDevice) = &JoystickAvt;
328 newDevice->joyfd = -1;
329 memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
330 *pdev=(IDirectInputDeviceA*)newDevice;
331 return DI_OK;
333 #endif
334 return E_FAIL;
337 static HRESULT WINAPI IDirectInputAImpl_QueryInterface(
338 LPDIRECTINPUTA iface,REFIID riid,LPVOID *ppobj
340 ICOM_THIS(IDirectInputAImpl,iface);
341 char xbuf[50];
343 WINE_StringFromCLSID(riid,xbuf);
344 TRACE("(this=%p,%s,%p)\n",This,xbuf,ppobj);
345 if (!memcmp(&IID_IUnknown,riid,sizeof(*riid))) {
346 IDirectInputA_AddRef(iface);
347 *ppobj = This;
348 return 0;
350 if (!memcmp(&IID_IDirectInputA,riid,sizeof(*riid))) {
351 IDirectInputA_AddRef(iface);
352 *ppobj = This;
353 return 0;
355 return E_FAIL;
358 static HRESULT WINAPI IDirectInputAImpl_Initialize(
359 LPDIRECTINPUTA iface,HINSTANCE hinst,DWORD x
361 return DIERR_ALREADYINITIALIZED;
364 static HRESULT WINAPI IDirectInputAImpl_GetDeviceStatus(LPDIRECTINPUTA iface,
365 REFGUID rguid) {
366 ICOM_THIS(IDirectInputAImpl,iface);
367 char xbuf[50];
369 WINE_StringFromCLSID(rguid,xbuf);
370 FIXME("(%p)->(%s): stub\n",This,xbuf);
372 return DI_OK;
375 static HRESULT WINAPI IDirectInputAImpl_RunControlPanel(LPDIRECTINPUTA iface,
376 HWND hwndOwner,
377 DWORD dwFlags) {
378 ICOM_THIS(IDirectInputAImpl,iface);
379 FIXME("(%p)->(%08lx,%08lx): stub\n",This, (DWORD) hwndOwner, dwFlags);
381 return DI_OK;
384 static ICOM_VTABLE(IDirectInputA) ddiavt =
386 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
387 IDirectInputAImpl_QueryInterface,
388 IDirectInputAImpl_AddRef,
389 IDirectInputAImpl_Release,
390 IDirectInputAImpl_CreateDevice,
391 IDirectInputAImpl_EnumDevices,
392 IDirectInputAImpl_GetDeviceStatus,
393 IDirectInputAImpl_RunControlPanel,
394 IDirectInputAImpl_Initialize
397 /******************************************************************************
398 * IDirectInputDeviceA
401 static HRESULT WINAPI IDirectInputDevice2AImpl_SetDataFormat(
402 LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df
405 int i;
406 TRACE(dinput,"(this=%p,%p)\n",This,df);
408 TRACE(dinput,"df.dwSize=%ld\n",df->dwSize);
409 TRACE(dinput,"(df.dwObjsize=%ld)\n",df->dwObjSize);
410 TRACE(dinput,"(df.dwFlags=0x%08lx)\n",df->dwFlags);
411 TRACE(dinput,"(df.dwDataSize=%ld)\n",df->dwDataSize);
412 TRACE(dinput,"(df.dwNumObjs=%ld)\n",df->dwNumObjs);
414 for (i=0;i<df->dwNumObjs;i++) {
415 char xbuf[50];
417 if (df->rgodf[i].pguid)
418 WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
419 else
420 strcpy(xbuf,"<no guid>");
421 TRACE(dinput,"df.rgodf[%d].guid %s\n",i,xbuf);
422 TRACE(dinput,"df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
423 TRACE(dinput,"dwType 0x%02lx,dwInstance %ld\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
424 TRACE(dinput,"df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
427 return 0;
430 static HRESULT WINAPI IDirectInputDevice2AImpl_SetCooperativeLevel(
431 LPDIRECTINPUTDEVICE2A iface,HWND hwnd,DWORD dwflags
433 ICOM_THIS(IDirectInputDevice2AImpl,iface);
434 FIXME("(this=%p,0x%08lx,0x%08lx): stub\n",This,(DWORD)hwnd,dwflags);
435 if (TRACE_ON(dinput))
436 _dump_cooperativelevel(dwflags);
437 return 0;
440 static HRESULT WINAPI IDirectInputDevice2AImpl_SetEventNotification(
441 LPDIRECTINPUTDEVICE2A iface,HANDLE hnd
443 ICOM_THIS(IDirectInputDevice2AImpl,iface);
444 FIXME("(this=%p,0x%08lx): stub\n",This,(DWORD)hnd);
445 return 0;
448 static ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE2A iface)
450 ICOM_THIS(IDirectInputDevice2AImpl,iface);
451 This->ref--;
452 if (This->ref)
453 return This->ref;
454 HeapFree(GetProcessHeap(),0,This);
455 return 0;
458 static HRESULT WINAPI SysKeyboardAImpl_SetProperty(
459 LPDIRECTINPUTDEVICE2A iface,REFGUID rguid,LPCDIPROPHEADER ph
462 ICOM_THIS(SysKeyboardAImpl,iface);
463 char xbuf[50];
465 if (HIWORD(rguid))
466 WINE_StringFromCLSID(rguid,xbuf);
467 else
468 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
469 TRACE("(this=%p,%s,%p)\n",This,xbuf,ph);
470 TRACE("(size=%ld,headersize=%ld,obj=%ld,how=%ld\n",
471 ph->dwSize,ph->dwHeaderSize,ph->dwObj,ph->dwHow);
472 if (!HIWORD(rguid)) {
473 switch ((DWORD)rguid) {
474 case (DWORD) DIPROP_BUFFERSIZE: {
475 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
477 TRACE("(buffersize=%ld)\n",pd->dwData);
478 break;
480 default:
481 WARN("Unknown type %ld\n",(DWORD)rguid);
482 break;
485 return 0;
488 static HRESULT WINAPI SysKeyboardAImpl_GetDeviceState(
489 LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr
492 return KEYBOARD_Driver->pGetDIState(len, ptr)?DI_OK:E_FAIL;
495 static HRESULT WINAPI SysKeyboardAImpl_GetDeviceData(
496 LPDIRECTINPUTDEVICE2A iface,DWORD dodsize,LPDIDEVICEOBJECTDATA dod,
497 LPDWORD entries,DWORD flags
500 ICOM_THIS(SysKeyboardAImpl,iface);
501 HRESULT ret;
502 int i;
504 TRACE("(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n",
505 This,dodsize,dod,entries,entries?*entries:0,flags);
507 ret=KEYBOARD_Driver->pGetDIData(
508 This->keystate, dodsize, dod, entries, flags)?DI_OK:E_FAIL;
509 for (i=0;i<*entries;i++) {
510 dod[i].dwTimeStamp = time(NULL);
511 dod[i].dwSequence = evsequence++;
513 return ret;
516 static HRESULT WINAPI SysKeyboardAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface)
518 ICOM_THIS(SysKeyboardAImpl,iface);
519 TRACE("(this=%p): stub\n",This);
520 return 0;
523 static HRESULT WINAPI SysKeyboardAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface)
525 ICOM_THIS(SysKeyboardAImpl,iface);
526 TRACE("(this=%p): stub\n",This);
527 return 0;
530 static HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface(
531 LPDIRECTINPUTDEVICE2A iface,REFIID riid,LPVOID *ppobj
534 ICOM_THIS(IDirectInputDevice2AImpl,iface);
535 char xbuf[50];
537 WINE_StringFromCLSID(riid,xbuf);
538 TRACE("(this=%p,%s,%p)\n",This,xbuf,ppobj);
539 if (!memcmp(&IID_IUnknown,riid,sizeof(*riid))) {
540 IDirectInputDevice2_AddRef(iface);
541 *ppobj = This;
542 return 0;
544 if (!memcmp(&IID_IDirectInputDeviceA,riid,sizeof(*riid))) {
545 IDirectInputDevice2_AddRef(iface);
546 *ppobj = This;
547 return 0;
549 if (!memcmp(&IID_IDirectInputDevice2A,riid,sizeof(*riid))) {
550 IDirectInputDevice2_AddRef(iface);
551 *ppobj = This;
552 return 0;
554 return E_FAIL;
557 static ULONG WINAPI IDirectInputDevice2AImpl_AddRef(
558 LPDIRECTINPUTDEVICE2A iface)
560 ICOM_THIS(IDirectInputDevice2AImpl,iface);
561 return ++This->ref;
564 static HRESULT WINAPI IDirectInputDevice2AImpl_GetCapabilities(
565 LPDIRECTINPUTDEVICE2A iface,
566 LPDIDEVCAPS lpDIDevCaps)
568 lpDIDevCaps->dwFlags = DIDC_ATTACHED;
569 FIXME("stub!\n");
570 return DI_OK;
573 static HRESULT WINAPI IDirectInputDevice2AImpl_EnumObjects(
574 LPDIRECTINPUTDEVICE2A iface,
575 LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback,
576 LPVOID lpvRef,
577 DWORD dwFlags)
579 FIXME("stub!\n");
580 #if 0
581 if (lpCallback)
582 lpCallback(NULL, lpvRef);
583 #endif
584 return DI_OK;
587 static HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty(
588 LPDIRECTINPUTDEVICE2A iface,
589 REFGUID rguid,
590 LPDIPROPHEADER pdiph)
592 FIXME("stub!\n");
593 return DI_OK;
596 static HRESULT WINAPI IDirectInputDevice2AImpl_GetObjectInfo(
597 LPDIRECTINPUTDEVICE2A iface,
598 LPDIDEVICEOBJECTINSTANCEA pdidoi,
599 DWORD dwObj,
600 DWORD dwHow)
602 FIXME("stub!\n");
603 return DI_OK;
606 static HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceInfo(
607 LPDIRECTINPUTDEVICE2A iface,
608 LPDIDEVICEINSTANCEA pdidi)
610 FIXME("stub!\n");
611 return DI_OK;
614 static HRESULT WINAPI IDirectInputDevice2AImpl_RunControlPanel(
615 LPDIRECTINPUTDEVICE2A iface,
616 HWND hwndOwner,
617 DWORD dwFlags)
619 FIXME("stub!\n");
620 return DI_OK;
623 static HRESULT WINAPI IDirectInputDevice2AImpl_Initialize(
624 LPDIRECTINPUTDEVICE2A iface,
625 HINSTANCE hinst,
626 DWORD dwVersion,
627 REFGUID rguid)
629 FIXME("stub!\n");
630 return DI_OK;
633 /******************************************************************************
634 * IDirectInputDevice2A
637 static HRESULT WINAPI IDirectInputDevice2AImpl_CreateEffect(
638 LPDIRECTINPUTDEVICE2A iface,
639 REFGUID rguid,
640 LPCDIEFFECT lpeff,
641 LPDIRECTINPUTEFFECT *ppdef,
642 LPUNKNOWN pUnkOuter)
644 FIXME("stub!\n");
645 return DI_OK;
648 static HRESULT WINAPI IDirectInputDevice2AImpl_EnumEffects(
649 LPDIRECTINPUTDEVICE2A iface,
650 LPDIENUMEFFECTSCALLBACKA lpCallback,
651 LPVOID lpvRef,
652 DWORD dwFlags)
654 FIXME("stub!\n");
655 if (lpCallback)
656 lpCallback(NULL, lpvRef);
657 return DI_OK;
660 static HRESULT WINAPI IDirectInputDevice2AImpl_GetEffectInfo(
661 LPDIRECTINPUTDEVICE2A iface,
662 LPDIEFFECTINFOA lpdei,
663 REFGUID rguid)
665 FIXME("stub!\n");
666 return DI_OK;
669 static HRESULT WINAPI IDirectInputDevice2AImpl_GetForceFeedbackState(
670 LPDIRECTINPUTDEVICE2A iface,
671 LPDWORD pdwOut)
673 FIXME("stub!\n");
674 return DI_OK;
677 static HRESULT WINAPI IDirectInputDevice2AImpl_SendForceFeedbackCommand(
678 LPDIRECTINPUTDEVICE2A iface,
679 DWORD dwFlags)
681 FIXME("stub!\n");
682 return DI_OK;
685 static HRESULT WINAPI IDirectInputDevice2AImpl_EnumCreatedEffectObjects(
686 LPDIRECTINPUTDEVICE2A iface,
687 LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback,
688 LPVOID lpvRef,
689 DWORD dwFlags)
691 FIXME("stub!\n");
692 if (lpCallback)
693 lpCallback(NULL, lpvRef);
694 return DI_OK;
697 static HRESULT WINAPI IDirectInputDevice2AImpl_Escape(
698 LPDIRECTINPUTDEVICE2A iface,
699 LPDIEFFESCAPE lpDIEEsc)
701 FIXME("stub!\n");
702 return DI_OK;
705 static HRESULT WINAPI IDirectInputDevice2AImpl_Poll(
706 LPDIRECTINPUTDEVICE2A iface)
708 FIXME("stub!\n");
709 return DI_OK;
712 static HRESULT WINAPI IDirectInputDevice2AImpl_SendDeviceData(
713 LPDIRECTINPUTDEVICE2A iface,
714 DWORD cbObjectData,
715 LPDIDEVICEOBJECTDATA rgdod,
716 LPDWORD pdwInOut,
717 DWORD dwFlags)
719 FIXME("stub!\n");
720 return DI_OK;
723 /******************************************************************************
724 * SysMouseA (DInput Mouse support)
727 /******************************************************************************
728 * Release : release the mouse buffer.
730 static ULONG WINAPI SysMouseAImpl_Release(LPDIRECTINPUTDEVICE2A iface)
732 ICOM_THIS(SysMouseAImpl,iface);
734 This->ref--;
735 if (This->ref)
736 return This->ref;
738 /* Free the data queue */
739 if (This->data_queue != NULL)
740 HeapFree(GetProcessHeap(),0,This->data_queue);
742 /* Install the previous event handler (in case of releasing an aquired
743 mouse device) */
744 if (This->prev_handler != NULL)
745 MOUSE_Enable(This->prev_handler);
746 DeleteCriticalSection(&(This->crit));
748 HeapFree(GetProcessHeap(),0,This);
749 return 0;
753 /******************************************************************************
754 * SetCooperativeLevel : store the window in which we will do our
755 * grabbing.
757 static HRESULT WINAPI SysMouseAImpl_SetCooperativeLevel(
758 LPDIRECTINPUTDEVICE2A iface,HWND hwnd,DWORD dwflags
761 ICOM_THIS(SysMouseAImpl,iface);
763 TRACE("(this=%p,0x%08lx,0x%08lx): stub\n",This,(DWORD)hwnd,dwflags);
765 if (TRACE_ON(dinput))
766 _dump_cooperativelevel(dwflags);
768 /* Store the window which asks for the mouse */
769 This->win = hwnd;
771 return 0;
775 /******************************************************************************
776 * SetDataFormat : the application can choose the format of the data
777 * the device driver sends back with GetDeviceState.
779 * For the moment, only the "standard" configuration (c_dfDIMouse) is supported
780 * in absolute and relative mode.
782 static HRESULT WINAPI SysMouseAImpl_SetDataFormat(
783 LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df
786 ICOM_THIS(SysMouseAImpl,iface);
787 int i;
789 TRACE("(this=%p,%p)\n",This,df);
791 TRACE("(df.dwSize=%ld)\n",df->dwSize);
792 TRACE("(df.dwObjsize=%ld)\n",df->dwObjSize);
793 TRACE("(df.dwFlags=0x%08lx)\n",df->dwFlags);
794 TRACE("(df.dwDataSize=%ld)\n",df->dwDataSize);
795 TRACE("(df.dwNumObjs=%ld)\n",df->dwNumObjs);
797 for (i=0;i<df->dwNumObjs;i++) {
798 char xbuf[50];
800 if (df->rgodf[i].pguid)
801 WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
802 else
803 strcpy(xbuf,"<no guid>");
804 TRACE("df.rgodf[%d].guid %s (%p)\n",i,xbuf, df->rgodf[i].pguid);
805 TRACE("df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
806 TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
807 TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
810 /* Check size of data format to prevent crashes if the applications
811 sends a smaller buffer */
812 if (df->dwDataSize != sizeof(struct DIMOUSESTATE)) {
813 FIXME("non-standard mouse configuration not supported yet.");
814 return DIERR_INVALIDPARAM;
817 /* For the moment, ignore these fields and return always as if
818 c_dfDIMouse was passed as format... */
820 /* Check if the mouse is in absolute or relative mode */
821 if (df->dwFlags == DIDF_ABSAXIS)
822 This->absolute = 1;
823 else if (df->dwFlags == DIDF_RELAXIS)
824 This->absolute = 0;
825 else
826 ERR("Neither absolute nor relative flag set.");
828 This->df = HeapAlloc(GetProcessHeap(),0,df->dwSize+(df->dwNumObjs*df->dwObjSize));
829 memcpy(This->df,df,df->dwSize+(df->dwNumObjs*df->dwObjSize));
830 return 0;
833 #define GEN_EVENT(offset,data,xtime,seq) \
835 if (This->queue_pos < This->queue_len) { \
836 This->data_queue[This->queue_pos].dwOfs = offset; \
837 This->data_queue[This->queue_pos].dwData = data; \
838 This->data_queue[This->queue_pos].dwTimeStamp = xtime; \
839 This->data_queue[This->queue_pos].dwSequence = seq; \
840 This->queue_pos++; \
845 /* Our private mouse event handler */
846 static void WINAPI dinput_mouse_event( DWORD dwFlags, DWORD dx, DWORD dy,
847 DWORD cButtons, DWORD dwExtraInfo )
849 DWORD posX, posY, keyState, xtime, extra;
850 SysMouseAImpl* This = (SysMouseAImpl*) current_lock;
852 EnterCriticalSection(&(This->crit));
853 /* Mouse moved -> send event if asked */
854 if (This->hEvent)
855 SetEvent(This->hEvent);
857 if ( !IsBadReadPtr( (LPVOID)dwExtraInfo, sizeof(WINE_MOUSEEVENT) )
858 && ((WINE_MOUSEEVENT *)dwExtraInfo)->magic == WINE_MOUSEEVENT_MAGIC ) {
859 WINE_MOUSEEVENT *wme = (WINE_MOUSEEVENT *)dwExtraInfo;
860 keyState = wme->keyState;
861 xtime = wme->time;
862 extra = (DWORD)wme->hWnd;
864 if ((dwFlags & MOUSEEVENTF_MOVE) &&
865 (dwFlags & MOUSEEVENTF_ABSOLUTE)) {
866 posX = (dx * GetSystemMetrics(SM_CXSCREEN)) >> 16;
867 posY = (dy * GetSystemMetrics(SM_CYSCREEN)) >> 16;
868 } else {
869 posX = This->prevX;
870 posY = This->prevY;
872 } else {
873 ERR("Mouse event not supported...\n");
874 LeaveCriticalSection(&(This->crit));
875 return ;
878 TRACE(" %ld %ld ", posX, posY);
880 if ( dwFlags & MOUSEEVENTF_MOVE ) {
881 if (This->absolute) {
882 if (posX != This->prevX)
883 GEN_EVENT(DIMOFS_X, posX, xtime, 0);
884 if (posY != This->prevY)
885 GEN_EVENT(DIMOFS_Y, posY, xtime, 0);
886 } else {
887 /* Relative mouse input : the real fun starts here... */
888 if (This->need_warp) {
889 if (posX != This->prevX)
890 GEN_EVENT(DIMOFS_X, posX - This->prevX, xtime, evsequence++);
891 if (posY != This->prevY)
892 GEN_EVENT(DIMOFS_Y, posY - This->prevY, xtime, evsequence++);
893 } else {
894 /* This is the first time the event handler has been called after a
895 GetData of GetState. */
896 if (posX != This->win_centerX) {
897 GEN_EVENT(DIMOFS_X, posX - This->win_centerX, xtime, evsequence++);
898 This->need_warp = 1;
901 if (posY != This->win_centerY) {
902 GEN_EVENT(DIMOFS_Y, posY - This->win_centerY, xtime, evsequence++);
903 This->need_warp = 1;
908 if ( dwFlags & MOUSEEVENTF_LEFTDOWN ) {
909 if (TRACE_ON(dinput))
910 DPRINTF(" LD ");
912 GEN_EVENT(DIMOFS_BUTTON0, 0xFF, xtime, evsequence++);
913 This->m_state.rgbButtons[0] = 0xFF;
915 if ( dwFlags & MOUSEEVENTF_LEFTUP ) {
916 if (TRACE_ON(dinput))
917 DPRINTF(" LU ");
919 GEN_EVENT(DIMOFS_BUTTON0, 0x00, xtime, evsequence++);
920 This->m_state.rgbButtons[0] = 0x00;
922 if ( dwFlags & MOUSEEVENTF_RIGHTDOWN ) {
923 if (TRACE_ON(dinput))
924 DPRINTF(" RD ");
926 GEN_EVENT(DIMOFS_BUTTON1, 0xFF, xtime, evsequence++);
927 This->m_state.rgbButtons[1] = 0xFF;
929 if ( dwFlags & MOUSEEVENTF_RIGHTUP ) {
930 if (TRACE_ON(dinput))
931 DPRINTF(" RU ");
933 GEN_EVENT(DIMOFS_BUTTON1, 0x00, xtime, evsequence++);
934 This->m_state.rgbButtons[1] = 0x00;
936 if ( dwFlags & MOUSEEVENTF_MIDDLEDOWN ) {
937 if (TRACE_ON(dinput))
938 DPRINTF(" MD ");
940 GEN_EVENT(DIMOFS_BUTTON2, 0xFF, xtime, evsequence++);
941 This->m_state.rgbButtons[2] = 0xFF;
943 if ( dwFlags & MOUSEEVENTF_MIDDLEUP ) {
944 if (TRACE_ON(dinput))
945 DPRINTF(" MU ");
947 GEN_EVENT(DIMOFS_BUTTON2, 0x00, xtime, evsequence++);
948 This->m_state.rgbButtons[2] = 0x00;
950 if (TRACE_ON(dinput))
951 DPRINTF("\n");
953 This->prevX = posX;
954 This->prevY = posY;
956 if (This->absolute) {
957 This->m_state.lX = posX;
958 This->m_state.lY = posY;
959 } else {
960 This->m_state.lX = posX - This->win_centerX;
961 This->m_state.lY = posY - This->win_centerY;
964 LeaveCriticalSection(&(This->crit));
969 /******************************************************************************
970 * Acquire : gets exclusive control of the mouse
972 static HRESULT WINAPI SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface)
974 ICOM_THIS(SysMouseAImpl,iface);
975 RECT rect;
977 TRACE("(this=%p)\n",This);
979 if (This->acquired == 0) {
980 POINT point;
982 /* This stores the current mouse handler. */
983 This->prev_handler = mouse_event;
985 /* Store (in a global variable) the current lock */
986 current_lock = (IDirectInputDevice2A*)This;
988 /* Init the mouse state */
989 This->m_state.lX = PosX;
990 This->m_state.lY = PosY;
991 This->m_state.lZ = 0;
992 This->m_state.rgbButtons[0] = (MouseButtonsStates[0] ? 0xFF : 0x00);
993 This->m_state.rgbButtons[1] = (MouseButtonsStates[1] ? 0xFF : 0x00);
994 This->m_state.rgbButtons[2] = (MouseButtonsStates[2] ? 0xFF : 0x00);
995 This->m_state.rgbButtons[3] = 0x00;
997 /* Install our own mouse event handler */
998 MOUSE_Enable(dinput_mouse_event);
1000 /* Get the window dimension and find the center */
1001 GetWindowRect(This->win, &rect);
1002 This->win_centerX = (rect.right - rect.left) / 2;
1003 This->win_centerY = (rect.bottom - rect.top ) / 2;
1005 /* Warp the mouse to the center of the window */
1006 TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY);
1007 point.x = This->win_centerX;
1008 point.y = This->win_centerY;
1009 MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
1010 DISPLAY_MoveCursor(point.x, point.y);
1012 This->acquired = 1;
1014 return 0;
1017 /******************************************************************************
1018 * Unacquire : frees the mouse
1020 static HRESULT WINAPI SysMouseAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface)
1022 ICOM_THIS(SysMouseAImpl,iface);
1024 TRACE("(this=%p)\n",This);
1026 /* Reinstall previous mouse event handler */
1027 MOUSE_Enable(This->prev_handler);
1028 This->prev_handler = NULL;
1030 /* No more locks */
1031 current_lock = NULL;
1033 /* Unacquire device */
1034 This->acquired = 0;
1036 return 0;
1039 /******************************************************************************
1040 * GetDeviceState : returns the "state" of the mouse.
1042 * For the moment, only the "standard" return structure (DIMOUSESTATE) is
1043 * supported.
1045 static HRESULT WINAPI SysMouseAImpl_GetDeviceState(
1046 LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr
1048 ICOM_THIS(SysMouseAImpl,iface);
1049 struct DIMOUSESTATE *mstate = (struct DIMOUSESTATE *) ptr;
1051 EnterCriticalSection(&(This->crit));
1052 TRACE("(this=%p,0x%08lx,%p): \n",This,len,ptr);
1054 /* Check if the buffer is big enough */
1055 if (len < sizeof(struct DIMOUSESTATE)) {
1056 FIXME("unsupported state structure.");
1057 LeaveCriticalSection(&(This->crit));
1058 return DIERR_INVALIDPARAM;
1061 /* Copy the current mouse state */
1062 *mstate = This->m_state;
1064 /* Check if we need to do a mouse warping */
1065 if (This->need_warp) {
1066 POINT point;
1068 TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY);
1069 point.x = This->win_centerX;
1070 point.y = This->win_centerY;
1071 MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
1072 DISPLAY_MoveCursor(point.x, point.y);
1074 This->need_warp = 0;
1077 LeaveCriticalSection(&(This->crit));
1079 TRACE("(X: %ld - Y: %ld L: %02x M: %02x R: %02x)\n",
1080 mstate->lX, mstate->lY,
1081 mstate->rgbButtons[0], mstate->rgbButtons[2], mstate->rgbButtons[1]);
1083 return 0;
1086 /******************************************************************************
1087 * GetDeviceState : gets buffered input data.
1089 static HRESULT WINAPI SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE2A iface,
1090 DWORD dodsize,
1091 LPDIDEVICEOBJECTDATA dod,
1092 LPDWORD entries,
1093 DWORD flags
1095 ICOM_THIS(SysMouseAImpl,iface);
1097 EnterCriticalSection(&(This->crit));
1098 TRACE("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx)\n",This,dodsize,*entries,flags);
1100 if (flags & DIGDD_PEEK)
1101 FIXME("DIGDD_PEEK\n");
1103 if (dod == NULL) {
1104 *entries = This->queue_pos;
1105 This->queue_pos = 0;
1106 } else {
1107 /* Check for buffer overflow */
1108 if (This->queue_pos > *entries) {
1109 WARN("Buffer overflow not handled properly yet...\n");
1110 This->queue_pos = *entries;
1112 if (dodsize != sizeof(DIDEVICEOBJECTDATA)) {
1113 ERR("Wrong structure size !\n");
1114 LeaveCriticalSection(&(This->crit));
1115 return DIERR_INVALIDPARAM;
1118 if (This->queue_pos)
1119 TRACE("Application retrieving %d event(s).\n", This->queue_pos);
1121 /* Copy the buffered data into the application queue */
1122 memcpy(dod, This->data_queue, This->queue_pos * dodsize);
1123 *entries = This->queue_pos;
1125 /* Reset the event queue */
1126 This->queue_pos = 0;
1128 LeaveCriticalSection(&(This->crit));
1130 #if 0 /* FIXME: seems to create motion events, which fire back at us. */
1131 /* Check if we need to do a mouse warping */
1132 if (This->need_warp) {
1133 POINT point;
1135 TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY);
1136 point.x = This->win_centerX;
1137 point.y = This->win_centerY;
1138 MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
1140 DISPLAY_MoveCursor(point.x, point.y);
1142 This->need_warp = 0;
1144 #endif
1145 return 0;
1148 /******************************************************************************
1149 * SetProperty : change input device properties
1151 static HRESULT WINAPI SysMouseAImpl_SetProperty(LPDIRECTINPUTDEVICE2A iface,
1152 REFGUID rguid,
1153 LPCDIPROPHEADER ph)
1155 ICOM_THIS(SysMouseAImpl,iface);
1156 char xbuf[50];
1158 if (HIWORD(rguid))
1159 WINE_StringFromCLSID(rguid,xbuf);
1160 else
1161 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
1163 TRACE("(this=%p,%s,%p)\n",This,xbuf,ph);
1165 if (!HIWORD(rguid)) {
1166 switch ((DWORD)rguid) {
1167 case (DWORD) DIPROP_BUFFERSIZE: {
1168 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
1170 TRACE("buffersize = %ld\n",pd->dwData);
1172 This->data_queue = (LPDIDEVICEOBJECTDATA)HeapAlloc(GetProcessHeap(),0,
1173 pd->dwData * sizeof(DIDEVICEOBJECTDATA));
1174 This->queue_pos = 0;
1175 This->queue_len = pd->dwData;
1176 break;
1178 default:
1179 FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,xbuf);
1180 break;
1184 return 0;
1187 /******************************************************************************
1188 * SetEventNotification : specifies event to be sent on state change
1190 static HRESULT WINAPI SysMouseAImpl_SetEventNotification(LPDIRECTINPUTDEVICE2A iface,
1191 HANDLE hnd) {
1192 ICOM_THIS(SysMouseAImpl,iface);
1194 TRACE("(this=%p,0x%08lx)\n",This,(DWORD)hnd);
1196 This->hEvent = hnd;
1198 return DI_OK;
1201 #ifdef HAVE_LINUX_22_JOYSTICK_API
1202 /******************************************************************************
1203 * Joystick
1205 static ULONG WINAPI JoystickAImpl_Release(LPDIRECTINPUTDEVICE2A iface)
1207 ICOM_THIS(JoystickAImpl,iface);
1209 This->ref--;
1210 if (This->ref)
1211 return This->ref;
1212 HeapFree(GetProcessHeap(),0,This);
1213 return 0;
1216 /******************************************************************************
1217 * SetDataFormat : the application can choose the format of the data
1218 * the device driver sends back with GetDeviceState.
1220 static HRESULT WINAPI JoystickAImpl_SetDataFormat(
1221 LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df
1224 ICOM_THIS(JoystickAImpl,iface);
1225 int i;
1227 TRACE("(this=%p,%p)\n",This,df);
1229 TRACE("(df.dwSize=%ld)\n",df->dwSize);
1230 TRACE("(df.dwObjsize=%ld)\n",df->dwObjSize);
1231 TRACE("(df.dwFlags=0x%08lx)\n",df->dwFlags);
1232 TRACE("(df.dwDataSize=%ld)\n",df->dwDataSize);
1233 TRACE("(df.dwNumObjs=%ld)\n",df->dwNumObjs);
1235 for (i=0;i<df->dwNumObjs;i++) {
1236 char xbuf[50];
1238 if (df->rgodf[i].pguid)
1239 WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
1240 else
1241 strcpy(xbuf,"<no guid>");
1242 TRACE("df.rgodf[%d].guid %s (%p)\n",i,xbuf, df->rgodf[i].pguid);
1243 TRACE("df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
1244 TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
1245 TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
1247 This->df = HeapAlloc(GetProcessHeap(),0,df->dwSize+(df->dwNumObjs*df->dwObjSize));
1248 memcpy(This->df,df,df->dwSize+(df->dwNumObjs*df->dwObjSize));
1249 return 0;
1252 /******************************************************************************
1253 * Acquire : gets exclusive control of the joystick
1255 static HRESULT WINAPI JoystickAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface)
1257 ICOM_THIS(JoystickAImpl,iface);
1259 TRACE("(this=%p)\n",This);
1260 if (This->joyfd!=-1)
1261 return 0;
1262 This->joyfd=open(JOYDEV,O_RDONLY);
1263 if (This->joyfd==-1)
1264 return DIERR_NOTFOUND;
1265 return 0;
1268 /******************************************************************************
1269 * Unacquire : frees the joystick
1271 static HRESULT WINAPI JoystickAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface)
1273 ICOM_THIS(JoystickAImpl,iface);
1275 TRACE("(this=%p)\n",This);
1276 if (This->joyfd!=-1) {
1277 close(This->joyfd);
1278 This->joyfd = -1;
1280 return 0;
1283 #define map_axis(val) ((val+32768)*(This->lMax-This->lMin)/65536+This->lMin)
1285 static void joy_polldev(JoystickAImpl *This) {
1286 struct timeval tv;
1287 fd_set readfds;
1288 struct js_event jse;
1290 if (This->joyfd==-1)
1291 return;
1292 while (1) {
1293 memset(&tv,0,sizeof(tv));
1294 FD_ZERO(&readfds);FD_SET(This->joyfd,&readfds);
1295 if (1>select(This->joyfd+1,&readfds,NULL,NULL,&tv))
1296 return;
1297 /* we have one event, so we can read */
1298 if (sizeof(jse)!=read(This->joyfd,&jse,sizeof(jse))) {
1299 return;
1301 TRACE("js_event: type 0x%x, number %d, value %d\n",jse.type,jse.number,jse.value);
1302 if (jse.type & JS_EVENT_BUTTON) {
1303 GEN_EVENT(DIJOFS_BUTTON(jse.number),jse.value?0x80:0x00,jse.time,evsequence++);
1304 This->js.rgbButtons[jse.number] = jse.value?0x80:0x00;
1306 if (jse.type & JS_EVENT_AXIS) {
1307 switch (jse.number) {
1308 case 0:
1309 GEN_EVENT(jse.number*4,jse.value,jse.time,evsequence++);
1310 This->js.lX = map_axis(jse.value);
1311 break;
1312 case 1:
1313 GEN_EVENT(jse.number*4,jse.value,jse.time,evsequence++);
1314 This->js.lY = map_axis(jse.value);
1315 break;
1316 case 2:
1317 GEN_EVENT(jse.number*4,jse.value,jse.time,evsequence++);
1318 This->js.lZ = map_axis(jse.value);
1319 break;
1320 default:
1321 FIXME("more then 3 axes (%d) not handled!\n",jse.number);
1322 break;
1328 /******************************************************************************
1329 * GetDeviceState : returns the "state" of the joystick.
1332 static HRESULT WINAPI JoystickAImpl_GetDeviceState(
1333 LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr
1335 ICOM_THIS(JoystickAImpl,iface);
1337 joy_polldev(This);
1338 TRACE("(this=%p,0x%08lx,%p)\n",This,len,ptr);
1339 if (len != sizeof(DIJOYSTATE)) {
1340 FIXME("len %ld is not sizeof(DIJOYSTATE), unsupported format.\n",len);
1342 memcpy(ptr,&(This->js),len);
1343 This->queue_pos = 0;
1344 return 0;
1347 /******************************************************************************
1348 * GetDeviceState : gets buffered input data.
1350 static HRESULT WINAPI JoystickAImpl_GetDeviceData(LPDIRECTINPUTDEVICE2A iface,
1351 DWORD dodsize,
1352 LPDIDEVICEOBJECTDATA dod,
1353 LPDWORD entries,
1354 DWORD flags
1356 ICOM_THIS(JoystickAImpl,iface);
1358 FIXME("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx),STUB!\n",This,dodsize,*entries,flags);
1360 joy_polldev(This);
1361 if (flags & DIGDD_PEEK)
1362 FIXME("DIGDD_PEEK\n");
1364 if (dod == NULL) {
1365 } else {
1367 return 0;
1370 /******************************************************************************
1371 * SetProperty : change input device properties
1373 static HRESULT WINAPI JoystickAImpl_SetProperty(LPDIRECTINPUTDEVICE2A iface,
1374 REFGUID rguid,
1375 LPCDIPROPHEADER ph)
1377 ICOM_THIS(JoystickAImpl,iface);
1378 char xbuf[50];
1380 if (HIWORD(rguid))
1381 WINE_StringFromCLSID(rguid,xbuf);
1382 else
1383 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
1385 FIXME("(this=%p,%s,%p)\n",This,xbuf,ph);
1386 FIXME("ph.dwSize = %ld, ph.dwHeaderSize =%ld, ph.dwObj = %ld, ph.dwHow= %ld\n",ph->dwSize, ph->dwHeaderSize,ph->dwObj,ph->dwHow);
1388 if (!HIWORD(rguid)) {
1389 switch ((DWORD)rguid) {
1390 case (DWORD) DIPROP_BUFFERSIZE: {
1391 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
1393 FIXME("buffersize = %ld\n",pd->dwData);
1394 break;
1396 case (DWORD)DIPROP_RANGE: {
1397 LPCDIPROPRANGE pr = (LPCDIPROPRANGE)ph;
1399 FIXME("proprange(%ld,%ld)\n",pr->lMin,pr->lMax);
1400 This->lMin = pr->lMin;
1401 This->lMax = pr->lMax;
1402 break;
1404 case (DWORD)DIPROP_DEADZONE: {
1405 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
1407 FIXME("deadzone(%ld)\n",pd->dwData);
1408 This->deadzone = pd->dwData;
1409 break;
1411 default:
1412 FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,xbuf);
1413 break;
1416 return 0;
1419 /******************************************************************************
1420 * SetEventNotification : specifies event to be sent on state change
1422 static HRESULT WINAPI JoystickAImpl_SetEventNotification(
1423 LPDIRECTINPUTDEVICE2A iface, HANDLE hnd
1425 ICOM_THIS(JoystickAImpl,iface);
1427 TRACE("(this=%p,0x%08lx)\n",This,(DWORD)hnd);
1428 This->hEvent = hnd;
1429 return DI_OK;
1432 static HRESULT WINAPI JoystickAImpl_GetCapabilities(
1433 LPDIRECTINPUTDEVICE2A iface,
1434 LPDIDEVCAPS lpDIDevCaps)
1436 ICOM_THIS(JoystickAImpl,iface);
1437 BYTE axes,buttons;
1438 int xfd = This->joyfd;
1440 TRACE("%p->(%p)\n",iface,lpDIDevCaps);
1441 if (xfd==-1)
1442 xfd = open(JOYDEV,O_RDONLY);
1443 lpDIDevCaps->dwFlags = DIDC_ATTACHED;
1444 lpDIDevCaps->dwDevType = DIDEVTYPE_JOYSTICK;
1445 #ifdef JSIOCGAXES
1446 if (-1==ioctl(xfd,JSIOCGAXES,&axes))
1447 axes = 2;
1448 lpDIDevCaps->dwAxes = axes;
1449 #endif
1450 #ifdef JSIOCGBUTTONS
1451 if (-1==ioctl(xfd,JSIOCGAXES,&buttons))
1452 buttons = 2;
1453 lpDIDevCaps->dwButtons = buttons;
1454 #endif
1455 if (xfd!=This->joyfd)
1456 close(xfd);
1457 return DI_OK;
1459 static HRESULT WINAPI JoystickAImpl_Poll(LPDIRECTINPUTDEVICE2A iface) {
1460 ICOM_THIS(JoystickAImpl,iface);
1461 TRACE("(),stub!\n");
1463 joy_polldev(This);
1464 return DI_OK;
1466 #endif
1468 /****************************************************************************/
1469 /****************************************************************************/
1471 static ICOM_VTABLE(IDirectInputDevice2A) SysKeyboardAvt =
1473 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1474 IDirectInputDevice2AImpl_QueryInterface,
1475 IDirectInputDevice2AImpl_AddRef,
1476 IDirectInputDevice2AImpl_Release,
1477 IDirectInputDevice2AImpl_GetCapabilities,
1478 IDirectInputDevice2AImpl_EnumObjects,
1479 IDirectInputDevice2AImpl_GetProperty,
1480 SysKeyboardAImpl_SetProperty,
1481 SysKeyboardAImpl_Acquire,
1482 SysKeyboardAImpl_Unacquire,
1483 SysKeyboardAImpl_GetDeviceState,
1484 SysKeyboardAImpl_GetDeviceData,
1485 IDirectInputDevice2AImpl_SetDataFormat,
1486 IDirectInputDevice2AImpl_SetEventNotification,
1487 IDirectInputDevice2AImpl_SetCooperativeLevel,
1488 IDirectInputDevice2AImpl_GetObjectInfo,
1489 IDirectInputDevice2AImpl_GetDeviceInfo,
1490 IDirectInputDevice2AImpl_RunControlPanel,
1491 IDirectInputDevice2AImpl_Initialize,
1492 IDirectInputDevice2AImpl_CreateEffect,
1493 IDirectInputDevice2AImpl_EnumEffects,
1494 IDirectInputDevice2AImpl_GetEffectInfo,
1495 IDirectInputDevice2AImpl_GetForceFeedbackState,
1496 IDirectInputDevice2AImpl_SendForceFeedbackCommand,
1497 IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
1498 IDirectInputDevice2AImpl_Escape,
1499 IDirectInputDevice2AImpl_Poll,
1500 IDirectInputDevice2AImpl_SendDeviceData,
1503 static ICOM_VTABLE(IDirectInputDevice2A) SysMouseAvt =
1505 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1506 IDirectInputDevice2AImpl_QueryInterface,
1507 IDirectInputDevice2AImpl_AddRef,
1508 SysMouseAImpl_Release,
1509 IDirectInputDevice2AImpl_GetCapabilities,
1510 IDirectInputDevice2AImpl_EnumObjects,
1511 IDirectInputDevice2AImpl_GetProperty,
1512 SysMouseAImpl_SetProperty,
1513 SysMouseAImpl_Acquire,
1514 SysMouseAImpl_Unacquire,
1515 SysMouseAImpl_GetDeviceState,
1516 SysMouseAImpl_GetDeviceData,
1517 SysMouseAImpl_SetDataFormat,
1518 SysMouseAImpl_SetEventNotification,
1519 SysMouseAImpl_SetCooperativeLevel,
1520 IDirectInputDevice2AImpl_GetObjectInfo,
1521 IDirectInputDevice2AImpl_GetDeviceInfo,
1522 IDirectInputDevice2AImpl_RunControlPanel,
1523 IDirectInputDevice2AImpl_Initialize,
1524 IDirectInputDevice2AImpl_CreateEffect,
1525 IDirectInputDevice2AImpl_EnumEffects,
1526 IDirectInputDevice2AImpl_GetEffectInfo,
1527 IDirectInputDevice2AImpl_GetForceFeedbackState,
1528 IDirectInputDevice2AImpl_SendForceFeedbackCommand,
1529 IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
1530 IDirectInputDevice2AImpl_Escape,
1531 IDirectInputDevice2AImpl_Poll,
1532 IDirectInputDevice2AImpl_SendDeviceData,
1535 #ifdef HAVE_LINUX_22_JOYSTICK_API
1536 static ICOM_VTABLE(IDirectInputDevice2A) JoystickAvt =
1538 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1539 IDirectInputDevice2AImpl_QueryInterface,
1540 IDirectInputDevice2AImpl_AddRef,
1541 JoystickAImpl_Release,
1542 JoystickAImpl_GetCapabilities,
1543 IDirectInputDevice2AImpl_EnumObjects,
1544 IDirectInputDevice2AImpl_GetProperty,
1545 JoystickAImpl_SetProperty,
1546 JoystickAImpl_Acquire,
1547 JoystickAImpl_Unacquire,
1548 JoystickAImpl_GetDeviceState,
1549 JoystickAImpl_GetDeviceData,
1550 JoystickAImpl_SetDataFormat,
1551 JoystickAImpl_SetEventNotification,
1552 IDirectInputDevice2AImpl_SetCooperativeLevel,
1553 IDirectInputDevice2AImpl_GetObjectInfo,
1554 IDirectInputDevice2AImpl_GetDeviceInfo,
1555 IDirectInputDevice2AImpl_RunControlPanel,
1556 IDirectInputDevice2AImpl_Initialize,
1557 IDirectInputDevice2AImpl_CreateEffect,
1558 IDirectInputDevice2AImpl_EnumEffects,
1559 IDirectInputDevice2AImpl_GetEffectInfo,
1560 IDirectInputDevice2AImpl_GetForceFeedbackState,
1561 IDirectInputDevice2AImpl_SendForceFeedbackCommand,
1562 IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
1563 IDirectInputDevice2AImpl_Escape,
1564 JoystickAImpl_Poll,
1565 IDirectInputDevice2AImpl_SendDeviceData,
1567 #endif