mirror of
https://github.com/libretro/RetroArch
synced 2025-04-02 16:20:39 +00:00
Implement changes to fix macOS controller duplication bug
This commit is contained in:
parent
1661d4e969
commit
ce4fce12c0
input
@ -26,9 +26,9 @@
|
|||||||
|
|
||||||
static bool joypad_is_end_of_list(joypad_connection_t *pad)
|
static bool joypad_is_end_of_list(joypad_connection_t *pad)
|
||||||
{
|
{
|
||||||
return pad
|
return pad
|
||||||
&& !pad->connected
|
&& !pad->connected
|
||||||
&& !pad->iface
|
&& !pad->iface
|
||||||
&& (pad->data == (void *)0xdeadbeef);
|
&& (pad->data == (void *)0xdeadbeef);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,8 +183,10 @@ int32_t pad_connection_pad_init(joypad_connection_t *joyconn,
|
|||||||
|
|
||||||
if (name_match || (pad_map[i].vid == vid && pad_map[i].pid == pid))
|
if (name_match || (pad_map[i].vid == vid && pad_map[i].pid == pid))
|
||||||
{
|
{
|
||||||
|
RARCH_DBG("Pad was matched to \"%s\". Setting up an interface.\n", name_match);
|
||||||
s->iface = pad_map[i].iface;
|
s->iface = pad_map[i].iface;
|
||||||
s->data = s->iface->init(data, pad, driver);
|
s->data = data;
|
||||||
|
s->connection = s->iface->init(data, pad, driver);
|
||||||
s->connected = true;
|
s->connected = true;
|
||||||
#if 0
|
#if 0
|
||||||
RARCH_LOG("%s found \n", pad_map[i].name);
|
RARCH_LOG("%s found \n", pad_map[i].name);
|
||||||
@ -203,6 +205,7 @@ int32_t pad_connection_pad_init(joypad_connection_t *joyconn,
|
|||||||
* set up one without an interface */
|
* set up one without an interface */
|
||||||
if (!s->connected)
|
if (!s->connected)
|
||||||
{
|
{
|
||||||
|
RARCH_DBG("Pad was not matched. Setting up without an interface.\n");
|
||||||
s->iface = NULL;
|
s->iface = NULL;
|
||||||
s->data = data;
|
s->data = data;
|
||||||
s->connected = true;
|
s->connected = true;
|
||||||
@ -219,15 +222,16 @@ void pad_connection_pad_deinit(joypad_connection_t *joyconn, uint32_t pad)
|
|||||||
|
|
||||||
if (joyconn->iface)
|
if (joyconn->iface)
|
||||||
{
|
{
|
||||||
joyconn->iface->set_rumble(joyconn->data, RETRO_RUMBLE_STRONG, 0);
|
joyconn->iface->set_rumble(joyconn->connection, RETRO_RUMBLE_STRONG, 0);
|
||||||
joyconn->iface->set_rumble(joyconn->data, RETRO_RUMBLE_WEAK, 0);
|
joyconn->iface->set_rumble(joyconn->connection, RETRO_RUMBLE_WEAK, 0);
|
||||||
|
|
||||||
if (joyconn->iface->deinit)
|
if (joyconn->iface->deinit)
|
||||||
joyconn->iface->deinit(joyconn->data);
|
joyconn->iface->deinit(joyconn->connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
joyconn->iface = NULL;
|
joyconn->iface = NULL;
|
||||||
joyconn->connected = false;
|
joyconn->connected = false;
|
||||||
|
joyconn->connection = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pad_connection_packet(joypad_connection_t *joyconn, uint32_t pad,
|
void pad_connection_packet(joypad_connection_t *joyconn, uint32_t pad,
|
||||||
@ -235,17 +239,17 @@ void pad_connection_packet(joypad_connection_t *joyconn, uint32_t pad,
|
|||||||
{
|
{
|
||||||
if (!joyconn || !joyconn->connected)
|
if (!joyconn || !joyconn->connected)
|
||||||
return;
|
return;
|
||||||
if (joyconn->iface && joyconn->data && joyconn->iface->packet_handler)
|
if (joyconn->iface && joyconn->connection && joyconn->iface->packet_handler)
|
||||||
joyconn->iface->packet_handler(joyconn->data, data, length);
|
joyconn->iface->packet_handler(joyconn->connection, data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pad_connection_get_buttons(joypad_connection_t *joyconn,
|
void pad_connection_get_buttons(joypad_connection_t *joyconn,
|
||||||
unsigned pad, input_bits_t *state)
|
unsigned pad, input_bits_t *state)
|
||||||
{
|
{
|
||||||
if (joyconn && joyconn->iface)
|
if (joyconn && joyconn->iface)
|
||||||
joyconn->iface->get_buttons(joyconn->data, state);
|
joyconn->iface->get_buttons(joyconn->connection, state);
|
||||||
else
|
else
|
||||||
BIT256_CLEAR_ALL_PTR( state );
|
BIT256_CLEAR_ALL_PTR( state );
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t pad_connection_get_axis(joypad_connection_t *joyconn,
|
int16_t pad_connection_get_axis(joypad_connection_t *joyconn,
|
||||||
@ -253,7 +257,7 @@ int16_t pad_connection_get_axis(joypad_connection_t *joyconn,
|
|||||||
{
|
{
|
||||||
if (!joyconn || !joyconn->iface)
|
if (!joyconn || !joyconn->iface)
|
||||||
return 0;
|
return 0;
|
||||||
return joyconn->iface->get_axis(joyconn->data, i);
|
return joyconn->iface->get_axis(joyconn->connection, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pad_connection_has_interface(joypad_connection_t *joyconn, unsigned pad)
|
bool pad_connection_has_interface(joypad_connection_t *joyconn, unsigned pad)
|
||||||
@ -283,7 +287,7 @@ bool pad_connection_rumble(joypad_connection_t *joyconn,
|
|||||||
if (!joyconn->iface || !joyconn->iface->set_rumble)
|
if (!joyconn->iface || !joyconn->iface->set_rumble)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
joyconn->iface->set_rumble(joyconn->data, effect, strength);
|
joyconn->iface->set_rumble(joyconn->connection, effect, strength);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,5 +295,5 @@ const char* pad_connection_get_name(joypad_connection_t *joyconn, unsigned pad)
|
|||||||
{
|
{
|
||||||
if (!joyconn || !joyconn->iface || !joyconn->iface->get_name)
|
if (!joyconn || !joyconn->iface || !joyconn->iface->get_name)
|
||||||
return NULL;
|
return NULL;
|
||||||
return joyconn->iface->get_name(joyconn->data);
|
return joyconn->iface->get_name(joyconn->connection);
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,7 @@ struct joypad_connection
|
|||||||
{
|
{
|
||||||
struct pad_connection_interface *iface;
|
struct pad_connection_interface *iface;
|
||||||
void* data;
|
void* data;
|
||||||
|
void* connection;
|
||||||
bool connected;
|
bool connected;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -33,9 +33,9 @@
|
|||||||
|
|
||||||
typedef struct apple_input_rec
|
typedef struct apple_input_rec
|
||||||
{
|
{
|
||||||
IOHIDElementCookie cookie;
|
IOHIDElementCookie cookie;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
struct apple_input_rec *next;
|
struct apple_input_rec *next;
|
||||||
} apple_input_rec_t;
|
} apple_input_rec_t;
|
||||||
|
|
||||||
typedef struct apple_hid
|
typedef struct apple_hid
|
||||||
@ -51,14 +51,12 @@ struct iohidmanager_hid_adapter
|
|||||||
{
|
{
|
||||||
uint32_t slot;
|
uint32_t slot;
|
||||||
IOHIDDeviceRef handle;
|
IOHIDDeviceRef handle;
|
||||||
|
uint32_t locationId;
|
||||||
char name[PATH_MAX_LENGTH];
|
char name[PATH_MAX_LENGTH];
|
||||||
apple_input_rec_t *axes;
|
apple_input_rec_t *axes;
|
||||||
apple_input_rec_t *hats;
|
apple_input_rec_t *hats;
|
||||||
apple_input_rec_t *buttons;
|
apple_input_rec_t *buttons;
|
||||||
uint8_t data[2048];
|
uint8_t data[2048];
|
||||||
#if !(defined(__ppc__) || defined(__ppc64__))
|
|
||||||
uint32_t uniqueId;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
CFComparisonResult iohidmanager_sort_elements(const void *val1, const void *val2, void *context)
|
CFComparisonResult iohidmanager_sort_elements(const void *val1, const void *val2, void *context)
|
||||||
@ -234,11 +232,11 @@ static int16_t iohidmanager_hid_joypad_state(
|
|||||||
const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE)
|
const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE)
|
||||||
? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis;
|
? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis;
|
||||||
if (
|
if (
|
||||||
(uint16_t)joykey != NO_BTN
|
(uint16_t)joykey != NO_BTN
|
||||||
&& iohidmanager_hid_joypad_button(data, port_idx, (uint16_t)joykey))
|
&& iohidmanager_hid_joypad_button(data, port_idx, (uint16_t)joykey))
|
||||||
ret |= ( 1 << i);
|
ret |= ( 1 << i);
|
||||||
else if (joyaxis != AXIS_NONE &&
|
else if (joyaxis != AXIS_NONE &&
|
||||||
((float)abs(iohidmanager_hid_joypad_axis(data, port_idx, joyaxis))
|
((float)abs(iohidmanager_hid_joypad_axis(data, port_idx, joyaxis))
|
||||||
/ 0x8000) > joypad_info->axis_threshold)
|
/ 0x8000) > joypad_info->axis_threshold)
|
||||||
ret |= (1 << i);
|
ret |= (1 << i);
|
||||||
}
|
}
|
||||||
@ -477,14 +475,29 @@ static void iohidmanager_hid_device_input_callback(void *data, IOReturn result,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iohidmanager_hid_device_remove(void *data,
|
static void iohidmanager_hid_device_remove(IOHIDDeviceRef device, iohidmanager_hid_t* hid)
|
||||||
IOReturn result, void* sender)
|
|
||||||
{
|
{
|
||||||
struct iohidmanager_hid_adapter *adapter =
|
struct iohidmanager_hid_adapter *adapter = NULL;
|
||||||
(struct iohidmanager_hid_adapter*)data;
|
int i;
|
||||||
iohidmanager_hid_t *hid = (iohidmanager_hid_t*)
|
|
||||||
hid_driver_get_data();
|
/*loop though the controller ports and find the device with a matching IOHINDeviceRef*/
|
||||||
|
for (i=0; i<MAX_USERS; i++)
|
||||||
|
{
|
||||||
|
struct iohidmanager_hid_adapter *a = (struct iohidmanager_hid_adapter*)hid->slots[i].data;
|
||||||
|
if (!a)
|
||||||
|
continue;
|
||||||
|
if (a->handle == device)
|
||||||
|
{
|
||||||
|
adapter = a;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!adapter)
|
||||||
|
{
|
||||||
|
RARCH_LOG("Error removing device %p\n",device, hid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int slot = adapter->slot;
|
||||||
if (hid && adapter && (adapter->slot < MAX_USERS))
|
if (hid && adapter && (adapter->slot < MAX_USERS))
|
||||||
{
|
{
|
||||||
input_autoconfigure_disconnect(adapter->slot, adapter->name);
|
input_autoconfigure_disconnect(adapter->slot, adapter->name);
|
||||||
@ -520,6 +533,7 @@ static void iohidmanager_hid_device_remove(void *data,
|
|||||||
}
|
}
|
||||||
free(adapter);
|
free(adapter);
|
||||||
}
|
}
|
||||||
|
RARCH_LOG("Device removed from port %d\n", slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t iohidmanager_hid_device_get_int_property(
|
static int32_t iohidmanager_hid_device_get_int_property(
|
||||||
@ -555,15 +569,7 @@ static uint32_t iohidmanager_hid_device_get_location_id(IOHIDDeviceRef device)
|
|||||||
CFSTR(kIOHIDLocationIDKey));
|
CFSTR(kIOHIDLocationIDKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !(defined(__ppc__) || defined(__ppc64__))
|
|
||||||
static uint32_t iohidmanager_hid_device_get_unique_id(IOHIDDeviceRef device)
|
|
||||||
{
|
|
||||||
/* osx seems to assign an unique id to each device when they are plugged in
|
|
||||||
* the id change if device is unplugged/plugged, but it's unique amongst the
|
|
||||||
* other device plugged */
|
|
||||||
return iohidmanager_hid_device_get_int_property(device,CFSTR(kIOHIDUniqueIDKey));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void iohidmanager_hid_device_get_product_string(
|
static void iohidmanager_hid_device_get_product_string(
|
||||||
IOHIDDeviceRef device, char *buf, size_t len)
|
IOHIDDeviceRef device, char *buf, size_t len)
|
||||||
@ -591,21 +597,11 @@ static void iohidmanager_hid_device_add_autodetect(unsigned idx,
|
|||||||
RARCH_LOG("Port %d: %s.\n", idx, device_name);
|
RARCH_LOG("Port %d: %s.\n", idx, device_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__ppc__) || defined(__ppc64__)
|
|
||||||
static void iohidmanager_hid_device_add(IOHIDDeviceRef device,
|
static void iohidmanager_hid_device_add(IOHIDDeviceRef device, iohidmanager_hid_t* hid)
|
||||||
iohidmanager_hid_t* hid)
|
|
||||||
#else
|
|
||||||
static void iohidmanager_hid_device_add_device(
|
|
||||||
IOHIDDeviceRef device, iohidmanager_hid_t* hid)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* get device unique id */
|
|
||||||
#if !(defined(__ppc__) || defined(__ppc64__))
|
|
||||||
uint32_t deviceUniqueId = iohidmanager_hid_device_get_unique_id(device);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const uint32_t axis_use_ids[11] =
|
static const uint32_t axis_use_ids[11] =
|
||||||
{
|
{
|
||||||
kHIDUsage_GD_X,
|
kHIDUsage_GD_X,
|
||||||
@ -621,18 +617,22 @@ static void iohidmanager_hid_device_add_device(
|
|||||||
kHIDUsage_Sim_Brake
|
kHIDUsage_Sim_Brake
|
||||||
};
|
};
|
||||||
|
|
||||||
#if !(defined(__ppc__) || defined(__ppc64__))
|
/* check if pad was already registered previously when the application was
|
||||||
/* check if pad was already registered previously (by deterministic method)
|
started (by deterministic method). if so do not re-add the pad */
|
||||||
* if so do not re-add the pad */
|
uint32_t deviceLocationId = iohidmanager_hid_device_get_location_id(device);
|
||||||
for (i=0; i<MAX_USERS; i++)
|
for (i=0; i<MAX_USERS; i++)
|
||||||
{
|
{
|
||||||
struct iohidmanager_hid_adapter *a = (struct iohidmanager_hid_adapter*)hid->slots[i].data;
|
struct iohidmanager_hid_adapter *a = (struct iohidmanager_hid_adapter*)hid->slots[i].data;
|
||||||
if (!a)
|
if (!a)
|
||||||
continue;
|
continue;
|
||||||
if (a->uniqueId == deviceUniqueId)
|
if (a->locationId == deviceLocationId)
|
||||||
return;
|
{
|
||||||
}
|
a->handle = device;
|
||||||
#endif
|
/* while we're not re-adding the controller, we are re-assigning the
|
||||||
|
handle so it can be removed properly upon disconnect */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
IOReturn ret;
|
IOReturn ret;
|
||||||
uint16_t dev_vid, dev_pid;
|
uint16_t dev_vid, dev_pid;
|
||||||
@ -654,6 +654,7 @@ static void iohidmanager_hid_device_add_device(
|
|||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
adapter->handle = device;
|
adapter->handle = device;
|
||||||
|
adapter->locationId = deviceLocationId;
|
||||||
|
|
||||||
ret = IOHIDDeviceOpen(device, kIOHIDOptionsTypeNone);
|
ret = IOHIDDeviceOpen(device, kIOHIDOptionsTypeNone);
|
||||||
|
|
||||||
@ -663,8 +664,6 @@ static void iohidmanager_hid_device_add_device(
|
|||||||
/* Move the device's run loop to this thread. */
|
/* Move the device's run loop to this thread. */
|
||||||
IOHIDDeviceScheduleWithRunLoop(device, CFRunLoopGetCurrent(),
|
IOHIDDeviceScheduleWithRunLoop(device, CFRunLoopGetCurrent(),
|
||||||
kCFRunLoopCommonModes);
|
kCFRunLoopCommonModes);
|
||||||
IOHIDDeviceRegisterRemovalCallback(device,
|
|
||||||
iohidmanager_hid_device_remove, adapter);
|
|
||||||
|
|
||||||
#ifndef IOS
|
#ifndef IOS
|
||||||
iohidmanager_hid_device_get_product_string(device, adapter->name,
|
iohidmanager_hid_device_get_product_string(device, adapter->name,
|
||||||
@ -673,9 +672,6 @@ static void iohidmanager_hid_device_add_device(
|
|||||||
|
|
||||||
dev_vid = iohidmanager_hid_device_get_vendor_id (device);
|
dev_vid = iohidmanager_hid_device_get_vendor_id (device);
|
||||||
dev_pid = iohidmanager_hid_device_get_product_id (device);
|
dev_pid = iohidmanager_hid_device_get_product_id (device);
|
||||||
#if !(defined(__ppc__) || defined(__ppc64__))
|
|
||||||
adapter->uniqueId = deviceUniqueId;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
adapter->slot = pad_connection_pad_init(hid->slots,
|
adapter->slot = pad_connection_pad_init(hid->slots,
|
||||||
adapter->name, dev_vid, dev_pid, adapter,
|
adapter->name, dev_vid, dev_pid, adapter,
|
||||||
@ -900,7 +896,6 @@ static void iohidmanager_hid_device_add_device(
|
|||||||
|
|
||||||
iohidmanager_hid_device_add_autodetect(adapter->slot,
|
iohidmanager_hid_device_add_autodetect(adapter->slot,
|
||||||
adapter->name, iohidmanager_hid.ident, dev_vid, dev_pid);
|
adapter->name, iohidmanager_hid.ident, dev_vid, dev_pid);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
@ -940,14 +935,21 @@ error:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !(defined(__ppc__) || defined(__ppc64__))
|
|
||||||
static void iohidmanager_hid_device_add(void *data, IOReturn result,
|
static void iohidmanager_hid_device_matched(void *data, IOReturn result,
|
||||||
void* sender, IOHIDDeviceRef device)
|
void* sender, IOHIDDeviceRef device)
|
||||||
{
|
{
|
||||||
iohidmanager_hid_t *hid = (iohidmanager_hid_t*) hid_driver_get_data();
|
iohidmanager_hid_t *hid = (iohidmanager_hid_t*) hid_driver_get_data();
|
||||||
iohidmanager_hid_device_add_device(device, hid);
|
|
||||||
|
iohidmanager_hid_device_add(device, hid);
|
||||||
}
|
}
|
||||||
#endif
|
static void iohidmanager_hid_device_removed(void *data, IOReturn result,
|
||||||
|
void* sender, IOHIDDeviceRef device)
|
||||||
|
{
|
||||||
|
iohidmanager_hid_t *hid = (iohidmanager_hid_t*) hid_driver_get_data();
|
||||||
|
iohidmanager_hid_device_remove(device, hid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void iohidmanager_hid_append_matching_dictionary(
|
static void iohidmanager_hid_append_matching_dictionary(
|
||||||
CFMutableArrayRef array,
|
CFMutableArrayRef array,
|
||||||
@ -980,7 +982,6 @@ static int iohidmanager_hid_manager_init(iohidmanager_hid_t *hid)
|
|||||||
|
|
||||||
if (!hid->ptr)
|
if (!hid->ptr)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
IOHIDManagerSetDeviceMatching(hid->ptr, NULL);
|
IOHIDManagerSetDeviceMatching(hid->ptr, NULL);
|
||||||
IOHIDManagerScheduleWithRunLoop(hid->ptr, CFRunLoopGetCurrent(),
|
IOHIDManagerScheduleWithRunLoop(hid->ptr, CFRunLoopGetCurrent(),
|
||||||
kCFRunLoopDefaultMode);
|
kCFRunLoopDefaultMode);
|
||||||
@ -1004,103 +1005,99 @@ static int iohidmanager_hid_manager_free(iohidmanager_hid_t *hid)
|
|||||||
static int iohidmanager_hid_manager_set_device_matching(
|
static int iohidmanager_hid_manager_set_device_matching(
|
||||||
iohidmanager_hid_t *hid)
|
iohidmanager_hid_t *hid)
|
||||||
{
|
{
|
||||||
/* deterministically add all device currently plugged when lanching retroarch
|
/* deterministically add all device currently plugged when lanching retroarch
|
||||||
* order by location id which seems to correspond to usb port number */
|
* order by location id which seems to correspond to usb port number */
|
||||||
CFSetRef set = IOHIDManagerCopyDevices(hid->ptr);
|
CFSetRef set = IOHIDManagerCopyDevices(hid->ptr);
|
||||||
CFIndex num_devices = CFSetGetCount(set);
|
CFIndex num_devices = CFSetGetCount(set);
|
||||||
IOHIDDeviceRef *device_array = (IOHIDDeviceRef*)calloc(num_devices, sizeof(IOHIDDeviceRef));
|
IOHIDDeviceRef *device_array = (IOHIDDeviceRef*)calloc(num_devices, sizeof(IOHIDDeviceRef));
|
||||||
CFSetGetValues(set, (const void **) device_array);
|
CFSetGetValues(set, (const void **) device_array);
|
||||||
CFRelease(set);
|
CFRelease(set);
|
||||||
|
/* re order device by location id */
|
||||||
|
typedef struct hid_list
|
||||||
|
{
|
||||||
|
IOHIDDeviceRef device;
|
||||||
|
uint32_t lid;
|
||||||
|
struct hid_list *next;
|
||||||
|
} hid_list_t;
|
||||||
|
|
||||||
/* re order device by location id */
|
hid_list_t* devList = NULL;
|
||||||
typedef struct hid_list
|
for (long i=0; i<num_devices;i++)
|
||||||
{
|
{
|
||||||
IOHIDDeviceRef device;
|
IOHIDDeviceRef dev = device_array[i];
|
||||||
uint32_t lid;
|
/* filter gamepad/joystick devices */
|
||||||
struct hid_list *next;
|
if ( IOHIDDeviceConformsTo(dev, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick)
|
||||||
} hid_list_t;
|
|| IOHIDDeviceConformsTo(dev, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!devList)
|
||||||
|
{
|
||||||
|
devList = (hid_list_t *)malloc(sizeof(hid_list_t));
|
||||||
|
devList->device = dev;
|
||||||
|
devList->lid = iohidmanager_hid_device_get_location_id(dev);
|
||||||
|
devList->next = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hid_list_t * devnew = (hid_list_t *)malloc(sizeof(hid_list_t));
|
||||||
|
devnew->device = dev;
|
||||||
|
devnew->lid = iohidmanager_hid_device_get_location_id(dev);
|
||||||
|
devnew->next = NULL;
|
||||||
|
|
||||||
hid_list_t* devList = NULL;
|
hid_list_t * ptr = devList;
|
||||||
for (long i=0; i<num_devices;i++)
|
if (devnew->lid < ptr->lid)
|
||||||
{
|
{
|
||||||
IOHIDDeviceRef dev = device_array[i];
|
devnew->next = ptr;
|
||||||
/* filter gamepad/joystick devices */
|
devList = devnew;
|
||||||
if ( IOHIDDeviceConformsTo(dev, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick)
|
}
|
||||||
|| IOHIDDeviceConformsTo(dev, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad)
|
else
|
||||||
)
|
{
|
||||||
{
|
while ( ( ptr->lid < devnew->lid ) && (ptr->next != NULL) )
|
||||||
if (!devList)
|
ptr = ptr->next;
|
||||||
{
|
devnew->next = ptr->next;
|
||||||
devList = (hid_list_t *)malloc(sizeof(hid_list_t));
|
ptr->next = devnew;
|
||||||
devList->device = dev;
|
}
|
||||||
devList->lid = iohidmanager_hid_device_get_location_id(dev);
|
}
|
||||||
devList->next = NULL;
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
hid_list_t * devnew = (hid_list_t *)malloc(sizeof(hid_list_t));
|
|
||||||
devnew->device = dev;
|
|
||||||
devnew->lid = iohidmanager_hid_device_get_location_id(dev);
|
|
||||||
devnew->next = NULL;
|
|
||||||
|
|
||||||
hid_list_t * ptr = devList;
|
/* register devices */
|
||||||
if (devnew->lid < ptr->lid)
|
hid_list_t * ptr = devList;
|
||||||
{
|
while (ptr != NULL)
|
||||||
devnew->next = ptr;
|
{
|
||||||
devList = devnew;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while ( ( ptr->lid < devnew->lid ) && (ptr->next != NULL) )
|
|
||||||
ptr = ptr->next;
|
|
||||||
devnew->next = ptr->next;
|
|
||||||
ptr->next = devnew;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* register devices */
|
|
||||||
hid_list_t * ptr = devList;
|
|
||||||
while (ptr != NULL)
|
|
||||||
{
|
|
||||||
#if defined(__ppc__) || defined(__ppc64__)
|
|
||||||
iohidmanager_hid_device_add(ptr->device, hid);
|
iohidmanager_hid_device_add(ptr->device, hid);
|
||||||
#else
|
|
||||||
iohidmanager_hid_device_add_device(ptr->device, hid);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//printf("%d\n",ptr->lid);
|
|
||||||
ptr = ptr->next;
|
|
||||||
free(devList);
|
|
||||||
devList = ptr;
|
|
||||||
}
|
|
||||||
free(device_array);
|
|
||||||
|
|
||||||
#if !(defined(__ppc__) || defined(__ppc64__))
|
ptr = ptr->next;
|
||||||
/* register call back to dynamically add device plugged when retroarch is
|
free(devList);
|
||||||
* running
|
devList = ptr;
|
||||||
* those will be added after the one plugged when retroarch was launched,
|
}
|
||||||
* and by order they are plugged in (so not deterministic) */
|
free(device_array);
|
||||||
CFMutableArrayRef matcher = CFArrayCreateMutable(kCFAllocatorDefault, 0,
|
|
||||||
&kCFTypeArrayCallBacks);
|
|
||||||
|
|
||||||
if (!matcher)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
iohidmanager_hid_append_matching_dictionary(matcher,
|
/* register call back to dynamically add device plugged when retroarch is
|
||||||
kHIDPage_GenericDesktop,
|
* running
|
||||||
kHIDUsage_GD_Joystick);
|
* those will be added after the one plugged when retroarch was launched,
|
||||||
iohidmanager_hid_append_matching_dictionary(matcher,
|
* and by order they are plugged in (so not deterministic) */
|
||||||
kHIDPage_GenericDesktop,
|
CFMutableArrayRef matcher = CFArrayCreateMutable(kCFAllocatorDefault, 0,
|
||||||
kHIDUsage_GD_GamePad);
|
&kCFTypeArrayCallBacks);
|
||||||
|
|
||||||
IOHIDManagerSetDeviceMatchingMultiple(hid->ptr, matcher);
|
if (!matcher)
|
||||||
IOHIDManagerRegisterDeviceMatchingCallback(hid->ptr,
|
return -1;
|
||||||
iohidmanager_hid_device_add, 0);
|
|
||||||
|
iohidmanager_hid_append_matching_dictionary(matcher,
|
||||||
|
kHIDPage_GenericDesktop,
|
||||||
|
kHIDUsage_GD_Joystick);
|
||||||
|
iohidmanager_hid_append_matching_dictionary(matcher,
|
||||||
|
kHIDPage_GenericDesktop,
|
||||||
|
kHIDUsage_GD_GamePad);
|
||||||
|
|
||||||
|
IOHIDManagerSetDeviceMatchingMultiple(hid->ptr, matcher);
|
||||||
|
IOHIDManagerRegisterDeviceMatchingCallback(hid->ptr,iohidmanager_hid_device_matched, 0);
|
||||||
|
IOHIDManagerRegisterDeviceRemovalCallback(hid->ptr,iohidmanager_hid_device_removed, 0);
|
||||||
|
|
||||||
|
CFRelease(matcher);
|
||||||
|
|
||||||
CFRelease(matcher);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user