FreeBSD Bugzilla – Attachment 151549 Details for
Bug 196678
x11-servers/xorg-server: Update to 1.20.7 + make config/devd recognize /dev/input/eventX from multimedia/webcamd
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
updates to devd backend in diff form.
patch-devd.txt (text/plain), 15.39 KB, created by
Alex Kozlov
on 2015-01-13 11:38:35 UTC
(
hide
)
Description:
updates to devd backend in diff form.
Filename:
MIME Type:
Creator:
Alex Kozlov
Created:
2015-01-13 11:38:35 UTC
Size:
15.39 KB
patch
obsolete
>Index: x11-servers/xorg-server/files/patch-config_devd.c >@@ -1,6 +1,6 @@ >---- config/devd.c.orig 2014-12-16 23:03:10 UTC >-+++ config/devd.c >-@@ -0,0 +1,530 @@ >+--- config/devd.c 2015-01-12 10:47:19.000000000 +0100 >++++ config/devd.c 2015-01-13 12:02:22.000000000 +0100 >+@@ -0,0 +1,574 @@ > +/* > + * Copyright (c) 2012 Baptiste Daroussin > + * Copyright (c) 2013, 2014 Alex Kozlov >@@ -41,12 +41,14 @@ > +#include <sys/un.h> > + > +#include <ctype.h> >++#include <dirent.h> > +#include <errno.h> > +#include <fcntl.h> > +#include <stdlib.h> > +#include <stdio.h> > +#include <stdbool.h> > +#include <unistd.h> >++#include <paths.h> > + > +#include "input.h" > +#include "inputstr.h" >@@ -56,13 +58,9 @@ > + > +#define DEVD_SOCK_PATH "/var/run/devd.pipe" > + >-+#define DEVD_EVENT_ADD '+' >-+#define DEVD_EVENT_REMOVE '-' >-+ >-+#define RECONNECT_DELAY 5 * 1000 >++#define RECONNECT_DELAY (5 * 1000) > + > +static int sock_devd; >-+static bool is_console_kbd = false; > +static bool is_kbdmux = false; > +OsTimerPtr rtimer; > + >@@ -70,70 +68,51 @@ > + const char *driver; > + int flag; > + const char *xdriver; >++ const char *sysctldesc; > +}; > + >-+static struct hw_type hw_types[] = { >-+ { "ukbd", ATTR_KEYBOARD, "kbd" }, >-+ { "atkbd", ATTR_KEYBOARD, "kbd" }, >-+ { "kbdmux", ATTR_KEYBOARD, "kbd" }, >-+ { "sysmouse", ATTR_POINTER, "mouse" }, >-+ { "ums", ATTR_POINTER, "mouse" }, >-+ { "psm", ATTR_POINTER, "mouse" }, >-+ { "joy", ATTR_JOYSTICK, NULL }, >-+ { "atp", ATTR_TOUCHPAD, NULL }, >-+ { "uep", ATTR_TOUCHSCREEN, NULL }, >-+ { NULL, -1, NULL }, >++static const struct hw_type hw_types0[] = { >++ { _PATH_DEV "sysmouse", ATTR_POINTER, "mouse", NULL }, >++ { NULL, 0, NULL, NULL }, > +}; > + >-+static bool >-+sysctl_exists(const struct hw_type *device, int unit, >-+ char *devname, size_t devname_len) >-+{ >-+ char sysctlname[PATH_MAX]; >-+ size_t len; >-+ int ret; >-+ >-+ if (device == NULL || device->driver == NULL) >-+ return false; >-+ >-+ /* Check if a sysctl exists. */ >-+ snprintf(sysctlname, sizeof(sysctlname), "dev.%s.%i.%%desc", >-+ device->driver, unit); >-+ ret = sysctlbyname(sysctlname, NULL, &len, NULL, 0); >++static const struct hw_type hw_types1[] = { >++ { _PATH_DEV "ukbd%d", ATTR_KEYBOARD, "kbd", "dev.ukbd.%d.%%desc" }, >++ { _PATH_DEV "atkbd%d", ATTR_KEYBOARD, "kbd", "dev.atkbd.%d.%%desc" }, >++ { _PATH_DEV "kbdmux%d", ATTR_KEYBOARD, "kbd", NULL }, >++ { _PATH_DEV "ums%d", ATTR_POINTER, "mouse", "dev.ums.%d.%%desc" }, >++ { _PATH_DEV "psm%d", ATTR_POINTER, "mouse", "dev.psm.%d.%%desc" }, >++ { _PATH_DEV "joy%d", ATTR_JOYSTICK, "mouse", "dev.joy.%d.%%desc" }, >++ { _PATH_DEV "atp%d", ATTR_TOUCHPAD, "mouse", "dev.atp.%d.%%desc" }, >++ { _PATH_DEV "wsp%d", ATTR_TOUCHPAD, "mouse", "dev.wsp.%d.%%desc" }, >++ { _PATH_DEV "uep%d", ATTR_TOUCHSCREEN, "mouse", "dev.uep.%d.%%desc" }, >++ { _PATH_DEV "input/event%d", ATTR_TOUCHPAD, "evdev", NULL}, >++ { NULL, 0, NULL, NULL }, >++}; > + >-+ if (ret == 0 && len > 0) { >-+ snprintf(devname, devname_len, "%s%i", device->driver, unit); >-+ return true; >++static void >++get_usb_id(char **pptr, int fd) >++{ >++ unsigned short vendor; >++ unsigned short product; >++ unsigned int speed; >++#define WEBCAMD_IOCTL_GET_USB_VENDOR_ID _IOR('q', 250, unsigned short) >++#define WEBCAMD_IOCTL_GET_USB_PRODUCT_ID _IOR('q', 251, unsigned short) >++#define WEBCAMD_IOCTL_GET_USB_SPEED _IOR('q', 252, unsigned int) >++ if (ioctl(fd, WEBCAMD_IOCTL_GET_USB_VENDOR_ID, &vendor) == 0 && >++ ioctl(fd, WEBCAMD_IOCTL_GET_USB_PRODUCT_ID, &product) == 0 && >++ ioctl(fd, WEBCAMD_IOCTL_GET_USB_SPEED, &speed) == 0) { >++ if (asprintf(pptr, "%04x:%04x", vendor, product) == -1) >++ *pptr = NULL; > + } >-+ >-+ return false; > +} > + >-+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 false; >-+ >-+ ret = stat(devpath, &st); >-+ free(devpath); >-+ >-+ if (ret == 0) { >-+ strncpy(devname, device->driver, devname_len); >-+ return true; >-+ } >-+ >-+ return false; >++static const char * >++skip_path_dev(const char *ptr) >++{ >++ if (strstr(ptr, _PATH_DEV) == ptr) >++ ptr += strlen(_PATH_DEV); >++ return (ptr); > +} > + > +static char * >@@ -161,58 +140,66 @@ > +} > + > +static void >-+device_added(const char *devname) >++device_added(const char *devicename, bool allow_no_device) > +{ >-+ char path[PATH_MAX]; >-+ char sysctlname[PATH_MAX]; >-+ char *vendor; >-+ char *product = NULL; >-+ char *config_info = NULL; >-+ char *walk; >-+ InputOption *options = NULL; > + InputAttributes attrs = { }; >++ InputOption *options = NULL; >++ char *config_info = NULL; > + DeviceIntPtr dev = NULL; >++ struct hw_type hw_type; >++ char *product = NULL; >++ char sysctlname[64]; >++ char *vendor = NULL; >++ int unit = 0; >++ int fd = -1; >++ char *walk; > + int i; >-+ int fd; >-+ >-+ for (i = 0; hw_types[i].driver != NULL; i++) { >-+ size_t len; > + >-+ len = strlen(hw_types[i].driver); >-+ if (strcmp(devname, hw_types[i].driver) == 0 || >-+ (strncmp(devname, hw_types[i].driver, len) == 0 && >-+ isnumber(*(devname + len)))) { >-+ attrs.flags |= hw_types[i].flag; >-+ break; >++ for (i = 0; hw_types0[i].driver != NULL; i++) { >++ if (strcmp(devicename, hw_types0[i].driver) == 0) { >++ hw_type = hw_types0[i]; >++ goto found; > + } > + } >-+ >-+ if (hw_types[i].driver == NULL || hw_types[i].xdriver == NULL) { >-+ LogMessage(X_INFO, "config/devd: ignoring device %s\n", >-+ devname); >-+ return; >++ for (i = 0; hw_types1[i].driver != NULL; i++) { >++ if (sscanf(devicename, hw_types1[i].driver, &unit) == 1) { >++ hw_type = hw_types1[i]; >++ goto found; >++ } > + } >++ goto ignore; > + >-+ /* Skip keyboard devices if kbdmux is enabled */ >-+ if (is_kbdmux && is_console_kbd && hw_types[i].flag & ATTR_KEYBOARD) { >-+ LogMessage(X_INFO, "config/devd: kbdmux is enabled, ignoring device %s\n", >-+ devname); >-+ return; >++found: >++ if (hw_type.xdriver == NULL) >++ goto ignore; >++ >++ if (strcmp(hw_type.xdriver, "kbd") == 0) { >++ bool match = (strstr(hw_type.driver, >++ _PATH_DEV "kbdmux") == hw_type.driver); >++ >++ if (is_kbdmux) { >++ if (!match) >++ goto ignore; >++ } else { >++ if (match) >++ goto ignore; >++ } > + } > + >-+ snprintf(path, sizeof(path), "/dev/%s", devname); >-+ > + options = input_option_new(NULL, "_source", "server/devd"); >-+ if (!options) >-+ return; >++ if (options == NULL) >++ goto error; > + >-+ snprintf(sysctlname, sizeof(sysctlname), "dev.%s.%s.%%desc", >-+ hw_types[i].driver, devname + strlen(hw_types[i].driver)); >-+ vendor = sysctl_get_str(sysctlname); >-+ if (vendor == NULL) { >-+ options = input_option_new(options, "name", devname); >++ if (hw_type.sysctldesc != NULL) { >++ snprintf(sysctlname, sizeof(sysctlname), >++ hw_type.sysctldesc, unit); >++ vendor = sysctl_get_str(sysctlname); > + } >-+ else { >++ >++ if (vendor == NULL) { >++ options = input_option_new(options, "name", >++ skip_path_dev(devicename)); >++ } else { > + if ((walk = strchr(vendor, ' ')) != NULL) { > + walk[0] = '\0'; > + walk++; >@@ -222,93 +209,157 @@ > + } > + > + attrs.vendor = strdup(vendor); >-+ if (product) { >++ if (product != NULL) { > + attrs.product = strdup(product); >-+ options = input_option_new(options, "name", product); >++ options = input_option_new(options, >++ "name", product); >++ } else { >++ options = input_option_new(options, >++ "name", "Unknown"); > + } >-+ else >-+ options = input_option_new(options, "name", "(unnamed)"); >-+ >-+ free(vendor); > + } >++ attrs.device = strdup(devicename); > + >-+ /* XXX implement usb_id */ >-+ attrs.usb_id = NULL; >-+ attrs.device = strdup(path); >-+ options = input_option_new(options, "driver", hw_types[i].xdriver); >-+ >-+ fd = open(path, O_RDONLY); >-+ if (fd > 0) { >++ fd = open(devicename, O_RDONLY); >++ if (fd > -1) { >++ get_usb_id(&attrs.usb_id, fd); > + close(fd); >-+ options = input_option_new(options, "device", path); >-+ } >-+ else { >-+ if (attrs.flags & ~ATTR_KEYBOARD) { >-+ LogMessage(X_INFO, "config/devd: device %s already opened\n", >-+ path); >-+ >-+ /* >-+ * Fail if cannot open device, it breaks AllowMouseOpenFail, >-+ * but it should not matter when config/devd enabled >-+ */ >-+ goto unwind; >-+ } >-+ >-+ if (is_console_kbd) { >-+ /* >-+ * There can be only one keyboard attached to console and >-+ * it is already added. >-+ */ >-+ LogMessage(X_WARNING, "config/devd: console keyboard is " >-+ "already added, ignoring %s (%s)\n", >-+ attrs.product, path); >-+ goto unwind; >-+ } >-+ else >-+ /* >-+ * Don't pass "device" option if the keyboard is already >-+ * attached to the console (ie. open() fails). >-+ * This would activate a special logic in xf86-input-keyboard. >-+ * Prevent any other attached to console keyboards being >-+ * processed. There can be only one such device. >-+ */ >-+ is_console_kbd = true; >-+ } >++ options = input_option_new(options, "device", devicename); >++ if (options == NULL) >++ goto error; >++ } else if (allow_no_device) { >++ /* >++ * Don't pass "device" option if the keyboard is >++ * already attached to the console (ie. open() fails). >++ * This would activate a special logic in >++ * xf86-input-keyboard. Prevent any other attached to >++ * console keyboards being processed. There can be >++ * only one such device. >++ */ >++ } else { >++ goto ignore; >++ } >++ >++ options = input_option_new(options, "driver", hw_type.xdriver); >++ if (options == NULL) >++ goto error; > + >-+ if (asprintf(&config_info, "devd:%s", devname) == -1) { >++ if (asprintf(&config_info, "devd:%s", >++ skip_path_dev(devicename)) == -1) { > + config_info = NULL; >-+ goto unwind; >++ goto error; > + } > + >-+ if (device_is_duplicate(config_info)) { >-+ LogMessage(X_WARNING, "config/devd: device %s (%s) already added. " >-+ "ignoring\n", attrs.product, path); >-+ goto unwind; >-+ } >++ if (device_is_duplicate(config_info)) >++ goto duplicate; > + > + options = input_option_new(options, "config_info", config_info); >-+ LogMessage(X_INFO, "config/devd: adding input device %s (%s)\n", >-+ attrs.product, path); >++ if (options == NULL) >++ goto error; >++ >++ LogMessage(X_INFO, "config/devd: adding input device '%s'\n", >++ devicename); > + > + NewInputDeviceRequest(options, &attrs, &dev); >++ goto done; >++ >++duplicate: >++ LogMessage(X_WARNING, "config/devd: device '%s' already " >++ "added. Ignoring\n", devicename); >++ goto done; >++ >++error: >++ LogMessage(X_INFO, "config/devd: error adding device '%s'\n", >++ devicename); >++ goto done; >++ >++ignore: >++ LogMessage(X_INFO, "config/devd: ignoring device '%s'\n", >++ devicename); >++ goto done; > + >-+unwind: >++done: > + free(config_info); > + input_option_free_list(&options); > + free(attrs.usb_id); > + free(attrs.product); > + free(attrs.device); > + free(attrs.vendor); >++ free(vendor); >++} >++ >++static void >++devpath_scan_sub(char *path, int off, int rem) >++{ >++ struct dirent *entry; >++ DIR *dp; >++ >++ if ((dp = opendir(path)) == NULL) { >++ LogMessage(X_INFO, "Cannot open directory '%s'\n", path); >++ return; >++ } >++ while ((entry = readdir(dp)) != NULL) { >++ int len = strlen(entry->d_name); >++ if (len > rem) >++ continue; >++ strcpy(path + off, entry->d_name); >++ off += len; >++ rem -= len; >++ switch (entry->d_type) { >++ case DT_DIR: >++ if (strcmp(entry->d_name, ".") == 0 || >++ strcmp(entry->d_name, "..") == 0) >++ break; >++ if (rem < 1) >++ break; >++ path[off] = '/'; >++ path[off+1] = '\0'; >++ off++; >++ rem--; >++ /* recurse */ >++ devpath_scan_sub(path, off, rem); >++ off--; >++ rem++; >++ break; >++ case DT_SOCK: >++ case DT_FIFO: >++ case DT_LNK: >++ case DT_CHR: >++ /* add device, if any */ >++ device_added(path, false); >++ break; >++ default: >++ break; >++ } >++ off -= len; >++ rem += len; >++ } >++ closedir(dp); > +} > + > +static void >-+device_removed(char *devname) >++devpath_scan(void) >++{ >++ char path[PATH_MAX + 1]; >++ >++ strlcpy(path, _PATH_DEV, sizeof(path)); >++ >++ devpath_scan_sub(path, strlen(path), PATH_MAX - strlen(path)); >++} >++ >++static void >++device_removed(char *devicename) > +{ > + char *config_info; > + >-+ if (asprintf(&config_info, "devd:%s", devname) == -1) >++ if (asprintf(&config_info, "devd:%s", >++ skip_path_dev(devicename)) == -1) > + return; > + >++ if (device_is_duplicate(config_info)) { >++ LogMessage(X_INFO, "config/devd: removing input device '%s'\n", >++ devicename); >++ } > + remove_devices("devd", config_info); > + > + free(config_info); >@@ -317,8 +368,7 @@ > +static bool is_kbdmux_enabled(void) > +{ > + /* Xorg uses /dev/ttyv0 as a console device */ >-+ /* const char device[]="/dev/console"; */ >-+ const char device[]="/dev/ttyv0"; >++ static const char device[]= { _PATH_DEV "ttyv0" }; > + keyboard_info_t info; > + int fd; > + >@@ -447,7 +497,11 @@ > +static void > +wakeup_handler(void *data, int err, void *read_mask) > +{ >++ static const char cdev_create[] = { "!system=DEVFS subsystem=CDEV type=CREATE cdev=" }; >++ static const char cdev_destroy[] = { "!system=DEVFS subsystem=CDEV type=DESTROY cdev=" }; >++ static const char cdev_path[] = { _PATH_DEV }; > + char *line = NULL; >++ char *devicename; > + char *walk; > + > + if (err < 0) >@@ -456,20 +510,20 @@ > + if (FD_ISSET(sock_devd, (fd_set *) read_mask)) { > + if (socket_getline(sock_devd, &line) < 0) > + return; >-+ >-+ walk = strchr(line + 1, ' '); >-+ if (walk != NULL) >-+ walk[0] = '\0'; >-+ >-+ switch (*line) { >-+ case DEVD_EVENT_ADD: >-+ device_added(line + 1); >-+ break; >-+ case DEVD_EVENT_REMOVE: >-+ device_removed(line + 1); >-+ break; >-+ default: >-+ break; >++ if (strstr(line, cdev_create) == line) { >++ devicename = line + strlen(cdev_create) - strlen(cdev_path); >++ memcpy(devicename, cdev_path, strlen(cdev_path)); >++ walk = strchr(devicename, ' '); >++ if (walk != NULL) >++ walk[0] = '\0'; >++ device_added(devicename, false); >++ } else if (strstr(line, cdev_destroy) == line) { >++ devicename = line + strlen(cdev_destroy) - strlen(cdev_path); >++ memcpy(devicename, cdev_path, strlen(cdev_path)); >++ walk = strchr(devicename, ' '); >++ if (walk != NULL) >++ walk[0] = '\0'; >++ device_removed(devicename); > + } > + free(line); > + } >@@ -483,34 +537,25 @@ > +int > +config_devd_init(void) > +{ >-+ char devicename[1024]; >-+ int i, j; >-+ > + LogMessage(X_INFO, "config/devd: probing input devices...\n"); > + >-+ /* >-+ * Add fake keyboard and give up on keyboards management >-+ * if kbdmux is enabled >-+ */ >-+ if ((is_kbdmux = is_kbdmux_enabled()) == true) >-+ device_added("kbdmux"); >-+ >-+ for (i = 0; hw_types[i].driver != NULL; i++) { >-+ /* First scan the sysctl to determine the hardware */ >-+ for (j = 0; j < 16; j++) { >-+ if (sysctl_exists(&hw_types[i], j, >-+ devicename, sizeof(devicename)) != 0) >-+ device_added(devicename); >-+ } >++ /* Check if kbdmux is enabled */ >++ is_kbdmux = is_kbdmux_enabled(); > + >-+ if (devpath_exists(&hw_types[i], devicename, sizeof(devicename)) != 0) >-+ device_added(devicename); >-+ } >++ /* Try to add kbdmux device first */ >++ if (is_kbdmux) >++ device_added(_PATH_DEV "kbdmux0", true); > + >++ /* Connect to devd, so that we don't loose any events */ > + if ((sock_devd = connect_devd()) < 0) > + return 0; > + >-+ RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, NULL); >++ /* Scan what is currently connected */ >++ devpath_scan(); >++ >++ /* Register wakeup handler */ >++ RegisterBlockAndWakeupHandlers(block_handler, >++ wakeup_handler, NULL); > + > + return 1; > +} >@@ -527,7 +572,6 @@ > + > + disconnect_devd(sock_devd); > + >-+ RemoveBlockAndWakeupHandlers(block_handler, wakeup_handler, NULL); >-+ >-+ is_console_kbd = false; >++ RemoveBlockAndWakeupHandlers(block_handler, >++ wakeup_handler, NULL); > +}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 196678
:
151548
|
151549
|
160696
|
160697
|
161034
|
161035
|
166727
|
167354
|
167426
|
167594
|
172378
|
175616
|
179892
|
180700
|
180710
|
180880
|
191592
|
195909
|
196037
|
197417
|
198703
|
203086
|
209380
|
211620
|
211740
|
211748
|
211749
|
211907