Skip to content

Commit

Permalink
WIP: fixing controller duplication bug.
Browse files Browse the repository at this point in the history
In this commit, I have disabled the pad-matching feature at ~L:218 in joypad_connection.c
You can re-enable the functionality from there to experience the current issues.
When I plug in a PS4 controller, the iohidmanager_hid_adapter is being overwritten by what I believe is a pad_controller struct within hidpad_ps4_init()
The *data being passed to hidpad_ps4_init() is a struct iohidmanager_hid_adapter, but it's being de-referenced as a pad_connection
I do not know what this function is intended to be doing - but it's certainly not this.
This is likely an issue across most/all of the other connect_xxx.c files.
I suspect this code was broken for a very long time, but went unnoticed because the thing it broke was already broken.
  • Loading branch information
ComradeEcho committed Aug 4, 2021
1 parent 96705f2 commit 7b87ab6
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 20 deletions.
10 changes: 10 additions & 0 deletions input/connect/joypad_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ int32_t pad_connection_pad_init(joypad_connection_t *joyconn,

if (name_match || (pad_map[i].vid == vid && pad_map[i].pid == pid))
{
printf("Pad was matched to \"%s\". Setting up an interface.\n", name_match);
s->iface = pad_map[i].iface;
s->data = s->iface->init(data, pad, driver);
s->connected = true;
Expand All @@ -203,11 +204,20 @@ int32_t pad_connection_pad_init(joypad_connection_t *joyconn,
* set up one without an interface */
if (!s->connected)
{
printf("Pad was not matched. Setting up without an interface.\n");
s->iface = NULL;
s->data = data;
s->connected = true;
}
}
/* This was added to override the pad-matching code.
Something in the pad-matching code overwrites
our iohidmanager_hid_adapter with a pad_connection struct
resulting in the loss of the IOHIDDeviceRef required to
identify when a specific controller is disconnected*/
s->iface = NULL; //delete these three lines to re-enable pad-matching
s->data = data; //delete these three lines to re-enable pad-matching
s->connected = true; //delete these three lines to re-enable pad-matching

return pad;
}
Expand Down
70 changes: 50 additions & 20 deletions input/drivers_hid/iohidmanager_hid.c
Original file line number Diff line number Diff line change
Expand Up @@ -473,14 +473,43 @@ static void iohidmanager_hid_device_input_callback(void *data, IOReturn result,
}
}
}

static void iohidmanager_hid_device_remove(void *data,
IOReturn result, void* sender)
static void list_controllers()
{
struct iohidmanager_hid_adapter *adapter =
(struct iohidmanager_hid_adapter*)data;
iohidmanager_hid_t *hid = (iohidmanager_hid_t*)
hid_driver_get_data();
iohidmanager_hid_t *hid = (iohidmanager_hid_t*) hid_driver_get_data();
if (!hid)
return;
for (int i=0; i<4; i++)
{
struct iohidmanager_hid_adapter *a = (struct iohidmanager_hid_adapter*)hid->slots[i].data;
if (!a)
{
printf("Port %d is not assigned to a controller on HID %p \n", i, hid);
continue;
}
else
printf("Port %d is assigned to device %p on HID %p \n", i, a->handle, hid);
}
printf("\n");
}
static void iohidmanager_hid_device_remove(IOHIDDeviceRef *device, iohidmanager_hid_t* hid)
{
struct iohidmanager_hid_adapter *adapter = NULL;
//loop though the controller ports and find the device with a matching IOHINDeviceRef
for (int 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)
{
printf("Error removing device %p from HID %p\n",device, hid);
}

if (hid && adapter && (adapter->slot < MAX_USERS))
{
Expand Down Expand Up @@ -517,6 +546,7 @@ static void iohidmanager_hid_device_remove(void *data,
}
free(adapter);
}
list_controllers();
}

static int32_t iohidmanager_hid_device_get_int_property(
Expand Down Expand Up @@ -581,12 +611,10 @@ static void iohidmanager_hid_device_add_autodetect(unsigned idx,
}


static void iohidmanager_hid_device_add_device(IOHIDDeviceRef device, iohidmanager_hid_t* hid)
static void iohidmanager_hid_device_add(IOHIDDeviceRef* device, iohidmanager_hid_t* hid)
{
int i;



static const uint32_t axis_use_ids[11] =
{
kHIDUsage_GD_X,
Expand Down Expand Up @@ -633,8 +661,6 @@ static void iohidmanager_hid_device_add_device(IOHIDDeviceRef device, iohidmanag
/* Move the device's run loop to this thread. */
IOHIDDeviceScheduleWithRunLoop(device, CFRunLoopGetCurrent(),
kCFRunLoopCommonModes);
IOHIDDeviceRegisterRemovalCallback(device,
iohidmanager_hid_device_remove, adapter);

#ifndef IOS
iohidmanager_hid_device_get_product_string(device, adapter->name,
Expand Down Expand Up @@ -863,7 +889,7 @@ static void iohidmanager_hid_device_add_device(IOHIDDeviceRef device, iohidmanag

iohidmanager_hid_device_add_autodetect(adapter->slot,
adapter->name, iohidmanager_hid.ident, dev_vid, dev_pid);

list_controllers();
return;

error:
Expand Down Expand Up @@ -904,11 +930,15 @@ static void iohidmanager_hid_device_add_device(IOHIDDeviceRef device, iohidmanag
}


static void iohidmanager_hid_device_add(void *data, IOReturn result,
void* sender, IOHIDDeviceRef device)
static void iohidmanager_hid_device_matched(iohidmanager_hid_t *hid, IOReturn result, void* sender, IOHIDDeviceRef device)
{
printf("Adding device %p to HID %p\n", device, hid);
iohidmanager_hid_device_add(device, hid);
}
static void iohidmanager_hid_device_removed(iohidmanager_hid_t *hid, IOReturn result, void* sender, IOHIDDeviceRef device)
{
iohidmanager_hid_t *hid = (iohidmanager_hid_t*) hid_driver_get_data();
iohidmanager_hid_device_add_device(device, hid);
printf("Removing device %p from HID %p\n", device, hid);
iohidmanager_hid_device_remove(device, hid);
}


Expand Down Expand Up @@ -1027,7 +1057,7 @@ static int iohidmanager_hid_manager_set_device_matching(
while (ptr != NULL)
{

iohidmanager_hid_device_add_device(ptr->device, hid);
iohidmanager_hid_device_add(ptr->device, hid);


ptr = ptr->next;
Expand Down Expand Up @@ -1055,8 +1085,8 @@ static int iohidmanager_hid_manager_set_device_matching(
kHIDUsage_GD_GamePad);

IOHIDManagerSetDeviceMatchingMultiple(hid->ptr, matcher);
IOHIDManagerRegisterDeviceMatchingCallback(hid->ptr,
iohidmanager_hid_device_add, 0);
IOHIDManagerRegisterDeviceMatchingCallback(hid->ptr,iohidmanager_hid_device_matched, hid);
IOHIDManagerRegisterDeviceRemovalCallback(hid->ptr,iohidmanager_hid_device_removed, hid);

CFRelease(matcher);

Expand Down

0 comments on commit 7b87ab6

Please sign in to comment.