diff options
-rw-r--r-- | Xi/stubs.c | 3 | ||||
-rw-r--r-- | config/dbus.c | 2 | ||||
-rw-r--r-- | config/hal.c | 25 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | hw/dmx/dmxinput.c | 3 | ||||
-rw-r--r-- | hw/kdrive/src/kinput.c | 3 | ||||
-rw-r--r-- | hw/xfree86/common/xf86Module.h | 2 | ||||
-rw-r--r-- | hw/xfree86/common/xf86Option.c | 25 | ||||
-rw-r--r-- | hw/xfree86/common/xf86Xinput.c | 96 | ||||
-rw-r--r-- | hw/xfree86/doc/man/xorg.conf.man.pre | 96 | ||||
-rw-r--r-- | hw/xfree86/parser/Configint.h | 2 | ||||
-rw-r--r-- | hw/xfree86/parser/InputClass.c | 232 | ||||
-rw-r--r-- | hw/xfree86/parser/Makefile.am | 1 | ||||
-rw-r--r-- | hw/xfree86/parser/configProcs.h | 4 | ||||
-rw-r--r-- | hw/xfree86/parser/read.c | 8 | ||||
-rw-r--r-- | hw/xfree86/parser/scan.c | 30 | ||||
-rw-r--r-- | hw/xfree86/parser/write.c | 2 | ||||
-rw-r--r-- | hw/xfree86/parser/xf86Parser.h | 29 | ||||
-rw-r--r-- | hw/xfree86/parser/xf86tokens.h | 13 | ||||
-rw-r--r-- | hw/xquartz/darwinXinput.c | 3 | ||||
-rw-r--r-- | include/dix-config.h.in | 3 | ||||
-rw-r--r-- | include/input.h | 16 |
22 files changed, 567 insertions, 33 deletions
diff --git a/Xi/stubs.c b/Xi/stubs.c index 400e937d1..04ba9769e 100644 --- a/Xi/stubs.c +++ b/Xi/stubs.c @@ -227,7 +227,8 @@ ChangeDeviceControl(ClientPtr client, DeviceIntPtr dev, * */ int -NewInputDeviceRequest(InputOption *options, DeviceIntPtr *pdev) +NewInputDeviceRequest(InputOption *options, InputAttributes *attrs, + DeviceIntPtr *pdev) { return BadValue; } diff --git a/config/dbus.c b/config/dbus.c index 37462ace0..86d9d287f 100644 --- a/config/dbus.c +++ b/config/dbus.c @@ -147,7 +147,7 @@ add_device(DBusMessage *message, DBusMessage *reply, DBusError *error) dbus_message_iter_next(&iter); } - ret = NewInputDeviceRequest(options, &dev); + ret = NewInputDeviceRequest(options, NULL, &dev); if (ret != Success) { DebugF("[config/dbus] NewInputDeviceRequest failed\n"); goto unwind; diff --git a/config/hal.c b/config/hal.c index 28f55a02f..6bebbdf34 100644 --- a/config/hal.c +++ b/config/hal.c @@ -191,6 +191,7 @@ device_added(LibHalContext *hal_ctx, const char *udi) { char *path = NULL, *driver = NULL, *name = NULL, *config_info = NULL; InputOption *options = NULL, *tmpo = NULL; + InputAttributes attrs = {0}; DeviceIntPtr dev = NULL; DBusError error; struct xkb_options xkb_opts = {0}; @@ -215,10 +216,28 @@ device_added(LibHalContext *hal_ctx, const char *udi) LogMessage(X_WARNING,"config/hal: no driver or path specified for %s\n", udi); goto unwind; } + attrs.device = xstrdup(path); name = get_prop_string(hal_ctx, udi, "info.product"); if (!name) name = xstrdup("(unnamed)"); + else + attrs.product = xstrdup(name); + + attrs.vendor = get_prop_string(hal_ctx, udi, "info.vendor"); + + if (libhal_device_query_capability(hal_ctx, udi, "input.keys", NULL)) + attrs.flags |= ATTR_KEYBOARD; + if (libhal_device_query_capability(hal_ctx, udi, "input.mouse", NULL)) + attrs.flags |= ATTR_POINTER; + if (libhal_device_query_capability(hal_ctx, udi, "input.joystick", NULL)) + attrs.flags |= ATTR_JOYSTICK; + if (libhal_device_query_capability(hal_ctx, udi, "input.tablet", NULL)) + attrs.flags |= ATTR_TABLET; + if (libhal_device_query_capability(hal_ctx, udi, "input.touchpad", NULL)) + attrs.flags |= ATTR_TOUCHPAD; + if (libhal_device_query_capability(hal_ctx, udi, "input.touchscreen", NULL)) + attrs.flags |= ATTR_TOUCHSCREEN; options = xcalloc(sizeof(*options), 1); if (!options){ @@ -400,7 +419,7 @@ device_added(LibHalContext *hal_ctx, const char *udi) /* this isn't an error, but how else do you output something that the user can see? */ LogMessage(X_INFO, "config/hal: Adding input device %s\n", name); - if ((rc = NewInputDeviceRequest(options, &dev)) != Success) { + if ((rc = NewInputDeviceRequest(options, &attrs, &dev)) != Success) { LogMessage(X_ERROR, "config/hal: NewInputDeviceRequest failed (%d)\n", rc); dev = NULL; goto unwind; @@ -430,6 +449,10 @@ unwind: xfree(tmpo); } + xfree(attrs.product); + xfree(attrs.vendor); + xfree(attrs.device); + if (xkb_opts.layout) xfree(xkb_opts.layout); if (xkb_opts.rules) diff --git a/configure.ac b/configure.ac index b55eaaa35..e5eb380bc 100644 --- a/configure.ac +++ b/configure.ac @@ -122,7 +122,7 @@ AM_CONDITIONAL(SPECIAL_DTRACE_OBJECTS, [test "x$SPECIAL_DTRACE_OBJECTS" = "xyes" AC_HEADER_DIRENT AC_HEADER_STDC -AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h dlfcn.h stropts.h]) +AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h dlfcn.h stropts.h fnmatch.h]) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST diff --git a/hw/dmx/dmxinput.c b/hw/dmx/dmxinput.c index d9118b6a0..c099349d8 100644 --- a/hw/dmx/dmxinput.c +++ b/hw/dmx/dmxinput.c @@ -103,7 +103,8 @@ void dmxUpdateWindowInfo(DMXUpdateType type, WindowPtr pWindow) } int -NewInputDeviceRequest (InputOption *options, DeviceIntPtr *pdev) +NewInputDeviceRequest (InputOption *options, InputAttributes *attrs, + DeviceIntPtr *pdev) { return BadRequest; } diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c index 65fc75a54..c08459112 100644 --- a/hw/kdrive/src/kinput.c +++ b/hw/kdrive/src/kinput.c @@ -2249,7 +2249,8 @@ ChangeDeviceControl(register ClientPtr client, DeviceIntPtr pDev, } int -NewInputDeviceRequest(InputOption *options, DeviceIntPtr *pdev) +NewInputDeviceRequest(InputOption *options, InputAttributes *attrs, + DeviceIntPtr *pdev) { InputOption *option = NULL; KdPointerInfo *pi = NULL; diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h index 8e5d5cfb5..bbf5786c9 100644 --- a/hw/xfree86/common/xf86Module.h +++ b/hw/xfree86/common/xf86Module.h @@ -83,7 +83,7 @@ typedef enum { */ #define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 4) #define ABI_VIDEODRV_VERSION SET_ABI_VERSION(7, 0) -#define ABI_XINPUT_VERSION SET_ABI_VERSION(8, 0) +#define ABI_XINPUT_VERSION SET_ABI_VERSION(9, 0) #define ABI_EXTENSION_VERSION SET_ABI_VERSION(3, 0) #define ABI_FONT_VERSION SET_ABI_VERSION(0, 6) diff --git a/hw/xfree86/common/xf86Option.c b/hw/xfree86/common/xf86Option.c index ad8d1c426..a2868bf21 100644 --- a/hw/xfree86/common/xf86Option.c +++ b/hw/xfree86/common/xf86Option.c @@ -42,6 +42,7 @@ #include "xf86.h" #include "xf86Xinput.h" #include "xf86Optrec.h" +#include "xf86Parser.h" static Bool ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p, Bool markUsed); @@ -456,29 +457,7 @@ xf86ShowUnusedOptions(int scrnIndex, pointer options) static Bool GetBoolValue(OptionInfoPtr p, const char *s) { - if (*s == '\0') { - p->value.bool = TRUE; - } else { - if (xf86NameCmp(s, "1") == 0) - p->value.bool = TRUE; - else if (xf86NameCmp(s, "on") == 0) - p->value.bool = TRUE; - else if (xf86NameCmp(s, "true") == 0) - p->value.bool = TRUE; - else if (xf86NameCmp(s, "yes") == 0) - p->value.bool = TRUE; - else if (xf86NameCmp(s, "0") == 0) - p->value.bool = FALSE; - else if (xf86NameCmp(s, "off") == 0) - p->value.bool = FALSE; - else if (xf86NameCmp(s, "false") == 0) - p->value.bool = FALSE; - else if (xf86NameCmp(s, "no") == 0) - p->value.bool = FALSE; - else - return FALSE; - } - return TRUE; + return xf86getBoolValue(&p->value.bool, s); } static Bool diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c index f637cfe19..e0c783089 100644 --- a/hw/xfree86/common/xf86Xinput.c +++ b/hw/xfree86/common/xf86Xinput.c @@ -57,9 +57,11 @@ #include <X11/Xatom.h> #include "xf86.h" #include "xf86Priv.h" +#include "xf86Config.h" #include "xf86Xinput.h" #include "XIstubs.h" #include "xf86Optrec.h" +#include "xf86Parser.h" #include "mipointer.h" #include "xf86InPriv.h" #include "compiler.h" @@ -74,6 +76,11 @@ #include "exglobals.h" #include "eventstr.h" +#include <string.h> /* InputClassMatches */ +#ifdef HAVE_FNMATCH_H +#include <fnmatch.h> +#endif + #include "extnsionst.h" #include "windowstr.h" /* screenIsSaved */ @@ -466,6 +473,85 @@ AddOtherInputDevices(void) { } +/* + * Classes without any Match statements match all devices. Otherwise, all + * statements must match. + */ +static Bool +InputClassMatches(XF86ConfInputClassPtr iclass, InputAttributes *attrs) +{ + if (iclass->match_product && + (!attrs->product || !strstr(attrs->product, iclass->match_product))) + return False; + if (iclass->match_vendor && + (!attrs->vendor || !strstr(attrs->vendor, iclass->match_vendor))) + return False; + if (iclass->match_device && +#ifdef HAVE_FNMATCH_H + (!attrs->device || + fnmatch(iclass->match_device, attrs->device, 0) != 0)) +#else + (!attrs->device || !strstr(attrs->device, iclass->match_device))) +#endif + return False; + if (iclass->is_keyboard.set && + iclass->is_keyboard.val != !!(attrs->flags & ATTR_KEYBOARD)) + return False; + if (iclass->is_pointer.set && + iclass->is_pointer.val != !!(attrs->flags & ATTR_POINTER)) + return False; + if (iclass->is_joystick.set && + iclass->is_joystick.val != !!(attrs->flags & ATTR_JOYSTICK)) + return False; + if (iclass->is_tablet.set && + iclass->is_tablet.val != !!(attrs->flags & ATTR_TABLET)) + return False; + if (iclass->is_touchpad.set && + iclass->is_touchpad.val != !!(attrs->flags & ATTR_TOUCHPAD)) + return False; + if (iclass->is_touchscreen.set && + iclass->is_touchscreen.val != !!(attrs->flags & ATTR_TOUCHSCREEN)) + return False; + return True; +} + +/* + * Merge in any InputClass configurations. Each InputClass section can + * add to the original device configuration as well as any previous + * InputClass sections. + */ +static int +MergeInputClasses(IDevPtr idev, InputAttributes *attrs) +{ + XF86ConfInputClassPtr cl; + XF86OptionPtr classopts; + + for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) { + if (!InputClassMatches(cl, attrs)) + continue; + + xf86Msg(X_CONFIG, "%s: Applying InputClass \"%s\"\n", + idev->identifier, cl->identifier); + if (cl->driver && !idev->driver) { + idev->driver = xstrdup(cl->driver); + if (!idev->driver) { + xf86Msg(X_ERROR, "Could not allocate memory while merging " + "InputClass configuration"); + return BadAlloc; + } + } + + classopts = xf86optionListDup(cl->option_lst); + if (idev->commonOptions) + idev->commonOptions = xf86optionListMerge(classopts, + idev->commonOptions); + else + idev->commonOptions = classopts; + } + + return Success; +} + /** * Create a new input device, activate and enable it. * @@ -568,7 +654,8 @@ unwind: } int -NewInputDeviceRequest (InputOption *options, DeviceIntPtr *pdev) +NewInputDeviceRequest (InputOption *options, InputAttributes *attrs, + DeviceIntPtr *pdev) { IDevRec *idev = NULL; InputOption *option = NULL; @@ -635,6 +722,13 @@ NewInputDeviceRequest (InputOption *options, DeviceIntPtr *pdev) option->value = NULL; } + /* Apply InputClass settings */ + if (attrs) { + rval = MergeInputClasses(idev, attrs); + if (rval != Success) + goto unwind; + } + rval = xf86NewInputDevice(idev, pdev, (!is_auto || (is_auto && xf86Info.autoEnableDevices))); if (rval == Success) diff --git a/hw/xfree86/doc/man/xorg.conf.man.pre b/hw/xfree86/doc/man/xorg.conf.man.pre index 7941a470a..5b98bda63 100644 --- a/hw/xfree86/doc/man/xorg.conf.man.pre +++ b/hw/xfree86/doc/man/xorg.conf.man.pre @@ -144,6 +144,7 @@ The section names are: .BR "Module " "Dynamic module loading" .BR "Extensions " "Extension enabling" .BR "InputDevice " "Input device description" +.BR "InputClass " "Input class description" .BR "Device " "Graphics device description" .BR "VideoAdaptor " "Xv video adaptor description" .BR "Monitor " "Monitor description" @@ -914,6 +915,101 @@ may be reattached or set floating at runtime. .TP 7 .BI "Option \*qSendDragEvents\*q \*q" boolean \*q ??? +.SH "INPUTCLASS SECTION" +The config file may have multiple +.B InputClass +sections. +These sections are optional and are used to provide configuration for a +class of input devices as they are automatically added. An input device can +match more than one +.B InputClass +section. Each class can only supplement settings from a previous class, so +it is best to arrange the sections with the most generic matches last. +.PP +.B InputClass +sections have the following format: +.PP +.RS 4 +.nf +.B "Section \*qInputClass\*q" +.BI " Identifier \*q" name \*q +.I " entries" +.I " ..." +.I " options" +.I " ..." +.B "EndSection" +.fi +.RE +.PP +The +.B Identifier +entry is required in all +.B InputClass +sections. +All other entries are optional. +.PP +The +.B Identifier +entry specifies the unique name for this input class. +The +.B Driver +entry specifies the name of the driver to use for this input device. +After all classes have been examined, the +.RI \*q inputdriver \*q +module from the final +.B Driver +entry will be enabled when using the loadable server. +.PP +When an input device is automatically added, its characteristics are +checked against all +.B InputClass +sections. Each section can contain optional entries to narrow the match +of the class. If none of the optional entries appear, the +.B InputClass +section is generic and will match any input device. If more than one of +these entries appear, they all must match for the configuration to apply. +The allowed matching entries are shown below. +.PP +.TP 7 +.BI "MatchProduct \*q" matchproduct \*q +This entry can be used to check if the substring +.RI \*q matchproduct \*q +occurs in the device's product name. +.TP 7 +.BI "MatchVendor \*q" matchvendor \*q +This entry can be used to check if the substring +.RI \*q matchvendor \*q +occurs in the device's vendor name. +.TP 7 +.BI "MatchDevicePath \*q" matchdevice \*q +This entry can be used to check if the device file matches the +.RI \*q matchdevice \*q +pathname pattern. +.TP 7 +.BI "MatchIsKeyboard \*q" bool \*q +.TP 7 +.BI "MatchIsPointer \*q" bool \*q +.TP 7 +.BI "MatchIsJoystick \*q" bool \*q +.TP 7 +.BI "MatchIsTablet \*q" bool \*q +.TP 7 +.BI "MatchIsTouchpad \*q" bool \*q +.TP 7 +.BI "MatchIsTouchscreen \*q" bool \*q +Match device types. These entries take a boolean argument similar to +.B Option +entries. +.PP +When an input device has been matched to the +.B InputClass +section, any +.B Option +entries are applied to the device. See the +.B InputDevice +section above for a description of the various +.B Option +entries. .SH "DEVICE SECTION" The config file may have multiple .B Device diff --git a/hw/xfree86/parser/Configint.h b/hw/xfree86/parser/Configint.h index cdc7be806..03509b397 100644 --- a/hw/xfree86/parser/Configint.h +++ b/hw/xfree86/parser/Configint.h @@ -148,6 +148,8 @@ else\ "The %s keyword requires a number to follow it." #define POSITIVE_INT_MSG \ "The %s keyword requires a positive integer to follow it." +#define BOOL_MSG \ +"The %s keyword requires a boolean to follow it." #define ZAXISMAPPING_MSG \ "The ZAxisMapping keyword requires 2 positive numbers or X or Y to follow it." #define AUTOREPEAT_MSG \ diff --git a/hw/xfree86/parser/InputClass.c b/hw/xfree86/parser/InputClass.c new file mode 100644 index 000000000..1c9816012 --- /dev/null +++ b/hw/xfree86/parser/InputClass.c @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2009 Dan Nicholson + * + * 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 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. + */ + +/* View/edit this file with tab stops set to 4 */ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include "xf86Parser.h" +#include "xf86tokens.h" +#include "Configint.h" + +extern LexRec val; + +static +xf86ConfigSymTabRec InputClassTab[] = +{ + {ENDSECTION, "endsection"}, + {IDENTIFIER, "identifier"}, + {OPTION, "option"}, + {DRIVER, "driver"}, + {MATCH_PRODUCT, "matchproduct"}, + {MATCH_VENDOR, "matchvendor"}, + {MATCH_DEVICE_PATH, "matchdevicepath"}, + {MATCH_IS_KEYBOARD, "matchiskeyboard"}, + {MATCH_IS_POINTER, "matchispointer"}, + {MATCH_IS_JOYSTICK, "matchisjoystick"}, + {MATCH_IS_TABLET, "matchistablet"}, + {MATCH_IS_TOUCHPAD, "matchistouchpad"}, + {MATCH_IS_TOUCHSCREEN, "matchistouchscreen"}, + {-1, ""}, +}; + +#define CLEANUP xf86freeInputClassList + +XF86ConfInputClassPtr +xf86parseInputClassSection(void) +{ + int has_ident = FALSE; + int token; + + parsePrologue(XF86ConfInputClassPtr, XF86ConfInputClassRec) + + while ((token = xf86getToken(InputClassTab)) != ENDSECTION) { + switch (token) { + case COMMENT: + ptr->comment = xf86addComment(ptr->comment, val.str); + break; + case IDENTIFIER: + if (xf86getSubToken(&(ptr->comment)) != STRING) + Error(QUOTE_MSG, "Identifier"); + if (has_ident == TRUE) + Error(MULTIPLE_MSG, "Identifier"); + ptr->identifier = val.str; + has_ident = TRUE; + break; + case DRIVER: + if (xf86getSubToken(&(ptr->comment)) != STRING) + Error(QUOTE_MSG, "Driver"); + if (strcmp(val.str, "keyboard") == 0) + ptr->driver = "kbd"; + else + ptr->driver = val.str; + break; + case OPTION: + ptr->option_lst = xf86parseOption(ptr->option_lst); + break; + case MATCH_PRODUCT: + if (xf86getSubToken(&(ptr->comment)) != STRING) + Error(QUOTE_MSG, "MatchProduct"); + ptr->match_product = val.str; + break; + case MATCH_VENDOR: + if (xf86getSubToken(&(ptr->comment)) != STRING) + Error(QUOTE_MSG, "MatchVendor"); + ptr->match_vendor = val.str; + break; + case MATCH_DEVICE_PATH: + if (xf86getSubToken(&(ptr->comment)) != STRING) + Error(QUOTE_MSG, "MatchDevicePath"); + ptr->match_device = val.str; + break; + case MATCH_IS_KEYBOARD: + if (xf86getSubToken(&(ptr->comment)) != STRING) + Error(QUOTE_MSG, "MatchIsKeyboard"); + ptr->is_keyboard.set = xf86getBoolValue(&ptr->is_keyboard.val, + val.str); + if (!ptr->is_keyboard.set) + Error(BOOL_MSG, "MatchIsKeyboard"); + break; + case MATCH_IS_POINTER: + if (xf86getSubToken(&(ptr->comment)) != STRING) + Error(QUOTE_MSG, "MatchIsPointer"); + ptr->is_pointer.set = xf86getBoolValue(&ptr->is_pointer.val, + val.str); + if (!ptr->is_pointer.set) + Error(BOOL_MSG, "MatchIsPointer"); + break; + case MATCH_IS_JOYSTICK: + if (xf86getSubToken(&(ptr->comment)) != STRING) + Error(QUOTE_MSG, "MatchIsJoystick"); + ptr->is_joystick.set = xf86getBoolValue(&ptr->is_joystick.val, + val.str); + if (!ptr->is_joystick.set) + Error(BOOL_MSG, "MatchIsJoystick"); + break; + case MATCH_IS_TABLET: + if (xf86getSubToken(&(ptr->comment)) != STRING) + Error(QUOTE_MSG, "MatchIsTablet"); + ptr->is_tablet.set = xf86getBoolValue(&ptr->is_tablet.val, + val.str); + if (!ptr->is_tablet.set) + Error(BOOL_MSG, "MatchIsTablet"); + break; + case MATCH_IS_TOUCHPAD: + if (xf86getSubToken(&(ptr->comment)) != STRING) + Error(QUOTE_MSG, "MatchIsTouchpad"); + ptr->is_touchpad.set = xf86getBoolValue(&ptr->is_touchpad.val, + val.str); + if (!ptr->is_touchpad.set) + Error(BOOL_MSG, "MatchIsTouchpad"); + break; + case MATCH_IS_TOUCHSCREEN: + if (xf86getSubToken(&(ptr->comment)) != STRING) + Error(QUOTE_MSG, "MatchIsTouchscreen"); + ptr->is_touchscreen.set = xf86getBoolValue(&ptr->is_touchscreen.val, + val.str); + if (!ptr->is_touchscreen.set) + Error(BOOL_MSG, "MatchIsTouchscreen"); + break; + case EOF_TOKEN: + Error(UNEXPECTED_EOF_MSG, NULL); + break; + default: + Error(INVALID_KEYWORD_MSG, xf86tokenString ()); + break; + } + } + + if (!has_ident) + Error(NO_IDENT_MSG, NULL); + +#ifdef DEBUG + printf("InputClass section parsed\n"); +#endif + + return ptr; +} + +void +xf86printInputClassSection (FILE * cf, XF86ConfInputClassPtr ptr) +{ + while (ptr) { + fprintf(cf, "Section \"InputClass\"\n"); + if (ptr->comment) + fprintf(cf, "%s", ptr->comment); + if (ptr->identifier) + fprintf(cf, "\tIdentifier \"%s\"\n", ptr->identifier); + if (ptr->driver) + fprintf(cf, "\tDriver \"%s\"\n", ptr->driver); + if (ptr->match_product) + fprintf(cf, "\tMatchProduct \"%s\"\n", ptr->match_product); + if (ptr->match_vendor) + fprintf(cf, "\tMatchVendor \"%s\"\n", ptr->match_vendor); + if (ptr->match_device) + fprintf(cf, "\tMatchDevicePath \"%s\"\n", ptr->match_device); + if (ptr->is_keyboard.set) + fprintf(cf, "\tIsKeyboard \"%s\"\n", + ptr->is_keyboard.val ? "yes" : "no"); + if (ptr->is_pointer.set) + fprintf(cf, "\tIsPointer \"%s\"\n", + ptr->is_pointer.val ? "yes" : "no"); + if (ptr->is_joystick.set) + fprintf(cf, "\tIsJoystick \"%s\"\n", + ptr->is_joystick.val ? "yes" : "no"); + if (ptr->is_tablet.set) + fprintf(cf, "\tIsTablet \"%s\"\n", + ptr->is_tablet.val ? "yes" : "no"); + if (ptr->is_touchpad.set) + fprintf(cf, "\tIsTouchpad \"%s\"\n", + ptr->is_touchpad.val ? "yes" : "no"); + if (ptr->is_touchscreen.set) + fprintf(cf, "\tIsTouchscreen \"%s\"\n", + ptr->is_touchscreen.val ? "yes" : "no"); + xf86printOptionList(cf, ptr->option_lst, 1); + fprintf(cf, "EndSection\n\n"); + ptr = ptr->list.next; + } +} + +void +xf86freeInputClassList (XF86ConfInputClassPtr ptr) +{ + XF86ConfInputClassPtr prev; + + while (ptr) { + TestFree(ptr->identifier); + TestFree(ptr->driver); + TestFree(ptr->match_product); + TestFree(ptr->match_vendor); + TestFree(ptr->match_device); + TestFree(ptr->comment); + xf86optionListFree(ptr->option_lst); + + prev = ptr; + ptr = ptr->list.next; + free(prev); + } +} diff --git a/hw/xfree86/parser/Makefile.am b/hw/xfree86/parser/Makefile.am index b8fab2835..49c191f2a 100644 --- a/hw/xfree86/parser/Makefile.am +++ b/hw/xfree86/parser/Makefile.am @@ -13,6 +13,7 @@ INTERNAL_SOURCES= \ Files.c \ Flags.c \ Input.c \ + InputClass.c \ Layout.c \ Module.c \ Video.c \ diff --git a/hw/xfree86/parser/configProcs.h b/hw/xfree86/parser/configProcs.h index 26ba40ebb..7d8a8e53a 100644 --- a/hw/xfree86/parser/configProcs.h +++ b/hw/xfree86/parser/configProcs.h @@ -48,6 +48,10 @@ XF86ConfInputPtr xf86parseInputSection(void); void xf86printInputSection(FILE *f, XF86ConfInputPtr ptr); void xf86freeInputList(XF86ConfInputPtr ptr); int xf86validateInput (XF86ConfigPtr p); +/* InputClass.c */ +XF86ConfInputClassPtr xf86parseInputClassSection(void); +void xf86printInputClassSection(FILE *f, XF86ConfInputClassPtr ptr); +void xf86freeInputClassList(XF86ConfInputClassPtr ptr); /* Layout.c */ XF86ConfLayoutPtr xf86parseLayoutSection(void); void xf86printLayoutSection(FILE *cf, XF86ConfLayoutPtr ptr); diff --git a/hw/xfree86/parser/read.c b/hw/xfree86/parser/read.c index e965d209e..1091be5e5 100644 --- a/hw/xfree86/parser/read.c +++ b/hw/xfree86/parser/read.c @@ -177,6 +177,14 @@ xf86readConfigFile (void) HANDLE_LIST (conf_input_lst, xf86parseInputSection, XF86ConfInputPtr); } + else if (xf86nameCompare(val.str, "inputclass") == 0) + { + free(val.str); + val.str = NULL; + HANDLE_LIST (conf_inputclass_lst, + xf86parseInputClassSection, + XF86ConfInputClassPtr); + } else if (xf86nameCompare (val.str, "module") == 0) { free(val.str); diff --git a/hw/xfree86/parser/scan.c b/hw/xfree86/parser/scan.c index 9f1835085..b80fbfb8f 100644 --- a/hw/xfree86/parser/scan.c +++ b/hw/xfree86/parser/scan.c @@ -1186,3 +1186,33 @@ xf86addComment(char *cur, char *add) return (cur); } + +Bool +xf86getBoolValue(Bool *val, const char *str) +{ + if (!val || !str) + return FALSE; + if (*str == '\0') { + *val = TRUE; + } else { + if (strcmp(str, "1") == 0) + *val = TRUE; + else if (strcmp(str, "on") == 0) + *val = TRUE; + else if (strcmp(str, "true") == 0) + *val = TRUE; + else if (strcmp(str, "yes") == 0) + *val = TRUE; + else if (strcmp(str, "0") == 0) + *val = FALSE; + else if (strcmp(str, "off") == 0) + *val = FALSE; + else if (strcmp(str, "false") == 0) + *val = FALSE; + else if (strcmp(str, "no") == 0) + *val = FALSE; + else + return FALSE; + } + return TRUE; +} diff --git a/hw/xfree86/parser/write.c b/hw/xfree86/parser/write.c index 3b77b9314..083203c05 100644 --- a/hw/xfree86/parser/write.c +++ b/hw/xfree86/parser/write.c @@ -117,6 +117,8 @@ doWriteConfigFile (const char *filename, XF86ConfigPtr cptr) xf86printInputSection (cf, cptr->conf_input_lst); + xf86printInputClassSection (cf, cptr->conf_inputclass_lst); + xf86printVideoAdaptorSection (cf, cptr->conf_videoadaptor_lst); xf86printModesSection (cf, cptr->conf_modes_lst); diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h index 4675d02c7..5e8351fc4 100644 --- a/hw/xfree86/parser/xf86Parser.h +++ b/hw/xfree86/parser/xf86Parser.h @@ -64,6 +64,7 @@ #ifndef _xf86Parser_h_ #define _xf86Parser_h_ +#include <X11/Xdefs.h> #include "xf86Optrec.h" #define HAVE_PARSER_DECLS @@ -330,6 +331,32 @@ typedef struct } XF86ConfInputrefRec, *XF86ConfInputrefPtr; +typedef struct +{ + Bool set; + Bool val; +} +xf86TriState; + +typedef struct +{ + GenericListRec list; + char *identifier; + char *driver; + char *match_product; + char *match_vendor; + char *match_device; + xf86TriState is_keyboard; + xf86TriState is_pointer; + xf86TriState is_joystick; + xf86TriState is_tablet; + xf86TriState is_touchpad; + xf86TriState is_touchscreen; + XF86OptionPtr option_lst; + char *comment; +} +XF86ConfInputClassRec, *XF86ConfInputClassPtr; + /* Values for adj_where */ #define CONF_ADJ_OBSOLETE -1 #define CONF_ADJ_ABSOLUTE 0 @@ -438,6 +465,7 @@ typedef struct XF86ConfDevicePtr conf_device_lst; XF86ConfScreenPtr conf_screen_lst; XF86ConfInputPtr conf_input_lst; + XF86ConfInputClassPtr conf_inputclass_lst; XF86ConfLayoutPtr conf_layout_lst; XF86ConfVendorPtr conf_vendor_lst; XF86ConfDRIPtr conf_dri; @@ -484,5 +512,6 @@ extern _X_EXPORT int xf86itemNotSublist(GenericListPtr list_1, GenericListPtr li extern _X_EXPORT int xf86pathIsAbsolute(const char *path); extern _X_EXPORT int xf86pathIsSafe(const char *path); extern _X_EXPORT char *xf86addComment(char *cur, char *add); +extern _X_EXPORT Bool xf86getBoolValue(Bool *val, const char *str); #endif /* _xf86Parser_h_ */ diff --git a/hw/xfree86/parser/xf86tokens.h b/hw/xfree86/parser/xf86tokens.h index 4c1d38c03..e3a9d716b 100644 --- a/hw/xfree86/parser/xf86tokens.h +++ b/hw/xfree86/parser/xf86tokens.h @@ -273,7 +273,18 @@ typedef enum { /* DRI Tokens */ GROUP, - BUFFERS + BUFFERS, + + /* InputClass Tokens */ + MATCH_PRODUCT, + MATCH_VENDOR, + MATCH_DEVICE_PATH, + MATCH_IS_KEYBOARD, + MATCH_IS_POINTER, + MATCH_IS_JOYSTICK, + MATCH_IS_TABLET, + MATCH_IS_TOUCHPAD, + MATCH_IS_TOUCHSCREEN } ParserTokens; #endif /* _xf86_tokens_h */ diff --git a/hw/xquartz/darwinXinput.c b/hw/xquartz/darwinXinput.c index 8af9fc740..43aea6140 100644 --- a/hw/xquartz/darwinXinput.c +++ b/hw/xquartz/darwinXinput.c @@ -230,7 +230,8 @@ ChangeDeviceControl(ClientPtr client, DeviceIntPtr dev, * */ int -NewInputDeviceRequest(InputOption *options, DeviceIntPtr *pdev) +NewInputDeviceRequest(InputOption *options, InputAttributes *attrs, + DeviceIntPtr *pdev) { DEBUG_LOG("NewInputDeviceRequest(%p, %p)\n", options, pdev); return BadValue; diff --git a/include/dix-config.h.in b/include/dix-config.h.in index 109637115..ab04414f1 100644 --- a/include/dix-config.h.in +++ b/include/dix-config.h.in @@ -231,6 +231,9 @@ /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H +/* Define to 1 if you have the <fnmatch.h> header file. */ +#undef HAVE_FNMATCH_H + /* Have /dev/urandom */ #undef HAVE_URANDOM diff --git a/include/input.h b/include/input.h index afcc006f8..7a6242d08 100644 --- a/include/input.h +++ b/include/input.h @@ -52,6 +52,7 @@ SOFTWARE. #include "screenint.h" #include <X11/Xmd.h> #include <X11/Xproto.h> +#include <stdint.h> #include "window.h" /* for WindowPtr */ #include "xkbrules.h" #include "events.h" @@ -210,6 +211,20 @@ typedef struct _InputOption { struct _InputOption *next; } InputOption; +typedef struct _InputAttributes { + char *product; + char *vendor; + char *device; + uint32_t flags; +} InputAttributes; + +#define ATTR_KEYBOARD (1<<0) +#define ATTR_POINTER (1<<1) +#define ATTR_JOYSTICK (1<<2) +#define ATTR_TABLET (1<<3) +#define ATTR_TOUCHPAD (1<<4) +#define ATTR_TOUCHSCREEN (1<<5) + /* Key has been run through all input processing and events sent to clients. */ #define KEY_PROCESSED 1 /* Key has not been fully processed, no events have been sent. */ @@ -514,6 +529,7 @@ void FixUpEventFromWindow(DeviceIntPtr pDev, /* Implemented by the DDX. */ extern _X_EXPORT int NewInputDeviceRequest( InputOption *options, + InputAttributes *attrs, DeviceIntPtr *dev); extern _X_EXPORT void DeleteInputDeviceRequest( DeviceIntPtr dev); |