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"
48 #include "sysmetrics.h"
55 DEFAULT_DEBUG_CHANNEL(dinput
);
57 /* Wine mouse driver object instances */
58 #define WINE_MOUSE_X_AXIS_INSTANCE 0x0001
59 #define WINE_MOUSE_Y_AXIS_INSTANCE 0x0002
60 #define WINE_MOUSE_L_BUTTON_INSTANCE 0x0004
61 #define WINE_MOUSE_R_BUTTON_INSTANCE 0x0008
62 #define WINE_MOUSE_M_BUTTON_INSTANCE 0x0010
64 /* Wine joystick driver object instances */
65 #define WINE_JOYSTICK_AXIS_BASE 0
66 #define WINE_JOYSTICK_BUTTON_BASE 8
68 extern BYTE InputKeyStateTable
[256];
69 extern int min_keycode
, max_keycode
;
70 extern WORD keyc2vkey
[256];
72 /* Routines to do DataFormat / WineFormat conversions */
82 int internal_format_size
;
86 /* ------------------------------- */
87 /* Wine mouse internal data format */
88 /* ------------------------------- */
90 /* Constants used to access the offset array */
91 #define WINE_MOUSE_X_POSITION 0
92 #define WINE_MOUSE_Y_POSITION 1
93 #define WINE_MOUSE_L_POSITION 2
94 #define WINE_MOUSE_R_POSITION 3
95 #define WINE_MOUSE_M_POSITION 4
101 } Wine_InternalMouseData
;
103 #define WINE_INTERNALMOUSE_NUM_OBJS 5
105 static DIOBJECTDATAFORMAT Wine_InternalMouseObjectFormat
[WINE_INTERNALMOUSE_NUM_OBJS
] = {
106 { &GUID_XAxis
, FIELD_OFFSET(Wine_InternalMouseData
, lX
),
107 DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE
) | DIDFT_RELAXIS
, 0 },
108 { &GUID_YAxis
, FIELD_OFFSET(Wine_InternalMouseData
, lY
),
109 DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE
) | DIDFT_RELAXIS
, 0 },
110 { &GUID_Button
, (FIELD_OFFSET(Wine_InternalMouseData
, rgbButtons
)) + 0,
111 DIDFT_MAKEINSTANCE(WINE_MOUSE_L_BUTTON_INSTANCE
) | DIDFT_PSHBUTTON
, 0 },
112 { &GUID_Button
, (FIELD_OFFSET(Wine_InternalMouseData
, rgbButtons
)) + 1,
113 DIDFT_MAKEINSTANCE(WINE_MOUSE_R_BUTTON_INSTANCE
) | DIDFT_PSHBUTTON
, 0 },
114 { &GUID_Button
, (FIELD_OFFSET(Wine_InternalMouseData
, rgbButtons
)) + 2,
115 DIDFT_MAKEINSTANCE(WINE_MOUSE_M_BUTTON_INSTANCE
) | DIDFT_PSHBUTTON
, 0 }
118 static DIDATAFORMAT Wine_InternalMouseFormat
= {
119 0, /* dwSize - unused */
120 0, /* dwObjsize - unused */
121 0, /* dwFlags - unused */
122 sizeof(Wine_InternalMouseData
),
123 WINE_INTERNALMOUSE_NUM_OBJS
, /* dwNumObjs */
124 Wine_InternalMouseObjectFormat
127 static ICOM_VTABLE(IDirectInputA
) ddiavt
;
128 static ICOM_VTABLE(IDirectInputDevice2A
) SysKeyboardAvt
;
129 static ICOM_VTABLE(IDirectInputDevice2A
) SysMouseAvt
;
131 typedef struct IDirectInputAImpl IDirectInputAImpl
;
132 typedef struct IDirectInputDevice2AImpl IDirectInputDevice2AImpl
;
133 typedef struct SysKeyboardAImpl SysKeyboardAImpl
;
134 typedef struct SysMouseAImpl SysMouseAImpl
;
136 struct IDirectInputDevice2AImpl
138 ICOM_VFIELD(IDirectInputDevice2A
);
143 struct SysKeyboardAImpl
145 /* IDirectInputDevice2AImpl */
146 ICOM_VFIELD(IDirectInputDevice2A
);
149 /* SysKeyboardAImpl */
151 KEYBOARD_CONFIG initial_config
;
155 #ifdef HAVE_LINUX_22_JOYSTICK_API
156 typedef struct JoystickAImpl JoystickAImpl
;
157 static ICOM_VTABLE(IDirectInputDevice2A
) JoystickAvt
;
160 /* IDirectInputDevice2AImpl */
161 ICOM_VFIELD(IDirectInputDevice2A
);
165 /* joystick private */
169 LONG lMin
,lMax
,deadzone
;
170 LPDIDEVICEOBJECTDATA data_queue
;
171 int queue_pos
, queue_len
;
177 WARP_NEEDED
, /* Warping is needed */
178 WARP_STARTED
, /* Warping has been done, waiting for the warp event */
179 WARP_DONE
/* Warping has been done */
184 /* IDirectInputDevice2AImpl */
185 ICOM_VFIELD(IDirectInputDevice2A
);
189 /* The current data format and the conversion between internal
190 and external data formats */
197 /* Previous position for relative moves */
199 LPMOUSE_EVENT_PROC prev_handler
;
201 DWORD win_centerX
, win_centerY
;
202 LPDIDEVICEOBJECTDATA data_queue
;
203 int queue_pos
, queue_len
;
204 WARP_STATUS need_warp
;
207 CRITICAL_SECTION crit
;
209 /* This is for mouse reporting. */
210 Wine_InternalMouseData m_state
;
213 static int evsequence
=0;
216 /* UIDs for Wine "drivers".
217 When enumerating each device supporting DInput, they have two UIDs :
220 #ifdef HAVE_LINUX_22_JOYSTICK_API
221 static GUID DInput_Wine_Joystick_GUID
= { /* 9e573ed9-7734-11d2-8d4a-23903fb6bdf7 */
225 {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
228 static GUID DInput_Wine_Mouse_GUID
= { /* 9e573ed8-7734-11d2-8d4a-23903fb6bdf7 */
232 {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
234 static GUID DInput_Wine_Keyboard_GUID
= { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */
238 {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41}
241 /* FIXME: This is ugly and not thread safe :/ */
242 static IDirectInputDevice2A
* current_lock
= NULL
;
244 /******************************************************************************
245 * Various debugging tools
247 static void _dump_cooperativelevel(DWORD dwFlags
) {
253 #define FE(x) { x, #x},
257 FE(DISCL_NONEXCLUSIVE
)
260 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
261 if (flags
[i
].mask
& dwFlags
)
262 DPRINTF("%s ",flags
[i
].name
);
266 static void _dump_EnumObjects_flags(DWORD dwFlags
) {
272 #define FE(x) { x, #x},
279 FE(DIDFT_FFEFFECTTRIGGER
)
280 FE(DIDFT_NOCOLLECTION
)
289 if (dwFlags
== DIDFT_ALL
) {
290 DPRINTF("DIDFT_ALL");
293 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
294 if (flags
[i
].mask
& dwFlags
)
295 DPRINTF("%s ",flags
[i
].name
);
296 if (dwFlags
& DIDFT_INSTANCEMASK
)
297 DPRINTF("Instance(%04lx) ", dwFlags
>> 8);
300 static void _dump_DIPROPHEADER(DIPROPHEADER
*diph
) {
301 DPRINTF(" - dwObj = 0x%08lx\n", diph
->dwObj
);
302 DPRINTF(" - dwHow = %s\n",
303 ((diph
->dwHow
== DIPH_DEVICE
) ? "DIPH_DEVICE" :
304 ((diph
->dwHow
== DIPH_BYOFFSET
) ? "DIPH_BYOFFSET" :
305 ((diph
->dwHow
== DIPH_BYID
)) ? "DIPH_BYID" : "unknown")));
308 static void _dump_OBJECTINSTANCEA(DIDEVICEOBJECTINSTANCEA
*ddoi
) {
309 if (TRACE_ON(dinput
)) {
310 DPRINTF(" - enumerating : 0x%08lx - %2ld - 0x%08lx - %s\n",
311 ddoi
->guidType
.Data1
, ddoi
->dwOfs
, ddoi
->dwType
, ddoi
->tszName
);
315 struct IDirectInputAImpl
317 ICOM_VFIELD(IDirectInputA
);
321 /* Conversion between internal data buffer and external data buffer */
322 static void fill_DataFormat(void *out
, void *in
, DataFormat
*df
) {
324 char *in_c
= (char *) in
;
325 char *out_c
= (char *) out
;
327 if (df
->dt
== NULL
) {
328 /* This means that the app uses Wine's internal data format */
329 memcpy(out
, in
, df
->internal_format_size
);
331 for (i
= 0; i
< df
->size
; i
++) {
332 if (df
->dt
[i
].offset_in
>= 0) {
333 switch (df
->dt
[i
].size
) {
335 TRACE("Copying (c) to %d from %d (value %d)\n",
336 df
->dt
[i
].offset_out
, df
->dt
[i
].offset_in
, *((char *) (in_c
+ df
->dt
[i
].offset_in
)));
337 *((char *) (out_c
+ df
->dt
[i
].offset_out
)) = *((char *) (in_c
+ df
->dt
[i
].offset_in
));
341 TRACE("Copying (s) to %d from %d (value %d)\n",
342 df
->dt
[i
].offset_out
, df
->dt
[i
].offset_in
, *((short *) (in_c
+ df
->dt
[i
].offset_in
)));
343 *((short *) (out_c
+ df
->dt
[i
].offset_out
)) = *((short *) (in_c
+ df
->dt
[i
].offset_in
));
347 TRACE("Copying (i) to %d from %d (value %d)\n",
348 df
->dt
[i
].offset_out
, df
->dt
[i
].offset_in
, *((int *) (in_c
+ df
->dt
[i
].offset_in
)));
349 *((int *) (out_c
+ df
->dt
[i
].offset_out
)) = *((int *) (in_c
+ df
->dt
[i
].offset_in
));
353 memcpy((out_c
+ df
->dt
[i
].offset_out
), (in_c
+ df
->dt
[i
].offset_in
), df
->dt
[i
].size
);
356 switch (df
->dt
[i
].size
) {
358 TRACE("Copying (c) to %d default value %d\n",
359 df
->dt
[i
].offset_out
, df
->dt
[i
].value
);
360 *((char *) (out_c
+ df
->dt
[i
].offset_out
)) = (char) df
->dt
[i
].value
;
364 TRACE("Copying (s) to %d default value %d\n",
365 df
->dt
[i
].offset_out
, df
->dt
[i
].value
);
366 *((short *) (out_c
+ df
->dt
[i
].offset_out
)) = (short) df
->dt
[i
].value
;
370 TRACE("Copying (i) to %d default value %d\n",
371 df
->dt
[i
].offset_out
, df
->dt
[i
].value
);
372 *((int *) (out_c
+ df
->dt
[i
].offset_out
)) = (int) df
->dt
[i
].value
;
376 memset((out_c
+ df
->dt
[i
].offset_out
), df
->dt
[i
].size
, 0);
383 static DataFormat
*create_DataFormat(DIDATAFORMAT
*wine_format
, DIDATAFORMAT
*asked_format
, int *offset
) {
391 ret
= (DataFormat
*) HeapAlloc(GetProcessHeap(), 0, sizeof(DataFormat
));
393 done
= (int *) HeapAlloc(GetProcessHeap(), 0, sizeof(int) * asked_format
->dwNumObjs
);
394 memset(done
, 0, sizeof(int) * asked_format
->dwNumObjs
);
396 dt
= (DataTransform
*) HeapAlloc(GetProcessHeap(), 0, asked_format
->dwNumObjs
* sizeof(DataTransform
));
398 TRACE("Creating DataTransorm : \n");
400 for (i
= 0; i
< wine_format
->dwNumObjs
; i
++) {
403 for (j
= 0; j
< asked_format
->dwNumObjs
; j
++) {
407 if (((asked_format
->rgodf
[j
].pguid
== NULL
) || (IsEqualGUID(wine_format
->rgodf
[i
].pguid
, asked_format
->rgodf
[j
].pguid
)))
409 (wine_format
->rgodf
[i
].dwType
& asked_format
->rgodf
[j
].dwType
)) {
413 TRACE("Matching : \n");
414 TRACE(" - Asked (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n",
415 j
, debugstr_guid(asked_format
->rgodf
[j
].pguid
),
416 asked_format
->rgodf
[j
].dwOfs
,
417 DIDFT_GETTYPE(asked_format
->rgodf
[j
].dwType
), DIDFT_GETINSTANCE(asked_format
->rgodf
[j
].dwType
));
419 TRACE(" - Wine (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n",
420 j
, debugstr_guid(wine_format
->rgodf
[i
].pguid
),
421 wine_format
->rgodf
[i
].dwOfs
,
422 DIDFT_GETTYPE(wine_format
->rgodf
[i
].dwType
), DIDFT_GETINSTANCE(wine_format
->rgodf
[i
].dwType
));
424 if (wine_format
->rgodf
[i
].dwType
& DIDFT_BUTTON
)
425 dt
[index
].size
= sizeof(BYTE
);
427 dt
[index
].size
= sizeof(DWORD
);
428 dt
[index
].offset_in
= wine_format
->rgodf
[i
].dwOfs
;
429 dt
[index
].offset_out
= asked_format
->rgodf
[j
].dwOfs
;
433 if (wine_format
->rgodf
[i
].dwOfs
!= asked_format
->rgodf
[j
].dwOfs
)
436 offset
[i
] = asked_format
->rgodf
[j
].dwOfs
;
441 if (j
== asked_format
->dwNumObjs
)
445 TRACE("Setting to default value :\n");
446 for (j
= 0; j
< asked_format
->dwNumObjs
; j
++) {
448 TRACE(" - Asked (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n",
449 j
, debugstr_guid(asked_format
->rgodf
[j
].pguid
),
450 asked_format
->rgodf
[j
].dwOfs
,
451 DIDFT_GETTYPE(asked_format
->rgodf
[j
].dwType
), DIDFT_GETINSTANCE(asked_format
->rgodf
[j
].dwType
));
454 if (asked_format
->rgodf
[j
].dwType
& DIDFT_BUTTON
)
455 dt
[index
].size
= sizeof(BYTE
);
457 dt
[index
].size
= sizeof(DWORD
);
458 dt
[index
].offset_in
= -1;
459 dt
[index
].offset_out
= asked_format
->rgodf
[j
].dwOfs
;
467 ret
->internal_format_size
= wine_format
->dwDataSize
;
471 HeapFree(GetProcessHeap(), 0, dt
);
476 HeapFree(GetProcessHeap(), 0, done
);
481 /******************************************************************************
484 HRESULT WINAPI
DirectInputCreateA(HINSTANCE hinst
, DWORD dwVersion
, LPDIRECTINPUTA
*ppDI
, LPUNKNOWN punkOuter
)
486 IDirectInputAImpl
* This
;
487 TRACE("(0x%08lx,%04lx,%p,%p)\n",
488 (DWORD
)hinst
,dwVersion
,ppDI
,punkOuter
490 This
= (IDirectInputAImpl
*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl
));
492 ICOM_VTBL(This
) = &ddiavt
;
493 *ppDI
=(IDirectInputA
*)This
;
496 /******************************************************************************
497 * IDirectInputA_EnumDevices
499 static HRESULT WINAPI
IDirectInputAImpl_EnumDevices(
500 LPDIRECTINPUTA iface
, DWORD dwDevType
, LPDIENUMDEVICESCALLBACKA lpCallback
,
501 LPVOID pvRef
, DWORD dwFlags
504 ICOM_THIS(IDirectInputAImpl
,iface
);
505 DIDEVICEINSTANCEA devInstance
;
508 TRACE("(this=%p,0x%04lx,%p,%p,%04lx)\n", This
, dwDevType
, lpCallback
, pvRef
, dwFlags
);
510 devInstance
.dwSize
= sizeof(DIDEVICEINSTANCEA
);
511 if ((dwDevType
== 0) || (dwDevType
== DIDEVTYPE_KEYBOARD
)) {
512 /* Return keyboard */
513 devInstance
.guidInstance
= GUID_SysKeyboard
;/* DInput's GUID */
514 devInstance
.guidProduct
= DInput_Wine_Keyboard_GUID
; /* Vendor's GUID */
515 devInstance
.dwDevType
= DIDEVTYPE_KEYBOARD
| (DIDEVTYPEKEYBOARD_UNKNOWN
<< 8);
516 strcpy(devInstance
.tszInstanceName
, "Keyboard");
517 strcpy(devInstance
.tszProductName
, "Wine Keyboard");
519 ret
= lpCallback(&devInstance
, pvRef
);
520 TRACE("Keyboard registered\n");
521 if (ret
== DIENUM_STOP
)
525 if ((dwDevType
== 0) || (dwDevType
== DIDEVTYPE_MOUSE
)) {
527 devInstance
.guidInstance
= GUID_SysMouse
;/* DInput's GUID */
528 devInstance
.guidProduct
= DInput_Wine_Mouse_GUID
; /* Vendor's GUID */
529 devInstance
.dwDevType
= DIDEVTYPE_MOUSE
| (DIDEVTYPEMOUSE_UNKNOWN
<< 8);
530 strcpy(devInstance
.tszInstanceName
, "Mouse");
531 strcpy(devInstance
.tszProductName
, "Wine Mouse");
533 ret
= lpCallback(&devInstance
, pvRef
);
534 TRACE("Mouse registered\n");
535 if (ret
== DIENUM_STOP
)
538 if ((dwDevType
== 0) || (dwDevType
== DIDEVTYPE_JOYSTICK
)) {
539 /* check whether we have a joystick */
540 #ifdef HAVE_LINUX_22_JOYSTICK_API
541 if ( (access(JOYDEV
,O_RDONLY
)!=-1) ||
542 (errno
!=ENODEV
&& errno
!=ENOENT
)
544 /* Return joystick */
545 devInstance
.guidInstance
= GUID_Joystick
;
546 devInstance
.guidProduct
= DInput_Wine_Joystick_GUID
;
547 /* we only support traditional joysticks for now */
548 devInstance
.dwDevType
= DIDEVTYPE_JOYSTICK
| DIDEVTYPEJOYSTICK_TRADITIONAL
;
549 strcpy(devInstance
.tszInstanceName
, "Joystick");
550 /* ioctl JSIOCGNAME(len) */
551 strcpy(devInstance
.tszProductName
, "Wine Joystick");
553 ret
= lpCallback(&devInstance
,pvRef
);
554 TRACE("Joystick registered\n");
555 if (ret
== DIENUM_STOP
)
563 static ULONG WINAPI
IDirectInputAImpl_AddRef(LPDIRECTINPUTA iface
)
565 ICOM_THIS(IDirectInputAImpl
,iface
);
566 return ++(This
->ref
);
569 static ULONG WINAPI
IDirectInputAImpl_Release(LPDIRECTINPUTA iface
)
571 ICOM_THIS(IDirectInputAImpl
,iface
);
572 if (!(--This
->ref
)) {
573 HeapFree(GetProcessHeap(),0,This
);
579 static HRESULT WINAPI
IDirectInputAImpl_CreateDevice(
580 LPDIRECTINPUTA iface
,REFGUID rguid
,LPDIRECTINPUTDEVICEA
* pdev
,
583 ICOM_THIS(IDirectInputAImpl
,iface
);
585 TRACE("(this=%p,%s,%p,%p)\n",This
,debugstr_guid(rguid
),pdev
,punk
);
586 if ((IsEqualGUID(&GUID_SysKeyboard
,rguid
)) || /* Generic Keyboard */
587 (IsEqualGUID(&DInput_Wine_Keyboard_GUID
,rguid
))) { /* Wine Keyboard */
588 SysKeyboardAImpl
* newDevice
;
589 newDevice
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(SysKeyboardAImpl
));
591 ICOM_VTBL(newDevice
) = &SysKeyboardAvt
;
592 memcpy(&(newDevice
->guid
),rguid
,sizeof(*rguid
));
593 memset(newDevice
->keystate
,0,256);
594 *pdev
=(IDirectInputDeviceA
*)newDevice
;
596 TRACE("Creating a Keyboard device (%p)\n", newDevice
);
599 if ((IsEqualGUID(&GUID_SysMouse
,rguid
)) || /* Generic Mouse */
600 (IsEqualGUID(&DInput_Wine_Mouse_GUID
,rguid
))) { /* Wine Mouse */
601 SysMouseAImpl
* newDevice
;
602 int offset_array
[5] = {
603 FIELD_OFFSET(Wine_InternalMouseData
, lX
),
604 FIELD_OFFSET(Wine_InternalMouseData
, lY
),
605 FIELD_OFFSET(Wine_InternalMouseData
, rgbButtons
) + 0,
606 FIELD_OFFSET(Wine_InternalMouseData
, rgbButtons
) + 1,
607 FIELD_OFFSET(Wine_InternalMouseData
, rgbButtons
) + 2
610 newDevice
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(SysMouseAImpl
));
612 ICOM_VTBL(newDevice
) = &SysMouseAvt
;
613 InitializeCriticalSection(&(newDevice
->crit
));
614 MakeCriticalSectionGlobal(&(newDevice
->crit
));
615 memcpy(&(newDevice
->guid
),rguid
,sizeof(*rguid
));
616 *pdev
=(IDirectInputDeviceA
*)newDevice
;
618 /* Per default, Wine uses its internal data format */
619 newDevice
->df
= &Wine_InternalMouseFormat
;
620 memcpy(newDevice
->offset_array
, offset_array
, 5 * sizeof(int));
621 newDevice
->wine_df
= (DataFormat
*) HeapAlloc(GetProcessHeap(), 0, sizeof(DataFormat
));
622 newDevice
->wine_df
->size
= 0;
623 newDevice
->wine_df
->internal_format_size
= Wine_InternalMouseFormat
.dwDataSize
;
624 newDevice
->wine_df
->dt
= NULL
;
626 TRACE("Creating a Mouse device (%p)\n", newDevice
);
629 #ifdef HAVE_LINUX_22_JOYSTICK_API
630 if ((IsEqualGUID(&GUID_Joystick
,rguid
)) ||
631 (IsEqualGUID(&DInput_Wine_Joystick_GUID
,rguid
))) {
632 JoystickAImpl
* newDevice
;
633 newDevice
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(JoystickAImpl
));
635 ICOM_VTBL(newDevice
) = &JoystickAvt
;
636 newDevice
->joyfd
= -1;
637 newDevice
->lMin
= -32768;
638 newDevice
->lMax
= +32767;
639 memcpy(&(newDevice
->guid
),rguid
,sizeof(*rguid
));
640 *pdev
=(IDirectInputDeviceA
*)newDevice
;
642 TRACE("Creating a Joystick device (%p)\n", newDevice
);
649 static HRESULT WINAPI
IDirectInputAImpl_QueryInterface(
650 LPDIRECTINPUTA iface
,REFIID riid
,LPVOID
*ppobj
652 ICOM_THIS(IDirectInputAImpl
,iface
);
654 TRACE("(this=%p,%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
655 if (IsEqualGUID(&IID_IUnknown
,riid
)) {
656 IDirectInputA_AddRef(iface
);
660 if (IsEqualGUID(&IID_IDirectInputA
,riid
)) {
661 IDirectInputA_AddRef(iface
);
665 TRACE("Unsupported interface !\n");
669 static HRESULT WINAPI
IDirectInputAImpl_Initialize(
670 LPDIRECTINPUTA iface
,HINSTANCE hinst
,DWORD x
672 return DIERR_ALREADYINITIALIZED
;
675 static HRESULT WINAPI
IDirectInputAImpl_GetDeviceStatus(LPDIRECTINPUTA iface
,
677 ICOM_THIS(IDirectInputAImpl
,iface
);
679 FIXME("(%p)->(%s): stub\n",This
,debugstr_guid(rguid
));
684 static HRESULT WINAPI
IDirectInputAImpl_RunControlPanel(LPDIRECTINPUTA iface
,
687 ICOM_THIS(IDirectInputAImpl
,iface
);
688 FIXME("(%p)->(%08lx,%08lx): stub\n",This
, (DWORD
) hwndOwner
, dwFlags
);
693 static ICOM_VTABLE(IDirectInputA
) ddiavt
=
695 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
696 IDirectInputAImpl_QueryInterface
,
697 IDirectInputAImpl_AddRef
,
698 IDirectInputAImpl_Release
,
699 IDirectInputAImpl_CreateDevice
,
700 IDirectInputAImpl_EnumDevices
,
701 IDirectInputAImpl_GetDeviceStatus
,
702 IDirectInputAImpl_RunControlPanel
,
703 IDirectInputAImpl_Initialize
706 /******************************************************************************
707 * IDirectInputDeviceA
710 static HRESULT WINAPI
IDirectInputDevice2AImpl_SetDataFormat(
711 LPDIRECTINPUTDEVICE2A iface
,LPCDIDATAFORMAT df
715 TRACE(dinput,"(this=%p,%p)\n",This,df);
717 TRACE(dinput,"df.dwSize=%ld\n",df->dwSize);
718 TRACE(dinput,"(df.dwObjsize=%ld)\n",df->dwObjSize);
719 TRACE(dinput,"(df.dwFlags=0x%08lx)\n",df->dwFlags);
720 TRACE(dinput,"(df.dwDataSize=%ld)\n",df->dwDataSize);
721 TRACE(dinput,"(df.dwNumObjs=%ld)\n",df->dwNumObjs);
723 for (i=0;i<df->dwNumObjs;i++) {
724 TRACE(dinput,"df.rgodf[%d].guid %s\n",i,debugstr_guid(df->rgodf[i].pguid));
725 TRACE(dinput,"df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
726 TRACE(dinput,"dwType 0x%02lx,dwInstance %ld\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
727 TRACE(dinput,"df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
733 static HRESULT WINAPI
IDirectInputDevice2AImpl_SetCooperativeLevel(
734 LPDIRECTINPUTDEVICE2A iface
,HWND hwnd
,DWORD dwflags
736 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
737 TRACE("(this=%p,0x%08lx,0x%08lx)\n",This
,(DWORD
)hwnd
,dwflags
);
738 if (TRACE_ON(dinput
))
739 _dump_cooperativelevel(dwflags
);
743 static HRESULT WINAPI
IDirectInputDevice2AImpl_SetEventNotification(
744 LPDIRECTINPUTDEVICE2A iface
,HANDLE hnd
746 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
747 FIXME("(this=%p,0x%08lx): stub\n",This
,(DWORD
)hnd
);
751 static ULONG WINAPI
IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE2A iface
)
753 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
757 HeapFree(GetProcessHeap(),0,This
);
761 static HRESULT WINAPI
SysKeyboardAImpl_SetProperty(
762 LPDIRECTINPUTDEVICE2A iface
,REFGUID rguid
,LPCDIPROPHEADER ph
765 ICOM_THIS(SysKeyboardAImpl
,iface
);
767 TRACE("(this=%p,%s,%p)\n",This
,debugstr_guid(rguid
),ph
);
768 TRACE("(size=%ld,headersize=%ld,obj=%ld,how=%ld\n",
769 ph
->dwSize
,ph
->dwHeaderSize
,ph
->dwObj
,ph
->dwHow
);
770 if (!HIWORD(rguid
)) {
771 switch ((DWORD
)rguid
) {
772 case (DWORD
) DIPROP_BUFFERSIZE
: {
773 LPCDIPROPDWORD pd
= (LPCDIPROPDWORD
)ph
;
775 TRACE("(buffersize=%ld)\n",pd
->dwData
);
779 WARN("Unknown type %ld\n",(DWORD
)rguid
);
786 static HRESULT WINAPI
SysKeyboardAImpl_GetDeviceState(
787 LPDIRECTINPUTDEVICE2A iface
,DWORD len
,LPVOID ptr
790 return USER_Driver
->pGetDIState(len
, ptr
)?DI_OK
:E_FAIL
;
793 static HRESULT WINAPI
SysKeyboardAImpl_GetDeviceData(
794 LPDIRECTINPUTDEVICE2A iface
,DWORD dodsize
,LPDIDEVICEOBJECTDATA dod
,
795 LPDWORD entries
,DWORD flags
798 ICOM_THIS(SysKeyboardAImpl
,iface
);
802 TRACE("(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n",
803 This
,dodsize
,dod
,entries
,entries
?*entries
:0,flags
);
805 ret
=USER_Driver
->pGetDIData(
806 This
->keystate
, dodsize
, dod
, entries
, flags
)?DI_OK
:E_FAIL
;
807 for (i
=0;i
<*entries
;i
++) {
808 dod
[i
].dwTimeStamp
= GetTickCount();
809 dod
[i
].dwSequence
= evsequence
++;
814 static HRESULT WINAPI
SysKeyboardAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface
)
816 ICOM_THIS(SysKeyboardAImpl
,iface
);
818 TRACE("(this=%p)\n",This
);
820 if (This
->acquired
== 0) {
821 KEYBOARD_CONFIG no_auto
;
823 /* Save the original config */
824 USER_Driver
->pGetKeyboardConfig(&(This
->initial_config
));
826 /* Now, remove auto-repeat */
827 no_auto
.auto_repeat
= FALSE
;
828 USER_Driver
->pSetKeyboardConfig(&no_auto
, WINE_KEYBOARD_CONFIG_AUTO_REPEAT
);
836 static HRESULT WINAPI
SysKeyboardAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface
)
838 ICOM_THIS(SysKeyboardAImpl
,iface
);
839 TRACE("(this=%p)\n",This
);
841 if (This
->acquired
== 1) {
842 /* Restore the original configuration */
843 USER_Driver
->pSetKeyboardConfig(&(This
->initial_config
), 0xFFFFFFFF);
846 ERR("Unacquiring a not-acquired device !!!\n");
852 /******************************************************************************
853 * GetCapabilities : get the device capablitites
855 static HRESULT WINAPI
SysKeyboardAImpl_GetCapabilities(
856 LPDIRECTINPUTDEVICE2A iface
,
857 LPDIDEVCAPS lpDIDevCaps
)
859 ICOM_THIS(SysMouseAImpl
,iface
);
861 TRACE("(this=%p,%p)\n",This
,lpDIDevCaps
);
863 if (lpDIDevCaps
->dwSize
== sizeof(DIDEVCAPS
)) {
864 lpDIDevCaps
->dwFlags
= DIDC_ATTACHED
;
865 lpDIDevCaps
->dwDevType
= DIDEVTYPE_KEYBOARD
;
866 lpDIDevCaps
->dwAxes
= 0;
867 lpDIDevCaps
->dwButtons
= 0;
868 lpDIDevCaps
->dwPOVs
= 0;
869 lpDIDevCaps
->dwFFSamplePeriod
= 0;
870 lpDIDevCaps
->dwFFMinTimeResolution
= 0;
871 lpDIDevCaps
->dwFirmwareRevision
= 100;
872 lpDIDevCaps
->dwHardwareRevision
= 100;
873 lpDIDevCaps
->dwFFDriverVersion
= 0;
876 FIXME("DirectX 3.0 not supported....\n");
882 static HRESULT WINAPI
IDirectInputDevice2AImpl_QueryInterface(
883 LPDIRECTINPUTDEVICE2A iface
,REFIID riid
,LPVOID
*ppobj
886 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
888 TRACE("(this=%p,%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
889 if (IsEqualGUID(&IID_IUnknown
,riid
)) {
890 IDirectInputDevice2_AddRef(iface
);
894 if (IsEqualGUID(&IID_IDirectInputDeviceA
,riid
)) {
895 IDirectInputDevice2_AddRef(iface
);
899 if (IsEqualGUID(&IID_IDirectInputDevice2A
,riid
)) {
900 IDirectInputDevice2_AddRef(iface
);
904 TRACE("Unsupported interface !\n");
908 static ULONG WINAPI
IDirectInputDevice2AImpl_AddRef(
909 LPDIRECTINPUTDEVICE2A iface
)
911 ICOM_THIS(IDirectInputDevice2AImpl
,iface
);
915 static HRESULT WINAPI
IDirectInputDevice2AImpl_EnumObjects(
916 LPDIRECTINPUTDEVICE2A iface
,
917 LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback
,
921 FIXME("(this=%p,%p,%p,%08lx): stub!\n", iface
, lpCallback
, lpvRef
, dwFlags
);
922 if (TRACE_ON(dinput
)) {
923 DPRINTF(" - flags = ");
924 _dump_EnumObjects_flags(dwFlags
);
931 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetProperty(
932 LPDIRECTINPUTDEVICE2A iface
,
934 LPDIPROPHEADER pdiph
)
936 FIXME("(this=%p,%s,%p): stub!\n",
937 iface
, debugstr_guid(rguid
), pdiph
);
939 if (TRACE_ON(dinput
))
940 _dump_DIPROPHEADER(pdiph
);
945 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetObjectInfo(
946 LPDIRECTINPUTDEVICE2A iface
,
947 LPDIDEVICEOBJECTINSTANCEA pdidoi
,
951 FIXME("(this=%p,%p,%ld,0x%08lx): stub!\n",
952 iface
, pdidoi
, dwObj
, dwHow
);
957 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetDeviceInfo(
958 LPDIRECTINPUTDEVICE2A iface
,
959 LPDIDEVICEINSTANCEA pdidi
)
961 FIXME("(this=%p,%p): stub!\n",
967 static HRESULT WINAPI
IDirectInputDevice2AImpl_RunControlPanel(
968 LPDIRECTINPUTDEVICE2A iface
,
972 FIXME("(this=%p,0x%08x,0x%08lx): stub!\n",
973 iface
, hwndOwner
, dwFlags
);
978 static HRESULT WINAPI
IDirectInputDevice2AImpl_Initialize(
979 LPDIRECTINPUTDEVICE2A iface
,
984 FIXME("(this=%p,%d,%ld,%s): stub!\n",
985 iface
, hinst
, dwVersion
, debugstr_guid(rguid
));
989 /******************************************************************************
990 * IDirectInputDevice2A
993 static HRESULT WINAPI
IDirectInputDevice2AImpl_CreateEffect(
994 LPDIRECTINPUTDEVICE2A iface
,
997 LPDIRECTINPUTEFFECT
*ppdef
,
1000 FIXME("(this=%p,%s,%p,%p,%p): stub!\n",
1001 iface
, debugstr_guid(rguid
), lpeff
, ppdef
, pUnkOuter
);
1005 static HRESULT WINAPI
IDirectInputDevice2AImpl_EnumEffects(
1006 LPDIRECTINPUTDEVICE2A iface
,
1007 LPDIENUMEFFECTSCALLBACKA lpCallback
,
1011 FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
1012 iface
, lpCallback
, lpvRef
, dwFlags
);
1015 lpCallback(NULL
, lpvRef
);
1019 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetEffectInfo(
1020 LPDIRECTINPUTDEVICE2A iface
,
1021 LPDIEFFECTINFOA lpdei
,
1024 FIXME("(this=%p,%p,%s): stub!\n",
1025 iface
, lpdei
, debugstr_guid(rguid
));
1029 static HRESULT WINAPI
IDirectInputDevice2AImpl_GetForceFeedbackState(
1030 LPDIRECTINPUTDEVICE2A iface
,
1033 FIXME("(this=%p,%p): stub!\n",
1038 static HRESULT WINAPI
IDirectInputDevice2AImpl_SendForceFeedbackCommand(
1039 LPDIRECTINPUTDEVICE2A iface
,
1042 FIXME("(this=%p,0x%08lx): stub!\n",
1047 static HRESULT WINAPI
IDirectInputDevice2AImpl_EnumCreatedEffectObjects(
1048 LPDIRECTINPUTDEVICE2A iface
,
1049 LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback
,
1053 FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
1054 iface
, lpCallback
, lpvRef
, dwFlags
);
1056 lpCallback(NULL
, lpvRef
);
1060 static HRESULT WINAPI
IDirectInputDevice2AImpl_Escape(
1061 LPDIRECTINPUTDEVICE2A iface
,
1062 LPDIEFFESCAPE lpDIEEsc
)
1064 FIXME("(this=%p,%p): stub!\n",
1069 static HRESULT WINAPI
IDirectInputDevice2AImpl_Poll(
1070 LPDIRECTINPUTDEVICE2A iface
)
1072 FIXME("(this=%p): stub!\n",
1077 static HRESULT WINAPI
IDirectInputDevice2AImpl_SendDeviceData(
1078 LPDIRECTINPUTDEVICE2A iface
,
1080 LPDIDEVICEOBJECTDATA rgdod
,
1084 FIXME("(this=%p,0x%08lx,%p,%p,0x%08lx): stub!\n",
1085 iface
, cbObjectData
, rgdod
, pdwInOut
, dwFlags
);
1090 /******************************************************************************
1091 * SysMouseA (DInput Mouse support)
1094 /******************************************************************************
1095 * Release : release the mouse buffer.
1097 static ULONG WINAPI
SysMouseAImpl_Release(LPDIRECTINPUTDEVICE2A iface
)
1099 ICOM_THIS(SysMouseAImpl
,iface
);
1105 /* Free the data queue */
1106 if (This
->data_queue
!= NULL
)
1107 HeapFree(GetProcessHeap(),0,This
->data_queue
);
1109 /* Install the previous event handler (in case of releasing an aquired
1111 if (This
->prev_handler
!= NULL
)
1112 MOUSE_Enable(This
->prev_handler
);
1113 DeleteCriticalSection(&(This
->crit
));
1115 /* Free the DataFormat */
1116 if (This
->df
!= &(Wine_InternalMouseFormat
)) {
1117 HeapFree(GetProcessHeap(), 0, This
->df
->rgodf
);
1118 HeapFree(GetProcessHeap(), 0, This
->df
);
1121 HeapFree(GetProcessHeap(),0,This
);
1126 /******************************************************************************
1127 * SetCooperativeLevel : store the window in which we will do our
1130 static HRESULT WINAPI
SysMouseAImpl_SetCooperativeLevel(
1131 LPDIRECTINPUTDEVICE2A iface
,HWND hwnd
,DWORD dwflags
1134 ICOM_THIS(SysMouseAImpl
,iface
);
1136 TRACE("(this=%p,0x%08lx,0x%08lx)\n",This
,(DWORD
)hwnd
,dwflags
);
1138 if (TRACE_ON(dinput
))
1139 _dump_cooperativelevel(dwflags
);
1141 /* Store the window which asks for the mouse */
1148 /******************************************************************************
1149 * SetDataFormat : the application can choose the format of the data
1150 * the device driver sends back with GetDeviceState.
1152 * For the moment, only the "standard" configuration (c_dfDIMouse) is supported
1153 * in absolute and relative mode.
1155 static HRESULT WINAPI
SysMouseAImpl_SetDataFormat(
1156 LPDIRECTINPUTDEVICE2A iface
,LPCDIDATAFORMAT df
1159 ICOM_THIS(SysMouseAImpl
,iface
);
1162 TRACE("(this=%p,%p)\n",This
,df
);
1164 TRACE("(df.dwSize=%ld)\n",df
->dwSize
);
1165 TRACE("(df.dwObjsize=%ld)\n",df
->dwObjSize
);
1166 TRACE("(df.dwFlags=0x%08lx)\n",df
->dwFlags
);
1167 TRACE("(df.dwDataSize=%ld)\n",df
->dwDataSize
);
1168 TRACE("(df.dwNumObjs=%ld)\n",df
->dwNumObjs
);
1170 for (i
=0;i
<df
->dwNumObjs
;i
++) {
1172 TRACE("df.rgodf[%d].guid %s (%p)\n",i
, debugstr_guid(df
->rgodf
[i
].pguid
), df
->rgodf
[i
].pguid
);
1173 TRACE("df.rgodf[%d].dwOfs %ld\n",i
,df
->rgodf
[i
].dwOfs
);
1174 TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df
->rgodf
[i
].dwType
),DIDFT_GETINSTANCE(df
->rgodf
[i
].dwType
));
1175 TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i
,df
->rgodf
[i
].dwFlags
);
1178 /* Check if the mouse is in absolute or relative mode */
1179 if (df
->dwFlags
== DIDF_ABSAXIS
)
1181 else if (df
->dwFlags
== DIDF_RELAXIS
)
1184 ERR("Neither absolute nor relative flag set.");
1186 /* Store the new data format */
1187 This
->df
= HeapAlloc(GetProcessHeap(),0,df
->dwSize
);
1188 memcpy(This
->df
, df
, df
->dwSize
);
1189 This
->df
->rgodf
= HeapAlloc(GetProcessHeap(),0,df
->dwNumObjs
*df
->dwObjSize
);
1190 memcpy(This
->df
->rgodf
,df
->rgodf
,df
->dwNumObjs
*df
->dwObjSize
);
1192 /* Prepare all the data-conversion filters */
1193 This
->wine_df
= create_DataFormat(&(Wine_InternalMouseFormat
), df
, This
->offset_array
);
1198 #define GEN_EVENT(offset,data,xtime,seq) \
1200 /* If queue_len > 0, queuing is requested -> TRACE the event queued */ \
1201 if (This->queue_len > 0) { \
1202 TRACE(" queueing %d at offset %d (queue pos %d / size %d)\n", \
1203 (int) (data), (int) (offset), \
1204 (int) (This->queue_pos), (int) (This->queue_len)); \
1206 if ((offset >= 0) && (This->queue_pos < This->queue_len)) { \
1207 This->data_queue[This->queue_pos].dwOfs = offset; \
1208 This->data_queue[This->queue_pos].dwData = data; \
1209 This->data_queue[This->queue_pos].dwTimeStamp = xtime; \
1210 This->data_queue[This->queue_pos].dwSequence = seq; \
1211 This->queue_pos++; \
1217 /* Our private mouse event handler */
1218 static void WINAPI
dinput_mouse_event( DWORD dwFlags
, DWORD dx
, DWORD dy
,
1219 DWORD cButtons
, DWORD dwExtraInfo
)
1221 long posX
= -1, posY
= -1;
1222 DWORD keyState
, xtime
, extra
;
1223 SysMouseAImpl
* This
= (SysMouseAImpl
*) current_lock
;
1225 EnterCriticalSection(&(This
->crit
));
1226 /* Mouse moved -> send event if asked */
1228 SetEvent(This
->hEvent
);
1230 if ( !IsBadReadPtr( (LPVOID
)dwExtraInfo
, sizeof(WINE_MOUSEEVENT
) )
1231 && ((WINE_MOUSEEVENT
*)dwExtraInfo
)->magic
== WINE_MOUSEEVENT_MAGIC
) {
1232 WINE_MOUSEEVENT
*wme
= (WINE_MOUSEEVENT
*)dwExtraInfo
;
1233 keyState
= wme
->keyState
;
1235 extra
= (DWORD
)wme
->hWnd
;
1237 if (dwFlags
& MOUSEEVENTF_MOVE
) {
1238 if (dwFlags
& MOUSEEVENTF_ABSOLUTE
) {
1239 posX
= (dx
* GetSystemMetrics(SM_CXSCREEN
)) >> 16;
1240 posY
= (dy
* GetSystemMetrics(SM_CYSCREEN
)) >> 16;
1242 if (This
->absolute
) {
1243 if (posX
!= This
->prevX
)
1244 GEN_EVENT(This
->offset_array
[WINE_MOUSE_X_POSITION
], posX
, xtime
, 0);
1245 if (posY
!= This
->prevY
)
1246 GEN_EVENT(This
->offset_array
[WINE_MOUSE_Y_POSITION
], posY
, xtime
, 0);
1248 /* Now, warp handling */
1249 if ((This
->need_warp
== WARP_STARTED
) &&
1250 (posX
== This
->win_centerX
) && (posX
== This
->win_centerX
)) {
1251 /* Warp has been done... */
1252 This
->need_warp
= WARP_DONE
;
1253 LeaveCriticalSection(&(This
->crit
));
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 USER_Driver
->pMoveCursor( 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 USER_Driver
->pMoveCursor( 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 USER_Driver
->pMoveCursor( 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
,
2277 /***********************************************************************
2278 * DllCanUnloadNow (DINPUT.@)
2280 HRESULT WINAPI
DINPUT_DllCanUnloadNow(void)
2282 FIXME("(void): stub\n");
2287 /***********************************************************************
2288 * DllGetClassObject (DINPUT.@)
2290 HRESULT WINAPI
DINPUT_DllGetClassObject(REFCLSID rclsid
, REFIID riid
,
2293 FIXME("(%p, %p, %p): stub\n", debugstr_guid(rclsid
),
2294 debugstr_guid(riid
), ppv
);
2296 return CLASS_E_CLASSNOTAVAILABLE
;
2299 /***********************************************************************
2300 * DllRegisterServer (DINPUT.@)
2302 HRESULT WINAPI
DINPUT_DllRegisterServer(void)
2304 FIXME("(void): stub\n");
2309 /***********************************************************************
2310 * DllUnregisterServer (DINPUT.@)
2312 HRESULT WINAPI
DINPUT_DllUnregisterServer(void)
2314 FIXME("(void): stub\n");