winejoystick.drv: Remove unnecessary driver.

Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Rémi Bernon 2021-12-10 09:44:49 +01:00 committed by Alexandre Julliard
parent 4f1095a0ee
commit f9d7acbf45
10 changed files with 0 additions and 1590 deletions

56
configure vendored
View File

@ -1717,7 +1717,6 @@ enable_winecrt0
enable_wined3d
enable_winegstreamer
enable_winehid_sys
enable_winejoystick_drv
enable_winemac_drv
enable_winemapi
enable_wineoss_drv
@ -8317,12 +8316,6 @@ if test "x$ac_cv_header_linux_ioctl_h" = xyes
then :
printf "%s\n" "#define HAVE_LINUX_IOCTL_H 1" >>confdefs.h
fi
ac_fn_c_check_header_compile "$LINENO" "linux/joystick.h" "ac_cv_header_linux_joystick_h" "$ac_includes_default"
if test "x$ac_cv_header_linux_joystick_h" = xyes
then :
printf "%s\n" "#define HAVE_LINUX_JOYSTICK_H 1" >>confdefs.h
fi
ac_fn_c_check_header_compile "$LINENO" "linux/major.h" "ac_cv_header_linux_major_h" "$ac_includes_default"
if test "x$ac_cv_header_linux_major_h" = xyes
@ -10870,7 +10863,6 @@ esac
enable_winecoreaudio_drv=${enable_winecoreaudio_drv:-no}
enable_wineandroid_drv=${enable_wineandroid_drv:-no}
enable_winemac_drv=${enable_winemac_drv:-no}
test "$ac_cv_header_linux_joystick_h" = "yes" -o "$ac_cv_header_IOKit_hid_IOHIDLib_h" = "yes" || enable_winejoystick_drv=${enable_winejoystick_drv:-no}
if test "x$with_mingw" != xno
@ -20567,53 +20559,6 @@ printf "%s\n" "#define HAVE_LINUX_GETHOSTBYNAME_R_6 1" >>confdefs.h
fi
if test "$ac_cv_header_linux_joystick_h" = "yes"
then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether linux/joystick.h uses the Linux 2.2+ API" >&5
printf %s "checking whether linux/joystick.h uses the Linux 2.2+ API... " >&6; }
if test ${wine_cv_linux_joystick_22_api+y}
then :
printf %s "(cached) " >&6
else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/ioctl.h>
#include <sys/types.h>
#include <linux/joystick.h>
struct js_event blub;
#if !defined(JS_EVENT_AXIS) || !defined(JS_EVENT_BUTTON)
#error "no 2.2 header"
#endif
int
main (void)
{
/*empty*/
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
wine_cv_linux_joystick_22_api=yes
else $as_nop
wine_cv_linux_joystick_22_api=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $wine_cv_linux_joystick_22_api" >&5
printf "%s\n" "$wine_cv_linux_joystick_22_api" >&6; }
if test "$wine_cv_linux_joystick_22_api" = "yes"
then
printf "%s\n" "#define HAVE_LINUX_22_JOYSTICK_API 1" >>confdefs.h
fi
fi
ac_fn_c_check_member "$LINENO" "struct msghdr" "msg_accrights" "ac_cv_member_struct_msghdr_msg_accrights" "#include <sys/types.h>
#include <sys/socket.h>
#ifdef HAVE_SYS_UN_H
@ -22516,7 +22461,6 @@ wine_fn_config_makefile dlls/winecrt0 enable_winecrt0
wine_fn_config_makefile dlls/wined3d enable_wined3d
wine_fn_config_makefile dlls/winegstreamer enable_winegstreamer
wine_fn_config_makefile dlls/winehid.sys enable_winehid_sys
wine_fn_config_makefile dlls/winejoystick.drv enable_winejoystick_drv
wine_fn_config_makefile dlls/winemac.drv enable_winemac_drv
wine_fn_config_makefile dlls/winemapi enable_winemapi
wine_fn_config_makefile dlls/wineoss.drv enable_wineoss_drv

View File

@ -445,7 +445,6 @@ AC_CHECK_HEADERS(\
linux/hidraw.h \
linux/input.h \
linux/ioctl.h \
linux/joystick.h \
linux/major.h \
linux/param.h \
linux/serial.h \
@ -866,7 +865,6 @@ esac
enable_winecoreaudio_drv=${enable_winecoreaudio_drv:-no}
enable_wineandroid_drv=${enable_wineandroid_drv:-no}
enable_winemac_drv=${enable_winemac_drv:-no}
test "$ac_cv_header_linux_joystick_h" = "yes" -o "$ac_cv_header_IOKit_hid_IOHIDLib_h" = "yes" || enable_winejoystick_drv=${enable_winejoystick_drv:-no}
dnl Check for cross compiler to build test programs
AC_SUBST(CROSSTARGET)
@ -2108,28 +2106,6 @@ AC_CACHE_CHECK([whether we can use re-entrant gethostbyname_r Linux style],
[Define if Linux-style gethostbyname_r and gethostbyaddr_r are available])
fi
if test "$ac_cv_header_linux_joystick_h" = "yes"
then
AC_CACHE_CHECK([whether linux/joystick.h uses the Linux 2.2+ API],
wine_cv_linux_joystick_22_api,
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/ioctl.h>
#include <sys/types.h>
#include <linux/joystick.h>
struct js_event blub;
#if !defined(JS_EVENT_AXIS) || !defined(JS_EVENT_BUTTON)
#error "no 2.2 header"
#endif
]], [[/*empty*/]])],[wine_cv_linux_joystick_22_api=yes],[wine_cv_linux_joystick_22_api=no])
)
if test "$wine_cv_linux_joystick_22_api" = "yes"
then
AC_DEFINE(HAVE_LINUX_22_JOYSTICK_API, 1,
[Define if <linux/joystick.h> defines the Linux 2.2 joystick API])
fi
fi
dnl Check for socket structure members
AC_CHECK_MEMBERS([struct msghdr.msg_accrights, struct sockaddr_un.sun_len],,,
[#include <sys/types.h>
@ -3409,7 +3385,6 @@ WINE_CONFIG_MAKEFILE(dlls/winecrt0)
WINE_CONFIG_MAKEFILE(dlls/wined3d)
WINE_CONFIG_MAKEFILE(dlls/winegstreamer)
WINE_CONFIG_MAKEFILE(dlls/winehid.sys)
WINE_CONFIG_MAKEFILE(dlls/winejoystick.drv)
WINE_CONFIG_MAKEFILE(dlls/winemac.drv)
WINE_CONFIG_MAKEFILE(dlls/winemapi)
WINE_CONFIG_MAKEFILE(dlls/wineoss.drv)

View File

@ -1,10 +0,0 @@
MODULE = winejoystick.drv
IMPORTS = winmm user32
EXTRALIBS = $(IOKIT_LIBS)
EXTRADLLFLAGS = -mcygwin
C_SRCS = \
joystick.c \
joystick_linux.c \
joystick_osx.c

View File

@ -1,52 +0,0 @@
/*
* WinMM joystick driver common code
*
* Copyright 1997 Andreas Mohr
* Copyright 2000 Wolfgang Schwotzer
* Copyright 2002 David Hagood
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "joystick.h"
/**************************************************************************
* DriverProc (JOYSTICK.@)
*/
LRESULT CALLBACK JSTCK_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, LPARAM dwParam1, LPARAM dwParam2)
{
switch(wMsg) {
case DRV_LOAD: return 1;
case DRV_FREE: return 1;
case DRV_OPEN: return driver_open((LPSTR)dwParam1, dwParam2);
case DRV_CLOSE: return driver_close(dwDevID);
case DRV_ENABLE: return 1;
case DRV_DISABLE: return 1;
case DRV_QUERYCONFIGURE: return 1;
case DRV_CONFIGURE: MessageBoxA(0, "JoyStick MultiMedia Driver !", "JoyStick Driver", MB_OK); return 1;
case DRV_INSTALL: return DRVCNF_RESTART;
case DRV_REMOVE: return DRVCNF_RESTART;
case JDD_GETNUMDEVS: return 1;
case JDD_GETDEVCAPS: return driver_joyGetDevCaps(dwDevID, (LPJOYCAPSW)dwParam1, dwParam2);
case JDD_GETPOS: return driver_joyGetPos(dwDevID, (LPJOYINFO)dwParam1);
case JDD_SETCALIBRATION:
case JDD_CONFIGCHANGED: return JOYERR_NOCANDO;
case JDD_GETPOSEX: return driver_joyGetPosEx(dwDevID, (LPJOYINFOEX)dwParam1);
default:
return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
}
}

View File

@ -1,34 +0,0 @@
/*
* WinMM joystick driver header
*
* Copyright 2015 Ken Thomases for CodeWeavers Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "mmddk.h"
#include "winuser.h"
LRESULT driver_open(LPSTR str, DWORD index) DECLSPEC_HIDDEN;
LRESULT driver_close(DWORD_PTR device_id) DECLSPEC_HIDDEN;
LRESULT driver_joyGetDevCaps(DWORD_PTR device_id, JOYCAPSW* caps, DWORD size) DECLSPEC_HIDDEN;
LRESULT driver_joyGetPosEx(DWORD_PTR device_id, JOYINFOEX* info) DECLSPEC_HIDDEN;
LRESULT driver_joyGetPos(DWORD_PTR device_id, JOYINFO* info) DECLSPEC_HIDDEN;

View File

@ -1,458 +0,0 @@
/*
* joystick functions
*
* Copyright 1997 Andreas Mohr
* Copyright 2000 Wolfgang Schwotzer
* Copyright 2002 David Hagood
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* NOTES:
*
* - nearly all joystick functions can be regarded as obsolete,
* as Linux (2.1.x) now supports extended joysticks with a completely
* new joystick driver interface
* New driver's documentation says:
* "For backward compatibility the old interface is still included,
* but will be dropped in the future."
* Thus we should implement the new interface and at most keep the old
* routines for backward compatibility.
* - better support of enhanced joysticks (Linux 2.2 interface is available)
* - support more joystick drivers (like the XInput extension)
* - should load joystick DLL as any other driver (instead of hardcoding)
* the driver's name, and load it as any low lever driver.
*/
#include "config.h"
#ifdef HAVE_LINUX_22_JOYSTICK_API
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#ifdef HAVE_LINUX_IOCTL_H
#include <linux/ioctl.h>
#endif
#include <linux/joystick.h>
#ifdef SW_MAX
#undef SW_MAX
#endif
#define JOYDEV_NEW "/dev/input/js%d"
#define JOYDEV_OLD "/dev/js%d"
#include <errno.h>
#include "joystick.h"
#include "wingdi.h"
#include "winnls.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(joystick);
#define MAXJOYSTICK (JOYSTICKID2 + 30)
typedef struct tagWINE_JSTCK {
int joyIntf;
BOOL in_use;
/* Some extra info we need to make this actually work under the
Linux 2.2 event api.
First of all, we cannot keep closing and reopening the device file -
that blows away the state of the stick device, and we lose events. So, we
need to open the low-level device once, and close it when we are done.
Secondly, the event API only gives us what's changed. However, Windows apps
want the whole state every time, so we have to cache the data.
*/
int dev; /* Linux level device file descriptor */
int x;
int y;
int z;
int r;
int u;
int v;
int pov_x;
int pov_y;
int buttons;
char axesMap[ABS_MAX + 1];
} WINE_JSTCK;
static WINE_JSTCK JSTCK_Data[MAXJOYSTICK];
/**************************************************************************
* JSTCK_drvGet [internal]
*/
static WINE_JSTCK *JSTCK_drvGet(DWORD_PTR dwDevID)
{
int p;
if ((dwDevID - (DWORD_PTR)JSTCK_Data) % sizeof(JSTCK_Data[0]) != 0)
return NULL;
p = (dwDevID - (DWORD_PTR)JSTCK_Data) / sizeof(JSTCK_Data[0]);
if (p < 0 || p >= MAXJOYSTICK || !((WINE_JSTCK*)dwDevID)->in_use)
return NULL;
return (WINE_JSTCK*)dwDevID;
}
/**************************************************************************
* driver_open
*/
LRESULT driver_open(LPSTR str, DWORD dwIntf)
{
if (dwIntf >= MAXJOYSTICK || JSTCK_Data[dwIntf].in_use)
return 0;
JSTCK_Data[dwIntf].joyIntf = dwIntf;
JSTCK_Data[dwIntf].dev = -1;
JSTCK_Data[dwIntf].in_use = TRUE;
return (LRESULT)&JSTCK_Data[dwIntf];
}
/**************************************************************************
* driver_close
*/
LRESULT driver_close(DWORD_PTR dwDevID)
{
WINE_JSTCK* jstck = JSTCK_drvGet(dwDevID);
if (jstck == NULL)
return 0;
jstck->in_use = FALSE;
if (jstck->dev > 0)
{
close(jstck->dev);
jstck->dev = 0;
}
return 1;
}
struct js_status
{
int buttons;
int x;
int y;
};
/**************************************************************************
* JSTCK_OpenDevice [internal]
*/
static int JSTCK_OpenDevice(WINE_JSTCK* jstick)
{
char buf[20];
int flags, fd, found_ix, i;
static DWORD last_attempt;
DWORD now;
if (jstick->dev > 0)
return jstick->dev;
now = GetTickCount();
if (now - last_attempt < 2000)
return -1;
last_attempt = now;
flags = O_RDONLY | O_NONBLOCK;
/* The first joystick may not be at /dev/input/js0, find the correct
* first or second device. For example the driver for XBOX 360 wireless
* receiver creates entries starting at 20.
*/
for (found_ix = i = 0; i < MAXJOYSTICK; i++) {
sprintf(buf, JOYDEV_NEW, i);
if ((fd = open(buf, flags)) < 0) {
sprintf(buf, JOYDEV_OLD, i);
if ((fd = open(buf, flags)) < 0)
continue;
}
if (found_ix++ == jstick->joyIntf)
{
TRACE("Found joystick[%d] at %s\n", jstick->joyIntf, buf);
jstick->dev = fd;
last_attempt = 0;
break;
}
close(fd);
}
if (jstick->dev > 0)
ioctl(jstick->dev, JSIOCGAXMAP, jstick->axesMap);
return jstick->dev;
}
/**************************************************************************
* JoyGetDevCaps [MMSYSTEM.102]
*/
LRESULT driver_joyGetDevCaps(DWORD_PTR dwDevID, LPJOYCAPSW lpCaps, DWORD dwSize)
{
WINE_JSTCK* jstck;
int dev;
char nrOfAxes;
char nrOfButtons;
char identString[MAXPNAMELEN];
int i;
int driverVersion;
if ((jstck = JSTCK_drvGet(dwDevID)) == NULL)
return MMSYSERR_NODRIVER;
if ((dev = JSTCK_OpenDevice(jstck)) < 0) return JOYERR_PARMS;
ioctl(dev, JSIOCGAXES, &nrOfAxes);
ioctl(dev, JSIOCGBUTTONS, &nrOfButtons);
ioctl(dev, JSIOCGVERSION, &driverVersion);
ioctl(dev, JSIOCGNAME(sizeof(identString)), identString);
TRACE("Driver: 0x%06x, Name: %s, #Axes: %d, #Buttons: %d\n",
driverVersion, identString, nrOfAxes, nrOfButtons);
lpCaps->wMid = MM_MICROSOFT;
lpCaps->wPid = MM_PC_JOYSTICK;
MultiByteToWideChar(CP_UNIXCP, 0, identString, -1, lpCaps->szPname, MAXPNAMELEN);
lpCaps->szPname[MAXPNAMELEN-1] = '\0';
lpCaps->wXmin = 0;
lpCaps->wXmax = 0xFFFF;
lpCaps->wYmin = 0;
lpCaps->wYmax = 0xFFFF;
lpCaps->wZmin = 0;
lpCaps->wZmax = (nrOfAxes >= 3) ? 0xFFFF : 0;
#ifdef BODGE_THE_HAT
/* Half-Life won't allow you to map an axis event to things like
"next weapon" and "use". Linux reports the hat on my stick as
axis U and V. So, IFF BODGE_THE_HAT is defined, lie through our
teeth and say we have 32 buttons, and we will map the axes to
the high buttons. Really, perhaps this should be a registry entry,
or even a parameter to the Linux joystick driver (which would completely
remove the need for this.)
*/
lpCaps->wNumButtons = 32;
#else
lpCaps->wNumButtons = nrOfButtons;
#endif
if (dwSize == sizeof(JOYCAPSW)) {
/* complete 95 structure */
lpCaps->wRmin = 0;
lpCaps->wRmax = 0xFFFF;
lpCaps->wUmin = 0;
lpCaps->wUmax = 0xFFFF;
lpCaps->wVmin = 0;
lpCaps->wVmax = 0xFFFF;
lpCaps->wMaxAxes = 6; /* same as MS Joystick Driver */
lpCaps->wNumAxes = 0; /* nr of axes in use */
lpCaps->wMaxButtons = 32; /* same as MS Joystick Driver */
lpCaps->szRegKey[0] = 0;
lpCaps->szOEMVxD[0] = 0;
lpCaps->wCaps = 0;
for (i = 0; i < nrOfAxes; i++) {
switch (jstck->axesMap[i]) {
case 0: /* X */
case 1: /* Y */
case 8: /* Wheel */
case 9: /* Gas */
lpCaps->wNumAxes++;
break;
case 2: /* Z */
case 6: /* Throttle */
case 10: /* Brake */
lpCaps->wNumAxes++;
lpCaps->wCaps |= JOYCAPS_HASZ;
break;
case 5: /* Rz */
case 7: /* Rudder */
lpCaps->wNumAxes++;
lpCaps->wCaps |= JOYCAPS_HASR;
break;
case 3: /* Rx */
lpCaps->wNumAxes++;
lpCaps->wCaps |= JOYCAPS_HASU;
break;
case 4: /* Ry */
lpCaps->wNumAxes++;
lpCaps->wCaps |= JOYCAPS_HASV;
break;
case 16: /* Hat 0 X */
case 17: /* Hat 0 Y */
lpCaps->wCaps |= JOYCAPS_HASPOV | JOYCAPS_POV4DIR;
/* TODO: JOYCAPS_POVCTS handling */
break;
default:
WARN("Unknown axis %hhu(%u). Skipped.\n", jstck->axesMap[i], i);
}
}
}
return JOYERR_NOERROR;
}
/**************************************************************************
* driver_joyGetPos
*/
LRESULT driver_joyGetPosEx(DWORD_PTR dwDevID, LPJOYINFOEX lpInfo)
{
WINE_JSTCK* jstck;
int dev;
struct js_event ev;
if ((jstck = JSTCK_drvGet(dwDevID)) == NULL)
return MMSYSERR_NODRIVER;
if ((dev = JSTCK_OpenDevice(jstck)) < 0) return JOYERR_PARMS;
while ((read(dev, &ev, sizeof(struct js_event))) > 0) {
if (ev.type == (JS_EVENT_AXIS)) {
switch (jstck->axesMap[ev.number]) {
case 0: /* X */
case 8: /* Wheel */
jstck->x = ev.value;
break;
case 1: /* Y */
case 9: /* Gas */
jstck->y = ev.value;
break;
case 2: /* Z */
case 6: /* Throttle */
case 10: /* Brake */
jstck->z = ev.value;
break;
case 5: /* Rz */
case 7: /* Rudder */
jstck->r = ev.value;
break;
case 3: /* Rx */
jstck->u = ev.value;
break;
case 4: /* Ry */
jstck->v = ev.value;
break;
case 16: /* Hat 0 X */
jstck->pov_x = ev.value;
break;
case 17: /* Hat 0 Y */
jstck->pov_y = ev.value;
break;
default:
FIXME("Unknown joystick event '%d'\n", ev.number);
}
} else if (ev.type == (JS_EVENT_BUTTON)) {
if (ev.value) {
jstck->buttons |= (1 << ev.number);
/* FIXME: what to do for this field when
* multiple buttons are depressed ?
*/
if (lpInfo->dwFlags & JOY_RETURNBUTTONS)
lpInfo->dwButtonNumber = ev.number + 1;
}
else
jstck->buttons &= ~(1 << ev.number);
}
}
/* EAGAIN is returned when the queue is empty */
if (errno != EAGAIN) {
/* FIXME: error should not be ignored */
ERR("Error while reading joystick state (%s)\n", strerror(errno));
}
/* Now, copy the cached values into Window's structure... */
if (lpInfo->dwFlags & JOY_RETURNBUTTONS)
lpInfo->dwButtons = jstck->buttons;
if (lpInfo->dwFlags & JOY_RETURNX)
lpInfo->dwXpos = jstck->x + 32767;
if (lpInfo->dwFlags & JOY_RETURNY)
lpInfo->dwYpos = jstck->y + 32767;
if (lpInfo->dwFlags & JOY_RETURNZ)
lpInfo->dwZpos = jstck->z + 32767;
if (lpInfo->dwFlags & JOY_RETURNR)
lpInfo->dwRpos = jstck->r + 32767;
# ifdef BODGE_THE_HAT
else if (lpInfo->dwFlags & JOY_RETURNBUTTONS)
{
if (jstck->r > 0)
lpInfo->dwButtons |= 1<<7;
else if (jstck->r < 0)
lpInfo->dwButtons |= 1<<8;
}
# endif
if (lpInfo->dwFlags & JOY_RETURNU)
lpInfo->dwUpos = jstck->u + 32767;
# ifdef BODGE_THE_HAT
else if (lpInfo->dwFlags & JOY_RETURNBUTTONS)
{
if (jstck->u > 0)
lpInfo->dwButtons |= 1<<9;
else if (jstck->u < 0)
lpInfo->dwButtons |= 1<<10;
}
# endif
if (lpInfo->dwFlags & JOY_RETURNV)
lpInfo->dwVpos = jstck->v + 32767;
if (lpInfo->dwFlags & JOY_RETURNPOV) {
if (jstck->pov_y > 0) {
if (jstck->pov_x < 0)
lpInfo->dwPOV = 22500; /* SW */
else if (jstck->pov_x > 0)
lpInfo->dwPOV = 13500; /* SE */
else
lpInfo->dwPOV = 18000; /* S, JOY_POVBACKWARD */
} else if (jstck->pov_y < 0) {
if (jstck->pov_x < 0)
lpInfo->dwPOV = 31500; /* NW */
else if (jstck->pov_x > 0)
lpInfo->dwPOV = 4500; /* NE */
else
lpInfo->dwPOV = 0; /* N, JOY_POVFORWARD */
} else if (jstck->pov_x < 0)
lpInfo->dwPOV = 27000; /* W, JOY_POVLEFT */
else if (jstck->pov_x > 0)
lpInfo->dwPOV = 9000; /* E, JOY_POVRIGHT */
else
lpInfo->dwPOV = JOY_POVCENTERED; /* Center */
}
TRACE("x: %d, y: %d, z: %d, r: %d, u: %d, v: %d, buttons: 0x%04x, flags: 0x%04x (fd %d)\n",
lpInfo->dwXpos, lpInfo->dwYpos, lpInfo->dwZpos,
lpInfo->dwRpos, lpInfo->dwUpos, lpInfo->dwVpos,
lpInfo->dwButtons, lpInfo->dwFlags, dev
);
return JOYERR_NOERROR;
}
/**************************************************************************
* driver_joyGetPos
*/
LRESULT driver_joyGetPos(DWORD_PTR dwDevID, LPJOYINFO lpInfo)
{
JOYINFOEX ji;
LONG ret;
memset(&ji, 0, sizeof(ji));
ji.dwSize = sizeof(ji);
ji.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | JOY_RETURNBUTTONS;
ret = driver_joyGetPosEx(dwDevID, &ji);
if (ret == JOYERR_NOERROR) {
lpInfo->wXpos = ji.dwXpos;
lpInfo->wYpos = ji.dwYpos;
lpInfo->wZpos = ji.dwZpos;
lpInfo->wButtons = ji.dwButtons;
}
return ret;
}
#endif /* HAVE_LINUX_JOYSTICK_H */

View File

@ -1,935 +0,0 @@
/*
* WinMM joystick driver OS X implementation
*
* Copyright 1997 Andreas Mohr
* Copyright 1998 Marcus Meissner
* Copyright 1998,1999 Lionel Ulmer
* Copyright 2000 Wolfgang Schwotzer
* Copyright 2000-2001 TransGaming Technologies Inc.
* Copyright 2002 David Hagood
* Copyright 2009 CodeWeavers, Aric Stewart
* Copyright 2015 Ken Thomases for CodeWeavers Inc.
* Copyright 2016 David Lawrie
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#if defined(HAVE_IOKIT_HID_IOHIDLIB_H)
#define DWORD UInt32
#define LPDWORD UInt32*
#define LONG SInt32
#define LPLONG SInt32*
#define E_PENDING __carbon_E_PENDING
#define ULONG __carbon_ULONG
#define E_INVALIDARG __carbon_E_INVALIDARG
#define E_OUTOFMEMORY __carbon_E_OUTOFMEMORY
#define E_HANDLE __carbon_E_HANDLE
#define E_ACCESSDENIED __carbon_E_ACCESSDENIED
#define E_UNEXPECTED __carbon_E_UNEXPECTED
#define E_FAIL __carbon_E_FAIL
#define E_ABORT __carbon_E_ABORT
#define E_POINTER __carbon_E_POINTER
#define E_NOINTERFACE __carbon_E_NOINTERFACE
#define E_NOTIMPL __carbon_E_NOTIMPL
#define S_FALSE __carbon_S_FALSE
#define S_OK __carbon_S_OK
#define HRESULT_FACILITY __carbon_HRESULT_FACILITY
#define IS_ERROR __carbon_IS_ERROR
#define FAILED __carbon_FAILED
#define SUCCEEDED __carbon_SUCCEEDED
#define MAKE_HRESULT __carbon_MAKE_HRESULT
#define HRESULT __carbon_HRESULT
#define STDMETHODCALLTYPE __carbon_STDMETHODCALLTYPE
#include <IOKit/IOKitLib.h>
#include <IOKit/hid/IOHIDLib.h>
#undef ULONG
#undef E_INVALIDARG
#undef E_OUTOFMEMORY
#undef E_HANDLE
#undef E_ACCESSDENIED
#undef E_UNEXPECTED
#undef E_FAIL
#undef E_ABORT
#undef E_POINTER
#undef E_NOINTERFACE
#undef E_NOTIMPL
#undef S_FALSE
#undef S_OK
#undef HRESULT_FACILITY
#undef IS_ERROR
#undef FAILED
#undef SUCCEEDED
#undef MAKE_HRESULT
#undef HRESULT
#undef STDMETHODCALLTYPE
#undef DWORD
#undef LPDWORD
#undef LONG
#undef LPLONG
#undef E_PENDING
#include "joystick.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(joystick);
#define MAXJOYSTICK (JOYSTICKID2 + 30)
enum {
AXIS_X, /* Winmm X */
AXIS_Y, /* Winmm Y */
AXIS_Z, /* Winmm Z */
AXIS_RX, /* Winmm V */
AXIS_RY, /* Winmm U */
AXIS_RZ, /* Winmm R */
NUM_AXES
};
struct axis {
IOHIDElementRef element;
CFIndex min_value, max_value;
};
typedef struct {
BOOL in_use;
IOHIDElementRef element;
struct axis axes[NUM_AXES];
CFMutableArrayRef buttons;
IOHIDElementRef hatswitch;
} joystick_t;
static joystick_t joysticks[MAXJOYSTICK];
static CFMutableArrayRef device_main_elements = NULL;
static long get_device_property_long(IOHIDDeviceRef device, CFStringRef key)
{
CFTypeRef ref;
long result = 0;
if (device)
{
assert(IOHIDDeviceGetTypeID() == CFGetTypeID(device));
ref = IOHIDDeviceGetProperty(device, key);
if (ref && CFNumberGetTypeID() == CFGetTypeID(ref))
CFNumberGetValue((CFNumberRef)ref, kCFNumberLongType, &result);
}
return result;
}
static CFStringRef copy_device_name(IOHIDDeviceRef device)
{
CFStringRef name;
if (device)
{
CFTypeRef ref_name;
assert(IOHIDDeviceGetTypeID() == CFGetTypeID(device));
ref_name = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
if (ref_name && CFStringGetTypeID() == CFGetTypeID(ref_name))
name = CFStringCreateCopy(kCFAllocatorDefault, ref_name);
else
{
long vendID, prodID;
vendID = get_device_property_long(device, CFSTR(kIOHIDVendorIDKey));
prodID = get_device_property_long(device, CFSTR(kIOHIDProductIDKey));
name = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("0x%04lx 0x%04lx"), vendID, prodID);
}
}
else
{
ERR("NULL device\n");
name = CFStringCreateCopy(kCFAllocatorDefault, CFSTR(""));
}
return name;
}
static long get_device_location_ID(IOHIDDeviceRef device)
{
return get_device_property_long(device, CFSTR(kIOHIDLocationIDKey));
}
static const char* debugstr_cf(CFTypeRef t)
{
CFStringRef s;
const char* ret;
if (!t) return "(null)";
if (CFGetTypeID(t) == CFStringGetTypeID())
s = t;
else
s = CFCopyDescription(t);
ret = CFStringGetCStringPtr(s, kCFStringEncodingUTF8);
if (ret) ret = debugstr_a(ret);
if (!ret)
{
const UniChar* u = CFStringGetCharactersPtr(s);
if (u)
ret = debugstr_wn((const WCHAR*)u, CFStringGetLength(s));
}
if (!ret)
{
UniChar buf[200];
int len = min(CFStringGetLength(s), ARRAY_SIZE(buf));
CFStringGetCharacters(s, CFRangeMake(0, len), buf);
ret = debugstr_wn(buf, len);
}
if (s != t) CFRelease(s);
return ret;
}
static const char* debugstr_device(IOHIDDeviceRef device)
{
return wine_dbg_sprintf("<IOHIDDevice %p product %s IOHIDLocationID %lu>", device,
debugstr_cf(IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey))),
get_device_location_ID(device));
}
static const char* debugstr_element(IOHIDElementRef element)
{
return wine_dbg_sprintf("<IOHIDElement %p type %d usage %u/%u device %p>", element,
IOHIDElementGetType(element), IOHIDElementGetUsagePage(element),
IOHIDElementGetUsage(element), IOHIDElementGetDevice(element));
}
static int axis_for_usage_GD(int usage)
{
switch (usage)
{
case kHIDUsage_GD_X: return AXIS_X;
case kHIDUsage_GD_Y: return AXIS_Y;
case kHIDUsage_GD_Z: return AXIS_Z;
case kHIDUsage_GD_Rx: return AXIS_RX;
case kHIDUsage_GD_Ry: return AXIS_RY;
case kHIDUsage_GD_Rz: return AXIS_RZ;
}
return -1;
}
static int axis_for_usage_Sim(int usage)
{
switch (usage)
{
case kHIDUsage_Sim_Rudder: return AXIS_RZ;
case kHIDUsage_Sim_Throttle: return AXIS_Z;
case kHIDUsage_Sim_Steering: return AXIS_X;
case kHIDUsage_Sim_Accelerator: return AXIS_Y;
case kHIDUsage_Sim_Brake: return AXIS_RZ;
}
return -1;
}
/**************************************************************************
* joystick_from_id
*/
static joystick_t* joystick_from_id(DWORD_PTR device_id)
{
int index;
if ((device_id - (DWORD_PTR)joysticks) % sizeof(joysticks[0]) != 0)
return NULL;
index = (device_id - (DWORD_PTR)joysticks) / sizeof(joysticks[0]);
if (index < 0 || index >= MAXJOYSTICK || !((joystick_t*)device_id)->in_use)
return NULL;
return (joystick_t*)device_id;
}
/**************************************************************************
* create_osx_device_match
*/
static CFDictionaryRef create_osx_device_match(int usage)
{
CFDictionaryRef result = NULL;
int number;
CFStringRef keys[] = { CFSTR(kIOHIDDeviceUsagePageKey), CFSTR(kIOHIDDeviceUsageKey) };
CFNumberRef values[2];
int i;
TRACE("usage %d\n", usage);
number = kHIDPage_GenericDesktop;
values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &number);
values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage);
if (values[0] && values[1])
{
result = CFDictionaryCreate(NULL, (const void**)keys, (const void**)values, ARRAY_SIZE(values),
&kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if (!result)
ERR("CFDictionaryCreate failed.\n");
}
else
ERR("CFNumberCreate failed.\n");
for (i = 0; i < ARRAY_SIZE(values); i++)
if (values[i]) CFRelease(values[i]);
return result;
}
/**************************************************************************
* find_top_level
*/
static CFIndex find_top_level(IOHIDDeviceRef hid_device, CFMutableArrayRef main_elements)
{
CFArrayRef elements;
CFIndex total = 0;
TRACE("hid_device %s\n", debugstr_device(hid_device));
if (!hid_device)
return 0;
elements = IOHIDDeviceCopyMatchingElements(hid_device, NULL, 0);
if (elements)
{
CFIndex i, count = CFArrayGetCount(elements);
for (i = 0; i < count; i++)
{
IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i);
int type = IOHIDElementGetType(element);
TRACE("element %s\n", debugstr_element(element));
/* Check for top-level gaming device collections */
if (type == kIOHIDElementTypeCollection && IOHIDElementGetParent(element) == 0)
{
int usage_page = IOHIDElementGetUsagePage(element);
int usage = IOHIDElementGetUsage(element);
if (usage_page == kHIDPage_GenericDesktop &&
(usage == kHIDUsage_GD_Joystick || usage == kHIDUsage_GD_GamePad || usage == kHIDUsage_GD_MultiAxisController))
{
CFArrayAppendValue(main_elements, element);
total++;
}
}
}
CFRelease(elements);
}
TRACE("-> total %d\n", (int)total);
return total;
}
/**************************************************************************
* device_name_comparator
*
* Virtual joysticks may not have a kIOHIDLocationIDKey and will default to location ID of 0, this orders virtual joysticks by their name
*/
static CFComparisonResult device_name_comparator(IOHIDDeviceRef device1, IOHIDDeviceRef device2)
{
CFStringRef name1 = copy_device_name(device1), name2 = copy_device_name(device2);
CFComparisonResult result = CFStringCompare(name1, name2, (kCFCompareForcedOrdering | kCFCompareNumerically));
CFRelease(name1);
CFRelease(name2);
return result;
}
/**************************************************************************
* device_location_name_comparator
*
* Helper to sort device array first by location ID, since location IDs are consistent across boots & launches, then by product name
*/
static CFComparisonResult device_location_name_comparator(const void *val1, const void *val2, void *context)
{
IOHIDDeviceRef device1 = (IOHIDDeviceRef)val1, device2 = (IOHIDDeviceRef)val2;
long loc1 = get_device_location_ID(device1), loc2 = get_device_location_ID(device2);
if (loc1 < loc2)
return kCFCompareLessThan;
else if (loc1 > loc2)
return kCFCompareGreaterThan;
return device_name_comparator(device1, device2);
}
/**************************************************************************
* copy_set_to_array
*
* Helper to copy the CFSet to a CFArray
*/
static void copy_set_to_array(const void *value, void *context)
{
CFArrayAppendValue(context, value);
}
/**************************************************************************
* find_osx_devices
*/
static int find_osx_devices(void)
{
IOHIDManagerRef hid_manager;
int usages[] = { kHIDUsage_GD_Joystick, kHIDUsage_GD_GamePad, kHIDUsage_GD_MultiAxisController };
int i;
CFDictionaryRef matching_dicts[ARRAY_SIZE(usages)];
CFArrayRef matching;
CFSetRef devset;
TRACE("()\n");
hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, 0L);
if (IOHIDManagerOpen(hid_manager, 0) != kIOReturnSuccess)
{
ERR("Couldn't open IOHIDManager.\n");
CFRelease(hid_manager);
return 0;
}
for (i = 0; i < ARRAY_SIZE(matching_dicts); i++)
{
matching_dicts[i] = create_osx_device_match(usages[i]);
if (!matching_dicts[i])
{
while (i > 0)
CFRelease(matching_dicts[--i]);
goto fail;
}
}
matching = CFArrayCreate(NULL, (const void**)matching_dicts, ARRAY_SIZE(matching_dicts),
&kCFTypeArrayCallBacks);
for (i = 0; i < ARRAY_SIZE(matching_dicts); i++)
CFRelease(matching_dicts[i]);
IOHIDManagerSetDeviceMatchingMultiple(hid_manager, matching);
CFRelease(matching);
devset = IOHIDManagerCopyDevices(hid_manager);
if (devset)
{
CFIndex num_devices, num_main_elements;
CFMutableArrayRef devices;
num_devices = CFSetGetCount(devset);
devices = CFArrayCreateMutable(kCFAllocatorDefault, num_devices, &kCFTypeArrayCallBacks);
CFSetApplyFunction(devset, copy_set_to_array, (void *)devices);
CFArraySortValues(devices, CFRangeMake(0, num_devices), device_location_name_comparator, NULL);
CFRelease(devset);
if (!devices)
goto fail;
device_main_elements = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
if (!device_main_elements)
{
CFRelease(devices);
goto fail;
}
num_main_elements = 0;
for (i = 0; i < num_devices; i++)
{
IOHIDDeviceRef hid_device = (IOHIDDeviceRef)CFArrayGetValueAtIndex(devices, i);
TRACE("hid_device %s\n", debugstr_device(hid_device));
num_main_elements += find_top_level(hid_device, device_main_elements);
}
CFRelease(devices);
TRACE("found %i device(s), %i collection(s)\n",(int)num_devices,(int)num_main_elements);
return (int)num_main_elements;
}
fail:
IOHIDManagerClose(hid_manager, 0);
CFRelease(hid_manager);
return 0;
}
/**************************************************************************
* collect_joystick_elements
*/
static void collect_joystick_elements(joystick_t* joystick, IOHIDElementRef collection)
{
CFIndex i, count;
CFArrayRef children = IOHIDElementGetChildren(collection);
TRACE("collection %s\n", debugstr_element(collection));
count = CFArrayGetCount(children);
for (i = 0; i < count; i++)
{
IOHIDElementRef child;
int type;
uint32_t usage_page;
child = (IOHIDElementRef)CFArrayGetValueAtIndex(children, i);
TRACE("child %s\n", debugstr_element(child));
type = IOHIDElementGetType(child);
usage_page = IOHIDElementGetUsagePage(child);
switch (type)
{
case kIOHIDElementTypeCollection:
collect_joystick_elements(joystick, child);
break;
case kIOHIDElementTypeInput_Button:
{
TRACE("kIOHIDElementTypeInput_Button usage_page %d\n", usage_page);
/* avoid strange elements found on the 360 controller */
if (usage_page == kHIDPage_Button)
CFArrayAppendValue(joystick->buttons, child);
break;
}
case kIOHIDElementTypeInput_Axis:
case kIOHIDElementTypeInput_Misc:
{
uint32_t usage = IOHIDElementGetUsage( child );
switch (usage_page)
{
case kHIDPage_GenericDesktop:
{
switch(usage)
{
case kHIDUsage_GD_Hatswitch:
{
TRACE("kIOHIDElementTypeInput_Axis/Misc / kHIDUsage_GD_Hatswitch\n");
if (joystick->hatswitch)
TRACE(" ignoring additional hatswitch\n");
else
joystick->hatswitch = (IOHIDElementRef)CFRetain(child);
break;
}
case kHIDUsage_GD_X:
case kHIDUsage_GD_Y:
case kHIDUsage_GD_Z:
case kHIDUsage_GD_Rx:
case kHIDUsage_GD_Ry:
case kHIDUsage_GD_Rz:
{
int axis = axis_for_usage_GD(usage);
TRACE("kIOHIDElementTypeInput_Axis/Misc / kHIDUsage_GD_<axis> (%d) axis %d\n", usage, axis);
if (axis < 0 || joystick->axes[axis].element)
TRACE(" ignoring\n");
else
{
joystick->axes[axis].element = (IOHIDElementRef)CFRetain(child);
joystick->axes[axis].min_value = IOHIDElementGetLogicalMin(child);
joystick->axes[axis].max_value = IOHIDElementGetLogicalMax(child);
}
break;
}
case kHIDUsage_GD_Slider:
case kHIDUsage_GD_Dial:
case kHIDUsage_GD_Wheel:
{
/* if one axis is taken, fall to the next until axes are filled */
int possible_axes[3] = {AXIS_Z,AXIS_RY,AXIS_RX};
int axis = 0;
while(axis < 3 && joystick->axes[possible_axes[axis]].element)
axis++;
if (axis == 3)
TRACE("kIOHIDElementTypeInput_Axis/Misc / kHIDUsage_GD_<axis> (%d)\n ignoring\n", usage);
else
{
TRACE("kIOHIDElementTypeInput_Axis/Misc / kHIDUsage_GD_<axis> (%d) axis %d\n", usage, possible_axes[axis]);
joystick->axes[possible_axes[axis]].element = (IOHIDElementRef)CFRetain(child);
joystick->axes[possible_axes[axis]].min_value = IOHIDElementGetLogicalMin(child);
joystick->axes[possible_axes[axis]].max_value = IOHIDElementGetLogicalMax(child);
}
break;
}
default:
FIXME("kIOHIDElementTypeInput_Axis/Misc / Unhandled GD Page usage %d\n", usage);
break;
}
break;
}
case kHIDPage_Simulation:
{
switch(usage)
{
case kHIDUsage_Sim_Rudder:
case kHIDUsage_Sim_Throttle:
case kHIDUsage_Sim_Steering:
case kHIDUsage_Sim_Accelerator:
case kHIDUsage_Sim_Brake:
{
int axis = axis_for_usage_Sim(usage);
TRACE("kIOHIDElementTypeInput_Axis/Misc / kHIDUsage_Sim_<axis> (%d) axis %d\n", usage, axis);
if (axis < 0 || joystick->axes[axis].element)
TRACE(" ignoring\n");
else
{
joystick->axes[axis].element = (IOHIDElementRef)CFRetain(child);
joystick->axes[axis].min_value = IOHIDElementGetLogicalMin(child);
joystick->axes[axis].max_value = IOHIDElementGetLogicalMax(child);
}
break;
}
default:
FIXME("kIOHIDElementTypeInput_Axis/Misc / Unhandled Sim Page usage %d\n", usage);
break;
}
break;
}
default:
FIXME("kIOHIDElementTypeInput_Axis/Misc / Unhandled Usage Page %d\n", usage_page);
break;
}
break;
}
case kIOHIDElementTypeFeature:
/* Describes input and output elements not intended for consumption by the end user. Ignoring. */
break;
default:
FIXME("Unhandled type %i\n",type);
break;
}
}
}
/**************************************************************************
* button_usage_comparator
*/
static CFComparisonResult button_usage_comparator(const void *val1, const void *val2, void *context)
{
IOHIDElementRef element1 = (IOHIDElementRef)val1, element2 = (IOHIDElementRef)val2;
int usage1 = IOHIDElementGetUsage(element1), usage2 = IOHIDElementGetUsage(element2);
if (usage1 < usage2)
return kCFCompareLessThan;
if (usage1 > usage2)
return kCFCompareGreaterThan;
return kCFCompareEqualTo;
}
/**************************************************************************
* driver_open
*/
LRESULT driver_open(LPSTR str, DWORD index)
{
if (index >= MAXJOYSTICK || joysticks[index].in_use)
return 0;
joysticks[index].in_use = TRUE;
return (LRESULT)&joysticks[index];
}
/**************************************************************************
* driver_close
*/
LRESULT driver_close(DWORD_PTR device_id)
{
joystick_t* joystick = joystick_from_id(device_id);
int i;
if (joystick == NULL)
return 0;
CFRelease(joystick->element);
for (i = 0; i < NUM_AXES; i++)
{
if (joystick->axes[i].element)
CFRelease(joystick->axes[i].element);
}
if (joystick->buttons)
CFRelease(joystick->buttons);
if (joystick->hatswitch)
CFRelease(joystick->hatswitch);
memset(joystick, 0, sizeof(*joystick));
return 1;
}
/**************************************************************************
* open_joystick
*/
static BOOL open_joystick(joystick_t* joystick)
{
CFIndex index;
CFRange range;
if (joystick->element)
return TRUE;
if (!device_main_elements)
{
find_osx_devices();
if (!device_main_elements)
return FALSE;
}
index = joystick - joysticks;
if (index >= CFArrayGetCount(device_main_elements))
return FALSE;
joystick->element = (IOHIDElementRef)CFArrayGetValueAtIndex(device_main_elements, index);
joystick->buttons = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
collect_joystick_elements(joystick, joystick->element);
/* Sort buttons into correct order */
range.location = 0;
range.length = CFArrayGetCount(joystick->buttons);
CFArraySortValues(joystick->buttons, range, button_usage_comparator, NULL);
if (range.length > 32)
{
/* Delete any buttons beyond the first 32 */
range.location = 32;
range.length -= 32;
CFArrayReplaceValues(joystick->buttons, range, NULL, 0);
}
return TRUE;
}
/**************************************************************************
* driver_joyGetDevCaps
*/
LRESULT driver_joyGetDevCaps(DWORD_PTR device_id, JOYCAPSW* caps, DWORD size)
{
joystick_t* joystick;
IOHIDDeviceRef device;
if ((joystick = joystick_from_id(device_id)) == NULL)
return MMSYSERR_NODRIVER;
if (!open_joystick(joystick))
return JOYERR_PARMS;
caps->szPname[0] = 0;
device = IOHIDElementGetDevice(joystick->element);
if (device)
{
CFStringRef product_name = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
if (product_name)
{
CFRange range;
range.location = 0;
range.length = min(MAXPNAMELEN - 1, CFStringGetLength(product_name));
CFStringGetCharacters(product_name, range, (UniChar*)caps->szPname);
caps->szPname[range.length] = 0;
}
}
caps->wMid = MM_MICROSOFT;
caps->wPid = MM_PC_JOYSTICK;
caps->wXmin = 0;
caps->wXmax = 0xFFFF;
caps->wYmin = 0;
caps->wYmax = 0xFFFF;
caps->wZmin = 0;
caps->wZmax = joystick->axes[AXIS_Z].element ? 0xFFFF : 0;
caps->wNumButtons = CFArrayGetCount(joystick->buttons);
if (size == sizeof(JOYCAPSW))
{
int i;
/* complete 95 structure */
caps->wRmin = 0;
caps->wRmax = 0xFFFF;
caps->wUmin = 0;
caps->wUmax = 0xFFFF;
caps->wVmin = 0;
caps->wVmax = 0xFFFF;
caps->wMaxAxes = 6; /* same as MS Joystick Driver */
caps->wNumAxes = 0;
caps->wMaxButtons = 32; /* same as MS Joystick Driver */
caps->szRegKey[0] = 0;
caps->szOEMVxD[0] = 0;
caps->wCaps = 0;
for (i = 0; i < NUM_AXES; i++)
{
if (joystick->axes[i].element)
{
caps->wNumAxes++;
switch (i)
{
case AXIS_Z: caps->wCaps |= JOYCAPS_HASZ; break;
case AXIS_RX: caps->wCaps |= JOYCAPS_HASV; break;
case AXIS_RY: caps->wCaps |= JOYCAPS_HASU; break;
case AXIS_RZ: caps->wCaps |= JOYCAPS_HASR; break;
}
}
}
if (joystick->hatswitch)
caps->wCaps |= JOYCAPS_HASPOV | JOYCAPS_POV4DIR;
}
TRACE("name %s buttons %u axes %d caps 0x%08x\n", debugstr_w(caps->szPname), caps->wNumButtons, caps->wNumAxes, caps->wCaps);
return JOYERR_NOERROR;
}
/*
* Helper to get the value from an element
*/
static LRESULT driver_getElementValue(IOHIDDeviceRef device, IOHIDElementRef element, IOHIDValueRef *pValueRef)
{
IOReturn ret;
ret = IOHIDDeviceGetValue(device, element, pValueRef);
switch (ret)
{
case kIOReturnSuccess:
return JOYERR_NOERROR;
case kIOReturnNotAttached:
return JOYERR_UNPLUGGED;
default:
ERR("IOHIDDeviceGetValue returned 0x%x\n",ret);
return JOYERR_NOCANDO;
}
}
/**************************************************************************
* driver_joyGetPosEx
*/
LRESULT driver_joyGetPosEx(DWORD_PTR device_id, JOYINFOEX* info)
{
static const struct {
DWORD flag;
off_t offset;
} axis_map[NUM_AXES] = {
{ JOY_RETURNX, FIELD_OFFSET(JOYINFOEX, dwXpos) },
{ JOY_RETURNY, FIELD_OFFSET(JOYINFOEX, dwYpos) },
{ JOY_RETURNZ, FIELD_OFFSET(JOYINFOEX, dwZpos) },
{ JOY_RETURNV, FIELD_OFFSET(JOYINFOEX, dwVpos) },
{ JOY_RETURNU, FIELD_OFFSET(JOYINFOEX, dwUpos) },
{ JOY_RETURNR, FIELD_OFFSET(JOYINFOEX, dwRpos) },
};
joystick_t* joystick;
IOHIDDeviceRef device;
CFIndex i, count;
IOHIDValueRef valueRef;
long value;
LRESULT rc;
if ((joystick = joystick_from_id(device_id)) == NULL)
return MMSYSERR_NODRIVER;
if (!open_joystick(joystick))
return JOYERR_PARMS;
device = IOHIDElementGetDevice(joystick->element);
if (info->dwFlags & JOY_RETURNBUTTONS)
{
info->dwButtons = 0;
info->dwButtonNumber = 0;
count = CFArrayGetCount(joystick->buttons);
for (i = 0; i < count; i++)
{
IOHIDElementRef button = (IOHIDElementRef)CFArrayGetValueAtIndex(joystick->buttons, i);
rc = driver_getElementValue(device, button, &valueRef);
if (rc != JOYERR_NOERROR)
return rc;
value = IOHIDValueGetIntegerValue(valueRef);
if (value)
{
info->dwButtons |= 1 << i;
info->dwButtonNumber++;
}
}
}
for (i = 0; i < NUM_AXES; i++)
{
if (info->dwFlags & axis_map[i].flag)
{
DWORD* field = (DWORD*)((char*)info + axis_map[i].offset);
if (joystick->axes[i].element)
{
rc = driver_getElementValue(device, joystick->axes[i].element, &valueRef);
if (rc != JOYERR_NOERROR)
return rc;
value = IOHIDValueGetIntegerValue(valueRef) - joystick->axes[i].min_value;
*field = MulDiv(value, 0xFFFF, joystick->axes[i].max_value - joystick->axes[i].min_value);
}
else
{
*field = 0;
info->dwFlags &= ~axis_map[i].flag;
}
}
}
if (info->dwFlags & JOY_RETURNPOV)
{
if (joystick->hatswitch)
{
rc = driver_getElementValue(device, joystick->hatswitch, &valueRef);
if (rc != JOYERR_NOERROR)
return rc;
value = IOHIDValueGetIntegerValue(valueRef);
if (value >= 8)
info->dwPOV = JOY_POVCENTERED;
else
info->dwPOV = value * 4500;
}
else
{
info->dwPOV = JOY_POVCENTERED;
info->dwFlags &= ~JOY_RETURNPOV;
}
}
TRACE("x: %d, y: %d, z: %d, r: %d, u: %d, v: %d, buttons: 0x%04x, pov %d, flags: 0x%04x\n",
info->dwXpos, info->dwYpos, info->dwZpos, info->dwRpos, info->dwUpos, info->dwVpos, info->dwButtons, info->dwPOV, info->dwFlags);
return JOYERR_NOERROR;
}
/**************************************************************************
* driver_joyGetPos
*/
LRESULT driver_joyGetPos(DWORD_PTR device_id, JOYINFO* info)
{
JOYINFOEX ji;
LONG ret;
memset(&ji, 0, sizeof(ji));
ji.dwSize = sizeof(ji);
ji.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | JOY_RETURNBUTTONS;
ret = driver_joyGetPosEx(device_id, &ji);
if (ret == JOYERR_NOERROR)
{
info->wXpos = ji.dwXpos;
info->wYpos = ji.dwYpos;
info->wZpos = ji.dwZpos;
info->wButtons = ji.dwButtons;
}
return ret;
}
#endif /* HAVE_IOKIT_HID_IOHIDLIB_H */

View File

@ -1 +0,0 @@
@ stdcall -private DriverProc(long long long long long) JSTCK_DriverProc

View File

@ -188,9 +188,6 @@
/* Define to 1 if you have the <link.h> header file. */
#undef HAVE_LINK_H
/* Define if <linux/joystick.h> defines the Linux 2.2 joystick API */
#undef HAVE_LINUX_22_JOYSTICK_API
/* Define to 1 if you have the <linux/capi.h> header file. */
#undef HAVE_LINUX_CAPI_H
@ -221,9 +218,6 @@
/* Define to 1 if you have the <linux/irda.h> header file. */
#undef HAVE_LINUX_IRDA_H
/* Define to 1 if you have the <linux/joystick.h> header file. */
#undef HAVE_LINUX_JOYSTICK_H
/* Define to 1 if you have the <linux/major.h> header file. */
#undef HAVE_LINUX_MAJOR_H

View File

@ -5615,19 +5615,6 @@ IUnknown *
IWineD3D *
IWineD3DClipper *
%%winejoystick.drv
%long
HDRVR
LPARAM
LRESULT
UINT
%long --pointer
DWORD_PTR
%%l3codeca.acm
%long