hiho,
the attached patch detects _all_ joysticks of /dev/input/event%d; please
have a test before i refine the patch for submission. i tried it with
Il2 Sturmovik and with Live For Speed - both games worked. as neither my
cougar nor my brd wheel have force feedback i was not able to test, if
everything still works.
details:
- use a seperate struct for holding infos about the /dev/input/event
devices
- use the general infos about the devices instead of
acquiring/unacquiring before/after infos about the device are needed
- changed the dinput_main to use three states to return on
create_device: -1 == dont try further, 0 == there is no such device,
1 == there we go
next ideas/patches:
- use a linked list for storing only the JoyDev's that there are
- the guid is stored in the JoyImpl and the JoyDev
- the logic in setting the guids is as "first joystick == GUID_Joystick"
then use the wine default; this currently leads into the same GUID for
instance and product; i saw in joystick_linux.c how this is solved
there
- as dmesg shows a proper name for the device we might somehow retrieve
it with an ioctl-call; currently the /dev/... name is used, which is
good for developers but not for users
- per-device-config via registry (e.g. combine axes)
this patch actually is longer than the things it really does -
introducing a "sub-struct" for holding common data adds lots of
``->joydev'' so i decided instead of splitting this patch into several
fragments send an "unfinished" version and then finish the job with the
following small patches.
please note: the patch is against ~wine/dll/dinput (i use cvs for the
wine original and git where i need it for patching)
--
cu
diff --git a/device.c b/device.c
diff --git a/dinput_main.c b/dinput_main.c
index 9f93a52..d928d96 100644
--- a/dinput_main.c
+++ b/dinput_main.c
@@ -220,10 +220,11 @@ static HRESULT WINAPI IDirectInputAImpl_
for (i = 0; i < NB_DINPUT_DEVICES; i++) {
if (!dinput_devices[i]->enum_deviceA) continue;
- for (j = 0, r = -1; r != 0; j++) {
+ TRACE(" - checking device %d ('%s')\n", i, dinput_devices[i]->name);
+ for (j = 0, r = 0; r != -1; j++) {
devInstance.dwSize = sizeof(devInstance);
- TRACE(" - checking device %d ('%s')\n", i, dinput_devices[i]->name);
- if ((r = dinput_devices[i]->enum_deviceA(dwDevType, dwFlags, &devInstance, This->dwVersion, j))) {
+ if (1 == (r = dinput_devices[i]->enum_deviceA(dwDevType, dwFlags, &devInstance, This->dwVersion, j))) {
+ TRACE(" - found id %d\n", j);
if (lpCallback(&devInstance,pvRef) == DIENUM_STOP)
return 0;
}
@@ -250,10 +251,11 @@ static HRESULT WINAPI IDirectInputWImpl_
for (i = 0; i < NB_DINPUT_DEVICES; i++) {
if (!dinput_devices[i]->enum_deviceW) continue;
- for (j = 0, r = -1; r != 0; j++) {
+ TRACE(" - checking device %d ('%s')\n", i, dinput_devices[i]->name);
+ for (j = 0, r = 0; r != -1; j++) {
devInstance.dwSize = sizeof(devInstance);
- TRACE(" - checking device %d ('%s')\n", i, dinput_devices[i]->name);
- if ((r = dinput_devices[i]->enum_deviceW(dwDevType, dwFlags, &devInstance, This->dwVersion, j))) {
+ if (1 == (r = dinput_devices[i]->enum_deviceW(dwDevType, dwFlags, &devInstance, This->dwVersion, j))) {
+ TRACE(" - found id %d\n", j);
if (lpCallback(&devInstance,pvRef) == DIENUM_STOP)
return 0;
}
diff --git a/joystick_linux.c b/joystick_linux.c
index d56271d..abedc5c 100644
--- a/joystick_linux.c
+++ b/joystick_linux.c
@@ -162,11 +162,15 @@ static int joydev_get_device(char *dev,
return ret;
}
-static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id)
+static int joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id)
{
int fd = -1;
char dev[32];
+ if (id>0) {
+ return -1;
+ }
+
if (dwFlags & DIEDFL_FORCEFEEDBACK) {
WARN("force feedback not supported\n");
return FALSE;
@@ -209,13 +213,17 @@ static BOOL joydev_enum_deviceA(DWORD dw
return FALSE;
}
-static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
+static int joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
{
int fd = -1;
char name[MAX_PATH];
char dev[32];
char friendly[32];
+ if (id>0) {
+ return -1;
+ }
+
if (dwFlags & DIEDFL_FORCEFEEDBACK) {
WARN("force feedback not supported\n");
return FALSE;
diff --git a/joystick_linuxinput.c b/joystick_linuxinput.c
index 30f81f1..94a0383 100644
--- a/joystick_linuxinput.c
+++ b/joystick_linuxinput.c
@@ -85,12 +85,28 @@ HRESULT linuxinput_get_info_W(int fd, RE
typedef struct JoystickImpl JoystickImpl;
static const IDirectInputDevice8AVtbl JoystickAvt;
static const IDirectInputDevice8WVtbl JoystickWvt;
+
+struct JoyDev {
+ int is_joystick;
+ char *device;
+ GUID guid;
+
+ int has_ff;
+ int num_effects;
+
+ /* 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 keybits[(KEY_MAX+7)/8];
+ BYTE ffbits[(FF_MAX+7)/8];
+};
+
struct JoystickImpl
{
const void *lpVtbl;
LONG ref;
GUID guid;
-
+ struct JoyDev *joydev;
/* The 'parent' DInput */
IDirectInputImpl *dinput;
@@ -130,100 +146,115 @@ struct JoystickImpl
#define AXE_ABSMAX 2
#define AXE_ABSFUZZ 3
#define AXE_ABSFLAT 4
-
-
- /* 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 keybits[(KEY_MAX+7)/8];
- BYTE ffbits[(FF_MAX+7)/8];
};
+static void fake_current_js_state(JoystickImpl *ji);
+static int find_property_offset(JoystickImpl *This, LPCDIPROPHEADER ph);
+static DWORD map_pov(int event_value, int is_x);
+static void find_joydevs(void);
+
/* This GUID is slightly different from the linux joystick one. Take note. */
-static GUID DInput_Wine_Joystick_GUID = { /* 9e573eda-7734-11d2-8d4a-23903fb6bdf7 */
+static const GUID DInput_Wine_Joystick_Base_GUID = { /* 9e573eda-7734-11d2-8d4a-23903fb6bdf7 */
0x9e573eda,
0x7734,
0x11d2,
{0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
};
-static void fake_current_js_state(JoystickImpl *ji);
-static int find_property_offset(JoystickImpl *This, LPCDIPROPHEADER ph);
-static DWORD map_pov(int event_value, int is_x);
-
#define test_bit(arr,bit) (((BYTE*)(arr))[(bit)>>3]&(1<<((bit)&7)))
-static int joydev_have(BOOL require_ff)
+#define MAX_JOYDEV 64
+
+static int have_joydevs = -1;
+static int first_joydev = -1;
+static struct JoyDev joydevs[MAX_JOYDEV] = {};
+
+static void find_joydevs(void)
{
- int i, fd, flags, num_effects;
- int havejoy = 0;
+ int i;
+
+ if (have_joydevs!=-1) {
+ return;
+ }
+
+ have_joydevs = 0;
+
+ for (i=0;i<MAX_JOYDEV;i++) {
+ char buf[200];
+ struct JoyDev *joydev = &joydevs[i];
+ int fd;
+ int no_ff_check = 0;
+
+ sprintf(buf,EVDEVPREFIX"%d",i);
+
+ if ((fd=open(buf, O_RDWR))==-1) {
+ fd = open(buf, O_RDONLY);
+ no_ff_check = 1;
+ }
+
+ if (fd!=-1) {
+ if ((-1==ioctl(fd,EVIOCGBIT(0,sizeof(joydev->evbits)),joydev->evbits))) {
+ perror("EVIOCGBIT 0");
+ close(fd);
+ continue;
+ }
+ if (-1==ioctl(fd,EVIOCGBIT(EV_ABS,sizeof(joydev->absbits)),joydev->absbits)) {
+ perror("EVIOCGBIT EV_ABS");
+ close(fd);
+ continue;
+ }
+ if (-1==ioctl(fd,EVIOCGBIT(EV_KEY,sizeof(joydev->keybits)),joydev->keybits)) {
+ perror("EVIOCGBIT EV_KEY");
+ close(fd);
+ continue;
+ }
+ /* A true joystick has at least axis X and Y, and at least 1
+ * button. copied from linux/drivers/input/joydev.c */
+ if (test_bit(joydev->absbits,ABS_X) && test_bit(joydev->absbits,ABS_Y) &&
+ ( test_bit(joydev->keybits,BTN_TRIGGER) ||
+ test_bit(joydev->keybits,BTN_A) ||
+ test_bit(joydev->keybits,BTN_1)
+ )
+ ) {
+ TRACE("Found a joystick '%s'\n", buf);
+
+ joydev->is_joystick = 1;
+ joydev->device = strdup(buf);
+ joydev->guid = DInput_Wine_Joystick_Base_GUID;
+ joydev->guid.Data1 += have_joydevs;
+ have_joydevs++;
+ if (first_joydev==-1) {
+ first_joydev = i;
+ }
+
+#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
+ if (!no_ff_check) {
+ if ((!test_bit(joydev->evbits,EV_FF))
+ || (-1==ioctl(fd,EVIOCGBIT(EV_FF,sizeof(joydev->ffbits)),joydev->ffbits))
+ || (-1==ioctl(fd,EVIOCGEFFECTS,&joydev->num_effects))
+ || (joydev->num_effects <= 0)) {
+ close(fd);
+ continue;
+ }
- for (i=0;i<64;i++) {
- char buf[200];
- BYTE absbits[(ABS_MAX+7)/8],keybits[(KEY_MAX+7)/8];
- BYTE evbits[(EV_MAX+7)/8],ffbits[(FF_MAX+7)/8];
-
- sprintf(buf,EVDEVPREFIX"%d",i);
-
- if (require_ff)
- flags = O_RDWR;
- else
- flags = O_RDONLY;
-
- if (-1!=(fd=open(buf,flags))) {
- if (-1==ioctl(fd,EVIOCGBIT(EV_ABS,sizeof(absbits)),absbits)) {
- perror("EVIOCGBIT EV_ABS");
- close(fd);
- continue;
- }
- if (-1==ioctl(fd,EVIOCGBIT(EV_KEY,sizeof(keybits)),keybits)) {
- perror("EVIOCGBIT EV_KEY");
- close(fd);
- continue;
- }
-
- /* test for force feedback if it's required */
- if (require_ff) {
- if ((-1==ioctl(fd,EVIOCGBIT(0,sizeof(evbits)),evbits))) {
- perror("EVIOCGBIT 0");
- close(fd);
- continue;
- }
- if ( (!test_bit(evbits,EV_FF))
- || (-1==ioctl(fd,EVIOCGBIT(EV_FF,sizeof(ffbits)),ffbits))
- || (-1==ioctl(fd,EVIOCGEFFECTS,&num_effects))
- || (num_effects <= 0)) {
- close(fd);
- continue;
- }
- }
-
- /* A true joystick has at least axis X and Y, and at least 1
- * button. copied from linux/drivers/input/joydev.c */
- if (test_bit(absbits,ABS_X) && test_bit(absbits,ABS_Y) &&
- ( test_bit(keybits,BTN_TRIGGER) ||
- test_bit(keybits,BTN_A) ||
- test_bit(keybits,BTN_1)
- )
- ) {
- FIXME("found a joystick at %s!\n",buf);
- havejoy = 1;
- }
- close(fd);
+ TRACE(" ... with force feedback\n");
+
+ joydev->has_ff = 1;
+ }
+#endif
}
- if (havejoy || (errno==ENODEV))
- break;
+
+ close(fd);
+ }
}
- return havejoy;
}
-static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id)
+static int joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id)
{
- int havejoy = 0;
-
- if (id != 0)
- return FALSE;
-
+ if (id >= MAX_JOYDEV) {
+ return -1;
+ }
+
if (!((dwDevType == 0) ||
((dwDevType == DIDEVTYPE_JOYSTICK) && (version < 0x0800)) ||
(((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) && (version >= 0x0800))))
@@ -234,35 +265,34 @@ static BOOL joydev_enum_deviceA(DWORD dw
return FALSE;
#endif
- havejoy = joydev_have(dwFlags & DIEDFL_FORCEFEEDBACK);
-
- if (!havejoy)
- return FALSE;
+ find_joydevs();
- TRACE("Enumerating the linuxinput Joystick device\n");
-
- /* Return joystick */
- lpddi->guidInstance = GUID_Joystick;
- lpddi->guidProduct = DInput_Wine_Joystick_GUID;
+ if (joydevs[id].is_joystick && ((!(dwFlags & DIEDFL_FORCEFEEDBACK)) || joydevs[id].has_ff)) {
+ if (id==first_joydev) {
+ lpddi->guidInstance = GUID_Joystick;
+ } else {
+ lpddi->guidInstance = joydevs[id].guid;
+ }
+ lpddi->guidProduct = joydevs[id].guid;
- lpddi->guidFFDriver = GUID_NULL;
- if (version >= 0x0800)
- lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
- else
- lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
+ lpddi->guidFFDriver = GUID_NULL;
+ if (version >= 0x0800)
+ lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
+ else
+ lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
- strcpy(lpddi->tszInstanceName, "Joystick");
- /* ioctl JSIOCGNAME(len) */
- strcpy(lpddi->tszProductName, "Wine Joystick");
- return TRUE;
+ strcpy(lpddi->tszInstanceName, "Joystick");
+ strcpy(lpddi->tszProductName, joydevs[id].device);
+ return TRUE;
+ }
+ return FALSE;
}
-static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
+static int joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
{
- int havejoy = 0;
-
- if (id != 0)
- return FALSE;
+ if (id >= MAX_JOYDEV) {
+ return -1;
+ }
if (!((dwDevType == 0) ||
((dwDevType == DIDEVTYPE_JOYSTICK) && (version < 0x0800)) ||
@@ -274,30 +304,27 @@ static BOOL joydev_enum_deviceW(DWORD dw
return FALSE;
#endif
- havejoy = joydev_have(dwFlags & DIEDFL_FORCEFEEDBACK);
-
- if (!havejoy)
- return FALSE;
-
- TRACE("Enumerating the linuxinput Joystick device\n");
-
- /* Return joystick */
- lpddi->guidInstance = GUID_Joystick;
- lpddi->guidProduct = DInput_Wine_Joystick_GUID;
+ find_joydevs();
- lpddi->guidFFDriver = GUID_NULL;
- if (version >= 0x0800)
- lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
- else
- lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
+ if (joydevs[id].is_joystick && ((!(dwFlags & DIEDFL_FORCEFEEDBACK)) || joydevs[id].has_ff)) {
+ /* Return joystick */
+ lpddi->guidInstance = GUID_Joystick;
+ lpddi->guidProduct = joydevs[id].guid;
+
+ lpddi->guidFFDriver = GUID_NULL;
+ if (version >= 0x0800)
+ lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
+ else
+ lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
- MultiByteToWideChar(CP_ACP, 0, "Joystick", -1, lpddi->tszInstanceName, MAX_PATH);
- /* ioctl JSIOCGNAME(len) */
- MultiByteToWideChar(CP_ACP, 0, "Wine Joystick", -1, lpddi->tszProductName, MAX_PATH);
- return TRUE;
+ MultiByteToWideChar(CP_ACP, 0, "Joystick", -1, lpddi->tszInstanceName, MAX_PATH);
+ MultiByteToWideChar(CP_ACP, 0, joydevs[id].device, -1, lpddi->tszProductName, MAX_PATH);
+ return TRUE;
+ }
+ return FALSE;
}
-static JoystickImpl *alloc_device(REFGUID rguid, const void *jvt, IDirectInputImpl *dinput)
+static JoystickImpl *alloc_device(REFGUID rguid, const void *jvt, IDirectInputImpl *dinput, struct JoyDev *joydev)
{
JoystickImpl* newDevice;
int i;
@@ -307,6 +334,7 @@ static JoystickImpl *alloc_device(REFGUI
newDevice->ref = 1;
newDevice->joyfd = -1;
newDevice->dinput = dinput;
+ newDevice->joydev = joydev;
#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
newDevice->ff_state = FF_STATUS_STOPPED;
#endif
@@ -327,25 +355,30 @@ static JoystickImpl *alloc_device(REFGUI
static HRESULT joydev_create_deviceA(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev)
{
- int havejoy = 0;
+ int i;
- havejoy = joydev_have(FALSE);
+ find_joydevs();
- if (!havejoy)
+ if (!have_joydevs)
return DIERR_DEVICENOTREG;
- if ((IsEqualGUID(&GUID_Joystick,rguid)) ||
- (IsEqualGUID(&DInput_Wine_Joystick_GUID,rguid))) {
- if ((riid == NULL) ||
- IsEqualGUID(&IID_IDirectInputDeviceA,riid) ||
- IsEqualGUID(&IID_IDirectInputDevice2A,riid) ||
- IsEqualGUID(&IID_IDirectInputDevice7A,riid) ||
- IsEqualGUID(&IID_IDirectInputDevice8A,riid)) {
- *pdev = (IDirectInputDeviceA*) alloc_device(rguid, &JoystickAvt, dinput);
- TRACE("Creating a Joystick device (%p)\n", *pdev);
- return DI_OK;
- } else
- return DIERR_NOINTERFACE;
+ for (i=0; i<MAX_JOYDEV; i++) {
+ if (joydevs[i].is_joystick && (
+ IsEqualGUID(&GUID_Joystick,rguid) ||
+ IsEqualGUID(&joydevs[i].guid,rguid)
+ )) {
+ if ((riid == NULL) ||
+ IsEqualGUID(&IID_IDirectInputDeviceA,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice2A,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice7A,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice8A,riid)) {
+ *pdev = (IDirectInputDeviceA*) alloc_device(rguid, &JoystickAvt, dinput, &joydevs[i]);
+ TRACE("Creating a Joystick device (%p)\n", *pdev);
+ return DI_OK;
+ } else {
+ return DIERR_NOINTERFACE;
+ }
+ }
}
return DIERR_DEVICENOTREG;
@@ -354,25 +387,30 @@ static HRESULT joydev_create_deviceA(IDi
static HRESULT joydev_create_deviceW(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev)
{
- int havejoy = 0;
+ int i;
- havejoy = joydev_have(FALSE);
+ find_joydevs();
- if (!havejoy)
+ if (!have_joydevs)
return DIERR_DEVICENOTREG;
- if ((IsEqualGUID(&GUID_Joystick,rguid)) ||
- (IsEqualGUID(&DInput_Wine_Joystick_GUID,rguid))) {
- if ((riid == NULL) ||
- IsEqualGUID(&IID_IDirectInputDeviceW,riid) ||
- IsEqualGUID(&IID_IDirectInputDevice2W,riid) ||
- IsEqualGUID(&IID_IDirectInputDevice7W,riid) ||
- IsEqualGUID(&IID_IDirectInputDevice8W,riid)) {
- *pdev = (IDirectInputDeviceW*) alloc_device(rguid, &JoystickWvt, dinput);
- TRACE("Creating a Joystick device (%p)\n", *pdev);
- return DI_OK;
- } else
- return DIERR_NOINTERFACE;
+ for (i=0; i<MAX_JOYDEV; i++) {
+ if (joydevs[i].is_joystick && (
+ IsEqualGUID(&GUID_Joystick,rguid) ||
+ IsEqualGUID(&joydevs[i].guid,rguid)
+ )) {
+ if ((riid == NULL) ||
+ IsEqualGUID(&IID_IDirectInputDeviceW,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice2W,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice7W,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice8W,riid)) {
+ *pdev = (IDirectInputDeviceW*) alloc_device(rguid, &JoystickWvt, dinput, &joydevs[i]);
+ TRACE("Creating a Joystick device (%p)\n", *pdev);
+ return DI_OK;
+ } else {
+ return DIERR_NOINTERFACE;
+ }
+ }
}
return DIERR_DEVICENOTREG;
@@ -461,9 +499,8 @@ static HRESULT WINAPI JoystickAImpl_SetD
*/
static HRESULT WINAPI JoystickAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
{
- int i,buttons;
+ int i, buttons;
JoystickImpl *This = (JoystickImpl *)iface;
- char buf[200];
BOOL readonly = TRUE;
TRACE("(this=%p)\n",This);
@@ -472,68 +509,23 @@ static HRESULT WINAPI JoystickAImpl_Acqu
if (This->df==NULL) {
return DIERR_INVALIDPARAM;
}
- for (i=0;i<64;i++) {
- sprintf(buf,EVDEVPREFIX"%d",i);
- if (-1==(This->joyfd=open(buf,O_RDWR))) {
- if (-1==(This->joyfd=open(buf,O_RDONLY))) {
- /* Couldn't open the device at all */
- if (errno==ENODEV)
- 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);
- }
- }
- 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)) &&
- (test_bit(This->absbits,ABS_X) && test_bit(This->absbits,ABS_Y) &&
- (test_bit(This->keybits,BTN_TRIGGER)||
- test_bit(This->keybits,BTN_A) ||
- test_bit(This->keybits,BTN_1)
- )
- )
- )
- break;
- close(This->joyfd);
- This->joyfd = -1;
- }
- if (This->joyfd==-1)
- 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");
+ if (-1==(This->joyfd=open(This->joydev->device,O_RDWR))) {
+ if (-1==(This->joyfd=open(This->joydev->device,O_RDONLY))) {
+ /* Couldn't open the device at all */
+ perror(This->joydev->device);
+ return DIERR_NOTFOUND;
+ } 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", This->joydev->device);
+ }
+ } else {
+ /* Opened device in read-write */
+ readonly = FALSE;
}
-#endif
for (i=0;i<ABS_MAX;i++) {
- if (test_bit(This->absbits,i)) {
+ if (test_bit(This->joydev->absbits,i)) {
if (-1==ioctl(This->joyfd,EVIOCGABS(i),&(This->axes[i])))
continue;
TRACE("axe %d: cur=%d, min=%d, max=%d, fuzz=%d, flat=%d\n",
@@ -550,14 +542,14 @@ static HRESULT WINAPI JoystickAImpl_Acqu
}
buttons = 0;
for (i=0;i<KEY_MAX;i++) {
- if (test_bit(This->keybits,i)) {
+ if (test_bit(This->joydev->keybits,i)) {
TRACE("button %d: %d\n", i, buttons);
This->buttons[i] = 0x80 | buttons;
buttons++;
}
}
- fake_current_js_state(This);
+ fake_current_js_state(This);
return 0;
}
@@ -985,7 +977,6 @@ static HRESULT WINAPI JoystickAImpl_GetC
LPDIDEVCAPS lpDIDevCaps)
{
JoystickImpl *This = (JoystickImpl *)iface;
- int xfd = This->joyfd;
int i,axes,buttons;
TRACE("%p->(%p)\n",iface,lpDIDevCaps);
@@ -1000,11 +991,6 @@ static HRESULT WINAPI JoystickAImpl_GetC
return DIERR_INVALIDPARAM;
}
- if (xfd==-1) {
- /* yes, games assume we return something, even if unacquired */
- JoystickAImpl_Acquire(iface);
- }
-
lpDIDevCaps->dwFlags = DIDC_ATTACHED;
if (This->dinput->dwVersion >= 0x0800)
lpDIDevCaps->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
@@ -1012,9 +998,9 @@ static HRESULT WINAPI JoystickAImpl_GetC
lpDIDevCaps->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
axes=0;
- for (i=0;i<ABS_MAX;i++) if (test_bit(This->absbits,i)) axes++;
+ for (i=0;i<ABS_MAX;i++) if (test_bit(This->joydev->absbits,i)) axes++;
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->joydev->keybits,i)) buttons++;
if (This->has_ff)
lpDIDevCaps->dwFlags |= DIDC_FORCEFEEDBACK;
@@ -1022,10 +1008,6 @@ static HRESULT WINAPI JoystickAImpl_GetC
lpDIDevCaps->dwAxes = axes;
lpDIDevCaps->dwButtons = buttons;
- if (xfd==-1) {
- JoystickAImpl_Unacquire(iface);
- }
-
return DI_OK;
}
@@ -1052,7 +1034,6 @@ static HRESULT WINAPI JoystickAImpl_Enum
{
JoystickImpl *This = (JoystickImpl *)iface;
DIDEVICEOBJECTINSTANCEA ddoi;
- int xfd = This->joyfd;
TRACE("(this=%p,%p,%p,%08lx)\n", This, lpCallback, lpvRef, dwFlags);
if (TRACE_ON(dinput)) {
@@ -1061,10 +1042,6 @@ static HRESULT WINAPI JoystickAImpl_Enum
TRACE("\n");
}
- /* We need to work even if we're not yet acquired */
- if (xfd == -1)
- IDirectInputDevice8_Acquire(iface);
-
/* Only the fields till dwFFMaxForce are relevant */
ddoi.dwSize = FIELD_OFFSET(DIDEVICEOBJECTINSTANCEA, dwFFMaxForce);
@@ -1075,7 +1052,7 @@ static HRESULT WINAPI JoystickAImpl_Enum
BYTE i;
for (i = 0; i < ABS_MAX; i++) {
- if (!test_bit(This->absbits,i)) continue;
+ if (!test_bit(This->joydev->absbits,i)) continue;
switch (i) {
case ABS_X:
@@ -1122,9 +1099,6 @@ static HRESULT WINAPI JoystickAImpl_Enum
sprintf(ddoi.tszName, "%d-Axis", i);
_dump_OBJECTINSTANCEA(&ddoi);
if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) {
- /* return to unaquired state if that's where we were */
- if (xfd == -1)
- IDirectInputDevice8_Unacquire(iface);
return DI_OK;
}
}
@@ -1135,15 +1109,12 @@ static HRESULT WINAPI JoystickAImpl_Enum
int i;
ddoi.guidType = GUID_POV;
for (i=0; i<4; i++) {
- if (test_bit(This->absbits,ABS_HAT0X+(i<<1)) && test_bit(This->absbits,ABS_HAT0Y+(i<<1))) {
+ if (test_bit(This->joydev->absbits,ABS_HAT0X+(i<<1)) && test_bit(This->joydev->absbits,ABS_HAT0Y+(i<<1))) {
ddoi.dwOfs = DIJOFS_POV(i);
ddoi.dwType = DIDFT_MAKEINSTANCE(i << WINE_JOYSTICK_POV_BASE) | DIDFT_POV;
sprintf(ddoi.tszName, "%d-POV", i);
_dump_OBJECTINSTANCEA(&ddoi);
if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) {
- /* return to unaquired state if that's where we were */
- if (xfd == -1)
- IDirectInputDevice8_Unacquire(iface);
return DI_OK;
}
}
@@ -1159,25 +1130,18 @@ static HRESULT WINAPI JoystickAImpl_Enum
ddoi.guidType = GUID_Button;
for (i = 0; i < KEY_MAX; i++) {
- if (!test_bit(This->keybits,i)) continue;
+ if (!test_bit(This->joydev->keybits,i)) continue;
ddoi.dwOfs = DIJOFS_BUTTON(btncount);
ddoi.dwType = DIDFT_MAKEINSTANCE(btncount << WINE_JOYSTICK_BUTTON_BASE) | DIDFT_PSHBUTTON;
sprintf(ddoi.tszName, "%d-Button", btncount);
btncount++;
_dump_OBJECTINSTANCEA(&ddoi);
if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) {
- /* return to unaquired state if that's where we were */
- if (xfd == -1)
- IDirectInputDevice8_Unacquire(iface);
return DI_OK;
}
}
}
- /* return to unaquired state if that's where we were */
- if (xfd == -1)
- IDirectInputDevice8_Unacquire(iface);
-
return DI_OK;
}
@@ -1300,74 +1264,66 @@ static HRESULT WINAPI JoystickAImpl_Enum
DIEFFECTINFOA dei; /* feif */
DWORD type = DIEFT_GETTYPE(dwEffType);
JoystickImpl* This = (JoystickImpl*)iface;
- int xfd = This->joyfd;
- TRACE("(this=%p,%p,%ld) type=%ld fd=%d\n", This, pvRef, dwEffType, type, xfd);
+ TRACE("(this=%p,%p,%ld) type=%ld\n", This, pvRef, dwEffType, type);
dei.dwSize = sizeof(DIEFFECTINFOA);
- /* We need to return something even if we're not yet acquired */
- if (xfd == -1)
- IDirectInputDevice8_Acquire(iface);
-
if ((type == DIEFT_ALL || type == DIEFT_CONSTANTFORCE)
- && test_bit(This->ffbits, FF_CONSTANT)) {
+ && test_bit(This->joydev->ffbits, FF_CONSTANT)) {
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_ConstantForce);
(*lpCallback)(&dei, pvRef);
}
if ((type == DIEFT_ALL || type == DIEFT_PERIODIC)
- && test_bit(This->ffbits, FF_PERIODIC)) {
- if (test_bit(This->ffbits, FF_SQUARE)) {
+ && test_bit(This->joydev->ffbits, FF_PERIODIC)) {
+ if (test_bit(This->joydev->ffbits, FF_SQUARE)) {
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Square);
(*lpCallback)(&dei, pvRef);
}
- if (test_bit(This->ffbits, FF_SINE)) {
+ if (test_bit(This->joydev->ffbits, FF_SINE)) {
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Sine);
(*lpCallback)(&dei, pvRef);
}
- if (test_bit(This->ffbits, FF_TRIANGLE)) {
+ if (test_bit(This->joydev->ffbits, FF_TRIANGLE)) {
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Triangle);
(*lpCallback)(&dei, pvRef);
}
- if (test_bit(This->ffbits, FF_SAW_UP)) {
+ if (test_bit(This->joydev->ffbits, FF_SAW_UP)) {
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_SawtoothUp);
(*lpCallback)(&dei, pvRef);
}
- if (test_bit(This->ffbits, FF_SAW_DOWN)) {
+ if (test_bit(This->joydev->ffbits, FF_SAW_DOWN)) {
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_SawtoothDown);
(*lpCallback)(&dei, pvRef);
}
}
if ((type == DIEFT_ALL || type == DIEFT_RAMPFORCE)
- && test_bit(This->ffbits, FF_RAMP)) {
+ && test_bit(This->joydev->ffbits, FF_RAMP)) {
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_RampForce);
(*lpCallback)(&dei, pvRef);
}
if (type == DIEFT_ALL || type == DIEFT_CONDITION) {
- if (test_bit(This->ffbits, FF_SPRING)) {
+ if (test_bit(This->joydev->ffbits, FF_SPRING)) {
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Spring);
(*lpCallback)(&dei, pvRef);
}
- if (test_bit(This->ffbits, FF_DAMPER)) {
+ if (test_bit(This->joydev->ffbits, FF_DAMPER)) {
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Damper);
(*lpCallback)(&dei, pvRef);
}
- if (test_bit(This->ffbits, FF_INERTIA)) {
+ if (test_bit(This->joydev->ffbits, FF_INERTIA)) {
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Inertia);
(*lpCallback)(&dei, pvRef);
}
- if (test_bit(This->ffbits, FF_FRICTION)) {
+ if (test_bit(This->joydev->ffbits, FF_FRICTION)) {
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Friction);
(*lpCallback)(&dei, pvRef);
}
}
- /* return to unaquired state if that's where it was */
- if (xfd == -1)
- IDirectInputDevice8_Unacquire(iface);
#endif
return DI_OK;
@@ -1390,60 +1346,56 @@ static HRESULT WINAPI JoystickWImpl_Enum
dei.dwSize = sizeof(DIEFFECTINFOW);
- /* We need to return something even if we're not yet acquired */
- if (xfd == -1)
- IDirectInputDevice8_Acquire(iface);
-
if ((type == DIEFT_ALL || type == DIEFT_CONSTANTFORCE)
- && test_bit(This->ffbits, FF_CONSTANT)) {
+ && test_bit(This->joydev->ffbits, FF_CONSTANT)) {
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_ConstantForce);
(*lpCallback)(&dei, pvRef);
}
if ((type == DIEFT_ALL || type == DIEFT_PERIODIC)
- && test_bit(This->ffbits, FF_PERIODIC)) {
- if (test_bit(This->ffbits, FF_SQUARE)) {
+ && test_bit(This->joydev->ffbits, FF_PERIODIC)) {
+ if (test_bit(This->joydev->ffbits, FF_SQUARE)) {
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Square);
(*lpCallback)(&dei, pvRef);
}
- if (test_bit(This->ffbits, FF_SINE)) {
+ if (test_bit(This->joydev->ffbits, FF_SINE)) {
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Sine);
(*lpCallback)(&dei, pvRef);
}
- if (test_bit(This->ffbits, FF_TRIANGLE)) {
+ if (test_bit(This->joydev->ffbits, FF_TRIANGLE)) {
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Triangle);
(*lpCallback)(&dei, pvRef);
}
- if (test_bit(This->ffbits, FF_SAW_UP)) {
+ if (test_bit(This->joydev->ffbits, FF_SAW_UP)) {
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_SawtoothUp);
(*lpCallback)(&dei, pvRef);
}
- if (test_bit(This->ffbits, FF_SAW_DOWN)) {
+ if (test_bit(This->joydev->ffbits, FF_SAW_DOWN)) {
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_SawtoothDown);
(*lpCallback)(&dei, pvRef);
}
}
if ((type == DIEFT_ALL || type == DIEFT_RAMPFORCE)
- && test_bit(This->ffbits, FF_RAMP)) {
+ && test_bit(This->joydev->ffbits, FF_RAMP)) {
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_RampForce);
(*lpCallback)(&dei, pvRef);
}
if (type == DIEFT_ALL || type == DIEFT_CONDITION) {
- if (test_bit(This->ffbits, FF_SPRING)) {
+ if (test_bit(This->joydev->ffbits, FF_SPRING)) {
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Spring);
(*lpCallback)(&dei, pvRef);
}
- if (test_bit(This->ffbits, FF_DAMPER)) {
+ if (test_bit(This->joydev->ffbits, FF_DAMPER)) {
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Damper);
(*lpCallback)(&dei, pvRef);
}
- if (test_bit(This->ffbits, FF_INERTIA)) {
+ if (test_bit(This->joydev->ffbits, FF_INERTIA)) {
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Inertia);
(*lpCallback)(&dei, pvRef);
}
- if (test_bit(This->ffbits, FF_FRICTION)) {
+ if (test_bit(This->joydev->ffbits, FF_FRICTION)) {
IDirectInputDevice8_GetEffectInfo(iface, &dei, &GUID_Friction);
(*lpCallback)(&dei, pvRef);
}
diff --git a/keyboard.c b/keyboard.c
index 9640db9..2cd9314 100644
--- a/keyboard.c
+++ b/keyboard.c
@@ -186,10 +186,10 @@ static void fill_keyboard_dideviceinstan
memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi)));
}
-static BOOL keyboarddev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id)
+static int keyboarddev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id)
{
if (id != 0)
- return FALSE;
+ return -1;
if ((dwDevType == 0) ||
((dwDevType == DIDEVTYPE_KEYBOARD) && (version < 0x0800)) ||
@@ -204,10 +204,10 @@ static BOOL keyboarddev_enum_deviceA(DWO
return FALSE;
}
-static BOOL keyboarddev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
+static int keyboarddev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
{
if (id != 0)
- return FALSE;
+ return -1;
if ((dwDevType == 0) ||
((dwDevType == DIDEVTYPE_KEYBOARD) && (version < 0x0800)) ||
diff --git a/mouse.c b/mouse.c
index 8bd395e..f313b10 100644
--- a/mouse.c
+++ b/mouse.c
@@ -202,10 +202,10 @@ static void fill_mouse_dideviceinstanceW
memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi)));
}
-static BOOL mousedev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id)
+static int mousedev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id)
{
if (id != 0)
- return FALSE;
+ return -1;
if ((dwDevType == 0) ||
((dwDevType == DIDEVTYPE_MOUSE) && (version < 0x0800)) ||
@@ -220,10 +220,10 @@ static BOOL mousedev_enum_deviceA(DWORD
return FALSE;
}
-static BOOL mousedev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
+static int mousedev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
{
if (id != 0)
- return FALSE;
+ return -1;
if ((dwDevType == 0) ||
((dwDevType == DIDEVTYPE_MOUSE) && (version < 0x0800)) ||