From f851244b9298d88c29331ab285c2839d8bee6925 Mon Sep 17 00:00:00 2001 From: marha Date: Thu, 16 Dec 2010 16:13:08 +0000 Subject: xserver libXdmcp git update 16-12-2010 --- xorg-server/hw/xfree86/common/xf86Option.c | 1790 +++++++++--------- xorg-server/hw/xfree86/common/xf86Xinput.c | 2791 ++++++++++++++-------------- xorg-server/hw/xfree86/doc/Makefile.am | 12 +- 3 files changed, 2298 insertions(+), 2295 deletions(-) (limited to 'xorg-server/hw/xfree86') diff --git a/xorg-server/hw/xfree86/common/xf86Option.c b/xorg-server/hw/xfree86/common/xf86Option.c index d7b294a86..16c27e5ee 100644 --- a/xorg-server/hw/xfree86/common/xf86Option.c +++ b/xorg-server/hw/xfree86/common/xf86Option.c @@ -1,895 +1,895 @@ -/* - * Copyright (c) 1998-2003 by The XFree86 Project, Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - * Except as contained in this notice, the name of the copyright holder(s) - * and author(s) shall not be used in advertising or otherwise to promote - * the sale, use or other dealings in this Software without prior written - * authorization from the copyright holder(s) and author(s). - */ - -/* - * Author: David Dawes - * - * This file includes public option handling functions. - */ - -#ifdef HAVE_XORG_CONFIG_H -#include -#endif - -#include -#include -#include -#include "os.h" -#include "xf86.h" -#include "xf86Xinput.h" -#include "xf86Optrec.h" -#include "xf86Parser.h" - -static Bool ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p, - Bool markUsed); - -/* - * xf86CollectOptions collects the options from each of the config file - * sections used by the screen and puts the combined list in pScrn->options. - * This function requires that the following have been initialised: - * - * pScrn->confScreen - * pScrn->Entities[i]->device - * pScrn->display - * pScrn->monitor - * - * The extraOpts parameter may optionally contain a list of additional options - * to include. - * - * The order of precedence for options is: - * - * extraOpts, display, confScreen, monitor, device - */ - -void -xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts) -{ - XF86OptionPtr tmp; - XF86OptionPtr extras = (XF86OptionPtr)extraOpts; - GDevPtr device; - - int i; - - pScrn->options = NULL; - - for (i=pScrn->numEntities - 1; i >= 0; i--) { - device = xf86GetDevFromEntity(pScrn->entityList[i], - pScrn->entityInstanceList[i]); - if (device && device->options) { - tmp = xf86optionListDup(device->options); - if (pScrn->options) - xf86optionListMerge(pScrn->options,tmp); - else - pScrn->options = tmp; - } - } - if (pScrn->monitor->options) { - tmp = xf86optionListDup(pScrn->monitor->options); - if (pScrn->options) - pScrn->options = xf86optionListMerge(pScrn->options, tmp); - else - pScrn->options = tmp; - } - if (pScrn->confScreen->options) { - tmp = xf86optionListDup(pScrn->confScreen->options); - if (pScrn->options) - pScrn->options = xf86optionListMerge(pScrn->options, tmp); - else - pScrn->options = tmp; - } - if (pScrn->display->options) { - tmp = xf86optionListDup(pScrn->display->options); - if (pScrn->options) - pScrn->options = xf86optionListMerge(pScrn->options, tmp); - else - pScrn->options = tmp; - } - if (extras) { - tmp = xf86optionListDup(extras); - if (pScrn->options) - pScrn->options = xf86optionListMerge(pScrn->options, tmp); - else - pScrn->options = tmp; - } -} - -/* - * xf86CollectInputOptions collects extra options for an InputDevice (other - * than those added by the config backend). - * The options are merged into the existing ones and thus take precedence - * over the others. - */ - -void -xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts) -{ - if (defaultOpts) { - XF86OptionPtr tmp =xf86optionListCreate(defaultOpts, -1, 0); - if (pInfo->options) - pInfo->options = xf86optionListMerge(pInfo->options, tmp); - else - pInfo->options = tmp; - } -} - -/** - * Duplicate the option list passed in. The returned pointer will be a newly - * allocated option list and must be freed by the caller. - */ -pointer -xf86OptionListDuplicate(pointer options) -{ - pointer o = NULL; - - while (options) - { - o = xf86AddNewOption(o, xf86OptionName(options), xf86OptionValue(options)); - options = xf86nextOption(options); - } - - return o; -} - - -/* Created for new XInput stuff -- essentially extensions to the parser */ - -static int -LookupIntOption(pointer optlist, const char *name, int deflt, Bool markUsed) -{ - OptionInfoRec o; - - o.name = name; - o.type = OPTV_INTEGER; - if (ParseOptionValue(-1, optlist, &o, markUsed)) - deflt = o.value.num; - return deflt; -} - - -static double -LookupRealOption(pointer optlist, const char *name, double deflt, - Bool markUsed) -{ - OptionInfoRec o; - - o.name = name; - o.type = OPTV_REAL; - if (ParseOptionValue(-1, optlist, &o, markUsed)) - deflt = o.value.realnum; - return deflt; -} - - -static char * -LookupStrOption(pointer optlist, const char *name, char *deflt, Bool markUsed) -{ - OptionInfoRec o; - - o.name = name; - o.type = OPTV_STRING; - if (ParseOptionValue(-1, optlist, &o, markUsed)) - deflt = o.value.str; - if (deflt) - return strdup(deflt); - else - return NULL; -} - - -static int -LookupBoolOption(pointer optlist, const char *name, int deflt, Bool markUsed) -{ - OptionInfoRec o; - - o.name = name; - o.type = OPTV_BOOLEAN; - if (ParseOptionValue(-1, optlist, &o, markUsed)) - deflt = o.value.bool; - return deflt; -} - -static int -LookupPercentOption(pointer optlist, const char *name, double deflt, Bool markUsed) -{ - OptionInfoRec o; - - o.name = name; - o.type = OPTV_PERCENT; - if (ParseOptionValue(-1, optlist, &o, markUsed)) - deflt = o.value.realnum; - return deflt; -} - -/* These xf86Set* functions are intended for use by non-screen specific code */ - -int -xf86SetIntOption(pointer optlist, const char *name, int deflt) -{ - return LookupIntOption(optlist, name, deflt, TRUE); -} - - -double -xf86SetRealOption(pointer optlist, const char *name, double deflt) -{ - return LookupRealOption(optlist, name, deflt, TRUE); -} - - -char * -xf86SetStrOption(pointer optlist, const char *name, char *deflt) -{ - return LookupStrOption(optlist, name, deflt, TRUE); -} - - -int -xf86SetBoolOption(pointer optlist, const char *name, int deflt) -{ - return LookupBoolOption(optlist, name, deflt, TRUE); -} - -double -xf86SetPercentOption(pointer optlist, const char *name, double deflt) -{ - return LookupPercentOption(optlist, name, deflt, TRUE); -} - -/* - * These are like the Set*Option functions, but they don't mark the options - * as used. - */ -int -xf86CheckIntOption(pointer optlist, const char *name, int deflt) -{ - return LookupIntOption(optlist, name, deflt, FALSE); -} - - -double -xf86CheckRealOption(pointer optlist, const char *name, double deflt) -{ - return LookupRealOption(optlist, name, deflt, FALSE); -} - - -char * -xf86CheckStrOption(pointer optlist, const char *name, char *deflt) -{ - return LookupStrOption(optlist, name, deflt, FALSE); -} - - -int -xf86CheckBoolOption(pointer optlist, const char *name, int deflt) -{ - return LookupBoolOption(optlist, name, deflt, FALSE); -} - - -double -xf86CheckPercentOption(pointer optlist, const char *name, double deflt) -{ - return LookupPercentOption(optlist, name, deflt, FALSE); -} -/* - * addNewOption() has the required property of replacing the option value - * if the option is already present. - */ -pointer -xf86ReplaceIntOption(pointer optlist, const char *name, const int val) -{ - char tmp[16]; - sprintf(tmp,"%i",val); - return xf86AddNewOption(optlist,name,tmp); -} - -pointer -xf86ReplaceRealOption(pointer optlist, const char *name, const double val) -{ - char tmp[32]; - snprintf(tmp,32,"%f",val); - return xf86AddNewOption(optlist,name,tmp); -} - -pointer -xf86ReplaceBoolOption(pointer optlist, const char *name, const Bool val) -{ - return xf86AddNewOption(optlist,name,val?"True":"False"); -} - -pointer -xf86ReplacePercentOption(pointer optlist, const char *name, const double val) -{ - char tmp[16]; - sprintf(tmp, "%lf%%", val); - return xf86AddNewOption(optlist,name,tmp); -} - -pointer -xf86ReplaceStrOption(pointer optlist, const char *name, const char* val) -{ - return xf86AddNewOption(optlist,name,val); -} - -pointer -xf86AddNewOption(pointer head, const char *name, const char *val) -{ - /* XXX These should actually be allocated in the parser library. */ - char *tmp = strdup(val); - char *tmp_name = strdup(name); - - return xf86addNewOption(head, tmp_name, tmp); -} - - -pointer -xf86NewOption(char *name, char *value) -{ - return xf86newOption(name, value); -} - - -pointer -xf86NextOption(pointer list) -{ - return xf86nextOption(list); -} - -pointer -xf86OptionListCreate(const char **options, int count, int used) -{ - return xf86optionListCreate(options, count, used); -} - -pointer -xf86OptionListMerge(pointer head, pointer tail) -{ - return xf86optionListMerge(head, tail); -} - -void -xf86OptionListFree(pointer opt) -{ - xf86optionListFree(opt); -} - -char * -xf86OptionName(pointer opt) -{ - return xf86optionName(opt); -} - -char * -xf86OptionValue(pointer opt) -{ - return xf86optionValue(opt); -} - -void -xf86OptionListReport(pointer parm) -{ - XF86OptionPtr opts = parm; - - while(opts) { - if (xf86optionValue(opts)) - xf86ErrorFVerb(5, "\tOption \"%s\" \"%s\"\n", - xf86optionName(opts), xf86optionValue(opts)); - else - xf86ErrorFVerb( 5, "\tOption \"%s\"\n", xf86optionName(opts)); - opts = xf86nextOption(opts); - } -} - -/* End of XInput-caused section */ - -pointer -xf86FindOption(pointer options, const char *name) -{ - return xf86findOption(options, name); -} - - -char * -xf86FindOptionValue(pointer options, const char *name) -{ - return xf86findOptionValue(options, name); -} - - -void -xf86MarkOptionUsed(pointer option) -{ - if (option != NULL) - ((XF86OptionPtr)option)->opt_used = TRUE; -} - - -void -xf86MarkOptionUsedByName(pointer options, const char *name) -{ - XF86OptionPtr opt; - - opt = xf86findOption(options, name); - if (opt != NULL) - opt->opt_used = TRUE; -} - -Bool -xf86CheckIfOptionUsed(pointer option) -{ - if (option != NULL) - return ((XF86OptionPtr)option)->opt_used; - else - return FALSE; -} - -Bool -xf86CheckIfOptionUsedByName(pointer options, const char *name) -{ - XF86OptionPtr opt; - - opt = xf86findOption(options, name); - if (opt != NULL) - return opt->opt_used; - else - return FALSE; -} - -void -xf86ShowUnusedOptions(int scrnIndex, pointer options) -{ - XF86OptionPtr opt = options; - - while (opt) { - if (opt->opt_name && !opt->opt_used) { - xf86DrvMsg(scrnIndex, X_WARNING, "Option \"%s\" is not used\n", - opt->opt_name); - } - opt = opt->list.next; - } -} - - -static Bool -GetBoolValue(OptionInfoPtr p, const char *s) -{ - return xf86getBoolValue(&p->value.bool, s); -} - -static Bool -ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p, - Bool markUsed) -{ - char *s, *end; - Bool wasUsed = FALSE; - - if ((s = xf86findOptionValue(options, p->name)) != NULL) { - if (markUsed) { - wasUsed = xf86CheckIfOptionUsedByName(options, p->name); - xf86MarkOptionUsedByName(options, p->name); - } - switch (p->type) { - case OPTV_INTEGER: - if (*s == '\0') { - xf86DrvMsg(scrnIndex, X_WARNING, - "Option \"%s\" requires an integer value\n", - p->name); - p->found = FALSE; - } else { - p->value.num = strtoul(s, &end, 0); - if (*end == '\0') { - p->found = TRUE; - } else { - xf86DrvMsg(scrnIndex, X_WARNING, - "Option \"%s\" requires an integer value\n", - p->name); - p->found = FALSE; - } - } - break; - case OPTV_STRING: - if (*s == '\0') { - xf86DrvMsg(scrnIndex, X_WARNING, - "Option \"%s\" requires an string value\n", - p->name); - p->found = FALSE; - } else { - p->value.str = s; - p->found = TRUE; - } - break; - case OPTV_ANYSTR: - p->value.str = s; - p->found = TRUE; - break; - case OPTV_REAL: - if (*s == '\0') { - xf86DrvMsg(scrnIndex, X_WARNING, - "Option \"%s\" requires a floating point value\n", - p->name); - p->found = FALSE; - } else { - p->value.realnum = strtod(s, &end); - if (*end == '\0') { - p->found = TRUE; - } else { - xf86DrvMsg(scrnIndex, X_WARNING, - "Option \"%s\" requires a floating point value\n", - p->name); - p->found = FALSE; - } - } - break; - case OPTV_BOOLEAN: - if (GetBoolValue(p, s)) { - p->found = TRUE; - } else { - xf86DrvMsg(scrnIndex, X_WARNING, - "Option \"%s\" requires a boolean value\n", p->name); - p->found = FALSE; - } - break; - case OPTV_PERCENT: - { - char tmp = 0; - /* awkward match, but %% doesn't increase the match counter, - * hence 100 looks the same as 100% to the caller of sccanf - */ - if (sscanf(s, "%lf%c", &p->value.realnum, &tmp) != 2 || tmp != '%') { - xf86DrvMsg(scrnIndex, X_WARNING, - "Option \"%s\" requires a percent value\n", p->name); - p->found = FALSE; - } else { - p->found = TRUE; - } - } - break; - case OPTV_FREQ: - if (*s == '\0') { - xf86DrvMsg(scrnIndex, X_WARNING, - "Option \"%s\" requires a frequency value\n", - p->name); - p->found = FALSE; - } else { - double freq = strtod(s, &end); - int units = 0; - - if (end != s) { - p->found = TRUE; - if (!xf86NameCmp(end, "Hz")) - units = 1; - else if (!xf86NameCmp(end, "kHz") || - !xf86NameCmp(end, "k")) - units = 1000; - else if (!xf86NameCmp(end, "MHz") || - !xf86NameCmp(end, "M")) - units = 1000000; - else { - xf86DrvMsg(scrnIndex, X_WARNING, - "Option \"%s\" requires a frequency value\n", - p->name); - p->found = FALSE; - } - if (p->found) - freq *= (double)units; - } else { - xf86DrvMsg(scrnIndex, X_WARNING, - "Option \"%s\" requires a frequency value\n", - p->name); - p->found = FALSE; - } - if (p->found) { - p->value.freq.freq = freq; - p->value.freq.units = units; - } - } - break; - case OPTV_NONE: - /* Should never get here */ - p->found = FALSE; - break; - } - if (p->found && markUsed) { - int verb = 2; - if (wasUsed) - verb = 4; - xf86DrvMsgVerb(scrnIndex, X_CONFIG, verb, "Option \"%s\"", p->name); - if (!(p->type == OPTV_BOOLEAN && *s == 0)) { - xf86ErrorFVerb(verb, " \"%s\"", s); - } - xf86ErrorFVerb(verb, "\n"); - } - } else if (p->type == OPTV_BOOLEAN) { - /* Look for matches with options with or without a "No" prefix. */ - char *n, *newn; - OptionInfoRec opt; - - n = xf86NormalizeName(p->name); - if (!n) { - p->found = FALSE; - return FALSE; - } - if (strncmp(n, "no", 2) == 0) { - newn = n + 2; - } else { - free(n); - if (asprintf(&n, "No%s", p->name) == -1) { - p->found = FALSE; - return FALSE; - } - newn = n; - } - if ((s = xf86findOptionValue(options, newn)) != NULL) { - if (markUsed) - xf86MarkOptionUsedByName(options, newn); - if (GetBoolValue(&opt, s)) { - p->value.bool = !opt.value.bool; - p->found = TRUE; - } else { - xf86DrvMsg(scrnIndex, X_WARNING, - "Option \"%s\" requires a boolean value\n", newn); - p->found = FALSE; - } - } else { - p->found = FALSE; - } - if (p->found && markUsed) { - xf86DrvMsgVerb(scrnIndex, X_CONFIG, 2, "Option \"%s\"", newn); - if (*s != 0) { - xf86ErrorFVerb(2, " \"%s\"", s); - } - xf86ErrorFVerb(2, "\n"); - } - free(n); - } else { - p->found = FALSE; - } - return p->found; -} - - -void -xf86ProcessOptions(int scrnIndex, pointer options, OptionInfoPtr optinfo) -{ - OptionInfoPtr p; - - for (p = optinfo; p->name != NULL; p++) { - ParseOptionValue(scrnIndex, options, p, TRUE); - } -} - - -OptionInfoPtr -xf86TokenToOptinfo(const OptionInfoRec *table, int token) -{ - const OptionInfoRec *p, *match = NULL, *set = NULL; - - if (!table) { - ErrorF("xf86TokenToOptinfo: table is NULL\n"); - return NULL; - } - - for (p = table; p->token >= 0; p++) { - if (p->token == token) { - match = p; - if (p->found) - set = p; - } - } - - if (set) - return (OptionInfoPtr)set; - else if (match) - return (OptionInfoPtr)match; - else - return NULL; -} - - -const char * -xf86TokenToOptName(const OptionInfoRec *table, int token) -{ - const OptionInfoRec *p; - - p = xf86TokenToOptinfo(table, token); - return p->name; -} - - -Bool -xf86IsOptionSet(const OptionInfoRec *table, int token) -{ - OptionInfoPtr p; - - p = xf86TokenToOptinfo(table, token); - return p && p->found; -} - - -char * -xf86GetOptValString(const OptionInfoRec *table, int token) -{ - OptionInfoPtr p; - - p = xf86TokenToOptinfo(table, token); - if (p && p->found) - return p->value.str; - else - return NULL; -} - - -Bool -xf86GetOptValInteger(const OptionInfoRec *table, int token, int *value) -{ - OptionInfoPtr p; - - p = xf86TokenToOptinfo(table, token); - if (p && p->found) { - *value = p->value.num; - return TRUE; - } else - return FALSE; -} - - -Bool -xf86GetOptValULong(const OptionInfoRec *table, int token, unsigned long *value) -{ - OptionInfoPtr p; - - p = xf86TokenToOptinfo(table, token); - if (p && p->found) { - *value = p->value.num; - return TRUE; - } else - return FALSE; -} - - -Bool -xf86GetOptValReal(const OptionInfoRec *table, int token, double *value) -{ - OptionInfoPtr p; - - p = xf86TokenToOptinfo(table, token); - if (p && p->found) { - *value = p->value.realnum; - return TRUE; - } else - return FALSE; -} - - -Bool -xf86GetOptValFreq(const OptionInfoRec *table, int token, - OptFreqUnits expectedUnits, double *value) -{ - OptionInfoPtr p; - - p = xf86TokenToOptinfo(table, token); - if (p && p->found) { - if (p->value.freq.units > 0) { - /* Units give, so the scaling is known. */ - switch (expectedUnits) { - case OPTUNITS_HZ: - *value = p->value.freq.freq; - break; - case OPTUNITS_KHZ: - *value = p->value.freq.freq / 1000.0; - break; - case OPTUNITS_MHZ: - *value = p->value.freq.freq / 1000000.0; - break; - } - } else { - /* No units given, so try to guess the scaling. */ - switch (expectedUnits) { - case OPTUNITS_HZ: - *value = p->value.freq.freq; - break; - case OPTUNITS_KHZ: - if (p->value.freq.freq > 1000.0) - *value = p->value.freq.freq / 1000.0; - else - *value = p->value.freq.freq; - break; - case OPTUNITS_MHZ: - if (p->value.freq.freq > 1000000.0) - *value = p->value.freq.freq / 1000000.0; - else if (p->value.freq.freq > 1000.0) - *value = p->value.freq.freq / 1000.0; - else - *value = p->value.freq.freq; - } - } - return TRUE; - } else - return FALSE; -} - - -Bool -xf86GetOptValBool(const OptionInfoRec *table, int token, Bool *value) -{ - OptionInfoPtr p; - - p = xf86TokenToOptinfo(table, token); - if (p && p->found) { - *value = p->value.bool; - return TRUE; - } else - return FALSE; -} - - -Bool -xf86ReturnOptValBool(const OptionInfoRec *table, int token, Bool def) -{ - OptionInfoPtr p; - - p = xf86TokenToOptinfo(table, token); - if (p && p->found) { - return p->value.bool; - } else - return def; -} - - -int -xf86NameCmp(const char *s1, const char *s2) -{ - return xf86nameCompare(s1, s2); -} - -char * -xf86NormalizeName(const char *s) -{ - char *ret, *q; - const char *p; - - if (s == NULL) - return NULL; - - ret = malloc(strlen(s) + 1); - for (p = s, q = ret; *p != 0; p++) { - switch (*p) { - case '_': - case ' ': - case '\t': - continue; - default: - if (isupper(*p)) - *q++ = tolower(*p); - else - *q++ = *p; - } - } - *q = '\0'; - return ret; -} +/* + * Copyright (c) 1998-2003 by The XFree86 Project, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + +/* + * Author: David Dawes + * + * This file includes public option handling functions. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include +#endif + +#include +#include +#include +#include "os.h" +#include "xf86.h" +#include "xf86Xinput.h" +#include "xf86Optrec.h" +#include "xf86Parser.h" + +static Bool ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p, + Bool markUsed); + +/* + * xf86CollectOptions collects the options from each of the config file + * sections used by the screen and puts the combined list in pScrn->options. + * This function requires that the following have been initialised: + * + * pScrn->confScreen + * pScrn->Entities[i]->device + * pScrn->display + * pScrn->monitor + * + * The extraOpts parameter may optionally contain a list of additional options + * to include. + * + * The order of precedence for options is: + * + * extraOpts, display, confScreen, monitor, device + */ + +void +xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts) +{ + XF86OptionPtr tmp; + XF86OptionPtr extras = (XF86OptionPtr)extraOpts; + GDevPtr device; + + int i; + + pScrn->options = NULL; + + for (i=pScrn->numEntities - 1; i >= 0; i--) { + device = xf86GetDevFromEntity(pScrn->entityList[i], + pScrn->entityInstanceList[i]); + if (device && device->options) { + tmp = xf86optionListDup(device->options); + if (pScrn->options) + xf86optionListMerge(pScrn->options,tmp); + else + pScrn->options = tmp; + } + } + if (pScrn->monitor->options) { + tmp = xf86optionListDup(pScrn->monitor->options); + if (pScrn->options) + pScrn->options = xf86optionListMerge(pScrn->options, tmp); + else + pScrn->options = tmp; + } + if (pScrn->confScreen->options) { + tmp = xf86optionListDup(pScrn->confScreen->options); + if (pScrn->options) + pScrn->options = xf86optionListMerge(pScrn->options, tmp); + else + pScrn->options = tmp; + } + if (pScrn->display->options) { + tmp = xf86optionListDup(pScrn->display->options); + if (pScrn->options) + pScrn->options = xf86optionListMerge(pScrn->options, tmp); + else + pScrn->options = tmp; + } + if (extras) { + tmp = xf86optionListDup(extras); + if (pScrn->options) + pScrn->options = xf86optionListMerge(pScrn->options, tmp); + else + pScrn->options = tmp; + } +} + +/* + * xf86CollectInputOptions collects extra options for an InputDevice (other + * than those added by the config backend). + * The options are merged into the existing ones and thus take precedence + * over the others. + */ + +void +xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts) +{ + if (defaultOpts) { + XF86OptionPtr tmp =xf86optionListCreate(defaultOpts, -1, 0); + if (pInfo->options) + pInfo->options = xf86optionListMerge(tmp, pInfo->options); + else + pInfo->options = tmp; + } +} + +/** + * Duplicate the option list passed in. The returned pointer will be a newly + * allocated option list and must be freed by the caller. + */ +pointer +xf86OptionListDuplicate(pointer options) +{ + pointer o = NULL; + + while (options) + { + o = xf86AddNewOption(o, xf86OptionName(options), xf86OptionValue(options)); + options = xf86nextOption(options); + } + + return o; +} + + +/* Created for new XInput stuff -- essentially extensions to the parser */ + +static int +LookupIntOption(pointer optlist, const char *name, int deflt, Bool markUsed) +{ + OptionInfoRec o; + + o.name = name; + o.type = OPTV_INTEGER; + if (ParseOptionValue(-1, optlist, &o, markUsed)) + deflt = o.value.num; + return deflt; +} + + +static double +LookupRealOption(pointer optlist, const char *name, double deflt, + Bool markUsed) +{ + OptionInfoRec o; + + o.name = name; + o.type = OPTV_REAL; + if (ParseOptionValue(-1, optlist, &o, markUsed)) + deflt = o.value.realnum; + return deflt; +} + + +static char * +LookupStrOption(pointer optlist, const char *name, char *deflt, Bool markUsed) +{ + OptionInfoRec o; + + o.name = name; + o.type = OPTV_STRING; + if (ParseOptionValue(-1, optlist, &o, markUsed)) + deflt = o.value.str; + if (deflt) + return strdup(deflt); + else + return NULL; +} + + +static int +LookupBoolOption(pointer optlist, const char *name, int deflt, Bool markUsed) +{ + OptionInfoRec o; + + o.name = name; + o.type = OPTV_BOOLEAN; + if (ParseOptionValue(-1, optlist, &o, markUsed)) + deflt = o.value.bool; + return deflt; +} + +static int +LookupPercentOption(pointer optlist, const char *name, double deflt, Bool markUsed) +{ + OptionInfoRec o; + + o.name = name; + o.type = OPTV_PERCENT; + if (ParseOptionValue(-1, optlist, &o, markUsed)) + deflt = o.value.realnum; + return deflt; +} + +/* These xf86Set* functions are intended for use by non-screen specific code */ + +int +xf86SetIntOption(pointer optlist, const char *name, int deflt) +{ + return LookupIntOption(optlist, name, deflt, TRUE); +} + + +double +xf86SetRealOption(pointer optlist, const char *name, double deflt) +{ + return LookupRealOption(optlist, name, deflt, TRUE); +} + + +char * +xf86SetStrOption(pointer optlist, const char *name, char *deflt) +{ + return LookupStrOption(optlist, name, deflt, TRUE); +} + + +int +xf86SetBoolOption(pointer optlist, const char *name, int deflt) +{ + return LookupBoolOption(optlist, name, deflt, TRUE); +} + +double +xf86SetPercentOption(pointer optlist, const char *name, double deflt) +{ + return LookupPercentOption(optlist, name, deflt, TRUE); +} + +/* + * These are like the Set*Option functions, but they don't mark the options + * as used. + */ +int +xf86CheckIntOption(pointer optlist, const char *name, int deflt) +{ + return LookupIntOption(optlist, name, deflt, FALSE); +} + + +double +xf86CheckRealOption(pointer optlist, const char *name, double deflt) +{ + return LookupRealOption(optlist, name, deflt, FALSE); +} + + +char * +xf86CheckStrOption(pointer optlist, const char *name, char *deflt) +{ + return LookupStrOption(optlist, name, deflt, FALSE); +} + + +int +xf86CheckBoolOption(pointer optlist, const char *name, int deflt) +{ + return LookupBoolOption(optlist, name, deflt, FALSE); +} + + +double +xf86CheckPercentOption(pointer optlist, const char *name, double deflt) +{ + return LookupPercentOption(optlist, name, deflt, FALSE); +} +/* + * addNewOption() has the required property of replacing the option value + * if the option is already present. + */ +pointer +xf86ReplaceIntOption(pointer optlist, const char *name, const int val) +{ + char tmp[16]; + sprintf(tmp,"%i",val); + return xf86AddNewOption(optlist,name,tmp); +} + +pointer +xf86ReplaceRealOption(pointer optlist, const char *name, const double val) +{ + char tmp[32]; + snprintf(tmp,32,"%f",val); + return xf86AddNewOption(optlist,name,tmp); +} + +pointer +xf86ReplaceBoolOption(pointer optlist, const char *name, const Bool val) +{ + return xf86AddNewOption(optlist,name,val?"True":"False"); +} + +pointer +xf86ReplacePercentOption(pointer optlist, const char *name, const double val) +{ + char tmp[16]; + sprintf(tmp, "%lf%%", val); + return xf86AddNewOption(optlist,name,tmp); +} + +pointer +xf86ReplaceStrOption(pointer optlist, const char *name, const char* val) +{ + return xf86AddNewOption(optlist,name,val); +} + +pointer +xf86AddNewOption(pointer head, const char *name, const char *val) +{ + /* XXX These should actually be allocated in the parser library. */ + char *tmp = strdup(val); + char *tmp_name = strdup(name); + + return xf86addNewOption(head, tmp_name, tmp); +} + + +pointer +xf86NewOption(char *name, char *value) +{ + return xf86newOption(name, value); +} + + +pointer +xf86NextOption(pointer list) +{ + return xf86nextOption(list); +} + +pointer +xf86OptionListCreate(const char **options, int count, int used) +{ + return xf86optionListCreate(options, count, used); +} + +pointer +xf86OptionListMerge(pointer head, pointer tail) +{ + return xf86optionListMerge(head, tail); +} + +void +xf86OptionListFree(pointer opt) +{ + xf86optionListFree(opt); +} + +char * +xf86OptionName(pointer opt) +{ + return xf86optionName(opt); +} + +char * +xf86OptionValue(pointer opt) +{ + return xf86optionValue(opt); +} + +void +xf86OptionListReport(pointer parm) +{ + XF86OptionPtr opts = parm; + + while(opts) { + if (xf86optionValue(opts)) + xf86ErrorFVerb(5, "\tOption \"%s\" \"%s\"\n", + xf86optionName(opts), xf86optionValue(opts)); + else + xf86ErrorFVerb( 5, "\tOption \"%s\"\n", xf86optionName(opts)); + opts = xf86nextOption(opts); + } +} + +/* End of XInput-caused section */ + +pointer +xf86FindOption(pointer options, const char *name) +{ + return xf86findOption(options, name); +} + + +char * +xf86FindOptionValue(pointer options, const char *name) +{ + return xf86findOptionValue(options, name); +} + + +void +xf86MarkOptionUsed(pointer option) +{ + if (option != NULL) + ((XF86OptionPtr)option)->opt_used = TRUE; +} + + +void +xf86MarkOptionUsedByName(pointer options, const char *name) +{ + XF86OptionPtr opt; + + opt = xf86findOption(options, name); + if (opt != NULL) + opt->opt_used = TRUE; +} + +Bool +xf86CheckIfOptionUsed(pointer option) +{ + if (option != NULL) + return ((XF86OptionPtr)option)->opt_used; + else + return FALSE; +} + +Bool +xf86CheckIfOptionUsedByName(pointer options, const char *name) +{ + XF86OptionPtr opt; + + opt = xf86findOption(options, name); + if (opt != NULL) + return opt->opt_used; + else + return FALSE; +} + +void +xf86ShowUnusedOptions(int scrnIndex, pointer options) +{ + XF86OptionPtr opt = options; + + while (opt) { + if (opt->opt_name && !opt->opt_used) { + xf86DrvMsg(scrnIndex, X_WARNING, "Option \"%s\" is not used\n", + opt->opt_name); + } + opt = opt->list.next; + } +} + + +static Bool +GetBoolValue(OptionInfoPtr p, const char *s) +{ + return xf86getBoolValue(&p->value.bool, s); +} + +static Bool +ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p, + Bool markUsed) +{ + char *s, *end; + Bool wasUsed = FALSE; + + if ((s = xf86findOptionValue(options, p->name)) != NULL) { + if (markUsed) { + wasUsed = xf86CheckIfOptionUsedByName(options, p->name); + xf86MarkOptionUsedByName(options, p->name); + } + switch (p->type) { + case OPTV_INTEGER: + if (*s == '\0') { + xf86DrvMsg(scrnIndex, X_WARNING, + "Option \"%s\" requires an integer value\n", + p->name); + p->found = FALSE; + } else { + p->value.num = strtoul(s, &end, 0); + if (*end == '\0') { + p->found = TRUE; + } else { + xf86DrvMsg(scrnIndex, X_WARNING, + "Option \"%s\" requires an integer value\n", + p->name); + p->found = FALSE; + } + } + break; + case OPTV_STRING: + if (*s == '\0') { + xf86DrvMsg(scrnIndex, X_WARNING, + "Option \"%s\" requires an string value\n", + p->name); + p->found = FALSE; + } else { + p->value.str = s; + p->found = TRUE; + } + break; + case OPTV_ANYSTR: + p->value.str = s; + p->found = TRUE; + break; + case OPTV_REAL: + if (*s == '\0') { + xf86DrvMsg(scrnIndex, X_WARNING, + "Option \"%s\" requires a floating point value\n", + p->name); + p->found = FALSE; + } else { + p->value.realnum = strtod(s, &end); + if (*end == '\0') { + p->found = TRUE; + } else { + xf86DrvMsg(scrnIndex, X_WARNING, + "Option \"%s\" requires a floating point value\n", + p->name); + p->found = FALSE; + } + } + break; + case OPTV_BOOLEAN: + if (GetBoolValue(p, s)) { + p->found = TRUE; + } else { + xf86DrvMsg(scrnIndex, X_WARNING, + "Option \"%s\" requires a boolean value\n", p->name); + p->found = FALSE; + } + break; + case OPTV_PERCENT: + { + char tmp = 0; + /* awkward match, but %% doesn't increase the match counter, + * hence 100 looks the same as 100% to the caller of sccanf + */ + if (sscanf(s, "%lf%c", &p->value.realnum, &tmp) != 2 || tmp != '%') { + xf86DrvMsg(scrnIndex, X_WARNING, + "Option \"%s\" requires a percent value\n", p->name); + p->found = FALSE; + } else { + p->found = TRUE; + } + } + break; + case OPTV_FREQ: + if (*s == '\0') { + xf86DrvMsg(scrnIndex, X_WARNING, + "Option \"%s\" requires a frequency value\n", + p->name); + p->found = FALSE; + } else { + double freq = strtod(s, &end); + int units = 0; + + if (end != s) { + p->found = TRUE; + if (!xf86NameCmp(end, "Hz")) + units = 1; + else if (!xf86NameCmp(end, "kHz") || + !xf86NameCmp(end, "k")) + units = 1000; + else if (!xf86NameCmp(end, "MHz") || + !xf86NameCmp(end, "M")) + units = 1000000; + else { + xf86DrvMsg(scrnIndex, X_WARNING, + "Option \"%s\" requires a frequency value\n", + p->name); + p->found = FALSE; + } + if (p->found) + freq *= (double)units; + } else { + xf86DrvMsg(scrnIndex, X_WARNING, + "Option \"%s\" requires a frequency value\n", + p->name); + p->found = FALSE; + } + if (p->found) { + p->value.freq.freq = freq; + p->value.freq.units = units; + } + } + break; + case OPTV_NONE: + /* Should never get here */ + p->found = FALSE; + break; + } + if (p->found && markUsed) { + int verb = 2; + if (wasUsed) + verb = 4; + xf86DrvMsgVerb(scrnIndex, X_CONFIG, verb, "Option \"%s\"", p->name); + if (!(p->type == OPTV_BOOLEAN && *s == 0)) { + xf86ErrorFVerb(verb, " \"%s\"", s); + } + xf86ErrorFVerb(verb, "\n"); + } + } else if (p->type == OPTV_BOOLEAN) { + /* Look for matches with options with or without a "No" prefix. */ + char *n, *newn; + OptionInfoRec opt; + + n = xf86NormalizeName(p->name); + if (!n) { + p->found = FALSE; + return FALSE; + } + if (strncmp(n, "no", 2) == 0) { + newn = n + 2; + } else { + free(n); + if (asprintf(&n, "No%s", p->name) == -1) { + p->found = FALSE; + return FALSE; + } + newn = n; + } + if ((s = xf86findOptionValue(options, newn)) != NULL) { + if (markUsed) + xf86MarkOptionUsedByName(options, newn); + if (GetBoolValue(&opt, s)) { + p->value.bool = !opt.value.bool; + p->found = TRUE; + } else { + xf86DrvMsg(scrnIndex, X_WARNING, + "Option \"%s\" requires a boolean value\n", newn); + p->found = FALSE; + } + } else { + p->found = FALSE; + } + if (p->found && markUsed) { + xf86DrvMsgVerb(scrnIndex, X_CONFIG, 2, "Option \"%s\"", newn); + if (*s != 0) { + xf86ErrorFVerb(2, " \"%s\"", s); + } + xf86ErrorFVerb(2, "\n"); + } + free(n); + } else { + p->found = FALSE; + } + return p->found; +} + + +void +xf86ProcessOptions(int scrnIndex, pointer options, OptionInfoPtr optinfo) +{ + OptionInfoPtr p; + + for (p = optinfo; p->name != NULL; p++) { + ParseOptionValue(scrnIndex, options, p, TRUE); + } +} + + +OptionInfoPtr +xf86TokenToOptinfo(const OptionInfoRec *table, int token) +{ + const OptionInfoRec *p, *match = NULL, *set = NULL; + + if (!table) { + ErrorF("xf86TokenToOptinfo: table is NULL\n"); + return NULL; + } + + for (p = table; p->token >= 0; p++) { + if (p->token == token) { + match = p; + if (p->found) + set = p; + } + } + + if (set) + return (OptionInfoPtr)set; + else if (match) + return (OptionInfoPtr)match; + else + return NULL; +} + + +const char * +xf86TokenToOptName(const OptionInfoRec *table, int token) +{ + const OptionInfoRec *p; + + p = xf86TokenToOptinfo(table, token); + return p->name; +} + + +Bool +xf86IsOptionSet(const OptionInfoRec *table, int token) +{ + OptionInfoPtr p; + + p = xf86TokenToOptinfo(table, token); + return p && p->found; +} + + +char * +xf86GetOptValString(const OptionInfoRec *table, int token) +{ + OptionInfoPtr p; + + p = xf86TokenToOptinfo(table, token); + if (p && p->found) + return p->value.str; + else + return NULL; +} + + +Bool +xf86GetOptValInteger(const OptionInfoRec *table, int token, int *value) +{ + OptionInfoPtr p; + + p = xf86TokenToOptinfo(table, token); + if (p && p->found) { + *value = p->value.num; + return TRUE; + } else + return FALSE; +} + + +Bool +xf86GetOptValULong(const OptionInfoRec *table, int token, unsigned long *value) +{ + OptionInfoPtr p; + + p = xf86TokenToOptinfo(table, token); + if (p && p->found) { + *value = p->value.num; + return TRUE; + } else + return FALSE; +} + + +Bool +xf86GetOptValReal(const OptionInfoRec *table, int token, double *value) +{ + OptionInfoPtr p; + + p = xf86TokenToOptinfo(table, token); + if (p && p->found) { + *value = p->value.realnum; + return TRUE; + } else + return FALSE; +} + + +Bool +xf86GetOptValFreq(const OptionInfoRec *table, int token, + OptFreqUnits expectedUnits, double *value) +{ + OptionInfoPtr p; + + p = xf86TokenToOptinfo(table, token); + if (p && p->found) { + if (p->value.freq.units > 0) { + /* Units give, so the scaling is known. */ + switch (expectedUnits) { + case OPTUNITS_HZ: + *value = p->value.freq.freq; + break; + case OPTUNITS_KHZ: + *value = p->value.freq.freq / 1000.0; + break; + case OPTUNITS_MHZ: + *value = p->value.freq.freq / 1000000.0; + break; + } + } else { + /* No units given, so try to guess the scaling. */ + switch (expectedUnits) { + case OPTUNITS_HZ: + *value = p->value.freq.freq; + break; + case OPTUNITS_KHZ: + if (p->value.freq.freq > 1000.0) + *value = p->value.freq.freq / 1000.0; + else + *value = p->value.freq.freq; + break; + case OPTUNITS_MHZ: + if (p->value.freq.freq > 1000000.0) + *value = p->value.freq.freq / 1000000.0; + else if (p->value.freq.freq > 1000.0) + *value = p->value.freq.freq / 1000.0; + else + *value = p->value.freq.freq; + } + } + return TRUE; + } else + return FALSE; +} + + +Bool +xf86GetOptValBool(const OptionInfoRec *table, int token, Bool *value) +{ + OptionInfoPtr p; + + p = xf86TokenToOptinfo(table, token); + if (p && p->found) { + *value = p->value.bool; + return TRUE; + } else + return FALSE; +} + + +Bool +xf86ReturnOptValBool(const OptionInfoRec *table, int token, Bool def) +{ + OptionInfoPtr p; + + p = xf86TokenToOptinfo(table, token); + if (p && p->found) { + return p->value.bool; + } else + return def; +} + + +int +xf86NameCmp(const char *s1, const char *s2) +{ + return xf86nameCompare(s1, s2); +} + +char * +xf86NormalizeName(const char *s) +{ + char *ret, *q; + const char *p; + + if (s == NULL) + return NULL; + + ret = malloc(strlen(s) + 1); + for (p = s, q = ret; *p != 0; p++) { + switch (*p) { + case '_': + case ' ': + case '\t': + continue; + default: + if (isupper(*p)) + *q++ = tolower(*p); + else + *q++ = *p; + } + } + *q = '\0'; + return ret; +} diff --git a/xorg-server/hw/xfree86/common/xf86Xinput.c b/xorg-server/hw/xfree86/common/xf86Xinput.c index dad993ec1..b9006ab07 100644 --- a/xorg-server/hw/xfree86/common/xf86Xinput.c +++ b/xorg-server/hw/xfree86/common/xf86Xinput.c @@ -1,1392 +1,1399 @@ -/* - * Copyright 1995-1999 by Frederic Lepied, France. - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Frederic Lepied not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Frederic Lepied makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * FREDERIC LEPIED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL FREDERIC LEPIED BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - * - */ -/* - * Copyright (c) 2000-2002 by The XFree86 Project, Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name of the copyright holder(s) - * and author(s) shall not be used in advertising or otherwise to promote - * the sale, use or other dealings in this Software without prior written - * authorization from the copyright holder(s) and author(s). - */ - -#ifdef HAVE_XORG_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include "xf86.h" -#include "xf86Priv.h" -#include "xf86Config.h" -#include "xf86Xinput.h" -#include "xf86Optrec.h" -#include "mipointer.h" -#include "extinit.h" -#include "loaderProcs.h" - -#include "exevents.h" /* AddInputDevice */ -#include "exglobals.h" -#include "eventstr.h" -#include "inpututils.h" - -#include /* InputClassMatches */ -#ifdef HAVE_FNMATCH_H -#include -#endif -#ifdef HAVE_SYS_UTSNAME_H -#include -#endif - -#include -#include /* for int64_t */ - -#include "mi.h" - -#include /* dix pointer acceleration */ -#include - -#ifdef XFreeXDGA -#include "dgaproc.h" -#endif - -#include "xkbsrv.h" - -/* Valuator verification macro */ -#define XI_VERIFY_VALUATORS(num_valuators) \ - if (num_valuators > MAX_VALUATORS) { \ - xf86Msg(X_ERROR, "%s: num_valuator %d is greater than" \ - " MAX_VALUATORS\n", __FUNCTION__, num_valuators); \ - return; \ - } - -EventListPtr xf86Events = NULL; - -static int -xf86InputDevicePostInit(DeviceIntPtr dev); - -/** - * Eval config and modify DeviceVelocityRec accordingly - */ -static void -ProcessVelocityConfiguration(DeviceIntPtr pDev, char* devname, pointer list, - DeviceVelocityPtr s) -{ - int tempi; - float tempf; - Atom float_prop = XIGetKnownProperty(XATOM_FLOAT); - Atom prop; - - if(!s) - return; - - /* common settings (available via device properties) */ - tempf = xf86SetRealOption(list, "ConstantDeceleration", 1.0); - if (tempf > 1.0) { - xf86Msg(X_CONFIG, "%s: (accel) constant deceleration by %.1f\n", - devname, tempf); - prop = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION); - XIChangeDeviceProperty(pDev, prop, float_prop, 32, - PropModeReplace, 1, &tempf, FALSE); - } - - tempf = xf86SetRealOption(list, "AdaptiveDeceleration", 1.0); - if (tempf > 1.0) { - xf86Msg(X_CONFIG, "%s: (accel) adaptive deceleration by %.1f\n", - devname, tempf); - prop = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION); - XIChangeDeviceProperty(pDev, prop, float_prop, 32, - PropModeReplace, 1, &tempf, FALSE); - } - - /* select profile by number */ - tempi = xf86SetIntOption(list, "AccelerationProfile", - s->statistics.profile_number); - - prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER); - if (XIChangeDeviceProperty(pDev, prop, XA_INTEGER, 32, - PropModeReplace, 1, &tempi, FALSE) == Success) { - xf86Msg(X_CONFIG, "%s: (accel) acceleration profile %i\n", devname, - tempi); - } else { - xf86Msg(X_CONFIG, "%s: (accel) acceleration profile %i is unknown\n", - devname, tempi); - } - - /* set scaling */ - tempf = xf86SetRealOption(list, "ExpectedRate", 0); - prop = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING); - if (tempf > 0) { - tempf = 1000.0 / tempf; - XIChangeDeviceProperty(pDev, prop, float_prop, 32, - PropModeReplace, 1, &tempf, FALSE); - } else { - tempf = xf86SetRealOption(list, "VelocityScale", s->corr_mul); - XIChangeDeviceProperty(pDev, prop, float_prop, 32, - PropModeReplace, 1, &tempf, FALSE); - } - - tempi = xf86SetIntOption(list, "VelocityTrackerCount", -1); - if (tempi > 1) - InitTrackers(s, tempi); - - s->initial_range = xf86SetIntOption(list, "VelocityInitialRange", - s->initial_range); - - s->max_diff = xf86SetRealOption(list, "VelocityAbsDiff", s->max_diff); - - tempf = xf86SetRealOption(list, "VelocityRelDiff", -1); - if (tempf >= 0) { - xf86Msg(X_CONFIG, "%s: (accel) max rel. velocity difference: %.1f%%\n", - devname, tempf*100.0); - s->max_rel_diff = tempf; - } - - /* Configure softening. If const deceleration is used, this is expected - * to provide better subpixel information so we enable - * softening by default only if ConstantDeceleration is not used - */ - s->use_softening = xf86SetBoolOption(list, "Softening", - s->const_acceleration == 1.0); - - s->average_accel = xf86SetBoolOption(list, "AccelerationProfileAveraging", - s->average_accel); - - s->reset_time = xf86SetIntOption(list, "VelocityReset", s->reset_time); -} - -static void -ApplyAccelerationSettings(DeviceIntPtr dev){ - int scheme, i; - DeviceVelocityPtr pVel; - InputInfoPtr pInfo = (InputInfoPtr)dev->public.devicePrivate; - char* schemeStr; - - if (dev->valuator && dev->ptrfeed) { - schemeStr = xf86SetStrOption(pInfo->options, "AccelerationScheme", ""); - - scheme = dev->valuator->accelScheme.number; - - if (!xf86NameCmp(schemeStr, "predictable")) - scheme = PtrAccelPredictable; - - if (!xf86NameCmp(schemeStr, "lightweight")) - scheme = PtrAccelLightweight; - - if (!xf86NameCmp(schemeStr, "none")) - scheme = PtrAccelNoOp; - - /* reinit scheme if needed */ - if (dev->valuator->accelScheme.number != scheme) { - if (dev->valuator->accelScheme.AccelCleanupProc) { - dev->valuator->accelScheme.AccelCleanupProc(dev); - } - - if (InitPointerAccelerationScheme(dev, scheme)) { - xf86Msg(X_CONFIG, "%s: (accel) selected scheme %s/%i\n", - pInfo->name, schemeStr, scheme); - } else { - xf86Msg(X_CONFIG, "%s: (accel) could not init scheme %s\n", - pInfo->name, schemeStr); - scheme = dev->valuator->accelScheme.number; - } - } else { - xf86Msg(X_CONFIG, "%s: (accel) keeping acceleration scheme %i\n", - pInfo->name, scheme); - } - - free(schemeStr); - - /* process special configuration */ - switch (scheme) { - case PtrAccelPredictable: - pVel = GetDevicePredictableAccelData(dev); - ProcessVelocityConfiguration (dev, pInfo->name, pInfo->options, - pVel); - break; - } - - i = xf86SetIntOption(pInfo->options, "AccelerationNumerator", - dev->ptrfeed->ctrl.num); - if (i >= 0) - dev->ptrfeed->ctrl.num = i; - - i = xf86SetIntOption(pInfo->options, "AccelerationDenominator", - dev->ptrfeed->ctrl.den); - if (i > 0) - dev->ptrfeed->ctrl.den = i; - - i = xf86SetIntOption(pInfo->options, "AccelerationThreshold", - dev->ptrfeed->ctrl.threshold); - if (i >= 0) - dev->ptrfeed->ctrl.threshold = i; - - xf86Msg(X_CONFIG, "%s: (accel) acceleration factor: %.3f\n", - pInfo->name, ((float)dev->ptrfeed->ctrl.num)/ - ((float)dev->ptrfeed->ctrl.den)); - xf86Msg(X_CONFIG, "%s: (accel) acceleration threshold: %i\n", - pInfo->name, dev->ptrfeed->ctrl.threshold); - } -} - -/*********************************************************************** - * - * xf86ProcessCommonOptions -- - * - * Process global options. - * - *********************************************************************** - */ -void -xf86ProcessCommonOptions(InputInfoPtr pInfo, - pointer list) -{ - if (xf86SetBoolOption(list, "Floating", 0) || - !xf86SetBoolOption(list, "AlwaysCore", 1) || - !xf86SetBoolOption(list, "SendCoreEvents", 1) || - !xf86SetBoolOption(list, "CorePointer", 1) || - !xf86SetBoolOption(list, "CoreKeyboard", 1)) { - xf86Msg(X_CONFIG, "%s: doesn't report core events\n", pInfo->name); - } else { - pInfo->flags |= XI86_ALWAYS_CORE; - xf86Msg(X_CONFIG, "%s: always reports core events\n", pInfo->name); - } -} - -/*********************************************************************** - * - * xf86ActivateDevice -- - * - * Initialize an input device. - * - * Returns TRUE on success, or FALSE otherwise. - *********************************************************************** - */ -static DeviceIntPtr -xf86ActivateDevice(InputInfoPtr pInfo) -{ - DeviceIntPtr dev; - Atom atom; - - dev = AddInputDevice(serverClient, pInfo->device_control, TRUE); - - if (dev == NULL) - { - xf86Msg(X_ERROR, "Too many input devices. Ignoring %s\n", - pInfo->name); - pInfo->dev = NULL; - return NULL; - } - - atom = MakeAtom(pInfo->type_name, strlen(pInfo->type_name), TRUE); - AssignTypeAndName(dev, atom, pInfo->name); - dev->public.devicePrivate = pInfo; - pInfo->dev = dev; - - dev->coreEvents = pInfo->flags & XI86_ALWAYS_CORE; - dev->type = SLAVE; - dev->spriteInfo->spriteOwner = FALSE; - - dev->config_info = xf86SetStrOption(pInfo->options, "config_info", NULL); - - if (serverGeneration == 1) - xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n", - pInfo->name, pInfo->type_name); - - return dev; -} - -/**************************************************************************** - * - * Caller: ProcXSetDeviceMode - * - * Change the mode of an extension device. - * This function is used to change the mode of a device from reporting - * relative motion to reporting absolute positional information, and - * vice versa. - * The default implementation below is that no such devices are supported. - * - *********************************************************************** - */ - -int -SetDeviceMode (ClientPtr client, DeviceIntPtr dev, int mode) -{ - InputInfoPtr pInfo = (InputInfoPtr)dev->public.devicePrivate; - - if (pInfo->switch_mode) { - return (*pInfo->switch_mode)(client, dev, mode); - } - else - return BadMatch; -} - - -/*********************************************************************** - * - * Caller: ProcXSetDeviceValuators - * - * Set the value of valuators on an extension input device. - * This function is used to set the initial value of valuators on - * those input devices that are capable of reporting either relative - * motion or an absolute position, and allow an initial position to be set. - * The default implementation below is that no such devices are supported. - * - *********************************************************************** - */ - -int -SetDeviceValuators (ClientPtr client, DeviceIntPtr dev, int *valuators, - int first_valuator, int num_valuators) -{ - InputInfoPtr pInfo = (InputInfoPtr) dev->public.devicePrivate; - - if (pInfo->set_device_valuators) - return (*pInfo->set_device_valuators)(pInfo, valuators, first_valuator, - num_valuators); - - return BadMatch; -} - - -/*********************************************************************** - * - * Caller: ProcXChangeDeviceControl - * - * Change the specified device controls on an extension input device. - * - *********************************************************************** - */ - -int -ChangeDeviceControl (ClientPtr client, DeviceIntPtr dev, xDeviceCtl *control) -{ - InputInfoPtr pInfo = (InputInfoPtr)dev->public.devicePrivate; - - if (!pInfo->control_proc) { - switch (control->control) { - case DEVICE_CORE: - return BadMatch; - case DEVICE_RESOLUTION: - case DEVICE_ABS_CALIB: - case DEVICE_ABS_AREA: - case DEVICE_ENABLE: - return Success; - default: - return BadMatch; - } - } - else { - return (*pInfo->control_proc)(pInfo, control); - } -} - -/* - * Get the operating system name from uname and store it statically to avoid - * repeating the system call each time MatchOS is checked. - */ -static const char * -HostOS(void) -{ -#ifdef HAVE_SYS_UTSNAME_H - struct utsname name; - static char host_os[sizeof(name.sysname)] = ""; - - if (*host_os == '\0') { - if (uname(&name) >= 0) - strcpy(host_os, name.sysname); - else { - strncpy(host_os, "unknown", sizeof(host_os)); - host_os[sizeof(host_os)-1] = '\0'; - } - } - return host_os; -#else - return ""; -#endif -} - -static int -match_substring(const char *attr, const char *pattern) -{ - return (strstr(attr, pattern)) ? 0 : -1; -} - -#ifdef HAVE_FNMATCH_H -static int -match_pattern(const char *attr, const char *pattern) -{ - return fnmatch(pattern, attr, 0); -} -#else -#define match_pattern match_substring -#endif - -#ifdef HAVE_FNMATCH_H -static int -match_path_pattern(const char *attr, const char *pattern) -{ - return fnmatch(pattern, attr, FNM_PATHNAME); -} -#else -#define match_path_pattern match_substring -#endif - -/* - * Match an attribute against a list of NULL terminated arrays of patterns. - * If a pattern in each list entry is matched, return TRUE. - */ -static Bool -MatchAttrToken(const char *attr, struct list *patterns, - int (*compare)(const char *attr, const char *pattern)) -{ - const xf86MatchGroup *group; - - /* If there are no patterns, accept the match */ - if (list_is_empty(patterns)) - return TRUE; - - /* If there are patterns but no attribute, reject the match */ - if (!attr) - return FALSE; - - /* - * Otherwise, iterate the list of patterns ensuring each entry has a - * match. Each list entry is a separate Match line of the same type. - */ - list_for_each_entry(group, patterns, entry) { - char * const *cur; - Bool match = FALSE; - - for (cur = group->values; *cur; cur++) - if ((*compare)(attr, *cur) == 0) { - match = TRUE; - break; - } - if (!match) - return FALSE; - } - - /* All the entries in the list matched the attribute */ - return TRUE; -} - -/* - * Classes without any Match statements match all devices. Otherwise, all - * statements must match. - */ -static Bool -InputClassMatches(const XF86ConfInputClassPtr iclass, const InputInfoPtr idev, - const InputAttributes *attrs) -{ - /* MatchProduct substring */ - if (!MatchAttrToken(attrs->product, &iclass->match_product, match_substring)) - return FALSE; - - /* MatchVendor substring */ - if (!MatchAttrToken(attrs->vendor, &iclass->match_vendor, match_substring)) - return FALSE; - - /* MatchDevicePath pattern */ - if (!MatchAttrToken(attrs->device, &iclass->match_device, match_path_pattern)) - return FALSE; - - /* MatchOS case-insensitive string */ - if (!MatchAttrToken(HostOS(), &iclass->match_os, strcasecmp)) - return FALSE; - - /* MatchPnPID pattern */ - if (!MatchAttrToken(attrs->pnp_id, &iclass->match_pnpid, match_pattern)) - return FALSE; - - /* MatchUSBID pattern */ - if (!MatchAttrToken(attrs->usb_id, &iclass->match_usbid, match_pattern)) - return FALSE; - - /* MatchDriver string */ - if (!MatchAttrToken(idev->driver, &iclass->match_driver, strcmp)) - return FALSE; - - /* - * MatchTag string - * See if any of the device's tags match any of the MatchTag tokens. - */ - if (!list_is_empty(&iclass->match_tag)) { - char * const *tag; - Bool match; - - if (!attrs->tags) - return FALSE; - for (tag = attrs->tags, match = FALSE; *tag; tag++) { - if (MatchAttrToken(*tag, &iclass->match_tag, strcmp)) { - match = TRUE; - break; - } - } - if (!match) - return FALSE; - } - - /* MatchIs* booleans */ - 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. Options in each InputClass - * section have more priority than the original device configuration as - * well as any previous InputClass sections. - */ -static int -MergeInputClasses(const InputInfoPtr idev, const InputAttributes *attrs) -{ - XF86ConfInputClassPtr cl; - XF86OptionPtr classopts; - - for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) { - if (!InputClassMatches(cl, idev, attrs)) - continue; - - /* Collect class options and driver settings */ - classopts = xf86optionListDup(cl->option_lst); - if (cl->driver) { - free(idev->driver); - idev->driver = xstrdup(cl->driver); - if (!idev->driver) { - xf86Msg(X_ERROR, "Failed to allocate memory while merging " - "InputClass configuration"); - return BadAlloc; - } - classopts = xf86ReplaceStrOption(classopts, "driver", - idev->driver); - } - - /* Apply options to device with InputClass settings preferred. */ - xf86Msg(X_CONFIG, "%s: Applying InputClass \"%s\"\n", - idev->name, cl->identifier); - idev->options = xf86optionListMerge(idev->options, classopts); - } - - return Success; -} - -/* - * Iterate the list of classes and look for Option "Ignore". Return the - * value of the last matching class and holler when returning TRUE. - */ -static Bool -IgnoreInputClass(const InputInfoPtr idev, const InputAttributes *attrs) -{ - XF86ConfInputClassPtr cl; - Bool ignore = FALSE; - const char *ignore_class; - - for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) { - if (!InputClassMatches(cl, idev, attrs)) - continue; - if (xf86findOption(cl->option_lst, "Ignore")) { - ignore = xf86CheckBoolOption(cl->option_lst, "Ignore", FALSE); - ignore_class = cl->identifier; - } - } - - if (ignore) - xf86Msg(X_CONFIG, "%s: Ignoring device from InputClass \"%s\"\n", - idev->name, ignore_class); - return ignore; -} - -InputInfoPtr -xf86AllocateInput(void) -{ - InputInfoPtr pInfo; - - pInfo = calloc(sizeof(*pInfo), 1); - if (!pInfo) - return NULL; - - pInfo->fd = -1; - pInfo->type_name = "UNKNOWN"; - - return pInfo; -} - -/* Append InputInfoRec to the tail of xf86InputDevs. */ -static void -xf86AddInput(InputDriverPtr drv, InputInfoPtr pInfo) -{ - InputInfoPtr *prev = NULL; - - pInfo->drv = drv; - pInfo->module = DuplicateModule(drv->module, NULL); - - for (prev = &xf86InputDevs; *prev; prev = &(*prev)->next) - ; - - *prev = pInfo; - pInfo->next = NULL; - - xf86CollectInputOptions(pInfo, (const char**)drv->default_options); - xf86ProcessCommonOptions(pInfo, pInfo->options); -} - -/* - * Remove an entry from xf86InputDevs and free all the device's information. - */ -void -xf86DeleteInput(InputInfoPtr pInp, int flags) -{ - /* First check if the inputdev is valid. */ - if (pInp == NULL) - return; - - if (pInp->module) - UnloadModule(pInp->module); - - /* This should *really* be handled in drv->UnInit(dev) call instead, but - * if the driver forgets about it make sure we free it or at least crash - * with flying colors */ - free(pInp->private); - - FreeInputAttributes(pInp->attrs); - - /* Remove the entry from the list. */ - if (pInp == xf86InputDevs) - xf86InputDevs = pInp->next; - else { - InputInfoPtr p = xf86InputDevs; - while (p && p->next != pInp) - p = p->next; - if (p) - p->next = pInp->next; - /* Else the entry wasn't in the xf86InputDevs list (ignore this). */ - } - - free(pInp->driver); - free(pInp->name); - xf86optionListFree(pInp->options); - free(pInp); -} - -/* - * Apply backend-specific initialization. Invoked after ActiveteDevice(), - * i.e. after the driver successfully completed DEVICE_INIT and the device - * is advertised. - * @param dev the device - * @return Success or an error code - */ -static int -xf86InputDevicePostInit(DeviceIntPtr dev) { - ApplyAccelerationSettings(dev); - return Success; -} - -/** - * Create a new input device, activate and enable it. - * - * Possible return codes: - * BadName .. a bad driver name was supplied. - * BadImplementation ... The driver does not have a PreInit function. This - * is a driver bug. - * BadMatch .. device initialization failed. - * BadAlloc .. too many input devices - * - * @param idev The device, already set up with identifier, driver, and the - * options. - * @param pdev Pointer to the new device, if Success was reported. - * @param enable Enable the device after activating it. - * - * @return Success or an error code - */ -_X_INTERNAL int -xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable) -{ - InputDriverPtr drv = NULL; - DeviceIntPtr dev = NULL; - int rval; - - /* Memory leak for every attached device if we don't - * test if the module is already loaded first */ - drv = xf86LookupInputDriver(pInfo->driver); - if (!drv) - if (xf86LoadOneModule(pInfo->driver, NULL)) - drv = xf86LookupInputDriver(pInfo->driver); - if (!drv) { - xf86Msg(X_ERROR, "No input driver matching `%s'\n", pInfo->driver); - rval = BadName; - goto unwind; - } - - if (!drv->PreInit) { - xf86Msg(X_ERROR, - "Input driver `%s' has no PreInit function (ignoring)\n", - drv->driverName); - rval = BadImplementation; - goto unwind; - } - - xf86AddInput(drv, pInfo); - - rval = drv->PreInit(drv, pInfo, 0); - - if (rval != Success) { - xf86Msg(X_ERROR, "PreInit returned %d for \"%s\"\n", rval, pInfo->name); - goto unwind; - } - - if (!(dev = xf86ActivateDevice(pInfo))) - { - rval = BadAlloc; - goto unwind; - } - - rval = ActivateDevice(dev, TRUE); - if (rval != Success) - { - xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", pInfo->name); - RemoveDevice(dev, TRUE); - goto unwind; - } - - rval = xf86InputDevicePostInit(dev); - if (rval != Success) - { - xf86Msg(X_ERROR, "Couldn't post-init device \"%s\"\n", pInfo->name); - RemoveDevice(dev, TRUE); - goto unwind; - } - - /* Enable it if it's properly initialised and we're currently in the VT */ - if (enable && dev->inited && dev->startup && xf86Screens[0]->vtSema) - { - EnableDevice(dev, TRUE); - if (!dev->enabled) - { - xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", pInfo->name); - rval = BadMatch; - goto unwind; - } - /* send enter/leave event, update sprite window */ - CheckMotion(NULL, dev); - } - - *pdev = dev; - return Success; - -unwind: - if(pInfo) { - if(drv && drv->UnInit) - drv->UnInit(drv, pInfo, 0); - else - xf86DeleteInput(pInfo, 0); - } - return rval; -} - -int -NewInputDeviceRequest (InputOption *options, InputAttributes *attrs, - DeviceIntPtr *pdev) -{ - InputInfoPtr pInfo = NULL; - InputOption *option = NULL; - int rval = Success; - int is_auto = 0; - - pInfo = xf86AllocateInput(); - if (!pInfo) - return BadAlloc; - - for (option = options; option; option = option->next) { - if (strcasecmp(option->key, "driver") == 0) { - if (pInfo->driver) { - rval = BadRequest; - goto unwind; - } - pInfo->driver = xstrdup(option->value); - if (!pInfo->driver) { - rval = BadAlloc; - goto unwind; - } - } - - if (strcasecmp(option->key, "name") == 0 || - strcasecmp(option->key, "identifier") == 0) { - if (pInfo->name) { - rval = BadRequest; - goto unwind; - } - pInfo->name = xstrdup(option->value); - if (!pInfo->name) { - rval = BadAlloc; - goto unwind; - } - } - - if (strcmp(option->key, "_source") == 0 && - (strcmp(option->value, "server/hal") == 0 || - strcmp(option->value, "server/udev") == 0)) { - is_auto = 1; - if (!xf86Info.autoAddDevices) { - rval = BadMatch; - goto unwind; - } - } - } - - for (option = options; option; option = option->next) { - /* Steal option key/value strings from the provided list. - * We need those strings, the InputOption list doesn't. */ - pInfo->options = xf86addNewOption(pInfo->options, - option->key, option->value); - option->key = NULL; - option->value = NULL; - } - - /* Apply InputClass settings */ - if (attrs) { - if (IgnoreInputClass(pInfo, attrs)) { - rval = BadIDChoice; - goto unwind; - } - - rval = MergeInputClasses(pInfo, attrs); - if (rval != Success) - goto unwind; - - pInfo->attrs = DuplicateInputAttributes(attrs); - } - - if (!pInfo->driver || !pInfo->name) { - xf86Msg(X_INFO, "No input driver/identifier specified (ignoring)\n"); - rval = BadRequest; - goto unwind; - } - - if (!pInfo->name) { - xf86Msg(X_ERROR, "No device identifier specified (ignoring)\n"); - rval = BadMatch; - goto unwind; - } - - rval = xf86NewInputDevice(pInfo, pdev, - (!is_auto || (is_auto && xf86Info.autoEnableDevices))); - - return rval; - -unwind: - if (is_auto && !xf86Info.autoAddDevices) - xf86Msg(X_INFO, "AutoAddDevices is off - not adding device.\n"); - xf86DeleteInput(pInfo, 0); - return rval; -} - -void -DeleteInputDeviceRequest(DeviceIntPtr pDev) -{ - InputInfoPtr pInfo = (InputInfoPtr) pDev->public.devicePrivate; - InputDriverPtr drv = NULL; - Bool isMaster = IsMaster(pDev); - - if (pInfo) /* need to get these before RemoveDevice */ - drv = pInfo->drv; - - OsBlockSignals(); - RemoveDevice(pDev, TRUE); - - if (!isMaster && pInfo != NULL) - { - if(drv->UnInit) - drv->UnInit(drv, pInfo, 0); - else - xf86DeleteInput(pInfo, 0); - } - OsReleaseSignals(); -} - -/* - * convenient functions to post events - */ - -void -xf86PostMotionEvent(DeviceIntPtr device, - int is_absolute, - int first_valuator, - int num_valuators, - ...) -{ - va_list var; - int i = 0; - ValuatorMask mask; - - XI_VERIFY_VALUATORS(num_valuators); - - valuator_mask_zero(&mask); - va_start(var, num_valuators); - for (i = 0; i < num_valuators; i++) - valuator_mask_set(&mask, first_valuator + i, va_arg(var, int)); - va_end(var); - - xf86PostMotionEventM(device, is_absolute, &mask); -} - -void -xf86PostMotionEventP(DeviceIntPtr device, - int is_absolute, - int first_valuator, - int num_valuators, - const int *valuators) -{ - ValuatorMask mask; - - XI_VERIFY_VALUATORS(num_valuators); - - valuator_mask_set_range(&mask, first_valuator, num_valuators, valuators); - xf86PostMotionEventM(device, is_absolute, &mask); -} - -void -xf86PostMotionEventM(DeviceIntPtr device, - int is_absolute, - const ValuatorMask *mask) -{ - int i = 0, nevents = 0; - DeviceEvent *event; - int flags = 0; - -#if XFreeXDGA - int index; - int dx = 0, dy = 0; -#endif - - if (is_absolute) - flags = POINTER_ABSOLUTE; - else - flags = POINTER_RELATIVE | POINTER_ACCELERATE; - -#if XFreeXDGA - /* The evdev driver may not always send all axes across. */ - if (valuator_mask_isset(mask, 0) || - valuator_mask_isset(mask, 1)) - if (miPointerGetScreen(device)) { - index = miPointerGetScreen(device)->myNum; - if (valuator_mask_isset(mask, 0)) - { - dx = valuator_mask_get(mask, 0); - if (is_absolute) - dx -= device->last.valuators[0]; - } - - if (valuator_mask_isset(mask, 1)) - { - dy = valuator_mask_get(mask, 1); - if (is_absolute) - dy -= device->last.valuators[1]; - } - - if (DGAStealMotionEvent(device, index, dx, dy)) - return; - } -#endif - - nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0, flags, mask); - - for (i = 0; i < nevents; i++) { - event = (DeviceEvent*)((xf86Events + i)->event); - mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event)); - } -} - -void -xf86PostProximityEvent(DeviceIntPtr device, - int is_in, - int first_valuator, - int num_valuators, - ...) -{ - va_list var; - int i; - ValuatorMask mask; - - XI_VERIFY_VALUATORS(num_valuators); - - valuator_mask_zero(&mask); - va_start(var, num_valuators); - for (i = 0; i < num_valuators; i++) - valuator_mask_set(&mask, first_valuator + i, va_arg(var, int)); - va_end(var); - - xf86PostProximityEventM(device, is_in, &mask); -} - -void -xf86PostProximityEventP(DeviceIntPtr device, - int is_in, - int first_valuator, - int num_valuators, - const int *valuators) -{ - ValuatorMask mask; - - XI_VERIFY_VALUATORS(num_valuators); - - valuator_mask_set_range(&mask, first_valuator, num_valuators, valuators); - xf86PostProximityEventM(device, is_in, &mask); -} - -void -xf86PostProximityEventM(DeviceIntPtr device, - int is_in, - const ValuatorMask *mask) -{ - int i, nevents; - - nevents = GetProximityEvents(xf86Events, device, - is_in ? ProximityIn : ProximityOut, mask); - for (i = 0; i < nevents; i++) - mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event)); - -} - -void -xf86PostButtonEvent(DeviceIntPtr device, - int is_absolute, - int button, - int is_down, - int first_valuator, - int num_valuators, - ...) -{ - va_list var; - ValuatorMask mask; - int i = 0; - - XI_VERIFY_VALUATORS(num_valuators); - - valuator_mask_zero(&mask); - - va_start(var, num_valuators); - for (i = 0; i < num_valuators; i++) - valuator_mask_set(&mask, first_valuator + i, va_arg(var, int)); - va_end(var); - - xf86PostButtonEventM(device, is_absolute, button, is_down, &mask); -} - -void -xf86PostButtonEventP(DeviceIntPtr device, - int is_absolute, - int button, - int is_down, - int first_valuator, - int num_valuators, - const int *valuators) -{ - ValuatorMask mask; - - XI_VERIFY_VALUATORS(num_valuators); - - valuator_mask_set_range(&mask, first_valuator, num_valuators, valuators); - xf86PostButtonEventM(device, is_absolute, button, is_down, &mask); -} - -void -xf86PostButtonEventM(DeviceIntPtr device, - int is_absolute, - int button, - int is_down, - const ValuatorMask *mask) -{ - int i = 0, nevents = 0; - int flags = 0; - -#if XFreeXDGA - int index; -#endif - - if (is_absolute) - flags = POINTER_ABSOLUTE; - else - flags = POINTER_RELATIVE | POINTER_ACCELERATE; - -#if XFreeXDGA - if (miPointerGetScreen(device)) { - index = miPointerGetScreen(device)->myNum; - if (DGAStealButtonEvent(device, index, button, is_down)) - return; - } -#endif - - nevents = GetPointerEvents(xf86Events, device, - is_down ? ButtonPress : ButtonRelease, button, - flags, mask); - - for (i = 0; i < nevents; i++) - mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event)); - -} - -void -xf86PostKeyEvent(DeviceIntPtr device, - unsigned int key_code, - int is_down, - int is_absolute, - int first_valuator, - int num_valuators, - ...) -{ - va_list var; - int i = 0; - ValuatorMask mask; - - XI_VERIFY_VALUATORS(num_valuators); - - valuator_mask_zero(&mask); - - va_start(var, num_valuators); - for (i = 0; i < num_valuators; i++) - valuator_mask_set(&mask, first_valuator + i, va_arg(var, int)); - va_end(var); - - xf86PostKeyEventM(device, key_code, is_down, is_absolute, &mask); -} - -void -xf86PostKeyEventP(DeviceIntPtr device, - unsigned int key_code, - int is_down, - int is_absolute, - int first_valuator, - int num_valuators, - const int *valuators) -{ - ValuatorMask mask; - - XI_VERIFY_VALUATORS(num_valuators); - - valuator_mask_set_range(&mask, first_valuator, num_valuators, valuators); - xf86PostKeyEventM(device, key_code, is_down, is_absolute, &mask); -} - -void -xf86PostKeyEventM(DeviceIntPtr device, - unsigned int key_code, - int is_down, - int is_absolute, - const ValuatorMask *mask) -{ - int i = 0, nevents = 0; - - if (is_absolute) { - nevents = GetKeyboardValuatorEvents(xf86Events, device, - is_down ? KeyPress : KeyRelease, - key_code, mask); - } - else { - nevents = GetKeyboardEvents(xf86Events, device, - is_down ? KeyPress : KeyRelease, - key_code); - } - - for (i = 0; i < nevents; i++) - mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event)); -} - -void -xf86PostKeyboardEvent(DeviceIntPtr device, - unsigned int key_code, - int is_down) -{ - ValuatorMask mask; - - valuator_mask_zero(&mask); - xf86PostKeyEventM(device, key_code, is_down, 0, &mask); -} - -InputInfoPtr -xf86FirstLocalDevice(void) -{ - return xf86InputDevs; -} - -/* - * Cx - raw data from touch screen - * to_max - scaled highest dimension - * (remember, this is of rows - 1 because of 0 origin) - * to_min - scaled lowest dimension - * from_max - highest raw value from touch screen calibration - * from_min - lowest raw value from touch screen calibration - * - * This function is the same for X or Y coordinates. - * You may have to reverse the high and low values to compensate for - * different orgins on the touch screen vs X. - * - * e.g. to scale from device coordinates into screen coordinates, call - * xf86ScaleAxis(x, 0, screen_width, dev_min, dev_max); - */ - -int -xf86ScaleAxis(int Cx, - int to_max, - int to_min, - int from_max, - int from_min ) -{ - int X; - int64_t to_width = to_max - to_min; - int64_t from_width = from_max - from_min; - - if (from_width) { - X = (int)(((to_width * (Cx - from_min)) / from_width) + to_min); - } - else { - X = 0; - ErrorF ("Divide by Zero in xf86ScaleAxis\n"); - } - - if (X > to_max) - X = to_max; - if (X < to_min) - X = to_min; - - return X; -} - -/* - * This function checks the given screen against the current screen and - * makes changes if appropriate. It should be called from an XInput driver's - * ReadInput function before any events are posted, if the device is screen - * specific like a touch screen. - */ -void -xf86XInputSetScreen(InputInfoPtr pInfo, - int screen_number, - int x, - int y) -{ - if (miPointerGetScreen(pInfo->dev) != - screenInfo.screens[screen_number]) { - miPointerSetScreen(pInfo->dev, screen_number, x, y); - } -} - - -void -xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval, - int resolution, int min_res, int max_res, int mode) -{ - if (!dev || !dev->valuator) - return; - - InitValuatorAxisStruct(dev, axnum, label, minval, maxval, resolution, min_res, - max_res, mode); -} - -/* - * Set the valuator values to be in synch with dix/event.c - * DefineInitialRootWindow(). - */ -void -xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum) -{ - if (axnum == 0) { - dev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2; - dev->last.valuators[0] = dev->valuator->axisVal[0]; - } - else if (axnum == 1) { - dev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2; - dev->last.valuators[1] = dev->valuator->axisVal[1]; - } -} - - -/** - * Deactivate a device. Call this function from the driver if you receive a - * read error or something else that spoils your day. - * Device will be moved to the off_devices list, but it will still be there - * until you really clean up after it. - * Notifies the client about an inactive device. - * - * @param panic True if device is unrecoverable and needs to be removed. - */ -void -xf86DisableDevice(DeviceIntPtr dev, Bool panic) -{ - if(!panic) - { - DisableDevice(dev, TRUE); - } else - { - SendDevicePresenceEvent(dev->id, DeviceUnrecoverable); - DeleteInputDeviceRequest(dev); - } -} - -/** - * Reactivate a device. Call this function from the driver if you just found - * out that the read error wasn't quite that bad after all. - * Device will be re-activated, and an event sent to the client. - */ -void -xf86EnableDevice(DeviceIntPtr dev) -{ - EnableDevice(dev, TRUE); -} - -/* end of xf86Xinput.c */ +/* + * Copyright 1995-1999 by Frederic Lepied, France. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Frederic Lepied not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Frederic Lepied makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * FREDERIC LEPIED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL FREDERIC LEPIED BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ +/* + * Copyright (c) 2000-2002 by The XFree86 Project, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + +#ifdef HAVE_XORG_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86Config.h" +#include "xf86Xinput.h" +#include "xf86Optrec.h" +#include "mipointer.h" +#include "extinit.h" +#include "loaderProcs.h" + +#include "exevents.h" /* AddInputDevice */ +#include "exglobals.h" +#include "eventstr.h" +#include "inpututils.h" + +#include /* InputClassMatches */ +#ifdef HAVE_FNMATCH_H +#include +#endif +#ifdef HAVE_SYS_UTSNAME_H +#include +#endif + +#include +#include /* for int64_t */ + +#include "mi.h" + +#include /* dix pointer acceleration */ +#include + +#ifdef XFreeXDGA +#include "dgaproc.h" +#endif + +#include "xkbsrv.h" + +/* Valuator verification macro */ +#define XI_VERIFY_VALUATORS(num_valuators) \ + if (num_valuators > MAX_VALUATORS) { \ + xf86Msg(X_ERROR, "%s: num_valuator %d is greater than" \ + " MAX_VALUATORS\n", __FUNCTION__, num_valuators); \ + return; \ + } + +EventListPtr xf86Events = NULL; + +static int +xf86InputDevicePostInit(DeviceIntPtr dev); + +/** + * Eval config and modify DeviceVelocityRec accordingly + */ +static void +ProcessVelocityConfiguration(DeviceIntPtr pDev, char* devname, pointer list, + DeviceVelocityPtr s) +{ + int tempi; + float tempf; + Atom float_prop = XIGetKnownProperty(XATOM_FLOAT); + Atom prop; + + if(!s) + return; + + /* common settings (available via device properties) */ + tempf = xf86SetRealOption(list, "ConstantDeceleration", 1.0); + if (tempf > 1.0) { + xf86Msg(X_CONFIG, "%s: (accel) constant deceleration by %.1f\n", + devname, tempf); + prop = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION); + XIChangeDeviceProperty(pDev, prop, float_prop, 32, + PropModeReplace, 1, &tempf, FALSE); + } + + tempf = xf86SetRealOption(list, "AdaptiveDeceleration", 1.0); + if (tempf > 1.0) { + xf86Msg(X_CONFIG, "%s: (accel) adaptive deceleration by %.1f\n", + devname, tempf); + prop = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION); + XIChangeDeviceProperty(pDev, prop, float_prop, 32, + PropModeReplace, 1, &tempf, FALSE); + } + + /* select profile by number */ + tempi = xf86SetIntOption(list, "AccelerationProfile", + s->statistics.profile_number); + + prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER); + if (XIChangeDeviceProperty(pDev, prop, XA_INTEGER, 32, + PropModeReplace, 1, &tempi, FALSE) == Success) { + xf86Msg(X_CONFIG, "%s: (accel) acceleration profile %i\n", devname, + tempi); + } else { + xf86Msg(X_CONFIG, "%s: (accel) acceleration profile %i is unknown\n", + devname, tempi); + } + + /* set scaling */ + tempf = xf86SetRealOption(list, "ExpectedRate", 0); + prop = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING); + if (tempf > 0) { + tempf = 1000.0 / tempf; + XIChangeDeviceProperty(pDev, prop, float_prop, 32, + PropModeReplace, 1, &tempf, FALSE); + } else { + tempf = xf86SetRealOption(list, "VelocityScale", s->corr_mul); + XIChangeDeviceProperty(pDev, prop, float_prop, 32, + PropModeReplace, 1, &tempf, FALSE); + } + + tempi = xf86SetIntOption(list, "VelocityTrackerCount", -1); + if (tempi > 1) + InitTrackers(s, tempi); + + s->initial_range = xf86SetIntOption(list, "VelocityInitialRange", + s->initial_range); + + s->max_diff = xf86SetRealOption(list, "VelocityAbsDiff", s->max_diff); + + tempf = xf86SetRealOption(list, "VelocityRelDiff", -1); + if (tempf >= 0) { + xf86Msg(X_CONFIG, "%s: (accel) max rel. velocity difference: %.1f%%\n", + devname, tempf*100.0); + s->max_rel_diff = tempf; + } + + /* Configure softening. If const deceleration is used, this is expected + * to provide better subpixel information so we enable + * softening by default only if ConstantDeceleration is not used + */ + s->use_softening = xf86SetBoolOption(list, "Softening", + s->const_acceleration == 1.0); + + s->average_accel = xf86SetBoolOption(list, "AccelerationProfileAveraging", + s->average_accel); + + s->reset_time = xf86SetIntOption(list, "VelocityReset", s->reset_time); +} + +static void +ApplyAccelerationSettings(DeviceIntPtr dev){ + int scheme, i; + DeviceVelocityPtr pVel; + InputInfoPtr pInfo = (InputInfoPtr)dev->public.devicePrivate; + char* schemeStr; + + if (dev->valuator && dev->ptrfeed) { + schemeStr = xf86SetStrOption(pInfo->options, "AccelerationScheme", ""); + + scheme = dev->valuator->accelScheme.number; + + if (!xf86NameCmp(schemeStr, "predictable")) + scheme = PtrAccelPredictable; + + if (!xf86NameCmp(schemeStr, "lightweight")) + scheme = PtrAccelLightweight; + + if (!xf86NameCmp(schemeStr, "none")) + scheme = PtrAccelNoOp; + + /* reinit scheme if needed */ + if (dev->valuator->accelScheme.number != scheme) { + if (dev->valuator->accelScheme.AccelCleanupProc) { + dev->valuator->accelScheme.AccelCleanupProc(dev); + } + + if (InitPointerAccelerationScheme(dev, scheme)) { + xf86Msg(X_CONFIG, "%s: (accel) selected scheme %s/%i\n", + pInfo->name, schemeStr, scheme); + } else { + xf86Msg(X_CONFIG, "%s: (accel) could not init scheme %s\n", + pInfo->name, schemeStr); + scheme = dev->valuator->accelScheme.number; + } + } else { + xf86Msg(X_CONFIG, "%s: (accel) keeping acceleration scheme %i\n", + pInfo->name, scheme); + } + + free(schemeStr); + + /* process special configuration */ + switch (scheme) { + case PtrAccelPredictable: + pVel = GetDevicePredictableAccelData(dev); + ProcessVelocityConfiguration (dev, pInfo->name, pInfo->options, + pVel); + break; + } + + i = xf86SetIntOption(pInfo->options, "AccelerationNumerator", + dev->ptrfeed->ctrl.num); + if (i >= 0) + dev->ptrfeed->ctrl.num = i; + + i = xf86SetIntOption(pInfo->options, "AccelerationDenominator", + dev->ptrfeed->ctrl.den); + if (i > 0) + dev->ptrfeed->ctrl.den = i; + + i = xf86SetIntOption(pInfo->options, "AccelerationThreshold", + dev->ptrfeed->ctrl.threshold); + if (i >= 0) + dev->ptrfeed->ctrl.threshold = i; + + xf86Msg(X_CONFIG, "%s: (accel) acceleration factor: %.3f\n", + pInfo->name, ((float)dev->ptrfeed->ctrl.num)/ + ((float)dev->ptrfeed->ctrl.den)); + xf86Msg(X_CONFIG, "%s: (accel) acceleration threshold: %i\n", + pInfo->name, dev->ptrfeed->ctrl.threshold); + } +} + +/*********************************************************************** + * + * xf86ProcessCommonOptions -- + * + * Process global options. + * + *********************************************************************** + */ +void +xf86ProcessCommonOptions(InputInfoPtr pInfo, + pointer list) +{ + if (xf86SetBoolOption(list, "Floating", 0) || + !xf86SetBoolOption(list, "AlwaysCore", 1) || + !xf86SetBoolOption(list, "SendCoreEvents", 1) || + !xf86SetBoolOption(list, "CorePointer", 1) || + !xf86SetBoolOption(list, "CoreKeyboard", 1)) { + xf86Msg(X_CONFIG, "%s: doesn't report core events\n", pInfo->name); + } else { + pInfo->flags |= XI86_ALWAYS_CORE; + xf86Msg(X_CONFIG, "%s: always reports core events\n", pInfo->name); + } +} + +/*********************************************************************** + * + * xf86ActivateDevice -- + * + * Initialize an input device. + * + * Returns TRUE on success, or FALSE otherwise. + *********************************************************************** + */ +static DeviceIntPtr +xf86ActivateDevice(InputInfoPtr pInfo) +{ + DeviceIntPtr dev; + Atom atom; + + dev = AddInputDevice(serverClient, pInfo->device_control, TRUE); + + if (dev == NULL) + { + xf86Msg(X_ERROR, "Too many input devices. Ignoring %s\n", + pInfo->name); + pInfo->dev = NULL; + return NULL; + } + + atom = MakeAtom(pInfo->type_name, strlen(pInfo->type_name), TRUE); + AssignTypeAndName(dev, atom, pInfo->name); + dev->public.devicePrivate = pInfo; + pInfo->dev = dev; + + dev->coreEvents = pInfo->flags & XI86_ALWAYS_CORE; + dev->type = SLAVE; + dev->spriteInfo->spriteOwner = FALSE; + + dev->config_info = xf86SetStrOption(pInfo->options, "config_info", NULL); + + if (serverGeneration == 1) + xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n", + pInfo->name, pInfo->type_name); + + return dev; +} + +/**************************************************************************** + * + * Caller: ProcXSetDeviceMode + * + * Change the mode of an extension device. + * This function is used to change the mode of a device from reporting + * relative motion to reporting absolute positional information, and + * vice versa. + * The default implementation below is that no such devices are supported. + * + *********************************************************************** + */ + +int +SetDeviceMode (ClientPtr client, DeviceIntPtr dev, int mode) +{ + InputInfoPtr pInfo = (InputInfoPtr)dev->public.devicePrivate; + + if (pInfo->switch_mode) { + return (*pInfo->switch_mode)(client, dev, mode); + } + else + return BadMatch; +} + + +/*********************************************************************** + * + * Caller: ProcXSetDeviceValuators + * + * Set the value of valuators on an extension input device. + * This function is used to set the initial value of valuators on + * those input devices that are capable of reporting either relative + * motion or an absolute position, and allow an initial position to be set. + * The default implementation below is that no such devices are supported. + * + *********************************************************************** + */ + +int +SetDeviceValuators (ClientPtr client, DeviceIntPtr dev, int *valuators, + int first_valuator, int num_valuators) +{ + InputInfoPtr pInfo = (InputInfoPtr) dev->public.devicePrivate; + + if (pInfo->set_device_valuators) + return (*pInfo->set_device_valuators)(pInfo, valuators, first_valuator, + num_valuators); + + return BadMatch; +} + + +/*********************************************************************** + * + * Caller: ProcXChangeDeviceControl + * + * Change the specified device controls on an extension input device. + * + *********************************************************************** + */ + +int +ChangeDeviceControl (ClientPtr client, DeviceIntPtr dev, xDeviceCtl *control) +{ + InputInfoPtr pInfo = (InputInfoPtr)dev->public.devicePrivate; + + if (!pInfo->control_proc) { + switch (control->control) { + case DEVICE_CORE: + return BadMatch; + case DEVICE_RESOLUTION: + case DEVICE_ABS_CALIB: + case DEVICE_ABS_AREA: + case DEVICE_ENABLE: + return Success; + default: + return BadMatch; + } + } + else { + return (*pInfo->control_proc)(pInfo, control); + } +} + +/* + * Get the operating system name from uname and store it statically to avoid + * repeating the system call each time MatchOS is checked. + */ +static const char * +HostOS(void) +{ +#ifdef HAVE_SYS_UTSNAME_H + struct utsname name; + static char host_os[sizeof(name.sysname)] = ""; + + if (*host_os == '\0') { + if (uname(&name) >= 0) + strcpy(host_os, name.sysname); + else { + strncpy(host_os, "unknown", sizeof(host_os)); + host_os[sizeof(host_os)-1] = '\0'; + } + } + return host_os; +#else + return ""; +#endif +} + +static int +match_substring(const char *attr, const char *pattern) +{ + return (strstr(attr, pattern)) ? 0 : -1; +} + +#ifdef HAVE_FNMATCH_H +static int +match_pattern(const char *attr, const char *pattern) +{ + return fnmatch(pattern, attr, 0); +} +#else +#define match_pattern match_substring +#endif + +#ifdef HAVE_FNMATCH_H +static int +match_path_pattern(const char *attr, const char *pattern) +{ + return fnmatch(pattern, attr, FNM_PATHNAME); +} +#else +#define match_path_pattern match_substring +#endif + +/* + * Match an attribute against a list of NULL terminated arrays of patterns. + * If a pattern in each list entry is matched, return TRUE. + */ +static Bool +MatchAttrToken(const char *attr, struct list *patterns, + int (*compare)(const char *attr, const char *pattern)) +{ + const xf86MatchGroup *group; + + /* If there are no patterns, accept the match */ + if (list_is_empty(patterns)) + return TRUE; + + /* If there are patterns but no attribute, reject the match */ + if (!attr) + return FALSE; + + /* + * Otherwise, iterate the list of patterns ensuring each entry has a + * match. Each list entry is a separate Match line of the same type. + */ + list_for_each_entry(group, patterns, entry) { + char * const *cur; + Bool match = FALSE; + + for (cur = group->values; *cur; cur++) + if ((*compare)(attr, *cur) == 0) { + match = TRUE; + break; + } + if (!match) + return FALSE; + } + + /* All the entries in the list matched the attribute */ + return TRUE; +} + +/* + * Classes without any Match statements match all devices. Otherwise, all + * statements must match. + */ +static Bool +InputClassMatches(const XF86ConfInputClassPtr iclass, const InputInfoPtr idev, + const InputAttributes *attrs) +{ + /* MatchProduct substring */ + if (!MatchAttrToken(attrs->product, &iclass->match_product, match_substring)) + return FALSE; + + /* MatchVendor substring */ + if (!MatchAttrToken(attrs->vendor, &iclass->match_vendor, match_substring)) + return FALSE; + + /* MatchDevicePath pattern */ + if (!MatchAttrToken(attrs->device, &iclass->match_device, match_path_pattern)) + return FALSE; + + /* MatchOS case-insensitive string */ + if (!MatchAttrToken(HostOS(), &iclass->match_os, strcasecmp)) + return FALSE; + + /* MatchPnPID pattern */ + if (!MatchAttrToken(attrs->pnp_id, &iclass->match_pnpid, match_pattern)) + return FALSE; + + /* MatchUSBID pattern */ + if (!MatchAttrToken(attrs->usb_id, &iclass->match_usbid, match_pattern)) + return FALSE; + + /* MatchDriver string */ + if (!MatchAttrToken(idev->driver, &iclass->match_driver, strcmp)) + return FALSE; + + /* + * MatchTag string + * See if any of the device's tags match any of the MatchTag tokens. + */ + if (!list_is_empty(&iclass->match_tag)) { + char * const *tag; + Bool match; + + if (!attrs->tags) + return FALSE; + for (tag = attrs->tags, match = FALSE; *tag; tag++) { + if (MatchAttrToken(*tag, &iclass->match_tag, strcmp)) { + match = TRUE; + break; + } + } + if (!match) + return FALSE; + } + + /* MatchIs* booleans */ + 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. Options in each InputClass + * section have more priority than the original device configuration as + * well as any previous InputClass sections. + */ +static int +MergeInputClasses(const InputInfoPtr idev, const InputAttributes *attrs) +{ + XF86ConfInputClassPtr cl; + XF86OptionPtr classopts; + + for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) { + if (!InputClassMatches(cl, idev, attrs)) + continue; + + /* Collect class options and driver settings */ + classopts = xf86optionListDup(cl->option_lst); + if (cl->driver) { + free(idev->driver); + idev->driver = xstrdup(cl->driver); + if (!idev->driver) { + xf86Msg(X_ERROR, "Failed to allocate memory while merging " + "InputClass configuration"); + return BadAlloc; + } + classopts = xf86ReplaceStrOption(classopts, "driver", + idev->driver); + } + + /* Apply options to device with InputClass settings preferred. */ + xf86Msg(X_CONFIG, "%s: Applying InputClass \"%s\"\n", + idev->name, cl->identifier); + idev->options = xf86optionListMerge(idev->options, classopts); + } + + return Success; +} + +/* + * Iterate the list of classes and look for Option "Ignore". Return the + * value of the last matching class and holler when returning TRUE. + */ +static Bool +IgnoreInputClass(const InputInfoPtr idev, const InputAttributes *attrs) +{ + XF86ConfInputClassPtr cl; + Bool ignore = FALSE; + const char *ignore_class; + + for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) { + if (!InputClassMatches(cl, idev, attrs)) + continue; + if (xf86findOption(cl->option_lst, "Ignore")) { + ignore = xf86CheckBoolOption(cl->option_lst, "Ignore", FALSE); + ignore_class = cl->identifier; + } + } + + if (ignore) + xf86Msg(X_CONFIG, "%s: Ignoring device from InputClass \"%s\"\n", + idev->name, ignore_class); + return ignore; +} + +InputInfoPtr +xf86AllocateInput(void) +{ + InputInfoPtr pInfo; + + pInfo = calloc(sizeof(*pInfo), 1); + if (!pInfo) + return NULL; + + pInfo->fd = -1; + pInfo->type_name = "UNKNOWN"; + + return pInfo; +} + +/* Append InputInfoRec to the tail of xf86InputDevs. */ +static void +xf86AddInput(InputDriverPtr drv, InputInfoPtr pInfo) +{ + InputInfoPtr *prev = NULL; + + pInfo->drv = drv; + pInfo->module = DuplicateModule(drv->module, NULL); + + for (prev = &xf86InputDevs; *prev; prev = &(*prev)->next) + ; + + *prev = pInfo; + pInfo->next = NULL; + + xf86CollectInputOptions(pInfo, (const char**)drv->default_options); + xf86OptionListReport(pInfo->options); + xf86ProcessCommonOptions(pInfo, pInfo->options); +} + +/* + * Remove an entry from xf86InputDevs and free all the device's information. + */ +void +xf86DeleteInput(InputInfoPtr pInp, int flags) +{ + /* First check if the inputdev is valid. */ + if (pInp == NULL) + return; + + if (pInp->module) + UnloadModule(pInp->module); + + /* This should *really* be handled in drv->UnInit(dev) call instead, but + * if the driver forgets about it make sure we free it or at least crash + * with flying colors */ + free(pInp->private); + + FreeInputAttributes(pInp->attrs); + + /* Remove the entry from the list. */ + if (pInp == xf86InputDevs) + xf86InputDevs = pInp->next; + else { + InputInfoPtr p = xf86InputDevs; + while (p && p->next != pInp) + p = p->next; + if (p) + p->next = pInp->next; + /* Else the entry wasn't in the xf86InputDevs list (ignore this). */ + } + + free(pInp->driver); + free(pInp->name); + xf86optionListFree(pInp->options); + free(pInp); +} + +/* + * Apply backend-specific initialization. Invoked after ActiveteDevice(), + * i.e. after the driver successfully completed DEVICE_INIT and the device + * is advertised. + * @param dev the device + * @return Success or an error code + */ +static int +xf86InputDevicePostInit(DeviceIntPtr dev) { + ApplyAccelerationSettings(dev); + return Success; +} + +/** + * Create a new input device, activate and enable it. + * + * Possible return codes: + * BadName .. a bad driver name was supplied. + * BadImplementation ... The driver does not have a PreInit function. This + * is a driver bug. + * BadMatch .. device initialization failed. + * BadAlloc .. too many input devices + * + * @param idev The device, already set up with identifier, driver, and the + * options. + * @param pdev Pointer to the new device, if Success was reported. + * @param enable Enable the device after activating it. + * + * @return Success or an error code + */ +_X_INTERNAL int +xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable) +{ + InputDriverPtr drv = NULL; + DeviceIntPtr dev = NULL; + int rval; + + /* Memory leak for every attached device if we don't + * test if the module is already loaded first */ + drv = xf86LookupInputDriver(pInfo->driver); + if (!drv) + if (xf86LoadOneModule(pInfo->driver, NULL)) + drv = xf86LookupInputDriver(pInfo->driver); + if (!drv) { + xf86Msg(X_ERROR, "No input driver matching `%s'\n", pInfo->driver); + rval = BadName; + goto unwind; + } + + if (!drv->PreInit) { + xf86Msg(X_ERROR, + "Input driver `%s' has no PreInit function (ignoring)\n", + drv->driverName); + rval = BadImplementation; + goto unwind; + } + + xf86AddInput(drv, pInfo); + + rval = drv->PreInit(drv, pInfo, 0); + + if (rval != Success) { + xf86Msg(X_ERROR, "PreInit returned %d for \"%s\"\n", rval, pInfo->name); + goto unwind; + } + + if (!(dev = xf86ActivateDevice(pInfo))) + { + rval = BadAlloc; + goto unwind; + } + + rval = ActivateDevice(dev, TRUE); + if (rval != Success) + { + xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", pInfo->name); + RemoveDevice(dev, TRUE); + goto unwind; + } + + rval = xf86InputDevicePostInit(dev); + if (rval != Success) + { + xf86Msg(X_ERROR, "Couldn't post-init device \"%s\"\n", pInfo->name); + RemoveDevice(dev, TRUE); + goto unwind; + } + + /* Enable it if it's properly initialised and we're currently in the VT */ + if (enable && dev->inited && dev->startup && xf86Screens[0]->vtSema) + { + EnableDevice(dev, TRUE); + if (!dev->enabled) + { + xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", pInfo->name); + rval = BadMatch; + goto unwind; + } + /* send enter/leave event, update sprite window */ + CheckMotion(NULL, dev); + } + + *pdev = dev; + return Success; + +unwind: + if(pInfo) { + if(drv && drv->UnInit) + drv->UnInit(drv, pInfo, 0); + else + xf86DeleteInput(pInfo, 0); + } + return rval; +} + +int +NewInputDeviceRequest (InputOption *options, InputAttributes *attrs, + DeviceIntPtr *pdev) +{ + InputInfoPtr pInfo = NULL; + InputOption *option = NULL; + int rval = Success; + int is_auto = 0; + + pInfo = xf86AllocateInput(); + if (!pInfo) + return BadAlloc; + + for (option = options; option; option = option->next) { + if (strcasecmp(option->key, "driver") == 0) { + if (pInfo->driver) { + rval = BadRequest; + goto unwind; + } + pInfo->driver = xstrdup(option->value); + if (!pInfo->driver) { + rval = BadAlloc; + goto unwind; + } + } + + if (strcasecmp(option->key, "name") == 0 || + strcasecmp(option->key, "identifier") == 0) { + if (pInfo->name) { + rval = BadRequest; + goto unwind; + } + pInfo->name = xstrdup(option->value); + if (!pInfo->name) { + rval = BadAlloc; + goto unwind; + } + } + + if (strcmp(option->key, "_source") == 0 && + (strcmp(option->value, "server/hal") == 0 || + strcmp(option->value, "server/udev") == 0)) { + is_auto = 1; + if (!xf86Info.autoAddDevices) { + rval = BadMatch; + goto unwind; + } + } + } + + for (option = options; option; option = option->next) { + /* Steal option key/value strings from the provided list. + * We need those strings, the InputOption list doesn't. */ + pInfo->options = xf86addNewOption(pInfo->options, + option->key, option->value); + option->key = NULL; + option->value = NULL; + } + + /* Apply InputClass settings */ + if (attrs) { + if (IgnoreInputClass(pInfo, attrs)) { + rval = BadIDChoice; + goto unwind; + } + + rval = MergeInputClasses(pInfo, attrs); + if (rval != Success) + goto unwind; + + pInfo->attrs = DuplicateInputAttributes(attrs); + } + + if (!pInfo->driver || !pInfo->name) { + xf86Msg(X_INFO, "No input driver/identifier specified (ignoring)\n"); + rval = BadRequest; + goto unwind; + } + + if (!pInfo->name) { + xf86Msg(X_ERROR, "No device identifier specified (ignoring)\n"); + rval = BadMatch; + goto unwind; + } + + rval = xf86NewInputDevice(pInfo, pdev, + (!is_auto || (is_auto && xf86Info.autoEnableDevices))); + + return rval; + +unwind: + if (is_auto && !xf86Info.autoAddDevices) + xf86Msg(X_INFO, "AutoAddDevices is off - not adding device.\n"); + xf86DeleteInput(pInfo, 0); + return rval; +} + +void +DeleteInputDeviceRequest(DeviceIntPtr pDev) +{ + InputInfoPtr pInfo = (InputInfoPtr) pDev->public.devicePrivate; + InputDriverPtr drv = NULL; + Bool isMaster = IsMaster(pDev); + + if (pInfo) /* need to get these before RemoveDevice */ + drv = pInfo->drv; + + OsBlockSignals(); + RemoveDevice(pDev, TRUE); + + if (!isMaster && pInfo != NULL) + { + if(drv->UnInit) + drv->UnInit(drv, pInfo, 0); + else + xf86DeleteInput(pInfo, 0); + } + OsReleaseSignals(); +} + +/* + * convenient functions to post events + */ + +void +xf86PostMotionEvent(DeviceIntPtr device, + int is_absolute, + int first_valuator, + int num_valuators, + ...) +{ + va_list var; + int i = 0; + ValuatorMask mask; + + XI_VERIFY_VALUATORS(num_valuators); + + valuator_mask_zero(&mask); + va_start(var, num_valuators); + for (i = 0; i < num_valuators; i++) + valuator_mask_set(&mask, first_valuator + i, va_arg(var, int)); + va_end(var); + + xf86PostMotionEventM(device, is_absolute, &mask); +} + +void +xf86PostMotionEventP(DeviceIntPtr device, + int is_absolute, + int first_valuator, + int num_valuators, + const int *valuators) +{ + ValuatorMask mask; + + XI_VERIFY_VALUATORS(num_valuators); + + valuator_mask_set_range(&mask, first_valuator, num_valuators, valuators); + xf86PostMotionEventM(device, is_absolute, &mask); +} + +void +xf86PostMotionEventM(DeviceIntPtr device, + int is_absolute, + const ValuatorMask *mask) +{ + int i = 0, nevents = 0; + DeviceEvent *event; + int flags = 0; + +#if XFreeXDGA + int index; + int dx = 0, dy = 0; +#endif + + if (valuator_mask_num_valuators(mask) > 0) + { + if (is_absolute) + flags = POINTER_ABSOLUTE; + else + flags = POINTER_RELATIVE | POINTER_ACCELERATE; + } + +#if XFreeXDGA + /* The evdev driver may not always send all axes across. */ + if (valuator_mask_isset(mask, 0) || + valuator_mask_isset(mask, 1)) + if (miPointerGetScreen(device)) { + index = miPointerGetScreen(device)->myNum; + if (valuator_mask_isset(mask, 0)) + { + dx = valuator_mask_get(mask, 0); + if (is_absolute) + dx -= device->last.valuators[0]; + } + + if (valuator_mask_isset(mask, 1)) + { + dy = valuator_mask_get(mask, 1); + if (is_absolute) + dy -= device->last.valuators[1]; + } + + if (DGAStealMotionEvent(device, index, dx, dy)) + return; + } +#endif + + nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0, flags, mask); + + for (i = 0; i < nevents; i++) { + event = (DeviceEvent*)((xf86Events + i)->event); + mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event)); + } +} + +void +xf86PostProximityEvent(DeviceIntPtr device, + int is_in, + int first_valuator, + int num_valuators, + ...) +{ + va_list var; + int i; + ValuatorMask mask; + + XI_VERIFY_VALUATORS(num_valuators); + + valuator_mask_zero(&mask); + va_start(var, num_valuators); + for (i = 0; i < num_valuators; i++) + valuator_mask_set(&mask, first_valuator + i, va_arg(var, int)); + va_end(var); + + xf86PostProximityEventM(device, is_in, &mask); +} + +void +xf86PostProximityEventP(DeviceIntPtr device, + int is_in, + int first_valuator, + int num_valuators, + const int *valuators) +{ + ValuatorMask mask; + + XI_VERIFY_VALUATORS(num_valuators); + + valuator_mask_set_range(&mask, first_valuator, num_valuators, valuators); + xf86PostProximityEventM(device, is_in, &mask); +} + +void +xf86PostProximityEventM(DeviceIntPtr device, + int is_in, + const ValuatorMask *mask) +{ + int i, nevents; + + nevents = GetProximityEvents(xf86Events, device, + is_in ? ProximityIn : ProximityOut, mask); + for (i = 0; i < nevents; i++) + mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event)); + +} + +void +xf86PostButtonEvent(DeviceIntPtr device, + int is_absolute, + int button, + int is_down, + int first_valuator, + int num_valuators, + ...) +{ + va_list var; + ValuatorMask mask; + int i = 0; + + XI_VERIFY_VALUATORS(num_valuators); + + valuator_mask_zero(&mask); + + va_start(var, num_valuators); + for (i = 0; i < num_valuators; i++) + valuator_mask_set(&mask, first_valuator + i, va_arg(var, int)); + va_end(var); + + xf86PostButtonEventM(device, is_absolute, button, is_down, &mask); +} + +void +xf86PostButtonEventP(DeviceIntPtr device, + int is_absolute, + int button, + int is_down, + int first_valuator, + int num_valuators, + const int *valuators) +{ + ValuatorMask mask; + + XI_VERIFY_VALUATORS(num_valuators); + + valuator_mask_set_range(&mask, first_valuator, num_valuators, valuators); + xf86PostButtonEventM(device, is_absolute, button, is_down, &mask); +} + +void +xf86PostButtonEventM(DeviceIntPtr device, + int is_absolute, + int button, + int is_down, + const ValuatorMask *mask) +{ + int i = 0, nevents = 0; + int flags = 0; + +#if XFreeXDGA + int index; +#endif + + if (valuator_mask_num_valuators(mask) > 0) + { + if (is_absolute) + flags = POINTER_ABSOLUTE; + else + flags = POINTER_RELATIVE | POINTER_ACCELERATE; + } + +#if XFreeXDGA + if (miPointerGetScreen(device)) { + index = miPointerGetScreen(device)->myNum; + if (DGAStealButtonEvent(device, index, button, is_down)) + return; + } +#endif + + nevents = GetPointerEvents(xf86Events, device, + is_down ? ButtonPress : ButtonRelease, button, + flags, mask); + + for (i = 0; i < nevents; i++) + mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event)); + +} + +void +xf86PostKeyEvent(DeviceIntPtr device, + unsigned int key_code, + int is_down, + int is_absolute, + int first_valuator, + int num_valuators, + ...) +{ + va_list var; + int i = 0; + ValuatorMask mask; + + XI_VERIFY_VALUATORS(num_valuators); + + valuator_mask_zero(&mask); + + va_start(var, num_valuators); + for (i = 0; i < num_valuators; i++) + valuator_mask_set(&mask, first_valuator + i, va_arg(var, int)); + va_end(var); + + xf86PostKeyEventM(device, key_code, is_down, is_absolute, &mask); +} + +void +xf86PostKeyEventP(DeviceIntPtr device, + unsigned int key_code, + int is_down, + int is_absolute, + int first_valuator, + int num_valuators, + const int *valuators) +{ + ValuatorMask mask; + + XI_VERIFY_VALUATORS(num_valuators); + + valuator_mask_set_range(&mask, first_valuator, num_valuators, valuators); + xf86PostKeyEventM(device, key_code, is_down, is_absolute, &mask); +} + +void +xf86PostKeyEventM(DeviceIntPtr device, + unsigned int key_code, + int is_down, + int is_absolute, + const ValuatorMask *mask) +{ + int i = 0, nevents = 0; + + if (is_absolute) { + nevents = GetKeyboardValuatorEvents(xf86Events, device, + is_down ? KeyPress : KeyRelease, + key_code, mask); + } + else { + nevents = GetKeyboardEvents(xf86Events, device, + is_down ? KeyPress : KeyRelease, + key_code); + } + + for (i = 0; i < nevents; i++) + mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event)); +} + +void +xf86PostKeyboardEvent(DeviceIntPtr device, + unsigned int key_code, + int is_down) +{ + ValuatorMask mask; + + valuator_mask_zero(&mask); + xf86PostKeyEventM(device, key_code, is_down, 0, &mask); +} + +InputInfoPtr +xf86FirstLocalDevice(void) +{ + return xf86InputDevs; +} + +/* + * Cx - raw data from touch screen + * to_max - scaled highest dimension + * (remember, this is of rows - 1 because of 0 origin) + * to_min - scaled lowest dimension + * from_max - highest raw value from touch screen calibration + * from_min - lowest raw value from touch screen calibration + * + * This function is the same for X or Y coordinates. + * You may have to reverse the high and low values to compensate for + * different orgins on the touch screen vs X. + * + * e.g. to scale from device coordinates into screen coordinates, call + * xf86ScaleAxis(x, 0, screen_width, dev_min, dev_max); + */ + +int +xf86ScaleAxis(int Cx, + int to_max, + int to_min, + int from_max, + int from_min ) +{ + int X; + int64_t to_width = to_max - to_min; + int64_t from_width = from_max - from_min; + + if (from_width) { + X = (int)(((to_width * (Cx - from_min)) / from_width) + to_min); + } + else { + X = 0; + ErrorF ("Divide by Zero in xf86ScaleAxis\n"); + } + + if (X > to_max) + X = to_max; + if (X < to_min) + X = to_min; + + return X; +} + +/* + * This function checks the given screen against the current screen and + * makes changes if appropriate. It should be called from an XInput driver's + * ReadInput function before any events are posted, if the device is screen + * specific like a touch screen. + */ +void +xf86XInputSetScreen(InputInfoPtr pInfo, + int screen_number, + int x, + int y) +{ + if (miPointerGetScreen(pInfo->dev) != + screenInfo.screens[screen_number]) { + miPointerSetScreen(pInfo->dev, screen_number, x, y); + } +} + + +void +xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval, + int resolution, int min_res, int max_res, int mode) +{ + if (!dev || !dev->valuator) + return; + + InitValuatorAxisStruct(dev, axnum, label, minval, maxval, resolution, min_res, + max_res, mode); +} + +/* + * Set the valuator values to be in synch with dix/event.c + * DefineInitialRootWindow(). + */ +void +xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum) +{ + if (axnum == 0) { + dev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2; + dev->last.valuators[0] = dev->valuator->axisVal[0]; + } + else if (axnum == 1) { + dev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2; + dev->last.valuators[1] = dev->valuator->axisVal[1]; + } +} + + +/** + * Deactivate a device. Call this function from the driver if you receive a + * read error or something else that spoils your day. + * Device will be moved to the off_devices list, but it will still be there + * until you really clean up after it. + * Notifies the client about an inactive device. + * + * @param panic True if device is unrecoverable and needs to be removed. + */ +void +xf86DisableDevice(DeviceIntPtr dev, Bool panic) +{ + if(!panic) + { + DisableDevice(dev, TRUE); + } else + { + SendDevicePresenceEvent(dev->id, DeviceUnrecoverable); + DeleteInputDeviceRequest(dev); + } +} + +/** + * Reactivate a device. Call this function from the driver if you just found + * out that the read error wasn't quite that bad after all. + * Device will be re-activated, and an event sent to the client. + */ +void +xf86EnableDevice(DeviceIntPtr dev) +{ + EnableDevice(dev, TRUE); +} + +/* end of xf86Xinput.c */ diff --git a/xorg-server/hw/xfree86/doc/Makefile.am b/xorg-server/hw/xfree86/doc/Makefile.am index a8cbc3c6b..80217365d 100644 --- a/xorg-server/hw/xfree86/doc/Makefile.am +++ b/xorg-server/hw/xfree86/doc/Makefile.am @@ -1,8 +1,4 @@ -if BUILDDOCS -SUBDIRS = devel man sgml -else -SUBDIRS = man -endif - -EXTRA_DIST = \ - README.modes +SUBDIRS = devel man sgml + +EXTRA_DIST = \ + README.modes -- cgit v1.2.3