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

Last change on this file since 2010 was 1634, checked in by sandervl, 26 years ago

Creation of initial Wine Port (991031)

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