void SDL_SYS_JoystickDetect() { #if SDL_USE_LIBUDEV struct udev_device *dev = NULL; const char *devnode = NULL; const char *action = NULL; const char *val = NULL; while (HotplugUpdateAvailable()) { dev = UDEV_udev_monitor_receive_device(udev_mon); if (dev == NULL) { break; } val = UDEV_udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK"); if ((!val) || (SDL_strcmp(val, "1") != 0)) { continue; } action = UDEV_udev_device_get_action(dev); devnode = UDEV_udev_device_get_devnode(dev); if (SDL_strcmp(action, "add") == 0) { const int device_index = MaybeAddDevice(devnode); if (device_index != -1) { /* !!! FIXME: Move this to an SDL_PrivateJoyDeviceAdded() function? */ #if !SDL_EVENTS_DISABLED SDL_Event event; event.type = SDL_JOYDEVICEADDED; if (SDL_GetEventState(event.type) == SDL_ENABLE) { event.jdevice.which = device_index; if ( (SDL_EventOK == NULL) || (*SDL_EventOK) (SDL_EventOKParam, &event) ) { SDL_PushEvent(&event); } } #endif // !SDL_EVENTS_DISABLED } } else if (SDL_strcmp(action, "remove") == 0) { const int inst = MaybeRemoveDevice(devnode); if (inst != -1) { /* !!! FIXME: Move this to an SDL_PrivateJoyDeviceRemoved() function? */ #if !SDL_EVENTS_DISABLED SDL_Event event; event.type = SDL_JOYDEVICEREMOVED; if (SDL_GetEventState(event.type) == SDL_ENABLE) { event.jdevice.which = inst; if ( (SDL_EventOK == NULL) || (*SDL_EventOK) (SDL_EventOKParam, &event) ) { SDL_PushEvent(&event); } } #endif // !SDL_EVENTS_DISABLED } } UDEV_udev_device_unref(dev); } #endif }
int SDL_SYS_JoystickInit(void) { /* First see if the user specified one or more joysticks to use */ if (SDL_getenv("SDL_JOYSTICK_DEVICE") != NULL) { char *envcopy, *envpath, *delim; envcopy = SDL_strdup(SDL_getenv("SDL_JOYSTICK_DEVICE")); envpath = envcopy; while (envpath != NULL) { delim = SDL_strchr(envpath, ':'); if (delim != NULL) { *delim++ = '\0'; } MaybeAddDevice(envpath); envpath = delim; } SDL_free(envcopy); } SDL_InitSteamControllers(SteamControllerConnectedCallback, SteamControllerDisconnectedCallback); #if SDL_USE_LIBUDEV return JoystickInitWithUdev(); #else return JoystickInitWithoutUdev(); #endif }
int SDL_SYS_JoystickInit(void) { /* First see if the user specified one or more joysticks to use */ if (SDL_getenv("SDL_JOYSTICK_DEVICE") != NULL) { char *envcopy, *envpath, *delim; envcopy = SDL_strdup(SDL_getenv("SDL_JOYSTICK_DEVICE")); envpath = envcopy; while (envpath != NULL) { delim = SDL_strchr(envpath, ':'); if (delim != NULL) { *delim++ = '\0'; } MaybeAddDevice(envpath); envpath = delim; } SDL_free(envcopy); } #if SDL_USE_LIBUDEV if (LoadUDEVLibrary() == 0) { /* okay if this fails, FOR NOW. */ return JoystickInitWithUdev(); } #endif return JoystickInitWithoutUdev(); }
void joystick_udev_callback(SDL_UDEV_deviceevent udev_type, SDL_UDEV_deviceclass udev_class, const char *devpath) { int instance; if (devpath == NULL || udev_class != SDL_UDEV_DEVICE_JOYSTICK) { return; } switch( udev_type ) { case SDL_UDEV_DEVICEADDED: instance = MaybeAddDevice(devpath); if (instance != -1) { /* !!! FIXME: Move this to an SDL_PrivateJoyDeviceAdded() function? */ #if !SDL_EVENTS_DISABLED SDL_Event event; event.type = SDL_JOYDEVICEADDED; if (SDL_GetEventState(event.type) == SDL_ENABLE) { event.jdevice.which = instance; if ( (SDL_EventOK == NULL) || (*SDL_EventOK) (SDL_EventOKParam, &event) ) { SDL_PushEvent(&event); } } #endif /* !SDL_EVENTS_DISABLED */ } break; case SDL_UDEV_DEVICEREMOVED: instance = MaybeRemoveDevice(devpath); if (instance != -1) { /* !!! FIXME: Move this to an SDL_PrivateJoyDeviceRemoved() function? */ #if !SDL_EVENTS_DISABLED SDL_Event event; event.type = SDL_JOYDEVICEREMOVED; if (SDL_GetEventState(event.type) == SDL_ENABLE) { event.jdevice.which = instance; if ( (SDL_EventOK == NULL) || (*SDL_EventOK) (SDL_EventOKParam, &event) ) { SDL_PushEvent(&event); } } #endif /* !SDL_EVENTS_DISABLED */ } break; default: break; } }
static int JoystickInitWithoutUdev(void) { int i; char path[PATH_MAX]; /* !!! FIXME: only finds sticks if they're called /dev/input/event[0..31] */ /* !!! FIXME: we could at least readdir() through /dev/input...? */ /* !!! FIXME: (or delete this and rely on libudev?) */ for (i = 0; i < 32; i++) { SDL_snprintf(path, SDL_arraysize(path), "/dev/input/event%d", i); MaybeAddDevice(path); } return numjoysticks; }
static int JoystickInitWithUdev(void) { struct udev_enumerate *enumerate = NULL; struct udev_list_entry *devs = NULL; struct udev_list_entry *item = NULL; SDL_assert(udev == NULL); udev = UDEV_udev_new(); if (udev == NULL) { SDL_SetError("udev_new() failed"); return -1; } udev_mon = UDEV_udev_monitor_new_from_netlink(udev, "udev"); if (udev_mon != NULL) { /* okay if it's NULL, we just lose hotplugging. */ UDEV_udev_monitor_filter_add_match_subsystem_devtype(udev_mon, "input", NULL); UDEV_udev_monitor_enable_receiving(udev_mon); } enumerate = UDEV_udev_enumerate_new(udev); if (enumerate == NULL) { SDL_SetError("udev_enumerate_new() failed"); return -1; } UDEV_udev_enumerate_add_match_subsystem(enumerate, "input"); UDEV_udev_enumerate_add_match_property(enumerate, "ID_INPUT_JOYSTICK", "1"); UDEV_udev_enumerate_scan_devices(enumerate); devs = UDEV_udev_enumerate_get_list_entry(enumerate); for (item = devs; item; item = UDEV_udev_list_entry_get_next(item)) { const char *path = UDEV_udev_list_entry_get_name(item); struct udev_device *dev = UDEV_udev_device_new_from_syspath(udev, path); MaybeAddDevice(UDEV_udev_device_get_devnode(dev)); UDEV_udev_device_unref(dev); } UDEV_udev_enumerate_unref(enumerate); return numjoysticks; }
void joystick_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath) { if (devpath == NULL || !(udev_class & SDL_UDEV_DEVICE_JOYSTICK)) { return; } switch( udev_type ) { case SDL_UDEV_DEVICEADDED: MaybeAddDevice(devpath); break; case SDL_UDEV_DEVICEREMOVED: MaybeRemoveDevice(devpath); break; default: break; } }