Detect force-feedback-capable linux event device joysticks and return
DIDC_FORCEFEEDBACK when queried for capabilities.
This commit is contained in:
parent
111a913d5e
commit
e491e8f897
|
@ -17574,6 +17574,121 @@ _ACEOF
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "$as_me:$LINENO: checking for struct ff_effect.direction" >&5
|
||||||
|
echo $ECHO_N "checking for struct ff_effect.direction... $ECHO_C" >&6
|
||||||
|
if test "${ac_cv_member_struct_ff_effect_direction+set}" = set; then
|
||||||
|
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||||
|
else
|
||||||
|
cat >conftest.$ac_ext <<_ACEOF
|
||||||
|
/* confdefs.h. */
|
||||||
|
_ACEOF
|
||||||
|
cat confdefs.h >>conftest.$ac_ext
|
||||||
|
cat >>conftest.$ac_ext <<_ACEOF
|
||||||
|
/* end confdefs.h. */
|
||||||
|
#ifdef HAVE_LINUX_INPUT_H
|
||||||
|
#include <linux/input.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
static struct ff_effect ac_aggr;
|
||||||
|
if (ac_aggr.direction)
|
||||||
|
return 0;
|
||||||
|
;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
rm -f conftest.$ac_objext
|
||||||
|
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||||
|
(eval $ac_compile) 2>conftest.er1
|
||||||
|
ac_status=$?
|
||||||
|
grep -v '^ *+' conftest.er1 >conftest.err
|
||||||
|
rm -f conftest.er1
|
||||||
|
cat conftest.err >&5
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); } &&
|
||||||
|
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||||
|
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||||
|
(eval $ac_try) 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); }; } &&
|
||||||
|
{ ac_try='test -s conftest.$ac_objext'
|
||||||
|
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||||
|
(eval $ac_try) 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); }; }; then
|
||||||
|
ac_cv_member_struct_ff_effect_direction=yes
|
||||||
|
else
|
||||||
|
echo "$as_me: failed program was:" >&5
|
||||||
|
sed 's/^/| /' conftest.$ac_ext >&5
|
||||||
|
|
||||||
|
cat >conftest.$ac_ext <<_ACEOF
|
||||||
|
/* confdefs.h. */
|
||||||
|
_ACEOF
|
||||||
|
cat confdefs.h >>conftest.$ac_ext
|
||||||
|
cat >>conftest.$ac_ext <<_ACEOF
|
||||||
|
/* end confdefs.h. */
|
||||||
|
#ifdef HAVE_LINUX_INPUT_H
|
||||||
|
#include <linux/input.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
static struct ff_effect ac_aggr;
|
||||||
|
if (sizeof ac_aggr.direction)
|
||||||
|
return 0;
|
||||||
|
;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
rm -f conftest.$ac_objext
|
||||||
|
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||||
|
(eval $ac_compile) 2>conftest.er1
|
||||||
|
ac_status=$?
|
||||||
|
grep -v '^ *+' conftest.er1 >conftest.err
|
||||||
|
rm -f conftest.er1
|
||||||
|
cat conftest.err >&5
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); } &&
|
||||||
|
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||||
|
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||||
|
(eval $ac_try) 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); }; } &&
|
||||||
|
{ ac_try='test -s conftest.$ac_objext'
|
||||||
|
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||||
|
(eval $ac_try) 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); }; }; then
|
||||||
|
ac_cv_member_struct_ff_effect_direction=yes
|
||||||
|
else
|
||||||
|
echo "$as_me: failed program was:" >&5
|
||||||
|
sed 's/^/| /' conftest.$ac_ext >&5
|
||||||
|
|
||||||
|
ac_cv_member_struct_ff_effect_direction=no
|
||||||
|
fi
|
||||||
|
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||||
|
fi
|
||||||
|
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||||
|
fi
|
||||||
|
echo "$as_me:$LINENO: result: $ac_cv_member_struct_ff_effect_direction" >&5
|
||||||
|
echo "${ECHO_T}$ac_cv_member_struct_ff_effect_direction" >&6
|
||||||
|
if test $ac_cv_member_struct_ff_effect_direction = yes; then
|
||||||
|
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define HAVE_STRUCT_FF_EFFECT_DIRECTION 1
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
echo "$as_me:$LINENO: checking for sigaddset" >&5
|
echo "$as_me:$LINENO: checking for sigaddset" >&5
|
||||||
echo $ECHO_N "checking for sigaddset... $ECHO_C" >&6
|
echo $ECHO_N "checking for sigaddset... $ECHO_C" >&6
|
||||||
if test "${wine_cv_have_sigaddset+set}" = set; then
|
if test "${wine_cv_have_sigaddset+set}" = set; then
|
||||||
|
|
|
@ -1289,6 +1289,11 @@ AC_CACHE_CHECK([whether linux/input.h is for real],
|
||||||
[Define if we have linux/input.h AND it contains the INPUT event API])
|
[Define if we have linux/input.h AND it contains the INPUT event API])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_CHECK_MEMBERS([struct ff_effect.direction],,,
|
||||||
|
[#ifdef HAVE_LINUX_INPUT_H
|
||||||
|
#include <linux/input.h>
|
||||||
|
#endif])
|
||||||
|
|
||||||
AC_CACHE_CHECK([for sigaddset],wine_cv_have_sigaddset,
|
AC_CACHE_CHECK([for sigaddset],wine_cv_have_sigaddset,
|
||||||
AC_TRY_LINK([#include <signal.h>],[sigset_t set; sigaddset(&set,SIGTERM);],
|
AC_TRY_LINK([#include <signal.h>],[sigset_t set; sigaddset(&set,SIGTERM);],
|
||||||
wine_cv_have_sigaddset=yes,wine_cv_have_sigaddset=no))
|
wine_cv_have_sigaddset=yes,wine_cv_have_sigaddset=no))
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* Copyright 1998,2000 Marcus Meissner
|
* Copyright 1998,2000 Marcus Meissner
|
||||||
* Copyright 1998,1999 Lionel Ulmer
|
* Copyright 1998,1999 Lionel Ulmer
|
||||||
* Copyright 2000-2001 TransGaming Technologies Inc.
|
* Copyright 2000-2001 TransGaming Technologies Inc.
|
||||||
|
* Copyright 2005 Daniel Remenak
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -97,6 +98,10 @@ struct JoystickImpl
|
||||||
BOOL overflow;
|
BOOL overflow;
|
||||||
DIJOYSTATE2 js;
|
DIJOYSTATE2 js;
|
||||||
|
|
||||||
|
/* Force feedback variables */
|
||||||
|
BOOL has_ff;
|
||||||
|
int num_effects;
|
||||||
|
|
||||||
/* data returned by the EVIOCGABS() ioctl */
|
/* data returned by the EVIOCGABS() ioctl */
|
||||||
int axes[ABS_MAX+1][5];
|
int axes[ABS_MAX+1][5];
|
||||||
|
|
||||||
|
@ -107,9 +112,11 @@ struct JoystickImpl
|
||||||
#define AXE_ABSFLAT 4
|
#define AXE_ABSFLAT 4
|
||||||
|
|
||||||
|
|
||||||
/* data returned by EVIOCGBIT for EV_ABS and EV_KEY */
|
/* data returned by EVIOCGBIT for caps, EV_ABS, EV_KEY, and EV_FF */
|
||||||
|
BYTE evbits[(EV_MAX+7)/8];
|
||||||
BYTE absbits[(ABS_MAX+7)/8];
|
BYTE absbits[(ABS_MAX+7)/8];
|
||||||
BYTE keybits[(KEY_MAX+7)/8];
|
BYTE keybits[(KEY_MAX+7)/8];
|
||||||
|
BYTE ffbits[(FF_MAX+7)/8];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This GUID is slightly different from the linux joystick one. Take note. */
|
/* This GUID is slightly different from the linux joystick one. Take note. */
|
||||||
|
@ -379,19 +386,32 @@ static HRESULT WINAPI JoystickAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
|
||||||
int i;
|
int i;
|
||||||
JoystickImpl *This = (JoystickImpl *)iface;
|
JoystickImpl *This = (JoystickImpl *)iface;
|
||||||
char buf[200];
|
char buf[200];
|
||||||
|
BOOL readonly = TRUE;
|
||||||
|
|
||||||
TRACE("(this=%p)\n",This);
|
TRACE("(this=%p)\n",This);
|
||||||
if (This->joyfd!=-1)
|
if (This->joyfd!=-1)
|
||||||
return 0;
|
return 0;
|
||||||
for (i=0;i<64;i++) {
|
for (i=0;i<64;i++) {
|
||||||
sprintf(buf,EVDEVPREFIX"%d",i);
|
sprintf(buf,EVDEVPREFIX"%d",i);
|
||||||
if (-1==(This->joyfd=open(buf,O_RDONLY))) {
|
if (-1==(This->joyfd=open(buf,O_RDWR))) {
|
||||||
if (errno==ENODEV)
|
if (-1==(This->joyfd=open(buf,O_RDONLY))) {
|
||||||
return DIERR_NOTFOUND;
|
/* Couldn't open the device at all */
|
||||||
perror(buf);
|
if (errno==ENODEV)
|
||||||
continue;
|
return DIERR_NOTFOUND;
|
||||||
|
perror(buf);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Couldn't open in r/w but opened in read-only. */
|
||||||
|
WARN("Could not open %s in read-write mode. Force feedback will be disabled.\n",buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ((-1!=ioctl(This->joyfd,EVIOCGBIT(EV_ABS,sizeof(This->absbits)),This->absbits)) &&
|
else {
|
||||||
|
/* Opened device in read-write */
|
||||||
|
readonly = FALSE;
|
||||||
|
}
|
||||||
|
if ((-1!=ioctl(This->joyfd,EVIOCGBIT(0,sizeof(This->evbits)),This->evbits)) &&
|
||||||
|
(-1!=ioctl(This->joyfd,EVIOCGBIT(EV_ABS,sizeof(This->absbits)),This->absbits)) &&
|
||||||
(-1!=ioctl(This->joyfd,EVIOCGBIT(EV_KEY,sizeof(This->keybits)),This->keybits)) &&
|
(-1!=ioctl(This->joyfd,EVIOCGBIT(EV_KEY,sizeof(This->keybits)),This->keybits)) &&
|
||||||
(test_bit(This->absbits,ABS_X) && test_bit(This->absbits,ABS_Y) &&
|
(test_bit(This->absbits,ABS_X) && test_bit(This->absbits,ABS_Y) &&
|
||||||
(test_bit(This->keybits,BTN_TRIGGER)||
|
(test_bit(This->keybits,BTN_TRIGGER)||
|
||||||
|
@ -407,6 +427,30 @@ static HRESULT WINAPI JoystickAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
|
||||||
if (This->joyfd==-1)
|
if (This->joyfd==-1)
|
||||||
return DIERR_NOTFOUND;
|
return DIERR_NOTFOUND;
|
||||||
|
|
||||||
|
This->has_ff = FALSE;
|
||||||
|
This->num_effects = 0;
|
||||||
|
|
||||||
|
#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
|
||||||
|
if (!readonly && test_bit(This->evbits, EV_FF)) {
|
||||||
|
if (-1!=ioctl(This->joyfd,EVIOCGBIT(EV_FF,sizeof(This->ffbits)),This->ffbits)) {
|
||||||
|
if (-1!=ioctl(This->joyfd,EVIOCGEFFECTS,&This->num_effects)
|
||||||
|
&& This->num_effects > 0) {
|
||||||
|
This->has_ff = TRUE;
|
||||||
|
TRACE("Joystick seems to be capable of force feedback.\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
TRACE("Joystick does not support any effects, disabling force feedback.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
TRACE("Could not get EV_FF bits; disabling force feedback.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
TRACE("Force feedback disabled (device is readonly or joystick incapable).\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
for (i=0;i<ABS_MAX;i++) {
|
for (i=0;i<ABS_MAX;i++) {
|
||||||
if (test_bit(This->absbits,i)) {
|
if (test_bit(This->absbits,i)) {
|
||||||
if (-1==ioctl(This->joyfd,EVIOCGABS(i),&(This->axes[i])))
|
if (-1==ioctl(This->joyfd,EVIOCGABS(i),&(This->axes[i])))
|
||||||
|
@ -779,6 +823,9 @@ static HRESULT WINAPI JoystickAImpl_GetCapabilities(
|
||||||
buttons=0;
|
buttons=0;
|
||||||
for (i=0;i<KEY_MAX;i++) if (test_bit(This->keybits,i)) buttons++;
|
for (i=0;i<KEY_MAX;i++) if (test_bit(This->keybits,i)) buttons++;
|
||||||
|
|
||||||
|
if (This->has_ff)
|
||||||
|
lpDIDevCaps->dwFlags |= DIDC_FORCEFEEDBACK;
|
||||||
|
|
||||||
lpDIDevCaps->dwAxes = axes;
|
lpDIDevCaps->dwAxes = axes;
|
||||||
lpDIDevCaps->dwButtons = buttons;
|
lpDIDevCaps->dwButtons = buttons;
|
||||||
|
|
||||||
|
|
|
@ -596,6 +596,9 @@
|
||||||
/* Define to 1 if you have the `strncasecmp' function. */
|
/* Define to 1 if you have the `strncasecmp' function. */
|
||||||
#undef HAVE_STRNCASECMP
|
#undef HAVE_STRNCASECMP
|
||||||
|
|
||||||
|
/* Define to 1 if `direction' is member of `struct ff_effect'. */
|
||||||
|
#undef HAVE_STRUCT_FF_EFFECT_DIRECTION
|
||||||
|
|
||||||
/* Define to 1 if `msg_accrights' is member of `struct msghdr'. */
|
/* Define to 1 if `msg_accrights' is member of `struct msghdr'. */
|
||||||
#undef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
|
#undef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue