Index: config/devd.c =================================================================== --- config/devd.c +++ config/devd.c @@ -53,8 +53,9 @@ #define DEVD_SOCK_PATH "/var/run/devd.pipe" -#define DEVD_EVENT_ADD '+' -#define DEVD_EVENT_REMOVE '-' +#define DEVD_EVENT_CDEV "cdev=" +#define DEVD_EVENT_ADD "type=CREATE" +#define DEVD_EVENT_REMOVE "type=DESTROY" #define RECONNECT_DELAY 5 * 1000 @@ -80,6 +81,7 @@ { "joy", ATTR_JOYSTICK, NULL }, { "atp", ATTR_TOUCHPAD, NULL }, { "uep", ATTR_TOUCHSCREEN, NULL }, + { "input/event", 0, "evdev" }, { NULL, -1, NULL }, }; @@ -134,6 +136,28 @@ return false; } +static bool +evdev_exists(const struct hw_type *device, int unit, + char *devname, size_t devname_len) +{ + char devpath[1024]; + struct stat st; + + if (device == NULL || device->driver == NULL) + return false; + + if (device->xdriver == 0 || 0 != strcmp(device->xdriver, "evdev")) + return false; + + /* Check if /dev/$driver$unit exists. */ + snprintf(devpath, sizeof(devpath), "/dev/%s%i", device->driver, unit); + if (0 != stat(devpath, &st)) + return false; + + snprintf(devname, devname_len, "%s%i", device->driver, unit); + return true; +} + static char * sysctl_get_str(const char *sysctlname) { @@ -447,6 +471,8 @@ wakeup_handler(void *data, int err, void *read_mask) { char *line = NULL; + char *type = NULL; + char *cdev = NULL; char *walk; if (err < 0) @@ -456,20 +482,27 @@ if (socket_getline(sock_devd, &line) < 0) return; - walk = strchr(line + 1, ' '); - if (walk != NULL) - walk[0] = '\0'; + cdev = strrchr(line + 1, ' '); + if (cdev == NULL) + goto unwind; + (cdev++)[0] = '\0'; - switch (*line) { - case DEVD_EVENT_ADD: - device_added(line + 1); - break; - case DEVD_EVENT_REMOVE: - device_removed(line + 1); - break; - default: - break; + const size_t len = strlen(DEVD_EVENT_CDEV); + if (0 != strncmp(cdev, DEVD_EVENT_CDEV, len)) + goto unwind; + cdev += len; + + type = strrchr(line + 1, ' '); + if (type == NULL) + goto unwind; + (type++)[0] = '\0'; + + if (0 == strcmp(type, DEVD_EVENT_ADD)) { + device_added(cdev); + } else if (0 == strcmp(type, DEVD_EVENT_REMOVE)) { + device_removed(cdev); } +unwind: free(line); } } @@ -500,6 +533,10 @@ if (sysctl_exists(&hw_types[i], j, devicename, sizeof(devicename)) != 0) device_added(devicename); + + if (evdev_exists(&hw_types[i], j, + devicename, sizeof(devicename)) != 0) + device_added(devicename); } if (devpath_exists(&hw_types[i], devicename, sizeof(devicename)) != 0)