void joystick_linux::open_joystick(const char *p_path) { int joy_num = get_free_joy_slot(); int fd = open(p_path, O_RDONLY | O_NONBLOCK); if (fd != -1 && joy_num != -1) { int rc = libevdev_new_from_fd(fd, &joysticks[joy_num].dev); if (rc < 0) { fprintf(stderr, "Failed to init libevdev (%s)\n", strerror(-rc)); return; } libevdev *dev = joysticks[joy_num].dev; //check if the device supports basic gamepad events, prevents certain keyboards from //being detected as joysticks if (libevdev_has_event_type(dev, EV_ABS) && libevdev_has_event_type(dev, EV_KEY) && (libevdev_has_event_code(dev, EV_KEY, BTN_A) || libevdev_has_event_code(dev, EV_KEY, BTN_THUMBL) || libevdev_has_event_code(dev, EV_KEY, BTN_TOP))) { char uid[128]; String name = libevdev_get_name(dev); uint16_t bus = __bswap_16(libevdev_get_id_bustype(dev)); uint16_t vendor = __bswap_16(libevdev_get_id_vendor(dev)); uint16_t product = __bswap_16(libevdev_get_id_product(dev)); uint16_t version = __bswap_16(libevdev_get_id_version(dev)); joysticks[joy_num].reset(); Joystick &joy = joysticks[joy_num]; joy.fd = fd; joy.devpath = String(p_path); setup_joystick_properties(joy_num); sprintf(uid, "%04x%04x", bus, 0); if (vendor && product && version) { sprintf(uid + String(uid).length(), "%04x%04x%04x%04x%04x%04x", vendor,0,product,0,version,0); input->joy_connection_changed(joy_num, true, name, uid); } else { String uidname = uid; int uidlen = MIN(name.length(), 11); for (int i=0; i<uidlen; i++) { uidname = uidname + _hex_str(name[i]); } uidname += "00"; input->joy_connection_changed(joy_num, true, name, uidname); } } else { //device is not a gamepad, clean up libevdev_free(dev); close(fd); } } }
bool JoystickOSX::configure_joystick(IOHIDDeviceRef p_device_ref, joystick *p_joy) { CFTypeRef refCF = NULL; p_joy->device_ref = p_device_ref; /* get device name */ String name; char c_name[256]; refCF = IOHIDDeviceGetProperty(p_device_ref, CFSTR(kIOHIDProductKey)); if (!refCF) { refCF = IOHIDDeviceGetProperty(p_device_ref, CFSTR(kIOHIDManufacturerKey)); } if ((!refCF) || (!CFStringGetCString((CFStringRef)refCF, c_name, sizeof(c_name), kCFStringEncodingUTF8))) { name = "Unidentified Joystick"; } name = c_name; int id = input->get_unused_joy_id(); ERR_FAIL_COND_V(id == -1, false); p_joy->id = id; int vendor = 0; refCF = IOHIDDeviceGetProperty(p_device_ref, CFSTR(kIOHIDVendorIDKey)); if (refCF) { CFNumberGetValue((CFNumberRef)refCF, kCFNumberSInt32Type, &vendor); } int product_id = 0; refCF = IOHIDDeviceGetProperty(p_device_ref, CFSTR(kIOHIDProductIDKey)); if (refCF) { CFNumberGetValue((CFNumberRef)refCF, kCFNumberSInt32Type, &product_id); } if (vendor && product_id) { char uid[128]; sprintf(uid, "%04x%08x%04x%08x", OSSwapHostToBigInt32(vendor), 0, OSSwapHostToBigInt32(product_id), 0); input->joy_connection_changed(id, true, name, uid); } else { //bluetooth device String guid = "05000000"; for (int i = 0; i < 12; i++) { if (i < name.size()) guid += _hex_str(name[i]); else guid += "00"; } input->joy_connection_changed(id, true, name, guid); } CFArrayRef array = NULL; array = IOHIDDeviceCopyMatchingElements(p_device_ref, NULL, kIOHIDOptionsTypeNone); if (array) { p_joy->add_hid_elements(array); CFRelease(array); } return true; }
void joystick_linux::open_joystick(const char *p_path) { int joy_num = get_free_joy_slot(); int fd = open(p_path, O_RDONLY | O_NONBLOCK); if (fd != -1 && joy_num != -1) { unsigned long evbit[NBITS(EV_MAX)] = { 0 }; unsigned long keybit[NBITS(KEY_MAX)] = { 0 }; unsigned long absbit[NBITS(ABS_MAX)] = { 0 }; if ((ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) || (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) || (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0)) { return; } //check if the device supports basic gamepad events, prevents certain keyboards from //being detected as joysticks if (!(test_bit(EV_KEY, evbit) && test_bit(EV_ABS, evbit) && ((test_bit(ABS_X, absbit) || test_bit(ABS_Y, absbit)) || (test_bit(BTN_A, keybit) || test_bit(BTN_THUMBL, keybit))))) { close(fd); return; } char uid[128]; char namebuf[128]; String name = ""; input_id inpid; if (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) >= 0) { name = namebuf; } if (ioctl(fd, EVIOCGID, &inpid) < 0) { close(fd); return; } joysticks[joy_num].reset(); Joystick &joy = joysticks[joy_num]; joy.fd = fd; joy.devpath = String(p_path); setup_joystick_properties(joy_num); sprintf(uid, "%04x%04x", __bswap_16(inpid.bustype), 0); if (inpid.vendor && inpid.product && inpid.version) { uint16_t vendor = __bswap_16(inpid.vendor); uint16_t product = __bswap_16(inpid.product); uint16_t version = __bswap_16(inpid.version); sprintf(uid + String(uid).length(), "%04x%04x%04x%04x%04x%04x", vendor,0,product,0,version,0); input->joy_connection_changed(joy_num, true, name, uid); } else { String uidname = uid; int uidlen = MIN(name.length(), 11); for (int i=0; i<uidlen; i++) { uidname = uidname + _hex_str(name[i]); } uidname += "00"; input->joy_connection_changed(joy_num, true, name, uidname); } } }