diff options
-rw-r--r-- | xserver/config/Makefile.am | 6 | ||||
-rw-r--r-- | xserver/config/config-backends.h | 5 | ||||
-rw-r--r-- | xserver/config/config.c | 5 | ||||
-rw-r--r-- | xserver/config/wscons.c | 278 | ||||
-rw-r--r-- | xserver/configure.ac | 16 | ||||
-rw-r--r-- | xserver/hw/xfree86/common/xf86Config.c | 6 | ||||
-rw-r--r-- | xserver/hw/xfree86/common/xf86Globals.c | 2 | ||||
-rw-r--r-- | xserver/hw/xfree86/common/xf86Xinput.c | 3 | ||||
-rw-r--r-- | xserver/include/dix-config.h.in | 3 | ||||
-rw-r--r-- | xserver/include/do-not-use-config.h.in | 3 |
10 files changed, 323 insertions, 4 deletions
diff --git a/xserver/config/Makefile.am b/xserver/config/Makefile.am index e1f1c4e16..cb5149270 100644 --- a/xserver/config/Makefile.am +++ b/xserver/config/Makefile.am @@ -32,6 +32,12 @@ libconfig_la_SOURCES += hal.c libconfig_la_LIBADD += $(HAL_LIBS) endif +else + +if CONFIG_WSCONS +libconfig_la_SOURCES += wscons.c +endif # CONFIG_WSCONS + endif # CONFIG_NEED_DBUS endif # !CONFIG_UDEV diff --git a/xserver/config/config-backends.h b/xserver/config/config-backends.h index 0a2a22af0..945cc1f40 100644 --- a/xserver/config/config-backends.h +++ b/xserver/config/config-backends.h @@ -68,3 +68,8 @@ int config_hal_init(void); void config_hal_fini(void); # endif #endif + +#ifdef CONFIG_WSCONS +int config_wscons_init(void); +void config_wscons_fini(void); +#endif diff --git a/xserver/config/config.c b/xserver/config/config.c index d86f7c649..69bd6a137 100644 --- a/xserver/config/config.c +++ b/xserver/config/config.c @@ -52,6 +52,9 @@ config_init(void) else { ErrorF("[config] failed to initialise D-Bus core\n"); } +#elif defined(CONFIG_WSCONS) + if (!config_wscons_init()) + ErrorF("[config] failed to initialise wscons\n"); #endif } @@ -68,6 +71,8 @@ config_fini(void) config_dbus_fini(); # endif config_dbus_core_fini(); +#elif defined(CONFIG_WSCONS) + config_wscons_fini(); #endif } diff --git a/xserver/config/wscons.c b/xserver/config/wscons.c new file mode 100644 index 000000000..5da90f6e3 --- /dev/null +++ b/xserver/config/wscons.c @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2011 Matthieu Herrb + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <dev/wscons/wsconsio.h> +#include <dev/wscons/wsksymdef.h> + +#include <sys/ioctl.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> + +#include "input.h" +#include "inputstr.h" +#include "os.h" +#include "config-backends.h" + +#define WSCONS_KBD_DEVICE "/dev/wskbd" +#define WSCONS_MOUSE_PREFIX "/dev/wsmouse" + +#define KB_OVRENC \ + { KB_UK, "gb" }, \ + { KB_SV, "se" }, \ + { KB_SG, "ch" }, \ + { KB_SF, "ch" }, \ + { KB_LA, "latam" }, \ + { KB_CF, "ca" } + +struct nameint { + int val; + char *name; +} kbdenc[] = { KB_OVRENC, KB_ENCTAB, { 0 } }; + +struct nameint kbdvar[] = { + { KB_NODEAD | KB_SG, "de_nodeadkeys" }, + { KB_NODEAD | KB_SF, "fr_nodeadkeys" }, + { KB_SF, "fr" }, + { KB_DVORAK | KB_CF, "fr-dvorak" }, + { KB_DVORAK | KB_FR, "bepo" }, + { KB_DVORAK, "dvorak" }, + { KB_CF, "fr-legacy" }, + { KB_NODEAD, "nodeadkeys" }, + { 0 } +}; + +struct nameint kbdopt[] = { + { KB_SWAPCTRLCAPS, "ctrl:swapcaps" }, + { 0 } +}; + +struct nameint kbdtype[] = { + { WSKBD_TYPE_ZAURUS, "zaurus" }, + { 0 } +}; + +extern int priv_open_device(const char *); + +static void +wscons_add_keyboard(void) +{ + InputAttributes attrs = {}; + DeviceIntPtr dev = NULL; + InputOption *options = NULL, *tmpo; + char *config_info = NULL; + int fd, i, rc; + unsigned int type; + kbd_t wsenc = 0; + + /* Find keyboard configuration */ + fd = priv_open_device(WSCONS_KBD_DEVICE); + if (fd == -1) { + LogMessage(X_ERROR, "wskbd: open %s: %s\n", + WSCONS_KBD_DEVICE, strerror(errno)); + return; + } + if (ioctl(fd, WSKBDIO_GETENCODING, &wsenc) == -1) { + LogMessage(X_WARNING, "wskbd: ioctl(WSKBDIO_GETENCODING) " + "failed: %s\n", strerror(errno)); + close(fd); + return; + } + if (ioctl(fd, WSKBDIO_GTYPE, &type) == -1) { + LogMessage(X_WARNING, "wskbd: ioctl(WSKBDIO_GTYPE) " + "failed: %s\n", strerror(errno)); + close(fd); + return; + } + close (fd); + + options = calloc(sizeof(*options), 1); + if (!options) + return; + + options->key = strdup("_source"); + options->value = strdup("server/wscons"); + if (!options->key || !options->value) + return; + + LogMessage(X_INFO, "config/wscons: checking input device %s\n", + WSCONS_KBD_DEVICE); + add_option(&options, "name", WSCONS_KBD_DEVICE); + add_option(&options, "driver", "kbd"); + + config_info = Xprintf("wscons:%s", WSCONS_KBD_DEVICE); + if (!config_info) + goto unwind; + if (KB_ENCODING(wsenc) == KB_USER) { + /* Ignore wscons "user" layout */ + LogMessageVerb(X_INFO, 3, "wskbd: ignoring \"user\" layout\n"); + goto kbd_config_done; + } + for (i = 0; kbdenc[i].val; i++) + if(KB_ENCODING(wsenc) == kbdenc[i].val) { + LogMessageVerb(X_INFO, 3, "wskbd: using layout %s\n", + kbdenc[i].name); + add_option(&options, "xkb_layout", kbdenc[i].name); + break; + } + for (i = 0; kbdvar[i].val; i++) + if (wsenc == kbdvar[i].val || + KB_VARIANT(wsenc) == kbdvar[i].val) { + LogMessageVerb(X_INFO, 3, "wskbd: using variant %s\n", + kbdvar[i].name); + add_option(&options, "xkb_variant", kbdvar[i].name); + break; + } + for (i = 0; kbdopt[i].val; i++) + if (KB_VARIANT(wsenc) == kbdopt[i].val) { + LogMessageVerb(X_INFO, 3, "wskbd: using option %s\n", + kbdopt[i].name); + add_option(&options, "xkb_options", kbdopt[i].name); + break; + } + for (i = 0; kbdtype[i].val; i++) + if (type == kbdtype[i].val) { + LogMessageVerb(X_INFO, 3, "wskbd: using type %s\n", + kbdtype[i].name); + add_option(&options, "xkb_type", kbdtype[i].name); + break; + } + +kbd_config_done: + attrs.flags |= ATTR_KEYBOARD; + rc = NewInputDeviceRequest(options, &attrs, &dev); + if (rc != Success) + goto unwind; + + for (; dev; dev = dev->next) { + free(dev->config_info); + dev->config_info = strdup(config_info); + } +unwind: + while (!dev && (tmpo = options)) { + options = tmpo->next; + free(tmpo->key); + free(tmpo->value); + free(tmpo); + } +} + +static void +wscons_add_pointer(const char *path, const char *driver, int flags) +{ + InputAttributes attrs = {}; + DeviceIntPtr dev = NULL; + InputOption *options = NULL, *tmpo; + char *config_info = NULL; + int rc; + + config_info = Xprintf("wscons:%s", path); + if (!config_info) + return; + options = calloc(sizeof(*options), 1); + if (!options) + return; + + options->key = strdup("_source"); + options->value = strdup("server/wscons"); + if (!options->key || !options->value) + return; + add_option(&options, "name", strdup(path)); + add_option(&options, "driver", strdup(driver)); + add_option(&options, "device", strdup(path)); + LogMessage(X_INFO, "config/wscons: checking input device %s\n", path); + attrs.flags |= flags; + rc = NewInputDeviceRequest(options, &attrs, &dev); + if (rc != Success) + goto unwind; + + for (; dev; dev = dev->next) { + free(dev->config_info); + dev->config_info = strdup(config_info); + } +unwind: + while (!dev && (tmpo = options)) { + options = tmpo->next; + free(tmpo->key); + free(tmpo->value); + free(tmpo); + } +} + +static void +wscons_add_pointers(void) +{ + char devname[256]; + int fd, i, wsmouse_type; + + /* Check pointing devices */ + for (i = 0; i < 4; i++) { + snprintf(devname, sizeof(devname), "%s%d", + WSCONS_MOUSE_PREFIX, i); + LogMessageVerb(X_INFO, 10, "wsmouse: checking %s\n", devname); + fd = priv_open_device(devname); + if (fd == -1) { + LogMessageVerb(X_WARNING, 10, "%s: %s\n", devname, + strerror(errno)); + continue; + } + if (ioctl(fd, WSMOUSEIO_GTYPE, &wsmouse_type) != 0) { + LogMessageVerb(X_WARNING, 10, + "%s: WSMOUSEIO_GTYPE failed\n", devname); + close(fd); + continue; + } + close(fd); + switch (wsmouse_type) { + case WSMOUSE_TYPE_SYNAPTICS: + wscons_add_pointer(devname, "synaptics", + ATTR_TOUCHPAD); + break; + case WSMOUSE_TYPE_TPANEL: + wscons_add_pointer(devname, "ws", ATTR_TOUCHSCREEN); + break; + default: + break; + } + } + /* Add a default entry catching all other mux elements as "mouse" */ + wscons_add_pointer(WSCONS_MOUSE_PREFIX, "mouse", ATTR_POINTER); +} + +int +config_wscons_init(void) +{ + wscons_add_keyboard(); + wscons_add_pointers(); + return 1; +} + +void +config_wscons_fini(void) +{ + /* Not much to do ? */ +} diff --git a/xserver/configure.ac b/xserver/configure.ac index f5c574a71..fe402cb90 100644 --- a/xserver/configure.ac +++ b/xserver/configure.ac @@ -672,6 +672,7 @@ AC_ARG_ENABLE(dpms, AS_HELP_STRING([--disable-dpms], [Build DPMS exten AC_ARG_ENABLE(config-udev, AS_HELP_STRING([--enable-config-udev], [Build udev support (default: auto)]), [CONFIG_UDEV=$enableval], [CONFIG_UDEV=auto]) AC_ARG_ENABLE(config-dbus, AS_HELP_STRING([--enable-config-dbus], [Build D-BUS API support (default: no)]), [CONFIG_DBUS_API=$enableval], [CONFIG_DBUS_API=no]) AC_ARG_ENABLE(config-hal, AS_HELP_STRING([--disable-config-hal], [Build HAL support (default: auto)]), [CONFIG_HAL=$enableval], [CONFIG_HAL=auto]) +AC_ARG_ENABLE(config-wscons, AS_HELP_STRING([--enable-config-wscons], [Build wscons config support (default: auto)]), [CONFIG_WSCONS=$enableval], [CONFIG_WSCONS=auto]) AC_ARG_ENABLE(xfree86-utils, AS_HELP_STRING([--enable-xfree86-utils], [Build xfree86 DDX utilities (default: enabled)]), [XF86UTILS=$enableval], [XF86UTILS=yes]) AC_ARG_ENABLE(xaa, AS_HELP_STRING([--enable-xaa], [Build XAA (default: enabled)]), [XAA=$enableval], [XAA=yes]) AC_ARG_ENABLE(vgahw, AS_HELP_STRING([--enable-vgahw], [Build Xorg with vga access (default: enabled)]), [VGAHW=$enableval], [VGAHW=yes]) @@ -916,6 +917,21 @@ if test "x$CONFIG_NEED_DBUS" = xyes; then fi AM_CONDITIONAL(CONFIG_NEED_DBUS, [test "x$CONFIG_NEED_DBUS" = xyes]) +if test "x$CONFIG_WSCONS" = xauto; then + case $host_os in + *openbsd*) + CONFIG_WSCONS=yes; + ;; + *) + CONFIG_WSCONS=no; + ;; + esac +fi +AM_CONDITIONAL(CONFIG_WSCONS, [test "x$CONFIG_WSCONS" = xyes]) +if test "x$CONFIG_WSCONS" = xyes; then + AC_DEFINE(CONFIG_WSCONS, 1, [Use wscons for input auto configuration]) +fi + if test "x$USE_SIGIO_BY_DEFAULT" = xyes; then USE_SIGIO_BY_DEFAULT_VALUE=TRUE else diff --git a/xserver/hw/xfree86/common/xf86Config.c b/xserver/hw/xfree86/common/xf86Config.c index dc84eed64..4853c1da9 100644 --- a/xserver/hw/xfree86/common/xf86Config.c +++ b/xserver/hw/xfree86/common/xf86Config.c @@ -1444,12 +1444,14 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout) } if (xf86Info.allowEmptyInput && !(foundPointer && foundKeyboard)) { -#if defined(CONFIG_HAL) || defined(CONFIG_UDEV) +#if defined(CONFIG_HAL) || defined(CONFIG_UDEV) || defined(CONFIG_WSCONS) const char *config_backend; #if defined(CONFIG_HAL) config_backend = "HAL"; -#else +#elif defined(CONFIG_UDEV) config_backend = "udev"; +#else + config_backend = "wscons"; #endif xf86Msg(X_INFO, "The server relies on %s to provide the list of " "input devices.\n\tIf no devices become available, " diff --git a/xserver/hw/xfree86/common/xf86Globals.c b/xserver/hw/xfree86/common/xf86Globals.c index 43665d1b6..e57b9d05a 100644 --- a/xserver/hw/xfree86/common/xf86Globals.c +++ b/xserver/hw/xfree86/common/xf86Globals.c @@ -128,7 +128,7 @@ xf86InfoRec xf86Info = { .kbdCustomKeycodes = FALSE, .disableRandR = FALSE, .randRFrom = X_DEFAULT, -#if defined(CONFIG_HAL) || defined(CONFIG_UDEV) +#if defined(CONFIG_HAL) || defined(CONFIG_UDEV) || defined(CONFIG_WSCONS) .allowEmptyInput = TRUE, .autoAddDevices = TRUE, .autoEnableDevices = TRUE diff --git a/xserver/hw/xfree86/common/xf86Xinput.c b/xserver/hw/xfree86/common/xf86Xinput.c index 116d8a4af..d0134335a 100644 --- a/xserver/hw/xfree86/common/xf86Xinput.c +++ b/xserver/hw/xfree86/common/xf86Xinput.c @@ -873,7 +873,8 @@ NewInputDeviceRequest (InputOption *options, InputAttributes *attrs, if (strcmp(option->key, "_source") == 0 && (strcmp(option->value, "server/hal") == 0 || - strcmp(option->value, "server/udev") == 0)) { + strcmp(option->value, "server/udev") == 0 || + strcmp(option->value, "server/wscons") == 0)) { is_auto = 1; if (!xf86Info.autoAddDevices) { rval = BadMatch; diff --git a/xserver/include/dix-config.h.in b/xserver/include/dix-config.h.in index a618f94b4..766116725 100644 --- a/xserver/include/dix-config.h.in +++ b/xserver/include/dix-config.h.in @@ -411,6 +411,9 @@ /* Support HAL for hotplug */ #undef CONFIG_HAL +/* Use wscons for input auto configuration */ +#undef CONFIG_WSCONS + /* Have a monotonic clock from clock_gettime() */ #undef MONOTONIC_CLOCK diff --git a/xserver/include/do-not-use-config.h.in b/xserver/include/do-not-use-config.h.in index 11bd3b625..08c842605 100644 --- a/xserver/include/do-not-use-config.h.in +++ b/xserver/include/do-not-use-config.h.in @@ -39,6 +39,9 @@ /* Use libudev for input hotplug */ #undef CONFIG_UDEV +/* Use wscons for input auto configuration */ +#undef CONFIG_WSCONS + /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP systems. This function is required for `alloca.c' support on those systems. */ |