From 3fc2ddb8d243b12237f5cc9d64428352b8c1040a Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 22 Jan 2018 06:48:56 +0100 Subject: [PATCH] (IOHIDManager) Add improvements - https://github.com/libretro/RetroArch/issues/4816#issuecomment-359145035 --- input/drivers_hid/iohidmanager_hid.c | 183 +++++++++++++++------------ 1 file changed, 105 insertions(+), 78 deletions(-) diff --git a/input/drivers_hid/iohidmanager_hid.c b/input/drivers_hid/iohidmanager_hid.c index 98a53901db..c2c215ec80 100644 --- a/input/drivers_hid/iohidmanager_hid.c +++ b/input/drivers_hid/iohidmanager_hid.c @@ -227,10 +227,8 @@ static void iohidmanager_hid_device_report(void *data, static void iohidmanager_hid_device_input_callback(void *data, IOReturn result, void* sender, IOHIDValueRef value) { - iohidmanager_hid_t *hid = (iohidmanager_hid_t*) - hid_driver_get_data(); - struct iohidmanager_hid_adapter *adapter = - (struct iohidmanager_hid_adapter*)data; + iohidmanager_hid_t *hid = (iohidmanager_hid_t*)hid_driver_get_data(); + struct iohidmanager_hid_adapter *adapter = (struct iohidmanager_hid_adapter*)data; IOHIDElementRef element = IOHIDValueGetElement(value); uint32_t type = (uint32_t)IOHIDElementGetType(element); uint32_t page = (uint32_t)IOHIDElementGetUsagePage(element); @@ -246,6 +244,8 @@ static void iohidmanager_hid_device_input_callback(void *data, IOReturn result, /* Joystick handler. * TODO: Can GamePad work the same? */ + int pushed_button = 0; + switch (page) { case kHIDPage_GenericDesktop: @@ -326,43 +326,58 @@ static void iohidmanager_hid_device_input_callback(void *data, IOReturn result, while(tmp && tmp->cookie != (IOHIDElementCookie)cookie) tmp = tmp->next; - if(tmp->cookie == (IOHIDElementCookie)cookie) + if (tmp) { - CFIndex min = IOHIDElementGetPhysicalMin(element); - CFIndex state = IOHIDValueGetIntegerValue(value) - min; - CFIndex max = IOHIDElementGetPhysicalMax(element) - min; - float val = (float)state / (float)max; + if(tmp->cookie == (IOHIDElementCookie)cookie) + { + CFIndex min = IOHIDElementGetPhysicalMin(element); + CFIndex state = IOHIDValueGetIntegerValue(value) - min; + CFIndex max = IOHIDElementGetPhysicalMax(element) - min; + float val = (float)state / (float)max; - hid->axes[adapter->slot][tmp->id] = - ((val * 2.0f) - 1.0f) * 32767.0f; + hid->axes[adapter->slot][tmp->id] = + ((val * 2.0f) - 1.0f) * 32767.0f; + } } + else + pushed_button = 1; break; } break; } break; + case kHIDPage_Consumer: case kHIDPage_Button: switch (type) { + case kIOHIDElementTypeInput_Misc: case kIOHIDElementTypeInput_Button: - tmp = adapter->buttons; - - while(tmp && tmp->cookie != (IOHIDElementCookie)cookie) - tmp = tmp->next; - - if(tmp->cookie == (IOHIDElementCookie)cookie) - { - CFIndex state = IOHIDValueGetIntegerValue(value); - - if (state) - BIT64_SET(hid->buttons[adapter->slot], tmp->id); - else - BIT64_CLEAR(hid->buttons[adapter->slot], tmp->id); - } + pushed_button = 1; break; } break; } + + if (pushed_button) + { + tmp = adapter->buttons; + + uint8_t bit = 0; + while(tmp && tmp->cookie != (IOHIDElementCookie)cookie) + { + bit++; + tmp = tmp->next; + } + + if(tmp && tmp->cookie == (IOHIDElementCookie)cookie) + { + CFIndex state = IOHIDValueGetIntegerValue(value); + if (state) + BIT64_SET(hid->buttons[adapter->slot], bit); + else + BIT64_CLEAR(hid->buttons[adapter->slot], bit); + } + } } static void iohidmanager_hid_device_remove(void *data, @@ -530,13 +545,13 @@ static void iohidmanager_hid_device_add(void *data, IOReturn result, elements_raw = IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone); count = (int)CFArrayGetCount(elements_raw); elements = CFArrayCreateMutableCopy( - kCFAllocatorDefault,(CFIndex)count,elements_raw); + kCFAllocatorDefault,(CFIndex)count,elements_raw); range = CFRangeMake(0,count); CFArraySortValues(elements, - range, iohidmanager_sort_elements, NULL); + range, iohidmanager_sort_elements, NULL); - for(i=0; iaxes = axis; } } + else + detected_button = 1; } break; } break; } break; + case kHIDPage_Consumer: case kHIDPage_Button: switch (type) { case kIOHIDElementTypeCollection: case kIOHIDElementTypeFeature: case kIOHIDElementTypeInput_ScanCodes: - case kIOHIDElementTypeInput_Misc: case kIOHIDElementTypeInput_Axis: case kIOHIDElementTypeOutput: /* TODO/FIXME */ break; + case kIOHIDElementTypeInput_Misc: case kIOHIDElementTypeInput_Button: - { - apple_input_rec_t *btn = (apple_input_rec_t *)malloc(sizeof(apple_input_rec_t)); - btn->id = (uint32_t)(use - 1); - btn->cookie = (IOHIDElementCookie)cookie; - btn->next = NULL; - - if(iohidmanager_check_for_id(adapter->buttons,btn->id)) - { - if(tmpButtons) - iohidmanager_append_record(tmpButtons, btn); - else - tmpButtons = btn; - } - else - { - if(adapter->buttons) - iohidmanager_append_record(adapter->buttons, btn); - else - adapter->buttons = btn; - } - } + detected_button = 1; break; } break; } + + if (detected_button) + { + apple_input_rec_t *btn = (apple_input_rec_t *)malloc(sizeof(apple_input_rec_t)); + btn->id = (uint32_t)use; + btn->cookie = (IOHIDElementCookie)cookie; + btn->next = NULL; + + if(iohidmanager_check_for_id(adapter->buttons,btn->id)) + { + if(tmpButtons) + iohidmanager_append_record(tmpButtons, btn); + else + tmpButtons = btn; + } + else + { + if(adapter->buttons) + iohidmanager_append_record(adapter->buttons, btn); + else + adapter->buttons = btn; + } + } } /* take care of buttons/axes with duplicate 'use' values */ - for(i=0; i<6; i++) + for (i = 0; i < 6; i++) { - if(found_axis[i] == false && tmpAxes) - { - apple_input_rec_t *next = tmpAxes->next; - tmpAxes->id = i; - tmpAxes->next = NULL; - iohidmanager_append_record(adapter->axes, tmpAxes); - tmpAxes = next; - } + if(found_axis[i] == false && tmpAxes) + { + apple_input_rec_t *next = tmpAxes->next; + tmpAxes->id = i; + tmpAxes->next = NULL; + iohidmanager_append_record(adapter->axes, tmpAxes); + tmpAxes = next; + } } tmp = adapter->buttons; - while(tmp->next) - tmp = tmp->next; + + if (tmp) + { + while(tmp->next) + tmp = tmp->next; + } while(tmpButtons) { apple_input_rec_t *next = tmpButtons->next; - tmpButtons->id = tmp->id + 1; + tmpButtons->id = tmp->id; tmpButtons->next = NULL; tmp->next = tmpButtons; @@ -693,33 +720,33 @@ error: apple_input_rec_t *tmp = NULL; while(adapter->hats != NULL) { - tmp = adapter->hats; - adapter->hats = adapter->hats->next; - free(tmp); + tmp = adapter->hats; + adapter->hats = adapter->hats->next; + free(tmp); } while(adapter->axes != NULL) { - tmp = adapter->axes; - adapter->axes = adapter->axes->next; - free(tmp); + tmp = adapter->axes; + adapter->axes = adapter->axes->next; + free(tmp); } while(adapter->buttons != NULL) { - tmp = adapter->buttons; - adapter->buttons = adapter->buttons->next; - free(tmp); + tmp = adapter->buttons; + adapter->buttons = adapter->buttons->next; + free(tmp); } while(tmpAxes != NULL) { - tmp = tmpAxes; - tmpAxes = tmpAxes->next; - free(tmp); + tmp = tmpAxes; + tmpAxes = tmpAxes->next; + free(tmp); } while(tmpButtons != NULL) { - tmp = tmpButtons; - tmpButtons = tmpButtons->next; - free(tmp); + tmp = tmpButtons; + tmpButtons = tmpButtons->next; + free(tmp); } free(adapter); }