Advertisement
Guest User

dirty fix for wine-1.5.17

a guest
Jan 22nd, 2013
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 24.09 KB | None | 0 0
  1. From 093876689778e06f853f977eac67c8e366464f4d Mon Sep 17 00:00:00 2001
  2. From: Christoph Frick <frick@sc-networks.com>
  3. Date: Sat, 26 Apr 2008 02:50:01 +0200
  4. Subject: Initial support for BSD's usbhid joysticks
  5.  
  6. Please consider this a tracer bullet. I had only time to test it with a
  7. 4-axis/4-button wheel in LFS in FreeBSD 7.0. I will take further tests using a
  8. flight stick and other games soon. But for now i just want to see, what others
  9. have to say about it.
  10. ---
  11. configure                      |  49 ++++
  12.  configure.ac                   |   7 +
  13.  dlls/dinput/Makefile.in        |   3 +-
  14.  dlls/dinput/dinput_main.c      |   1 +
  15.  dlls/dinput/dinput_private.h   |   1 +
  16.  dlls/dinput/joystick_bsduhid.c | 562 +++++++++++++++++++++++++++++++++++++++++
  17.  include/config.h.in            |   3 +
  18.  7 files changed, 625 insertions(+), 1 deletion(-)
  19.  create mode 100644 dlls/dinput/joystick_bsduhid.c
  20.  
  21. diff --git a/configure b/configure
  22. index d3247bd..0a0171e 100755
  23. --- a/configure
  24. +++ b/configure
  25. @@ -627,6 +627,7 @@ LIBOBJS
  26.  PORCFLAGS
  27.  LINGUAS
  28.  ALL_TEST_RESOURCES
  29. +LIBUSBHID
  30.  LDAPLIBS
  31.  LIBPOLL
  32.  LIBDL
  33. @@ -5943,6 +5944,7 @@ for ac_header in \
  34.     termios.h \
  35.     tiffio.h \
  36.     unistd.h \
  37. +   usbhid.h \
  38.     utime.h \
  39.     valgrind/memcheck.h \
  40.     valgrind/valgrind.h \
  41. @@ -13852,6 +13854,53 @@ $as_echo "#define HAVE_LINUX_22_JOYSTICK_API 1" >>confdefs.h
  42.     fi
  43.  fi
  44.  
  45. +LIBUSBHID=""
  46. +
  47. +if test "$ac_cv_header_usbhid_h" = "yes"
  48. +then
  49. +  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for hid_get_report_desc in -lusbhid" >&5
  50. +$as_echo_n "checking for hid_get_report_desc in -lusbhid... " >&6; }
  51. +if ${ac_cv_lib_usbhid_hid_get_report_desc+:} false; then :
  52. +  $as_echo_n "(cached) " >&6
  53. +else
  54. +  ac_check_lib_save_LIBS=$LIBS
  55. +LIBS="-lusbhid  $LIBS"
  56. +cat confdefs.h - <<_ACEOF >conftest.$ac_ext
  57. +/* end confdefs.h.  */
  58. +
  59. +/* Override any GCC internal prototype to avoid an error.
  60. +   Use char because int might match the return type of a GCC
  61. +   builtin and then its argument prototype would still apply.  */
  62. +#ifdef __cplusplus
  63. +extern "C"
  64. +#endif
  65. +char hid_get_report_desc ();
  66. +int
  67. +main ()
  68. +{
  69. +return hid_get_report_desc ();
  70. +  ;
  71. +  return 0;
  72. +}
  73. +_ACEOF
  74. +if ac_fn_c_try_link "$LINENO"; then :
  75. +  ac_cv_lib_usbhid_hid_get_report_desc=yes
  76. +else
  77. +  ac_cv_lib_usbhid_hid_get_report_desc=no
  78. +fi
  79. +rm -f core conftest.err conftest.$ac_objext \
  80. +    conftest$ac_exeext conftest.$ac_ext
  81. +LIBS=$ac_check_lib_save_LIBS
  82. +fi
  83. +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_usbhid_hid_get_report_desc" >&5
  84. +$as_echo "$ac_cv_lib_usbhid_hid_get_report_desc" >&6; }
  85. +if test "x$ac_cv_lib_usbhid_hid_get_report_desc" = xyes; then :
  86. +  LIBUSBHID="-lusbhid"
  87. +
  88. +fi
  89. +
  90. +fi
  91. +
  92.  
  93.  ac_fn_c_check_member "$LINENO" "struct statfs" "f_bfree" "ac_cv_member_struct_statfs_f_bfree" "#include <sys/types.h>
  94.  #ifdef HAVE_SYS_PARAM_H
  95. diff --git a/configure.ac b/configure.ac
  96. index 2a0a1b6..7eb3409 100644
  97. --- a/configure.ac
  98. +++ b/configure.ac
  99. @@ -530,6 +530,7 @@ AC_CHECK_HEADERS(\
  100.     termios.h \
  101.     tiffio.h \
  102.     unistd.h \
  103. +   usbhid.h \
  104.     utime.h \
  105.     valgrind/memcheck.h \
  106.     valgrind/valgrind.h \
  107. @@ -2223,6 +2224,12 @@ then
  108.     fi
  109.  fi
  110.  
  111. +AC_SUBST(LIBUSBHID,"")
  112. +if test "$ac_cv_header_usbhid_h" = "yes"
  113. +then
  114. +  AC_CHECK_LIB(usbhid,hid_get_report_desc,[AC_SUBST(LIBUSBHID,"-lusbhid")])
  115. +fi
  116. +
  117.  dnl **** FIXME: what about mixed cases, where we need two of them? ***
  118.  
  119.  dnl Check for statfs members
  120. diff --git a/dlls/dinput/Makefile.in b/dlls/dinput/Makefile.in
  121. index 1be48c4..9adf4af 100644
  122. --- a/dlls/dinput/Makefile.in
  123. +++ b/dlls/dinput/Makefile.in
  124. @@ -1,7 +1,7 @@
  125.  MODULE    = dinput.dll
  126.  IMPORTLIB = dinput
  127.  IMPORTS   = dxguid uuid comctl32 ole32 user32 advapi32
  128. -EXTRALIBS = @IOKITLIB@
  129. +EXTRALIBS = @IOKITLIB@ @LIBUSBHID@
  130.  
  131.  C_SRCS = \
  132.     config.c \
  133. @@ -12,6 +12,7 @@ C_SRCS = \
  134.     joystick.c \
  135.     joystick_linux.c \
  136.     joystick_linuxinput.c \
  137. +   joystick_bsduhid.c \
  138.     joystick_osx.c \
  139.     keyboard.c \
  140.     mouse.c
  141. diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
  142. index c07b333..6658c46 100644
  143. --- a/dlls/dinput/dinput_main.c
  144. +++ b/dlls/dinput/dinput_main.c
  145. @@ -94,6 +94,7 @@ static const struct dinput_device *dinput_devices[] =
  146.      &keyboard_device,
  147.      &joystick_linuxinput_device,
  148.      &joystick_linux_device,
  149. +    &joystick_bsduhid_device,
  150.      &joystick_osx_device
  151.  };
  152.  #define NB_DINPUT_DEVICES (sizeof(dinput_devices)/sizeof(dinput_devices[0]))
  153. diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h
  154. index e593b40..0fd49b3 100644
  155. --- a/dlls/dinput/dinput_private.h
  156. +++ b/dlls/dinput/dinput_private.h
  157. @@ -60,6 +60,7 @@ extern const struct dinput_device mouse_device DECLSPEC_HIDDEN;
  158.  extern const struct dinput_device keyboard_device DECLSPEC_HIDDEN;
  159.  extern const struct dinput_device joystick_linux_device DECLSPEC_HIDDEN;
  160.  extern const struct dinput_device joystick_linuxinput_device DECLSPEC_HIDDEN;
  161. +extern const struct dinput_device joystick_bsduhid_device DECLSPEC_HIDDEN;
  162.  extern const struct dinput_device joystick_osx_device DECLSPEC_HIDDEN;
  163.  
  164.  extern void check_dinput_hooks(LPDIRECTINPUTDEVICE8W) DECLSPEC_HIDDEN;
  165. diff --git a/dlls/dinput/joystick_bsduhid.c b/dlls/dinput/joystick_bsduhid.c
  166. new file mode 100644
  167. index 0000000..db6ec7e
  168. --- /dev/null
  169. +++ b/dlls/dinput/joystick_bsduhid.c
  170. @@ -0,0 +1,562 @@
  171. +/*
  172. + * DirectInput Joystick device For BSD's uhid(4) interface
  173. + *
  174. + * This library is free software; you can redistribute it and/or modify it under
  175. + * the terms of the GNU Lesser General Public License as published by the
  176. + * Free Software Foundation; either version 2.1 of the License, or (at your
  177. + * option) any later version.
  178. + *
  179. + * This library is distributed in the hope that it will be useful, but WITHOUT
  180. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  181. + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  182. + * License for more details.
  183. + *
  184. + * You should have received a copy of the GNU Lesser General Public License
  185. + * along with this library; if not, write to the Free Software Foundation,
  186. + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  187. + */
  188. +
  189. +#include "config.h"
  190. +#include "wine/port.h"
  191. +#include <errno.h>
  192. +#include <stdio.h>
  193. +#include <time.h>
  194. +#ifdef HAVE_SYS_TIME_H
  195. +# include <sys/time.h>
  196. +#endif
  197. +#ifdef HAVE_SYS_ERRNO_H
  198. +#include <sys/errno.h>
  199. +#endif
  200. +#ifdef HAVE_SYS_IOCTL_H
  201. +# include <sys/ioctl.h>
  202. +#endif
  203. +#ifdef HAVE_SYS_POLL_H
  204. +# include <sys/poll.h>
  205. +#endif
  206. +
  207. +#include "wine/debug.h"
  208. +#include "wine/unicode.h"
  209. +#include "windef.h"
  210. +#include "winbase.h"
  211. +#include "winerror.h"
  212. +#include "winreg.h"
  213. +#include "dinput.h"
  214. +
  215. +#include "dinput_private.h"
  216. +#include "device_private.h"
  217. +#include "joystick_private.h"
  218. +
  219. +WINE_DEFAULT_DEBUG_CHANNEL(dinput);
  220. +
  221. +#ifdef HAVE_USBHID_H
  222. +
  223. +#include <usbhid.h>
  224. +#include <dev/usb/usb.h>
  225. +#include <dev/usb/usbhid.h>
  226. +#include <dev/usb/usb_ioctl.h>
  227. +
  228. +#define FMT_UHIDDEVS   "/dev/uhid%d"
  229. +#define MAX_UHIDDEVS   64
  230. +
  231. +/* FIXME: these are offsets in c_dfDIJoystick2 */
  232. +#define WINE_JOYSTICK_MAX_AXES    8
  233. +#define WINE_JOYSTICK_MAX_POVS    4
  234. +#define WINE_JOYSTICK_MAX_BUTTONS 128
  235. +
  236. +typedef struct JoystickImpl JoystickImpl;
  237. +static const IDirectInputDevice8AVtbl JoystickAvt;
  238. +static const IDirectInputDevice8WVtbl JoystickWvt;
  239. +
  240. +struct JoyDev {
  241. +   char           *device;
  242. +   char           *name;
  243. +   GUID        guid;
  244. +
  245. +   int     num_axes;
  246. +   int     num_buttons;
  247. +
  248. +   struct hid_item axes[WINE_JOYSTICK_MAX_AXES];
  249. +   struct hid_item buttons[WINE_JOYSTICK_MAX_BUTTONS];
  250. +
  251. +   int axis_values[WINE_JOYSTICK_MAX_AXES];
  252. +   int button_values[WINE_JOYSTICK_MAX_BUTTONS];
  253. +
  254. +   size_t      len_data;
  255. +   char           *data;
  256. +};
  257. +
  258. +struct JoystickImpl {
  259. +   struct IDirectInputDeviceImpl base;
  260. +   struct JoyDev  *joydev;
  261. +   DIJOYSTATE2 js;
  262. +   ObjProps    props  [WINE_JOYSTICK_MAX_AXES];
  263. +   int joyfd;
  264. +};
  265. +
  266. +static const GUID DInput_Wine_Joystick_Base_GUID = {   /* 9e573edb-7734-11d2-8d4
  267. +                            * a-23903fb6bdf7 */
  268. +   0x9e573edb,
  269. +   0x7734,
  270. +   0x11d2,
  271. +   {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
  272. +};
  273. +
  274. +static int have_joy_devs = -1;
  275. +static struct JoyDev *joy_devs = NULL;
  276. +
  277. +static void
  278. +find_joy_devs(void)
  279. +{
  280. +   int     i;
  281. +
  282. +   if (have_joy_devs >= 0) {
  283. +       return;
  284. +   }
  285. +   have_joy_devs = 0;
  286. +
  287. +   for (i = 0; i < MAX_UHIDDEVS; i++) {
  288. +       int     usb_report_id, is_joystick = 0;
  289. +       char        buf       [MAX_PATH];
  290. +       int     fd;
  291. +       struct JoyDev   joydev = {0};
  292. +       report_desc_t   rdesc;
  293. +
  294. +       snprintf(buf, MAX_PATH, FMT_UHIDDEVS, i);
  295. +       buf[MAX_PATH - 1] = 0;
  296. +
  297. +       if ((fd = open(buf, O_RDWR | O_NDELAY, 0)) == -1) {
  298. +           TRACE("Unable to open %s read/write: %s\n", buf, strerror(errno));
  299. +           continue;
  300. +       }
  301. +       if ((rdesc = hid_get_report_desc(fd)) == 0) {
  302. +           TRACE("%s: unable to get report descriptor: %s\n", buf, strerror(errno));
  303. +           close(fd);
  304. +           continue;
  305. +       }
  306. +       if (ioctl(fd, USB_GET_REPORT_ID, &usb_report_id) < 0) {
  307. +           TRACE("%s: unable to get USB report id: %s\n", buf, strerror(errno));
  308. +           hid_dispose_report_desc(rdesc);
  309. +           close(fd);
  310. +           continue;
  311. +       }
  312. +       joydev.len_data = hid_report_size(rdesc, hid_input, usb_report_id);
  313. +       joydev.data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(char) * joydev.len_data);
  314. +
  315. +       {
  316. +           struct hid_data *hdata;
  317. +           struct hid_item hitem;
  318. +           hdata = hid_start_parse(rdesc, 1 << hid_input, usb_report_id);
  319. +           do {
  320. +               int     page = HID_PAGE(hitem.usage);
  321. +               int     usage = HID_USAGE(hitem.usage);
  322. +
  323. +               is_joystick |= hitem.kind == hid_collection && page == HUP_GENERIC_DESKTOP && (usage == HUG_JOYSTICK || usage == HUG_GAME_PAD);
  324. +               if (hitem.kind != hid_input) {
  325. +                   continue;
  326. +               }
  327. +               if (!is_joystick) {
  328. +                   continue;
  329. +               }
  330. +               if (page == HUP_GENERIC_DESKTOP) {
  331. +                   if (usage != HUG_HAT_SWITCH) {
  332. +                       if (joydev.num_axes < WINE_JOYSTICK_MAX_AXES) {
  333. +                           joydev.axes[joydev.num_axes++] = hitem;
  334. +                       }
  335. +                   }
  336. +               } else if (page == HUP_BUTTON) {
  337. +                   if (joydev.num_buttons < WINE_JOYSTICK_MAX_BUTTONS) {
  338. +                       joydev.buttons[joydev.num_buttons++] = hitem;
  339. +                   }
  340. +               }
  341. +           } while (hid_get_item(hdata, &hitem));
  342. +           hid_end_parse(hdata);
  343. +       }
  344. +
  345. +       if (!is_joystick) {
  346. +           TRACE("%s: looks not like a joystick\n", buf);
  347. +           HeapFree(GetProcessHeap(), 0, joydev.data);
  348. +           hid_dispose_report_desc(rdesc);
  349. +           close(fd);
  350. +           continue;
  351. +       }
  352. +       joydev.device = strdup(buf);
  353. +       joydev.name = strdup(buf);  /* TODO */
  354. +       joydev.guid = DInput_Wine_Joystick_Base_GUID;
  355. +       joydev.guid.Data3 += have_joy_devs;
  356. +
  357. +       TRACE("Found a joystick on %s: %s (%s)\n", joydev.device, joydev.name, debugstr_guid(&joydev.guid));
  358. +
  359. +       if (have_joy_devs == 0) {
  360. +           joy_devs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct JoyDev));
  361. +       } else {
  362. +           HeapReAlloc(GetProcessHeap(), 0, joy_devs, (1 + have_joy_devs) * sizeof(struct JoyDev));
  363. +       }
  364. +       joy_devs[have_joy_devs++] = joydev;
  365. +
  366. +       hid_dispose_report_desc(rdesc);
  367. +       close(fd);
  368. +   }
  369. +}
  370. +
  371. +#define CENTER_AXIS(a) (a < ji->joydev->num_axes ? joystick_map_axis( &ji->props[a], ji->joydev->axis_values[a]) : 0)
  372. +static void fake_current_js_state(JoystickImpl *ji)
  373. +{
  374. +    ji->js.lX           = CENTER_AXIS(0);
  375. +    ji->js.lY           = CENTER_AXIS(1);
  376. +    ji->js.lZ           = CENTER_AXIS(2);
  377. +    ji->js.lRx          = CENTER_AXIS(3);
  378. +    ji->js.lRy          = CENTER_AXIS(4);
  379. +    ji->js.lRz          = CENTER_AXIS(5);
  380. +    ji->js.rglSlider[0] = CENTER_AXIS(6);
  381. +    ji->js.rglSlider[1] = CENTER_AXIS(7);
  382. +}
  383. +#undef CENTER_AXIS
  384. +
  385. +/* FIXME: duplication */
  386. +static void
  387. +fill_joystick_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, DWORD version, int id)
  388. +{
  389. +   DWORD       dwSize = lpddi->dwSize;
  390. +
  391. +   TRACE("%d %p\n", dwSize, lpddi);
  392. +   memset(lpddi, 0, dwSize);
  393. +
  394. +   lpddi->dwSize = dwSize;
  395. +   lpddi->guidInstance = joy_devs[id].guid;
  396. +   lpddi->guidProduct = DInput_Wine_Joystick_Base_GUID;
  397. +   lpddi->guidFFDriver = GUID_NULL;
  398. +
  399. +   if (version >= 0x0800)
  400. +       lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
  401. +   else
  402. +       lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
  403. +
  404. +   strcpy(lpddi->tszInstanceName, joy_devs[id].name);
  405. +   strcpy(lpddi->tszProductName, joy_devs[id].device);
  406. +}
  407. +
  408. +/* FIXME: duplication */
  409. +static void
  410. +fill_joystick_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
  411. +{
  412. +   DWORD       dwSize = lpddi->dwSize;
  413. +
  414. +   TRACE("%d %p\n", dwSize, lpddi);
  415. +   memset(lpddi, 0, dwSize);
  416. +
  417. +   lpddi->dwSize = dwSize;
  418. +   lpddi->guidInstance = joy_devs[id].guid;
  419. +   lpddi->guidProduct = DInput_Wine_Joystick_Base_GUID;
  420. +   lpddi->guidFFDriver = GUID_NULL;
  421. +
  422. +   if (version >= 0x0800)
  423. +       lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
  424. +   else
  425. +       lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
  426. +
  427. +   MultiByteToWideChar(CP_ACP, 0, joy_devs[id].name, -1, lpddi->tszInstanceName, MAX_PATH);
  428. +   MultiByteToWideChar(CP_ACP, 0, joy_devs[id].device, -1, lpddi->tszProductName, MAX_PATH);
  429. +}
  430. +
  431. +/* FIXME: duplication */
  432. +static BOOL
  433. +joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id)
  434. +{
  435. +   find_joy_devs();
  436. +
  437. +   if (id >= have_joy_devs) {
  438. +       return FALSE;
  439. +   }
  440. +   if (!((dwDevType == 0) ||
  441. +         ((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version < 0x0800)) ||
  442. +         (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))))
  443. +       return FALSE;
  444. +
  445. +   fill_joystick_dideviceinstanceA(lpddi, version, id);
  446. +   return TRUE;
  447. +}
  448. +
  449. +/* FIXME: duplication */
  450. +static BOOL
  451. +joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
  452. +{
  453. +   find_joy_devs();
  454. +
  455. +   if (id >= have_joy_devs) {
  456. +       return FALSE;
  457. +   }
  458. +   if (!((dwDevType == 0) ||
  459. +         ((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version < 0x0800)) ||
  460. +         (((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))))
  461. +       return FALSE;
  462. +
  463. +   fill_joystick_dideviceinstanceW(lpddi, version, id);
  464. +   return TRUE;
  465. +}
  466. +
  467. +/* FIXME: duplication */
  468. +static JoystickImpl *alloc_device(REFGUID rguid, const void *jvt, IDirectInputImpl *dinput, unsigned short index)
  469. +{
  470. +    JoystickImpl* newDevice;
  471. +    LPDIDATAFORMAT df = NULL;
  472. +    int i, idx=0;
  473. +    char buffer[MAX_PATH+16];
  474. +    HKEY hkey, appkey;
  475. +    LONG def_deadzone = 0;
  476. +
  477. +    newDevice = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(JoystickImpl));
  478. +    if (!newDevice) return NULL;
  479. +
  480. +    newDevice->base.IDirectInputDevice8A_iface.lpVtbl = &JoystickAvt;
  481. +    newDevice->base.IDirectInputDevice8W_iface.lpVtbl = &JoystickWvt;
  482. +    newDevice->base.ref    = 1;
  483. +    newDevice->base.guid   = *rguid;
  484. +    newDevice->base.dinput = dinput;
  485. +    newDevice->joyfd       = -1;
  486. +    newDevice->joydev      = &joy_devs[index];
  487. +    InitializeCriticalSection(&newDevice->base.crit);
  488. +    newDevice->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JoystickImpl*->base.crit");
  489. +
  490. +    /* get options */
  491. +    get_app_key(&hkey, &appkey);
  492. +
  493. +    if (!get_config_key(hkey, appkey, "DefaultDeadZone", buffer, MAX_PATH))
  494. +    {
  495. +        def_deadzone = atoi(buffer);
  496. +        TRACE("setting default deadzone to: %d\n", def_deadzone);
  497. +    }
  498. +    if (appkey) RegCloseKey(appkey);
  499. +    if (hkey) RegCloseKey(hkey);
  500. +
  501. +    /* Create copy of default data format */
  502. +    if (!(df = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, c_dfDIJoystick2.dwSize))) goto failed;
  503. +    memcpy(df, &c_dfDIJoystick2, c_dfDIJoystick2.dwSize);
  504. +    if (!(df->rgodf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, df->dwNumObjs * df->dwObjSize))) goto failed;
  505. +
  506. +    /* Supported Axis & POVs should map 1-to-1 */
  507. +    for (i = 0; i < newDevice->joydev->num_axes; i++) {
  508. +       memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i], df->dwObjSize);
  509. +       newDevice->props[idx].lDevMin = newDevice->joydev->axes[i].logical_minimum;
  510. +       newDevice->props[idx].lDevMax = newDevice->joydev->axes[i].logical_maximum;
  511. +       newDevice->props[idx].lMin    = 0;
  512. +       newDevice->props[idx].lMax    = 0xffff;
  513. +       newDevice->props[idx].lSaturation = 0;
  514. +       newDevice->props[idx].lDeadZone = def_deadzone;
  515. +       df->rgodf[idx].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_ABSAXIS;
  516. +       idx ++;
  517. +    }
  518. +
  519. +    for (i = 0; i < newDevice->joydev->num_buttons; i++) {
  520. +        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[WINE_JOYSTICK_MAX_AXES + WINE_JOYSTICK_MAX_POVS + i], df->dwObjSize);
  521. +        df->rgodf[idx  ].pguid = &GUID_Button;
  522. +        df->rgodf[idx].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_PSHBUTTON;
  523. +   idx ++;
  524. +    }
  525. +    df->dwNumObjs = idx;
  526. +
  527. +    fake_current_js_state(newDevice);
  528. +
  529. +    newDevice->base.data_format.wine_df = df;
  530. +    IDirectInput_AddRef((LPDIRECTINPUTDEVICE8A)newDevice->base.dinput);
  531. +    return newDevice;
  532. +
  533. +failed:
  534. +    if (df) HeapFree(GetProcessHeap(), 0, df->rgodf);
  535. +    HeapFree(GetProcessHeap(), 0, df);
  536. +    HeapFree(GetProcessHeap(), 0, newDevice);
  537. +    return NULL;
  538. +}
  539. +
  540. +/* FIXME: duplication */
  541. +/******************************************************************************
  542. +  *     get_joystick_index : Get the joystick index from a given GUID
  543. +  */
  544. +static unsigned short get_joystick_index(REFGUID guid)
  545. +{
  546. +    GUID wine_joystick = DInput_Wine_Joystick_Base_GUID;
  547. +    GUID dev_guid = *guid;
  548. +
  549. +    wine_joystick.Data3 = 0;
  550. +    dev_guid.Data3 = 0;
  551. +
  552. +    /* for the standard joystick GUID use index 0 */
  553. +    if(IsEqualGUID(&GUID_Joystick,guid)) return 0;
  554. +
  555. +    /* for the wine joystick GUIDs use the index stored in Data3 */
  556. +    if(IsEqualGUID(&wine_joystick, &dev_guid)) return guid->Data3 - DInput_Wine_Joystick_Base_GUID.Data3;
  557. +
  558. +    return MAX_UHIDDEVS;
  559. +}
  560. +
  561. +/* FIXME: duplication */
  562. +static HRESULT joydev_create_device(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPVOID *pdev, int unicode)
  563. +{
  564. +    unsigned short index;
  565. +
  566. +    TRACE("%p %s %s %p %i\n", dinput, debugstr_guid(rguid), debugstr_guid(riid), pdev, unicode);
  567. +    find_joy_devs();
  568. +
  569. +    if ((index = get_joystick_index(rguid)) < MAX_UHIDDEVS && have_joy_devs && index < have_joy_devs)
  570. +    {
  571. +        if (riid == NULL)
  572. +            ;/* nothing */
  573. +        else if (IsEqualGUID(&IID_IDirectInputDeviceA,  riid) ||
  574. +                 IsEqualGUID(&IID_IDirectInputDevice2A, riid) ||
  575. +                 IsEqualGUID(&IID_IDirectInputDevice7A, riid) ||
  576. +                 IsEqualGUID(&IID_IDirectInputDevice8A, riid))
  577. +        {
  578. +            unicode = 0;
  579. +        }
  580. +        else if (IsEqualGUID(&IID_IDirectInputDeviceW,  riid) ||
  581. +                 IsEqualGUID(&IID_IDirectInputDevice2W, riid) ||
  582. +                 IsEqualGUID(&IID_IDirectInputDevice7W, riid) ||
  583. +                 IsEqualGUID(&IID_IDirectInputDevice8W, riid))
  584. +        {
  585. +            unicode = 1;
  586. +        }
  587. +        else
  588. +        {
  589. +            WARN("no interface\n");
  590. +            return DIERR_NOINTERFACE;
  591. +        }
  592. +
  593. +   *pdev = (IDirectInputDeviceW*) alloc_device(rguid, &JoystickWvt, dinput, index);
  594. +        return DIERR_NOINTERFACE;
  595. +    }
  596. +
  597. +    return DIERR_DEVICENOTREG;
  598. +}
  599. +
  600. +const struct dinput_device joystick_bsduhid_device = {
  601. +   "Wine BSD uhid joystick driver",
  602. +   joydev_enum_deviceA,
  603. +   joydev_enum_deviceW,
  604. +   joydev_create_device
  605. +};
  606. +
  607. +/******************************************************************************
  608. +  *     Acquire : gets exclusive control of the joystick
  609. +  */
  610. +static HRESULT WINAPI JoystickAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
  611. +{
  612. +    JoystickImpl *This = (JoystickImpl *)iface;
  613. +    HRESULT res;
  614. +
  615. +    TRACE("(this=%p)\n",This);
  616. +
  617. +    res = IDirectInputDevice2AImpl_Acquire(iface);
  618. +    if (res==DI_OK) {
  619. +      if ((This->joyfd=open(This->joydev->device,O_RDWR|O_NDELAY,0))==-1) {
  620. +          /* Couldn't open in r/w but opened in read-only. */
  621. +          WARN("Could not open %s in read-write mode: %s\n", This->joydev->device, strerror(errno));
  622. +        }
  623. +      }
  624. +    return res;
  625. +}
  626. +
  627. +/******************************************************************************
  628. +  *     Unacquire : frees the joystick
  629. +  */
  630. +static HRESULT WINAPI JoystickAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface)
  631. +{
  632. +    JoystickImpl *This = (JoystickImpl *)iface;
  633. +    HRESULT res;
  634. +
  635. +    TRACE("(this=%p)\n",This);
  636. +    res = IDirectInputDevice2AImpl_Unacquire(iface);
  637. +    if (res==DI_OK && This->joyfd!=-1) {
  638. +      close(This->joyfd);
  639. +      This->joyfd = -1;
  640. +    }
  641. +    return res;
  642. +}
  643. +
  644. +static const IDirectInputDevice8AVtbl JoystickAvt =
  645. +{
  646. +   IDirectInputDevice2AImpl_QueryInterface,
  647. +   IDirectInputDevice2AImpl_AddRef,
  648. +   IDirectInputDevice2AImpl_Release,
  649. +   JoystickAGenericImpl_GetCapabilities,
  650. +   IDirectInputDevice2AImpl_EnumObjects,
  651. +   JoystickAGenericImpl_GetProperty,
  652. +   JoystickAGenericImpl_SetProperty,
  653. +   JoystickAImpl_Acquire,
  654. +   JoystickAImpl_Unacquire,
  655. +   JoystickAGenericImpl_GetDeviceState,
  656. +   IDirectInputDevice2AImpl_GetDeviceData,
  657. +   IDirectInputDevice2AImpl_SetDataFormat,
  658. +   IDirectInputDevice2AImpl_SetEventNotification,
  659. +   IDirectInputDevice2AImpl_SetCooperativeLevel,
  660. +   JoystickAGenericImpl_GetObjectInfo,
  661. +   JoystickAGenericImpl_GetDeviceInfo,
  662. +   IDirectInputDevice2AImpl_RunControlPanel,
  663. +   IDirectInputDevice2AImpl_Initialize,
  664. +   IDirectInputDevice2AImpl_CreateEffect,
  665. +   IDirectInputDevice2AImpl_EnumEffects,
  666. +   IDirectInputDevice2AImpl_GetEffectInfo,
  667. +   IDirectInputDevice2AImpl_GetForceFeedbackState,
  668. +   IDirectInputDevice2AImpl_SendForceFeedbackCommand,
  669. +   IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
  670. +   IDirectInputDevice2AImpl_Escape,
  671. +   JoystickAGenericImpl_Poll,
  672. +   IDirectInputDevice2AImpl_SendDeviceData,
  673. +   IDirectInputDevice7AImpl_EnumEffectsInFile,
  674. +   IDirectInputDevice7AImpl_WriteEffectToFile,
  675. +   JoystickAGenericImpl_BuildActionMap,
  676. +   JoystickAGenericImpl_SetActionMap,
  677. +   IDirectInputDevice8AImpl_GetImageInfo
  678. +};
  679. +
  680. +#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
  681. +# define XCAST(fun)    (typeof(JoystickWvt.fun))
  682. +#else
  683. +# define XCAST(fun)    (void*)
  684. +#endif
  685. +
  686. +static const IDirectInputDevice8WVtbl JoystickWvt =
  687. +{
  688. +   IDirectInputDevice2WImpl_QueryInterface,
  689. +   XCAST(AddRef)IDirectInputDevice2AImpl_AddRef,
  690. +   XCAST(Release)IDirectInputDevice2AImpl_Release,
  691. +   JoystickWGenericImpl_GetCapabilities,
  692. +   IDirectInputDevice2WImpl_EnumObjects,
  693. +   JoystickWGenericImpl_GetProperty,
  694. +   JoystickWGenericImpl_SetProperty,
  695. +   XCAST(Acquire)JoystickAImpl_Acquire,
  696. +   XCAST(Unacquire)JoystickAImpl_Unacquire,
  697. +   JoystickWGenericImpl_GetDeviceState,
  698. +   XCAST(GetDeviceData)IDirectInputDevice2AImpl_GetDeviceData,
  699. +   XCAST(SetDataFormat)IDirectInputDevice2AImpl_SetDataFormat,
  700. +   XCAST(SetEventNotification)IDirectInputDevice2AImpl_SetEventNotification,
  701. +   XCAST(SetCooperativeLevel)IDirectInputDevice2AImpl_SetCooperativeLevel,
  702. +   JoystickWGenericImpl_GetObjectInfo,
  703. +   JoystickWGenericImpl_GetDeviceInfo,
  704. +   XCAST(RunControlPanel)IDirectInputDevice2AImpl_RunControlPanel,
  705. +   XCAST(Initialize)IDirectInputDevice2AImpl_Initialize,
  706. +   XCAST(CreateEffect)IDirectInputDevice2AImpl_CreateEffect,
  707. +   XCAST(EnumEffects)IDirectInputDevice2AImpl_EnumEffects,
  708. +   XCAST(GetEffectInfo)IDirectInputDevice2AImpl_GetEffectInfo,
  709. +   XCAST(GetForceFeedbackState)IDirectInputDevice2AImpl_GetForceFeedbackState,
  710. +   XCAST(SendForceFeedbackCommand)IDirectInputDevice2AImpl_SendForceFeedbackCommand,
  711. +   XCAST(EnumCreatedEffectObjects)IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
  712. +   XCAST(Escape)IDirectInputDevice2AImpl_Escape,
  713. +   JoystickWGenericImpl_Poll,
  714. +   XCAST(SendDeviceData)IDirectInputDevice2AImpl_SendDeviceData,
  715. +   IDirectInputDevice7WImpl_EnumEffectsInFile,
  716. +   IDirectInputDevice7WImpl_WriteEffectToFile,
  717. +   JoystickWGenericImpl_BuildActionMap,
  718. +   JoystickWGenericImpl_SetActionMap,
  719. +   IDirectInputDevice8WImpl_GetImageInfo
  720. +};
  721. +#undef XCAST
  722. +
  723. +#else /* HAVE_USBHID_H */
  724. +
  725. +const struct dinput_device joystick_bsduhid_device = {
  726. +   "Wine BSD uhid joystick driver",
  727. +   NULL,
  728. +   NULL,
  729. +   NULL
  730. +};
  731. +
  732. +#endif /* HAVE_USBHID_H */
  733. diff --git a/include/config.h.in b/include/config.h.in
  734. index 9dc3e14..864748f 100644
  735. --- a/include/config.h.in
  736. +++ b/include/config.h.in
  737. @@ -1082,6 +1082,9 @@
  738.  /* Define to 1 if you have the <unistd.h> header file. */
  739.  #undef HAVE_UNISTD_H
  740.  
  741. +/* Define to 1 if you have the <usbhid.h> header file. */
  742. +#undef HAVE_USBHID_H
  743. +
  744.  /* Define to 1 if you have the `usleep' function. */
  745.  #undef HAVE_USLEEP
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement