static bool linuxraw_joypad_init(void *data) { unsigned i; settings_t *settings = config_get_ptr(); g_epoll = epoll_create(MAX_USERS + 1); if (g_epoll < 0) return false; (void)data; for (i = 0; i < MAX_USERS; i++) { char path[PATH_MAX_LENGTH] = {0}; autoconfig_params_t params = {{0}}; struct linuxraw_joypad *pad = (struct linuxraw_joypad*)&linuxraw_pads[i]; if (!pad) continue; params.idx = i; pad->fd = -1; pad->ident = settings->input.device_names[i]; snprintf(path, sizeof(path), "/dev/input/js%u", i); if (linuxraw_joypad_init_pad(path, pad)) { strlcpy(params.name, pad->ident, sizeof(params.name)); strlcpy(params.driver, "linuxraw", sizeof(params.driver)); /* TODO - implement VID/PID? */ input_config_autoconfigure_joypad(¶ms); linuxraw_poll_pad(pad); } else input_config_autoconfigure_joypad(¶ms); } g_notify = inotify_init(); if (g_notify >= 0) { struct epoll_event event; linuxraw_joypad_setup_notify(); event.events = EPOLLIN; event.data.ptr = NULL; epoll_ctl(g_epoll, EPOLL_CTL_ADD, g_notify, &event); } g_hotplug = true; return true; }
static bool linuxraw_joypad_init(void *data) { unsigned i; settings_t *settings = config_get_ptr(); if (!epoll_new(true)) return false; (void)data; for (i = 0; i < MAX_USERS; i++) { char path[PATH_MAX_LENGTH] = {0}; autoconfig_params_t params = {{0}}; struct linuxraw_joypad *pad = (struct linuxraw_joypad*)&linuxraw_pads[i]; if (!pad) continue; params.idx = i; pad->fd = -1; pad->ident = settings->input.device_names[i]; snprintf(path, sizeof(path), "/dev/input/js%u", i); if (linuxraw_joypad_init_pad(path, pad)) { strlcpy(params.name, pad->ident, sizeof(params.name)); strlcpy(params.driver, "linuxraw", sizeof(params.driver)); /* TODO - implement VID/PID? */ input_config_autoconfigure_joypad(¶ms); linuxraw_poll_pad(pad); } else input_config_autoconfigure_joypad(¶ms); } g_inotify = inotify_init(); if (g_inotify >= 0) { fcntl(g_inotify, F_SETFL, fcntl(g_inotify, F_GETFL) | O_NONBLOCK); inotify_add_watch(g_inotify, "/dev/input", IN_DELETE | IN_CREATE | IN_ATTRIB); epoll_add(g_inotify, NULL); } g_hotplug = true; return true; }
static bool linuxraw_joypad_init(void) { g_epoll = epoll_create(MAX_PLAYERS + 1); if (g_epoll < 0) return false; for (unsigned i = 0; i < MAX_PLAYERS; i++) { struct linuxraw_joypad *pad = &g_pads[i]; pad->fd = -1; pad->ident = g_settings.input.device_names[i]; char path[PATH_MAX]; snprintf(path, sizeof(path), "/dev/input/js%u", i); if (linuxraw_joypad_init_pad(path, pad)) { input_config_autoconfigure_joypad(i, pad->ident, "linuxraw"); poll_pad(pad); } else input_config_autoconfigure_joypad(i, NULL, NULL); } g_notify = inotify_init(); if (g_notify >= 0) { linuxraw_joypad_setup_notify(); struct epoll_event event; event.events = EPOLLIN; event.data.ptr = NULL; epoll_ctl(g_epoll, EPOLL_CTL_ADD, g_notify, &event); } g_hotplug = true; return true; }
static void handle_plugged_pad(void) { int i, rc; size_t event_size = sizeof(struct inotify_event) + NAME_MAX + 1; uint8_t *event_buf = (uint8_t*)calloc(1, event_size); if (!event_buf) return; while ((rc = read(g_notify, event_buf, event_size)) >= 0) { struct inotify_event *event = NULL; /* Can read multiple events in one read() call. */ for (i = 0; i < rc; i += event->len + sizeof(struct inotify_event)) { unsigned idx; autoconfig_params_t params = {{0}}; event = (struct inotify_event*)&event_buf[i]; if (strstr(event->name, "js") != event->name) continue; idx = strtoul(event->name + 2, NULL, 0); if (idx >= MAX_USERS) continue; if (event->mask & IN_DELETE) { if (linuxraw_pads[idx].fd >= 0) { if (g_hotplug) input_config_autoconfigure_disconnect(idx, linuxraw_pads[idx].ident); close(linuxraw_pads[idx].fd); linuxraw_pads[idx].buttons = 0; memset(linuxraw_pads[idx].axes, 0, sizeof(linuxraw_pads[idx].axes)); linuxraw_pads[idx].fd = -1; *linuxraw_pads[idx].ident = '\0'; /* TODO - implement VID/PID? */ params.idx = idx; input_config_autoconfigure_joypad(¶ms); } } /* Sometimes, device will be created before acess to it is established. */ else if (event->mask & (IN_CREATE | IN_ATTRIB)) { bool ret; char path[PATH_MAX_LENGTH] = {0}; snprintf(path, sizeof(path), "/dev/input/%s", event->name); ret = linuxraw_joypad_init_pad(path, &linuxraw_pads[idx]); if (*linuxraw_pads[idx].ident && ret) { params.idx = idx; strlcpy(params.name, linuxraw_pads[idx].ident, sizeof(params.name)); strlcpy(params.driver, linuxraw_joypad.ident, sizeof(params.driver)); /* TODO - implement VID/PID? */ input_config_autoconfigure_joypad(¶ms); } } } } free(event_buf); }
static void handle_plugged_pad(void) { size_t event_size = sizeof(struct inotify_event) + NAME_MAX + 1; uint8_t *event_buf = (uint8_t*)calloc(1, event_size); if (!event_buf) return; int rc; while ((rc = read(g_notify, event_buf, event_size)) >= 0) { struct inotify_event *event = NULL; // Can read multiple events in one read() call. for (int i = 0; i < rc; i += event->len + sizeof(struct inotify_event)) { event = (struct inotify_event*)&event_buf[i]; if (strstr(event->name, "js") != event->name) continue; unsigned index = strtoul(event->name + 2, NULL, 0); if (index >= MAX_PLAYERS) continue; if (event->mask & IN_DELETE) { if (g_pads[index].fd >= 0) { if (g_hotplug) { char msg[512]; snprintf(msg, sizeof(msg), "Joypad #%u (%s) disconnected.", index, g_pads[index].ident); #ifndef IS_JOYCONFIG msg_queue_push(g_extern.msg_queue, msg, 0, 60); #endif } RARCH_LOG("[Joypad]: Joypad %s disconnected.\n", g_pads[index].ident); close(g_pads[index].fd); memset(g_pads[index].buttons, 0, sizeof(g_pads[index].buttons)); memset(g_pads[index].axes, 0, sizeof(g_pads[index].axes)); g_pads[index].fd = -1; *g_pads[index].ident = '\0'; input_config_autoconfigure_joypad(index, NULL, NULL); } } // Sometimes, device will be created before acess to it is established. else if (event->mask & (IN_CREATE | IN_ATTRIB)) { char path[PATH_MAX]; snprintf(path, sizeof(path), "/dev/input/%s", event->name); bool ret = linuxraw_joypad_init_pad(path, &g_pads[index]); if (*g_pads[index].ident && ret) input_config_autoconfigure_joypad(index, g_pads[index].ident, "linuxraw"); } } } free(event_buf); }