3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998,1999 Lionel Ulmer
9 * - Tomb Raider 2 Demo:
10 * Playable using keyboard only.
11 * - WingCommander Prophecy Demo:
12 * Doesn't get Input Focus.
14 * - Fallout : works great in X and DGA mode
16 * FIXME: The keyboard handling needs to (and will) be merged into keyboard.c
17 * (The current implementation is currently only a proof of concept and
27 #ifdef HAVE_SYS_SIGNAL_H
28 # include <sys/signal.h>
31 #include <sys/fcntl.h>
32 #include <sys/ioctl.h>
34 #ifdef HAVE_SYS_ERRNO_H
35 # include <sys/errno.h>
37 #ifdef HAVE_LINUX_JOYSTICK_H
38 # include <linux/joystick.h>
39 # define JOYDEV "/dev/js0"
41 #include "wine/obj_base.h"
42 #include "debugtools.h"
49 #include "sysmetrics.h"
56 DEFAULT_DEBUG_CHANNEL(dinput
)
58 /* Wine mouse driver object instances */
59 #define WINE_MOUSE_X_AXIS_INSTANCE 0x0001
60 #define WINE_MOUSE_Y_AXIS_INSTANCE 0x0002
61 #define WINE_MOUSE_L_BUTTON_INSTANCE 0x0004
62 #define WINE_MOUSE_R_BUTTON_INSTANCE 0x0008
63 #define WINE_MOUSE_M_BUTTON_INSTANCE 0x0010
65 /* Wine joystick driver object instances */
66 #define WINE_JOYSTICK_AXIS_BASE 0
67 #define WINE_JOYSTICK_BUTTON_BASE 8
69 extern BYTE InputKeyStateTable
[256];
70 extern int min_keycode
, max_keycode
;
71 extern WORD keyc2vkey
[256];
73 /* Routines to do DataFormat / WineFormat conversions */
83 int internal_format_size
;
87 /* ------------------------------- */
88 /* Wine mouse internal data format */
89 /* ------------------------------- */
91 /* Constants used to access the offset array */
92 #define WINE_MOUSE_X_POSITION 0
93 #define WINE_MOUSE_Y_POSITION 1
94 #define WINE_MOUSE_L_POSITION 2
95 #define WINE_MOUSE_R_POSITION 3
96 #define WINE_MOUSE_M_POSITION 4
102 } Wine_InternalMouseData
;
104 #define WINE_INTERNALMOUSE_NUM_OBJS 5
106 static DIOBJECTDATAFORMAT Wine_InternalMouseObjectFormat
[WINE_INTERNALMOUSE_NUM_OBJS
] = {
107 { &GUID_XAxis
, FIELD_OFFSET(Wine_InternalMouseData
, lX
),
108 DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE
) | DIDFT_RELAXIS
, 0 },
109 { &GUID_YAxis
, FIELD_OFFSET(Wine_InternalMouseData
, lY
),
110 DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE
) | DIDFT_RELAXIS
, 0 },
111 { &GUID_Button
, (FIELD_OFFSET(Wine_InternalMouseData
, rgbButtons
)) + 0,
112 DIDFT_MAKEINSTANCE(WINE_MOUSE_L_BUTTON_INSTANCE
) | DIDFT_PSHBUTTON
, 0 },
113 { &GUID_Button
, (FIELD_OFFSET(Wine_InternalMouseData
, rgbButtons
)) + 1,
114 DIDFT_MAKEINSTANCE(WINE_MOUSE_R_BUTTON_INSTANCE
) | DIDFT_PSHBUTTON
, 0 },
115 { &GUID_Button
, (FIELD_OFFSET(Wine_InternalMouseData
, rgbButtons
)) + 2,
116 DIDFT_MAKEINSTANCE(WINE_MOUSE_M_BUTTON_INSTANCE
) | DIDFT_PSHBUTTON
, 0 }
119 static DIDATAFORMAT Wine_InternalMouseFormat
= {
120 0, /* dwSize - unused */
121 0, /* dwObjsize - unused */
122 0, /* dwFlags - unused */
123 sizeof(Wine_InternalMouseData
),
124 WINE_INTERNALMOUSE_NUM_OBJS
, /* dwNumObjs */
125 Wine_InternalMouseObjectFormat
128 static ICOM_VTABLE(IDirectInputA
) ddiavt
;
129 static ICOM_VTABLE(IDirectInputDevice2A
) SysKeyboardAvt
;
130 static ICOM_VTABLE(IDirectInputDevice2A
) SysMouseAvt
;
132 typedef struct IDirectInputAImpl IDirectInputAImpl
;
133 typedef struct IDirectInputDevice2AImpl IDirectInputDevice2AImpl
;
134 typedef struct SysKeyboardAImpl SysKeyboardAImpl
;
135 typedef struct SysMouseAImpl SysMouseAImpl
;
137 struct IDirectInputDevice2AImpl
139 ICOM_VFIELD(IDirectInputDevice2A
);
144 struct SysKeyboardAImpl
146 /* IDirectInputDevice2AImpl */
147 ICOM_VFIELD(IDirectInputDevice2A
);
150 /* SysKeyboardAImpl */
152 KEYBOARD_CONFIG initial_config
;
156 #ifdef HAVE_LINUX_22_JOYSTICK_API
157 typedef struct JoystickAImpl JoystickAImpl
;
158 static ICOM_VTABLE(IDirectInputDevice2A
) JoystickAvt
;
161 /* IDirectInputDevice2AImpl */
162 ICOM_VFIELD(IDirectInputDevice2A
);
166 /* joystick private */
170 LONG lMin
,lMax
,deadzone
;
171 LPDIDEVICEOBJECTDATA data_queue
;
172 int queue_pos
, queue_len
;
179 /* IDirectInputDevice2AImpl */
180 ICOM_VFIELD(IDirectInputDevice2A
);
184 /* The current data format and the conversion between internal
185 and external data formats */
192 /* Previous position for relative moves */
194 LPMOUSE_EVENT_PROC prev_handler
;
196 DWORD win_centerX
, win_centerY
;
197 LPDIDEVICEOBJECTDATA data_queue
;
198 int queue_pos
, queue_len
;
202 CRITICAL_SECTION crit
;
204 /* This is for mouse reporting. */
205 Wine_InternalMouseData m_state
;
208 static int evsequence
=0;
211 /* UIDs for Wine "drivers".
212 When enumerating each device supporting DInput, they have two UIDs :
215 #ifdef HAVE_LINUX_22_JOYSTICK_API
216 static GUID DInput_Wine_Joystick_GUID
= { /* 9e573ed9-7734-11d2-8d4a-23903fb6bdf7 */
220 {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
223 static GUID DInput_Wine_Mouse_GUID
= { /* 9e573ed8-7734-11d2-8d4a-23903fb6bdf7 */
227 {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
229 static GUID DInput_Wine_Keyboard_GUID
= { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */
233 {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41}
236 /* FIXME: This is ugly and not thread safe :/ */
237 static IDirectInputDevice2A
* current_lock
= NULL
;
239 /******************************************************************************
240 * Various debugging tools
242 static void _dump_cooperativelevel(DWORD dwFlags
) {
248 #define FE(x) { x, #x},
252 FE(DISCL_NONEXCLUSIVE
)
255 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
256 if (flags
[i
].mask
& dwFlags
)
257 DPRINTF("%s ",flags
[i
].name
);
261 static void _dump_EnumObjects_flags(DWORD dwFlags
) {
267 #define FE(x) { x, #x},
274 FE(DIDFT_FFEFFECTTRIGGER
)
275 FE(DIDFT_NOCOLLECTION
)
284 if (dwFlags
== DIDFT_ALL
) {
285 DPRINTF("DIDFT_ALL");
288 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
289 if (flags
[i
].mask
& dwFlags
)
290 DPRINTF("%s ",flags
[i
].name
);
291 if (dwFlags
& DIDFT_INSTANCEMASK
)
292 DPRINTF("Instance(%04lx) ", dwFlags
>> 8);
295 static void _dump_DIPROPHEADER(DIPROPHEADER
*diph
) {
296 DPRINTF(" - dwObj = 0x%08lx\n", diph
->dwObj
);
297 DPRINTF(" - dwHow = %s\n",
298 ((diph
->dwHow
== DIPH_DEVICE
) ? "DIPH_DEVICE" :
299 ((diph
->dwHow
== DIPH_BYOFFSET
) ? "DIPH_BYOFFSET" :
300 ((diph
->dwHow
== DIPH_BYID
)) ? "DIPH_BYID" : "unknown")));
303 static void _dump_OBJECTINSTANCE(DIDEVICEOBJECTINSTANCE
*ddoi
) {
304 if (TRACE_ON(dinput
)) {
305 DPRINTF(" - enumerating : 0x%08lx - %2ld - 0x%08lx - %s\n",
306 ddoi
->guidType
.Data1
, ddoi
->dwOfs
, ddoi
->dwType
, ddoi
->tszName
);
310 struct IDirectInputAImpl
312 ICOM_VFIELD(IDirectInputA
);
316 /* Conversion between internal data buffer and external data buffer */
317 static void fill_DataFormat(void *out
, void *in
, DataFormat
*df
) {
319 char *in_c
= (char *) in
;
320 char *out_c
= (char *) out
;
322 if (df
->dt
== NULL
) {
323 /* This means that the app uses Wine's internal data format */
324 memcpy(out
, in
, df
->internal_format_size
);
326 for (i
= 0; i
< df
->size
; i
++) {
327 if (df
->dt
[i
].offset_in
>= 0) {
328 switch (df
->dt
[i
].size
) {
330 TRACE("Copying (c) to %d from %d (value %d)\n",
331 df
->dt
[i
].offset_out
, df
->dt
[i
].offset_in
, *((char *) (in_c
+ df
->dt
[i
].offset_in
)));
332 *((char *) (out_c
+ df
->dt
[i
].offset_out
)) = *((char *) (in_c
+ df
->dt
[i
].offset_in
));
336 TRACE("Copying (s) to %d from %d (value %d)\n",
337 df
->dt
[i
].offset_out
, df
->dt
[i
].offset_in
, *((short *) (in_c
+ df
->dt
[i
].offset_in
)));
338 *((short *) (out_c
+ df
->dt
[i
].offset_out
)) = *((short *) (in_c
+ df
->dt
[i
].offset_in
));
342 TRACE("Copying (i) to %d from %d (value %d)\n",
343 df
->dt
[i
].offset_out
, df
->dt
[i
].offset_in
, *((int *) (in_c
+ df
->dt
[i
].offset_in
)));
344 *((int *) (out_c
+ df
->dt
[i
].offset_out
)) = *((int *) (in_c
+ df
->dt
[i
].offset_in
));
348 memcpy((out_c
+ df
->dt
[i
].offset_out
), (in_c
+ df
->dt
[i
].offset_in
), df
->dt
[i
].size
);
351 switch (df
->dt
[i
].size
) {
353 TRACE("Copying (c) to %d default value %d\n",
354 df
->dt
[i
].offset_out
, df
->dt
[i
].value
);
355 *((char *) (out_c
+ df
->dt
[i
].offset_out
)) = (char) df
->dt
[i
].value
;
359 TRACE("Copying (s) to %d default value %d\n",
360 df
->dt
[i
].offset_out
, df
->dt
[i
].value
);
361 *((short *) (out_c
+ df
->dt
[i
].offset_out
)) = (short) df
->dt
[i
].value
;
365 TRACE("Copying (i) to %d default value %d\n",
366 df
->dt
[i
].offset_out
, df
->dt
[i
].value
);
367 *((int *) (out_c
+ df
->dt
[i
].offset_out
)) = (int) df
->dt
[i
].value
;
371 memset((out_c
+ df
->dt
[i
].offset_out
), df
->dt
[i
].size
, 0);
378 static DataFormat
*create_DataFormat(DIDATAFORMAT
*wine_format
, DIDATAFORMAT
*asked_format
, int *offset
) {
386 ret
= (DataFormat
*) HeapAlloc(GetProcessHeap(), 0, sizeof(DataFormat
));
388 done
= (int *) HeapAlloc(GetProcessHeap(), 0, sizeof(int) * asked_format
->dwNumObjs
);
389 memset(done
, 0, sizeof(int) * asked_format
->dwNumObjs
);
391 dt
= (DataTransform
*) HeapAlloc(GetProcessHeap(), 0, asked_format
->dwNumObjs
* sizeof(DataTransform
));
393 TRACE("Creating DataTransorm : \n");
395 for (i
= 0; i
< wine_format
->dwNumObjs
; i
++) {
398 for (j
= 0; j
< asked_format
->dwNumObjs
; j
++) {
402 if (((asked_format
->rgodf
[j
].pguid
== NULL
) || (IsEqualGUID(wine_format
->rgodf
[i
].pguid
, asked_format
->rgodf
[j
].pguid
)))
404 (wine_format
->rgodf
[i
].dwType
& asked_format
->rgodf
[j
].dwType
)) {
408 TRACE("Matching : \n");
409 TRACE(" - Asked (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n",
410 j
, debugstr_guid(asked_format
->rgodf
[j
].pguid
),
411 asked_format
->rgodf
[j
].dwOfs
,
412 DIDFT_GETTYPE(asked_format
->rgodf
[j
].dwType
), DIDFT_GETINSTANCE(asked_format
->rgodf
[j
].dwType
));
414 TRACE(" - Wine (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n",
415 j
, debugstr_guid(wine_format
->rgodf
[i
].pguid
),
416 wine_format
->rgodf
[i
].dwOfs
,
417 DIDFT_GETTYPE(wine_format
->rgodf
[i
].dwType
), DIDFT_GETINSTANCE(wine_format
->rgodf
[i
].dwType
));
419 if (wine_format
->rgodf
[i
].dwType
& DIDFT_BUTTON
)
420 dt
[index
].size
= sizeof(BYTE
);
422 dt
[index
].size
= sizeof(DWORD
);
423 dt
[index
].offset_in
= wine_format
->rgodf
[i
].dwOfs
;
424 dt
[index
].offset_out
= asked_format
->rgodf
[j
].dwOfs
;
428 if (wine_format
->rgodf
[i
].dwOfs
!= asked_format
->rgodf
[j
].dwOfs
)
431 offset
[i
] = asked_format
->rgodf
[j
].dwOfs
;
436 if (j
== asked_format
->dwNumObjs
)
440 TRACE("Setting to default value :\n");
441 for (j
= 0; j
< asked_format
->dwNumObjs
; j
++) {
443 TRACE(" - Asked (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n",
444 j
, debugstr_guid(asked_format
->rgodf
[j
].pguid
),
445 asked_format
->rgodf
[j
].dwOfs
,
446 DIDFT_GETTYPE(asked_format
->rgodf
[j
].dwType
), DIDFT_GETINSTANCE(asked_format
->rgodf
[j
].dwType
));
449 if (asked_format
->rgodf
[j
].dwType
& DIDFT_BUTTON
)
450 dt
[index
].size
= sizeof(BYTE
);
452 dt
[index
].size
= sizeof(DWORD
);
453 dt
[index
].offset_in
= -1;
454 dt
[index
].offset_out
= asked_format
->rgodf
[j
].dwOfs
;
462 ret
->internal_format_size
= wine_format
->dwDataSize
;
466 HeapFree(GetProcessHeap(), 0, dt
);
471 HeapFree(GetProcessHeap(), 0, done
);
476 /******************************************************************************
477 * DirectInputCreate32A
479 HRESULT WINAPI
DirectInputCreateA(HINSTANCE hinst
, DWORD dwVersion
, LPDIRECTINPUTA
*ppDI
, LPUNKNOWN punkOuter
)
481 IDirectInputAImpl
* This
;
482 TRACE("(0x%08lx,%04lx,%p,%p)\n",
483 (DWORD
)hinst
,dwVersion
,ppDI
,punkOuter
485 This
= (IDirectInputAImpl
*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl
));
487 ICOM_VTBL(This
) = &ddiavt
;
488 *ppDI
=(IDirectInputA
*)This
;
491 /******************************************************************************
492 * IDirectInputA_EnumDevices
494 static HRESULT WINAPI
IDirectInputAImpl_EnumDevices(
495 LPDIRECTINPUTA iface
, DWORD dwDevType
, LPDIENUMDEVICESCALLBACKA lpCallback
,
496 LPVOID pvRef
, DWORD dwFlags
499 ICOM_THIS(IDirectInputAImpl
,iface
);
500 DIDEVICEINSTANCEA devInstance
;
503 TRACE("(this=%p,0x%04lx,%p,%p,%04lx)\n", This
, dwDevType
, lpCallback
, pvRef
, dwFlags
);
505 devInstance
.dwSize
= sizeof(DIDEVICEINSTANCEA
);
506 if ((dwDevType
== 0) || (dwDevType
== DIDEVTYPE_KEYBOARD
)) {
507 /* Return keyboard */
508 devInstance
.guidInstance
= GUID_SysKeyboard
;/* DInput's GUID */
509 devInstance
.guidProduct
= DInput_Wine_Keyboard_GUID
; /* Vendor's GUID */
510 devInstance
.dwDevType
= DIDEVTYPE_KEYBOARD
| (DIDEVTYPEKEYBOARD_UNKNOWN
<< 8);
511 strcpy(devInstance
.tszInstanceName
, "Keyboard");
512 strcpy(devInstance
.tszProductName
, "Wine Keyboard");
514 ret
= lpCallback(&devInstance
, pvRef
);
515 TRACE("Keyboard registered\n");
516 if (ret
== DIENUM_STOP
)
520 if ((dwDevType
== 0) || (dwDevType
== DIDEVTYPE_MOUSE
)) {
522 devInstance
.guidInstance
= GUID_SysMouse
;/* DInput's GUID */
523 devInstance
.guidProduct
= DInput_Wine_Mouse_GUID
; /* Vendor's GUID */
524 devInstance
.dwDevType
= DIDEVTYPE_MOUSE
| (DIDEVTYPEMOUSE_UNKNOWN
<< 8);
525 strcpy(devInstance
.tszInstanceName
, "Mouse");
526 strcpy(devInstance
.tszProductName
, "Wine Mouse");
528 ret
= lpCallback(&devInstance
, pvRef
);
529 TRACE("Mouse registered\n");
530 if (ret
== DIENUM_STOP
)
533 if ((dwDevType
== 0) || (dwDevType
== DIDEVTYPE_JOYSTICK
)) {
534 /* check whether we have a joystick */
535 #ifdef HAVE_LINUX_22_JOYSTICK_API
536 if ( (access(JOYDEV
,O_RDONLY
)!=-1) ||
537 (errno
!=ENODEV
&& errno
!=ENOENT
)
539 /* Return joystick */
540 devInstance
.guidInstance
= GUID_Joystick
;
541 devInstance
.guidProduct
= DInput_Wine_Joystick_GUID
;
542 /* we only support traditional joysticks for now */
543 devInstance
.dwDevType
= DIDEVTYPE_JOYSTICK
| DIDEVTYPEJOYSTICK_TRADITIONAL
;
544 strcpy(devInstance
.tszInstanceName
, "Joystick");
545 /* ioctl JSIOCGNAME(len) */
546 strcpy(devInstance
.tszProductName
, "Wine Joystick");
548 ret
= lpCallback(&devInstance
,pvRef
);
549 TRACE("Joystick registered\n");
550 if (ret
== DIENUM_STOP
)
558 static ULONG WINAPI
IDirectInputAImpl_AddRef(LPDIRECTINPUTA iface
)
560 ICOM_THIS(IDirectInputAImpl
,iface
);
561 return ++(This
->ref
);
564 static ULONG WINAPI
IDirectInputAImpl_Release(LPDIRECTINPUTA iface
)
566 ICOM_THIS(IDirectInputAImpl
,iface
);
567 if (!(--This
->ref
)) {
568 HeapFree(GetProcessHeap(),0,This
);
574 static HRESULT WINAPI
IDirectInputAImpl_CreateDevice(
575 LPDIRECTINPUTA iface
,REFGUID rguid
,LPDIRECTINPUTDEVICEA
* pdev
,
578 ICOM_THIS(IDirectInputAImpl
,iface
);
580 TRACE("(this=%p,%s,%p,%p)\n",This
,debugstr_guid(rguid
),pdev
,punk
);
581 if ((IsEqualGUID(&GUID_SysKeyboard
,rguid
)) || /* Generic Keyboard */
582 (IsEqualGUID(&DInput_Wine_Keyboard_GUID
,rguid
))) { /* Wine Keyboard */
583 SysKeyboardAImpl
* newDevice
;
584 newDevice
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(SysKeyboardAImpl
));
586 ICOM_VTBL(newDevice
) = &SysKeyboardAvt
;
587 memcpy(&(newDevice
->guid
),rguid
,sizeof(*rguid
));
588 memset(newDevice
->keystate
,0,256);
589 *pdev
=(IDirectInputDeviceA
*)newDevice
;
591 TRACE("Creating a Keyboard device (%p)\n", newDevice
);
594 if ((IsEqualGUID(&GUID_SysMouse
,rguid
)) || /* Generic Mouse */
595 (IsEqualGUID(&DInput_Wine_Mouse_GUID
,rguid
))) { /* Wine Mouse */
596 SysMouseAImpl
* newDevice
;
597 int offset_array
[5] = {
598 FIELD_OFFSET(Wine_InternalMouseData
, lX
),
599 FIELD_OFFSET(Wine_InternalMouseData
, lY
),
600 FIELD_OFFSET(Wine_InternalMouseData
, rgbButtons
) + 0,
601 FIELD_OFFSET(Wine_InternalMouseData
, rgbButtons
) + 1,
602 FIELD_OFFSET(Wine_InternalMouseData
, rgbButtons
) + 2
605 newDevice
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(SysMouseAImpl
));
607 ICOM_VTBL(newDevice
) = &SysMouseAvt
;
608 InitializeCriticalSection(&(newDevice
->crit
));
609 MakeCriticalSectionGlobal(&(newDevice
->crit
));
610 memcpy(&(newDevice
->guid
),rguid
,sizeof(*rguid
));
611 *pdev
=(IDirectInputDeviceA
*)newDevice
;
613 /* Per default, Wine uses its internal data format */
614 newDevice
->df
= &Wine_InternalMouseFormat
;
615 memcpy(newDevice
->offset_array
, offset_array
, 5 * sizeof(int));
616 newDevice
->wine_df
= (DataFormat
*) HeapAlloc(GetProcessHeap(), 0, sizeof(DataFormat
));
617 newDevice
->wine_df
->size
= 0;
618 newDevice
->wine_df
->internal_format_size
= Wine_InternalMouseFormat
.dwDataSize
;
619 newDevice
->wine_df
->dt
= NULL
;
621 TRACE("Creating a Mouse device (%p)\n", newDevice
);
624 #ifdef HAVE_LINUX_22_JOYSTICK_API
625 if ((IsEqualGUID(&GUID_Joystick
,rguid
)) ||
626 (IsEqualGUID(&DInput_Wine_Joystick_GUID
,rguid
))) {
627 JoystickAImpl
* newDevice
;
628 newDevice
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(JoystickAImpl
));
630 ICOM_VTBL(newDevice
) = &JoystickAvt
;
631 newDevice
->joyfd
= -1;
632 newDevice
->lMin
= -32768;
633 newDevice
->lMax
= +32767;
634 memcpy(&(newDevice
->guid
),rguid
,sizeof(*rguid
));
635 *pdev
=(IDirectInputDeviceA
*)newDevice
;
637 TRACE("Creating a Joystick device (%p)\n", newDevice
);
644 static HRESULT WINAPI
IDirectInputAImpl_QueryInterface(
645 LPDIRECTINPUTA iface
,REFIID riid
,LPVOID
*ppobj
647 ICOM_THIS(IDirectInputAImpl
,iface
);
649 TRACE("(this=%p,%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
650 if (IsEqualGUID(&IID_IUnknown
,riid
)) {
651 IDirectInputA_AddRef(iface
);
655 if (IsEqualGUID(&IID_IDirectInputA
,riid
)) {
656 IDirectInputA_AddRef(iface
);
660 TRACE("Unsupported interface !\n");
664 static HRESULT WINAPI
IDirectInputAImpl_Initialize(
665 LPDIRECTINPUTA iface
,HINSTANCE hinst
,DWORD x
667 return DIERR_ALREADYINITIALIZED
;
670 static HRESULT WINAPI
IDirectInputAImpl_GetDeviceStatus(LPDIRECTINPUTA iface
,
672 ICOM_THIS(IDirectInputAImpl
,iface
);
674 FIXME("(%p)->(%s): stub\n",This
,debugstr_guid(rguid
));
679 static HRESULT WINAPI
IDirectInputAImpl_RunControlPanel(LPDIRECTINPUTA iface
,
682 ICOM_THIS(IDirectInputAImpl
,iface
);
683 FIXME("(%p)->(%08lx,%08lx): stub\n",This
, (DWORD
) hwndOwner
, dwFlags
);
688 static ICOM_VTABLE(IDirectInputA
) ddiavt
=
690 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
691 IDirectInputAImpl_QueryInterface
,
692 IDirectInputAImpl_AddRef
,
693 IDirectInputAImpl_Release
,
694 IDirectInputAImpl_CreateDevice
,
695 IDirectInputAImpl_EnumDevices
,
696 IDirectInputAImpl_GetDeviceStatus
,
697 IDirectInputAImpl_RunControlPanel
,
698 IDirectInputAImpl_Initialize
701 /******************************************************************************
702 * IDirectInputDeviceA
705 static HRESULT WINAPI
IDirectInputDevice2AImpl_SetDataFormat(
706 LPDIRECTINPUTDEVICE2A iface
,LPCDIDATAFORMAT df
710 TRACE(dinput,"(this=%p,%p)\n",This,df);
712 TRACE(dinput,"df.dwSize=%ld\n",df->dwSize);
713 TRACE(dinput,"(df.dwObjsize=%ld)\n",df->dwObjSize);
714 TRACE(dinput,"(df.dwFlags=0x%08lx)\n",df->dwFlags);
715 TRACE(dinput,"(df.dwDataSize=%ld)\n",df->dwDataSize);
716 TRACE(dinput,"(df.dwNumObjs=%ld)\n",df->dwNumObjs);
718 for (i=0;i<df->dwNumObjs;i++) {
719 TRACE(dinput,"df.rgodf[%d].guid %s\n",i,debugstr_guid(df->rgodf[i].pguid));
720 TRACE(dinput,"df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
721 TRACE(dinput,"dwType 0x%02lx,dwInstance %ld\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
722 TRACE(dinput,"df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
728 static HRESULT WINAPI
IDirectInputDevice2AImpl_SetCooperativeLevel(
729 LPDIRECTINPUTDEVICE2A iface
,HWND hwnd
,DWORD dwflags
731 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
732 TRACE("(this=%p,0x%08lx,0x%08lx)\n",This
,(DWORD
)hwnd
,dwflags
);
733 if (TRACE_ON(dinput
))
734 _dump_cooperativelevel(dwflags
);
738 static HRESULT WINAPI
IDirectInputDevice2AImpl_SetEventNotification(
739 LPDIRECTINPUTDEVICE2A iface
,HANDLE hnd
741 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
742 FIXME("(this=%p,0x%08lx): stub\n",This
,(DWORD
)hnd
);
746 static ULONG WINAPI
IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE2A iface
)
748 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
752 HeapFree(GetProcessHeap(),0,This
);
756 static HRESULT WINAPI
SysKeyboardAImpl_SetProperty(
757 LPDIRECTINPUTDEVICE2A iface
,REFGUID rguid
,LPCDIPROPHEADER ph
760 ICOM_THIS(SysKeyboardAImpl
,iface
);
762 TRACE("(this=%p,%s,%p)\n",This
,debugstr_guid(rguid
),ph
);
763 TRACE("(size=%ld,headersize=%ld,obj=%ld,how=%ld\n",
764 ph
->dwSize
,ph
->dwHeaderSize
,ph
->dwObj
,ph
->dwHow
);
765 if (!HIWORD(rguid
)) {
766 switch ((DWORD
)rguid
) {
767 case (DWORD
) DIPROP_BUFFERSIZE
: {
768 LPCDIPROPDWORD pd
= (LPCDIPROPDWORD
)ph
;
770 TRACE("(buffersize=%ld)\n",pd
->dwData
);
774 WARN("Unknown type %ld\n",(DWORD
)rguid
);
781 static HRESULT WINAPI
SysKeyboardAImpl_GetDeviceState(
782 LPDIRECTINPUTDEVICE2A iface
,DWORD len
,LPVOID ptr
785 return KEYBOARD_Driver
->pGetDIState(len
, ptr
)?DI_OK
:E_FAIL
;
788 static HRESULT WINAPI
SysKeyboardAImpl_GetDeviceData(
789 LPDIRECTINPUTDEVICE2A iface
,DWORD dodsize
,LPDIDEVICEOBJECTDATA dod
,
790 LPDWORD entries
,DWORD flags
793 ICOM_THIS(SysKeyboardAImpl
,iface
);
797 TRACE("(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n",
798 This
,dodsize
,dod
,entries
,entries
?*entries
:0,flags
);
800 ret
=KEYBOARD_Driver
->pGetDIData(
801 This
->keystate
, dodsize
, dod
, entries
, flags
)?DI_OK
:E_FAIL
;
802 for (i
=0;i
<*entries
;i
++) {
803 dod
[i
].dwTimeStamp
= GetTickCount();
804 dod
[i
].dwSequence
= evsequence
++;
809 static HRESULT WINAPI
SysKeyboardAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface
)
811 ICOM_THIS(SysKeyboardAImpl
,iface
);
813 TRACE("(this=%p)\n",This
);
815 if (This
->acquired
== 0) {
816 KEYBOARD_CONFIG no_auto
;
818 /* Save the original config */
819 KEYBOARD_Driver
->pGetKeyboardConfig(&(This
->initial_config
));
821 /* Now, remove auto-repeat */
822 no_auto
.auto_repeat
= FALSE
;
823 KEYBOARD_Driver
->pSetKeyboardConfig(&no_auto
, WINE_KEYBOARD_CONFIG_AUTO_REPEAT
);
831 static HRESULT WINAPI
SysKeyboardAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface
)
833 ICOM_THIS(SysKeyboardAImpl
,iface
);
834 TRACE("(this=%p)\n",This
);
836 if (This
->acquired
== 1) {
837 /* Restore the original configuration */
838 KEYBOARD_Driver
->pSetKeyboardConfig(&(This
->initial_config
), 0xFFFFFFFF);
841 ERR("Unacquiring a not-acquired device !!!\n");
847 /******************************************************************************
848 * GetCapabilities : get the device capablitites
850 static HRESULT WINAPI
SysKeyboardAImpl_GetCapabilities(
851 LPDIRECTINPUTDEVICE2A iface
,
852 LPDIDEVCAPS lpDIDevCaps
)
854 ICOM_THIS(SysMouseAImpl
,iface
);
856 TRACE("(this=%p,%p)\n",This
,lpDIDevCaps
);
858 if (lpDIDevCaps
->dwSize
== sizeof(DIDEVCAPS
)) {
859 lpDIDevCaps
->dwFlags
= DIDC_ATTACHED
;
860 lpDIDevCaps
->dwDevType
= DIDEVTYPE_KEYBOARD
;
861 lpDIDevCaps
->dwAxes
= 0;
862 lpDIDevCaps
->dwButtons
= 0;
863 lpDIDevCaps
->dwPOVs
= 0;
864 lpDIDevCaps
->dwFFSamplePeriod
= 0;
865 lpDIDevCaps
->dwFFMinTimeResolution
= 0;
866 lpDIDevCaps
->dwFirmwareRevision
= 100;
867 lpDIDevCaps
->dwHardwareRevision
= 100;
868 lpDIDevCaps
->dwFFDriverVersion
= 0;
871 FIXME("DirectX 3.0 not supported....\n");
877 static HRESULT WINAPI
IDirectInputDevice2AImpl_QueryInterface(
878 LPDIRECTINPUTDEVICE2A iface
,REFIID riid
,LPVOID
*ppobj
881 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
883 TRACE("(this=%p,%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
884 if (IsEqualGUID(&IID_IUnknown
,riid
)) {
885 IDirectInputDevice2_AddRef(iface
);
889 if (IsEqualGUID(&IID_IDirectInputDeviceA
,riid
)) {
890 IDirectInputDevice2_AddRef(iface
);
894 if (IsEqualGUID(&IID_IDirectInputDevice2A
,riid
)) {
895 IDirectInputDevice2_AddRef(iface
);
899 TRACE("Unsupported interface !\n");
903 static ULONG WINAPI
IDirectInputDevice2AImpl_AddRef(
904 LPDIRECTINPUTDEVICE2A iface
)
906 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
910 static HRESULT WINAPI
IDirectInputDevice2AImpl_EnumObjects(
911 LPDIRECTINPUTDEVICE2A iface
,
912 LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback
,
916 FIXME("(this=%p,%p,%p,%08lx): stub!\n", iface
, lpCallback
, lpvRef
, dwFlags
);
917 if (TRACE_ON(dinput
)) {
918 DPRINTF(" - flags = ");
919 _dump_EnumObjects_flags(dwFlags
);
926 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetProperty(
927 LPDIRECTINPUTDEVICE2A iface
,
929 LPDIPROPHEADER pdiph
)
931 FIXME("(this=%p,%s,%p): stub!\n",
932 iface
, debugstr_guid(rguid
), pdiph
);
934 if (TRACE_ON(dinput
))
935 _dump_DIPROPHEADER(pdiph
);
940 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetObjectInfo(
941 LPDIRECTINPUTDEVICE2A iface
,
942 LPDIDEVICEOBJECTINSTANCEA pdidoi
,
946 FIXME("(this=%p,%p,%ld,0x%08lx): stub!\n",
947 iface
, pdidoi
, dwObj
, dwHow
);
952 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetDeviceInfo(
953 LPDIRECTINPUTDEVICE2A iface
,
954 LPDIDEVICEINSTANCEA pdidi
)
956 FIXME("(this=%p,%p): stub!\n",
962 static HRESULT WINAPI
IDirectInputDevice2AImpl_RunControlPanel(
963 LPDIRECTINPUTDEVICE2A iface
,
967 FIXME("(this=%p,0x%08x,0x%08lx): stub!\n",
968 iface
, hwndOwner
, dwFlags
);
973 static HRESULT WINAPI
IDirectInputDevice2AImpl_Initialize(
974 LPDIRECTINPUTDEVICE2A iface
,
979 FIXME("(this=%p,%d,%ld,%s): stub!\n",
980 iface
, hinst
, dwVersion
, debugstr_guid(rguid
));
984 /******************************************************************************
985 * IDirectInputDevice2A
988 static HRESULT WINAPI
IDirectInputDevice2AImpl_CreateEffect(
989 LPDIRECTINPUTDEVICE2A iface
,
992 LPDIRECTINPUTEFFECT
*ppdef
,
995 FIXME("(this=%p,%s,%p,%p,%p): stub!\n",
996 iface
, debugstr_guid(rguid
), lpeff
, ppdef
, pUnkOuter
);
1000 static HRESULT WINAPI
IDirectInputDevice2AImpl_EnumEffects(
1001 LPDIRECTINPUTDEVICE2A iface
,
1002 LPDIENUMEFFECTSCALLBACKA lpCallback
,
1006 FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
1007 iface
, lpCallback
, lpvRef
, dwFlags
);
1010 lpCallback(NULL
, lpvRef
);
1014 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetEffectInfo(
1015 LPDIRECTINPUTDEVICE2A iface
,
1016 LPDIEFFECTINFOA lpdei
,
1019 FIXME("(this=%p,%p,%s): stub!\n",
1020 iface
, lpdei
, debugstr_guid(rguid
));
1024 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetForceFeedbackState(
1025 LPDIRECTINPUTDEVICE2A iface
,
1028 FIXME("(this=%p,%p): stub!\n",
1033 static HRESULT WINAPI
IDirectInputDevice2AImpl_SendForceFeedbackCommand(
1034 LPDIRECTINPUTDEVICE2A iface
,
1037 FIXME("(this=%p,0x%08lx): stub!\n",
1042 static HRESULT WINAPI
IDirectInputDevice2AImpl_EnumCreatedEffectObjects(
1043 LPDIRECTINPUTDEVICE2A iface
,
1044 LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback
,
1048 FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
1049 iface
, lpCallback
, lpvRef
, dwFlags
);
1051 lpCallback(NULL
, lpvRef
);
1055 static HRESULT WINAPI
IDirectInputDevice2AImpl_Escape(
1056 LPDIRECTINPUTDEVICE2A iface
,
1057 LPDIEFFESCAPE lpDIEEsc
)
1059 FIXME("(this=%p,%p): stub!\n",
1064 static HRESULT WINAPI
IDirectInputDevice2AImpl_Poll(
1065 LPDIRECTINPUTDEVICE2A iface
)
1067 FIXME("(this=%p): stub!\n",
1072 static HRESULT WINAPI
IDirectInputDevice2AImpl_SendDeviceData(
1073 LPDIRECTINPUTDEVICE2A iface
,
1075 LPDIDEVICEOBJECTDATA rgdod
,
1079 FIXME("(this=%p,0x%08lx,%p,%p,0x%08lx): stub!\n",
1080 iface
, cbObjectData
, rgdod
, pdwInOut
, dwFlags
);
1085 /******************************************************************************
1086 * SysMouseA (DInput Mouse support)
1089 /******************************************************************************
1090 * Release : release the mouse buffer.
1092 static ULONG WINAPI
SysMouseAImpl_Release(LPDIRECTINPUTDEVICE2A iface
)
1094 ICOM_THIS(SysMouseAImpl
,iface
);
1100 /* Free the data queue */
1101 if (This
->data_queue
!= NULL
)
1102 HeapFree(GetProcessHeap(),0,This
->data_queue
);
1104 /* Install the previous event handler (in case of releasing an aquired
1106 if (This
->prev_handler
!= NULL
)
1107 MOUSE_Enable(This
->prev_handler
);
1108 DeleteCriticalSection(&(This
->crit
));
1110 /* Free the DataFormat */
1111 if (This
->df
!= &(Wine_InternalMouseFormat
)) {
1112 HeapFree(GetProcessHeap(), 0, This
->df
->rgodf
);
1113 HeapFree(GetProcessHeap(), 0, This
->df
);
1116 HeapFree(GetProcessHeap(),0,This
);
1121 /******************************************************************************
1122 * SetCooperativeLevel : store the window in which we will do our
1125 static HRESULT WINAPI
SysMouseAImpl_SetCooperativeLevel(
1126 LPDIRECTINPUTDEVICE2A iface
,HWND hwnd
,DWORD dwflags
1129 ICOM_THIS(SysMouseAImpl
,iface
);
1131 TRACE("(this=%p,0x%08lx,0x%08lx)\n",This
,(DWORD
)hwnd
,dwflags
);
1133 if (TRACE_ON(dinput
))
1134 _dump_cooperativelevel(dwflags
);
1136 /* Store the window which asks for the mouse */
1143 /******************************************************************************
1144 * SetDataFormat : the application can choose the format of the data
1145 * the device driver sends back with GetDeviceState.
1147 * For the moment, only the "standard" configuration (c_dfDIMouse) is supported
1148 * in absolute and relative mode.
1150 static HRESULT WINAPI
SysMouseAImpl_SetDataFormat(
1151 LPDIRECTINPUTDEVICE2A iface
,LPCDIDATAFORMAT df
1154 ICOM_THIS(SysMouseAImpl
,iface
);
1157 TRACE("(this=%p,%p)\n",This
,df
);
1159 TRACE("(df.dwSize=%ld)\n",df
->dwSize
);
1160 TRACE("(df.dwObjsize=%ld)\n",df
->dwObjSize
);
1161 TRACE("(df.dwFlags=0x%08lx)\n",df
->dwFlags
);
1162 TRACE("(df.dwDataSize=%ld)\n",df
->dwDataSize
);
1163 TRACE("(df.dwNumObjs=%ld)\n",df
->dwNumObjs
);
1165 for (i
=0;i
<df
->dwNumObjs
;i
++) {
1167 TRACE("df.rgodf[%d].guid %s (%p)\n",i
, debugstr_guid(df
->rgodf
[i
].pguid
), df
->rgodf
[i
].pguid
);
1168 TRACE("df.rgodf[%d].dwOfs %ld\n",i
,df
->rgodf
[i
].dwOfs
);
1169 TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df
->rgodf
[i
].dwType
),DIDFT_GETINSTANCE(df
->rgodf
[i
].dwType
));
1170 TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i
,df
->rgodf
[i
].dwFlags
);
1173 /* Check if the mouse is in absolute or relative mode */
1174 if (df
->dwFlags
== DIDF_ABSAXIS
)
1176 else if (df
->dwFlags
== DIDF_RELAXIS
)
1179 ERR("Neither absolute nor relative flag set.");
1181 /* Store the new data format */
1182 This
->df
= HeapAlloc(GetProcessHeap(),0,df
->dwSize
);
1183 memcpy(This
->df
, df
, df
->dwSize
);
1184 This
->df
->rgodf
= HeapAlloc(GetProcessHeap(),0,df
->dwNumObjs
*df
->dwObjSize
);
1185 memcpy(This
->df
->rgodf
,df
->rgodf
,df
->dwNumObjs
*df
->dwObjSize
);
1187 /* Prepare all the data-conversion filters */
1188 This
->wine_df
= create_DataFormat(&(Wine_InternalMouseFormat
), df
, This
->offset_array
);
1193 #define GEN_EVENT(offset,data,xtime,seq) \
1195 if ((offset >= 0) && (This->queue_pos < This->queue_len)) { \
1196 This->data_queue[This->queue_pos].dwOfs = offset; \
1197 This->data_queue[This->queue_pos].dwData = data; \
1198 This->data_queue[This->queue_pos].dwTimeStamp = xtime; \
1199 This->data_queue[This->queue_pos].dwSequence = seq; \
1200 This->queue_pos++; \
1205 /* Our private mouse event handler */
1206 static void WINAPI
dinput_mouse_event( DWORD dwFlags
, DWORD dx
, DWORD dy
,
1207 DWORD cButtons
, DWORD dwExtraInfo
)
1209 DWORD posX
, posY
, keyState
, xtime
, extra
;
1210 SysMouseAImpl
* This
= (SysMouseAImpl
*) current_lock
;
1212 EnterCriticalSection(&(This
->crit
));
1213 /* Mouse moved -> send event if asked */
1215 SetEvent(This
->hEvent
);
1217 if ( !IsBadReadPtr( (LPVOID
)dwExtraInfo
, sizeof(WINE_MOUSEEVENT
) )
1218 && ((WINE_MOUSEEVENT
*)dwExtraInfo
)->magic
== WINE_MOUSEEVENT_MAGIC
) {
1219 WINE_MOUSEEVENT
*wme
= (WINE_MOUSEEVENT
*)dwExtraInfo
;
1220 keyState
= wme
->keyState
;
1222 extra
= (DWORD
)wme
->hWnd
;
1224 if ((dwFlags
& MOUSEEVENTF_MOVE
) &&
1225 (dwFlags
& MOUSEEVENTF_ABSOLUTE
)) {
1226 posX
= (dx
* GetSystemMetrics(SM_CXSCREEN
)) >> 16;
1227 posY
= (dy
* GetSystemMetrics(SM_CYSCREEN
)) >> 16;
1233 ERR("Mouse event not supported...\n");
1234 LeaveCriticalSection(&(This
->crit
));
1238 TRACE(" %ld %ld ", posX
, posY
);
1240 if ( dwFlags
& MOUSEEVENTF_MOVE
) {
1241 if (This
->absolute
) {
1242 if (posX
!= This
->prevX
)
1243 GEN_EVENT(This
->offset_array
[WINE_MOUSE_X_POSITION
], posX
, xtime
, 0);
1244 if (posY
!= This
->prevY
)
1245 GEN_EVENT(This
->offset_array
[WINE_MOUSE_Y_POSITION
], posY
, xtime
, 0);
1247 /* Relative mouse input : the real fun starts here... */
1248 if (This
->need_warp
) {
1249 if (posX
!= This
->prevX
)
1250 GEN_EVENT(This
->offset_array
[WINE_MOUSE_X_POSITION
], posX
- This
->prevX
, xtime
, evsequence
++);
1251 if (posY
!= This
->prevY
)
1252 GEN_EVENT(This
->offset_array
[WINE_MOUSE_Y_POSITION
], posY
- This
->prevY
, xtime
, evsequence
++);
1254 /* This is the first time the event handler has been called after a
1255 GetData of GetState. */
1256 if (posX
!= This
->win_centerX
) {
1257 GEN_EVENT(This
->offset_array
[WINE_MOUSE_X_POSITION
], posX
- This
->win_centerX
, xtime
, evsequence
++);
1258 This
->need_warp
= 1;
1261 if (posY
!= This
->win_centerY
) {
1262 GEN_EVENT(This
->offset_array
[WINE_MOUSE_Y_POSITION
], posY
- This
->win_centerY
, xtime
, evsequence
++);
1263 This
->need_warp
= 1;
1268 if ( dwFlags
& MOUSEEVENTF_LEFTDOWN
) {
1269 if (TRACE_ON(dinput
))
1272 GEN_EVENT(This
->offset_array
[WINE_MOUSE_L_POSITION
], 0xFF, xtime
, evsequence
++);
1273 This
->m_state
.rgbButtons
[0] = 0xFF;
1275 if ( dwFlags
& MOUSEEVENTF_LEFTUP
) {
1276 if (TRACE_ON(dinput
))
1279 GEN_EVENT(This
->offset_array
[WINE_MOUSE_L_POSITION
], 0x00, xtime
, evsequence
++);
1280 This
->m_state
.rgbButtons
[0] = 0x00;
1282 if ( dwFlags
& MOUSEEVENTF_RIGHTDOWN
) {
1283 if (TRACE_ON(dinput
))
1286 GEN_EVENT(This
->offset_array
[WINE_MOUSE_R_POSITION
], 0xFF, xtime
, evsequence
++);
1287 This
->m_state
.rgbButtons
[1] = 0xFF;
1289 if ( dwFlags
& MOUSEEVENTF_RIGHTUP
) {
1290 if (TRACE_ON(dinput
))
1293 GEN_EVENT(This
->offset_array
[WINE_MOUSE_R_POSITION
], 0x00, xtime
, evsequence
++);
1294 This
->m_state
.rgbButtons
[1] = 0x00;
1296 if ( dwFlags
& MOUSEEVENTF_MIDDLEDOWN
) {
1297 if (TRACE_ON(dinput
))
1300 GEN_EVENT(This
->offset_array
[WINE_MOUSE_M_POSITION
], 0xFF, xtime
, evsequence
++);
1301 This
->m_state
.rgbButtons
[2] = 0xFF;
1303 if ( dwFlags
& MOUSEEVENTF_MIDDLEUP
) {
1304 if (TRACE_ON(dinput
))
1307 GEN_EVENT(This
->offset_array
[WINE_MOUSE_M_POSITION
], 0x00, xtime
, evsequence
++);
1308 This
->m_state
.rgbButtons
[2] = 0x00;
1310 if (TRACE_ON(dinput
))
1316 if (This
->absolute
) {
1317 This
->m_state
.lX
= posX
;
1318 This
->m_state
.lY
= posY
;
1320 This
->m_state
.lX
= posX
- This
->win_centerX
;
1321 This
->m_state
.lY
= posY
- This
->win_centerY
;
1324 LeaveCriticalSection(&(This
->crit
));
1329 /******************************************************************************
1330 * Acquire : gets exclusive control of the mouse
1332 static HRESULT WINAPI
SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface
)
1334 ICOM_THIS(SysMouseAImpl
,iface
);
1337 TRACE("(this=%p)\n",This
);
1339 if (This
->acquired
== 0) {
1342 /* This stores the current mouse handler. */
1343 This
->prev_handler
= mouse_event
;
1345 /* Store (in a global variable) the current lock */
1346 current_lock
= (IDirectInputDevice2A
*)This
;
1348 /* Init the mouse state */
1349 This
->m_state
.lX
= PosX
;
1350 This
->m_state
.lY
= PosY
;
1351 This
->m_state
.rgbButtons
[0] = (MouseButtonsStates
[0] ? 0xFF : 0x00);
1352 This
->m_state
.rgbButtons
[1] = (MouseButtonsStates
[1] ? 0xFF : 0x00);
1353 This
->m_state
.rgbButtons
[2] = (MouseButtonsStates
[2] ? 0xFF : 0x00);
1355 /* Install our own mouse event handler */
1356 MOUSE_Enable(dinput_mouse_event
);
1358 /* Get the window dimension and find the center */
1359 GetWindowRect(This
->win
, &rect
);
1360 This
->win_centerX
= (rect
.right
- rect
.left
) / 2;
1361 This
->win_centerY
= (rect
.bottom
- rect
.top
) / 2;
1363 /* Warp the mouse to the center of the window */
1364 TRACE("Warping mouse to %ld - %ld\n", This
->win_centerX
, This
->win_centerY
);
1365 point
.x
= This
->win_centerX
;
1366 point
.y
= This
->win_centerY
;
1367 MapWindowPoints(This
->win
, HWND_DESKTOP
, &point
, 1);
1368 DISPLAY_MoveCursor(point
.x
, point
.y
);
1375 /******************************************************************************
1376 * Unacquire : frees the mouse
1378 static HRESULT WINAPI
SysMouseAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface
)
1380 ICOM_THIS(SysMouseAImpl
,iface
);
1382 TRACE("(this=%p)\n",This
);
1384 /* Reinstall previous mouse event handler */
1385 MOUSE_Enable(This
->prev_handler
);
1386 This
->prev_handler
= NULL
;
1389 current_lock
= NULL
;
1391 /* Unacquire device */
1397 /******************************************************************************
1398 * GetDeviceState : returns the "state" of the mouse.
1400 * For the moment, only the "standard" return structure (DIMOUSESTATE) is
1403 static HRESULT WINAPI
SysMouseAImpl_GetDeviceState(
1404 LPDIRECTINPUTDEVICE2A iface
,DWORD len
,LPVOID ptr
1406 ICOM_THIS(SysMouseAImpl
,iface
);
1408 EnterCriticalSection(&(This
->crit
));
1409 TRACE("(this=%p,0x%08lx,%p): \n",This
,len
,ptr
);
1411 /* Copy the current mouse state */
1412 fill_DataFormat(ptr
, &(This
->m_state
), This
->wine_df
);
1414 /* Check if we need to do a mouse warping */
1415 if (This
->need_warp
) {
1418 TRACE("Warping mouse to %ld - %ld\n", This
->win_centerX
, This
->win_centerY
);
1419 point
.x
= This
->win_centerX
;
1420 point
.y
= This
->win_centerY
;
1421 MapWindowPoints(This
->win
, HWND_DESKTOP
, &point
, 1);
1422 DISPLAY_MoveCursor(point
.x
, point
.y
);
1424 This
->need_warp
= 0;
1427 LeaveCriticalSection(&(This
->crit
));
1429 TRACE("(X: %ld - Y: %ld L: %02x M: %02x R: %02x)\n",
1430 This
->m_state
.lX
, This
->m_state
.lY
,
1431 This
->m_state
.rgbButtons
[0], This
->m_state
.rgbButtons
[2], This
->m_state
.rgbButtons
[1]);
1436 /******************************************************************************
1437 * GetDeviceState : gets buffered input data.
1439 static HRESULT WINAPI
SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE2A iface
,
1441 LPDIDEVICEOBJECTDATA dod
,
1445 ICOM_THIS(SysMouseAImpl
,iface
);
1447 EnterCriticalSection(&(This
->crit
));
1448 TRACE("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx)\n",This
,dodsize
,*entries
,flags
);
1450 if (flags
& DIGDD_PEEK
)
1451 FIXME("DIGDD_PEEK\n");
1454 *entries
= This
->queue_pos
;
1455 This
->queue_pos
= 0;
1457 /* Check for buffer overflow */
1458 if (This
->queue_pos
> *entries
) {
1459 WARN("Buffer overflow not handled properly yet...\n");
1460 This
->queue_pos
= *entries
;
1462 if (dodsize
!= sizeof(DIDEVICEOBJECTDATA
)) {
1463 ERR("Wrong structure size !\n");
1464 LeaveCriticalSection(&(This
->crit
));
1465 return DIERR_INVALIDPARAM
;
1468 if (This
->queue_pos
)
1469 TRACE("Application retrieving %d event(s).\n", This
->queue_pos
);
1471 /* Copy the buffered data into the application queue */
1472 memcpy(dod
, This
->data_queue
, This
->queue_pos
* dodsize
);
1473 *entries
= This
->queue_pos
;
1475 /* Reset the event queue */
1476 This
->queue_pos
= 0;
1478 LeaveCriticalSection(&(This
->crit
));
1480 #if 0 /* FIXME: seems to create motion events, which fire back at us. */
1481 /* Check if we need to do a mouse warping */
1482 if (This
->need_warp
) {
1485 TRACE("Warping mouse to %ld - %ld\n", This
->win_centerX
, This
->win_centerY
);
1486 point
.x
= This
->win_centerX
;
1487 point
.y
= This
->win_centerY
;
1488 MapWindowPoints(This
->win
, HWND_DESKTOP
, &point
, 1);
1490 DISPLAY_MoveCursor(point
.x
, point
.y
);
1492 This
->need_warp
= 0;
1498 /******************************************************************************
1499 * SetProperty : change input device properties
1501 static HRESULT WINAPI
SysMouseAImpl_SetProperty(LPDIRECTINPUTDEVICE2A iface
,
1505 ICOM_THIS(SysMouseAImpl
,iface
);
1507 TRACE("(this=%p,%s,%p)\n",This
,debugstr_guid(rguid
),ph
);
1509 if (!HIWORD(rguid
)) {
1510 switch ((DWORD
)rguid
) {
1511 case (DWORD
) DIPROP_BUFFERSIZE
: {
1512 LPCDIPROPDWORD pd
= (LPCDIPROPDWORD
)ph
;
1514 TRACE("buffersize = %ld\n",pd
->dwData
);
1516 This
->data_queue
= (LPDIDEVICEOBJECTDATA
)HeapAlloc(GetProcessHeap(),0,
1517 pd
->dwData
* sizeof(DIDEVICEOBJECTDATA
));
1518 This
->queue_pos
= 0;
1519 This
->queue_len
= pd
->dwData
;
1523 FIXME("Unknown type %ld (%s)\n",(DWORD
)rguid
,debugstr_guid(rguid
));
1531 /******************************************************************************
1532 * GetProperty : get input device properties
1534 static HRESULT WINAPI
SysMouseAImpl_GetProperty(LPDIRECTINPUTDEVICE2A iface
,
1536 LPDIPROPHEADER pdiph
)
1538 ICOM_THIS(SysMouseAImpl
,iface
);
1540 TRACE("(this=%p,%s,%p): stub!\n",
1541 iface
, debugstr_guid(rguid
), pdiph
);
1543 if (TRACE_ON(dinput
))
1544 _dump_DIPROPHEADER(pdiph
);
1546 if (!HIWORD(rguid
)) {
1547 switch ((DWORD
)rguid
) {
1548 case (DWORD
) DIPROP_BUFFERSIZE
: {
1549 LPDIPROPDWORD pd
= (LPDIPROPDWORD
)pdiph
;
1551 TRACE(" return buffersize = %d\n",This
->queue_len
);
1552 pd
->dwData
= This
->queue_len
;
1556 case (DWORD
) DIPROP_RANGE
: {
1557 LPDIPROPRANGE pr
= (LPDIPROPRANGE
) pdiph
;
1559 if ((pdiph
->dwHow
== DIPH_BYID
) &&
1560 ((pdiph
->dwObj
== (DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE
) | DIDFT_RELAXIS
)) ||
1561 (pdiph
->dwObj
== (DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE
) | DIDFT_RELAXIS
)))) {
1562 /* Querying the range of either the X or the Y axis. As I do
1563 not know the range, do as if the range where
1565 pr
->lMin
= DIPROPRANGE_NOMIN
;
1566 pr
->lMax
= DIPROPRANGE_NOMAX
;
1573 FIXME("Unknown type %ld (%s)\n",(DWORD
)rguid
,debugstr_guid(rguid
));
1584 /******************************************************************************
1585 * SetEventNotification : specifies event to be sent on state change
1587 static HRESULT WINAPI
SysMouseAImpl_SetEventNotification(LPDIRECTINPUTDEVICE2A iface
,
1589 ICOM_THIS(SysMouseAImpl
,iface
);
1591 TRACE("(this=%p,0x%08lx)\n",This
,(DWORD
)hnd
);
1598 /******************************************************************************
1599 * GetCapabilities : get the device capablitites
1601 static HRESULT WINAPI
SysMouseAImpl_GetCapabilities(
1602 LPDIRECTINPUTDEVICE2A iface
,
1603 LPDIDEVCAPS lpDIDevCaps
)
1605 ICOM_THIS(SysMouseAImpl
,iface
);
1607 TRACE("(this=%p,%p)\n",This
,lpDIDevCaps
);
1609 if (lpDIDevCaps
->dwSize
== sizeof(DIDEVCAPS
)) {
1610 lpDIDevCaps
->dwFlags
= DIDC_ATTACHED
;
1611 lpDIDevCaps
->dwDevType
= DIDEVTYPE_MOUSE
;
1612 lpDIDevCaps
->dwAxes
= 2;
1613 lpDIDevCaps
->dwButtons
= 3;
1614 lpDIDevCaps
->dwPOVs
= 0;
1615 lpDIDevCaps
->dwFFSamplePeriod
= 0;
1616 lpDIDevCaps
->dwFFMinTimeResolution
= 0;
1617 lpDIDevCaps
->dwFirmwareRevision
= 100;
1618 lpDIDevCaps
->dwHardwareRevision
= 100;
1619 lpDIDevCaps
->dwFFDriverVersion
= 0;
1622 FIXME("DirectX 3.0 not supported....\n");
1629 /******************************************************************************
1630 * EnumObjects : enumerate the different buttons and axis...
1632 static HRESULT WINAPI
SysMouseAImpl_EnumObjects(
1633 LPDIRECTINPUTDEVICE2A iface
,
1634 LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback
,
1638 ICOM_THIS(SysMouseAImpl
,iface
);
1639 DIDEVICEOBJECTINSTANCE ddoi
;
1641 TRACE("(this=%p,%p,%p,%08lx)\n", This
, lpCallback
, lpvRef
, dwFlags
);
1642 if (TRACE_ON(dinput
)) {
1643 DPRINTF(" - flags = ");
1644 _dump_EnumObjects_flags(dwFlags
);
1648 /* Only the fields till dwFFMaxForce are relevant */
1649 ddoi
.dwSize
= FIELD_OFFSET(DIDEVICEOBJECTINSTANCE
, dwFFMaxForce
);
1651 /* In a mouse, we have : two relative axis and three buttons */
1652 if ((dwFlags
== DIDFT_ALL
) ||
1653 (dwFlags
& DIDFT_AXIS
)) {
1655 ddoi
.guidType
= GUID_XAxis
;
1656 ddoi
.dwOfs
= This
->offset_array
[WINE_MOUSE_X_POSITION
];
1657 ddoi
.dwType
= DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE
) | DIDFT_RELAXIS
;
1658 strcpy(ddoi
.tszName
, "X-Axis");
1659 _dump_OBJECTINSTANCE(&ddoi
);
1660 if (lpCallback(&ddoi
, lpvRef
) != DIENUM_CONTINUE
) return DI_OK
;
1663 ddoi
.guidType
= GUID_YAxis
;
1664 ddoi
.dwOfs
= This
->offset_array
[WINE_MOUSE_Y_POSITION
];
1665 ddoi
.dwType
= DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE
) | DIDFT_RELAXIS
;
1666 strcpy(ddoi
.tszName
, "Y-Axis");
1667 _dump_OBJECTINSTANCE(&ddoi
);
1668 if (lpCallback(&ddoi
, lpvRef
) != DIENUM_CONTINUE
) return DI_OK
;
1671 if ((dwFlags
== DIDFT_ALL
) ||
1672 (dwFlags
& DIDFT_BUTTON
)) {
1673 ddoi
.guidType
= GUID_Button
;
1676 ddoi
.dwOfs
= This
->offset_array
[WINE_MOUSE_L_POSITION
];
1677 ddoi
.dwType
= DIDFT_MAKEINSTANCE(WINE_MOUSE_L_BUTTON_INSTANCE
) | DIDFT_PSHBUTTON
;
1678 strcpy(ddoi
.tszName
, "Left-Button");
1679 _dump_OBJECTINSTANCE(&ddoi
);
1680 if (lpCallback(&ddoi
, lpvRef
) != DIENUM_CONTINUE
) return DI_OK
;
1683 ddoi
.dwOfs
= This
->offset_array
[WINE_MOUSE_R_POSITION
];
1684 ddoi
.dwType
= DIDFT_MAKEINSTANCE(WINE_MOUSE_R_BUTTON_INSTANCE
) | DIDFT_PSHBUTTON
;
1685 strcpy(ddoi
.tszName
, "Right-Button");
1686 _dump_OBJECTINSTANCE(&ddoi
);
1687 if (lpCallback(&ddoi
, lpvRef
) != DIENUM_CONTINUE
) return DI_OK
;
1690 ddoi
.dwOfs
= This
->offset_array
[WINE_MOUSE_M_POSITION
];
1691 ddoi
.dwType
= DIDFT_MAKEINSTANCE(WINE_MOUSE_M_BUTTON_INSTANCE
) | DIDFT_PSHBUTTON
;
1692 strcpy(ddoi
.tszName
, "Middle-Button");
1693 _dump_OBJECTINSTANCE(&ddoi
);
1694 if (lpCallback(&ddoi
, lpvRef
) != DIENUM_CONTINUE
) return DI_OK
;
1702 #ifdef HAVE_LINUX_22_JOYSTICK_API
1703 /******************************************************************************
1706 static ULONG WINAPI
JoystickAImpl_Release(LPDIRECTINPUTDEVICE2A iface
)
1708 ICOM_THIS(JoystickAImpl
,iface
);
1714 /* Free the data queue */
1715 if (This
->data_queue
!= NULL
)
1716 HeapFree(GetProcessHeap(),0,This
->data_queue
);
1718 /* Free the DataFormat */
1719 HeapFree(GetProcessHeap(), 0, This
->df
);
1721 HeapFree(GetProcessHeap(),0,This
);
1725 /******************************************************************************
1726 * SetDataFormat : the application can choose the format of the data
1727 * the device driver sends back with GetDeviceState.
1729 static HRESULT WINAPI
JoystickAImpl_SetDataFormat(
1730 LPDIRECTINPUTDEVICE2A iface
,LPCDIDATAFORMAT df
1733 ICOM_THIS(JoystickAImpl
,iface
);
1736 TRACE("(this=%p,%p)\n",This
,df
);
1738 TRACE("(df.dwSize=%ld)\n",df
->dwSize
);
1739 TRACE("(df.dwObjsize=%ld)\n",df
->dwObjSize
);
1740 TRACE("(df.dwFlags=0x%08lx)\n",df
->dwFlags
);
1741 TRACE("(df.dwDataSize=%ld)\n",df
->dwDataSize
);
1742 TRACE("(df.dwNumObjs=%ld)\n",df
->dwNumObjs
);
1744 for (i
=0;i
<df
->dwNumObjs
;i
++) {
1745 TRACE("df.rgodf[%d].guid %s (%p)\n",i
,debugstr_guid(df
->rgodf
[i
].pguid
), df
->rgodf
[i
].pguid
);
1746 TRACE("df.rgodf[%d].dwOfs %ld\n",i
,df
->rgodf
[i
].dwOfs
);
1747 TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df
->rgodf
[i
].dwType
),DIDFT_GETINSTANCE(df
->rgodf
[i
].dwType
));
1748 TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i
,df
->rgodf
[i
].dwFlags
);
1751 /* Store the new data format */
1752 This
->df
= HeapAlloc(GetProcessHeap(),0,df
->dwSize
);
1753 memcpy(This
->df
, df
, df
->dwSize
);
1754 This
->df
->rgodf
= HeapAlloc(GetProcessHeap(),0,df
->dwNumObjs
*df
->dwObjSize
);
1755 memcpy(This
->df
->rgodf
,df
->rgodf
,df
->dwNumObjs
*df
->dwObjSize
);
1760 /******************************************************************************
1761 * Acquire : gets exclusive control of the joystick
1763 static HRESULT WINAPI
JoystickAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface
)
1765 ICOM_THIS(JoystickAImpl
,iface
);
1767 TRACE("(this=%p)\n",This
);
1768 if (This
->joyfd
!=-1)
1770 This
->joyfd
=open(JOYDEV
,O_RDONLY
);
1771 if (This
->joyfd
==-1)
1772 return DIERR_NOTFOUND
;
1776 /******************************************************************************
1777 * Unacquire : frees the joystick
1779 static HRESULT WINAPI
JoystickAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface
)
1781 ICOM_THIS(JoystickAImpl
,iface
);
1783 TRACE("(this=%p)\n",This
);
1784 if (This
->joyfd
!=-1) {
1791 #define map_axis(val) ((val+32768)*(This->lMax-This->lMin)/65536+This->lMin)
1793 static void joy_polldev(JoystickAImpl
*This
) {
1796 struct js_event jse
;
1798 if (This
->joyfd
==-1)
1801 memset(&tv
,0,sizeof(tv
));
1802 FD_ZERO(&readfds
);FD_SET(This
->joyfd
,&readfds
);
1803 if (1>select(This
->joyfd
+1,&readfds
,NULL
,NULL
,&tv
))
1805 /* we have one event, so we can read */
1806 if (sizeof(jse
)!=read(This
->joyfd
,&jse
,sizeof(jse
))) {
1809 TRACE("js_event: type 0x%x, number %d, value %d\n",jse
.type
,jse
.number
,jse
.value
);
1810 if (jse
.type
& JS_EVENT_BUTTON
) {
1811 GEN_EVENT(DIJOFS_BUTTON(jse
.number
),jse
.value
?0x80:0x00,jse
.time
,evsequence
++);
1812 This
->js
.rgbButtons
[jse
.number
] = jse
.value
?0x80:0x00;
1814 if (jse
.type
& JS_EVENT_AXIS
) {
1815 switch (jse
.number
) {
1817 GEN_EVENT(jse
.number
*4,jse
.value
,jse
.time
,evsequence
++);
1818 This
->js
.lX
= map_axis(jse
.value
);
1821 GEN_EVENT(jse
.number
*4,jse
.value
,jse
.time
,evsequence
++);
1822 This
->js
.lY
= map_axis(jse
.value
);
1825 GEN_EVENT(jse
.number
*4,jse
.value
,jse
.time
,evsequence
++);
1826 This
->js
.lZ
= map_axis(jse
.value
);
1829 FIXME("more then 3 axes (%d) not handled!\n",jse
.number
);
1836 /******************************************************************************
1837 * GetDeviceState : returns the "state" of the joystick.
1840 static HRESULT WINAPI
JoystickAImpl_GetDeviceState(
1841 LPDIRECTINPUTDEVICE2A iface
,DWORD len
,LPVOID ptr
1843 ICOM_THIS(JoystickAImpl
,iface
);
1846 TRACE("(this=%p,0x%08lx,%p)\n",This
,len
,ptr
);
1847 if (len
!= sizeof(DIJOYSTATE
)) {
1848 FIXME("len %ld is not sizeof(DIJOYSTATE), unsupported format.\n",len
);
1850 memcpy(ptr
,&(This
->js
),len
);
1851 This
->queue_pos
= 0;
1855 /******************************************************************************
1856 * GetDeviceState : gets buffered input data.
1858 static HRESULT WINAPI
JoystickAImpl_GetDeviceData(LPDIRECTINPUTDEVICE2A iface
,
1860 LPDIDEVICEOBJECTDATA dod
,
1864 ICOM_THIS(JoystickAImpl
,iface
);
1866 FIXME("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx),STUB!\n",This
,dodsize
,*entries
,flags
);
1869 if (flags
& DIGDD_PEEK
)
1870 FIXME("DIGDD_PEEK\n");
1878 /******************************************************************************
1879 * SetProperty : change input device properties
1881 static HRESULT WINAPI
JoystickAImpl_SetProperty(LPDIRECTINPUTDEVICE2A iface
,
1885 ICOM_THIS(JoystickAImpl
,iface
);
1887 FIXME("(this=%p,%s,%p)\n",This
,debugstr_guid(rguid
),ph
);
1888 FIXME("ph.dwSize = %ld, ph.dwHeaderSize =%ld, ph.dwObj = %ld, ph.dwHow= %ld\n",ph
->dwSize
, ph
->dwHeaderSize
,ph
->dwObj
,ph
->dwHow
);
1890 if (!HIWORD(rguid
)) {
1891 switch ((DWORD
)rguid
) {
1892 case (DWORD
) DIPROP_BUFFERSIZE
: {
1893 LPCDIPROPDWORD pd
= (LPCDIPROPDWORD
)ph
;
1895 FIXME("buffersize = %ld\n",pd
->dwData
);
1898 case (DWORD
)DIPROP_RANGE
: {
1899 LPCDIPROPRANGE pr
= (LPCDIPROPRANGE
)ph
;
1901 FIXME("proprange(%ld,%ld)\n",pr
->lMin
,pr
->lMax
);
1902 This
->lMin
= pr
->lMin
;
1903 This
->lMax
= pr
->lMax
;
1906 case (DWORD
)DIPROP_DEADZONE
: {
1907 LPCDIPROPDWORD pd
= (LPCDIPROPDWORD
)ph
;
1909 FIXME("deadzone(%ld)\n",pd
->dwData
);
1910 This
->deadzone
= pd
->dwData
;
1914 FIXME("Unknown type %ld (%s)\n",(DWORD
)rguid
,debugstr_guid(rguid
));
1921 /******************************************************************************
1922 * SetEventNotification : specifies event to be sent on state change
1924 static HRESULT WINAPI
JoystickAImpl_SetEventNotification(
1925 LPDIRECTINPUTDEVICE2A iface
, HANDLE hnd
1927 ICOM_THIS(JoystickAImpl
,iface
);
1929 TRACE("(this=%p,0x%08lx)\n",This
,(DWORD
)hnd
);
1934 static HRESULT WINAPI
JoystickAImpl_GetCapabilities(
1935 LPDIRECTINPUTDEVICE2A iface
,
1936 LPDIDEVCAPS lpDIDevCaps
)
1938 ICOM_THIS(JoystickAImpl
,iface
);
1940 int xfd
= This
->joyfd
;
1942 TRACE("%p->(%p)\n",iface
,lpDIDevCaps
);
1944 xfd
= open(JOYDEV
,O_RDONLY
);
1945 lpDIDevCaps
->dwFlags
= DIDC_ATTACHED
;
1946 lpDIDevCaps
->dwDevType
= DIDEVTYPE_JOYSTICK
;
1948 if (-1==ioctl(xfd
,JSIOCGAXES
,&axes
))
1950 lpDIDevCaps
->dwAxes
= axes
;
1952 #ifdef JSIOCGBUTTONS
1953 if (-1==ioctl(xfd
,JSIOCGAXES
,&buttons
))
1955 lpDIDevCaps
->dwButtons
= buttons
;
1957 if (xfd
!=This
->joyfd
)
1961 static HRESULT WINAPI
JoystickAImpl_Poll(LPDIRECTINPUTDEVICE2A iface
) {
1962 ICOM_THIS(JoystickAImpl
,iface
);
1963 TRACE("(),stub!\n");
1969 /******************************************************************************
1970 * EnumObjects : enumerate the different buttons and axis...
1972 static HRESULT WINAPI
JoystickAImpl_EnumObjects(
1973 LPDIRECTINPUTDEVICE2A iface
,
1974 LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback
,
1978 ICOM_THIS(JoystickAImpl
,iface
);
1979 DIDEVICEOBJECTINSTANCE ddoi
;
1980 int xfd
= This
->joyfd
;
1982 TRACE("(this=%p,%p,%p,%08lx)\n", This
, lpCallback
, lpvRef
, dwFlags
);
1983 if (TRACE_ON(dinput
)) {
1984 DPRINTF(" - flags = ");
1985 _dump_EnumObjects_flags(dwFlags
);
1989 /* Only the fields till dwFFMaxForce are relevant */
1990 ddoi
.dwSize
= FIELD_OFFSET(DIDEVICEOBJECTINSTANCE
, dwFFMaxForce
);
1992 /* For the joystick, do as is done in the GetCapabilities function */
1993 if ((dwFlags
== DIDFT_ALL
) ||
1994 (dwFlags
& DIDFT_AXIS
)) {
1998 if (-1==ioctl(xfd
,JSIOCGAXES
,&axes
))
2002 for (i
= 0; i
< axes
; i
++) {
2005 ddoi
.guidType
= GUID_XAxis
;
2006 ddoi
.dwOfs
= DIJOFS_X
;
2009 ddoi
.guidType
= GUID_YAxis
;
2010 ddoi
.dwOfs
= DIJOFS_Y
;
2013 ddoi
.guidType
= GUID_ZAxis
;
2014 ddoi
.dwOfs
= DIJOFS_Z
;
2017 ddoi
.guidType
= GUID_Unknown
;
2018 ddoi
.dwOfs
= DIJOFS_Z
+ (i
- 2) * sizeof(LONG
);
2020 ddoi
.dwType
= DIDFT_MAKEINSTANCE((0x0001 << i
) << WINE_JOYSTICK_AXIS_BASE
) | DIDFT_ABSAXIS
;
2021 sprintf(ddoi
.tszName
, "%d-Axis", i
);
2022 _dump_OBJECTINSTANCE(&ddoi
);
2023 if (lpCallback(&ddoi
, lpvRef
) != DIENUM_CONTINUE
) return DI_OK
;
2027 if ((dwFlags
== DIDFT_ALL
) ||
2028 (dwFlags
& DIDFT_BUTTON
)) {
2031 #ifdef JSIOCGBUTTONS
2032 if (-1==ioctl(xfd
,JSIOCGAXES
,&buttons
))
2036 /* The DInput SDK says that GUID_Button is only for mouse buttons but well... */
2037 ddoi
.guidType
= GUID_Button
;
2039 for (i
= 0; i
< buttons
; i
++) {
2040 ddoi
.dwOfs
= DIJOFS_BUTTON(i
);
2041 ddoi
.dwType
= DIDFT_MAKEINSTANCE((0x0001 << i
) << WINE_JOYSTICK_BUTTON_BASE
) | DIDFT_PSHBUTTON
;
2042 sprintf(ddoi
.tszName
, "%d-Button", i
);
2043 _dump_OBJECTINSTANCE(&ddoi
);
2044 if (lpCallback(&ddoi
, lpvRef
) != DIENUM_CONTINUE
) return DI_OK
;
2048 if (xfd
!=This
->joyfd
)
2054 /******************************************************************************
2055 * GetProperty : get input device properties
2057 static HRESULT WINAPI
JoystickAImpl_GetProperty(LPDIRECTINPUTDEVICE2A iface
,
2059 LPDIPROPHEADER pdiph
)
2061 ICOM_THIS(JoystickAImpl
,iface
);
2063 TRACE("(this=%p,%s,%p): stub!\n",
2064 iface
, debugstr_guid(rguid
), pdiph
);
2066 if (TRACE_ON(dinput
))
2067 _dump_DIPROPHEADER(pdiph
);
2069 if (!HIWORD(rguid
)) {
2070 switch ((DWORD
)rguid
) {
2071 case (DWORD
) DIPROP_BUFFERSIZE
: {
2072 LPDIPROPDWORD pd
= (LPDIPROPDWORD
)pdiph
;
2074 TRACE(" return buffersize = %d\n",This
->queue_len
);
2075 pd
->dwData
= This
->queue_len
;
2079 case (DWORD
) DIPROP_RANGE
: {
2080 LPDIPROPRANGE pr
= (LPDIPROPRANGE
) pdiph
;
2082 if ((pdiph
->dwHow
== DIPH_BYID
) &&
2083 (pdiph
->dwObj
& DIDFT_ABSAXIS
)) {
2084 /* The app is querying the current range of the axis : return the lMin and lMax values */
2085 pr
->lMin
= This
->lMin
;
2086 pr
->lMax
= This
->lMax
;
2093 FIXME("Unknown type %ld (%s)\n",(DWORD
)rguid
,debugstr_guid(rguid
));
2104 /****************************************************************************/
2105 /****************************************************************************/
2107 static ICOM_VTABLE(IDirectInputDevice2A
) SysKeyboardAvt
=
2109 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2110 IDirectInputDevice2AImpl_QueryInterface
,
2111 IDirectInputDevice2AImpl_AddRef
,
2112 IDirectInputDevice2AImpl_Release
,
2113 SysKeyboardAImpl_GetCapabilities
,
2114 IDirectInputDevice2AImpl_EnumObjects
,
2115 IDirectInputDevice2AImpl_GetProperty
,
2116 SysKeyboardAImpl_SetProperty
,
2117 SysKeyboardAImpl_Acquire
,
2118 SysKeyboardAImpl_Unacquire
,
2119 SysKeyboardAImpl_GetDeviceState
,
2120 SysKeyboardAImpl_GetDeviceData
,
2121 IDirectInputDevice2AImpl_SetDataFormat
,
2122 IDirectInputDevice2AImpl_SetEventNotification
,
2123 IDirectInputDevice2AImpl_SetCooperativeLevel
,
2124 IDirectInputDevice2AImpl_GetObjectInfo
,
2125 IDirectInputDevice2AImpl_GetDeviceInfo
,
2126 IDirectInputDevice2AImpl_RunControlPanel
,
2127 IDirectInputDevice2AImpl_Initialize
,
2128 IDirectInputDevice2AImpl_CreateEffect
,
2129 IDirectInputDevice2AImpl_EnumEffects
,
2130 IDirectInputDevice2AImpl_GetEffectInfo
,
2131 IDirectInputDevice2AImpl_GetForceFeedbackState
,
2132 IDirectInputDevice2AImpl_SendForceFeedbackCommand
,
2133 IDirectInputDevice2AImpl_EnumCreatedEffectObjects
,
2134 IDirectInputDevice2AImpl_Escape
,
2135 IDirectInputDevice2AImpl_Poll
,
2136 IDirectInputDevice2AImpl_SendDeviceData
,
2139 static ICOM_VTABLE(IDirectInputDevice2A
) SysMouseAvt
=
2141 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2142 IDirectInputDevice2AImpl_QueryInterface
,
2143 IDirectInputDevice2AImpl_AddRef
,
2144 SysMouseAImpl_Release
,
2145 SysMouseAImpl_GetCapabilities
,
2146 SysMouseAImpl_EnumObjects
,
2147 SysMouseAImpl_GetProperty
,
2148 SysMouseAImpl_SetProperty
,
2149 SysMouseAImpl_Acquire
,
2150 SysMouseAImpl_Unacquire
,
2151 SysMouseAImpl_GetDeviceState
,
2152 SysMouseAImpl_GetDeviceData
,
2153 SysMouseAImpl_SetDataFormat
,
2154 SysMouseAImpl_SetEventNotification
,
2155 SysMouseAImpl_SetCooperativeLevel
,
2156 IDirectInputDevice2AImpl_GetObjectInfo
,
2157 IDirectInputDevice2AImpl_GetDeviceInfo
,
2158 IDirectInputDevice2AImpl_RunControlPanel
,
2159 IDirectInputDevice2AImpl_Initialize
,
2160 IDirectInputDevice2AImpl_CreateEffect
,
2161 IDirectInputDevice2AImpl_EnumEffects
,
2162 IDirectInputDevice2AImpl_GetEffectInfo
,
2163 IDirectInputDevice2AImpl_GetForceFeedbackState
,
2164 IDirectInputDevice2AImpl_SendForceFeedbackCommand
,
2165 IDirectInputDevice2AImpl_EnumCreatedEffectObjects
,
2166 IDirectInputDevice2AImpl_Escape
,
2167 IDirectInputDevice2AImpl_Poll
,
2168 IDirectInputDevice2AImpl_SendDeviceData
,
2171 #ifdef HAVE_LINUX_22_JOYSTICK_API
2172 static ICOM_VTABLE(IDirectInputDevice2A
) JoystickAvt
=
2174 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2175 IDirectInputDevice2AImpl_QueryInterface
,
2176 IDirectInputDevice2AImpl_AddRef
,
2177 JoystickAImpl_Release
,
2178 JoystickAImpl_GetCapabilities
,
2179 JoystickAImpl_EnumObjects
,
2180 JoystickAImpl_GetProperty
,
2181 JoystickAImpl_SetProperty
,
2182 JoystickAImpl_Acquire
,
2183 JoystickAImpl_Unacquire
,
2184 JoystickAImpl_GetDeviceState
,
2185 JoystickAImpl_GetDeviceData
,
2186 JoystickAImpl_SetDataFormat
,
2187 JoystickAImpl_SetEventNotification
,
2188 IDirectInputDevice2AImpl_SetCooperativeLevel
,
2189 IDirectInputDevice2AImpl_GetObjectInfo
,
2190 IDirectInputDevice2AImpl_GetDeviceInfo
,
2191 IDirectInputDevice2AImpl_RunControlPanel
,
2192 IDirectInputDevice2AImpl_Initialize
,
2193 IDirectInputDevice2AImpl_CreateEffect
,
2194 IDirectInputDevice2AImpl_EnumEffects
,
2195 IDirectInputDevice2AImpl_GetEffectInfo
,
2196 IDirectInputDevice2AImpl_GetForceFeedbackState
,
2197 IDirectInputDevice2AImpl_SendForceFeedbackCommand
,
2198 IDirectInputDevice2AImpl_EnumCreatedEffectObjects
,
2199 IDirectInputDevice2AImpl_Escape
,
2201 IDirectInputDevice2AImpl_SendDeviceData
,