diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index c59b1b1fb0a..54365c74af2 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -238,7 +238,7 @@ static HRESULT WINAPI IDirectInputAImpl_EnumDevices( { IDirectInputImpl *This = (IDirectInputImpl *)iface; DIDEVICEINSTANCEA devInstance; - int i; + int i, j, r; TRACE("(this=%p,0x%04lx '%s',%p,%p,%04lx)\n", This, dwDevType, _dump_DIDEVTYPE_value(dwDevType), @@ -246,11 +246,13 @@ static HRESULT WINAPI IDirectInputAImpl_EnumDevices( TRACE(" flags: "); _dump_EnumDevices_dwFlags(dwFlags); TRACE("\n"); for (i = 0; i < nrof_dinput_devices; i++) { - devInstance.dwSize = sizeof(devInstance); - TRACE(" - checking device %d ('%s')\n", i, dinput_devices[i]->name); - if (dinput_devices[i]->enum_deviceA(dwDevType, dwFlags, &devInstance, This->version)) { - if (lpCallback(&devInstance,pvRef) == DIENUM_STOP) - return 0; + for (j = 0, r = -1; r != 0; 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->version, j))) { + if (lpCallback(&devInstance,pvRef) == DIENUM_STOP) + return 0; + } } } @@ -265,7 +267,7 @@ static HRESULT WINAPI IDirectInputWImpl_EnumDevices( { IDirectInputImpl *This = (IDirectInputImpl *)iface; DIDEVICEINSTANCEW devInstance; - int i; + int i, j, r; TRACE("(this=%p,0x%04lx '%s',%p,%p,%04lx)\n", This, dwDevType, _dump_DIDEVTYPE_value(dwDevType), @@ -273,11 +275,13 @@ static HRESULT WINAPI IDirectInputWImpl_EnumDevices( TRACE(" flags: "); _dump_EnumDevices_dwFlags(dwFlags); TRACE("\n"); for (i = 0; i < nrof_dinput_devices; i++) { - devInstance.dwSize = sizeof(devInstance); - TRACE(" - checking device %d ('%s')\n", i, dinput_devices[i]->name); - if (dinput_devices[i]->enum_deviceW(dwDevType, dwFlags, &devInstance, This->version)) { - if (lpCallback(&devInstance,pvRef) == DIENUM_STOP) - return 0; + for (j = 0, r = -1; r != 0; 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->version, j))) { + if (lpCallback(&devInstance,pvRef) == DIENUM_STOP) + return 0; + } } } diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h index b24b2d8ebed..393d1259dbd 100644 --- a/dlls/dinput/dinput_private.h +++ b/dlls/dinput/dinput_private.h @@ -42,8 +42,8 @@ struct IDirectInputImpl typedef struct dinput_device { INT pref; const char *name; - BOOL (*enum_deviceA)(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version); - BOOL (*enum_deviceW)(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version); + BOOL (*enum_deviceA)(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version, int id); + BOOL (*enum_deviceW)(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version, int id); HRESULT (*create_deviceA)(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev); HRESULT (*create_deviceW)(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev); } dinput_device; diff --git a/dlls/dinput/joystick_linux.c b/dlls/dinput/joystick_linux.c index ea8a6644ebf..418db8a6a92 100644 --- a/dlls/dinput/joystick_linux.c +++ b/dlls/dinput/joystick_linux.c @@ -21,7 +21,6 @@ /* * To Do: - * support more than one device * dead zone * force feedback */ @@ -56,7 +55,7 @@ #ifdef HAVE_LINUX_JOYSTICK_H # include #endif -#define JOYDEV "/dev/js0" +#define JOYDEV "/dev/js" #include "wine/debug.h" #include "wine/unicode.h" @@ -91,6 +90,7 @@ struct JoystickImpl LPVOID lpVtbl; DWORD ref; GUID guid; + char dev[32]; /* The 'parent' DInput */ IDirectInputImpl *dinput; @@ -147,9 +147,10 @@ static void _dump_DIDEVCAPS(LPDIDEVCAPS lpDIDevCaps) } } -static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version) +static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version, int id) { int fd = -1; + char dev[32]; if (dwFlags & DIEDFL_FORCEFEEDBACK) { WARN("force feedback not supported\n"); @@ -158,23 +159,25 @@ static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTAN if ((dwDevType==0) || (GET_DIDEVICE_TYPE(dwDevType)==DIDEVTYPE_JOYSTICK)) { /* check whether we have a joystick */ - if ((fd = open(JOYDEV,O_RDONLY)) < 0) { - WARN("open(%s,O_RDONLY) failed: %s\n", JOYDEV, strerror(errno)); + sprintf(dev, "%s%d", JOYDEV, id); + if ((fd = open(dev,O_RDONLY)) < 0) { + WARN("open(%s,O_RDONLY) failed: %s\n", dev, strerror(errno)); return FALSE; } /* Return joystick */ - lpddi->guidInstance = GUID_Joystick; + lpddi->guidInstance = DInput_Wine_Joystick_GUID; + lpddi->guidInstance.Data3 = id; lpddi->guidProduct = DInput_Wine_Joystick_GUID; /* we only support traditional joysticks for now */ if (version >= 8) lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8); else lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8); - strcpy(lpddi->tszInstanceName, "Joystick"); + sprintf(lpddi->tszInstanceName, "Joystick %d", id); #if defined(JSIOCGNAME) if (ioctl(fd,JSIOCGNAME(sizeof(lpddi->tszProductName)),lpddi->tszProductName) < 0) { - WARN("ioctl(%s,JSIOCGNAME) failed: %s\n", JOYDEV, strerror(errno)); + WARN("ioctl(%s,JSIOCGNAME) failed: %s\n", dev, strerror(errno)); strcpy(lpddi->tszProductName, "Wine Joystick"); } #else @@ -183,17 +186,19 @@ static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTAN lpddi->guidFFDriver = GUID_NULL; close(fd); - TRACE("Enumerating the linux Joystick device: %s (%s)\n", JOYDEV, lpddi->tszProductName); + TRACE("Enumerating the linux Joystick device: %s (%s)\n", dev, lpddi->tszProductName); return TRUE; } return FALSE; } -static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version) +static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version, int id) { int fd = -1; char name[MAX_PATH]; + char dev[32]; + char friendly[32]; if (dwFlags & DIEDFL_FORCEFEEDBACK) { WARN("force feedback not supported\n"); @@ -202,22 +207,26 @@ static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTAN if ((dwDevType==0) || (GET_DIDEVICE_TYPE(dwDevType)==DIDEVTYPE_JOYSTICK)) { /* check whether we have a joystick */ - if ((fd = open(JOYDEV,O_RDONLY)) < 0) { - WARN("open(%s,O_RDONLY) failed: %s\n", JOYDEV, strerror(errno)); + sprintf(dev, "%s%d", JOYDEV, id); + if ((fd = open(dev,O_RDONLY)) < 0) { + WARN("open(%s,O_RDONLY) failed: %s\n", dev, strerror(errno)); return FALSE; } /* Return joystick */ - lpddi->guidInstance = GUID_Joystick; + lpddi->guidInstance = DInput_Wine_Joystick_GUID; + lpddi->guidInstance.Data3 = id; lpddi->guidProduct = DInput_Wine_Joystick_GUID; /* we only support traditional joysticks for now */ - lpddi->dwDevType = DIDEVTYPE_JOYSTICK | - (DIDEVTYPEJOYSTICK_TRADITIONAL<<8); - - MultiByteToWideChar(CP_ACP, 0, "Joystick", -1, lpddi->tszInstanceName, MAX_PATH); + if (version >= 8) + lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8); + else + lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8); + sprintf(friendly, "Joystick %d", id); + MultiByteToWideChar(CP_ACP, 0, friendly, -1, lpddi->tszInstanceName, MAX_PATH); #if defined(JSIOCGNAME) if (ioctl(fd,JSIOCGNAME(sizeof(name)),name) < 0) { - WARN("ioctl(%s,JSIOCGNAME) failed: %s\n", JOYDEV, strerror(errno)); + WARN("ioctl(%s,JSIOCGNAME) failed: %s\n", dev, strerror(errno)); strcpy(name, "Wine Joystick"); } #else @@ -226,7 +235,7 @@ static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTAN MultiByteToWideChar(CP_ACP, 0, name, -1, lpddi->tszProductName, MAX_PATH); lpddi->guidFFDriver = GUID_NULL; close(fd); - TRACE("Enumerating the linux Joystick device: %s (%s)\n",JOYDEV,name); + TRACE("Enumerating the linux Joystick device: %s (%s)\n",dev,name); return TRUE; } @@ -437,8 +446,10 @@ static HRESULT alloc_device(REFGUID rguid, LPVOID jvt, IDirectInputImpl *dinput, return DIERR_OUTOFMEMORY; } - if ((newDevice->joyfd = open(JOYDEV,O_RDONLY)) < 0) { - WARN("open(%s,O_RDONLY) failed: %s\n", JOYDEV, strerror(errno)); + sprintf(newDevice->dev, "%s%d", JOYDEV, rguid->Data3); + + if ((newDevice->joyfd = open(newDevice->dev,O_RDONLY)) < 0) { + WARN("open(%s,O_RDONLY) failed: %s\n", newDevice->dev, strerror(errno)); HeapFree(GetProcessHeap(), 0, newDevice); return DIERR_DEVICENOTREG; } @@ -446,7 +457,7 @@ static HRESULT alloc_device(REFGUID rguid, LPVOID jvt, IDirectInputImpl *dinput, /* get the device name */ #if defined(JSIOCGNAME) if (ioctl(newDevice->joyfd,JSIOCGNAME(MAX_PATH),name) < 0) { - WARN("ioctl(%s,JSIOCGNAME) failed: %s\n", JOYDEV, strerror(errno)); + WARN("ioctl(%s,JSIOCGNAME) failed: %s\n", newDevice->dev, strerror(errno)); strcpy(name, "Wine Joystick"); } #else @@ -459,13 +470,13 @@ static HRESULT alloc_device(REFGUID rguid, LPVOID jvt, IDirectInputImpl *dinput, #ifdef JSIOCGAXES if (ioctl(newDevice->joyfd,JSIOCGAXES,&newDevice->axes) < 0) { - WARN("ioctl(%s,JSIOCGAXES) failed: %s, defauting to 2\n", JOYDEV, strerror(errno)); + WARN("ioctl(%s,JSIOCGAXES) failed: %s, defauting to 2\n", newDevice->dev, strerror(errno)); newDevice->axes = 2; } #endif #ifdef JSIOCGBUTTONS if (ioctl(newDevice->joyfd,JSIOCGBUTTONS,&newDevice->buttons) < 0) { - WARN("ioctl(%s,JSIOCGBUTTONS) failed: %s, defauting to 2\n", JOYDEV, strerror(errno)); + WARN("ioctl(%s,JSIOCGBUTTONS) failed: %s, defauting to 2\n", newDevice->dev, strerror(errno)); newDevice->buttons = 2; } #endif @@ -579,10 +590,21 @@ FAILED1: return hr; } +static BOOL IsJoystickGUID(REFGUID guid) +{ + GUID wine_joystick = DInput_Wine_Joystick_GUID; + GUID dev_guid = *guid; + + wine_joystick.Data3 = 0; + dev_guid.Data3 = 0; + + return IsEqualGUID(&wine_joystick, &dev_guid); +} + static HRESULT joydev_create_deviceA(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev) { if ((IsEqualGUID(&GUID_Joystick,rguid)) || - (IsEqualGUID(&DInput_Wine_Joystick_GUID,rguid))) { + (IsJoystickGUID(rguid))) { if ((riid == NULL) || IsEqualGUID(&IID_IDirectInputDeviceA,riid) || IsEqualGUID(&IID_IDirectInputDevice2A,riid) || @@ -604,7 +626,7 @@ static HRESULT joydev_create_deviceA(IDirectInputImpl *dinput, REFGUID rguid, RE static HRESULT joydev_create_deviceW(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev) { if ((IsEqualGUID(&GUID_Joystick,rguid)) || - (IsEqualGUID(&DInput_Wine_Joystick_GUID,rguid))) { + (IsJoystickGUID(rguid))) { if ((riid == NULL) || IsEqualGUID(&IID_IDirectInputDeviceW,riid) || IsEqualGUID(&IID_IDirectInputDevice2W,riid) || @@ -764,11 +786,11 @@ static HRESULT WINAPI JoystickAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface) /* open the joystick device */ if (This->joyfd==-1) { - TRACE("opening joystick device %s\n", JOYDEV); + TRACE("opening joystick device %s\n", This->dev); - This->joyfd=open(JOYDEV,O_RDONLY); + This->joyfd=open(This->dev,O_RDONLY); if (This->joyfd==-1) { - ERR("open(%s) failed: %s\n", JOYDEV, strerror(errno)); + ERR("open(%s) failed: %s\n", This->dev, strerror(errno)); return DIERR_NOTFOUND; } } diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c index 6326948e87d..5a436aa16c6 100644 --- a/dlls/dinput/joystick_linuxinput.c +++ b/dlls/dinput/joystick_linuxinput.c @@ -168,10 +168,13 @@ static int joydev_have(void) return havejoy; } -static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version) +static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version, int id) { int havejoy = 0; + if (id != 0) + return FALSE; + if ((dwDevType != 0) && (GET_DIDEVICE_TYPE(dwDevType) != DIDEVTYPE_JOYSTICK)) return FALSE; @@ -201,10 +204,13 @@ static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTAN return TRUE; } -static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version) +static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version, int id) { int havejoy = 0; + if (id != 0) + return FALSE; + if ((dwDevType != 0) && (GET_DIDEVICE_TYPE(dwDevType) != DIDEVTYPE_JOYSTICK)) return FALSE; diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c index 944ca6bca81..c5931f93915 100644 --- a/dlls/dinput/keyboard.c +++ b/dlls/dinput/keyboard.c @@ -199,8 +199,11 @@ static void fill_keyboard_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, int versi memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi))); } -static BOOL keyboarddev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version) +static BOOL keyboarddev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version, int id) { + if (id != 0) + return FALSE; + if ((dwDevType == 0) || ((dwDevType == DIDEVTYPE_KEYBOARD) && (version < 8)) || ((dwDevType == DI8DEVTYPE_KEYBOARD) && (version >= 8))) { @@ -214,8 +217,11 @@ static BOOL keyboarddev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEI return FALSE; } -static BOOL keyboarddev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version) +static BOOL keyboarddev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version, int id) { + if (id != 0) + return FALSE; + if ((dwDevType == 0) || ((dwDevType == DIDEVTYPE_KEYBOARD) && (version < 8)) || ((dwDevType == DI8DEVTYPE_KEYBOARD) && (version >= 8))) { diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c index 55a011b8e59..60cbd430175 100644 --- a/dlls/dinput/mouse.c +++ b/dlls/dinput/mouse.c @@ -203,8 +203,11 @@ static void fill_mouse_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, int version) memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi))); } -static BOOL mousedev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version) +static BOOL mousedev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version, int id) { + if (id != 0) + return FALSE; + if ((dwDevType == 0) || ((dwDevType == DIDEVTYPE_MOUSE) && (version < 8)) || ((dwDevType == DI8DEVTYPE_MOUSE) && (version >= 8))) { @@ -218,8 +221,11 @@ static BOOL mousedev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINST return FALSE; } -static BOOL mousedev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version) +static BOOL mousedev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version, int id) { + if (id != 0) + return FALSE; + if ((dwDevType == 0) || ((dwDevType == DIDEVTYPE_MOUSE) && (version < 8)) || ((dwDevType == DI8DEVTYPE_MOUSE) && (version >= 8))) {