mirror of
https://github.com/reactos/reactos.git
synced 2025-05-17 16:27:00 +00:00
[DINPUT] Sync with Wine Staging 1.9.16. CORE-11866
svn path=/trunk/; revision=72264
This commit is contained in:
parent
db110c2bfe
commit
9311bf01ef
5 changed files with 175 additions and 15 deletions
|
@ -512,7 +512,7 @@ failed:
|
|||
return DIERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
/* find an object by it's offset in a data format */
|
||||
/* find an object by its offset in a data format */
|
||||
static int offset_to_object(const DataFormat *df, int offset)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -57,10 +57,13 @@ struct JoyDev
|
|||
{
|
||||
char device[MAX_PATH];
|
||||
char name[MAX_PATH];
|
||||
GUID guid_product;
|
||||
|
||||
BYTE axis_count;
|
||||
BYTE button_count;
|
||||
int *dev_axes_map;
|
||||
|
||||
WORD vendor_id, product_id;
|
||||
};
|
||||
|
||||
typedef struct JoystickImpl JoystickImpl;
|
||||
|
@ -100,6 +103,19 @@ static const GUID DInput_Wine_Joystick_GUID = { /* 9e573ed9-7734-11d2-8d4a-23903
|
|||
{0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
|
||||
};
|
||||
|
||||
/*
|
||||
* Construct the GUID in the same way of Windows doing this.
|
||||
* Data1 is concatenation of productid and vendorid.
|
||||
* Data2 and Data3 are NULL.
|
||||
* Data4 seems to be a constant.
|
||||
*/
|
||||
static const GUID DInput_Wine_Joystick_Constant_Part_GUID = {
|
||||
0x000000000,
|
||||
0x0000,
|
||||
0x0000,
|
||||
{0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44}
|
||||
};
|
||||
|
||||
#define MAX_JOYSTICKS 64
|
||||
static INT joystick_devices_count = -1;
|
||||
static struct JoyDev *joystick_devices;
|
||||
|
@ -115,9 +131,10 @@ static INT find_joystick_devices(void)
|
|||
joystick_devices_count = 0;
|
||||
for (i = 0; i < MAX_JOYSTICKS; i++)
|
||||
{
|
||||
int fd;
|
||||
int fd, sys_fd;
|
||||
struct JoyDev joydev, *new_joydevs;
|
||||
BYTE axes_map[ABS_MAX + 1];
|
||||
char sys_path[sizeof("/sys/class/input/js/device/id/product") + 10], id_str[5];
|
||||
|
||||
snprintf(joydev.device, sizeof(joydev.device), "%s%d", JOYDEV_NEW, i);
|
||||
if ((fd = open(joydev.device, O_RDONLY)) < 0)
|
||||
|
@ -184,6 +201,47 @@ static INT find_joystick_devices(void)
|
|||
joydev.dev_axes_map[j] = -1;
|
||||
}
|
||||
|
||||
/* Find vendor_id and product_id in sysfs */
|
||||
joydev.vendor_id = 0;
|
||||
joydev.product_id = 0;
|
||||
|
||||
sprintf(sys_path, "/sys/class/input/js%d/device/id/vendor", i);
|
||||
sys_fd = open(sys_path, O_RDONLY);
|
||||
if (sys_fd > 0)
|
||||
{
|
||||
if (read(sys_fd, id_str, 4) == 4)
|
||||
{
|
||||
id_str[4] = '\0';
|
||||
joydev.vendor_id = strtol(id_str, NULL, 16);
|
||||
}
|
||||
|
||||
close(sys_fd);
|
||||
}
|
||||
|
||||
sprintf(sys_path, "/sys/class/input/js%d/device/id/product", i);
|
||||
sys_fd = open(sys_path, O_RDONLY);
|
||||
if (sys_fd > 0)
|
||||
{
|
||||
if (read(sys_fd, id_str, 4) == 4)
|
||||
{
|
||||
id_str[4] = '\0';
|
||||
joydev.product_id = strtol(id_str, NULL, 16);
|
||||
}
|
||||
|
||||
close(sys_fd);
|
||||
}
|
||||
|
||||
if (joydev.vendor_id == 0 || joydev.product_id == 0)
|
||||
{
|
||||
joydev.guid_product = DInput_Wine_Joystick_GUID;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Concatenate product_id with vendor_id to mimic Windows behaviour */
|
||||
joydev.guid_product = DInput_Wine_Joystick_Constant_Part_GUID;
|
||||
joydev.guid_product.Data1 = MAKELONG(joydev.vendor_id, joydev.product_id);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
if (!joystick_devices_count)
|
||||
|
@ -214,7 +272,7 @@ static void fill_joystick_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, DWORD ver
|
|||
lpddi->dwSize = dwSize;
|
||||
lpddi->guidInstance = DInput_Wine_Joystick_GUID;
|
||||
lpddi->guidInstance.Data3 = id;
|
||||
lpddi->guidProduct = DInput_Wine_Joystick_GUID;
|
||||
lpddi->guidProduct = joystick_devices[id].guid_product;
|
||||
/* we only support traditional joysticks for now */
|
||||
if (version >= 0x0800)
|
||||
lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
|
||||
|
@ -237,7 +295,7 @@ static void fill_joystick_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD ver
|
|||
lpddi->dwSize = dwSize;
|
||||
lpddi->guidInstance = DInput_Wine_Joystick_GUID;
|
||||
lpddi->guidInstance.Data3 = id;
|
||||
lpddi->guidProduct = DInput_Wine_Joystick_GUID;
|
||||
lpddi->guidProduct = joystick_devices[id].guid_product;
|
||||
/* we only support traditional joysticks for now */
|
||||
if (version >= 0x0800)
|
||||
lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
|
||||
|
|
|
@ -77,6 +77,7 @@ struct JoyDev {
|
|||
char *device;
|
||||
char *name;
|
||||
GUID guid;
|
||||
GUID guid_product;
|
||||
|
||||
BOOL has_ff;
|
||||
int num_effects;
|
||||
|
@ -142,6 +143,19 @@ static const GUID DInput_Wine_Joystick_Base_GUID = { /* 9e573eda-7734-11d2-8d4a-
|
|||
{0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
|
||||
};
|
||||
|
||||
/*
|
||||
* Construct the GUID in the same way of Windows doing this.
|
||||
* Data1 is concatenation of productid and vendorid.
|
||||
* Data2 and Data3 are NULL.
|
||||
* Data4 seems to be a constant.
|
||||
*/
|
||||
static const GUID DInput_Wine_Joystick_Constant_Part_GUID = {
|
||||
0x000000000,
|
||||
0x0000,
|
||||
0x0000,
|
||||
{0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44}
|
||||
};
|
||||
|
||||
#define test_bit(arr,bit) (((BYTE*)(arr))[(bit)>>3]&(1<<((bit)&7)))
|
||||
|
||||
#define MAX_JOYDEV 64
|
||||
|
@ -274,11 +288,18 @@ static void find_joydevs(void)
|
|||
}
|
||||
|
||||
if (ioctl(fd, EVIOCGID, &device_id) == -1)
|
||||
{
|
||||
WARN("ioctl(EVIOCGID) failed: %d %s\n", errno, strerror(errno));
|
||||
joydev.guid_product = DInput_Wine_Joystick_Base_GUID;
|
||||
}
|
||||
else
|
||||
{
|
||||
joydev.vendor_id = device_id.vendor;
|
||||
joydev.product_id = device_id.product;
|
||||
|
||||
/* Concatenate product_id with vendor_id to mimic Windows behaviour */
|
||||
joydev.guid_product = DInput_Wine_Joystick_Constant_Part_GUID;
|
||||
joydev.guid_product.Data1 = MAKELONG(joydev.vendor_id, joydev.product_id);
|
||||
}
|
||||
|
||||
if (!have_joydevs)
|
||||
|
@ -308,7 +329,7 @@ static void fill_joystick_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, DWORD ver
|
|||
|
||||
lpddi->dwSize = dwSize;
|
||||
lpddi->guidInstance = joydevs[id].guid;
|
||||
lpddi->guidProduct = DInput_Wine_Joystick_Base_GUID;
|
||||
lpddi->guidProduct = joydevs[id].guid_product;
|
||||
lpddi->guidFFDriver = GUID_NULL;
|
||||
|
||||
if (version >= 0x0800)
|
||||
|
@ -329,7 +350,7 @@ static void fill_joystick_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD ver
|
|||
|
||||
lpddi->dwSize = dwSize;
|
||||
lpddi->guidInstance = joydevs[id].guid;
|
||||
lpddi->guidProduct = DInput_Wine_Joystick_Base_GUID;
|
||||
lpddi->guidProduct = joydevs[id].guid_product;
|
||||
lpddi->guidFFDriver = GUID_NULL;
|
||||
|
||||
if (version >= 0x0800)
|
||||
|
|
|
@ -175,9 +175,86 @@ static HRESULT osx_to_win32_hresult(HRESULT in)
|
|||
return in;
|
||||
}
|
||||
|
||||
static void CFSetApplierFunctionCopyToCFArray(const void *value, void *context)
|
||||
static long get_device_property_long(IOHIDDeviceRef device, CFStringRef key)
|
||||
{
|
||||
CFArrayAppendValue( ( CFMutableArrayRef ) context, value );
|
||||
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 void copy_set_to_array(const void *value, void *context)
|
||||
{
|
||||
CFArrayAppendValue(context, value);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
/* virtual joysticks may not have a kIOHIDLocationIDKey and will default to location ID of 0, this orders virtual joysticks by their name */
|
||||
return device_name_comparator(device1, device2);
|
||||
}
|
||||
|
||||
static const char* debugstr_cf(CFTypeRef t)
|
||||
|
@ -212,8 +289,9 @@ static const char* debugstr_cf(CFTypeRef t)
|
|||
|
||||
static const char* debugstr_device(IOHIDDeviceRef device)
|
||||
{
|
||||
return wine_dbg_sprintf("<IOHIDDevice %p product %s>", device,
|
||||
debugstr_cf(IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey))));
|
||||
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)
|
||||
|
@ -449,10 +527,13 @@ static int find_osx_devices(void)
|
|||
if (devset)
|
||||
{
|
||||
CFIndex num_devices, num_main_elements, idx;
|
||||
CFMutableArrayRef devices = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
|
||||
CFSetApplyFunction(devset, CFSetApplierFunctionCopyToCFArray, devices);
|
||||
CFRelease( devset);
|
||||
num_devices = CFArrayGetCount(devices);
|
||||
CFMutableArrayRef devices;
|
||||
|
||||
num_devices = CFSetGetCount(devset);
|
||||
devices = CFArrayCreateMutable(kCFAllocatorDefault, num_devices, &kCFTypeArrayCallBacks);
|
||||
CFSetApplyFunction(devset, copy_set_to_array, devices);
|
||||
CFRelease(devset);
|
||||
CFArraySortValues(devices, CFRangeMake(0, num_devices), device_location_name_comparator, NULL);
|
||||
|
||||
device_main_elements = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
|
||||
if (!device_main_elements)
|
||||
|
|
|
@ -30,7 +30,7 @@ reactos/dll/directx/wine/d3dx9_24 => 43 # Synced to WineStaging-1.9.4
|
|||
reactos/dll/directx/wine/d3dxof # Synced to WineStaging-1.9.16
|
||||
reactos/dll/directx/wine/ddraw # Synced to WineStaging-1.9.4
|
||||
reactos/dll/directx/wine/devenum # Synced to WineStaging-1.9.16
|
||||
reactos/dll/directx/wine/dinput # Synced to WineStaging-1.9.11
|
||||
reactos/dll/directx/wine/dinput # Synced to WineStaging-1.9.16
|
||||
reactos/dll/directx/wine/dinput8 # Synced to WineStaging-1.9.11
|
||||
reactos/dll/directx/wine/dmusic # Synced to WineStaging-1.9.11
|
||||
reactos/dll/directx/wine/dplay # Synced to WineStaging-1.9.11
|
||||
|
|
Loading…
Reference in a new issue