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
;
178 WARP_NEEDED
, /* Warping is needed */
179 WARP_STARTED
, /* Warping has been done, waiting for the warp event */
180 WARP_DONE
/* Warping has been done */
185 /* IDirectInputDevice2AImpl */
186 ICOM_VFIELD(IDirectInputDevice2A
);
190 /* The current data format and the conversion between internal
191 and external data formats */
198 /* Previous position for relative moves */
200 LPMOUSE_EVENT_PROC prev_handler
;
202 DWORD win_centerX
, win_centerY
;
203 LPDIDEVICEOBJECTDATA data_queue
;
204 int queue_pos
, queue_len
;
205 WARP_STATUS need_warp
;
208 CRITICAL_SECTION crit
;
210 /* This is for mouse reporting. */
211 Wine_InternalMouseData m_state
;
214 static int evsequence
=0;
217 /* UIDs for Wine "drivers".
218 When enumerating each device supporting DInput, they have two UIDs :
221 #ifdef HAVE_LINUX_22_JOYSTICK_API
222 static GUID DInput_Wine_Joystick_GUID
= { /* 9e573ed9-7734-11d2-8d4a-23903fb6bdf7 */
226 {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
229 static GUID DInput_Wine_Mouse_GUID
= { /* 9e573ed8-7734-11d2-8d4a-23903fb6bdf7 */
233 {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
235 static GUID DInput_Wine_Keyboard_GUID
= { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */
239 {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41}
242 /* FIXME: This is ugly and not thread safe :/ */
243 static IDirectInputDevice2A
* current_lock
= NULL
;
245 /******************************************************************************
246 * Various debugging tools
248 static void _dump_cooperativelevel(DWORD dwFlags
) {
254 #define FE(x) { x, #x},
258 FE(DISCL_NONEXCLUSIVE
)
261 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
262 if (flags
[i
].mask
& dwFlags
)
263 DPRINTF("%s ",flags
[i
].name
);
267 static void _dump_EnumObjects_flags(DWORD dwFlags
) {
273 #define FE(x) { x, #x},
280 FE(DIDFT_FFEFFECTTRIGGER
)
281 FE(DIDFT_NOCOLLECTION
)
290 if (dwFlags
== DIDFT_ALL
) {
291 DPRINTF("DIDFT_ALL");
294 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
295 if (flags
[i
].mask
& dwFlags
)
296 DPRINTF("%s ",flags
[i
].name
);
297 if (dwFlags
& DIDFT_INSTANCEMASK
)
298 DPRINTF("Instance(%04lx) ", dwFlags
>> 8);
301 static void _dump_DIPROPHEADER(DIPROPHEADER
*diph
) {
302 DPRINTF(" - dwObj = 0x%08lx\n", diph
->dwObj
);
303 DPRINTF(" - dwHow = %s\n",
304 ((diph
->dwHow
== DIPH_DEVICE
) ? "DIPH_DEVICE" :
305 ((diph
->dwHow
== DIPH_BYOFFSET
) ? "DIPH_BYOFFSET" :
306 ((diph
->dwHow
== DIPH_BYID
)) ? "DIPH_BYID" : "unknown")));
309 static void _dump_OBJECTINSTANCEA(DIDEVICEOBJECTINSTANCEA
*ddoi
) {
310 if (TRACE_ON(dinput
)) {
311 DPRINTF(" - enumerating : 0x%08lx - %2ld - 0x%08lx - %s\n",
312 ddoi
->guidType
.Data1
, ddoi
->dwOfs
, ddoi
->dwType
, ddoi
->tszName
);
316 struct IDirectInputAImpl
318 ICOM_VFIELD(IDirectInputA
);
322 /* Conversion between internal data buffer and external data buffer */
323 static void fill_DataFormat(void *out
, void *in
, DataFormat
*df
) {
325 char *in_c
= (char *) in
;
326 char *out_c
= (char *) out
;
328 if (df
->dt
== NULL
) {
329 /* This means that the app uses Wine's internal data format */
330 memcpy(out
, in
, df
->internal_format_size
);
332 for (i
= 0; i
< df
->size
; i
++) {
333 if (df
->dt
[i
].offset_in
>= 0) {
334 switch (df
->dt
[i
].size
) {
336 TRACE("Copying (c) to %d from %d (value %d)\n",
337 df
->dt
[i
].offset_out
, df
->dt
[i
].offset_in
, *((char *) (in_c
+ df
->dt
[i
].offset_in
)));
338 *((char *) (out_c
+ df
->dt
[i
].offset_out
)) = *((char *) (in_c
+ df
->dt
[i
].offset_in
));
342 TRACE("Copying (s) to %d from %d (value %d)\n",
343 df
->dt
[i
].offset_out
, df
->dt
[i
].offset_in
, *((short *) (in_c
+ df
->dt
[i
].offset_in
)));
344 *((short *) (out_c
+ df
->dt
[i
].offset_out
)) = *((short *) (in_c
+ df
->dt
[i
].offset_in
));
348 TRACE("Copying (i) to %d from %d (value %d)\n",
349 df
->dt
[i
].offset_out
, df
->dt
[i
].offset_in
, *((int *) (in_c
+ df
->dt
[i
].offset_in
)));
350 *((int *) (out_c
+ df
->dt
[i
].offset_out
)) = *((int *) (in_c
+ df
->dt
[i
].offset_in
));
354 memcpy((out_c
+ df
->dt
[i
].offset_out
), (in_c
+ df
->dt
[i
].offset_in
), df
->dt
[i
].size
);
357 switch (df
->dt
[i
].size
) {
359 TRACE("Copying (c) to %d default value %d\n",
360 df
->dt
[i
].offset_out
, df
->dt
[i
].value
);
361 *((char *) (out_c
+ df
->dt
[i
].offset_out
)) = (char) df
->dt
[i
].value
;
365 TRACE("Copying (s) to %d default value %d\n",
366 df
->dt
[i
].offset_out
, df
->dt
[i
].value
);
367 *((short *) (out_c
+ df
->dt
[i
].offset_out
)) = (short) df
->dt
[i
].value
;
371 TRACE("Copying (i) to %d default value %d\n",
372 df
->dt
[i
].offset_out
, df
->dt
[i
].value
);
373 *((int *) (out_c
+ df
->dt
[i
].offset_out
)) = (int) df
->dt
[i
].value
;
377 memset((out_c
+ df
->dt
[i
].offset_out
), df
->dt
[i
].size
, 0);
384 static DataFormat
*create_DataFormat(DIDATAFORMAT
*wine_format
, DIDATAFORMAT
*asked_format
, int *offset
) {
392 ret
= (DataFormat
*) HeapAlloc(GetProcessHeap(), 0, sizeof(DataFormat
));
394 done
= (int *) HeapAlloc(GetProcessHeap(), 0, sizeof(int) * asked_format
->dwNumObjs
);
395 memset(done
, 0, sizeof(int) * asked_format
->dwNumObjs
);
397 dt
= (DataTransform
*) HeapAlloc(GetProcessHeap(), 0, asked_format
->dwNumObjs
* sizeof(DataTransform
));
399 TRACE("Creating DataTransorm : \n");
401 for (i
= 0; i
< wine_format
->dwNumObjs
; i
++) {
404 for (j
= 0; j
< asked_format
->dwNumObjs
; j
++) {
408 if (((asked_format
->rgodf
[j
].pguid
== NULL
) || (IsEqualGUID(wine_format
->rgodf
[i
].pguid
, asked_format
->rgodf
[j
].pguid
)))
410 (wine_format
->rgodf
[i
].dwType
& asked_format
->rgodf
[j
].dwType
)) {
414 TRACE("Matching : \n");
415 TRACE(" - Asked (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n",
416 j
, debugstr_guid(asked_format
->rgodf
[j
].pguid
),
417 asked_format
->rgodf
[j
].dwOfs
,
418 DIDFT_GETTYPE(asked_format
->rgodf
[j
].dwType
), DIDFT_GETINSTANCE(asked_format
->rgodf
[j
].dwType
));
420 TRACE(" - Wine (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n",
421 j
, debugstr_guid(wine_format
->rgodf
[i
].pguid
),
422 wine_format
->rgodf
[i
].dwOfs
,
423 DIDFT_GETTYPE(wine_format
->rgodf
[i
].dwType
), DIDFT_GETINSTANCE(wine_format
->rgodf
[i
].dwType
));
425 if (wine_format
->rgodf
[i
].dwType
& DIDFT_BUTTON
)
426 dt
[index
].size
= sizeof(BYTE
);
428 dt
[index
].size
= sizeof(DWORD
);
429 dt
[index
].offset_in
= wine_format
->rgodf
[i
].dwOfs
;
430 dt
[index
].offset_out
= asked_format
->rgodf
[j
].dwOfs
;
434 if (wine_format
->rgodf
[i
].dwOfs
!= asked_format
->rgodf
[j
].dwOfs
)
437 offset
[i
] = asked_format
->rgodf
[j
].dwOfs
;
442 if (j
== asked_format
->dwNumObjs
)
446 TRACE("Setting to default value :\n");
447 for (j
= 0; j
< asked_format
->dwNumObjs
; j
++) {
449 TRACE(" - Asked (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n",
450 j
, debugstr_guid(asked_format
->rgodf
[j
].pguid
),
451 asked_format
->rgodf
[j
].dwOfs
,
452 DIDFT_GETTYPE(asked_format
->rgodf
[j
].dwType
), DIDFT_GETINSTANCE(asked_format
->rgodf
[j
].dwType
));
455 if (asked_format
->rgodf
[j
].dwType
& DIDFT_BUTTON
)
456 dt
[index
].size
= sizeof(BYTE
);
458 dt
[index
].size
= sizeof(DWORD
);
459 dt
[index
].offset_in
= -1;
460 dt
[index
].offset_out
= asked_format
->rgodf
[j
].dwOfs
;
468 ret
->internal_format_size
= wine_format
->dwDataSize
;
472 HeapFree(GetProcessHeap(), 0, dt
);
477 HeapFree(GetProcessHeap(), 0, done
);
482 /******************************************************************************
483 * DirectInputCreate32A
485 HRESULT WINAPI
DirectInputCreateA(HINSTANCE hinst
, DWORD dwVersion
, LPDIRECTINPUTA
*ppDI
, LPUNKNOWN punkOuter
)
487 IDirectInputAImpl
* This
;
488 TRACE("(0x%08lx,%04lx,%p,%p)\n",
489 (DWORD
)hinst
,dwVersion
,ppDI
,punkOuter
491 This
= (IDirectInputAImpl
*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl
));
493 ICOM_VTBL(This
) = &ddiavt
;
494 *ppDI
=(IDirectInputA
*)This
;
497 /******************************************************************************
498 * IDirectInputA_EnumDevices
500 static HRESULT WINAPI
IDirectInputAImpl_EnumDevices(
501 LPDIRECTINPUTA iface
, DWORD dwDevType
, LPDIENUMDEVICESCALLBACKA lpCallback
,
502 LPVOID pvRef
, DWORD dwFlags
505 ICOM_THIS(IDirectInputAImpl
,iface
);
506 DIDEVICEINSTANCEA devInstance
;
509 TRACE("(this=%p,0x%04lx,%p,%p,%04lx)\n", This
, dwDevType
, lpCallback
, pvRef
, dwFlags
);
511 devInstance
.dwSize
= sizeof(DIDEVICEINSTANCEA
);
512 if ((dwDevType
== 0) || (dwDevType
== DIDEVTYPE_KEYBOARD
)) {
513 /* Return keyboard */
514 devInstance
.guidInstance
= GUID_SysKeyboard
;/* DInput's GUID */
515 devInstance
.guidProduct
= DInput_Wine_Keyboard_GUID
; /* Vendor's GUID */
516 devInstance
.dwDevType
= DIDEVTYPE_KEYBOARD
| (DIDEVTYPEKEYBOARD_UNKNOWN
<< 8);
517 strcpy(devInstance
.tszInstanceName
, "Keyboard");
518 strcpy(devInstance
.tszProductName
, "Wine Keyboard");
520 ret
= lpCallback(&devInstance
, pvRef
);
521 TRACE("Keyboard registered\n");
522 if (ret
== DIENUM_STOP
)
526 if ((dwDevType
== 0) || (dwDevType
== DIDEVTYPE_MOUSE
)) {
528 devInstance
.guidInstance
= GUID_SysMouse
;/* DInput's GUID */
529 devInstance
.guidProduct
= DInput_Wine_Mouse_GUID
; /* Vendor's GUID */
530 devInstance
.dwDevType
= DIDEVTYPE_MOUSE
| (DIDEVTYPEMOUSE_UNKNOWN
<< 8);
531 strcpy(devInstance
.tszInstanceName
, "Mouse");
532 strcpy(devInstance
.tszProductName
, "Wine Mouse");
534 ret
= lpCallback(&devInstance
, pvRef
);
535 TRACE("Mouse registered\n");
536 if (ret
== DIENUM_STOP
)
539 if ((dwDevType
== 0) || (dwDevType
== DIDEVTYPE_JOYSTICK
)) {
540 /* check whether we have a joystick */
541 #ifdef HAVE_LINUX_22_JOYSTICK_API
542 if ( (access(JOYDEV
,O_RDONLY
)!=-1) ||
543 (errno
!=ENODEV
&& errno
!=ENOENT
)
545 /* Return joystick */
546 devInstance
.guidInstance
= GUID_Joystick
;
547 devInstance
.guidProduct
= DInput_Wine_Joystick_GUID
;
548 /* we only support traditional joysticks for now */
549 devInstance
.dwDevType
= DIDEVTYPE_JOYSTICK
| DIDEVTYPEJOYSTICK_TRADITIONAL
;
550 strcpy(devInstance
.tszInstanceName
, "Joystick");
551 /* ioctl JSIOCGNAME(len) */
552 strcpy(devInstance
.tszProductName
, "Wine Joystick");
554 ret
= lpCallback(&devInstance
,pvRef
);
555 TRACE("Joystick registered\n");
556 if (ret
== DIENUM_STOP
)
564 static ULONG WINAPI
IDirectInputAImpl_AddRef(LPDIRECTINPUTA iface
)
566 ICOM_THIS(IDirectInputAImpl
,iface
);
567 return ++(This
->ref
);
570 static ULONG WINAPI
IDirectInputAImpl_Release(LPDIRECTINPUTA iface
)
572 ICOM_THIS(IDirectInputAImpl
,iface
);
573 if (!(--This
->ref
)) {
574 HeapFree(GetProcessHeap(),0,This
);
580 static HRESULT WINAPI
IDirectInputAImpl_CreateDevice(
581 LPDIRECTINPUTA iface
,REFGUID rguid
,LPDIRECTINPUTDEVICEA
* pdev
,
584 ICOM_THIS(IDirectInputAImpl
,iface
);
586 TRACE("(this=%p,%s,%p,%p)\n",This
,debugstr_guid(rguid
),pdev
,punk
);
587 if ((IsEqualGUID(&GUID_SysKeyboard
,rguid
)) || /* Generic Keyboard */
588 (IsEqualGUID(&DInput_Wine_Keyboard_GUID
,rguid
))) { /* Wine Keyboard */
589 SysKeyboardAImpl
* newDevice
;
590 newDevice
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(SysKeyboardAImpl
));
592 ICOM_VTBL(newDevice
) = &SysKeyboardAvt
;
593 memcpy(&(newDevice
->guid
),rguid
,sizeof(*rguid
));
594 memset(newDevice
->keystate
,0,256);
595 *pdev
=(IDirectInputDeviceA
*)newDevice
;
597 TRACE("Creating a Keyboard device (%p)\n", newDevice
);
600 if ((IsEqualGUID(&GUID_SysMouse
,rguid
)) || /* Generic Mouse */
601 (IsEqualGUID(&DInput_Wine_Mouse_GUID
,rguid
))) { /* Wine Mouse */
602 SysMouseAImpl
* newDevice
;
603 int offset_array
[5] = {
604 FIELD_OFFSET(Wine_InternalMouseData
, lX
),
605 FIELD_OFFSET(Wine_InternalMouseData
, lY
),
606 FIELD_OFFSET(Wine_InternalMouseData
, rgbButtons
) + 0,
607 FIELD_OFFSET(Wine_InternalMouseData
, rgbButtons
) + 1,
608 FIELD_OFFSET(Wine_InternalMouseData
, rgbButtons
) + 2
611 newDevice
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(SysMouseAImpl
));
613 ICOM_VTBL(newDevice
) = &SysMouseAvt
;
614 InitializeCriticalSection(&(newDevice
->crit
));
615 MakeCriticalSectionGlobal(&(newDevice
->crit
));
616 memcpy(&(newDevice
->guid
),rguid
,sizeof(*rguid
));
617 *pdev
=(IDirectInputDeviceA
*)newDevice
;
619 /* Per default, Wine uses its internal data format */
620 newDevice
->df
= &Wine_InternalMouseFormat
;
621 memcpy(newDevice
->offset_array
, offset_array
, 5 * sizeof(int));
622 newDevice
->wine_df
= (DataFormat
*) HeapAlloc(GetProcessHeap(), 0, sizeof(DataFormat
));
623 newDevice
->wine_df
->size
= 0;
624 newDevice
->wine_df
->internal_format_size
= Wine_InternalMouseFormat
.dwDataSize
;
625 newDevice
->wine_df
->dt
= NULL
;
627 TRACE("Creating a Mouse device (%p)\n", newDevice
);
630 #ifdef HAVE_LINUX_22_JOYSTICK_API
631 if ((IsEqualGUID(&GUID_Joystick
,rguid
)) ||
632 (IsEqualGUID(&DInput_Wine_Joystick_GUID
,rguid
))) {
633 JoystickAImpl
* newDevice
;
634 newDevice
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(JoystickAImpl
));
636 ICOM_VTBL(newDevice
) = &JoystickAvt
;
637 newDevice
->joyfd
= -1;
638 newDevice
->lMin
= -32768;
639 newDevice
->lMax
= +32767;
640 memcpy(&(newDevice
->guid
),rguid
,sizeof(*rguid
));
641 *pdev
=(IDirectInputDeviceA
*)newDevice
;
643 TRACE("Creating a Joystick device (%p)\n", newDevice
);
650 static HRESULT WINAPI
IDirectInputAImpl_QueryInterface(
651 LPDIRECTINPUTA iface
,REFIID riid
,LPVOID
*ppobj
653 ICOM_THIS(IDirectInputAImpl
,iface
);
655 TRACE("(this=%p,%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
656 if (IsEqualGUID(&IID_IUnknown
,riid
)) {
657 IDirectInputA_AddRef(iface
);
661 if (IsEqualGUID(&IID_IDirectInputA
,riid
)) {
662 IDirectInputA_AddRef(iface
);
666 TRACE("Unsupported interface !\n");
670 static HRESULT WINAPI
IDirectInputAImpl_Initialize(
671 LPDIRECTINPUTA iface
,HINSTANCE hinst
,DWORD x
673 return DIERR_ALREADYINITIALIZED
;
676 static HRESULT WINAPI
IDirectInputAImpl_GetDeviceStatus(LPDIRECTINPUTA iface
,
678 ICOM_THIS(IDirectInputAImpl
,iface
);
680 FIXME("(%p)->(%s): stub\n",This
,debugstr_guid(rguid
));
685 static HRESULT WINAPI
IDirectInputAImpl_RunControlPanel(LPDIRECTINPUTA iface
,
688 ICOM_THIS(IDirectInputAImpl
,iface
);
689 FIXME("(%p)->(%08lx,%08lx): stub\n",This
, (DWORD
) hwndOwner
, dwFlags
);
694 static ICOM_VTABLE(IDirectInputA
) ddiavt
=
696 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
697 IDirectInputAImpl_QueryInterface
,
698 IDirectInputAImpl_AddRef
,
699 IDirectInputAImpl_Release
,
700 IDirectInputAImpl_CreateDevice
,
701 IDirectInputAImpl_EnumDevices
,
702 IDirectInputAImpl_GetDeviceStatus
,
703 IDirectInputAImpl_RunControlPanel
,
704 IDirectInputAImpl_Initialize
707 /******************************************************************************
708 * IDirectInputDeviceA
711 static HRESULT WINAPI
IDirectInputDevice2AImpl_SetDataFormat(
712 LPDIRECTINPUTDEVICE2A iface
,LPCDIDATAFORMAT df
716 TRACE(dinput,"(this=%p,%p)\n",This,df);
718 TRACE(dinput,"df.dwSize=%ld\n",df->dwSize);
719 TRACE(dinput,"(df.dwObjsize=%ld)\n",df->dwObjSize);
720 TRACE(dinput,"(df.dwFlags=0x%08lx)\n",df->dwFlags);
721 TRACE(dinput,"(df.dwDataSize=%ld)\n",df->dwDataSize);
722 TRACE(dinput,"(df.dwNumObjs=%ld)\n",df->dwNumObjs);
724 for (i=0;i<df->dwNumObjs;i++) {
725 TRACE(dinput,"df.rgodf[%d].guid %s\n",i,debugstr_guid(df->rgodf[i].pguid));
726 TRACE(dinput,"df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
727 TRACE(dinput,"dwType 0x%02lx,dwInstance %ld\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
728 TRACE(dinput,"df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
734 static HRESULT WINAPI
IDirectInputDevice2AImpl_SetCooperativeLevel(
735 LPDIRECTINPUTDEVICE2A iface
,HWND hwnd
,DWORD dwflags
737 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
738 TRACE("(this=%p,0x%08lx,0x%08lx)\n",This
,(DWORD
)hwnd
,dwflags
);
739 if (TRACE_ON(dinput
))
740 _dump_cooperativelevel(dwflags
);
744 static HRESULT WINAPI
IDirectInputDevice2AImpl_SetEventNotification(
745 LPDIRECTINPUTDEVICE2A iface
,HANDLE hnd
747 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
748 FIXME("(this=%p,0x%08lx): stub\n",This
,(DWORD
)hnd
);
752 static ULONG WINAPI
IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE2A iface
)
754 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
758 HeapFree(GetProcessHeap(),0,This
);
762 static HRESULT WINAPI
SysKeyboardAImpl_SetProperty(
763 LPDIRECTINPUTDEVICE2A iface
,REFGUID rguid
,LPCDIPROPHEADER ph
766 ICOM_THIS(SysKeyboardAImpl
,iface
);
768 TRACE("(this=%p,%s,%p)\n",This
,debugstr_guid(rguid
),ph
);
769 TRACE("(size=%ld,headersize=%ld,obj=%ld,how=%ld\n",
770 ph
->dwSize
,ph
->dwHeaderSize
,ph
->dwObj
,ph
->dwHow
);
771 if (!HIWORD(rguid
)) {
772 switch ((DWORD
)rguid
) {
773 case (DWORD
) DIPROP_BUFFERSIZE
: {
774 LPCDIPROPDWORD pd
= (LPCDIPROPDWORD
)ph
;
776 TRACE("(buffersize=%ld)\n",pd
->dwData
);
780 WARN("Unknown type %ld\n",(DWORD
)rguid
);
787 static HRESULT WINAPI
SysKeyboardAImpl_GetDeviceState(
788 LPDIRECTINPUTDEVICE2A iface
,DWORD len
,LPVOID ptr
791 return USER_Driver
->pGetDIState(len
, ptr
)?DI_OK
:E_FAIL
;
794 static HRESULT WINAPI
SysKeyboardAImpl_GetDeviceData(
795 LPDIRECTINPUTDEVICE2A iface
,DWORD dodsize
,LPDIDEVICEOBJECTDATA dod
,
796 LPDWORD entries
,DWORD flags
799 ICOM_THIS(SysKeyboardAImpl
,iface
);
803 TRACE("(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n",
804 This
,dodsize
,dod
,entries
,entries
?*entries
:0,flags
);
806 ret
=USER_Driver
->pGetDIData(
807 This
->keystate
, dodsize
, dod
, entries
, flags
)?DI_OK
:E_FAIL
;
808 for (i
=0;i
<*entries
;i
++) {
809 dod
[i
].dwTimeStamp
= GetTickCount();
810 dod
[i
].dwSequence
= evsequence
++;
815 static HRESULT WINAPI
SysKeyboardAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface
)
817 ICOM_THIS(SysKeyboardAImpl
,iface
);
819 TRACE("(this=%p)\n",This
);
821 if (This
->acquired
== 0) {
822 KEYBOARD_CONFIG no_auto
;
824 /* Save the original config */
825 USER_Driver
->pGetKeyboardConfig(&(This
->initial_config
));
827 /* Now, remove auto-repeat */
828 no_auto
.auto_repeat
= FALSE
;
829 USER_Driver
->pSetKeyboardConfig(&no_auto
, WINE_KEYBOARD_CONFIG_AUTO_REPEAT
);
837 static HRESULT WINAPI
SysKeyboardAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface
)
839 ICOM_THIS(SysKeyboardAImpl
,iface
);
840 TRACE("(this=%p)\n",This
);
842 if (This
->acquired
== 1) {
843 /* Restore the original configuration */
844 USER_Driver
->pSetKeyboardConfig(&(This
->initial_config
), 0xFFFFFFFF);
847 ERR("Unacquiring a not-acquired device !!!\n");
853 /******************************************************************************
854 * GetCapabilities : get the device capablitites
856 static HRESULT WINAPI
SysKeyboardAImpl_GetCapabilities(
857 LPDIRECTINPUTDEVICE2A iface
,
858 LPDIDEVCAPS lpDIDevCaps
)
860 ICOM_THIS(SysMouseAImpl
,iface
);
862 TRACE("(this=%p,%p)\n",This
,lpDIDevCaps
);
864 if (lpDIDevCaps
->dwSize
== sizeof(DIDEVCAPS
)) {
865 lpDIDevCaps
->dwFlags
= DIDC_ATTACHED
;
866 lpDIDevCaps
->dwDevType
= DIDEVTYPE_KEYBOARD
;
867 lpDIDevCaps
->dwAxes
= 0;
868 lpDIDevCaps
->dwButtons
= 0;
869 lpDIDevCaps
->dwPOVs
= 0;
870 lpDIDevCaps
->dwFFSamplePeriod
= 0;
871 lpDIDevCaps
->dwFFMinTimeResolution
= 0;
872 lpDIDevCaps
->dwFirmwareRevision
= 100;
873 lpDIDevCaps
->dwHardwareRevision
= 100;
874 lpDIDevCaps
->dwFFDriverVersion
= 0;
877 FIXME("DirectX 3.0 not supported....\n");
883 static HRESULT WINAPI
IDirectInputDevice2AImpl_QueryInterface(
884 LPDIRECTINPUTDEVICE2A iface
,REFIID riid
,LPVOID
*ppobj
887 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
889 TRACE("(this=%p,%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
890 if (IsEqualGUID(&IID_IUnknown
,riid
)) {
891 IDirectInputDevice2_AddRef(iface
);
895 if (IsEqualGUID(&IID_IDirectInputDeviceA
,riid
)) {
896 IDirectInputDevice2_AddRef(iface
);
900 if (IsEqualGUID(&IID_IDirectInputDevice2A
,riid
)) {
901 IDirectInputDevice2_AddRef(iface
);
905 TRACE("Unsupported interface !\n");
909 static ULONG WINAPI
IDirectInputDevice2AImpl_AddRef(
910 LPDIRECTINPUTDEVICE2A iface
)
912 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
916 static HRESULT WINAPI
IDirectInputDevice2AImpl_EnumObjects(
917 LPDIRECTINPUTDEVICE2A iface
,
918 LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback
,
922 FIXME("(this=%p,%p,%p,%08lx): stub!\n", iface
, lpCallback
, lpvRef
, dwFlags
);
923 if (TRACE_ON(dinput
)) {
924 DPRINTF(" - flags = ");
925 _dump_EnumObjects_flags(dwFlags
);
932 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetProperty(
933 LPDIRECTINPUTDEVICE2A iface
,
935 LPDIPROPHEADER pdiph
)
937 FIXME("(this=%p,%s,%p): stub!\n",
938 iface
, debugstr_guid(rguid
), pdiph
);
940 if (TRACE_ON(dinput
))
941 _dump_DIPROPHEADER(pdiph
);
946 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetObjectInfo(
947 LPDIRECTINPUTDEVICE2A iface
,
948 LPDIDEVICEOBJECTINSTANCEA pdidoi
,
952 FIXME("(this=%p,%p,%ld,0x%08lx): stub!\n",
953 iface
, pdidoi
, dwObj
, dwHow
);
958 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetDeviceInfo(
959 LPDIRECTINPUTDEVICE2A iface
,
960 LPDIDEVICEINSTANCEA pdidi
)
962 FIXME("(this=%p,%p): stub!\n",
968 static HRESULT WINAPI
IDirectInputDevice2AImpl_RunControlPanel(
969 LPDIRECTINPUTDEVICE2A iface
,
973 FIXME("(this=%p,0x%08x,0x%08lx): stub!\n",
974 iface
, hwndOwner
, dwFlags
);
979 static HRESULT WINAPI
IDirectInputDevice2AImpl_Initialize(
980 LPDIRECTINPUTDEVICE2A iface
,
985 FIXME("(this=%p,%d,%ld,%s): stub!\n",
986 iface
, hinst
, dwVersion
, debugstr_guid(rguid
));
990 /******************************************************************************
991 * IDirectInputDevice2A
994 static HRESULT WINAPI
IDirectInputDevice2AImpl_CreateEffect(
995 LPDIRECTINPUTDEVICE2A iface
,
998 LPDIRECTINPUTEFFECT
*ppdef
,
1001 FIXME("(this=%p,%s,%p,%p,%p): stub!\n",
1002 iface
, debugstr_guid(rguid
), lpeff
, ppdef
, pUnkOuter
);
1006 static HRESULT WINAPI
IDirectInputDevice2AImpl_EnumEffects(
1007 LPDIRECTINPUTDEVICE2A iface
,
1008 LPDIENUMEFFECTSCALLBACKA lpCallback
,
1012 FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
1013 iface
, lpCallback
, lpvRef
, dwFlags
);
1016 lpCallback(NULL
, lpvRef
);
1020 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetEffectInfo(
1021 LPDIRECTINPUTDEVICE2A iface
,
1022 LPDIEFFECTINFOA lpdei
,
1025 FIXME("(this=%p,%p,%s): stub!\n",
1026 iface
, lpdei
, debugstr_guid(rguid
));
1030 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetForceFeedbackState(
1031 LPDIRECTINPUTDEVICE2A iface
,
1034 FIXME("(this=%p,%p): stub!\n",
1039 static HRESULT WINAPI
IDirectInputDevice2AImpl_SendForceFeedbackCommand(
1040 LPDIRECTINPUTDEVICE2A iface
,
1043 FIXME("(this=%p,0x%08lx): stub!\n",
1048 static HRESULT WINAPI
IDirectInputDevice2AImpl_EnumCreatedEffectObjects(
1049 LPDIRECTINPUTDEVICE2A iface
,
1050 LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback
,
1054 FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
1055 iface
, lpCallback
, lpvRef
, dwFlags
);
1057 lpCallback(NULL
, lpvRef
);
1061 static HRESULT WINAPI
IDirectInputDevice2AImpl_Escape(
1062 LPDIRECTINPUTDEVICE2A iface
,
1063 LPDIEFFESCAPE lpDIEEsc
)
1065 FIXME("(this=%p,%p): stub!\n",
1070 static HRESULT WINAPI
IDirectInputDevice2AImpl_Poll(
1071 LPDIRECTINPUTDEVICE2A iface
)
1073 FIXME("(this=%p): stub!\n",
1078 static HRESULT WINAPI
IDirectInputDevice2AImpl_SendDeviceData(
1079 LPDIRECTINPUTDEVICE2A iface
,
1081 LPDIDEVICEOBJECTDATA rgdod
,
1085 FIXME("(this=%p,0x%08lx,%p,%p,0x%08lx): stub!\n",
1086 iface
, cbObjectData
, rgdod
, pdwInOut
, dwFlags
);
1091 /******************************************************************************
1092 * SysMouseA (DInput Mouse support)
1095 /******************************************************************************
1096 * Release : release the mouse buffer.
1098 static ULONG WINAPI
SysMouseAImpl_Release(LPDIRECTINPUTDEVICE2A iface
)
1100 ICOM_THIS(SysMouseAImpl
,iface
);
1106 /* Free the data queue */
1107 if (This
->data_queue
!= NULL
)
1108 HeapFree(GetProcessHeap(),0,This
->data_queue
);
1110 /* Install the previous event handler (in case of releasing an aquired
1112 if (This
->prev_handler
!= NULL
)
1113 MOUSE_Enable(This
->prev_handler
);
1114 DeleteCriticalSection(&(This
->crit
));
1116 /* Free the DataFormat */
1117 if (This
->df
!= &(Wine_InternalMouseFormat
)) {
1118 HeapFree(GetProcessHeap(), 0, This
->df
->rgodf
);
1119 HeapFree(GetProcessHeap(), 0, This
->df
);
1122 HeapFree(GetProcessHeap(),0,This
);
1127 /******************************************************************************
1128 * SetCooperativeLevel : store the window in which we will do our
1131 static HRESULT WINAPI
SysMouseAImpl_SetCooperativeLevel(
1132 LPDIRECTINPUTDEVICE2A iface
,HWND hwnd
,DWORD dwflags
1135 ICOM_THIS(SysMouseAImpl
,iface
);
1137 TRACE("(this=%p,0x%08lx,0x%08lx)\n",This
,(DWORD
)hwnd
,dwflags
);
1139 if (TRACE_ON(dinput
))
1140 _dump_cooperativelevel(dwflags
);
1142 /* Store the window which asks for the mouse */
1149 /******************************************************************************
1150 * SetDataFormat : the application can choose the format of the data
1151 * the device driver sends back with GetDeviceState.
1153 * For the moment, only the "standard" configuration (c_dfDIMouse) is supported
1154 * in absolute and relative mode.
1156 static HRESULT WINAPI
SysMouseAImpl_SetDataFormat(
1157 LPDIRECTINPUTDEVICE2A iface
,LPCDIDATAFORMAT df
1160 ICOM_THIS(SysMouseAImpl
,iface
);
1163 TRACE("(this=%p,%p)\n",This
,df
);
1165 TRACE("(df.dwSize=%ld)\n",df
->dwSize
);
1166 TRACE("(df.dwObjsize=%ld)\n",df
->dwObjSize
);
1167 TRACE("(df.dwFlags=0x%08lx)\n",df
->dwFlags
);
1168 TRACE("(df.dwDataSize=%ld)\n",df
->dwDataSize
);
1169 TRACE("(df.dwNumObjs=%ld)\n",df
->dwNumObjs
);
1171 for (i
=0;i
<df
->dwNumObjs
;i
++) {
1173 TRACE("df.rgodf[%d].guid %s (%p)\n",i
, debugstr_guid(df
->rgodf
[i
].pguid
), df
->rgodf
[i
].pguid
);
1174 TRACE("df.rgodf[%d].dwOfs %ld\n",i
,df
->rgodf
[i
].dwOfs
);
1175 TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df
->rgodf
[i
].dwType
),DIDFT_GETINSTANCE(df
->rgodf
[i
].dwType
));
1176 TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i
,df
->rgodf
[i
].dwFlags
);
1179 /* Check if the mouse is in absolute or relative mode */
1180 if (df
->dwFlags
== DIDF_ABSAXIS
)
1182 else if (df
->dwFlags
== DIDF_RELAXIS
)
1185 ERR("Neither absolute nor relative flag set.");
1187 /* Store the new data format */
1188 This
->df
= HeapAlloc(GetProcessHeap(),0,df
->dwSize
);
1189 memcpy(This
->df
, df
, df
->dwSize
);
1190 This
->df
->rgodf
= HeapAlloc(GetProcessHeap(),0,df
->dwNumObjs
*df
->dwObjSize
);
1191 memcpy(This
->df
->rgodf
,df
->rgodf
,df
->dwNumObjs
*df
->dwObjSize
);
1193 /* Prepare all the data-conversion filters */
1194 This
->wine_df
= create_DataFormat(&(Wine_InternalMouseFormat
), df
, This
->offset_array
);
1199 #define GEN_EVENT(offset,data,xtime,seq) \
1201 /* If queue_len > 0, queuing is requested -> TRACE the event queued */ \
1202 if (This->queue_len > 0) { \
1203 TRACE(" queueing %d at offset %d (queue pos %d / size %d)\n", \
1204 (int) (data), (int) (offset), \
1205 (int) (This->queue_pos), (int) (This->queue_len)); \
1207 if ((offset >= 0) && (This->queue_pos < This->queue_len)) { \
1208 This->data_queue[This->queue_pos].dwOfs = offset; \
1209 This->data_queue[This->queue_pos].dwData = data; \
1210 This->data_queue[This->queue_pos].dwTimeStamp = xtime; \
1211 This->data_queue[This->queue_pos].dwSequence = seq; \
1212 This->queue_pos++; \
1218 /* Our private mouse event handler */
1219 static void WINAPI
dinput_mouse_event( DWORD dwFlags
, DWORD dx
, DWORD dy
,
1220 DWORD cButtons
, DWORD dwExtraInfo
)
1222 long posX
= -1, posY
= -1;
1223 DWORD keyState
, xtime
, extra
;
1224 SysMouseAImpl
* This
= (SysMouseAImpl
*) current_lock
;
1226 EnterCriticalSection(&(This
->crit
));
1227 /* Mouse moved -> send event if asked */
1229 SetEvent(This
->hEvent
);
1231 if ( !IsBadReadPtr( (LPVOID
)dwExtraInfo
, sizeof(WINE_MOUSEEVENT
) )
1232 && ((WINE_MOUSEEVENT
*)dwExtraInfo
)->magic
== WINE_MOUSEEVENT_MAGIC
) {
1233 WINE_MOUSEEVENT
*wme
= (WINE_MOUSEEVENT
*)dwExtraInfo
;
1234 keyState
= wme
->keyState
;
1236 extra
= (DWORD
)wme
->hWnd
;
1238 if (dwFlags
& MOUSEEVENTF_MOVE
) {
1239 if (dwFlags
& MOUSEEVENTF_ABSOLUTE
) {
1240 posX
= (dx
* GetSystemMetrics(SM_CXSCREEN
)) >> 16;
1241 posY
= (dy
* GetSystemMetrics(SM_CYSCREEN
)) >> 16;
1243 if (This
->absolute
) {
1244 if (posX
!= This
->prevX
)
1245 GEN_EVENT(This
->offset_array
[WINE_MOUSE_X_POSITION
], posX
, xtime
, 0);
1246 if (posY
!= This
->prevY
)
1247 GEN_EVENT(This
->offset_array
[WINE_MOUSE_Y_POSITION
], posY
, xtime
, 0);
1249 /* Now, warp handling */
1250 if ((This
->need_warp
== WARP_STARTED
) &&
1251 (posX
== This
->win_centerX
) && (posX
== This
->win_centerX
)) {
1252 /* Warp has been done... */
1253 This
->need_warp
= WARP_DONE
;
1257 /* Relative mouse input with absolute mouse event : the real fun starts here... */
1258 if ((This
->need_warp
== WARP_NEEDED
) ||
1259 (This
->need_warp
== WARP_STARTED
)) {
1260 if (posX
!= This
->prevX
)
1261 GEN_EVENT(This
->offset_array
[WINE_MOUSE_X_POSITION
], posX
- This
->prevX
, xtime
, evsequence
++);
1262 if (posY
!= This
->prevY
)
1263 GEN_EVENT(This
->offset_array
[WINE_MOUSE_Y_POSITION
], posY
- This
->prevY
, xtime
, evsequence
++);
1265 /* This is the first time the event handler has been called after a
1266 GetData of GetState. */
1267 if (posX
!= This
->win_centerX
) {
1268 GEN_EVENT(This
->offset_array
[WINE_MOUSE_X_POSITION
], posX
- This
->win_centerX
, xtime
, evsequence
++);
1269 This
->need_warp
= WARP_NEEDED
;
1272 if (posY
!= This
->win_centerY
) {
1273 GEN_EVENT(This
->offset_array
[WINE_MOUSE_Y_POSITION
], posY
- This
->win_centerY
, xtime
, evsequence
++);
1274 This
->need_warp
= WARP_NEEDED
;
1282 if (This
->absolute
) {
1283 This
->m_state
.lX
= posX
;
1284 This
->m_state
.lY
= posY
;
1286 This
->m_state
.lX
= posX
- This
->win_centerX
;
1287 This
->m_state
.lY
= posY
- This
->win_centerY
;
1290 /* Mouse reporting is in relative mode */
1294 if (This
->absolute
) {
1297 aposX
= This
->m_state
.lX
+ posX
;
1300 if (aposX
>= GetSystemMetrics(SM_CXSCREEN
))
1301 aposX
= GetSystemMetrics(SM_CXSCREEN
);
1303 aposY
= This
->m_state
.lY
+ posY
;
1306 if (aposY
>= GetSystemMetrics(SM_CYSCREEN
))
1307 aposY
= GetSystemMetrics(SM_CYSCREEN
);
1310 GEN_EVENT(This
->offset_array
[WINE_MOUSE_X_POSITION
], aposX
, xtime
, evsequence
++);
1312 GEN_EVENT(This
->offset_array
[WINE_MOUSE_Y_POSITION
], aposY
, xtime
, evsequence
++);
1314 This
->m_state
.lX
= aposX
;
1315 This
->m_state
.lY
= aposY
;
1318 GEN_EVENT(This
->offset_array
[WINE_MOUSE_X_POSITION
], posX
, xtime
, evsequence
++);
1320 GEN_EVENT(This
->offset_array
[WINE_MOUSE_Y_POSITION
], posY
, xtime
, evsequence
++);
1322 This
->m_state
.lX
= posX
;
1323 This
->m_state
.lY
= posY
;
1328 ERR("Mouse event not supported...\n");
1329 LeaveCriticalSection(&(This
->crit
));
1333 if (TRACE_ON(dinput
)) {
1334 if (dwFlags
& MOUSEEVENTF_MOVE
)
1335 TRACE(" %ld %ld (%s)", posX
, posY
,
1336 (dwFlags
& MOUSEEVENTF_ABSOLUTE
? "abs" : "rel"));
1338 if ( dwFlags
& MOUSEEVENTF_LEFTDOWN
) DPRINTF(" LD ");
1339 if ( dwFlags
& MOUSEEVENTF_LEFTUP
) DPRINTF(" LU ");
1341 if ( dwFlags
& MOUSEEVENTF_RIGHTDOWN
) DPRINTF(" RD ");
1342 if ( dwFlags
& MOUSEEVENTF_RIGHTUP
) DPRINTF(" RU ");
1344 if ( dwFlags
& MOUSEEVENTF_MIDDLEDOWN
) DPRINTF(" MD ");
1345 if ( dwFlags
& MOUSEEVENTF_MIDDLEUP
) DPRINTF(" MU ");
1347 if (!(This
->absolute
)) DPRINTF(" W=%d ", This
->need_warp
);
1353 if ( dwFlags
& MOUSEEVENTF_LEFTDOWN
) {
1354 GEN_EVENT(This
->offset_array
[WINE_MOUSE_L_POSITION
], 0xFF, xtime
, evsequence
++);
1355 This
->m_state
.rgbButtons
[0] = 0xFF;
1357 if ( dwFlags
& MOUSEEVENTF_LEFTUP
) {
1358 GEN_EVENT(This
->offset_array
[WINE_MOUSE_L_POSITION
], 0x00, xtime
, evsequence
++);
1359 This
->m_state
.rgbButtons
[0] = 0x00;
1361 if ( dwFlags
& MOUSEEVENTF_RIGHTDOWN
) {
1362 GEN_EVENT(This
->offset_array
[WINE_MOUSE_R_POSITION
], 0xFF, xtime
, evsequence
++);
1363 This
->m_state
.rgbButtons
[1] = 0xFF;
1365 if ( dwFlags
& MOUSEEVENTF_RIGHTUP
) {
1366 GEN_EVENT(This
->offset_array
[WINE_MOUSE_R_POSITION
], 0x00, xtime
, evsequence
++);
1367 This
->m_state
.rgbButtons
[1] = 0x00;
1369 if ( dwFlags
& MOUSEEVENTF_MIDDLEDOWN
) {
1370 GEN_EVENT(This
->offset_array
[WINE_MOUSE_M_POSITION
], 0xFF, xtime
, evsequence
++);
1371 This
->m_state
.rgbButtons
[2] = 0xFF;
1373 if ( dwFlags
& MOUSEEVENTF_MIDDLEUP
) {
1374 GEN_EVENT(This
->offset_array
[WINE_MOUSE_M_POSITION
], 0x00, xtime
, evsequence
++);
1375 This
->m_state
.rgbButtons
[2] = 0x00;
1378 TRACE("(X: %ld - Y: %ld L: %02x M: %02x R: %02x)\n",
1379 This
->m_state
.lX
, This
->m_state
.lY
,
1380 This
->m_state
.rgbButtons
[0], This
->m_state
.rgbButtons
[2], This
->m_state
.rgbButtons
[1]);
1382 LeaveCriticalSection(&(This
->crit
));
1386 /******************************************************************************
1387 * Acquire : gets exclusive control of the mouse
1389 static HRESULT WINAPI
SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface
)
1391 ICOM_THIS(SysMouseAImpl
,iface
);
1394 TRACE("(this=%p)\n",This
);
1396 if (This
->acquired
== 0) {
1399 /* This stores the current mouse handler. */
1400 This
->prev_handler
= mouse_event
;
1402 /* Store (in a global variable) the current lock */
1403 current_lock
= (IDirectInputDevice2A
*)This
;
1405 /* Init the mouse state */
1406 if (This
->absolute
) {
1407 This
->m_state
.lX
= PosX
;
1408 This
->m_state
.lY
= PosY
;
1413 This
->m_state
.lX
= 0;
1414 This
->m_state
.lY
= 0;
1416 This
->m_state
.rgbButtons
[0] = (MouseButtonsStates
[0] ? 0xFF : 0x00);
1417 This
->m_state
.rgbButtons
[1] = (MouseButtonsStates
[1] ? 0xFF : 0x00);
1418 This
->m_state
.rgbButtons
[2] = (MouseButtonsStates
[2] ? 0xFF : 0x00);
1420 /* Install our own mouse event handler */
1421 MOUSE_Enable(dinput_mouse_event
);
1423 /* Get the window dimension and find the center */
1424 GetWindowRect(This
->win
, &rect
);
1425 This
->win_centerX
= (rect
.right
- rect
.left
) / 2;
1426 This
->win_centerY
= (rect
.bottom
- rect
.top
) / 2;
1428 /* Warp the mouse to the center of the window */
1429 if (This
->absolute
== 0) {
1430 TRACE("Warping mouse to %ld - %ld\n", This
->win_centerX
, This
->win_centerY
);
1431 point
.x
= This
->win_centerX
;
1432 point
.y
= This
->win_centerY
;
1433 MapWindowPoints(This
->win
, HWND_DESKTOP
, &point
, 1);
1434 DISPLAY_MoveCursor(point
.x
, point
.y
);
1435 This
->need_warp
= WARP_STARTED
;
1443 /******************************************************************************
1444 * Unacquire : frees the mouse
1446 static HRESULT WINAPI
SysMouseAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface
)
1448 ICOM_THIS(SysMouseAImpl
,iface
);
1450 TRACE("(this=%p)\n",This
);
1452 /* Reinstall previous mouse event handler */
1453 MOUSE_Enable(This
->prev_handler
);
1454 This
->prev_handler
= NULL
;
1457 current_lock
= NULL
;
1459 /* Unacquire device */
1465 /******************************************************************************
1466 * GetDeviceState : returns the "state" of the mouse.
1468 * For the moment, only the "standard" return structure (DIMOUSESTATE) is
1471 static HRESULT WINAPI
SysMouseAImpl_GetDeviceState(
1472 LPDIRECTINPUTDEVICE2A iface
,DWORD len
,LPVOID ptr
1474 ICOM_THIS(SysMouseAImpl
,iface
);
1476 EnterCriticalSection(&(This
->crit
));
1477 TRACE("(this=%p,0x%08lx,%p): \n",This
,len
,ptr
);
1479 /* Copy the current mouse state */
1480 fill_DataFormat(ptr
, &(This
->m_state
), This
->wine_df
);
1482 /* Initialize the buffer when in relative mode */
1483 if (This
->absolute
== 0) {
1484 This
->m_state
.lX
= 0;
1485 This
->m_state
.lY
= 0;
1488 /* Check if we need to do a mouse warping */
1489 if (This
->need_warp
== WARP_NEEDED
) {
1492 TRACE("Warping mouse to %ld - %ld\n", This
->win_centerX
, This
->win_centerY
);
1493 point
.x
= This
->win_centerX
;
1494 point
.y
= This
->win_centerY
;
1495 MapWindowPoints(This
->win
, HWND_DESKTOP
, &point
, 1);
1496 DISPLAY_MoveCursor(point
.x
, point
.y
);
1498 This
->need_warp
= WARP_STARTED
;
1501 LeaveCriticalSection(&(This
->crit
));
1503 TRACE("(X: %ld - Y: %ld L: %02x M: %02x R: %02x)\n",
1504 This
->m_state
.lX
, This
->m_state
.lY
,
1505 This
->m_state
.rgbButtons
[0], This
->m_state
.rgbButtons
[2], This
->m_state
.rgbButtons
[1]);
1510 /******************************************************************************
1511 * GetDeviceState : gets buffered input data.
1513 static HRESULT WINAPI
SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE2A iface
,
1515 LPDIDEVICEOBJECTDATA dod
,
1519 ICOM_THIS(SysMouseAImpl
,iface
);
1521 EnterCriticalSection(&(This
->crit
));
1522 TRACE("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx)\n",This
,dodsize
,*entries
,flags
);
1524 if (flags
& DIGDD_PEEK
)
1525 FIXME("DIGDD_PEEK\n");
1528 *entries
= This
->queue_pos
;
1529 This
->queue_pos
= 0;
1531 /* Check for buffer overflow */
1532 if (This
->queue_pos
> *entries
) {
1533 WARN("Buffer overflow not handled properly yet...\n");
1534 This
->queue_pos
= *entries
;
1536 if (dodsize
!= sizeof(DIDEVICEOBJECTDATA
)) {
1537 ERR("Wrong structure size !\n");
1538 LeaveCriticalSection(&(This
->crit
));
1539 return DIERR_INVALIDPARAM
;
1542 if (This
->queue_pos
)
1543 TRACE("Application retrieving %d event(s).\n", This
->queue_pos
);
1545 /* Copy the buffered data into the application queue */
1546 memcpy(dod
, This
->data_queue
, This
->queue_pos
* dodsize
);
1547 *entries
= This
->queue_pos
;
1549 /* Reset the event queue */
1550 This
->queue_pos
= 0;
1552 LeaveCriticalSection(&(This
->crit
));
1554 /* Check if we need to do a mouse warping */
1555 if (This
->need_warp
== WARP_NEEDED
) {
1558 TRACE("Warping mouse to %ld - %ld\n", This
->win_centerX
, This
->win_centerY
);
1559 point
.x
= This
->win_centerX
;
1560 point
.y
= This
->win_centerY
;
1561 MapWindowPoints(This
->win
, HWND_DESKTOP
, &point
, 1);
1563 DISPLAY_MoveCursor(point
.x
, point
.y
);
1565 This
->need_warp
= WARP_STARTED
;
1570 /******************************************************************************
1571 * SetProperty : change input device properties
1573 static HRESULT WINAPI
SysMouseAImpl_SetProperty(LPDIRECTINPUTDEVICE2A iface
,
1577 ICOM_THIS(SysMouseAImpl
,iface
);
1579 TRACE("(this=%p,%s,%p)\n",This
,debugstr_guid(rguid
),ph
);
1581 if (!HIWORD(rguid
)) {
1582 switch ((DWORD
)rguid
) {
1583 case (DWORD
) DIPROP_BUFFERSIZE
: {
1584 LPCDIPROPDWORD pd
= (LPCDIPROPDWORD
)ph
;
1586 TRACE("buffersize = %ld\n",pd
->dwData
);
1588 This
->data_queue
= (LPDIDEVICEOBJECTDATA
)HeapAlloc(GetProcessHeap(),0,
1589 pd
->dwData
* sizeof(DIDEVICEOBJECTDATA
));
1590 This
->queue_pos
= 0;
1591 This
->queue_len
= pd
->dwData
;
1595 FIXME("Unknown type %ld (%s)\n",(DWORD
)rguid
,debugstr_guid(rguid
));
1603 /******************************************************************************
1604 * GetProperty : get input device properties
1606 static HRESULT WINAPI
SysMouseAImpl_GetProperty(LPDIRECTINPUTDEVICE2A iface
,
1608 LPDIPROPHEADER pdiph
)
1610 ICOM_THIS(SysMouseAImpl
,iface
);
1612 TRACE("(this=%p,%s,%p): stub!\n",
1613 iface
, debugstr_guid(rguid
), pdiph
);
1615 if (TRACE_ON(dinput
))
1616 _dump_DIPROPHEADER(pdiph
);
1618 if (!HIWORD(rguid
)) {
1619 switch ((DWORD
)rguid
) {
1620 case (DWORD
) DIPROP_BUFFERSIZE
: {
1621 LPDIPROPDWORD pd
= (LPDIPROPDWORD
)pdiph
;
1623 TRACE(" return buffersize = %d\n",This
->queue_len
);
1624 pd
->dwData
= This
->queue_len
;
1628 case (DWORD
) DIPROP_RANGE
: {
1629 LPDIPROPRANGE pr
= (LPDIPROPRANGE
) pdiph
;
1631 if ((pdiph
->dwHow
== DIPH_BYID
) &&
1632 ((pdiph
->dwObj
== (DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE
) | DIDFT_RELAXIS
)) ||
1633 (pdiph
->dwObj
== (DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE
) | DIDFT_RELAXIS
)))) {
1634 /* Querying the range of either the X or the Y axis. As I do
1635 not know the range, do as if the range where
1637 pr
->lMin
= DIPROPRANGE_NOMIN
;
1638 pr
->lMax
= DIPROPRANGE_NOMAX
;
1645 FIXME("Unknown type %ld (%s)\n",(DWORD
)rguid
,debugstr_guid(rguid
));
1656 /******************************************************************************
1657 * SetEventNotification : specifies event to be sent on state change
1659 static HRESULT WINAPI
SysMouseAImpl_SetEventNotification(LPDIRECTINPUTDEVICE2A iface
,
1661 ICOM_THIS(SysMouseAImpl
,iface
);
1663 TRACE("(this=%p,0x%08lx)\n",This
,(DWORD
)hnd
);
1670 /******************************************************************************
1671 * GetCapabilities : get the device capablitites
1673 static HRESULT WINAPI
SysMouseAImpl_GetCapabilities(
1674 LPDIRECTINPUTDEVICE2A iface
,
1675 LPDIDEVCAPS lpDIDevCaps
)
1677 ICOM_THIS(SysMouseAImpl
,iface
);
1679 TRACE("(this=%p,%p)\n",This
,lpDIDevCaps
);
1681 if (lpDIDevCaps
->dwSize
== sizeof(DIDEVCAPS
)) {
1682 lpDIDevCaps
->dwFlags
= DIDC_ATTACHED
;
1683 lpDIDevCaps
->dwDevType
= DIDEVTYPE_MOUSE
;
1684 lpDIDevCaps
->dwAxes
= 2;
1685 lpDIDevCaps
->dwButtons
= 3;
1686 lpDIDevCaps
->dwPOVs
= 0;
1687 lpDIDevCaps
->dwFFSamplePeriod
= 0;
1688 lpDIDevCaps
->dwFFMinTimeResolution
= 0;
1689 lpDIDevCaps
->dwFirmwareRevision
= 100;
1690 lpDIDevCaps
->dwHardwareRevision
= 100;
1691 lpDIDevCaps
->dwFFDriverVersion
= 0;
1694 FIXME("DirectX 3.0 not supported....\n");
1701 /******************************************************************************
1702 * EnumObjects : enumerate the different buttons and axis...
1704 static HRESULT WINAPI
SysMouseAImpl_EnumObjects(
1705 LPDIRECTINPUTDEVICE2A iface
,
1706 LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback
,
1710 ICOM_THIS(SysMouseAImpl
,iface
);
1711 DIDEVICEOBJECTINSTANCEA ddoi
;
1713 TRACE("(this=%p,%p,%p,%08lx)\n", This
, lpCallback
, lpvRef
, dwFlags
);
1714 if (TRACE_ON(dinput
)) {
1715 DPRINTF(" - flags = ");
1716 _dump_EnumObjects_flags(dwFlags
);
1720 /* Only the fields till dwFFMaxForce are relevant */
1721 ddoi
.dwSize
= FIELD_OFFSET(DIDEVICEOBJECTINSTANCEA
, dwFFMaxForce
);
1723 /* In a mouse, we have : two relative axis and three buttons */
1724 if ((dwFlags
== DIDFT_ALL
) ||
1725 (dwFlags
& DIDFT_AXIS
)) {
1727 ddoi
.guidType
= GUID_XAxis
;
1728 ddoi
.dwOfs
= This
->offset_array
[WINE_MOUSE_X_POSITION
];
1729 ddoi
.dwType
= DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE
) | DIDFT_RELAXIS
;
1730 strcpy(ddoi
.tszName
, "X-Axis");
1731 _dump_OBJECTINSTANCEA(&ddoi
);
1732 if (lpCallback(&ddoi
, lpvRef
) != DIENUM_CONTINUE
) return DI_OK
;
1735 ddoi
.guidType
= GUID_YAxis
;
1736 ddoi
.dwOfs
= This
->offset_array
[WINE_MOUSE_Y_POSITION
];
1737 ddoi
.dwType
= DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE
) | DIDFT_RELAXIS
;
1738 strcpy(ddoi
.tszName
, "Y-Axis");
1739 _dump_OBJECTINSTANCEA(&ddoi
);
1740 if (lpCallback(&ddoi
, lpvRef
) != DIENUM_CONTINUE
) return DI_OK
;
1743 if ((dwFlags
== DIDFT_ALL
) ||
1744 (dwFlags
& DIDFT_BUTTON
)) {
1745 ddoi
.guidType
= GUID_Button
;
1748 ddoi
.dwOfs
= This
->offset_array
[WINE_MOUSE_L_POSITION
];
1749 ddoi
.dwType
= DIDFT_MAKEINSTANCE(WINE_MOUSE_L_BUTTON_INSTANCE
) | DIDFT_PSHBUTTON
;
1750 strcpy(ddoi
.tszName
, "Left-Button");
1751 _dump_OBJECTINSTANCEA(&ddoi
);
1752 if (lpCallback(&ddoi
, lpvRef
) != DIENUM_CONTINUE
) return DI_OK
;
1755 ddoi
.dwOfs
= This
->offset_array
[WINE_MOUSE_R_POSITION
];
1756 ddoi
.dwType
= DIDFT_MAKEINSTANCE(WINE_MOUSE_R_BUTTON_INSTANCE
) | DIDFT_PSHBUTTON
;
1757 strcpy(ddoi
.tszName
, "Right-Button");
1758 _dump_OBJECTINSTANCEA(&ddoi
);
1759 if (lpCallback(&ddoi
, lpvRef
) != DIENUM_CONTINUE
) return DI_OK
;
1762 ddoi
.dwOfs
= This
->offset_array
[WINE_MOUSE_M_POSITION
];
1763 ddoi
.dwType
= DIDFT_MAKEINSTANCE(WINE_MOUSE_M_BUTTON_INSTANCE
) | DIDFT_PSHBUTTON
;
1764 strcpy(ddoi
.tszName
, "Middle-Button");
1765 _dump_OBJECTINSTANCEA(&ddoi
);
1766 if (lpCallback(&ddoi
, lpvRef
) != DIENUM_CONTINUE
) return DI_OK
;
1774 #ifdef HAVE_LINUX_22_JOYSTICK_API
1775 /******************************************************************************
1778 static ULONG WINAPI
JoystickAImpl_Release(LPDIRECTINPUTDEVICE2A iface
)
1780 ICOM_THIS(JoystickAImpl
,iface
);
1786 /* Free the data queue */
1787 if (This
->data_queue
!= NULL
)
1788 HeapFree(GetProcessHeap(),0,This
->data_queue
);
1790 /* Free the DataFormat */
1791 HeapFree(GetProcessHeap(), 0, This
->df
);
1793 HeapFree(GetProcessHeap(),0,This
);
1797 /******************************************************************************
1798 * SetDataFormat : the application can choose the format of the data
1799 * the device driver sends back with GetDeviceState.
1801 static HRESULT WINAPI
JoystickAImpl_SetDataFormat(
1802 LPDIRECTINPUTDEVICE2A iface
,LPCDIDATAFORMAT df
1805 ICOM_THIS(JoystickAImpl
,iface
);
1808 TRACE("(this=%p,%p)\n",This
,df
);
1810 TRACE("(df.dwSize=%ld)\n",df
->dwSize
);
1811 TRACE("(df.dwObjsize=%ld)\n",df
->dwObjSize
);
1812 TRACE("(df.dwFlags=0x%08lx)\n",df
->dwFlags
);
1813 TRACE("(df.dwDataSize=%ld)\n",df
->dwDataSize
);
1814 TRACE("(df.dwNumObjs=%ld)\n",df
->dwNumObjs
);
1816 for (i
=0;i
<df
->dwNumObjs
;i
++) {
1817 TRACE("df.rgodf[%d].guid %s (%p)\n",i
,debugstr_guid(df
->rgodf
[i
].pguid
), df
->rgodf
[i
].pguid
);
1818 TRACE("df.rgodf[%d].dwOfs %ld\n",i
,df
->rgodf
[i
].dwOfs
);
1819 TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df
->rgodf
[i
].dwType
),DIDFT_GETINSTANCE(df
->rgodf
[i
].dwType
));
1820 TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i
,df
->rgodf
[i
].dwFlags
);
1823 /* Store the new data format */
1824 This
->df
= HeapAlloc(GetProcessHeap(),0,df
->dwSize
);
1825 memcpy(This
->df
, df
, df
->dwSize
);
1826 This
->df
->rgodf
= HeapAlloc(GetProcessHeap(),0,df
->dwNumObjs
*df
->dwObjSize
);
1827 memcpy(This
->df
->rgodf
,df
->rgodf
,df
->dwNumObjs
*df
->dwObjSize
);
1832 /******************************************************************************
1833 * Acquire : gets exclusive control of the joystick
1835 static HRESULT WINAPI
JoystickAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface
)
1837 ICOM_THIS(JoystickAImpl
,iface
);
1839 TRACE("(this=%p)\n",This
);
1840 if (This
->joyfd
!=-1)
1842 This
->joyfd
=open(JOYDEV
,O_RDONLY
);
1843 if (This
->joyfd
==-1)
1844 return DIERR_NOTFOUND
;
1848 /******************************************************************************
1849 * Unacquire : frees the joystick
1851 static HRESULT WINAPI
JoystickAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface
)
1853 ICOM_THIS(JoystickAImpl
,iface
);
1855 TRACE("(this=%p)\n",This
);
1856 if (This
->joyfd
!=-1) {
1863 #define map_axis(val) ((val+32768)*(This->lMax-This->lMin)/65536+This->lMin)
1865 static void joy_polldev(JoystickAImpl
*This
) {
1868 struct js_event jse
;
1870 if (This
->joyfd
==-1)
1873 memset(&tv
,0,sizeof(tv
));
1874 FD_ZERO(&readfds
);FD_SET(This
->joyfd
,&readfds
);
1875 if (1>select(This
->joyfd
+1,&readfds
,NULL
,NULL
,&tv
))
1877 /* we have one event, so we can read */
1878 if (sizeof(jse
)!=read(This
->joyfd
,&jse
,sizeof(jse
))) {
1881 TRACE("js_event: type 0x%x, number %d, value %d\n",jse
.type
,jse
.number
,jse
.value
);
1882 if (jse
.type
& JS_EVENT_BUTTON
) {
1883 GEN_EVENT(DIJOFS_BUTTON(jse
.number
),jse
.value
?0x80:0x00,jse
.time
,evsequence
++);
1884 This
->js
.rgbButtons
[jse
.number
] = jse
.value
?0x80:0x00;
1886 if (jse
.type
& JS_EVENT_AXIS
) {
1887 switch (jse
.number
) {
1889 GEN_EVENT(jse
.number
*4,jse
.value
,jse
.time
,evsequence
++);
1890 This
->js
.lX
= map_axis(jse
.value
);
1893 GEN_EVENT(jse
.number
*4,jse
.value
,jse
.time
,evsequence
++);
1894 This
->js
.lY
= map_axis(jse
.value
);
1897 GEN_EVENT(jse
.number
*4,jse
.value
,jse
.time
,evsequence
++);
1898 This
->js
.lZ
= map_axis(jse
.value
);
1901 FIXME("more then 3 axes (%d) not handled!\n",jse
.number
);
1908 /******************************************************************************
1909 * GetDeviceState : returns the "state" of the joystick.
1912 static HRESULT WINAPI
JoystickAImpl_GetDeviceState(
1913 LPDIRECTINPUTDEVICE2A iface
,DWORD len
,LPVOID ptr
1915 ICOM_THIS(JoystickAImpl
,iface
);
1918 TRACE("(this=%p,0x%08lx,%p)\n",This
,len
,ptr
);
1919 if (len
!= sizeof(DIJOYSTATE
)) {
1920 FIXME("len %ld is not sizeof(DIJOYSTATE), unsupported format.\n",len
);
1922 memcpy(ptr
,&(This
->js
),len
);
1923 This
->queue_pos
= 0;
1927 /******************************************************************************
1928 * GetDeviceState : gets buffered input data.
1930 static HRESULT WINAPI
JoystickAImpl_GetDeviceData(LPDIRECTINPUTDEVICE2A iface
,
1932 LPDIDEVICEOBJECTDATA dod
,
1936 ICOM_THIS(JoystickAImpl
,iface
);
1938 FIXME("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx),STUB!\n",This
,dodsize
,*entries
,flags
);
1941 if (flags
& DIGDD_PEEK
)
1942 FIXME("DIGDD_PEEK\n");
1950 /******************************************************************************
1951 * SetProperty : change input device properties
1953 static HRESULT WINAPI
JoystickAImpl_SetProperty(LPDIRECTINPUTDEVICE2A iface
,
1957 ICOM_THIS(JoystickAImpl
,iface
);
1959 FIXME("(this=%p,%s,%p)\n",This
,debugstr_guid(rguid
),ph
);
1960 FIXME("ph.dwSize = %ld, ph.dwHeaderSize =%ld, ph.dwObj = %ld, ph.dwHow= %ld\n",ph
->dwSize
, ph
->dwHeaderSize
,ph
->dwObj
,ph
->dwHow
);
1962 if (!HIWORD(rguid
)) {
1963 switch ((DWORD
)rguid
) {
1964 case (DWORD
) DIPROP_BUFFERSIZE
: {
1965 LPCDIPROPDWORD pd
= (LPCDIPROPDWORD
)ph
;
1967 FIXME("buffersize = %ld\n",pd
->dwData
);
1970 case (DWORD
)DIPROP_RANGE
: {
1971 LPCDIPROPRANGE pr
= (LPCDIPROPRANGE
)ph
;
1973 FIXME("proprange(%ld,%ld)\n",pr
->lMin
,pr
->lMax
);
1974 This
->lMin
= pr
->lMin
;
1975 This
->lMax
= pr
->lMax
;
1978 case (DWORD
)DIPROP_DEADZONE
: {
1979 LPCDIPROPDWORD pd
= (LPCDIPROPDWORD
)ph
;
1981 FIXME("deadzone(%ld)\n",pd
->dwData
);
1982 This
->deadzone
= pd
->dwData
;
1986 FIXME("Unknown type %ld (%s)\n",(DWORD
)rguid
,debugstr_guid(rguid
));
1993 /******************************************************************************
1994 * SetEventNotification : specifies event to be sent on state change
1996 static HRESULT WINAPI
JoystickAImpl_SetEventNotification(
1997 LPDIRECTINPUTDEVICE2A iface
, HANDLE hnd
1999 ICOM_THIS(JoystickAImpl
,iface
);
2001 TRACE("(this=%p,0x%08lx)\n",This
,(DWORD
)hnd
);
2006 static HRESULT WINAPI
JoystickAImpl_GetCapabilities(
2007 LPDIRECTINPUTDEVICE2A iface
,
2008 LPDIDEVCAPS lpDIDevCaps
)
2010 ICOM_THIS(JoystickAImpl
,iface
);
2012 int xfd
= This
->joyfd
;
2014 TRACE("%p->(%p)\n",iface
,lpDIDevCaps
);
2016 xfd
= open(JOYDEV
,O_RDONLY
);
2017 lpDIDevCaps
->dwFlags
= DIDC_ATTACHED
;
2018 lpDIDevCaps
->dwDevType
= DIDEVTYPE_JOYSTICK
;
2020 if (-1==ioctl(xfd
,JSIOCGAXES
,&axes
))
2022 lpDIDevCaps
->dwAxes
= axes
;
2024 #ifdef JSIOCGBUTTONS
2025 if (-1==ioctl(xfd
,JSIOCGAXES
,&buttons
))
2027 lpDIDevCaps
->dwButtons
= buttons
;
2029 if (xfd
!=This
->joyfd
)
2033 static HRESULT WINAPI
JoystickAImpl_Poll(LPDIRECTINPUTDEVICE2A iface
) {
2034 ICOM_THIS(JoystickAImpl
,iface
);
2035 TRACE("(),stub!\n");
2041 /******************************************************************************
2042 * EnumObjects : enumerate the different buttons and axis...
2044 static HRESULT WINAPI
JoystickAImpl_EnumObjects(
2045 LPDIRECTINPUTDEVICE2A iface
,
2046 LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback
,
2050 ICOM_THIS(JoystickAImpl
,iface
);
2051 DIDEVICEOBJECTINSTANCEA ddoi
;
2052 int xfd
= This
->joyfd
;
2054 TRACE("(this=%p,%p,%p,%08lx)\n", This
, lpCallback
, lpvRef
, dwFlags
);
2055 if (TRACE_ON(dinput
)) {
2056 DPRINTF(" - flags = ");
2057 _dump_EnumObjects_flags(dwFlags
);
2061 /* Only the fields till dwFFMaxForce are relevant */
2062 ddoi
.dwSize
= FIELD_OFFSET(DIDEVICEOBJECTINSTANCEA
, dwFFMaxForce
);
2064 /* For the joystick, do as is done in the GetCapabilities function */
2065 if ((dwFlags
== DIDFT_ALL
) ||
2066 (dwFlags
& DIDFT_AXIS
)) {
2070 if (-1==ioctl(xfd
,JSIOCGAXES
,&axes
))
2074 for (i
= 0; i
< axes
; i
++) {
2077 ddoi
.guidType
= GUID_XAxis
;
2078 ddoi
.dwOfs
= DIJOFS_X
;
2081 ddoi
.guidType
= GUID_YAxis
;
2082 ddoi
.dwOfs
= DIJOFS_Y
;
2085 ddoi
.guidType
= GUID_ZAxis
;
2086 ddoi
.dwOfs
= DIJOFS_Z
;
2089 ddoi
.guidType
= GUID_Unknown
;
2090 ddoi
.dwOfs
= DIJOFS_Z
+ (i
- 2) * sizeof(LONG
);
2092 ddoi
.dwType
= DIDFT_MAKEINSTANCE((0x0001 << i
) << WINE_JOYSTICK_AXIS_BASE
) | DIDFT_ABSAXIS
;
2093 sprintf(ddoi
.tszName
, "%d-Axis", i
);
2094 _dump_OBJECTINSTANCEA(&ddoi
);
2095 if (lpCallback(&ddoi
, lpvRef
) != DIENUM_CONTINUE
) return DI_OK
;
2099 if ((dwFlags
== DIDFT_ALL
) ||
2100 (dwFlags
& DIDFT_BUTTON
)) {
2103 #ifdef JSIOCGBUTTONS
2104 if (-1==ioctl(xfd
,JSIOCGAXES
,&buttons
))
2108 /* The DInput SDK says that GUID_Button is only for mouse buttons but well... */
2109 ddoi
.guidType
= GUID_Button
;
2111 for (i
= 0; i
< buttons
; i
++) {
2112 ddoi
.dwOfs
= DIJOFS_BUTTON(i
);
2113 ddoi
.dwType
= DIDFT_MAKEINSTANCE((0x0001 << i
) << WINE_JOYSTICK_BUTTON_BASE
) | DIDFT_PSHBUTTON
;
2114 sprintf(ddoi
.tszName
, "%d-Button", i
);
2115 _dump_OBJECTINSTANCEA(&ddoi
);
2116 if (lpCallback(&ddoi
, lpvRef
) != DIENUM_CONTINUE
) return DI_OK
;
2120 if (xfd
!=This
->joyfd
)
2126 /******************************************************************************
2127 * GetProperty : get input device properties
2129 static HRESULT WINAPI
JoystickAImpl_GetProperty(LPDIRECTINPUTDEVICE2A iface
,
2131 LPDIPROPHEADER pdiph
)
2133 ICOM_THIS(JoystickAImpl
,iface
);
2135 TRACE("(this=%p,%s,%p): stub!\n",
2136 iface
, debugstr_guid(rguid
), pdiph
);
2138 if (TRACE_ON(dinput
))
2139 _dump_DIPROPHEADER(pdiph
);
2141 if (!HIWORD(rguid
)) {
2142 switch ((DWORD
)rguid
) {
2143 case (DWORD
) DIPROP_BUFFERSIZE
: {
2144 LPDIPROPDWORD pd
= (LPDIPROPDWORD
)pdiph
;
2146 TRACE(" return buffersize = %d\n",This
->queue_len
);
2147 pd
->dwData
= This
->queue_len
;
2151 case (DWORD
) DIPROP_RANGE
: {
2152 LPDIPROPRANGE pr
= (LPDIPROPRANGE
) pdiph
;
2154 if ((pdiph
->dwHow
== DIPH_BYID
) &&
2155 (pdiph
->dwObj
& DIDFT_ABSAXIS
)) {
2156 /* The app is querying the current range of the axis : return the lMin and lMax values */
2157 pr
->lMin
= This
->lMin
;
2158 pr
->lMax
= This
->lMax
;
2165 FIXME("Unknown type %ld (%s)\n",(DWORD
)rguid
,debugstr_guid(rguid
));
2176 /****************************************************************************/
2177 /****************************************************************************/
2179 static ICOM_VTABLE(IDirectInputDevice2A
) SysKeyboardAvt
=
2181 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2182 IDirectInputDevice2AImpl_QueryInterface
,
2183 IDirectInputDevice2AImpl_AddRef
,
2184 IDirectInputDevice2AImpl_Release
,
2185 SysKeyboardAImpl_GetCapabilities
,
2186 IDirectInputDevice2AImpl_EnumObjects
,
2187 IDirectInputDevice2AImpl_GetProperty
,
2188 SysKeyboardAImpl_SetProperty
,
2189 SysKeyboardAImpl_Acquire
,
2190 SysKeyboardAImpl_Unacquire
,
2191 SysKeyboardAImpl_GetDeviceState
,
2192 SysKeyboardAImpl_GetDeviceData
,
2193 IDirectInputDevice2AImpl_SetDataFormat
,
2194 IDirectInputDevice2AImpl_SetEventNotification
,
2195 IDirectInputDevice2AImpl_SetCooperativeLevel
,
2196 IDirectInputDevice2AImpl_GetObjectInfo
,
2197 IDirectInputDevice2AImpl_GetDeviceInfo
,
2198 IDirectInputDevice2AImpl_RunControlPanel
,
2199 IDirectInputDevice2AImpl_Initialize
,
2200 IDirectInputDevice2AImpl_CreateEffect
,
2201 IDirectInputDevice2AImpl_EnumEffects
,
2202 IDirectInputDevice2AImpl_GetEffectInfo
,
2203 IDirectInputDevice2AImpl_GetForceFeedbackState
,
2204 IDirectInputDevice2AImpl_SendForceFeedbackCommand
,
2205 IDirectInputDevice2AImpl_EnumCreatedEffectObjects
,
2206 IDirectInputDevice2AImpl_Escape
,
2207 IDirectInputDevice2AImpl_Poll
,
2208 IDirectInputDevice2AImpl_SendDeviceData
,
2211 static ICOM_VTABLE(IDirectInputDevice2A
) SysMouseAvt
=
2213 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2214 IDirectInputDevice2AImpl_QueryInterface
,
2215 IDirectInputDevice2AImpl_AddRef
,
2216 SysMouseAImpl_Release
,
2217 SysMouseAImpl_GetCapabilities
,
2218 SysMouseAImpl_EnumObjects
,
2219 SysMouseAImpl_GetProperty
,
2220 SysMouseAImpl_SetProperty
,
2221 SysMouseAImpl_Acquire
,
2222 SysMouseAImpl_Unacquire
,
2223 SysMouseAImpl_GetDeviceState
,
2224 SysMouseAImpl_GetDeviceData
,
2225 SysMouseAImpl_SetDataFormat
,
2226 SysMouseAImpl_SetEventNotification
,
2227 SysMouseAImpl_SetCooperativeLevel
,
2228 IDirectInputDevice2AImpl_GetObjectInfo
,
2229 IDirectInputDevice2AImpl_GetDeviceInfo
,
2230 IDirectInputDevice2AImpl_RunControlPanel
,
2231 IDirectInputDevice2AImpl_Initialize
,
2232 IDirectInputDevice2AImpl_CreateEffect
,
2233 IDirectInputDevice2AImpl_EnumEffects
,
2234 IDirectInputDevice2AImpl_GetEffectInfo
,
2235 IDirectInputDevice2AImpl_GetForceFeedbackState
,
2236 IDirectInputDevice2AImpl_SendForceFeedbackCommand
,
2237 IDirectInputDevice2AImpl_EnumCreatedEffectObjects
,
2238 IDirectInputDevice2AImpl_Escape
,
2239 IDirectInputDevice2AImpl_Poll
,
2240 IDirectInputDevice2AImpl_SendDeviceData
,
2243 #ifdef HAVE_LINUX_22_JOYSTICK_API
2244 static ICOM_VTABLE(IDirectInputDevice2A
) JoystickAvt
=
2246 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2247 IDirectInputDevice2AImpl_QueryInterface
,
2248 IDirectInputDevice2AImpl_AddRef
,
2249 JoystickAImpl_Release
,
2250 JoystickAImpl_GetCapabilities
,
2251 JoystickAImpl_EnumObjects
,
2252 JoystickAImpl_GetProperty
,
2253 JoystickAImpl_SetProperty
,
2254 JoystickAImpl_Acquire
,
2255 JoystickAImpl_Unacquire
,
2256 JoystickAImpl_GetDeviceState
,
2257 JoystickAImpl_GetDeviceData
,
2258 JoystickAImpl_SetDataFormat
,
2259 JoystickAImpl_SetEventNotification
,
2260 IDirectInputDevice2AImpl_SetCooperativeLevel
,
2261 IDirectInputDevice2AImpl_GetObjectInfo
,
2262 IDirectInputDevice2AImpl_GetDeviceInfo
,
2263 IDirectInputDevice2AImpl_RunControlPanel
,
2264 IDirectInputDevice2AImpl_Initialize
,
2265 IDirectInputDevice2AImpl_CreateEffect
,
2266 IDirectInputDevice2AImpl_EnumEffects
,
2267 IDirectInputDevice2AImpl_GetEffectInfo
,
2268 IDirectInputDevice2AImpl_GetForceFeedbackState
,
2269 IDirectInputDevice2AImpl_SendForceFeedbackCommand
,
2270 IDirectInputDevice2AImpl_EnumCreatedEffectObjects
,
2271 IDirectInputDevice2AImpl_Escape
,
2273 IDirectInputDevice2AImpl_SendDeviceData
,