Date: Tue, 27 Jan 2015 15:32:09 -0500 From: Anthony Jenkins <Scoobi_doo@yahoo.com> To: freebsd-x11@freebsd.org Subject: [PATCH] Synaptics & devd(4) support Message-ID: <54C7F5C9.4070208@yahoo.com>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
The attached patches allow x11-servers/xorg-server with devd(4) support
enabled to attach the x11-drivers/xf86-input-synaptics driver. The
largest change is to config/devd.c, mainly because psm(4) can attach
either the synaptics or mouse driver.
Changes:
x11-drivers/xf86-input-synaptics:
- Added a PSMAutoDevProbe() method which returns TRUE if psm(4) is in
Synaptics mode (hw.psm.synaptics_support=1).
x11-drivers/xf86-input-mouse:
- Do not attach if psm(4) is in Synaptics mode.
x11-servers/xorg-server:
- Changed struct hw_type to consist of 3 members:
- name of driver
- handler to configure driver
- flag to ignore device path (for atkbd(4))
- Changed hw_types[] to associate driver names with handlers
- Moved test for open device file to is_path_openable().
- Added char *rtrim(char *) to strip trailing whitespace (called from
device_removed()).
- Changed device_added() to setup device generically, then call
driver-specific handler.
- Moved keyboard quirks to atkbd(4) handler (get_default_device()).
- Moved "driver" input option setting to individual driver handlers.
- Added get_default_device(), get_usb_device() and get_psm_device()
handlers.
- Reordered mousedrivers[] array to favor specialized pointer drivers
("synaptics", "evdev", "vmmouse") over generic driver ("mouse").
Patches should perform correctly regardless of psm(4) synaptics support,
but it's been a while since I've tested without synaptics support. I
also have an associated patch for sysutils/hal to support attaching the
Synaptics driver properly; I'll have to dig that up though.
Comments/suggestions/criticisms welcome.
--
Anthony Jenkins
[-- Attachment #2 --]
Index: x11-drivers/xf86-input-mouse/files/patch-src-bsd_mouse.c
===================================================================
--- x11-drivers/xf86-input-mouse/files/patch-src-bsd_mouse.c (revision 378012)
+++ x11-drivers/xf86-input-mouse/files/patch-src-bsd_mouse.c (working copy)
@@ -1,5 +1,5 @@
---- src/bsd_mouse.c.orig 2012-10-08 03:40:07.000000000 +0200
-+++ src/bsd_mouse.c 2013-07-03 01:00:50.897361950 +0200
+--- ./src/bsd_mouse.c.orig 2012-10-07 21:40:07.000000000 -0400
++++ ./src/bsd_mouse.c 2014-06-26 16:55:24.857626606 -0400
@@ -26,6 +26,24 @@
* authorization from the copyright holder(s) and author(s).
*/
@@ -86,7 +86,7 @@
#else
return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_XPS2 | MSE_AUTO | MSE_MISC;
#endif
-@@ -180,9 +215,30 @@
+@@ -180,17 +215,45 @@
{ MOUSE_PROTO_SYSMOUSE, "SysMouse" }
};
@@ -117,7 +117,8 @@
int i;
mousehw_t hw;
mousemode_t mode;
-@@ -190,7 +246,13 @@
++ synapticshw_t synhw;
+
if (pInfo->fd == -1)
return NULL;
@@ -131,7 +132,16 @@
i = 1;
ioctl(pInfo->fd, MOUSE_SETLEVEL, &i);
-@@ -209,9 +271,18 @@
+@@ -200,7 +263,7 @@
+ ioctl(pInfo->fd, MOUSE_GETHWINFO, &hw);
+ xf86MsgVerb(X_INFO, 3, "%s: SetupAuto: hw.iftype is %d, hw.model is %d\n",
+ pInfo->name, hw.iftype, hw.model);
+- if (ioctl(pInfo->fd, MOUSE_GETMODE, &mode) == 0) {
++ if (ioctl(pInfo->fd, MOUSE_GETMODE, &mode) == 0 && ioctl(pInfo->fd, MOUSE_SYN_GETHWINFO, &synhw) != 0) {
+ for (i = 0; i < sizeof(devproto)/sizeof(devproto[0]); ++i) {
+ if (mode.protocol == devproto[i].dproto) {
+ /* override some parameters */
+@@ -209,9 +272,18 @@
protoPara[0] = mode.syncmask[0];
protoPara[1] = mode.syncmask[1];
}
@@ -152,7 +162,7 @@
}
}
}
-@@ -234,41 +305,41 @@
+@@ -234,41 +306,41 @@
(protocol && xf86NameCmp(protocol, "SysMouse") == 0)) {
/*
* As the FreeBSD sysmouse driver defaults to protocol level 0
@@ -211,7 +221,7 @@
}
return FALSE;
}
-@@ -276,17 +347,17 @@
+@@ -276,17 +348,17 @@
static const char *
FindDevice(InputInfoPtr pInfo, const char *protocol, int flags)
{
@@ -233,7 +243,7 @@
#endif
} else {
/*
-@@ -295,28 +366,32 @@
+@@ -295,28 +367,32 @@
* the test for whether /dev/sysmouse is usable can be made.
*/
if (!strcmp(*pdev, DEFAULT_MOUSE_DEV)) {
@@ -279,7 +289,7 @@
break;
}
}
-@@ -468,30 +543,78 @@
+@@ -468,30 +544,78 @@
#if defined(USBMOUSE_SUPPORT)
@@ -366,7 +376,7 @@
switch (what) {
case DEVICE_INIT:
-@@ -500,38 +623,96 @@
+@@ -500,38 +624,96 @@
for (nbuttons = 0; nbuttons < MSE_MAXBUTTONS; ++nbuttons)
map[nbuttons + 1] = nbuttons + 1;
@@ -486,7 +496,7 @@
}
pMse->lastButtons = 0;
pMse->lastMappedButtons = 0;
-@@ -553,6 +734,7 @@
+@@ -553,6 +735,7 @@
xf86CloseSerial(pInfo->fd);
pInfo->fd = -1;
}
@@ -494,7 +504,7 @@
pPointer->public.on = FALSE;
usleep(300000);
break;
-@@ -568,45 +750,154 @@
+@@ -568,45 +751,154 @@
{
MouseDevPtr pMse;
UsbMsePtr pUsbMse;
@@ -551,11 +561,6 @@
- dy = hid_get_data(pBuf, &pUsbMse->loc_y);
- dz = hid_get_data(pBuf, &pUsbMse->loc_z);
- dw = hid_get_data(pBuf, &pUsbMse->loc_w);
--
-- buttons = 0;
-- for (n = 0; n < pMse->buttons; n++) {
-- if (hid_get_data(pBuf, &pUsbMse->loc_btn[n]))
-- buttons |= (1 << UMS_BUT(n));
+ for (nacol = 0; nacol < pUsbMse->nacols; nacol++) {
+ acol = &pUsbMse->acols[nacol];
+ if (acol->pInfo == NULL)
@@ -565,7 +570,11 @@
+ dx = dy = dz = dw = dp = 0;
+ for (nlcol = 0; nlcol < pUsbMse->acols[nacol].nlcols; nlcol++) {
+ lcol = &acol->lcols[nlcol];
-+
+
+- buttons = 0;
+- for (n = 0; n < pMse->buttons; n++) {
+- if (hid_get_data(pBuf, &pUsbMse->loc_btn[n]))
+- buttons |= (1 << UMS_BUT(n));
+ if (lcol->loc_valid.usage != 0 && rid == lcol->loc_valid.report_ID &&
+ hid_get_data(pBuf, &lcol->loc_valid) == 0)
+ continue;
@@ -671,7 +680,7 @@
}
static void
-@@ -615,14 +906,17 @@
+@@ -615,14 +907,17 @@
usbReadInput ((InputInfoPtr) closure);
}
@@ -692,7 +701,7 @@
pUsbMse = malloc(sizeof(UsbMseRec));
if (pUsbMse == NULL) {
-@@ -631,12 +925,7 @@
+@@ -631,12 +926,7 @@
return FALSE;
}
@@ -706,7 +715,7 @@
/* Check if the device can be opened. */
pInfo->fd = xf86OpenSerial(pInfo->options);
-@@ -652,19 +941,134 @@
+@@ -652,19 +942,134 @@
}
/* Get USB informations */
reportDesc = hid_get_report_desc(pInfo->fd);
@@ -716,13 +725,6 @@
- xf86Msg(X_ERROR, "Error ioctl USB_GET_REPORT_ID on %s : %s\n",
- pInfo->name, strerror(errno));
- return FALSE;
-- }
-- pUsbMse->packetSize = hid_report_size(reportDesc, hid_input,
-- pUsbMse->iid);
--#else
-- pUsbMse->packetSize = hid_report_size(reportDesc, hid_input,
-- &pUsbMse->iid);
--#endif
+ mdepth = 0;
+ pUsbMse->nacols = 0;
+ acol = &pUsbMse->acols[pUsbMse->nacols];
@@ -842,7 +844,13 @@
+ default:
+ break;
+ }
-+ }
+ }
+- pUsbMse->packetSize = hid_report_size(reportDesc, hid_input,
+- pUsbMse->iid);
+-#else
+- pUsbMse->packetSize = hid_report_size(reportDesc, hid_input,
+- &pUsbMse->iid);
+-#endif
+ if (lcolused)
+ acol->nlcols++;
+ if (acolused)
@@ -854,7 +862,7 @@
/* Allocate buffer */
if (pUsbMse->packetSize <= 8) {
pUsbMse->buffer = pMse->protoBuf;
-@@ -674,56 +1078,129 @@
+@@ -674,56 +1079,129 @@
if (pUsbMse->buffer == NULL) {
xf86Msg(X_ERROR, "%s: cannot allocate buffer\n", pInfo->name);
free(pUsbMse);
@@ -1021,7 +1029,7 @@
/* Setup the local procs. */
pInfo->device_control = usbMouseProc;
pInfo->read_input = usbReadInput;
-@@ -766,7 +1243,9 @@
+@@ -766,7 +1244,9 @@
p->CheckProtocol = CheckProtocol;
#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)) && defined(MOUSE_PROTO_SYSMOUSE)
p->SetupAuto = SetupAuto;
[-- Attachment #3 --]
Index: x11-drivers/xf86-input-synaptics/files/patch-src__psmcomm.c
===================================================================
--- x11-drivers/xf86-input-synaptics/files/patch-src__psmcomm.c (revision 0)
+++ x11-drivers/xf86-input-synaptics/files/patch-src__psmcomm.c (working copy)
@@ -0,0 +1,22 @@
+--- ./src/psmcomm.c.orig 2013-05-12 19:18:02.000000000 -0400
++++ ./src/psmcomm.c 2013-09-18 08:56:55.344635632 -0400
+@@ -165,11 +165,18 @@
+ return PS2ReadHwStateProto(pInfo, &psm_proto_operations, comm, hwRet);
+ }
+
++static Bool
++PSMAutoDevProbe(InputInfoPtr pInfo, const char *device)
++{
++ return pInfo && pInfo->name && !strcmp(pInfo->name, "PS/2 Mouse") &&
++ device && !strncmp(device, "/dev/psm", 8);
++}
++
+ struct SynapticsProtocolOperations psm_proto_operations = {
+ NULL,
+ NULL,
+ PSMQueryHardware,
+ PSMReadHwState,
+- NULL,
++ PSMAutoDevProbe,
+ NULL
+ };
Property changes on: x11-drivers/xf86-input-synaptics/files/patch-src__psmcomm.c
___________________________________________________________________
Added: fbsd:nokeywords
## -0,0 +1 ##
+yes
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
[-- Attachment #4 --]
Index: x11-servers/xorg-server/files/patch-config_devd.c
===================================================================
--- x11-servers/xorg-server/files/patch-config_devd.c (revision 378012)
+++ x11-servers/xorg-server/files/patch-config_devd.c (working copy)
@@ -1,6 +1,6 @@
--- config/devd.c.orig 2014-12-16 23:03:10 UTC
+++ config/devd.c
-@@ -0,0 +1,530 @@
+@@ -0,0 +1,613 @@
+/*
+ * Copyright (c) 2012 Baptiste Daroussin
+ * Copyright (c) 2013, 2014 Alex Kozlov
@@ -67,22 +67,26 @@
+OsTimerPtr rtimer;
+
+struct hw_type {
-+ const char *driver;
-+ int flag;
-+ const char *xdriver;
++ const char *driver;
++ int (*config_device)(const char *driver, const char *devd_line, InputOption *options, InputAttributes *attrs);
++ int ignore_path;
+};
+
++static int get_default_device(const char *driver, const char *devd_line, InputOption *options, InputAttributes *attrs);
++static int get_usb_device(const char *driver, const char *devd_line, InputOption *options, InputAttributes *attrs);
++static int get_psm_device(const char *driver, const char *devd_line, InputOption *options, InputAttributes *attrs);
++
+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 },
++ { "ukbd", get_usb_device, 0 },
++ { "atkbd", get_default_device, 1 },
++ { "kbdmux", get_default_device, 0 },
++ { "sysmouse", get_default_device, 0 },
++ { "ums", get_usb_device, 0 },
++ { "psm", get_psm_device, 0 },
++ { "joy", get_default_device, 0 },
++ { "atp", get_usb_device, 0 },
++ { "uep", get_usb_device, 0 },
++ { NULL, NULL, 0 }
+};
+
+static bool
@@ -136,7 +140,31 @@
+ return false;
+}
+
++static int
++is_path_openable(const char *path)
++{
++ int fd;
++
++ if ((fd = open(path, O_RDONLY)) >= 0) {
++ close(fd);
++ }
++ return fd >= 0;
++}
++
+static char *
++rtrim(char *str)
++{
++ if (str && *str) {
++ char *cp;
++
++ for (cp = str + strlen(str) - 1; isspace(*cp); --cp) {
++ *cp = '\0';
++ }
++ }
++ return str;
++}
++
++static char *
+sysctl_get_str(const char *sysctlname)
+{
+ char *dest = NULL;
@@ -163,17 +191,14 @@
+static void
+device_added(const char *devname)
+{
-+ char path[PATH_MAX];
++ char path[PATH_MAX] = "";
+ char sysctlname[PATH_MAX];
-+ char *vendor;
+ char *product = NULL;
+ char *config_info = NULL;
-+ char *walk;
+ InputOption *options = NULL;
+ InputAttributes attrs = { };
+ DeviceIntPtr dev = NULL;
+ int i;
-+ int fd;
+
+ for (i = 0; hw_types[i].driver != NULL; i++) {
+ size_t len;
@@ -182,97 +207,42 @@
+ 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;
+ }
+ }
+
-+ if (hw_types[i].driver == NULL || hw_types[i].xdriver == NULL) {
-+ LogMessage(X_INFO, "config/devd: ignoring device %s\n",
++ if (hw_types[i].driver == NULL) {
++ LogMessage(X_INFO, "config/devd: device %s unsupported.\n",
+ devname);
+ return;
+ }
+
-+ /* 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;
++ if (!hw_types[i].ignore_path) {
++ snprintf(path, sizeof(path), "/dev/%s", devname);
+ }
+
-+ snprintf(path, sizeof(path), "/dev/%s", devname);
-+
+ options = input_option_new(NULL, "_source", "server/devd");
+ if (!options)
+ return;
+
++ /* Generic device configuration */
+ 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);
-+ }
-+ else {
-+ if ((walk = strchr(vendor, ' ')) != NULL) {
-+ walk[0] = '\0';
-+ walk++;
-+ product = walk;
-+ if ((walk = strchr(product, ',')) != NULL)
-+ walk[0] = '\0';
-+ }
-+
-+ attrs.vendor = strdup(vendor);
-+ if (product) {
-+ attrs.product = strdup(product);
-+ options = input_option_new(options, "name", product);
-+ }
-+ else
-+ options = input_option_new(options, "name", "(unnamed)");
-+
-+ free(vendor);
-+ }
-+
++ product = sysctl_get_str(sysctlname);
++ attrs.product = strdup(product != NULL ? product : "(unnamed)");
++ attrs.vendor = strdup("(unnamed)");
+ /* XXX implement usb_id */
+ attrs.usb_id = NULL;
+ attrs.device = strdup(path);
-+ options = input_option_new(options, "driver", hw_types[i].xdriver);
++ options = input_option_new(options, "name", product != NULL ? product : "(unnamed)");
++ options = input_option_new(options, "path", path);
++ options = input_option_new(options, "device", path);
+
-+ fd = open(path, O_RDONLY);
-+ if (fd > 0) {
-+ 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
-+ */
++ /* Device-specific configuration */
++ if (hw_types[i].config_device) {
++ if (hw_types[i].config_device(hw_types[i].driver, devname, options, &attrs)) {
+ 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;
+ }
+
+ if (asprintf(&config_info, "devd:%s", devname) == -1) {
@@ -293,7 +263,8 @@
+ NewInputDeviceRequest(options, &attrs, &dev);
+
+unwind:
-+ free(config_info);
++ if (config_info)
++ free(config_info);
+ input_option_free_list(&options);
+ free(attrs.usb_id);
+ free(attrs.product);
@@ -306,6 +277,7 @@
+{
+ char *config_info;
+
++ rtrim(devname);
+ if (asprintf(&config_info, "devd:%s", devname) == -1)
+ return;
+
@@ -480,6 +452,117 @@
+{
+}
+
++static int get_default_device(const char *driver, const char *devd_line, InputOption *options, InputAttributes *attrs)
++{
++ int retval = 0;
++
++ if (strcmp(driver, "atkbd") == 0) {
++ attrs->flags |= ATTR_KEYBOARD;
++ options = input_option_new(options, "driver", "kbd");
++
++ /* Skip keyboard devices if kbdmux is enabled */
++ if (is_kbdmux && is_console_kbd) {
++ LogMessage(X_INFO, "config/devd: kbdmux is enabled, ignoring device %s\n",
++ devd_line);
++ retval = -1;
++ }
++ else if (attrs->device[0] && !is_path_openable(attrs->device)) {
++ LogMessage(X_INFO, "config/devd: device %s already opened\n",
++ attrs->device);
++ /*
++ * Fail if cannot open device, it breaks
++ * AllowMouseOpenFail, but it should not matter when
++ * config/devd enabled
++ */
++ retval = -1;
++ }
++ else 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, attrs->device);
++ retval = -1;
++ }
++ 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;
++ }
++
++ } else if (strcmp(driver, "joy") == 0) {
++ attrs->flags |= ATTR_JOYSTICK;
++ options = input_option_new(options, "driver", "joystick");
++ } else {
++ retval = -1;
++ }
++ return retval;
++}
++
++static int get_usb_device(const char *driver, const char *devd_line, InputOption *options, InputAttributes *attrs)
++{
++ int retval = 0;
++
++ if (strcmp(driver, "ukbd") == 0) {
++ attrs->flags |= ATTR_KEYBOARD;
++ options = input_option_new(options, "driver", "kbd");
++ }
++ else if (strcmp(driver, "ums") == 0 || strcmp(driver, "uhid") == 0) {
++ /* Change "path" and "device" to use sysmouse(4) */
++ InputOption *option;
++
++ attrs->flags |= ATTR_POINTER;
++ options = input_option_new(options, "driver", "mouse");
++ option = input_option_find(options, "path");
++ if (option) {
++ input_option_set_value(option, "/dev/sysmouse");
++ }
++ option = input_option_find(options, "device");
++ if (option) {
++ input_option_set_value(option, "/dev/sysmouse");
++ }
++ } else if (strcmp(driver, "uep") == 0) {
++ attrs->flags |= ATTR_TOUCHSCREEN;
++ options = input_option_new(options, "driver", "egalax");
++ } else {
++ retval = -1;
++ }
++ return retval;
++}
++
++static int get_psm_device(const char *driver, const char *devd_line, InputOption *options, InputAttributes *attrs)
++{
++ int retval = 0;
++
++ if (strcmp(driver, "psm") == 0) {
++ char *str;
++
++ if ((str = sysctl_get_str("hw.psm.synaptics.margin_top")) ||
++ (str = sysctl_get_str("dev.psm.synaptics.margin_top")))
++ {
++ free(str);
++ attrs->flags |= ATTR_TOUCHPAD;
++ options = input_option_new(options, "driver", "synaptics");
++ } else {
++ attrs->flags |= ATTR_POINTER;
++ options = input_option_new(options, "driver", "mouse");
++ }
++ } else {
++ retval = -1;
++ }
++ return retval;
++}
++
++
+int
+config_devd_init(void)
+{
Index: x11-servers/xorg-server/files/patch-hw_xfree86_common_xf86Config.c
===================================================================
--- x11-servers/xorg-server/files/patch-hw_xfree86_common_xf86Config.c (revision 378012)
+++ x11-servers/xorg-server/files/patch-hw_xfree86_common_xf86Config.c (working copy)
@@ -1,5 +1,14 @@
--- hw/xfree86/common/xf86Config.c.orig 2014-04-15 01:01:57 UTC
+++ hw/xfree86/common/xf86Config.c
+@@ -1135,7 +1135,7 @@ checkCoreInputDevices(serverLayoutPtr se
+ XF86ConfInputRec defPtr, defKbd;
+ MessageType from = X_DEFAULT;
+
+- const char *mousedrivers[] = { "mouse", "synaptics", "evdev", "vmmouse",
++ const char *mousedrivers[] = { "synaptics", "evdev", "vmmouse", "mouse",
+ "void", NULL
+ };
+
@@ -1376,13 +1376,16 @@ checkCoreInputDevices(serverLayoutPtr se
}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?54C7F5C9.4070208>
