ReactOS 0.4.15-dev-8227-g32d615f
joystick_linux.c
Go to the documentation of this file.
1/* DirectInput Joystick device
2 *
3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998,1999 Lionel Ulmer
5 * Copyright 2000-2001 TransGaming Technologies Inc.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22/*
23 * To Do:
24 * dead zone
25 * force feedback
26 */
27
28#include "config.h"
29#include "wine/port.h"
30
31#include <stdarg.h>
32#include <stdio.h>
33#include <string.h>
34#include <time.h>
35#ifdef HAVE_UNISTD_H
36# include <unistd.h>
37#endif
38#ifdef HAVE_SYS_TIME_H
39# include <sys/time.h>
40#endif
41#include <fcntl.h>
42#ifdef HAVE_SYS_IOCTL_H
43# include <sys/ioctl.h>
44#endif
45#include <errno.h>
46#ifdef HAVE_LINUX_IOCTL_H
47# include <linux/ioctl.h>
48#endif
49#ifdef HAVE_LINUX_JOYSTICK_H
50# include <linux/joystick.h>
51# undef SW_MAX
52#endif
53#ifdef HAVE_SYS_POLL_H
54# include <sys/poll.h>
55#endif
56
57#include "wine/debug.h"
58#include "wine/unicode.h"
59#include "windef.h"
60#include "winbase.h"
61#include "winerror.h"
62#include "devguid.h"
63#include "dinput.h"
64
65#include "dinput_private.h"
66#include "device_private.h"
67#include "joystick_private.h"
68
69#ifdef HAVE_LINUX_22_JOYSTICK_API
70
72
73#define JOYDEV_NEW "/dev/input/js"
74#define JOYDEV_OLD "/dev/js"
75#define JOYDEVDRIVER " (js)"
76
77struct JoyDev
78{
79 char device[MAX_PATH];
80 char name[MAX_PATH];
81 GUID guid_product;
82
83 BYTE axis_count;
84 BYTE button_count;
85 int *dev_axes_map;
86
87 WORD vendor_id, product_id, bus_type;
88
89 BOOL is_joystick;
90};
91
92typedef struct JoystickImpl JoystickImpl;
93static const IDirectInputDevice8AVtbl JoystickAvt;
94static const IDirectInputDevice8WVtbl JoystickWvt;
95struct JoystickImpl
96{
98
99 struct JoyDev *joydev;
100
101 /* joystick private */
102 int joyfd;
103 POINTL povs[4];
104};
105
106static inline JoystickImpl *impl_from_IDirectInputDevice8A(IDirectInputDevice8A *iface)
107{
108 return CONTAINING_RECORD(CONTAINING_RECORD(CONTAINING_RECORD(iface, IDirectInputDeviceImpl, IDirectInputDevice8A_iface),
109 JoystickGenericImpl, base), JoystickImpl, generic);
110}
111static inline JoystickImpl *impl_from_IDirectInputDevice8W(IDirectInputDevice8W *iface)
112{
113 return CONTAINING_RECORD(CONTAINING_RECORD(CONTAINING_RECORD(iface, IDirectInputDeviceImpl, IDirectInputDevice8W_iface),
114 JoystickGenericImpl, base), JoystickImpl, generic);
115}
116
117static inline IDirectInputDevice8W *IDirectInputDevice8W_from_impl(JoystickImpl *This)
118{
119 return &This->generic.base.IDirectInputDevice8W_iface;
120}
121
122static const GUID DInput_Wine_Joystick_GUID = { /* 9e573ed9-7734-11d2-8d4a-23903fb6bdf7 */
123 0x9e573ed9,
124 0x7734,
125 0x11d2,
126 {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
127};
128
129#define MAX_JOYSTICKS 64
130static INT joystick_devices_count = -1;
131static struct JoyDev *joystick_devices;
132
133static void joy_polldev(LPDIRECTINPUTDEVICE8A iface);
134
135#define SYS_PATH_FORMAT "/sys/class/input/js%d/device/id/%s"
136static BOOL read_sys_id_variable(int index, const char *property, WORD *value)
137{
138 char sys_path[sizeof(SYS_PATH_FORMAT) + 16], id_str[5];
139 int sys_fd;
140 BOOL ret = FALSE;
141
142 sprintf(sys_path, SYS_PATH_FORMAT, index, property);
143 if ((sys_fd = open(sys_path, O_RDONLY)) != -1)
144 {
145 if (read(sys_fd, id_str, 4) == 4)
146 {
147 id_str[4] = '\0';
148 *value = strtol(id_str, NULL, 16);
149 ret = TRUE;
150 }
151
152 close(sys_fd);
153 }
154 return ret;
155}
156#undef SYS_PATH_FORMAT
157
158static INT find_joystick_devices(void)
159{
160 INT i;
161
162 if (joystick_devices_count != -1) return joystick_devices_count;
163
164 joystick_devices_count = 0;
165 for (i = 0; i < MAX_JOYSTICKS; i++)
166 {
167 int fd;
168 struct JoyDev joydev, *new_joydevs;
169 BYTE axes_map[ABS_MAX + 1];
170 SHORT btn_map[KEY_MAX - BTN_MISC + 1];
171 BOOL is_stylus = FALSE;
172
173 snprintf(joydev.device, sizeof(joydev.device), "%s%d", JOYDEV_NEW, i);
174 if ((fd = open(joydev.device, O_RDONLY)) == -1)
175 {
176 snprintf(joydev.device, sizeof(joydev.device), "%s%d", JOYDEV_OLD, i);
177 if ((fd = open(joydev.device, O_RDONLY)) == -1) continue;
178 }
179
180 strcpy(joydev.name, "Wine Joystick");
181#if defined(JSIOCGNAME)
182 if (ioctl(fd, JSIOCGNAME(sizeof(joydev.name) - sizeof(JOYDEVDRIVER)), joydev.name) < 0)
183 WARN("ioctl(%s,JSIOCGNAME) failed: %s\n", joydev.device, strerror(errno));
184#endif
185
186 /* Append driver name */
187 strcat(joydev.name, JOYDEVDRIVER);
188
189 if (device_disabled_registry(joydev.name)) {
190 close(fd);
191 continue;
192 }
193
194#ifdef JSIOCGAXES
195 if (ioctl(fd, JSIOCGAXES, &joydev.axis_count) < 0)
196 {
197 WARN("ioctl(%s,JSIOCGAXES) failed: %s, defaulting to 2\n", joydev.device, strerror(errno));
198 joydev.axis_count = 2;
199 }
200#else
201 WARN("reading number of joystick axes unsupported in this platform, defaulting to 2\n");
202 joydev.axis_count = 2;
203#endif
204#ifdef JSIOCGBUTTONS
205 if (ioctl(fd, JSIOCGBUTTONS, &joydev.button_count) < 0)
206 {
207 WARN("ioctl(%s,JSIOCGBUTTONS) failed: %s, defaulting to 2\n", joydev.device, strerror(errno));
208 joydev.button_count = 2;
209 }
210#else
211 WARN("reading number of joystick buttons unsupported in this platform, defaulting to 2\n");
212 joydev.button_count = 2;
213#endif
214
215 joydev.is_joystick = FALSE;
216 if (ioctl(fd, JSIOCGBTNMAP, btn_map) < 0)
217 {
218 WARN("ioctl(%s,JSIOCGBTNMAP) failed: %s\n", joydev.device, strerror(errno));
219 }
220 else
221 {
222 INT j;
223 /* in lieu of properly reporting HID usage, detect presence of
224 * "joystick buttons" and report those devices as joysticks instead of
225 * gamepads */
226 for (j = 0; !joydev.is_joystick && j < joydev.button_count; j++)
227 {
228 switch (btn_map[j])
229 {
230 case BTN_TRIGGER:
231 case BTN_THUMB:
232 case BTN_THUMB2:
233 case BTN_TOP:
234 case BTN_TOP2:
235 case BTN_PINKIE:
236 case BTN_BASE:
237 case BTN_BASE2:
238 case BTN_BASE3:
239 case BTN_BASE4:
240 case BTN_BASE5:
241 case BTN_BASE6:
242 case BTN_DEAD:
243 joydev.is_joystick = TRUE;
244 break;
245 case BTN_STYLUS:
246 is_stylus = TRUE;
247 break;
248 default:
249 break;
250 }
251 }
252 }
253
254 if(is_stylus)
255 {
256 TRACE("Stylus detected. Skipping\n");
257 close(fd);
258 continue;
259 }
260
261 if (ioctl(fd, JSIOCGAXMAP, axes_map) < 0)
262 {
263 WARN("ioctl(%s,JSIOCGAXMAP) failed: %s\n", joydev.device, strerror(errno));
264 joydev.dev_axes_map = NULL;
265 }
266 else
267 if ((joydev.dev_axes_map = HeapAlloc(GetProcessHeap(), 0, joydev.axis_count * sizeof(int))))
268 {
269 INT j, found_axes = 0;
270
271 /* Remap to DI numbers */
272 for (j = 0; j < joydev.axis_count; j++)
273 {
274 if (axes_map[j] < 8)
275 {
276 /* Axis match 1-to-1 */
277 joydev.dev_axes_map[j] = j;
278 found_axes++;
279 }
280 else if (axes_map[j] <= 10)
281 {
282 /* Axes 8 through 10 are Wheel, Gas and Brake,
283 * remap to 0, 1 and 2
284 */
285 joydev.dev_axes_map[j] = axes_map[j] - 8;
286 found_axes++;
287 }
288 else if (axes_map[j] == 16 ||
289 axes_map[j] == 17)
290 {
291 /* POV axis */
292 joydev.dev_axes_map[j] = 8;
293 found_axes++;
294 }
295 else
296 joydev.dev_axes_map[j] = -1;
297 }
298
299 /* If no axes were configured but there are axes assume a 1-to-1 (wii controller) */
300 if (joydev.axis_count && !found_axes)
301 {
302 int axes_limit = min(joydev.axis_count, 8); /* generic driver limit */
303
304 ERR("Incoherent joystick data, advertised %d axes, detected 0. Assuming 1-to-1.\n",
305 joydev.axis_count);
306 for (j = 0; j < axes_limit; j++)
307 joydev.dev_axes_map[j] = j;
308
309 joydev.axis_count = axes_limit;
310 }
311 }
312
313 /* Find vendor_id and product_id in sysfs */
314 joydev.vendor_id = 0;
315 joydev.product_id = 0;
316
317 read_sys_id_variable(i, "vendor", &joydev.vendor_id);
318 read_sys_id_variable(i, "product", &joydev.product_id);
319 read_sys_id_variable(i, "bustype", &joydev.bus_type);
320
321 if (joydev.vendor_id == 0 || joydev.product_id == 0)
322 {
323 joydev.guid_product = DInput_Wine_Joystick_GUID;
324 }
325 else
326 {
327 /* Concatenate product_id with vendor_id to mimic Windows behaviour */
328 joydev.guid_product = DInput_PIDVID_Product_GUID;
329 joydev.guid_product.Data1 = MAKELONG(joydev.vendor_id, joydev.product_id);
330 }
331
332 close(fd);
333
334 if (!joystick_devices_count)
335 new_joydevs = HeapAlloc(GetProcessHeap(), 0, sizeof(struct JoyDev));
336 else
337 new_joydevs = HeapReAlloc(GetProcessHeap(), 0, joystick_devices,
338 (joystick_devices_count + 1) * sizeof(struct JoyDev));
339 if (!new_joydevs) continue;
340
341 TRACE("Found a joystick on %s: %s\n with %d axes and %d buttons\n", joydev.device,
342 joydev.name, joydev.axis_count, joydev.button_count);
343
344 joystick_devices = new_joydevs;
345 joystick_devices[joystick_devices_count++] = joydev;
346 }
347
348 return joystick_devices_count;
349}
350
351static void fill_joystick_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
352{
353 DWORD dwSize = lpddi->dwSize;
354
355 TRACE("%d %p\n", dwSize, lpddi);
356 memset(lpddi, 0, dwSize);
357
358 /* Return joystick */
359 lpddi->dwSize = dwSize;
360 lpddi->guidInstance = DInput_Wine_Joystick_GUID;
361 lpddi->guidInstance.Data3 = id;
362 lpddi->guidProduct = joystick_devices[id].guid_product;
363 lpddi->dwDevType = get_device_type(version, joystick_devices[id].is_joystick);
364
365 /* Assume the joystick as HID if it is attached to USB bus and has a valid VID/PID */
366 if (joystick_devices[id].bus_type == BUS_USB &&
367 joystick_devices[id].vendor_id && joystick_devices[id].product_id)
368 {
369 lpddi->dwDevType |= DIDEVTYPE_HID;
370 lpddi->wUsagePage = 0x01; /* Desktop */
371 if (joystick_devices[id].is_joystick)
372 lpddi->wUsage = 0x04; /* Joystick */
373 else
374 lpddi->wUsage = 0x05; /* Game Pad */
375 }
376
377 MultiByteToWideChar(CP_ACP, 0, joystick_devices[id].name, -1, lpddi->tszInstanceName, MAX_PATH);
378 MultiByteToWideChar(CP_ACP, 0, joystick_devices[id].name, -1, lpddi->tszProductName, MAX_PATH);
379 lpddi->guidFFDriver = GUID_NULL;
380}
381
382static void fill_joystick_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, DWORD version, int id)
383{
384 DIDEVICEINSTANCEW lpddiW;
385 DWORD dwSize = lpddi->dwSize;
386
387 lpddiW.dwSize = sizeof(lpddiW);
388 fill_joystick_dideviceinstanceW(&lpddiW, version, id);
389
390 TRACE("%d %p\n", dwSize, lpddi);
391 memset(lpddi, 0, dwSize);
392
393 /* Convert W->A */
394 lpddi->dwSize = dwSize;
395 lpddi->guidInstance = lpddiW.guidInstance;
396 lpddi->guidProduct = lpddiW.guidProduct;
397 lpddi->dwDevType = lpddiW.dwDevType;
398 strcpy(lpddi->tszInstanceName, joystick_devices[id].name);
399 strcpy(lpddi->tszProductName, joystick_devices[id].name);
400 lpddi->guidFFDriver = lpddiW.guidFFDriver;
401 lpddi->wUsagePage = lpddiW.wUsagePage;
402 lpddi->wUsage = lpddiW.wUsage;
403}
404
405static HRESULT joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id)
406{
407 int fd = -1;
408
409 if (id >= find_joystick_devices()) return E_FAIL;
410
412 WARN("force feedback not supported\n");
413 return S_FALSE;
414 }
415
416 if ((dwDevType == 0) ||
417 ((dwDevType == DIDEVTYPE_JOYSTICK) && (version >= 0x0300 && version < 0x0800)) ||
418 (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))) {
419 /* check whether we have a joystick */
420 if ((fd = open(joystick_devices[id].device, O_RDONLY)) == -1)
421 {
422 WARN("open(%s, O_RDONLY) failed: %s\n", joystick_devices[id].device, strerror(errno));
423 return S_FALSE;
424 }
425 fill_joystick_dideviceinstanceA( lpddi, version, id );
426 close(fd);
427 TRACE("Enumerating the linux Joystick device: %s (%s)\n", joystick_devices[id].device, joystick_devices[id].name);
428 return S_OK;
429 }
430
431 return S_FALSE;
432}
433
434static HRESULT joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
435{
436 int fd = -1;
437
438 if (id >= find_joystick_devices()) return E_FAIL;
439
441 WARN("force feedback not supported\n");
442 return S_FALSE;
443 }
444
445 if ((dwDevType == 0) ||
446 ((dwDevType == DIDEVTYPE_JOYSTICK) && (version >= 0x0300 && version < 0x0800)) ||
447 (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))) {
448 /* check whether we have a joystick */
449 if ((fd = open(joystick_devices[id].device, O_RDONLY)) == -1)
450 {
451 WARN("open(%s, O_RDONLY) failed: %s\n", joystick_devices[id].device, strerror(errno));
452 return S_FALSE;
453 }
454 fill_joystick_dideviceinstanceW( lpddi, version, id );
455 close(fd);
456 TRACE("Enumerating the linux Joystick device: %s (%s)\n", joystick_devices[id].device, joystick_devices[id].name);
457 return S_OK;
458 }
459
460 return S_FALSE;
461}
462
463static HRESULT alloc_device(REFGUID rguid, IDirectInputImpl *dinput,
464 JoystickImpl **pdev, unsigned short index)
465{
466 DWORD i;
467 JoystickImpl* newDevice;
468 HRESULT hr;
469 LPDIDATAFORMAT df = NULL;
470 int idx = 0;
472
473 TRACE("%s %p %p %hu\n", debugstr_guid(rguid), dinput, pdev, index);
474
475 newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(JoystickImpl));
476 if (newDevice == 0) {
477 WARN("out of memory\n");
478 *pdev = 0;
479 return DIERR_OUTOFMEMORY;
480 }
481
482 newDevice->joydev = &joystick_devices[index];
483 newDevice->joyfd = -1;
484 newDevice->generic.guidInstance = DInput_Wine_Joystick_GUID;
485 newDevice->generic.guidInstance.Data3 = index;
486 newDevice->generic.guidProduct = DInput_Wine_Joystick_GUID;
487 newDevice->generic.joy_polldev = joy_polldev;
488 newDevice->generic.name = newDevice->joydev->name;
489 newDevice->generic.device_axis_count = newDevice->joydev->axis_count;
490 newDevice->generic.devcaps.dwButtons = newDevice->joydev->button_count;
491
492 if (newDevice->generic.devcaps.dwButtons > 128)
493 {
494 WARN("Can't support %d buttons. Clamping down to 128\n", newDevice->generic.devcaps.dwButtons);
495 newDevice->generic.devcaps.dwButtons = 128;
496 }
497
498 newDevice->generic.base.IDirectInputDevice8A_iface.lpVtbl = &JoystickAvt;
499 newDevice->generic.base.IDirectInputDevice8W_iface.lpVtbl = &JoystickWvt;
500 newDevice->generic.base.ref = 1;
501 newDevice->generic.base.dinput = dinput;
502 newDevice->generic.base.guid = *rguid;
503 InitializeCriticalSection(&newDevice->generic.base.crit);
504 newDevice->generic.base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JoystickImpl*->generic.base.crit");
505
506 /* setup_dinput_options may change these */
507 newDevice->generic.deadzone = 0;
508
509 /* do any user specified configuration */
510 hr = setup_dinput_options(&newDevice->generic, newDevice->joydev->dev_axes_map);
511 if (hr != DI_OK)
512 goto FAILED1;
513
514 /* Create copy of default data format */
515 if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIJoystick2.dwSize))) goto FAILED;
517
518 df->dwNumObjs = newDevice->generic.devcaps.dwAxes + newDevice->generic.devcaps.dwPOVs + newDevice->generic.devcaps.dwButtons;
519 if (!(df->rgodf = HeapAlloc(GetProcessHeap(), 0, df->dwNumObjs * df->dwObjSize))) goto FAILED;
520
521 for (i = 0; i < newDevice->generic.device_axis_count; i++)
522 {
523 int wine_obj = newDevice->generic.axis_map[i];
524
525 if (wine_obj < 0) continue;
526
527 memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[wine_obj], df->dwObjSize);
528 if (wine_obj < 8)
529 df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(wine_obj) | DIDFT_ABSAXIS;
530 else
531 {
532 df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(wine_obj - 8) | DIDFT_POV;
533 i++; /* POV takes 2 axes */
534 }
535 }
536 for (i = 0; i < newDevice->generic.devcaps.dwButtons; i++)
537 {
538 memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i + 12], df->dwObjSize);
539 df->rgodf[idx ].pguid = &GUID_Button;
541 }
542 newDevice->generic.base.data_format.wine_df = df;
543
544 /* initialize default properties */
545 for (i = 0; i < c_dfDIJoystick2.dwNumObjs; i++) {
546 newDevice->generic.props[i].lDevMin = -32767;
547 newDevice->generic.props[i].lDevMax = +32767;
548 newDevice->generic.props[i].lMin = 0;
549 newDevice->generic.props[i].lMax = 0xffff;
550 newDevice->generic.props[i].lDeadZone = newDevice->generic.deadzone; /* % * 1000 */
551 newDevice->generic.props[i].lSaturation = 0;
552 }
553
554 IDirectInput_AddRef(&newDevice->generic.base.dinput->IDirectInput7A_iface);
555
556 EnterCriticalSection(&dinput->crit);
557 list_add_tail(&dinput->devices_list, &newDevice->generic.base.entry);
558 LeaveCriticalSection(&dinput->crit);
559
560 newDevice->generic.devcaps.dwSize = sizeof(newDevice->generic.devcaps);
561 newDevice->generic.devcaps.dwFlags = DIDC_ATTACHED;
562
563 ddi.dwSize = sizeof(ddi);
564 fill_joystick_dideviceinstanceW(&ddi, newDevice->generic.base.dinput->dwVersion, index);
565 newDevice->generic.devcaps.dwDevType = ddi.dwDevType;
566
567 newDevice->generic.devcaps.dwFFSamplePeriod = 0;
568 newDevice->generic.devcaps.dwFFMinTimeResolution = 0;
569 newDevice->generic.devcaps.dwFirmwareRevision = 0;
570 newDevice->generic.devcaps.dwHardwareRevision = 0;
571 newDevice->generic.devcaps.dwFFDriverVersion = 0;
572
573 if (TRACE_ON(dinput)) {
574 _dump_DIDATAFORMAT(newDevice->generic.base.data_format.wine_df);
575 for (i = 0; i < (newDevice->generic.device_axis_count); i++)
576 TRACE("axis_map[%d] = %d\n", i, newDevice->generic.axis_map[i]);
577 _dump_DIDEVCAPS(&newDevice->generic.devcaps);
578 }
579
580 *pdev = newDevice;
581
582 return DI_OK;
583
584FAILED:
586FAILED1:
587 if (df) HeapFree(GetProcessHeap(), 0, df->rgodf);
588 HeapFree(GetProcessHeap(), 0, df);
589 release_DataFormat(&newDevice->generic.base.data_format);
590 HeapFree(GetProcessHeap(),0,newDevice->generic.axis_map);
591 HeapFree(GetProcessHeap(),0,newDevice);
592 *pdev = 0;
593
594 return hr;
595}
596
597/******************************************************************************
598 * get_joystick_index : Get the joystick index from a given GUID
599 */
600static unsigned short get_joystick_index(REFGUID guid)
601{
602 GUID wine_joystick = DInput_Wine_Joystick_GUID;
603 GUID dev_guid = *guid;
604
605 wine_joystick.Data3 = 0;
606 dev_guid.Data3 = 0;
607
608 /* for the standard joystick GUID use index 0 */
609 if(IsEqualGUID(&GUID_Joystick,guid)) return 0;
610
611 /* for the wine joystick GUIDs use the index stored in Data3 */
612 if(IsEqualGUID(&wine_joystick, &dev_guid)) return guid->Data3;
613
614 return MAX_JOYSTICKS;
615}
616
617static HRESULT joydev_create_device(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPVOID *pdev, int unicode)
618{
619 unsigned short index;
620
621 TRACE("%p %s %s %p %i\n", dinput, debugstr_guid(rguid), debugstr_guid(riid), pdev, unicode);
622 find_joystick_devices();
623 *pdev = NULL;
624
625 if ((index = get_joystick_index(rguid)) < MAX_JOYSTICKS &&
626 joystick_devices_count && index < joystick_devices_count)
627 {
628 JoystickImpl *This;
629 HRESULT hr;
630
631 if (riid == NULL)
632 ;/* nothing */
633 else if (IsEqualGUID(&IID_IDirectInputDeviceA, riid) ||
634 IsEqualGUID(&IID_IDirectInputDevice2A, riid) ||
635 IsEqualGUID(&IID_IDirectInputDevice7A, riid) ||
636 IsEqualGUID(&IID_IDirectInputDevice8A, riid))
637 {
638 unicode = 0;
639 }
640 else if (IsEqualGUID(&IID_IDirectInputDeviceW, riid) ||
641 IsEqualGUID(&IID_IDirectInputDevice2W, riid) ||
642 IsEqualGUID(&IID_IDirectInputDevice7W, riid) ||
643 IsEqualGUID(&IID_IDirectInputDevice8W, riid))
644 {
645 unicode = 1;
646 }
647 else
648 {
649 WARN("no interface\n");
650 return DIERR_NOINTERFACE;
651 }
652
653 hr = alloc_device(rguid, dinput, &This, index);
654 if (!This) return hr;
655
656 if (unicode)
657 *pdev = &This->generic.base.IDirectInputDevice8W_iface;
658 else
659 *pdev = &This->generic.base.IDirectInputDevice8A_iface;
660
661 return hr;
662 }
663
664 return DIERR_DEVICENOTREG;
665}
666
667#undef MAX_JOYSTICKS
668
670 "Wine Linux joystick driver",
671 joydev_enum_deviceA,
672 joydev_enum_deviceW,
673 joydev_create_device
674};
675
676/******************************************************************************
677 * Acquire : gets exclusive control of the joystick
678 */
679static HRESULT WINAPI JoystickLinuxWImpl_Acquire(LPDIRECTINPUTDEVICE8W iface)
680{
681 JoystickImpl *This = impl_from_IDirectInputDevice8W(iface);
682 HRESULT res;
683
684 TRACE("(%p)\n",This);
685
687 if (res != DI_OK)
688 return res;
689
690 /* open the joystick device */
691 if (This->joyfd==-1) {
692 TRACE("opening joystick device %s\n", This->joydev->device);
693
694 This->joyfd = open(This->joydev->device, O_RDONLY);
695 if (This->joyfd==-1) {
696 ERR("open(%s) failed: %s\n", This->joydev->device, strerror(errno));
698 return DIERR_NOTFOUND;
699 }
700 }
701
702 return DI_OK;
703}
704
705static HRESULT WINAPI JoystickLinuxAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
706{
707 JoystickImpl *This = impl_from_IDirectInputDevice8A(iface);
708 return JoystickLinuxWImpl_Acquire(IDirectInputDevice8W_from_impl(This));
709}
710
711/******************************************************************************
712 * GetProperty : get input device properties
713 */
714static HRESULT WINAPI JoystickLinuxWImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPDIPROPHEADER pdiph)
715{
716 JoystickImpl *This = impl_from_IDirectInputDevice8W(iface);
717
718 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(rguid), pdiph);
719 _dump_DIPROPHEADER(pdiph);
720
721 if (!IS_DIPROP(rguid)) return DI_OK;
722
723 switch (LOWORD(rguid)) {
724
726 {
727 LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
728
729 if (!This->joydev->product_id || !This->joydev->vendor_id)
730 return DIERR_UNSUPPORTED;
731 pd->dwData = MAKELONG(This->joydev->vendor_id, This->joydev->product_id);
732 TRACE("DIPROP_VIDPID(%08x)\n", pd->dwData);
733 break;
734 }
736 {
737 LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
738
739 pd->dwData = get_joystick_index(&This->generic.base.guid);
740 TRACE("DIPROP_JOYSTICKID(%d)\n", pd->dwData);
741 break;
742 }
743
745 {
746 static const WCHAR formatW[] = {'\\','\\','?','\\','h','i','d','#','v','i','d','_','%','0','4','x','&',
747 'p','i','d','_','%','0','4','x','&','%','s','_','%','h','u',0};
748 static const WCHAR miW[] = {'m','i',0};
749 static const WCHAR igW[] = {'i','g',0};
750
751 BOOL is_gamepad;
753 WORD vid = This->joydev->vendor_id;
754 WORD pid = This->joydev->product_id;
755
756 if (!pid || !vid)
757 return DIERR_UNSUPPORTED;
758
759 is_gamepad = is_xinput_device(&This->generic.devcaps, vid, pid);
760 pd->guidClass = GUID_DEVCLASS_HIDCLASS;
761 sprintfW(pd->wszPath, formatW, vid, pid, is_gamepad ? igW : miW, get_joystick_index(&This->generic.base.guid));
762
763 TRACE("DIPROP_GUIDANDPATH(%s, %s): returning fake path\n", debugstr_guid(&pd->guidClass), debugstr_w(pd->wszPath));
764 break;
765 }
766
767 default:
768 return JoystickWGenericImpl_GetProperty(iface, rguid, pdiph);
769 }
770
771 return DI_OK;
772}
773
774static HRESULT WINAPI JoystickLinuxAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface, REFGUID rguid, LPDIPROPHEADER pdiph)
775{
776 JoystickImpl *This = impl_from_IDirectInputDevice8A(iface);
777 return JoystickLinuxWImpl_GetProperty(IDirectInputDevice8W_from_impl(This), rguid, pdiph);
778}
779
780/******************************************************************************
781 * GetDeviceInfo : get information about a device's identity
782 */
783static HRESULT WINAPI JoystickLinuxAImpl_GetDeviceInfo(LPDIRECTINPUTDEVICE8A iface, LPDIDEVICEINSTANCEA ddi)
784{
785 JoystickImpl *This = impl_from_IDirectInputDevice8A(iface);
786
787 TRACE("(%p) %p\n", This, ddi);
788
789 if (ddi == NULL) return E_POINTER;
790 if ((ddi->dwSize != sizeof(DIDEVICEINSTANCE_DX3A)) &&
791 (ddi->dwSize != sizeof(DIDEVICEINSTANCEA)))
792 return DIERR_INVALIDPARAM;
793
794 fill_joystick_dideviceinstanceA( ddi, This->generic.base.dinput->dwVersion,
795 get_joystick_index(&This->generic.base.guid) );
796 return DI_OK;
797}
798
799static HRESULT WINAPI JoystickLinuxWImpl_GetDeviceInfo(LPDIRECTINPUTDEVICE8W iface, LPDIDEVICEINSTANCEW ddi)
800{
801 JoystickImpl *This = impl_from_IDirectInputDevice8W(iface);
802
803 TRACE("(%p) %p\n", This, ddi);
804
805 if (ddi == NULL) return E_POINTER;
806 if ((ddi->dwSize != sizeof(DIDEVICEINSTANCE_DX3W)) &&
807 (ddi->dwSize != sizeof(DIDEVICEINSTANCEW)))
808 return DIERR_INVALIDPARAM;
809
810 fill_joystick_dideviceinstanceW( ddi, This->generic.base.dinput->dwVersion,
811 get_joystick_index(&This->generic.base.guid) );
812 return DI_OK;
813}
814
815/******************************************************************************
816 * Unacquire : frees the joystick
817 */
818static HRESULT WINAPI JoystickLinuxWImpl_Unacquire(LPDIRECTINPUTDEVICE8W iface)
819{
820 JoystickImpl *This = impl_from_IDirectInputDevice8W(iface);
821 HRESULT res;
822
823 TRACE("(%p)\n",This);
824
826
827 if (res != DI_OK)
828 return res;
829
830 if (This->joyfd!=-1) {
831 TRACE("closing joystick device\n");
832 close(This->joyfd);
833 This->joyfd = -1;
834 return DI_OK;
835 }
836
837 return DI_NOEFFECT;
838}
839
840static HRESULT WINAPI JoystickLinuxAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface)
841{
842 JoystickImpl *This = impl_from_IDirectInputDevice8A(iface);
843 return JoystickLinuxWImpl_Unacquire(IDirectInputDevice8W_from_impl(This));
844}
845
846static void joy_polldev(LPDIRECTINPUTDEVICE8A iface)
847{
848 struct pollfd plfd;
849 struct js_event jse;
850 JoystickImpl *This = impl_from_IDirectInputDevice8A(iface);
851
852 TRACE("(%p)\n", This);
853
854 if (This->joyfd==-1) {
855 WARN("no device\n");
856 return;
857 }
858 while (1)
859 {
860 LONG value;
861 int inst_id = -1;
862
863 plfd.fd = This->joyfd;
864 plfd.events = POLLIN;
865 if (poll(&plfd,1,0) != 1)
866 return;
867 /* we have one event, so we can read */
868 if (sizeof(jse)!=read(This->joyfd,&jse,sizeof(jse))) {
869 return;
870 }
871 TRACE("js_event: type 0x%x, number %d, value %d\n",
872 jse.type,jse.number,jse.value);
873 if (jse.type & JS_EVENT_BUTTON)
874 {
875 int button;
876 if (jse.number >= This->generic.devcaps.dwButtons) return;
877
878 button = This->generic.button_map[jse.number];
879
881 This->generic.js.rgbButtons[button] = value = jse.value ? 0x80 : 0x00;
882 }
883 else if (jse.type & JS_EVENT_AXIS)
884 {
885 int number = This->generic.axis_map[jse.number]; /* wine format object index */
886
887 if (number < 0) return;
888 inst_id = number < 8 ? DIDFT_MAKEINSTANCE(number) | DIDFT_ABSAXIS :
890 value = joystick_map_axis(&This->generic.props[id_to_object(This->generic.base.data_format.wine_df, inst_id)], jse.value);
891
892 TRACE("changing axis %d => %d\n", jse.number, number);
893 switch (number)
894 {
895 case 0: This->generic.js.lX = value; break;
896 case 1: This->generic.js.lY = value; break;
897 case 2: This->generic.js.lZ = value; break;
898 case 3: This->generic.js.lRx = value; break;
899 case 4: This->generic.js.lRy = value; break;
900 case 5: This->generic.js.lRz = value; break;
901 case 6: This->generic.js.rglSlider[0] = value; break;
902 case 7: This->generic.js.rglSlider[1] = value; break;
903 case 8: case 9: case 10: case 11:
904 {
905 int idx = number - 8;
906
907 if (jse.number % 2)
908 This->povs[idx].y = jse.value;
909 else
910 This->povs[idx].x = jse.value;
911
912 This->generic.js.rgdwPOV[idx] = value = joystick_map_pov(&This->povs[idx]);
913 break;
914 }
915 default:
916 WARN("axis %d not supported\n", number);
917 }
918 }
919 if (inst_id >= 0)
920 queue_event(iface, inst_id, value, GetCurrentTime(), This->generic.base.dinput->evsequence++);
921 }
922}
923
924static const IDirectInputDevice8AVtbl JoystickAvt =
925{
931 JoystickLinuxAImpl_GetProperty,
933 JoystickLinuxAImpl_Acquire,
934 JoystickLinuxAImpl_Unacquire,
941 JoystickLinuxAImpl_GetDeviceInfo,
958};
959
960static const IDirectInputDevice8WVtbl JoystickWvt =
961{
967 JoystickLinuxWImpl_GetProperty,
969 JoystickLinuxWImpl_Acquire,
970 JoystickLinuxWImpl_Unacquire,
977 JoystickLinuxWImpl_GetDeviceInfo,
994};
995
996#else /* HAVE_LINUX_22_JOYSTICK_API */
997
999 "Wine Linux joystick driver",
1000 NULL,
1001 NULL,
1002 NULL
1003};
1004
1005#endif /* HAVE_LINUX_22_JOYSTICK_API */
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define read
Definition: acwin.h:96
#define O_RDONLY
Definition: acwin.h:108
#define open
Definition: acwin.h:95
#define close
Definition: acwin.h:98
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
#define WARN(fmt,...)
Definition: debug.h:115
#define ERR(fmt,...)
Definition: debug.h:113
const DIDATAFORMAT c_dfDIJoystick2
Definition: data_formats.c:251
#define E_FAIL
Definition: ddrawi.h:102
DWORD joystick_map_pov(const POINTL *p) DECLSPEC_HIDDEN
Definition: joystick.c:1024
LONG joystick_map_axis(ObjProps *props, int val) DECLSPEC_HIDDEN
Definition: joystick.c:985
#define DIPROP_GUIDANDPATH
Definition: dinput.h:908
struct DIPROPDWORD * LPDIPROPDWORD
#define DIDEVTYPE_JOYSTICK
Definition: dinput.h:200
#define DIERR_INVALIDPARAM
Definition: dinput.h:152
#define DIERR_NOINTERFACE
Definition: dinput.h:153
#define DIDFT_POV
Definition: dinput.h:757
struct IDirectInputDevice8A * LPDIRECTINPUTDEVICE8A
Definition: dinput.h:105
#define DIDEVTYPE_HID
Definition: dinput.h:201
#define DIPROP_JOYSTICKID
Definition: dinput.h:912
#define DIDC_ATTACHED
Definition: dinput.h:945
#define IDirectInput_AddRef(p)
Definition: dinput.h:2293
#define DIERR_UNSUPPORTED
Definition: dinput.h:156
#define DIERR_DEVICENOTREG
Definition: dinput.h:147
#define DIDFT_PSHBUTTON
Definition: dinput.h:754
#define DIDFT_ABSAXIS
Definition: dinput.h:752
#define DIERR_OUTOFMEMORY
Definition: dinput.h:155
#define DI_OK
Definition: dinput.h:128
struct DIPROPGUIDANDPATH * LPDIPROPGUIDANDPATH
#define DIEDFL_FORCEFEEDBACK
Definition: dinput.h:192
#define DI_NOEFFECT
Definition: dinput.h:132
#define DIDFT_MAKEINSTANCE(n)
Definition: dinput.h:762
#define DIPROP_VIDPID
Definition: dinput.h:918
#define DI8DEVTYPE_JOYSTICK
Definition: dinput.h:212
#define DIERR_NOTFOUND
Definition: dinput.h:148
#define DI8DEVCLASS_GAMECTRL
Definition: dinput.h:207
struct IDirectInputDevice8W * LPDIRECTINPUTDEVICE8W
Definition: dinput.h:106
#define IS_DIPROP(x)
DWORD get_device_type(DWORD version, BOOL is_joystick) DECLSPEC_HIDDEN
Definition: joystick.c:107
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HRESULT WINAPI IDirectInputDevice8AImpl_GetImageInfo(LPDIRECTINPUTDEVICE8A iface, LPDIDEVICEIMAGEINFOHEADERA lpdiDevImageInfoHeader)
Definition: device.c:1941
HRESULT WINAPI IDirectInputDevice2AImpl_EnumEffects(LPDIRECTINPUTDEVICE8A iface, LPDIENUMEFFECTSCALLBACKA lpCallback, LPVOID lpvRef, DWORD dwFlags)
Definition: device.c:1743
HRESULT WINAPI IDirectInputDevice8WImpl_GetImageInfo(LPDIRECTINPUTDEVICE8W iface, LPDIDEVICEIMAGEINFOHEADERW lpdiDevImageInfoHeader)
Definition: device.c:1950
HRESULT WINAPI IDirectInputDevice2AImpl_SetDataFormat(LPDIRECTINPUTDEVICE8A iface, LPCDIDATAFORMAT df)
Definition: device.c:1156
HRESULT WINAPI IDirectInputDevice2WImpl_EnumEffects(LPDIRECTINPUTDEVICE8W iface, LPDIENUMEFFECTSCALLBACKW lpCallback, LPVOID lpvRef, DWORD dwFlags)
Definition: device.c:1755
HRESULT WINAPI IDirectInputDevice2WImpl_Acquire(LPDIRECTINPUTDEVICE8W iface)
Definition: device.c:1076
HRESULT WINAPI IDirectInputDevice2AImpl_EnumObjects(LPDIRECTINPUTDEVICE8A iface, LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback, LPVOID lpvRef, DWORD dwFlags)
Definition: device.c:1322
HRESULT WINAPI IDirectInputDevice2AImpl_SetCooperativeLevel(LPDIRECTINPUTDEVICE8A iface, HWND hwnd, DWORD dwflags)
Definition: device.c:1203
void _dump_DIPROPHEADER(LPCDIPROPHEADER diph)
Definition: device.c:176
HRESULT WINAPI IDirectInputDevice2WImpl_SetDataFormat(LPDIRECTINPUTDEVICE8W iface, LPCDIDATAFORMAT df)
Definition: device.c:1135
static IDirectInputDeviceImpl * impl_from_IDirectInputDevice8W(IDirectInputDevice8W *iface)
Definition: device.c:51
HRESULT WINAPI IDirectInputDevice2WImpl_SendForceFeedbackCommand(LPDIRECTINPUTDEVICE8W iface, DWORD dwFlags)
Definition: device.c:1800
HRESULT WINAPI IDirectInputDevice2WImpl_SendDeviceData(LPDIRECTINPUTDEVICE8W iface, DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags)
Definition: device.c:1857
void _dump_DIDATAFORMAT(const DIDATAFORMAT *df)
Definition: device.c:242
HRESULT WINAPI IDirectInputDevice2WImpl_SetEventNotification(LPDIRECTINPUTDEVICE8W iface, HANDLE event)
Definition: device.c:1212
HRESULT WINAPI IDirectInputDevice2WImpl_GetDeviceData(LPDIRECTINPUTDEVICE8W iface, DWORD dodsize, LPDIDEVICEOBJECTDATA dod, LPDWORD entries, DWORD flags)
Definition: device.c:1629
HRESULT WINAPI IDirectInputDevice2AImpl_RunControlPanel(LPDIRECTINPUTDEVICE8A iface, HWND hwndOwner, DWORD dwFlags)
Definition: device.c:1700
HRESULT WINAPI IDirectInputDevice2AImpl_GetForceFeedbackState(LPDIRECTINPUTDEVICE8A iface, LPDWORD pdwOut)
Definition: device.c:1794
ULONG WINAPI IDirectInputDevice2WImpl_AddRef(LPDIRECTINPUTDEVICE8W iface)
Definition: device.c:1308
HRESULT WINAPI IDirectInputDevice7AImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE8A iface, LPCSTR lpszFileName, LPDIENUMEFFECTSINFILECALLBACK pec, LPVOID pvRef, DWORD dwFlags)
Definition: device.c:1876
ULONG WINAPI IDirectInputDevice2WImpl_Release(LPDIRECTINPUTDEVICE8W iface)
Definition: device.c:1231
void queue_event(LPDIRECTINPUTDEVICE8A iface, int inst_id, DWORD data, DWORD time, DWORD seq)
Definition: device.c:1025
static IDirectInputDeviceImpl * impl_from_IDirectInputDevice8A(IDirectInputDevice8A *iface)
Definition: device.c:47
HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceData(LPDIRECTINPUTDEVICE8A iface, DWORD dodsize, LPDIDEVICEOBJECTDATA dod, LPDWORD entries, DWORD flags)
Definition: device.c:1685
HRESULT WINAPI IDirectInputDevice2AImpl_CreateEffect(LPDIRECTINPUTDEVICE8A iface, REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdef, LPUNKNOWN pUnkOuter)
Definition: device.c:1736
HRESULT WINAPI IDirectInputDevice2AImpl_EnumCreatedEffectObjects(LPDIRECTINPUTDEVICE8A iface, LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID lpvRef, DWORD dwFlags)
Definition: device.c:1821
int id_to_object(LPCDIDATAFORMAT df, int id)
Definition: device.c:588
HRESULT WINAPI IDirectInputDevice2WImpl_GetForceFeedbackState(LPDIRECTINPUTDEVICE8W iface, LPDWORD pdwOut)
Definition: device.c:1787
ULONG WINAPI IDirectInputDevice2AImpl_AddRef(LPDIRECTINPUTDEVICE8A iface)
Definition: device.c:1316
HRESULT WINAPI IDirectInputDevice2WImpl_SetCooperativeLevel(LPDIRECTINPUTDEVICE8W iface, HWND hwnd, DWORD dwflags)
Definition: device.c:1167
HRESULT WINAPI IDirectInputDevice2WImpl_EnumObjects(LPDIRECTINPUTDEVICE8W iface, LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback, LPVOID lpvRef, DWORD dwFlags)
Definition: device.c:1352
ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE8A iface)
Definition: device.c:1267
HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface(LPDIRECTINPUTDEVICE8A iface, REFIID riid, LPVOID *ppobj)
Definition: device.c:1302
HRESULT WINAPI IDirectInputDevice2AImpl_Escape(LPDIRECTINPUTDEVICE8A iface, LPDIEFFESCAPE lpDIEEsc)
Definition: device.c:1835
HRESULT WINAPI IDirectInputDevice2AImpl_SendForceFeedbackCommand(LPDIRECTINPUTDEVICE8A iface, DWORD dwFlags)
Definition: device.c:1807
HRESULT WINAPI IDirectInputDevice2AImpl_SetEventNotification(LPDIRECTINPUTDEVICE8A iface, HANDLE event)
Definition: device.c:1224
HRESULT WINAPI IDirectInputDevice7AImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE8A iface, LPCSTR lpszFileName, DWORD dwEntries, LPDIFILEEFFECT rgDiFileEft, DWORD dwFlags)
Definition: device.c:1900
HRESULT WINAPI IDirectInputDevice2WImpl_Initialize(LPDIRECTINPUTDEVICE8W iface, HINSTANCE hinst, DWORD dwVersion, REFGUID rguid)
Definition: device.c:1706
HRESULT WINAPI IDirectInputDevice2WImpl_QueryInterface(LPDIRECTINPUTDEVICE8W iface, REFIID riid, LPVOID *ppobj)
Definition: device.c:1273
HRESULT WINAPI IDirectInputDevice2WImpl_CreateEffect(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdef, LPUNKNOWN pUnkOuter)
Definition: device.c:1725
HRESULT WINAPI IDirectInputDevice2AImpl_Initialize(LPDIRECTINPUTDEVICE8A iface, HINSTANCE hinst, DWORD dwVersion, REFGUID rguid)
Definition: device.c:1714
HRESULT WINAPI IDirectInputDevice2WImpl_Unacquire(LPDIRECTINPUTDEVICE8W iface)
Definition: device.c:1108
HRESULT WINAPI IDirectInputDevice2AImpl_SendDeviceData(LPDIRECTINPUTDEVICE8A iface, DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags)
Definition: device.c:1867
HRESULT WINAPI IDirectInputDevice2AImpl_GetEffectInfo(LPDIRECTINPUTDEVICE8A iface, LPDIEFFECTINFOA lpdei, REFGUID rguid)
Definition: device.c:1767
HRESULT WINAPI IDirectInputDevice2WImpl_GetEffectInfo(LPDIRECTINPUTDEVICE8W iface, LPDIEFFECTINFOW lpdei, REFGUID rguid)
Definition: device.c:1777
HRESULT WINAPI IDirectInputDevice2WImpl_EnumCreatedEffectObjects(LPDIRECTINPUTDEVICE8W iface, LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID lpvRef, DWORD dwFlags)
Definition: device.c:1813
HRESULT WINAPI IDirectInputDevice2WImpl_RunControlPanel(LPDIRECTINPUTDEVICE8W iface, HWND hwndOwner, DWORD dwFlags)
Definition: device.c:1692
HRESULT WINAPI IDirectInputDevice7WImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE8W iface, LPCWSTR lpszFileName, LPDIENUMEFFECTSINFILECALLBACK pec, LPVOID pvRef, DWORD dwFlags)
Definition: device.c:1888
void release_DataFormat(DataFormat *format)
Definition: device.c:391
HRESULT WINAPI IDirectInputDevice7WImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE8W iface, LPCWSTR lpszFileName, DWORD dwEntries, LPDIFILEEFFECT rgDiFileEft, DWORD dwFlags)
Definition: device.c:1912
HRESULT WINAPI IDirectInputDevice2WImpl_Escape(LPDIRECTINPUTDEVICE8W iface, LPDIEFFESCAPE lpDIEEsc)
Definition: device.c:1828
static IDirectInputDevice8W * IDirectInputDevice8W_from_impl(IDirectInputDeviceImpl *This)
Definition: device.c:60
HRESULT WINAPI JoystickWGenericImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface, LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow)
Definition: joystick.c:563
HRESULT setup_dinput_options(JoystickGenericImpl *This, const int *default_axis_map)
Definition: joystick.c:1038
HRESULT WINAPI JoystickAGenericImpl_BuildActionMap(LPDIRECTINPUTDEVICE8A iface, LPDIACTIONFORMATA lpdiaf, LPCSTR lpszUserName, DWORD dwFlags)
Definition: joystick.c:906
BOOL is_xinput_device(const DIDEVCAPS *devcaps, WORD vid, WORD pid)
Definition: joystick.c:312
BOOL device_disabled_registry(const char *name)
Definition: joystick.c:274
HRESULT WINAPI JoystickWGenericImpl_GetCapabilities(LPDIRECTINPUTDEVICE8W iface, LPDIDEVCAPS lpDIDevCaps)
Definition: joystick.c:526
HRESULT WINAPI JoystickWGenericImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPDIPROPHEADER pdiph)
Definition: joystick.c:610
void _dump_DIDEVCAPS(const DIDEVCAPS *lpDIDevCaps)
Definition: joystick.c:480
HRESULT WINAPI JoystickAGenericImpl_SetProperty(LPDIRECTINPUTDEVICE8A iface, REFGUID rguid, LPCDIPROPHEADER ph)
Definition: joystick.c:473
HRESULT WINAPI JoystickWGenericImpl_SetProperty(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPCDIPROPHEADER ph)
Definition: joystick.c:398
HRESULT WINAPI JoystickWGenericImpl_Poll(LPDIRECTINPUTDEVICE8W iface)
Definition: joystick.c:779
HRESULT WINAPI JoystickWGenericImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUserName, DWORD dwFlags)
Definition: joystick.c:831
HRESULT WINAPI JoystickAGenericImpl_GetDeviceState(LPDIRECTINPUTDEVICE8A iface, DWORD len, LPVOID ptr)
Definition: joystick.c:824
HRESULT WINAPI JoystickWGenericImpl_GetDeviceState(LPDIRECTINPUTDEVICE8W iface, DWORD len, LPVOID ptr)
Definition: joystick.c:804
HRESULT WINAPI JoystickWGenericImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUserName, DWORD dwFlags)
Definition: joystick.c:936
HRESULT WINAPI JoystickAGenericImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8A iface, LPDIDEVICEOBJECTINSTANCEA pdidoi, DWORD dwObj, DWORD dwHow)
Definition: joystick.c:586
HRESULT WINAPI JoystickAGenericImpl_Poll(LPDIRECTINPUTDEVICE8A iface)
Definition: joystick.c:794
const GUID DInput_PIDVID_Product_GUID
Definition: joystick.c:61
HRESULT WINAPI JoystickAGenericImpl_SetActionMap(LPDIRECTINPUTDEVICE8A iface, LPDIACTIONFORMATA lpdiaf, LPCSTR lpszUserName, DWORD dwFlags)
Definition: joystick.c:948
HRESULT WINAPI JoystickAGenericImpl_GetCapabilities(LPDIRECTINPUTDEVICE8A iface, LPDIDEVCAPS lpDIDevCaps)
Definition: joystick.c:554
static SysKeyboardImpl * alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
Definition: keyboard.c:255
unsigned int idx
Definition: utils.c:41
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define TRACE_ON(x)
Definition: compat.h:75
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define MultiByteToWideChar
Definition: compat.h:110
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static const WCHAR version[]
Definition: asmname.c:66
#define POLLIN
Definition: linux.h:1853
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLuint res
Definition: glext.h:9613
GLuint index
Definition: glext.h:6031
GLuint id
Definition: glext.h:5910
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
_Check_return_ long __cdecl strtol(_In_z_ const char *_Str, _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix)
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
const struct dinput_device joystick_linux_device
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
#define GUID_NULL
Definition: ks.h:106
const GUID * guid
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define sprintf(buf, format,...)
Definition: sprintf.c:55
DWORD button
Definition: button.c:166
static unsigned int number
Definition: dsound.c:1479
const char * strerror(int err)
Definition: compat_str.c:23
#define min(a, b)
Definition: monoChain.cc:55
@ generic
Definition: optimize.h:97
#define LOWORD(l)
Definition: pedump.c:82
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define sprintfW
Definition: unicode.h:64
#define errno
Definition: errno.h:18
static int fd
Definition: io.c:51
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
GUID guidProduct
Definition: dinput.h:414
GUID guidFFDriver
Definition: dinput.h:418
GUID guidInstance
Definition: dinput.h:413
CHAR tszInstanceName[MAX_PATH]
Definition: dinput.h:416
CHAR tszProductName[MAX_PATH]
Definition: dinput.h:417
DWORD dwDevType
Definition: dinput.h:415
DWORD dwDevType
Definition: dinput.h:428
WCHAR tszProductName[MAX_PATH]
Definition: dinput.h:430
GUID guidFFDriver
Definition: dinput.h:431
GUID guidProduct
Definition: dinput.h:427
WCHAR tszInstanceName[MAX_PATH]
Definition: dinput.h:429
GUID guidInstance
Definition: dinput.h:426
DWORD dwData
Definition: dinput.h:844
WCHAR wszPath[MAX_PATH]
Definition: dinput.h:869
struct list devices_list
CRITICAL_SECTION crit
LPDIOBJECTDATAFORMAT rgodf
Definition: dinput.h:813
DWORD dwSize
Definition: dinput.h:808
DWORD dwObjSize
Definition: dinput.h:809
DWORD dwNumObjs
Definition: dinput.h:812
const GUID * pguid
Definition: dinput.h:800
Definition: scsiwmi.h:51
Definition: devices.h:37
Definition: name.c:39
Definition: linux.h:1867
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
#define DWORD_PTR
Definition: treelist.c:76
uint32_t DWORD_PTR
Definition: typedefs.h:65
int32_t INT
Definition: typedefs.h:58
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
Definition: pdh_main.c:94
int ret
#define GetCurrentTime
Definition: winbase.h:2108
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3837
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define E_POINTER
Definition: winerror.h:2365
#define ioctl
Definition: wintirpc.h:60
#define poll
Definition: wintirpc.h:59
#define snprintf
Definition: wintirpc.h:48
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193