source: trunk/src/dinput/dinput.cpp@ 7029

Last change on this file since 7029 was 5375, checked in by mike, 24 years ago

Fixed keyboard input a little

File size: 55.6 KB
Line 
1/* $Id: dinput.cpp,v 1.10 2001-03-25 20:06:13 mike Exp $ */
2/* DirectInput
3 *
4 * Copyright 1998 Marcus Meissner
5 * Copyright 1998,1999 Lionel Ulmer
6 *
7 */
8/* Status:
9 *
10 * - Tomb Raider 2 Demo:
11 * Playable using keyboard only.
12 * - WingCommander Prophecy Demo:
13 * Doesn't get Input Focus.
14 *
15 * - Fallout : works great in X and DGA mode
16 *
17 * FIXME: The keyboard handling needs to (and will) be merged into keyboard.c
18 * (The current implementation is currently only a proof of concept and
19 * an utter mess.)
20 */
21#ifdef __WIN32OS2__
22#include <odin.h>
23#include <os2win.h>
24
25#define ICOM_CINTERFACE 1
26#define CINTERFACE
27#endif
28
29#include "config.h"
30#include <string.h>
31#include <time.h>
32//#include <unistd.h>
33#include <assert.h>
34#ifdef HAVE_SYS_SIGNAL_H
35# include <sys/signal.h>
36#endif
37//#include <sys/time.h>
38//#include <sys/fcntl.h>
39//#include <sys/ioctl.h>
40#include <errno.h>
41#ifdef HAVE_SYS_ERRNO_H
42# include <sys/errno.h>
43#endif
44#ifdef HAVE_LINUX_JOYSTICK_H
45# include <linux/joystick.h>
46# define JOYDEV "/dev/js0"
47#endif
48#include "wine/obj_base.h"
49#include "debugtools.h"
50#include "dinput.h"
51#include "display.h"
52//#include "keyboard.h"
53//#include "message.h"
54#include "mouse.h"
55#include "sysmetrics.h"
56#include "winbase.h"
57#include "winerror.h"
58#include "winuser.h"
59
60#ifdef __WIN32OS2__
61#include <heapstring.h>
62#include <misc.h>
63#include "oslibinput.h"
64#endif
65
66DEFAULT_DEBUG_CHANNEL(dinput)
67
68extern VOID WIN32API KEYBOARD_Enable(WNDPROC handler);
69
70extern BYTE InputKeyStateTable[256];
71extern int min_keycode, max_keycode;
72extern WORD keyc2vkey[256];
73
74extern ICOM_VTABLE(IDirectInputA) ddiavt;
75extern ICOM_VTABLE(IDirectInputDevice2A) SysKeyboardAvt;
76extern ICOM_VTABLE(IDirectInputDevice2A) SysMouseAvt;
77
78typedef struct IDirectInputAImpl IDirectInputAImpl;
79typedef struct IDirectInputDevice2AImpl IDirectInputDevice2AImpl;
80typedef struct SysKeyboardAImpl SysKeyboardAImpl;
81typedef struct SysMouseAImpl SysMouseAImpl;
82
83struct IDirectInputDevice2AImpl
84{
85 ICOM_VFIELD(IDirectInputDevice2A);
86 DWORD ref;
87 GUID guid;
88};
89
90struct SysKeyboardAImpl
91{
92 /* IDirectInputDevice2AImpl */
93 ICOM_VFIELD(IDirectInputDevice2A);
94 DWORD ref;
95 GUID guid;
96 /* SysKeyboardAImpl */
97 LPDIDEVICEOBJECTDATA data_queue;
98 int queue_pos, queue_len;
99 CRITICAL_SECTION crit;
100 int acquired;
101 BYTE keystate[256];
102};
103
104#ifdef HAVE_LINUX_22_JOYSTICK_API
105typedef struct JoystickAImpl JoystickAImpl;
106ICOM_VTABLE(IDirectInputDevice2A) JoystickAvt;
107struct JoystickAImpl
108{
109 /* IDirectInputDevice2AImpl */
110 ICOM_VFIELD(IDirectInputDevice2A);
111 DWORD ref;
112 GUID guid;
113
114 /* joystick private */
115 int joyfd;
116 LPDIDATAFORMAT df;
117 HANDLE hEvent;
118 LONG lMin,lMax,deadzone;
119 LPDIDEVICEOBJECTDATA data_queue;
120 int queue_pos, queue_len;
121 DIJOYSTATE js;
122};
123#endif
124
125struct SysMouseAImpl
126{
127 /* IDirectInputDevice2AImpl */
128 ICOM_VFIELD(IDirectInputDevice2A);
129 DWORD ref;
130 GUID guid;
131
132 LPDIDATAFORMAT df;
133 /* SysMouseAImpl */
134 BYTE absolute;
135 /* Previous position for relative moves */
136 LONG prevX, prevY;
137 LPMOUSE_EVENT_PROC prev_handler;
138 HWND win;
139 DWORD win_centerX, win_centerY;
140 LPDIDEVICEOBJECTDATA data_queue;
141 int queue_pos, queue_len;
142 int need_warp;
143 int acquired;
144 HANDLE hEvent;
145 CRITICAL_SECTION crit;
146};
147
148static int evsequence=0;
149
150
151/* UIDs for Wine "drivers".
152 When enumerating each device supporting DInput, they have two UIDs :
153 - the 'windows' UID
154 - a vendor UID */
155#ifdef HAVE_LINUX_22_JOYSTICK_API
156static GUID DInput_Wine_Joystick_GUID = { /* 9e573ed9-7734-11d2-8d4a-23903fb6bdf7 */
157 0x9e573ed9,
158 0x7734,
159 0x11d2,
160 {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
161};
162#endif
163static GUID DInput_Wine_Mouse_GUID = { /* 9e573ed8-7734-11d2-8d4a-23903fb6bdf7 */
164 0x9e573ed8,
165 0x7734,
166 0x11d2,
167 {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
168};
169static GUID DInput_Wine_Keyboard_GUID = { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */
170 0x0ab8648a,
171 0x7735,
172 0x11d2,
173 {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41}
174};
175
176/* FIXME: This is ugly and not thread safe :/ */
177static IDirectInputDevice2A* current_lock = NULL;
178static IDirectInputDeviceA* current_keylock = NULL;
179
180/******************************************************************************
181 * Various debugging tools
182 */
183static void _dump_cooperativelevel(DWORD dwFlags) {
184 int i;
185 const struct {
186 DWORD mask;
187 char *name;
188 } flags[] = {
189#define FE(x) { x, #x},
190 FE(DISCL_BACKGROUND)
191 FE(DISCL_EXCLUSIVE)
192 FE(DISCL_FOREGROUND)
193 FE(DISCL_NONEXCLUSIVE)
194 };
195 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
196 if (flags[i].mask & dwFlags)
197 DPRINTF("%s ",flags[i].name);
198 DPRINTF("\n");
199}
200
201struct IDirectInputAImpl
202{
203 ICOM_VFIELD(IDirectInputA);
204 DWORD ref;
205};
206
207/******************************************************************************
208 * DirectInputCreate32A
209 */
210HRESULT WINAPI DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA *ppDI, LPUNKNOWN punkOuter)
211{
212 IDirectInputAImpl* This;
213 TRACE("(0x%08lx,%04lx,%p,%p)\n",
214 (DWORD)hinst,dwVersion,ppDI,punkOuter
215 );
216 This = (IDirectInputAImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl));
217 This->ref = 1;
218 ICOM_VTBL(This) = &ddiavt;
219 *ppDI=(IDirectInputA*)This;
220 OSLibInit();
221 return 0;
222}
223/******************************************************************************
224 * IDirectInputA_EnumDevices
225 */
226static HRESULT WINAPI IDirectInputAImpl_EnumDevices(
227 LPDIRECTINPUTA iface, DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback,
228 LPVOID pvRef, DWORD dwFlags
229)
230{
231 ICOM_THIS(IDirectInputAImpl,iface);
232 DIDEVICEINSTANCEA devInstance;
233 int ret;
234
235 TRACE("(this=%p,0x%04lx,%p,%p,%04lx)\n", This, dwDevType, lpCallback, pvRef, dwFlags);
236
237 devInstance.dwSize = sizeof(DIDEVICEINSTANCEA);
238 if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_KEYBOARD)) {
239 /* Return keyboard */
240 devInstance.guidInstance = GUID_SysKeyboard;/* DInput's GUID */
241 devInstance.guidProduct = DInput_Wine_Keyboard_GUID; /* Vendor's GUID */
242 devInstance.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8);
243 strcpy(devInstance.tszInstanceName, "Keyboard");
244 strcpy(devInstance.tszProductName, "Wine Keyboard");
245
246 ret = lpCallback(&devInstance, pvRef);
247 TRACE("Keyboard registered\n");
248 if (ret == DIENUM_STOP)
249 return 0;
250 }
251
252 if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_MOUSE)) {
253 /* Return mouse */
254 devInstance.guidInstance = GUID_SysMouse;/* DInput's GUID */
255 devInstance.guidProduct = DInput_Wine_Mouse_GUID; /* Vendor's GUID */
256 devInstance.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_UNKNOWN << 8);
257 strcpy(devInstance.tszInstanceName, "Mouse");
258 strcpy(devInstance.tszProductName, "Wine Mouse");
259
260 ret = lpCallback(&devInstance, pvRef);
261 TRACE("Mouse registered\n");
262 if (ret == DIENUM_STOP)
263 return 0;
264 }
265 if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_JOYSTICK)) {
266 /* check whether we have a joystick */
267#ifdef HAVE_LINUX_22_JOYSTICK_API
268 if ( (access(JOYDEV,O_RDONLY)!=-1) ||
269 (errno!=ENODEV && errno!=ENOENT)
270 ) {
271 /* Return joystick */
272 devInstance.guidInstance = GUID_Joystick;
273 devInstance.guidProduct = DInput_Wine_Joystick_GUID;
274 /* we only support traditional joysticks for now */
275 devInstance.dwDevType = DIDEVTYPE_JOYSTICK | DIDEVTYPEJOYSTICK_TRADITIONAL;
276 strcpy(devInstance.tszInstanceName, "Joystick");
277 /* ioctl JSIOCGNAME(len) */
278 strcpy(devInstance.tszProductName, "Wine Joystick");
279
280 ret = lpCallback(&devInstance,pvRef);
281 TRACE("Joystick registered\n");
282 if (ret == DIENUM_STOP)
283 return 0;
284 }
285#endif
286 }
287 return 0;
288}
289
290static ULONG WINAPI IDirectInputAImpl_AddRef(LPDIRECTINPUTA iface)
291{
292 ICOM_THIS(IDirectInputAImpl,iface);
293 return ++(This->ref);
294}
295
296static ULONG WINAPI IDirectInputAImpl_Release(LPDIRECTINPUTA iface)
297{
298 ICOM_THIS(IDirectInputAImpl,iface);
299 if (!(--This->ref)) {
300 HeapFree(GetProcessHeap(),0,This);
301 return 0;
302 }
303 return This->ref;
304}
305
306static HRESULT WINAPI IDirectInputAImpl_CreateDevice(
307 LPDIRECTINPUTA iface,REFGUID rguid,LPDIRECTINPUTDEVICEA* pdev,
308 LPUNKNOWN punk
309) {
310 ICOM_THIS(IDirectInputAImpl,iface);
311 char xbuf[50];
312
313 WINE_StringFromCLSID(rguid,xbuf);
314 FIXME("(this=%p,%s,%p,%p): stub\n",This,xbuf,pdev,punk);
315 if ((!memcmp(&GUID_SysKeyboard,rguid,sizeof(GUID_SysKeyboard))) || /* Generic Keyboard */
316 (!memcmp(&DInput_Wine_Keyboard_GUID,rguid,sizeof(GUID_SysKeyboard)))) { /* Wine Keyboard */
317 SysKeyboardAImpl* newDevice;
318 newDevice = (SysKeyboardAImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysKeyboardAImpl));
319 newDevice->ref = 1;
320 ICOM_VTBL(newDevice) = &SysKeyboardAvt;
321 InitializeCriticalSection(&(newDevice->crit));
322 MakeCriticalSectionGlobal(&(newDevice->crit));
323 memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
324 memset(newDevice->keystate,0,256);
325 *pdev=(IDirectInputDeviceA*)newDevice;
326 return DI_OK;
327 }
328 if ((!memcmp(&GUID_SysMouse,rguid,sizeof(GUID_SysMouse))) || /* Generic Mouse */
329 (!memcmp(&DInput_Wine_Mouse_GUID,rguid,sizeof(GUID_SysMouse)))) { /* Wine Mouse */
330 SysMouseAImpl* newDevice;
331 newDevice = (SysMouseAImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysMouseAImpl));
332 newDevice->ref = 1;
333 ICOM_VTBL(newDevice) = &SysMouseAvt;
334 InitializeCriticalSection(&(newDevice->crit));
335 MakeCriticalSectionGlobal(&(newDevice->crit));
336 memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
337 *pdev=(IDirectInputDeviceA*)newDevice;
338 return DI_OK;
339 }
340#ifdef HAVE_LINUX_22_JOYSTICK_API
341 if ((!memcmp(&GUID_Joystick,rguid,sizeof(GUID_Joystick))) ||
342 (!memcmp(&DInput_Wine_Joystick_GUID,rguid,sizeof(GUID_Joystick)))) {
343 JoystickAImpl* newDevice;
344 newDevice = (JoystickAImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(JoystickAImpl));
345 newDevice->ref = 1;
346 ICOM_VTBL(newDevice) = &JoystickAvt;
347 newDevice->joyfd = -1;
348 memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
349 *pdev=(IDirectInputDeviceA*)newDevice;
350 return DI_OK;
351 }
352#endif
353 return E_FAIL;
354}
355
356static HRESULT WINAPI IDirectInputAImpl_QueryInterface(
357 LPDIRECTINPUTA iface,REFIID riid,LPVOID *ppobj
358) {
359 ICOM_THIS(IDirectInputAImpl,iface);
360 char xbuf[50];
361
362 WINE_StringFromCLSID(riid,xbuf);
363 TRACE("(this=%p,%s,%p)\n",This,xbuf,ppobj);
364 if (!memcmp(&IID_IUnknown,riid,sizeof(*riid))) {
365 IDirectInputA_AddRef(iface);
366 *ppobj = This;
367 return 0;
368 }
369 if (!memcmp(&IID_IDirectInputA,riid,sizeof(*riid))) {
370 IDirectInputA_AddRef(iface);
371 *ppobj = This;
372 return 0;
373 }
374 return E_FAIL;
375}
376
377static HRESULT WINAPI IDirectInputAImpl_Initialize(
378 LPDIRECTINPUTA iface,HINSTANCE hinst,DWORD x
379) {
380 return DIERR_ALREADYINITIALIZED;
381}
382
383static HRESULT WINAPI IDirectInputAImpl_GetDeviceStatus(LPDIRECTINPUTA iface,
384 REFGUID rguid) {
385 ICOM_THIS(IDirectInputAImpl,iface);
386 char xbuf[50];
387
388 WINE_StringFromCLSID(rguid,xbuf);
389 FIXME("(%p)->(%s): stub\n",This,xbuf);
390
391 return DI_OK;
392}
393
394static HRESULT WINAPI IDirectInputAImpl_RunControlPanel(LPDIRECTINPUTA iface,
395 HWND hwndOwner,
396 DWORD dwFlags) {
397 ICOM_THIS(IDirectInputAImpl,iface);
398 FIXME("(%p)->(%08lx,%08lx): stub\n",This, (DWORD) hwndOwner, dwFlags);
399
400 return DI_OK;
401}
402
403ICOM_VTABLE(IDirectInputA) ddiavt =
404{
405 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
406 IDirectInputAImpl_QueryInterface,
407 IDirectInputAImpl_AddRef,
408 IDirectInputAImpl_Release,
409 IDirectInputAImpl_CreateDevice,
410 IDirectInputAImpl_EnumDevices,
411 IDirectInputAImpl_GetDeviceStatus,
412 IDirectInputAImpl_RunControlPanel,
413 IDirectInputAImpl_Initialize
414};
415
416/******************************************************************************
417 * IDirectInputDeviceA
418 */
419
420static HRESULT WINAPI IDirectInputDevice2AImpl_SetDataFormat(
421 LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df
422) {
423 /*
424 int i;
425 TRACE(dinput,"(this=%p,%p)\n",This,df);
426
427 TRACE(dinput,"df.dwSize=%ld\n",df->dwSize);
428 TRACE(dinput,"(df.dwObjsize=%ld)\n",df->dwObjSize);
429 TRACE(dinput,"(df.dwFlags=0x%08lx)\n",df->dwFlags);
430 TRACE(dinput,"(df.dwDataSize=%ld)\n",df->dwDataSize);
431 TRACE(dinput,"(df.dwNumObjs=%ld)\n",df->dwNumObjs);
432
433 for (i=0;i<df->dwNumObjs;i++) {
434 char xbuf[50];
435
436 if (df->rgodf[i].pguid)
437 WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
438 else
439 strcpy(xbuf,"<no guid>");
440 TRACE(dinput,"df.rgodf[%d].guid %s\n",i,xbuf);
441 TRACE(dinput,"df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
442 TRACE(dinput,"dwType 0x%02lx,dwInstance %ld\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
443 TRACE(dinput,"df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
444 }
445 */
446 return 0;
447}
448
449static HRESULT WINAPI IDirectInputDevice2AImpl_SetCooperativeLevel(
450 LPDIRECTINPUTDEVICE2A iface,HWND hwnd,DWORD dwflags
451) {
452 ICOM_THIS(IDirectInputDevice2AImpl,iface);
453 FIXME("(this=%p,0x%08lx,0x%08lx): stub\n",This,(DWORD)hwnd,dwflags);
454// if (TRACE_ON(dinput))
455// _dump_cooperativelevel(dwflags);
456 return 0;
457}
458
459static HRESULT WINAPI IDirectInputDevice2AImpl_SetEventNotification(
460 LPDIRECTINPUTDEVICE2A iface,HANDLE hnd
461) {
462 ICOM_THIS(IDirectInputDevice2AImpl,iface);
463 FIXME("(this=%p,0x%08lx): stub\n",This,(DWORD)hnd);
464 return 0;
465}
466
467static ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE2A iface)
468{
469 ICOM_THIS(IDirectInputDevice2AImpl,iface);
470 This->ref--;
471 if (This->ref)
472 return This->ref;
473 HeapFree(GetProcessHeap(),0,This);
474 return 0;
475}
476
477static HRESULT WINAPI SysKeyboardAImpl_SetProperty(
478 LPDIRECTINPUTDEVICE2A iface,REFGUID rguid,LPCDIPROPHEADER ph
479)
480{
481 ICOM_THIS(SysKeyboardAImpl,iface);
482 char xbuf[50];
483
484 if (HIWORD(rguid))
485 WINE_StringFromCLSID(rguid,xbuf);
486 else
487 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
488 TRACE("DINPUT-SKAI: SetProperty (this=%p,%s,%p)\n",This,xbuf,ph);
489 TRACE("(size=%ld,headersize=%ld,obj=%ld,how=%ld\n",
490 ph->dwSize,ph->dwHeaderSize,ph->dwObj,ph->dwHow);
491 if (!HIWORD(rguid)) {
492#ifdef __WIN32OS2__
493 if(rguid == DIPROP_BUFFERSIZE) {
494 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
495
496 This->data_queue = (LPDIDEVICEOBJECTDATA)HeapAlloc(GetProcessHeap(),0,
497 pd->dwData * sizeof(DIDEVICEOBJECTDATA));
498 This->queue_pos = 0;
499 This->queue_len = pd->dwData;
500
501 TRACE("(buffersize=%ld)\n",pd->dwData);
502 }
503 else WARN("Unknown type %ld\n",(DWORD)rguid);
504
505#else
506 switch ((DWORD)rguid) {
507 case (DWORD) DIPROP_BUFFERSIZE: {
508 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
509
510 TRACE("(buffersize=%ld)\n",pd->dwData);
511 break;
512 }
513 default:
514 WARN("Unknown type %ld\n",(DWORD)rguid);
515 break;
516 }
517#endif
518 }
519 return 0;
520}
521
522static HRESULT WINAPI SysKeyboardAImpl_GetDeviceState(
523 LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr
524)
525{
526 ICOM_THIS(SysKeyboardAImpl,iface);
527// TRACE("DINPUT-SKAI: GetDeviceData (this=%p,%ld,%p)\n",
528// This, len, ptr);
529
530#ifdef __WIN32OS2__
531// return OSLibGetDIState(len, ptr) ? DI_OK : E_FAIL;
532 if (ptr == NULL || len > 256)
533 return E_FAIL;
534
535 memcpy(ptr, This->keystate, len);
536 return DI_OK;
537#else
538 return KEYBOARD_Driver->pGetDIState(len, ptr)?DI_OK:E_FAIL;
539#endif
540}
541
542static ULONG WINAPI SysKeyboardAImpl_Release(LPDIRECTINPUTDEVICE2A iface)
543{
544 ICOM_THIS(SysKeyboardAImpl,iface);
545 TRACE("DINPUT-SKAI: Release (this=%p)\n", This);
546
547 This->ref--;
548 if (This->ref)
549 return This->ref;
550
551 /* Free the data queue */
552 if (This->data_queue != NULL)
553 HeapFree(GetProcessHeap(),0,This->data_queue);
554
555 /* Remeove the previous event handler (in case of releasing an acquired
556 keyboard device) */
557 KEYBOARD_Enable(NULL);
558
559 HeapFree(GetProcessHeap(),0,This);
560 return 0;
561}
562
563static HRESULT WINAPI SysKeyboardAImpl_GetDeviceData(
564 LPDIRECTINPUTDEVICE2A iface,DWORD dodsize,LPDIDEVICEOBJECTDATA dod,
565 LPDWORD entries,DWORD flags
566)
567{
568 ICOM_THIS(SysKeyboardAImpl,iface);
569 HRESULT ret;
570 int i;
571
572 TRACE("DINPUT-SKAI: GetDeviceData (this=%p,%ld,%p,%p(%ld)),0x%08lx)\n",
573 This,dodsize,dod,entries,entries?*entries:0,flags);
574
575 EnterCriticalSection(&(This->crit));
576 TRACE("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx)\n",This,dodsize,*entries,flags);
577
578 if (flags & DIGDD_PEEK)
579 FIXME("DIGDD_PEEK\n");
580
581 if (dod == NULL) {
582 *entries = This->queue_pos;
583 This->queue_pos = 0;
584 } else {
585 /* Check for buffer overflow */
586 if (This->queue_pos > *entries) {
587 WARN("Buffer overflow not handled properly yet...\n");
588 This->queue_pos = *entries;
589 }
590 if (dodsize != sizeof(DIDEVICEOBJECTDATA)) {
591 ERR("Wrong structure size !\n");
592 LeaveCriticalSection(&(This->crit));
593 return DIERR_INVALIDPARAM;
594 }
595
596 if (This->queue_pos)
597 TRACE("Application retrieving %d event(s).\n", This->queue_pos);
598
599 /* Copy the buffered data into the application queue */
600 memcpy(dod, This->data_queue, This->queue_pos * dodsize);
601 *entries = This->queue_pos;
602
603 /* Reset the event queue */
604 This->queue_pos = 0;
605 }
606 LeaveCriticalSection(&(This->crit));
607 ret = DI_OK;
608
609 return ret;
610}
611
612#define GEN_KEYEVENT(offset,data,xtime,seq) \
613{ \
614 if (This->queue_pos < This->queue_len) { \
615 This->data_queue[This->queue_pos].dwOfs = offset; \
616 This->data_queue[This->queue_pos].dwData = data; \
617 This->data_queue[This->queue_pos].dwTimeStamp = xtime; \
618 This->data_queue[This->queue_pos].dwSequence = seq; \
619 This->queue_pos++; \
620 } \
621}
622
623BYTE scan2dinput(WORD scan) {
624 BYTE dscan;
625
626 switch (scan) {
627 case 0x148:
628 dscan = DIK_UP;
629 break;
630 case 0x14b:
631 dscan = DIK_LEFT;
632 break;
633 case 0x14d:
634 dscan = DIK_RIGHT;
635 break;
636 case 0x150:
637 dscan = DIK_DOWN;
638 break;
639 case 0x135:
640 dscan = DIK_NUMPADSLASH;
641 break;
642 case 0x11c:
643 dscan = DIK_NUMPADENTER;
644 break;
645 case 0x152:
646 dscan = DIK_INSERT;
647 break;
648 case 0x147:
649 dscan = DIK_HOME;
650 break;
651 case 0x149:
652 dscan = DIK_PGUP;
653 break;
654 case 0x153:
655 dscan = DIK_DELETE;
656 break;
657 case 0x14F:
658 dscan = DIK_END;
659 break;
660 case 0x151:
661 dscan = DIK_PGDN;
662 break;
663 case 0x11D:
664 dscan = DIK_RCONTROL;
665 break;
666 case 0x5E:
667 dscan = DIK_RALT;
668 break;
669 default:
670 dscan = scan & 0xFF;
671 }
672 return dscan;
673}
674
675LRESULT CALLBACK event_keyHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
676 TRACE("DINPUT-SKAI: keyHandler (msg=%x wParam=0x%X, lParam=0x%lX)\n", msg, wParam, lParam);
677
678 SysKeyboardAImpl* This = (SysKeyboardAImpl*) current_keylock;
679 WORD scan = (lParam >> 16) & 0x1FF;
680 /* fix the scancode, DInput only uses real scancodes in 90% cases */
681 scan = scan2dinput(scan);
682
683 /* messages may arrive multiple times; we need to check for duplicates */
684 static HWND oldhwnd = NULL;
685 static UINT oldmsg = 0;
686 static WPARAM oldwParam = 0;
687 static LPARAM oldlParam = 0;
688
689 if ((hwnd == oldhwnd) && (msg == oldmsg) && (wParam == oldwParam) && (lParam == oldlParam)) {
690 // we already saw this message
691 return TRUE;
692 }
693 oldhwnd = hwnd; oldmsg = msg; oldwParam = wParam; oldlParam = lParam;
694
695 // fake a key up transition for typematic repeat
696 if (msg == WM_KEYDOWN)
697 if (lParam & 0x40000000) { // key was down before
698 dprintf(("Repeat\n"));
699 GEN_KEYEVENT(scan, // scancode
700 0, // key up
701 time(NULL), evsequence++);
702 }
703
704 GEN_KEYEVENT(scan, // scancode
705 (lParam & 0x80000000) ? 0 : 0x80,
706 time(NULL), evsequence++);
707
708 if (msg == WM_KEYDOWN)
709 This->keystate[scan] = 0x80;
710 else
711 This->keystate[scan] = 0x00;
712
713 return TRUE;
714}
715
716static HRESULT WINAPI SysKeyboardAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface)
717{
718 ICOM_THIS(SysKeyboardAImpl,iface);
719 TRACE("DINPUT-SKAI: Acquire (this=%p)\n",This);
720
721 if (This->acquired == 0) {
722 /* Store (in a global variable) the current lock */
723 current_keylock = (IDirectInputDeviceA*)This;
724
725 /* register the keyboard event callback */
726 KEYBOARD_Enable(event_keyHandler);
727 This->acquired = 1;
728 }
729 return 0;
730}
731
732static HRESULT WINAPI SysKeyboardAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface)
733{
734 ICOM_THIS(SysKeyboardAImpl,iface);
735 TRACE("DINPUT-SKAI: Unacquire (this=%p)\n",This);
736
737 /* unregister the callback */
738 KEYBOARD_Enable(NULL);
739
740 /* No more locks */
741 current_keylock = NULL;
742
743 This->acquired = 0;
744 return 0;
745}
746
747static HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface(
748 LPDIRECTINPUTDEVICE2A iface,REFIID riid,LPVOID *ppobj
749)
750{
751 ICOM_THIS(IDirectInputDevice2AImpl,iface);
752 char xbuf[50];
753
754 WINE_StringFromCLSID(riid,xbuf);
755 TRACE("(this=%p,%s,%p)\n",This,xbuf,ppobj);
756 if (!memcmp(&IID_IUnknown,riid,sizeof(*riid))) {
757 IDirectInputDevice2_AddRef(iface);
758 *ppobj = This;
759 return 0;
760 }
761 if (!memcmp(&IID_IDirectInputDeviceA,riid,sizeof(*riid))) {
762 IDirectInputDevice2_AddRef(iface);
763 *ppobj = This;
764 return 0;
765 }
766 if (!memcmp(&IID_IDirectInputDevice2A,riid,sizeof(*riid))) {
767 IDirectInputDevice2_AddRef(iface);
768 *ppobj = This;
769 return 0;
770 }
771 return E_FAIL;
772}
773
774static ULONG WINAPI IDirectInputDevice2AImpl_AddRef(
775 LPDIRECTINPUTDEVICE2A iface)
776{
777 ICOM_THIS(IDirectInputDevice2AImpl,iface);
778 return ++This->ref;
779}
780
781static HRESULT WINAPI IDirectInputDevice2AImpl_GetCapabilities(
782 LPDIRECTINPUTDEVICE2A iface,
783 LPDIDEVCAPS lpDIDevCaps)
784{
785 lpDIDevCaps->dwFlags = DIDC_ATTACHED;
786 FIXME("stub!\n");
787 return DI_OK;
788}
789
790static HRESULT WINAPI IDirectInputDevice2AImpl_EnumObjects(
791 LPDIRECTINPUTDEVICE2A iface,
792 LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback,
793 LPVOID lpvRef,
794 DWORD dwFlags)
795{
796 FIXME("stub!\n");
797#if 0
798 if (lpCallback)
799 lpCallback(NULL, lpvRef);
800#endif
801 return DI_OK;
802}
803
804static HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty(
805 LPDIRECTINPUTDEVICE2A iface,
806 REFGUID rguid,
807 LPDIPROPHEADER pdiph)
808{
809 FIXME("stub!\n");
810 return DI_OK;
811}
812
813static HRESULT WINAPI IDirectInputDevice2AImpl_GetObjectInfo(
814 LPDIRECTINPUTDEVICE2A iface,
815 LPDIDEVICEOBJECTINSTANCEA pdidoi,
816 DWORD dwObj,
817 DWORD dwHow)
818{
819 FIXME("stub!\n");
820 return DI_OK;
821}
822
823static HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceInfo(
824 LPDIRECTINPUTDEVICE2A iface,
825 LPDIDEVICEINSTANCEA pdidi)
826{
827 FIXME("stub!\n");
828 return DI_OK;
829}
830
831static HRESULT WINAPI IDirectInputDevice2AImpl_RunControlPanel(
832 LPDIRECTINPUTDEVICE2A iface,
833 HWND hwndOwner,
834 DWORD dwFlags)
835{
836 FIXME("stub!\n");
837 return DI_OK;
838}
839
840static HRESULT WINAPI IDirectInputDevice2AImpl_Initialize(
841 LPDIRECTINPUTDEVICE2A iface,
842 HINSTANCE hinst,
843 DWORD dwVersion,
844 REFGUID rguid)
845{
846 FIXME("stub!\n");
847 return DI_OK;
848}
849
850/******************************************************************************
851 * IDirectInputDevice2A
852 */
853
854static HRESULT WINAPI IDirectInputDevice2AImpl_CreateEffect(
855 LPDIRECTINPUTDEVICE2A iface,
856 REFGUID rguid,
857 LPCDIEFFECT lpeff,
858 LPDIRECTINPUTEFFECT *ppdef,
859 LPUNKNOWN pUnkOuter)
860{
861 FIXME("stub!\n");
862 return DI_OK;
863}
864
865static HRESULT WINAPI IDirectInputDevice2AImpl_EnumEffects(
866 LPDIRECTINPUTDEVICE2A iface,
867 LPDIENUMEFFECTSCALLBACKA lpCallback,
868 LPVOID lpvRef,
869 DWORD dwFlags)
870{
871 FIXME("stub!\n");
872 if (lpCallback)
873 lpCallback(NULL, lpvRef);
874 return DI_OK;
875}
876
877static HRESULT WINAPI IDirectInputDevice2AImpl_GetEffectInfo(
878 LPDIRECTINPUTDEVICE2A iface,
879 LPDIEFFECTINFOA lpdei,
880 REFGUID rguid)
881{
882 FIXME("stub!\n");
883 return DI_OK;
884}
885
886static HRESULT WINAPI IDirectInputDevice2AImpl_GetForceFeedbackState(
887 LPDIRECTINPUTDEVICE2A iface,
888 LPDWORD pdwOut)
889{
890 FIXME("stub!\n");
891 return DI_OK;
892}
893
894static HRESULT WINAPI IDirectInputDevice2AImpl_SendForceFeedbackCommand(
895 LPDIRECTINPUTDEVICE2A iface,
896 DWORD dwFlags)
897{
898 FIXME("stub!\n");
899 return DI_OK;
900}
901
902static HRESULT WINAPI IDirectInputDevice2AImpl_EnumCreatedEffectObjects(
903 LPDIRECTINPUTDEVICE2A iface,
904 LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback,
905 LPVOID lpvRef,
906 DWORD dwFlags)
907{
908 FIXME("stub!\n");
909 if (lpCallback)
910 lpCallback(NULL, lpvRef);
911 return DI_OK;
912}
913
914static HRESULT WINAPI IDirectInputDevice2AImpl_Escape(
915 LPDIRECTINPUTDEVICE2A iface,
916 LPDIEFFESCAPE lpDIEEsc)
917{
918 FIXME("stub!\n");
919 return DI_OK;
920}
921
922static HRESULT WINAPI IDirectInputDevice2AImpl_Poll(
923 LPDIRECTINPUTDEVICE2A iface)
924{
925 FIXME("stub!\n");
926 return DI_OK;
927}
928
929static HRESULT WINAPI IDirectInputDevice2AImpl_SendDeviceData(
930 LPDIRECTINPUTDEVICE2A iface,
931 DWORD cbObjectData,
932 LPDIDEVICEOBJECTDATA rgdod,
933 LPDWORD pdwInOut,
934 DWORD dwFlags)
935{
936 FIXME("stub!\n");
937 return DI_OK;
938}
939
940/******************************************************************************
941 * SysMouseA (DInput Mouse support)
942 */
943
944/******************************************************************************
945 * Release : release the mouse buffer.
946 */
947static ULONG WINAPI SysMouseAImpl_Release(LPDIRECTINPUTDEVICE2A iface)
948{
949 ICOM_THIS(SysMouseAImpl,iface);
950
951 This->ref--;
952 if (This->ref)
953 return This->ref;
954
955 /* Free the data queue */
956 if (This->data_queue != NULL)
957 HeapFree(GetProcessHeap(),0,This->data_queue);
958
959 /* Install the previous event handler (in case of releasing an aquired
960 mouse device) */
961 if (This->prev_handler != NULL)
962 MOUSE_Enable(This->prev_handler);
963 DeleteCriticalSection(&(This->crit));
964
965 HeapFree(GetProcessHeap(),0,This);
966 return 0;
967}
968
969
970/******************************************************************************
971 * SetCooperativeLevel : store the window in which we will do our
972 * grabbing.
973 */
974static HRESULT WINAPI SysMouseAImpl_SetCooperativeLevel(
975 LPDIRECTINPUTDEVICE2A iface,HWND hwnd,DWORD dwflags
976)
977{
978 ICOM_THIS(SysMouseAImpl,iface);
979
980 TRACE("(this=%p,0x%08lx,0x%08lx): stub\n",This,(DWORD)hwnd,dwflags);
981
982// if (TRACE_ON(dinput))
983// _dump_cooperativelevel(dwflags);
984
985 /* Store the window which asks for the mouse */
986 This->win = hwnd;
987
988 return 0;
989}
990
991
992/******************************************************************************
993 * SetDataFormat : the application can choose the format of the data
994 * the device driver sends back with GetDeviceState.
995 *
996 * For the moment, only the "standard" configuration (c_dfDIMouse) is supported
997 * in absolute and relative mode.
998 */
999static HRESULT WINAPI SysMouseAImpl_SetDataFormat(
1000 LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df
1001)
1002{
1003 ICOM_THIS(SysMouseAImpl,iface);
1004 int i;
1005
1006 TRACE("DINPUT-SMAI: SetDataFormat(this=%p,%p)\n",This,df);
1007
1008 TRACE("(df.dwSize=%ld)\n",df->dwSize);
1009 TRACE("(df.dwObjsize=%ld)\n",df->dwObjSize);
1010 TRACE("(df.dwFlags=0x%08lx)\n",df->dwFlags);
1011 TRACE("(df.dwDataSize=%ld)\n",df->dwDataSize);
1012 TRACE("(df.dwNumObjs=%ld)\n",df->dwNumObjs);
1013
1014 for (i=0;i<df->dwNumObjs;i++) {
1015 char xbuf[50];
1016
1017 if (df->rgodf[i].pguid)
1018 WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
1019 else
1020 strcpy(xbuf,"<no guid>");
1021 TRACE("df.rgodf[%d].guid %s (%p)\n",i,xbuf, df->rgodf[i].pguid);
1022 TRACE("df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
1023 TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
1024 TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
1025 }
1026
1027 /* Check size of data format to prevent crashes if the applications
1028 sends a smaller buffer */
1029 if (df->dwDataSize != sizeof(struct DIMOUSESTATE)) {
1030 FIXME("non-standard mouse configuration not supported yet.");
1031 return DIERR_INVALIDPARAM;
1032 }
1033
1034 /* For the moment, ignore these fields and return always as if
1035 c_dfDIMouse was passed as format... */
1036
1037 /* Check if the mouse is in absolute or relative mode */
1038 if (df->dwFlags == DIDF_ABSAXIS)
1039 This->absolute = 1;
1040 else if (df->dwFlags == DIDF_RELAXIS)
1041 This->absolute = 0;
1042 else
1043 ERR("Neither absolute nor relative flag set.");
1044
1045 This->df = (LPCDIDATAFORMAT)HeapAlloc(GetProcessHeap(),0,df->dwSize+(df->dwNumObjs*df->dwObjSize));
1046 memcpy(This->df,df,df->dwSize+(df->dwNumObjs*df->dwObjSize));
1047 return 0;
1048}
1049
1050#define GEN_EVENT(offset,data,xtime,seq) \
1051{ \
1052 if (This->queue_pos < This->queue_len) { \
1053 This->data_queue[This->queue_pos].dwOfs = offset; \
1054 This->data_queue[This->queue_pos].dwData = data; \
1055 This->data_queue[This->queue_pos].dwTimeStamp = xtime; \
1056 This->data_queue[This->queue_pos].dwSequence = seq; \
1057 This->queue_pos++; \
1058 } \
1059}
1060
1061
1062/* Our private mouse event handler */
1063static BOOL WINAPI dinput_mouse_event( DWORD dwFlags, DWORD dx, DWORD dy,
1064 DWORD cButtons, DWORD dwExtraInfo )
1065{
1066 DWORD posX, posY, keyState, xtime, extra;
1067 SysMouseAImpl* This = (SysMouseAImpl*) current_lock;
1068
1069 EnterCriticalSection(&(This->crit));
1070 /* Mouse moved -> send event if asked */
1071 if (This->hEvent)
1072 SetEvent(This->hEvent);
1073
1074 if ( !IsBadReadPtr( (LPVOID)dwExtraInfo, sizeof(WINE_MOUSEEVENT) )
1075 && ((WINE_MOUSEEVENT *)dwExtraInfo)->magic == WINE_MOUSEEVENT_MAGIC ) {
1076 WINE_MOUSEEVENT *wme = (WINE_MOUSEEVENT *)dwExtraInfo;
1077 keyState = wme->keyState;
1078 xtime = wme->time;
1079 extra = (DWORD)wme->hWnd;
1080
1081 if(This->win && This->win != wme->hWnd) {
1082 return FALSE;
1083 }
1084
1085 assert( dwFlags & MOUSEEVENTF_ABSOLUTE );
1086 posX = (dx * GetSystemMetrics(SM_CXSCREEN)) >> 16;
1087 posY = (dy * GetSystemMetrics(SM_CYSCREEN)) >> 16;
1088 } else {
1089 ERR("Mouse event not supported...\n");
1090 LeaveCriticalSection(&(This->crit));
1091 return FALSE;
1092 }
1093
1094 TRACE("DINPUT-SMAI: event %x %ld, %ld", dwFlags, posX, posY);
1095
1096 if ( dwFlags & MOUSEEVENTF_MOVE ) {
1097 if (This->absolute) {
1098 if (posX != This->prevX)
1099 GEN_EVENT(DIMOFS_X, posX, xtime, 0);
1100 if (posY != This->prevY)
1101 GEN_EVENT(DIMOFS_Y, posY, xtime, 0);
1102 } else {
1103 /* Relative mouse input : the real fun starts here... */
1104 if (This->need_warp) {
1105 if (posX != This->prevX)
1106 GEN_EVENT(DIMOFS_X, posX - This->prevX, xtime, evsequence++);
1107 if (posY != This->prevY)
1108 GEN_EVENT(DIMOFS_Y, posY - This->prevY, xtime, evsequence++);
1109 } else {
1110 /* This is the first time the event handler has been called after a
1111 GetData of GetState. */
1112 if (posX != This->win_centerX) {
1113 GEN_EVENT(DIMOFS_X, posX - This->win_centerX, xtime, evsequence++);
1114 This->need_warp = 1;
1115 }
1116
1117 if (posY != This->win_centerY) {
1118 GEN_EVENT(DIMOFS_Y, posY - This->win_centerY, xtime, evsequence++);
1119 This->need_warp = 1;
1120 }
1121 }
1122 }
1123 }
1124 if ( dwFlags & MOUSEEVENTF_LEFTDOWN ) {
1125// if (TRACE_ON(dinput))
1126// DPRINTF(" LD ");
1127
1128 GEN_EVENT(DIMOFS_BUTTON0, 0xFF, xtime, evsequence++);
1129 }
1130 if ( dwFlags & MOUSEEVENTF_LEFTUP ) {
1131// if (TRACE_ON(dinput))
1132// DPRINTF(" LU ");
1133
1134 GEN_EVENT(DIMOFS_BUTTON0, 0x00, xtime, evsequence++);
1135 }
1136 if ( dwFlags & MOUSEEVENTF_RIGHTDOWN ) {
1137// if (TRACE_ON(dinput))
1138// DPRINTF(" RD ");
1139
1140 GEN_EVENT(DIMOFS_BUTTON1, 0xFF, xtime, evsequence++);
1141 }
1142 if ( dwFlags & MOUSEEVENTF_RIGHTUP ) {
1143// if (TRACE_ON(dinput))
1144// DPRINTF(" RU ");
1145
1146 GEN_EVENT(DIMOFS_BUTTON1, 0x00, xtime, evsequence++);
1147 }
1148 if ( dwFlags & MOUSEEVENTF_MIDDLEDOWN ) {
1149// if (TRACE_ON(dinput))
1150// DPRINTF(" MD ");
1151
1152 GEN_EVENT(DIMOFS_BUTTON2, 0xFF, xtime, evsequence++);
1153 }
1154 if ( dwFlags & MOUSEEVENTF_MIDDLEUP ) {
1155// if (TRACE_ON(dinput))
1156// DPRINTF(" MU ");
1157
1158 GEN_EVENT(DIMOFS_BUTTON2, 0x00, xtime, evsequence++);
1159 }
1160// if (TRACE_ON(dinput))
1161// DPRINTF("\n");
1162
1163 This->prevX = posX;
1164 This->prevY = posY;
1165 LeaveCriticalSection(&(This->crit));
1166
1167 return TRUE;
1168}
1169
1170
1171/******************************************************************************
1172 * Acquire : gets exclusive control of the mouse
1173 */
1174static HRESULT WINAPI SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface)
1175{
1176 ICOM_THIS(SysMouseAImpl,iface);
1177 RECT rect;
1178
1179 TRACE("DINPUT-SMAI: Acquire(this=%p)\n",This);
1180
1181 if (This->acquired == 0) {
1182 POINT point;
1183
1184 /* This stores the current mouse handler. */
1185#ifdef __WIN32OS2__
1186 This->prev_handler = (LPMOUSE_EVENT_PROC)-1;
1187#else
1188 This->prev_handler = mouse_event;
1189#endif
1190
1191 /* Store (in a global variable) the current lock */
1192 current_lock = (IDirectInputDevice2A*)This;
1193
1194 /* Install our own mouse event handler */
1195 MOUSE_Enable(dinput_mouse_event);
1196
1197 /* Get the window dimension and find the center */
1198 GetWindowRect(This->win, &rect);
1199 This->win_centerX = (rect.right - rect.left) / 2;
1200 This->win_centerY = (rect.bottom - rect.top ) / 2;
1201
1202 /* Warp the mouse to the center of the window */
1203 TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY);
1204 point.x = This->win_centerX;
1205 point.y = This->win_centerY;
1206 MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
1207#ifdef __WIN32OS2__
1208 OSLibMoveCursor(point.x, point.y);
1209#else
1210 DISPLAY_MoveCursor(point.x, point.y);
1211#endif
1212
1213 This->acquired = 1;
1214 }
1215 return 0;
1216}
1217
1218/******************************************************************************
1219 * Unacquire : frees the mouse
1220 */
1221static HRESULT WINAPI SysMouseAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface)
1222{
1223 ICOM_THIS(SysMouseAImpl,iface);
1224
1225 TRACE("DINPUT-SMAI: Unacquire (this=%p)\n",This);
1226
1227 /* Reinstall previous mouse event handler */
1228 MOUSE_Enable(This->prev_handler);
1229 This->prev_handler = NULL;
1230
1231 /* No more locks */
1232 current_lock = NULL;
1233
1234 /* Unacquire device */
1235 This->acquired = 0;
1236
1237 return 0;
1238}
1239
1240/******************************************************************************
1241 * GetDeviceState : returns the "state" of the mouse.
1242 *
1243 * For the moment, only the "standard" return structure (DIMOUSESTATE) is
1244 * supported.
1245 */
1246static HRESULT WINAPI SysMouseAImpl_GetDeviceState(
1247 LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr
1248) {
1249 ICOM_THIS(SysMouseAImpl,iface);
1250 DWORD rx, ry, state;
1251 struct DIMOUSESTATE *mstate = (struct DIMOUSESTATE *) ptr;
1252
1253 TRACE("DINPUT-SMAI: GetDeviceState (this=%p,0x%08lx,%p): \n",This,len,ptr);
1254
1255 /* Check if the buffer is big enough */
1256 if (len < sizeof(struct DIMOUSESTATE)) {
1257 FIXME("unsupported state structure.");
1258 return DIERR_INVALIDPARAM;
1259 }
1260
1261 /* Get the mouse position */
1262#ifdef __WIN32OS2__
1263 OSLibQueryMousePos(&rx, &ry, &state);
1264#else
1265 EVENT_QueryPointer(&rx, &ry, &state);
1266#endif
1267 TRACE("(X:%ld - Y:%ld)\n", rx, ry);
1268
1269 /* Fill the mouse state structure */
1270 if (This->absolute) {
1271 mstate->lX = rx;
1272 mstate->lY = ry;
1273 } else {
1274 mstate->lX = rx - This->win_centerX;
1275 mstate->lY = ry - This->win_centerY;
1276
1277 if ((mstate->lX != 0) || (mstate->lY != 0))
1278 This->need_warp = 1;
1279 }
1280 mstate->lZ = 0;
1281 mstate->rgbButtons[0] = (state & MK_LBUTTON ? 0xFF : 0x00);
1282 mstate->rgbButtons[1] = (state & MK_RBUTTON ? 0xFF : 0x00);
1283 mstate->rgbButtons[2] = (state & MK_MBUTTON ? 0xFF : 0x00);
1284 mstate->rgbButtons[3] = 0x00;
1285
1286 /* Check if we need to do a mouse warping */
1287 if (This->need_warp) {
1288 POINT point;
1289
1290 TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY);
1291 point.x = This->win_centerX;
1292 point.y = This->win_centerY;
1293 MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
1294#ifdef __WIN32OS2__
1295 OSLibMoveCursor(point.x, point.y);
1296#else
1297 DISPLAY_MoveCursor(point.x, point.y);
1298#endif
1299 This->need_warp = 0;
1300 }
1301
1302 TRACE("(X: %ld - Y: %ld L: %02x M: %02x R: %02x)\n",
1303 mstate->lX, mstate->lY,
1304 mstate->rgbButtons[0], mstate->rgbButtons[2], mstate->rgbButtons[1]);
1305
1306 return 0;
1307}
1308
1309/******************************************************************************
1310 * GetDeviceState : gets buffered input data.
1311 */
1312static HRESULT WINAPI SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE2A iface,
1313 DWORD dodsize,
1314 LPDIDEVICEOBJECTDATA dod,
1315 LPDWORD entries,
1316 DWORD flags
1317) {
1318 ICOM_THIS(SysMouseAImpl,iface);
1319
1320 EnterCriticalSection(&(This->crit));
1321 TRACE("DINPUT-SMAI: GetDeviceData (%p)->(dods=%ld,entries=%ld,fl=0x%08lx)\n",This,dodsize,*entries,flags);
1322
1323 if (flags & DIGDD_PEEK)
1324 FIXME("DIGDD_PEEK\n");
1325
1326 if (dod == NULL) {
1327 *entries = This->queue_pos;
1328 This->queue_pos = 0;
1329 } else {
1330 /* Check for buffer overflow */
1331 if (This->queue_pos > *entries) {
1332 WARN("Buffer overflow not handled properly yet...\n");
1333 This->queue_pos = *entries;
1334 }
1335 if (dodsize != sizeof(DIDEVICEOBJECTDATA)) {
1336 ERR("Wrong structure size !\n");
1337 LeaveCriticalSection(&(This->crit));
1338 return DIERR_INVALIDPARAM;
1339 }
1340
1341 if (This->queue_pos)
1342 TRACE("Application retrieving %d event(s).\n", This->queue_pos);
1343
1344 /* Copy the buffered data into the application queue */
1345 memcpy(dod, This->data_queue, This->queue_pos * dodsize);
1346 *entries = This->queue_pos;
1347
1348 /* Reset the event queue */
1349 This->queue_pos = 0;
1350 }
1351 LeaveCriticalSection(&(This->crit));
1352
1353#if 0 /* FIXME: seems to create motion events, which fire back at us. */
1354 /* Check if we need to do a mouse warping */
1355 if (This->need_warp) {
1356 POINT point;
1357
1358 TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY);
1359 point.x = This->win_centerX;
1360 point.y = This->win_centerY;
1361 MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
1362
1363#ifdef __WIN32OS2__
1364 OSLibMoveCursor(point.x, point.y);
1365#else
1366 DISPLAY_MoveCursor(point.x, point.y);
1367#endif
1368
1369 This->need_warp = 0;
1370 }
1371#endif
1372 return 0;
1373}
1374
1375/******************************************************************************
1376 * SetProperty : change input device properties
1377 */
1378static HRESULT WINAPI SysMouseAImpl_SetProperty(LPDIRECTINPUTDEVICE2A iface,
1379 REFGUID rguid,
1380 LPCDIPROPHEADER ph)
1381{
1382 ICOM_THIS(SysMouseAImpl,iface);
1383 char xbuf[50];
1384
1385 if (HIWORD(rguid))
1386 WINE_StringFromCLSID(rguid,xbuf);
1387 else
1388 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
1389
1390 TRACE("DINPUT-SMAI: SetProperty (this=%p,%s,%p)\n",This,xbuf,ph);
1391
1392 if (!HIWORD(rguid)) {
1393#ifdef __WIN32OS2__
1394 if(rguid == DIPROP_BUFFERSIZE) {
1395 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
1396
1397 TRACE("buffersize = %ld\n",pd->dwData);
1398
1399 This->data_queue = (LPDIDEVICEOBJECTDATA)HeapAlloc(GetProcessHeap(),0,
1400 pd->dwData * sizeof(DIDEVICEOBJECTDATA));
1401 This->queue_pos = 0;
1402 This->queue_len = pd->dwData;
1403 }
1404 else {
1405 FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,xbuf);
1406 }
1407#else
1408 switch ((DWORD)rguid) {
1409 case (DWORD) DIPROP_BUFFERSIZE: {
1410 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
1411
1412 TRACE("buffersize = %ld\n",pd->dwData);
1413
1414 This->data_queue = (LPDIDEVICEOBJECTDATA)HeapAlloc(GetProcessHeap(),0,
1415 pd->dwData * sizeof(DIDEVICEOBJECTDATA));
1416 This->queue_pos = 0;
1417 This->queue_len = pd->dwData;
1418 break;
1419 }
1420 default:
1421 FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,xbuf);
1422 break;
1423 }
1424#endif
1425 }
1426
1427 return 0;
1428}
1429
1430/******************************************************************************
1431 * SetEventNotification : specifies event to be sent on state change
1432 */
1433static HRESULT WINAPI SysMouseAImpl_SetEventNotification(LPDIRECTINPUTDEVICE2A iface,
1434 HANDLE hnd) {
1435 ICOM_THIS(SysMouseAImpl,iface);
1436
1437 TRACE("DINPUT-SMAI: SetEventNotification (this=%p,0x%08lx)\n",This,(DWORD)hnd);
1438
1439 This->hEvent = hnd;
1440
1441 return DI_OK;
1442}
1443
1444#ifdef HAVE_LINUX_22_JOYSTICK_API
1445/******************************************************************************
1446 * Joystick
1447 */
1448static ULONG WINAPI JoystickAImpl_Release(LPDIRECTINPUTDEVICE2A iface)
1449{
1450 ICOM_THIS(JoystickAImpl,iface);
1451
1452 This->ref--;
1453 if (This->ref)
1454 return This->ref;
1455 HeapFree(GetProcessHeap(),0,This);
1456 return 0;
1457}
1458
1459/******************************************************************************
1460 * SetDataFormat : the application can choose the format of the data
1461 * the device driver sends back with GetDeviceState.
1462 */
1463static HRESULT WINAPI JoystickAImpl_SetDataFormat(
1464 LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df
1465)
1466{
1467 ICOM_THIS(JoystickAImpl,iface);
1468 int i;
1469
1470 TRACE("(this=%p,%p)\n",This,df);
1471
1472 TRACE("(df.dwSize=%ld)\n",df->dwSize);
1473 TRACE("(df.dwObjsize=%ld)\n",df->dwObjSize);
1474 TRACE("(df.dwFlags=0x%08lx)\n",df->dwFlags);
1475 TRACE("(df.dwDataSize=%ld)\n",df->dwDataSize);
1476 TRACE("(df.dwNumObjs=%ld)\n",df->dwNumObjs);
1477
1478 for (i=0;i<df->dwNumObjs;i++) {
1479 char xbuf[50];
1480
1481 if (df->rgodf[i].pguid)
1482 WINE_StringFromCLSID(df->rgodf[i].pguid,xbuf);
1483 else
1484 strcpy(xbuf,"<no guid>");
1485 TRACE("df.rgodf[%d].guid %s (%p)\n",i,xbuf, df->rgodf[i].pguid);
1486 TRACE("df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
1487 TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
1488 TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
1489 }
1490 This->df = HeapAlloc(GetProcessHeap(),0,df->dwSize+(df->dwNumObjs*df->dwObjSize));
1491 memcpy(This->df,df,df->dwSize+(df->dwNumObjs*df->dwObjSize));
1492 return 0;
1493}
1494
1495/******************************************************************************
1496 * Acquire : gets exclusive control of the joystick
1497 */
1498static HRESULT WINAPI JoystickAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface)
1499{
1500 ICOM_THIS(JoystickAImpl,iface);
1501
1502 TRACE("(this=%p)\n",This);
1503 if (This->joyfd!=-1)
1504 return 0;
1505 This->joyfd=open(JOYDEV,O_RDONLY);
1506 if (This->joyfd==-1)
1507 return DIERR_NOTFOUND;
1508 return 0;
1509}
1510
1511/******************************************************************************
1512 * Unacquire : frees the joystick
1513 */
1514static HRESULT WINAPI JoystickAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface)
1515{
1516 ICOM_THIS(JoystickAImpl,iface);
1517
1518 TRACE("(this=%p)\n",This);
1519 if (This->joyfd!=-1) {
1520 close(This->joyfd);
1521 This->joyfd = -1;
1522 }
1523 return 0;
1524}
1525
1526#define map_axis(val) ((val+32768)*(This->lMax-This->lMin)/65536+This->lMin)
1527
1528static void joy_polldev(JoystickAImpl *This) {
1529 struct timeval tv;
1530 fd_set readfds;
1531 struct js_event jse;
1532
1533 if (This->joyfd==-1)
1534 return;
1535 while (1) {
1536 memset(&tv,0,sizeof(tv));
1537 FD_ZERO(&readfds);FD_SET(This->joyfd,&readfds);
1538 if (1>select(This->joyfd+1,&readfds,NULL,NULL,&tv))
1539 return;
1540 /* we have one event, so we can read */
1541 if (sizeof(jse)!=read(This->joyfd,&jse,sizeof(jse))) {
1542 return;
1543 }
1544 TRACE("js_event: type 0x%x, number %d, value %d\n",jse.type,jse.number,jse.value);
1545 if (jse.type & JS_EVENT_BUTTON) {
1546 GEN_EVENT(DIJOFS_BUTTON(jse.number),jse.value?0x80:0x00,jse.time,evsequence++);
1547 This->js.rgbButtons[jse.number] = jse.value?0x80:0x00;
1548 }
1549 if (jse.type & JS_EVENT_AXIS) {
1550 switch (jse.number) {
1551 case 0:
1552 GEN_EVENT(jse.number*4,jse.value,jse.time,evsequence++);
1553 This->js.lX = map_axis(jse.value);
1554 break;
1555 case 1:
1556 GEN_EVENT(jse.number*4,jse.value,jse.time,evsequence++);
1557 This->js.lY = map_axis(jse.value);
1558 break;
1559 case 2:
1560 GEN_EVENT(jse.number*4,jse.value,jse.time,evsequence++);
1561 This->js.lZ = map_axis(jse.value);
1562 break;
1563 default:
1564 FIXME("more then 3 axes (%d) not handled!\n",jse.number);
1565 break;
1566 }
1567 }
1568 }
1569}
1570
1571/******************************************************************************
1572 * GetDeviceState : returns the "state" of the joystick.
1573 *
1574 */
1575static HRESULT WINAPI JoystickAImpl_GetDeviceState(
1576 LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr
1577) {
1578 ICOM_THIS(JoystickAImpl,iface);
1579
1580 joy_polldev(This);
1581 TRACE("(this=%p,0x%08lx,%p)\n",This,len,ptr);
1582 if (len != sizeof(DIJOYSTATE)) {
1583 FIXME("len %ld is not sizeof(DIJOYSTATE), unsupported format.\n",len);
1584 }
1585 memcpy(ptr,&(This->js),len);
1586 This->queue_pos = 0;
1587 return 0;
1588}
1589
1590/******************************************************************************
1591 * GetDeviceState : gets buffered input data.
1592 */
1593static HRESULT WINAPI JoystickAImpl_GetDeviceData(LPDIRECTINPUTDEVICE2A iface,
1594 DWORD dodsize,
1595 LPDIDEVICEOBJECTDATA dod,
1596 LPDWORD entries,
1597 DWORD flags
1598) {
1599 ICOM_THIS(JoystickAImpl,iface);
1600
1601 FIXME("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx),STUB!\n",This,dodsize,*entries,flags);
1602
1603 joy_polldev(This);
1604 if (flags & DIGDD_PEEK)
1605 FIXME("DIGDD_PEEK\n");
1606
1607 if (dod == NULL) {
1608 } else {
1609 }
1610 return 0;
1611}
1612
1613/******************************************************************************
1614 * SetProperty : change input device properties
1615 */
1616static HRESULT WINAPI JoystickAImpl_SetProperty(LPDIRECTINPUTDEVICE2A iface,
1617 REFGUID rguid,
1618 LPCDIPROPHEADER ph)
1619{
1620 ICOM_THIS(JoystickAImpl,iface);
1621 char xbuf[50];
1622
1623 if (HIWORD(rguid))
1624 WINE_StringFromCLSID(rguid,xbuf);
1625 else
1626 sprintf(xbuf,"<special guid %ld>",(DWORD)rguid);
1627
1628 FIXME("(this=%p,%s,%p)\n",This,xbuf,ph);
1629 FIXME("ph.dwSize = %ld, ph.dwHeaderSize =%ld, ph.dwObj = %ld, ph.dwHow= %ld\n",ph->dwSize, ph->dwHeaderSize,ph->dwObj,ph->dwHow);
1630
1631 if (!HIWORD(rguid)) {
1632 switch ((DWORD)rguid) {
1633 case (DWORD) DIPROP_BUFFERSIZE: {
1634 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
1635
1636 FIXME("buffersize = %ld\n",pd->dwData);
1637 break;
1638 }
1639 case (DWORD)DIPROP_RANGE: {
1640 LPCDIPROPRANGE pr = (LPCDIPROPRANGE)ph;
1641
1642 FIXME("proprange(%ld,%ld)\n",pr->lMin,pr->lMax);
1643 This->lMin = pr->lMin;
1644 This->lMax = pr->lMax;
1645 break;
1646 }
1647 case (DWORD)DIPROP_DEADZONE: {
1648 LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
1649
1650 FIXME("deadzone(%ld)\n",pd->dwData);
1651 This->deadzone = pd->dwData;
1652 break;
1653 }
1654 default:
1655 FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,xbuf);
1656 break;
1657 }
1658 }
1659 return 0;
1660}
1661
1662/******************************************************************************
1663 * SetEventNotification : specifies event to be sent on state change
1664 */
1665static HRESULT WINAPI JoystickAImpl_SetEventNotification(
1666 LPDIRECTINPUTDEVICE2A iface, HANDLE hnd
1667) {
1668 ICOM_THIS(JoystickAImpl,iface);
1669
1670 TRACE("(this=%p,0x%08lx)\n",This,(DWORD)hnd);
1671 This->hEvent = hnd;
1672 return DI_OK;
1673}
1674
1675static HRESULT WINAPI JoystickAImpl_GetCapabilities(
1676 LPDIRECTINPUTDEVICE2A iface,
1677 LPDIDEVCAPS lpDIDevCaps)
1678{
1679 ICOM_THIS(JoystickAImpl,iface);
1680 BYTE axes,buttons;
1681 int xfd = This->joyfd;
1682
1683 TRACE("%p->(%p)\n",iface,lpDIDevCaps);
1684 if (xfd==-1)
1685 xfd = open(JOYDEV,O_RDONLY);
1686 lpDIDevCaps->dwFlags = DIDC_ATTACHED;
1687 lpDIDevCaps->dwDevType = DIDEVTYPE_JOYSTICK;
1688#ifdef JSIOCGAXES
1689 if (-1==ioctl(xfd,JSIOCGAXES,&axes))
1690 axes = 2;
1691 lpDIDevCaps->dwAxes = axes;
1692#endif
1693#ifdef JSIOCGBUTTONS
1694 if (-1==ioctl(xfd,JSIOCGAXES,&buttons))
1695 buttons = 2;
1696 lpDIDevCaps->dwButtons = buttons;
1697#endif
1698 if (xfd!=This->joyfd)
1699 close(xfd);
1700 return DI_OK;
1701}
1702static HRESULT WINAPI JoystickAImpl_Poll(LPDIRECTINPUTDEVICE2A iface) {
1703 ICOM_THIS(JoystickAImpl,iface);
1704 TRACE("(),stub!\n");
1705
1706 joy_polldev(This);
1707 return DI_OK;
1708}
1709#endif
1710
1711/****************************************************************************/
1712/****************************************************************************/
1713
1714ICOM_VTABLE(IDirectInputDevice2A) SysKeyboardAvt =
1715{
1716 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1717 IDirectInputDevice2AImpl_QueryInterface,
1718 IDirectInputDevice2AImpl_AddRef,
1719 SysKeyboardAImpl_Release,
1720 IDirectInputDevice2AImpl_GetCapabilities,
1721 IDirectInputDevice2AImpl_EnumObjects,
1722 IDirectInputDevice2AImpl_GetProperty,
1723 SysKeyboardAImpl_SetProperty,
1724 SysKeyboardAImpl_Acquire,
1725 SysKeyboardAImpl_Unacquire,
1726 SysKeyboardAImpl_GetDeviceState,
1727 SysKeyboardAImpl_GetDeviceData,
1728 IDirectInputDevice2AImpl_SetDataFormat,
1729 IDirectInputDevice2AImpl_SetEventNotification,
1730 IDirectInputDevice2AImpl_SetCooperativeLevel,
1731 IDirectInputDevice2AImpl_GetObjectInfo,
1732 IDirectInputDevice2AImpl_GetDeviceInfo,
1733 IDirectInputDevice2AImpl_RunControlPanel,
1734 IDirectInputDevice2AImpl_Initialize,
1735 IDirectInputDevice2AImpl_CreateEffect,
1736 IDirectInputDevice2AImpl_EnumEffects,
1737 IDirectInputDevice2AImpl_GetEffectInfo,
1738 IDirectInputDevice2AImpl_GetForceFeedbackState,
1739 IDirectInputDevice2AImpl_SendForceFeedbackCommand,
1740 IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
1741 IDirectInputDevice2AImpl_Escape,
1742 IDirectInputDevice2AImpl_Poll,
1743 IDirectInputDevice2AImpl_SendDeviceData,
1744};
1745
1746ICOM_VTABLE(IDirectInputDevice2A) SysMouseAvt =
1747{
1748 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1749 IDirectInputDevice2AImpl_QueryInterface,
1750 IDirectInputDevice2AImpl_AddRef,
1751 SysMouseAImpl_Release,
1752 IDirectInputDevice2AImpl_GetCapabilities,
1753 IDirectInputDevice2AImpl_EnumObjects,
1754 IDirectInputDevice2AImpl_GetProperty,
1755 SysMouseAImpl_SetProperty,
1756 SysMouseAImpl_Acquire,
1757 SysMouseAImpl_Unacquire,
1758 SysMouseAImpl_GetDeviceState,
1759 SysMouseAImpl_GetDeviceData,
1760 SysMouseAImpl_SetDataFormat,
1761 SysMouseAImpl_SetEventNotification,
1762 SysMouseAImpl_SetCooperativeLevel,
1763 IDirectInputDevice2AImpl_GetObjectInfo,
1764 IDirectInputDevice2AImpl_GetDeviceInfo,
1765 IDirectInputDevice2AImpl_RunControlPanel,
1766 IDirectInputDevice2AImpl_Initialize,
1767 IDirectInputDevice2AImpl_CreateEffect,
1768 IDirectInputDevice2AImpl_EnumEffects,
1769 IDirectInputDevice2AImpl_GetEffectInfo,
1770 IDirectInputDevice2AImpl_GetForceFeedbackState,
1771 IDirectInputDevice2AImpl_SendForceFeedbackCommand,
1772 IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
1773 IDirectInputDevice2AImpl_Escape,
1774 IDirectInputDevice2AImpl_Poll,
1775 IDirectInputDevice2AImpl_SendDeviceData,
1776};
1777
1778#ifdef HAVE_LINUX_22_JOYSTICK_API
1779ICOM_VTABLE(IDirectInputDevice2A) JoystickAvt =
1780{
1781 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1782 IDirectInputDevice2AImpl_QueryInterface,
1783 IDirectInputDevice2AImpl_AddRef,
1784 JoystickAImpl_Release,
1785 JoystickAImpl_GetCapabilities,
1786 IDirectInputDevice2AImpl_EnumObjects,
1787 IDirectInputDevice2AImpl_GetProperty,
1788 JoystickAImpl_SetProperty,
1789 JoystickAImpl_Acquire,
1790 JoystickAImpl_Unacquire,
1791 JoystickAImpl_GetDeviceState,
1792 JoystickAImpl_GetDeviceData,
1793 JoystickAImpl_SetDataFormat,
1794 JoystickAImpl_SetEventNotification,
1795 IDirectInputDevice2AImpl_SetCooperativeLevel,
1796 IDirectInputDevice2AImpl_GetObjectInfo,
1797 IDirectInputDevice2AImpl_GetDeviceInfo,
1798 IDirectInputDevice2AImpl_RunControlPanel,
1799 IDirectInputDevice2AImpl_Initialize,
1800 IDirectInputDevice2AImpl_CreateEffect,
1801 IDirectInputDevice2AImpl_EnumEffects,
1802 IDirectInputDevice2AImpl_GetEffectInfo,
1803 IDirectInputDevice2AImpl_GetForceFeedbackState,
1804 IDirectInputDevice2AImpl_SendForceFeedbackCommand,
1805 IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
1806 IDirectInputDevice2AImpl_Escape,
1807 JoystickAImpl_Poll,
1808 IDirectInputDevice2AImpl_SendDeviceData,
1809};
1810#endif
Note: See TracBrowser for help on using the repository browser.