diff options
author | kwm <kwm@058c260c-8361-11dd-a0ac-aa2bafec7d09> | 2014-09-08 20:36:23 +0800 |
---|---|---|
committer | kwm <kwm@058c260c-8361-11dd-a0ac-aa2bafec7d09> | 2014-09-08 20:36:23 +0800 |
commit | f8fc69c71420057000837794ff8826e76e22be58 (patch) | |
tree | 2a7c80c14ec1720eda6cb1306e9e6253943c6c6b | |
parent | 157016418c5c07527649f92baae696b784289f71 (diff) | |
download | xorg-devel-ports-f8fc69c71420057000837794ff8826e76e22be58.tar.gz xorg-devel-ports-f8fc69c71420057000837794ff8826e76e22be58.tar.zst xorg-devel-ports-f8fc69c71420057000837794ff8826e76e22be58.zip |
Update devd support [1]
Remove experimental comment in descr.
Submitted by: ak@ [1]
git-svn-id: https://trillian.chruetertee.ch/svn/ports/branches/experimental@1504 058c260c-8361-11dd-a0ac-aa2bafec7d09
-rw-r--r-- | x11-servers/xorg-server/Makefile | 2 | ||||
-rw-r--r-- | x11-servers/xorg-server/files/extra-devd | 465 |
2 files changed, 160 insertions, 307 deletions
diff --git a/x11-servers/xorg-server/Makefile b/x11-servers/xorg-server/Makefile index 1ac7fc1..22fec50 100644 --- a/x11-servers/xorg-server/Makefile +++ b/x11-servers/xorg-server/Makefile @@ -25,7 +25,7 @@ OPTIONS_RADIO_CONF= HAL DEVD AIGLX_DESC= Compile with Accelerated Indirect GLX support SUID_DESC= Install the Xorg server with setuid bit set HAL_DESC= Compile with HAL config support -DEVD_DESC= Use devd for autoconfiguration of input devices (experimental) +DEVD_DESC= Use devd for autoconfiguration of input devices OPTIONS_DEFAULT=AIGLX SUID DEVD OPTIONS_EXCLUDE_sparc64= HAL diff --git a/x11-servers/xorg-server/files/extra-devd b/x11-servers/xorg-server/files/extra-devd index 3492265..c3d54f2 100644 --- a/x11-servers/xorg-server/files/extra-devd +++ b/x11-servers/xorg-server/files/extra-devd @@ -1,8 +1,9 @@ ---- config/devd.c.orig 2014-08-26 14:10:31.612458843 +0200 -+++ config/devd.c 2014-08-26 15:46:46.147064193 +0200 -@@ -0,0 +1,534 @@ +Index: config/devd.c +@@ -0,0 +1,388 @@ +/* -+ * Copyright © 2012 Baptiste Daroussin ++ * Copyright (c) 2012 Baptiste Daroussin ++ * Copyright (c) 2013, 2014 Alex Kozlov ++ * Copyright (c) 2014 Robert Millan + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), @@ -32,14 +33,15 @@ + +#include <sys/types.h> +#include <sys/socket.h> -+#include <sys/stat.h> +#include <sys/sysctl.h> +#include <sys/un.h> + +#include <ctype.h> ++#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> ++#include <stdarg.h> +#include <stdbool.h> +#include <unistd.h> + @@ -56,251 +58,144 @@ + +static int sock_devd = -1; + -+#if XORG_VERSION_CURRENT < 10800000 -+enum { -+ ATTR_KEYBOARD, -+ ATTR_POINTER, -+ ATTR_JOYSTICK, -+ ATTR_TOUCHPAD, -+ ATTR_TOUCHSCREEN, -+}; -+#endif -+ +struct hw_type { -+ const char *driver; -+ int flag; -+ const char *xdriver; ++ const char *driver; ++ int flag; ++ const char *xdriver; +}; + +static struct hw_type hw_types[] = { -+ { "ukbd", ATTR_KEYBOARD, "kbd" }, -+ { "atkbd", ATTR_KEYBOARD, "kbd" }, -+ { "ums", ATTR_POINTER, "mouse" }, -+ { "psm", ATTR_POINTER, "mouse" }, -+ { "uhid", ATTR_POINTER, "mouse" }, -+ { "sysmouse", ATTR_POINTER, "mouse" }, -+ { "joy", ATTR_JOYSTICK, NULL }, -+ { "atp", ATTR_TOUCHPAD, NULL }, -+ { "uep", ATTR_TOUCHSCREEN, NULL }, -+ { NULL, -1, NULL }, ++ { "ukbd", ATTR_KEYBOARD, "kbd" }, ++ { "atkbd", ATTR_KEYBOARD, "kbd" }, ++ { "ums", ATTR_POINTER, "mouse" }, ++ { "psm", ATTR_POINTER, "mouse" }, ++ { "uhid", ATTR_POINTER, "mouse" }, ++ { "joy", ATTR_JOYSTICK, NULL }, ++ { "atp", ATTR_TOUCHPAD, NULL }, ++ { "uep", ATTR_TOUCHSCREEN, NULL }, ++ { NULL, -1, NULL }, +}; + -+#if XORG_VERSION_CURRENT < 10800000 -+static void -+add_option(InputOption **options, const char *key, const char *value) -+{ -+ if (!value || *value == '\0') -+ return; -+ -+ for (; *options; options = &(*options)->next) -+ ; -+ *options = calloc(sizeof(**options), 1); -+ if (!*options) /* Yeesh. */ -+ return; -+ (*options)->key = xstrdup(key); -+ (*options)->value = xstrdup(value); -+ (*options)->next = NULL; -+} -+ -+static void -+remove_device(DeviceIntPtr dev) -+{ -+ /* this only gets called for devices that have already been added */ -+ LogMessage(X_INFO, "config/devd: removing device %s\n", dev->name); -+ -+ /* Call PIE here so we don't try to dereference a device that's -+ * already been removed. */ -+ OsBlockSignals(); -+ ProcessInputEvents(); -+ DeleteInputDeviceRequest(dev); -+ OsReleaseSignals(); -+} -+ +static bool -+device_is_duplicate(char *config_info) ++sysctl_exists(const char *format, ...) +{ -+ DeviceIntPtr dev; ++ va_list args; ++ char *name = NULL; ++ size_t len; ++ int ret; + -+ for (dev = inputInfo.devices; dev; dev = dev->next) -+ if (dev->config_info && (strcmp(dev->config_info, config_info) == 0)) -+ return true; -+ -+ for (dev = inputInfo.off_devices; dev; dev = dev->next) -+ if (dev->config_info && (strcmp(dev->config_info, config_info) == 0)) -+ return true; -+ -+ return false; -+} -+ -+#endif -+ -+static bool -+sysctl_exists(const struct hw_type *device, int unit, -+ char *devname, size_t devname_len) -+{ -+ char *sysctlname; -+ size_t len; -+ int ret; ++ if (format == NULL) ++ return false; + -+ if (device == NULL || device->driver == NULL) -+ return false; ++ va_start(args, format); ++ vasprintf(&name, format, args); ++ va_end(args); + -+ /* Check if a sysctl exists. */ -+ asprintf(&sysctlname, "dev.%s.%i.%%desc", device->driver, unit); -+ if (sysctlname == NULL) -+ return (0); ++ ret = sysctlbyname(name, NULL, &len, NULL, 0); + -+ ret = sysctlbyname(sysctlname, NULL, &len, NULL, 0); -+ free(sysctlname); ++ if (ret == -1) ++ len = 0; + -+ if (ret == 0 && len > 0) { -+ snprintf(devname, devname_len, "%s%i", device->driver, unit); -+ return (1); -+ } -+ -+ return (0); -+} -+ -+static bool -+devpath_exists(const struct hw_type *device, -+ char *devname, size_t devname_len) -+{ -+ char *devpath; -+ struct stat st; -+ int ret; -+ -+ if (device == NULL || device->driver == NULL) -+ return false; -+ -+ /* Check if /dev/$driver exists. */ -+ asprintf(&devpath, "/dev/%s", device->driver); -+ if (devpath == NULL) -+ return (0); -+ -+ ret = stat(devpath, &st); -+ free(devpath); -+ -+ if (ret == 0) { -+ snprintf(devname, devname_len, "%s ", device->driver); -+ return (1); -+ } -+ -+ return (0); ++ free(name); ++ return (len > 0); +} + +static char * +sysctl_get_str(const char *format, ...) +{ -+ va_list args; -+ char *name = NULL; -+ char *dest = NULL; -+ size_t len; -+ -+ if (format == NULL) -+ return NULL; -+ -+ va_start(args, format); -+ vasprintf(&name, format, args); -+ va_end(args); -+ -+ if (sysctlbyname(name, NULL, &len, NULL, 0) == 0) { -+ dest = malloc(len + 1); -+ if (sysctlbyname(name, dest, &len, NULL, 0) == 0) -+ dest[len] = '\0'; -+ else { -+ free(dest); -+ dest = NULL; -+ } -+ } ++ va_list args; ++ char *name = NULL; ++ char *dest = NULL; ++ size_t len; ++ ++ if (format == NULL) ++ return NULL; ++ ++ va_start(args, format); ++ vasprintf(&name, format, args); ++ va_end(args); ++ ++ if (sysctlbyname(name, NULL, &len, NULL, 0) == 0) { ++ dest = malloc(len + 1); ++ if (!dest) ++ goto unwind; ++ if (sysctlbyname(name, dest, &len, NULL, 0) == 0) ++ dest[len] = '\0'; ++ else { ++ free(dest); ++ dest = NULL; ++ } ++ } + -+ free(name); -+ return dest; ++ unwind: ++ free(name); ++ return dest; +} + +static void -+device_added(char *line) ++device_added(char *devname) +{ -+ char *walk; -+ char *path; ++ char path[PATH_MAX]; + char *vendor; + char *product = NULL; + char *config_info = NULL; ++ char *walk; + InputOption *options = NULL; -+#if XORG_VERSION_CURRENT > 10800000 -+ InputAttributes attrs = {}; -+#else -+ InputOption *tmpo; -+#endif ++ InputAttributes attrs = { }; + DeviceIntPtr dev = NULL; + int i, rc; + int fd; + -+ walk = strchr(line, ' '); -+ if (walk != NULL) -+ walk[0] = '\0'; -+ + for (i = 0; hw_types[i].driver != NULL; i++) { -+ size_t len; -+ -+ len = strlen(hw_types[i].driver); -+ if (strcmp(line, hw_types[i].driver) == 0 || -+ (strncmp(line, hw_types[i].driver, len) == 0 && -+ isnumber(*(line + len)))) { -+#if XORG_VERSION_CURRENT > 10800000 ++ if (strncmp(devname, hw_types[i].driver, ++ strlen(hw_types[i].driver)) == 0 && ++ isdigit(*(devname + strlen(hw_types[i].driver)))) { + attrs.flags |= hw_types[i].flag; -+#endif + break; + } + } + if (hw_types[i].driver == NULL) { -+ LogMessageVerb(X_INFO, 10, "config/devd: ignoring device %s\n", line); ++ LogMessageVerb(X_INFO, 10, "config/devd: ignoring device %s\n", ++ devname); + return; + } + if (hw_types[i].xdriver == NULL) { -+ LogMessageVerb(X_INFO, 10, "config/devd: ignoring device %s\n", line); ++ LogMessageVerb(X_INFO, 10, "config/devd: ignoring device %s\n", ++ devname); + return; + } -+ if (asprintf(&path, "/dev/%s", line) == -1) -+ return; -+ -+#if XORG_VERSION_CURRENT < 10800000 -+ options = calloc(sizeof(*options), 1); -+ if (!options) -+ return; ++ snprintf(path, sizeof(path), "/dev/%s", devname); + -+ add_option(&options, "_source", "server/devd"); -+#else -+ options = input_option_new(NULL, "_source", "server/devd"); ++ options = input_option_new(NULL, "_source", "server/devd"); + if (!options) + return; -+#endif + -+ vendor = sysctl_get_str("dev.%s.%s.%%desc", hw_types[i].driver, line + strlen(hw_types[i].driver)); ++ vendor = ++ sysctl_get_str("dev.%s.%s.%%desc", hw_types[i].driver, ++ devname + strlen(hw_types[i].driver)); + if (vendor == NULL) { -+#if XORG_VERSION_CURRENT > 10800000 -+ options = input_option_new(options, "name", line); + attrs.vendor = strdup("(unnamed)"); -+#else -+ add_option(&options, "name", line); -+#endif -+ } else { -+ if ((product = strchr(vendor, ' ')) != NULL) { -+ product[0] = '\0'; -+ product++; ++ attrs.product = strdup("(unnamed)"); ++ } ++ else { ++ if ((walk = strchr(vendor, ' ')) != NULL) { ++ walk[0] = '\0'; ++ walk++; ++ product = walk; ++ if ((walk = strchr(product, ',')) != NULL) ++ walk[0] = '\0'; + } -+#if XORG_VERSION_CURRENT > 10800000 ++ + attrs.vendor = strdup(vendor); -+#endif -+ if (product != NULL && (walk = strchr(product, ',')) != NULL) -+ walk[0] = '\0'; -+#if XORG_VERSION_CURRENT > 10800000 -+ attrs.product = strdup(product != NULL ? product : "(unnamed)"); -+ options = input_option_new(options, "name", product != NULL ? product : "(unnamed)"); -+#else -+ add_option(&options, "name", product != NULL ? product : "(unnamed)"); -+#endif ++ if (product) ++ attrs.product = strdup(product); ++ else ++ attrs.product = strdup("(unnamed)"); ++ ++ options = input_option_new(options, "name", xstrdup(attrs.product)); ++ ++ free(vendor); + } -+#if XORG_VERSION_CURRENT > 10800000 + attrs.usb_id = NULL; + attrs.device = strdup(path); + options = input_option_new(options, "driver", hw_types[i].xdriver); @@ -312,98 +207,52 @@ + fd = open(path, O_RDONLY | O_NONBLOCK | O_EXCL); + if (fd > 0) { + close(fd); -+ options = input_option_new(options, "device", path); ++ options = input_option_new(options, "device", xstrdup(path)); + } -+ } else { -+ options = input_option_new(options, "device", path); + } -+#else -+ add_option(&options, "path", path); -+ add_option(&options, "device", path); -+ add_option(&options, "driver", hw_types[i].xdriver); -+#endif ++ else { ++ options = input_option_new(options, "device", xstrdup(path)); ++ } + -+ if (asprintf(&config_info, "devd:%s", line) == -1) { ++ if (asprintf(&config_info, "devd:%s", devname) == -1) { + config_info = NULL; + goto unwind; + } + + if (device_is_duplicate(config_info)) { + LogMessage(X_WARNING, "config/devd: device %s already added. " -+ "Ignoring.\n", product != NULL ? product : "(unnamed)"); ++ "Ignoring.\n", attrs.product); + goto unwind; + } + -+#if XORG_VERSION_CURRENT < 10800000 -+ add_option(&options, "config_info", config_info); -+#else + options = input_option_new(options, "config_info", config_info); -+#endif + LogMessage(X_INFO, "config/devd: adding input device %s (%s)\n", -+ product != NULL ? product : "(unnamed)", path); ++ attrs.product, path); + -+#if XORG_VERSION_CURRENT > 10800000 + rc = NewInputDeviceRequest(options, &attrs, &dev); -+#else -+ rc = NewInputDeviceRequest(options, &dev); -+#endif + + if (rc != Success) + goto unwind; + + unwind: + free(config_info); -+#if XORG_VERSION_CURRENT < 10800000 -+ while ((tmpo = options)) { -+ options = tmpo->next; -+ free(tmpo->key); /* NULL if dev != NULL */ -+ free(tmpo->value); /* NULL if dev != NULL */ -+ free(tmpo); -+ } -+#else + input_option_free_list(&options); -+#endif + -+#if XORG_VERSION_CURRENT > 10800000 + free(attrs.usb_id); + free(attrs.product); + free(attrs.device); + free(attrs.vendor); -+#endif -+ -+ return; +} + +static void -+device_removed(char *line) ++device_removed(char *devname) +{ -+ char *walk; + char *value; -+#if XORG_VERSION_CURRENT < 10800000 -+ DeviceIntPtr dev, next; -+#endif + -+ walk = strchr(line, ' '); -+ if (walk != NULL) -+ walk[0] = '\0'; -+ -+ if (asprintf(&value, "devd:%s", line) == -1) ++ if (asprintf(&value, "devd:%s", devname) == -1) + return; + -+#if XORG_VERSION_CURRENT > 10800000 + remove_devices("devd", value); -+#else -+ for (dev = inputInfo.devices; dev; dev = next) { -+ next = dev->next; -+ if (dev->config_info && strcmp(dev->config_info, value) == 0) -+ remove_device(dev); -+ } -+ for (dev = inputInfo.off_devices; dev; dev = next) { -+ next = dev->next; -+ if (dev->config_info && strcmp(dev->config_info, value) == 0) -+ remove_device(dev); -+ } -+#endif + + free(value); +} @@ -411,60 +260,72 @@ +static ssize_t +socket_getline(int fd, char **out) +{ -+ char *buf; -+ ssize_t ret, cap, sz = 0; -+ char c; -+ -+ cap = 1024; -+ buf = malloc(cap * sizeof(char)); -+ if (!buf) -+ return -1; -+ -+ for (;;) { -+ ret = read(sock_devd, &c, 1); -+ if (ret < 1) { -+ free(buf); -+ return -1; -+ } -+ -+ if (c == '\n') -+ break; -+ -+ if (sz + 1 >= cap) { -+ cap *= 2; -+ buf = realloc(buf, cap *sizeof(char)); -+ } -+ buf[sz] = c; -+ sz++; -+ } -+ -+ buf[sz] = '\0'; -+ if (sz > 0) -+ *out = buf; -+ else -+ free(buf); -+ -+ return sz; /* number of bytes in the line, not counting the line break*/ ++ char *buf, *newbuf; ++ ssize_t ret, cap, sz = 0; ++ char c; ++ ++ cap = 1024; ++ buf = malloc(cap * sizeof(char)); ++ if (!buf) ++ return -1; ++ ++ for (;;) { ++ ret = read(sock_devd, &c, 1); ++ if (ret < 1) { ++ if (errno == EINTR) ++ continue; ++ free(buf); ++ return -1; ++ } ++ ++ if (c == '\n') ++ break; ++ ++ if (sz + 1 >= cap) { ++ cap *= 2; ++ newbuf = realloc(buf, cap * sizeof(char)); ++ if (!newbuf) { ++ free(buf); ++ return -1; ++ } ++ buf = newbuf; ++ } ++ buf[sz] = c; ++ sz++; ++ } ++ ++ buf[sz] = '\0'; ++ if (sz >= 0) ++ *out = buf; ++ else ++ free(buf); ++ ++ return sz; /* number of bytes in the line, not counting the line break */ +} + +static void +wakeup_handler(void *data, int err, void *read_mask) +{ + char *line = NULL; ++ char *walk; + + if (err < 0) + return; + -+ if (FD_ISSET(sock_devd, (fd_set *)read_mask)) { ++ if (FD_ISSET(sock_devd, (fd_set *) read_mask)) { + if (socket_getline(sock_devd, &line) < 0) + return; + -+ switch(*line) { ++ walk = strchr(line + 1, ' '); ++ if (walk != NULL) ++ walk[0] = '\0'; ++ ++ switch (*line) { + case DEVD_EVENT_ADD: -+ device_added(++line); ++ device_added(line + 1); + break; + case DEVD_EVENT_REMOVE: -+ device_removed(++line); ++ device_removed(line + 1); + break; + default: + break; @@ -483,27 +344,19 @@ +{ + struct sockaddr_un devd; + char devicename[1024]; -+ int i, j, ret; ++ int i, j; + + /* first scan the sysctl to determine the hardware if needed */ + + for (i = 0; hw_types[i].driver != NULL; i++) { -+ for (j = 0; j < 16; j++) { -+ ret = sysctl_exists(&hw_types[i], j, -+ devicename, sizeof(devicename)); -+ if (!ret) -+ continue; -+ ++ for (j = 0; sysctl_exists("dev.%s.%i.%%desc", hw_types[i].driver, j); ++ j++) { ++ snprintf(devicename, sizeof(devicename), "%s%i", hw_types[i].driver, ++ j); + device_added(devicename); + } + -+ ret = devpath_exists(&hw_types[i], devicename, sizeof(devicename)); -+ if (!ret) -+ continue; -+ -+ device_added(devicename); + } -+ + sock_devd = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock_devd < 0) { + ErrorF("config/devd: Fail opening stream socket"); @@ -513,7 +366,7 @@ + devd.sun_family = AF_UNIX; + strlcpy(devd.sun_path, DEVD_SOCK_PATH, sizeof(devd.sun_path)); + -+ if (connect(sock_devd, (struct sockaddr *) &devd, sizeof(struct sockaddr_un)) < 0) { ++ if (connect(sock_devd, (struct sockaddr *) &devd, sizeof(devd)) < 0) { + close(sock_devd); + ErrorF("config/devd: Fail to connect to devd"); + return 0; |