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; }
gint host_createDescriptor(Host* host, DescriptorType type) { MAGIC_ASSERT(host); /* get a unique descriptor that can be "closed" later */ Descriptor* descriptor; switch(type) { case DT_EPOLL: { descriptor = (Descriptor*) epoll_new(_host_getNextDescriptorHandle(host)); break; } case DT_TCPSOCKET: { descriptor = (Descriptor*) tcp_new(_host_getNextDescriptorHandle(host), host->receiveBufferSize, host->sendBufferSize); break; } case DT_UDPSOCKET: { descriptor = (Descriptor*) udp_new(_host_getNextDescriptorHandle(host), host->receiveBufferSize, host->sendBufferSize); break; } case DT_SOCKETPAIR: { gint handle = _host_getNextDescriptorHandle(host); gint linkedHandle = _host_getNextDescriptorHandle(host); /* each channel is readable and writable */ descriptor = (Descriptor*) channel_new(handle, linkedHandle, CT_NONE); Descriptor* linked = (Descriptor*) channel_new(linkedHandle, handle, CT_NONE); _host_monitorDescriptor(host, linked); break; } case DT_PIPE: { gint handle = _host_getNextDescriptorHandle(host); gint linkedHandle = _host_getNextDescriptorHandle(host); /* one side is readonly, the other is writeonly */ descriptor = (Descriptor*) channel_new(handle, linkedHandle, CT_READONLY); Descriptor* linked = (Descriptor*) channel_new(linkedHandle, handle, CT_WRITEONLY); _host_monitorDescriptor(host, linked); break; } case DT_TIMER: { gint handle = _host_getNextDescriptorHandle(host); descriptor = (Descriptor*) timer_new(handle, CLOCK_MONOTONIC, TFD_NONBLOCK); break; } default: { warning("unknown descriptor type: %i", (gint)type); return EINVAL; } } return _host_monitorDescriptor(host, descriptor); }
static void *udev_input_init(const char *joypad_driver) { udev_input_t *udev = (udev_input_t*)calloc(1, sizeof(*udev)); if (!udev) return NULL; udev->udev = udev_new(); if (!udev->udev) { RARCH_ERR("Failed to create udev handle.\n"); goto error; } udev->monitor = udev_monitor_new_from_netlink(udev->udev, "udev"); if (udev->monitor) { udev_monitor_filter_add_match_subsystem_devtype(udev->monitor, "input", NULL); udev_monitor_enable_receiving(udev->monitor); } #ifdef HAVE_XKBCOMMON if (init_xkb(-1, 0) == -1) goto error; #endif if (!epoll_new(&udev->epfd)) { RARCH_ERR("Failed to create epoll FD.\n"); goto error; } if (!open_devices(udev, "ID_INPUT_KEYBOARD", udev_handle_keyboard)) { RARCH_ERR("Failed to open keyboard.\n"); goto error; } if (!open_devices(udev, "ID_INPUT_MOUSE", udev_handle_mouse)) { RARCH_ERR("Failed to open mouse.\n"); goto error; } if (!open_devices(udev, "ID_INPUT_TOUCHPAD", udev_handle_touchpad)) { RARCH_ERR("Failed to open touchpads.\n"); goto error; } /* If using KMS and we forgot this, * we could lock ourselves out completely. */ if (!udev->num_devices) RARCH_WARN("[udev]: Couldn't open any keyboard, mouse or touchpad. Are permissions set correctly for /dev/input/event*?\n"); udev->joypad = input_joypad_init_driver(joypad_driver, udev); input_keymaps_init_keyboard_lut(rarch_key_map_linux); linux_terminal_disable_input(); return udev; error: udev_input_free(udev); return NULL; }