xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

xf86Option.c (24405B)


      1 /*
      2  * Copyright (c) 1998-2003 by The XFree86 Project, Inc.
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice shall be included in
     12  * all copies or substantial portions of the Software.
     13  *
     14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20  * OTHER DEALINGS IN THE SOFTWARE.
     21  *
     22  * Except as contained in this notice, the name of the copyright holder(s)
     23  * and author(s) shall not be used in advertising or otherwise to promote
     24  * the sale, use or other dealings in this Software without prior written
     25  * authorization from the copyright holder(s) and author(s).
     26  */
     27 
     28 /*
     29  * Author: David Dawes <dawes@xfree86.org>
     30  *
     31  * This file includes public option handling functions.
     32  */
     33 
     34 #ifdef HAVE_XORG_CONFIG_H
     35 #include <xorg-config.h>
     36 #endif
     37 
     38 #include <stdlib.h>
     39 #include <ctype.h>
     40 #include <X11/X.h>
     41 #include "os.h"
     42 #include "xf86.h"
     43 #include "xf86Opt.h"
     44 #include "xf86Xinput.h"
     45 #include "xf86Optrec.h"
     46 #include "xf86Parser.h"
     47 #include "xf86platformBus.h" /* For OutputClass functions */
     48 #include "optionstr.h"
     49 
     50 static Bool ParseOptionValue(int scrnIndex, XF86OptionPtr options,
     51                              OptionInfoPtr p, Bool markUsed);
     52 
     53 /*
     54  * xf86CollectOptions collects the options from each of the config file
     55  * sections used by the screen and puts the combined list in pScrn->options.
     56  * This function requires that the following have been initialised:
     57  *
     58  *	pScrn->confScreen
     59  *	pScrn->Entities[i]->device
     60  *	pScrn->display
     61  *	pScrn->monitor
     62  *
     63  * The extraOpts parameter may optionally contain a list of additional options
     64  * to include.
     65  *
     66  * The order of precedence for options is:
     67  *
     68  *   extraOpts, display, confScreen, monitor, device, outputClassOptions
     69  */
     70 
     71 void
     72 xf86CollectOptions(ScrnInfoPtr pScrn, XF86OptionPtr extraOpts)
     73 {
     74     XF86OptionPtr tmp;
     75     XF86OptionPtr extras = (XF86OptionPtr) extraOpts;
     76     GDevPtr device;
     77 
     78     int i;
     79 
     80     pScrn->options = NULL;
     81 
     82     for (i = pScrn->numEntities - 1; i >= 0; i--) {
     83         xf86MergeOutputClassOptions(pScrn->entityList[i], &pScrn->options);
     84 
     85         device = xf86GetDevFromEntity(pScrn->entityList[i],
     86                                       pScrn->entityInstanceList[i]);
     87         if (device && device->options) {
     88             tmp = xf86optionListDup(device->options);
     89             if (pScrn->options)
     90                 pScrn->options = xf86optionListMerge(pScrn->options, tmp);
     91             else
     92                 pScrn->options = tmp;
     93         }
     94     }
     95     if (pScrn->monitor->options) {
     96         tmp = xf86optionListDup(pScrn->monitor->options);
     97         if (pScrn->options)
     98             pScrn->options = xf86optionListMerge(pScrn->options, tmp);
     99         else
    100             pScrn->options = tmp;
    101     }
    102     if (pScrn->confScreen->options) {
    103         tmp = xf86optionListDup(pScrn->confScreen->options);
    104         if (pScrn->options)
    105             pScrn->options = xf86optionListMerge(pScrn->options, tmp);
    106         else
    107             pScrn->options = tmp;
    108     }
    109     if (pScrn->display->options) {
    110         tmp = xf86optionListDup(pScrn->display->options);
    111         if (pScrn->options)
    112             pScrn->options = xf86optionListMerge(pScrn->options, tmp);
    113         else
    114             pScrn->options = tmp;
    115     }
    116     if (extras) {
    117         tmp = xf86optionListDup(extras);
    118         if (pScrn->options)
    119             pScrn->options = xf86optionListMerge(pScrn->options, tmp);
    120         else
    121             pScrn->options = tmp;
    122     }
    123 }
    124 
    125 /*
    126  * xf86CollectInputOptions collects extra options for an InputDevice (other
    127  * than those added by the config backend).
    128  * The options are merged into the existing ones and thus take precedence
    129  * over the others.
    130  */
    131 
    132 void
    133 xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts)
    134 {
    135     if (defaultOpts) {
    136         XF86OptionPtr tmp = xf86optionListCreate(defaultOpts, -1, 0);
    137 
    138         if (pInfo->options)
    139             pInfo->options = xf86optionListMerge(tmp, pInfo->options);
    140         else
    141             pInfo->options = tmp;
    142     }
    143 }
    144 
    145 /**
    146  * Duplicate the option list passed in. The returned pointer will be a newly
    147  * allocated option list and must be freed by the caller.
    148  */
    149 XF86OptionPtr
    150 xf86OptionListDuplicate(XF86OptionPtr options)
    151 {
    152     XF86OptionPtr o = NULL;
    153 
    154     while (options) {
    155         o = xf86AddNewOption(o, xf86OptionName(options),
    156                              xf86OptionValue(options));
    157         options = xf86nextOption(options);
    158     }
    159 
    160     return o;
    161 }
    162 
    163 /* Created for new XInput stuff -- essentially extensions to the parser	*/
    164 
    165 static int
    166 LookupIntOption(XF86OptionPtr optlist, const char *name, int deflt,
    167                 Bool markUsed)
    168 {
    169     OptionInfoRec o;
    170 
    171     o.name = name;
    172     o.type = OPTV_INTEGER;
    173     if (ParseOptionValue(-1, optlist, &o, markUsed))
    174         deflt = o.value.num;
    175     return deflt;
    176 }
    177 
    178 static double
    179 LookupRealOption(XF86OptionPtr optlist, const char *name, double deflt,
    180                  Bool markUsed)
    181 {
    182     OptionInfoRec o;
    183 
    184     o.name = name;
    185     o.type = OPTV_REAL;
    186     if (ParseOptionValue(-1, optlist, &o, markUsed))
    187         deflt = o.value.realnum;
    188     return deflt;
    189 }
    190 
    191 static char *
    192 LookupStrOption(XF86OptionPtr optlist, const char *name, const char *deflt,
    193                 Bool markUsed)
    194 {
    195     OptionInfoRec o;
    196 
    197     o.name = name;
    198     o.type = OPTV_STRING;
    199     if (ParseOptionValue(-1, optlist, &o, markUsed))
    200         deflt = o.value.str;
    201     if (deflt)
    202         return strdup(deflt);
    203     else
    204         return NULL;
    205 }
    206 
    207 static int
    208 LookupBoolOption(XF86OptionPtr optlist, const char *name, int deflt,
    209                  Bool markUsed)
    210 {
    211     OptionInfoRec o;
    212 
    213     o.name = name;
    214     o.type = OPTV_BOOLEAN;
    215     if (ParseOptionValue(-1, optlist, &o, markUsed))
    216         deflt = o.value.boolean;
    217     return deflt;
    218 }
    219 
    220 static double
    221 LookupPercentOption(XF86OptionPtr optlist, const char *name, double deflt,
    222                     Bool markUsed)
    223 {
    224     OptionInfoRec o;
    225 
    226     o.name = name;
    227     o.type = OPTV_PERCENT;
    228     if (ParseOptionValue(-1, optlist, &o, markUsed))
    229         deflt = o.value.realnum;
    230     return deflt;
    231 }
    232 
    233 /* These xf86Set* functions are intended for use by non-screen specific code */
    234 
    235 int
    236 xf86SetIntOption(XF86OptionPtr optlist, const char *name, int deflt)
    237 {
    238     return LookupIntOption(optlist, name, deflt, TRUE);
    239 }
    240 
    241 double
    242 xf86SetRealOption(XF86OptionPtr optlist, const char *name, double deflt)
    243 {
    244     return LookupRealOption(optlist, name, deflt, TRUE);
    245 }
    246 
    247 char *
    248 xf86SetStrOption(XF86OptionPtr optlist, const char *name, const char *deflt)
    249 {
    250     return LookupStrOption(optlist, name, deflt, TRUE);
    251 }
    252 
    253 int
    254 xf86SetBoolOption(XF86OptionPtr optlist, const char *name, int deflt)
    255 {
    256     return LookupBoolOption(optlist, name, deflt, TRUE);
    257 }
    258 
    259 double
    260 xf86SetPercentOption(XF86OptionPtr optlist, const char *name, double deflt)
    261 {
    262     return LookupPercentOption(optlist, name, deflt, TRUE);
    263 }
    264 
    265 /*
    266  * These are like the Set*Option functions, but they don't mark the options
    267  * as used.
    268  */
    269 int
    270 xf86CheckIntOption(XF86OptionPtr optlist, const char *name, int deflt)
    271 {
    272     return LookupIntOption(optlist, name, deflt, FALSE);
    273 }
    274 
    275 double
    276 xf86CheckRealOption(XF86OptionPtr optlist, const char *name, double deflt)
    277 {
    278     return LookupRealOption(optlist, name, deflt, FALSE);
    279 }
    280 
    281 char *
    282 xf86CheckStrOption(XF86OptionPtr optlist, const char *name, const char *deflt)
    283 {
    284     return LookupStrOption(optlist, name, deflt, FALSE);
    285 }
    286 
    287 int
    288 xf86CheckBoolOption(XF86OptionPtr optlist, const char *name, int deflt)
    289 {
    290     return LookupBoolOption(optlist, name, deflt, FALSE);
    291 }
    292 
    293 double
    294 xf86CheckPercentOption(XF86OptionPtr optlist, const char *name, double deflt)
    295 {
    296     return LookupPercentOption(optlist, name, deflt, FALSE);
    297 }
    298 
    299 /*
    300  * xf86AddNewOption() has the required property of replacing the option value
    301  * if the option is already present.
    302  */
    303 XF86OptionPtr
    304 xf86ReplaceIntOption(XF86OptionPtr optlist, const char *name, const int val)
    305 {
    306     char tmp[16];
    307 
    308     snprintf(tmp, sizeof(tmp), "%i", val);
    309     return xf86AddNewOption(optlist, name, tmp);
    310 }
    311 
    312 XF86OptionPtr
    313 xf86ReplaceRealOption(XF86OptionPtr optlist, const char *name, const double val)
    314 {
    315     char tmp[32];
    316 
    317     snprintf(tmp, sizeof(tmp), "%f", val);
    318     return xf86AddNewOption(optlist, name, tmp);
    319 }
    320 
    321 XF86OptionPtr
    322 xf86ReplaceBoolOption(XF86OptionPtr optlist, const char *name, const Bool val)
    323 {
    324     return xf86AddNewOption(optlist, name, val ? "True" : "False");
    325 }
    326 
    327 XF86OptionPtr
    328 xf86ReplacePercentOption(XF86OptionPtr optlist, const char *name,
    329                          const double val)
    330 {
    331     char tmp[16];
    332 
    333     snprintf(tmp, sizeof(tmp), "%lf%%", val);
    334     return xf86AddNewOption(optlist, name, tmp);
    335 }
    336 
    337 XF86OptionPtr
    338 xf86ReplaceStrOption(XF86OptionPtr optlist, const char *name, const char *val)
    339 {
    340     return xf86AddNewOption(optlist, name, val);
    341 }
    342 
    343 XF86OptionPtr
    344 xf86AddNewOption(XF86OptionPtr head, const char *name, const char *val)
    345 {
    346     /* XXX These should actually be allocated in the parser library. */
    347     char *tmp = val ? strdup(val) : NULL;
    348     char *tmp_name = strdup(name);
    349 
    350     return xf86addNewOption(head, tmp_name, tmp);
    351 }
    352 
    353 XF86OptionPtr
    354 xf86NewOption(char *name, char *value)
    355 {
    356     return xf86newOption(name, value);
    357 }
    358 
    359 XF86OptionPtr
    360 xf86NextOption(XF86OptionPtr list)
    361 {
    362     return xf86nextOption(list);
    363 }
    364 
    365 XF86OptionPtr
    366 xf86OptionListCreate(const char **options, int count, int used)
    367 {
    368     return xf86optionListCreate(options, count, used);
    369 }
    370 
    371 XF86OptionPtr
    372 xf86OptionListMerge(XF86OptionPtr head, XF86OptionPtr tail)
    373 {
    374     return xf86optionListMerge(head, tail);
    375 }
    376 
    377 void
    378 xf86OptionListFree(XF86OptionPtr opt)
    379 {
    380     xf86optionListFree(opt);
    381 }
    382 
    383 char *
    384 xf86OptionName(XF86OptionPtr opt)
    385 {
    386     return xf86optionName(opt);
    387 }
    388 
    389 char *
    390 xf86OptionValue(XF86OptionPtr opt)
    391 {
    392     return xf86optionValue(opt);
    393 }
    394 
    395 void
    396 xf86OptionListReport(XF86OptionPtr parm)
    397 {
    398     XF86OptionPtr opts = parm;
    399 
    400     while (opts) {
    401         if (xf86optionValue(opts))
    402             xf86ErrorFVerb(5, "\tOption \"%s\" \"%s\"\n",
    403                            xf86optionName(opts), xf86optionValue(opts));
    404         else
    405             xf86ErrorFVerb(5, "\tOption \"%s\"\n", xf86optionName(opts));
    406         opts = xf86nextOption(opts);
    407     }
    408 }
    409 
    410 /* End of XInput-caused section	*/
    411 
    412 XF86OptionPtr
    413 xf86FindOption(XF86OptionPtr options, const char *name)
    414 {
    415     return xf86findOption(options, name);
    416 }
    417 
    418 const char *
    419 xf86FindOptionValue(XF86OptionPtr options, const char *name)
    420 {
    421     return xf86findOptionValue(options, name);
    422 }
    423 
    424 void
    425 xf86MarkOptionUsed(XF86OptionPtr option)
    426 {
    427     if (option != NULL)
    428         option->opt_used = TRUE;
    429 }
    430 
    431 void
    432 xf86MarkOptionUsedByName(XF86OptionPtr options, const char *name)
    433 {
    434     XF86OptionPtr opt;
    435 
    436     opt = xf86findOption(options, name);
    437     if (opt != NULL)
    438         opt->opt_used = TRUE;
    439 }
    440 
    441 Bool
    442 xf86CheckIfOptionUsed(XF86OptionPtr option)
    443 {
    444     if (option != NULL)
    445         return option->opt_used;
    446     else
    447         return FALSE;
    448 }
    449 
    450 Bool
    451 xf86CheckIfOptionUsedByName(XF86OptionPtr options, const char *name)
    452 {
    453     XF86OptionPtr opt;
    454 
    455     opt = xf86findOption(options, name);
    456     if (opt != NULL)
    457         return opt->opt_used;
    458     else
    459         return FALSE;
    460 }
    461 
    462 void
    463 xf86ShowUnusedOptions(int scrnIndex, XF86OptionPtr opt)
    464 {
    465     while (opt) {
    466         if (opt->opt_name && !opt->opt_used) {
    467             xf86DrvMsg(scrnIndex, X_WARNING, "Option \"%s\" is not used\n",
    468                        opt->opt_name);
    469         }
    470         opt = opt->list.next;
    471     }
    472 }
    473 
    474 static Bool
    475 GetBoolValue(OptionInfoPtr p, const char *s)
    476 {
    477     return xf86getBoolValue(&p->value.boolean, s);
    478 }
    479 
    480 static Bool
    481 ParseOptionValue(int scrnIndex, XF86OptionPtr options, OptionInfoPtr p,
    482                  Bool markUsed)
    483 {
    484     const char *s;
    485     char *end;
    486     Bool wasUsed = FALSE;
    487 
    488     if ((s = xf86findOptionValue(options, p->name)) != NULL) {
    489         if (markUsed) {
    490             wasUsed = xf86CheckIfOptionUsedByName(options, p->name);
    491             xf86MarkOptionUsedByName(options, p->name);
    492         }
    493         switch (p->type) {
    494         case OPTV_INTEGER:
    495             if (*s == '\0') {
    496                 if (markUsed) {
    497                     xf86DrvMsg(scrnIndex, X_WARNING,
    498                                "Option \"%s\" requires an integer value\n",
    499                                p->name);
    500                 }
    501                 p->found = FALSE;
    502             }
    503             else {
    504                 p->value.num = strtoul(s, &end, 0);
    505                 if (*end == '\0') {
    506                     p->found = TRUE;
    507                 }
    508                 else {
    509                     if (markUsed) {
    510                         xf86DrvMsg(scrnIndex, X_WARNING,
    511                                    "Option \"%s\" requires an integer value\n",
    512                                    p->name);
    513                     }
    514                     p->found = FALSE;
    515                 }
    516             }
    517             break;
    518         case OPTV_STRING:
    519             if (*s == '\0') {
    520                 if (markUsed) {
    521                     xf86DrvMsg(scrnIndex, X_WARNING,
    522                                "Option \"%s\" requires a string value\n",
    523                                p->name);
    524                 }
    525                 p->found = FALSE;
    526             }
    527             else {
    528                 p->value.str = s;
    529                 p->found = TRUE;
    530             }
    531             break;
    532         case OPTV_ANYSTR:
    533             p->value.str = s;
    534             p->found = TRUE;
    535             break;
    536         case OPTV_REAL:
    537             if (*s == '\0') {
    538                 if (markUsed) {
    539                     xf86DrvMsg(scrnIndex, X_WARNING,
    540                                "Option \"%s\" requires a floating point "
    541                                "value\n", p->name);
    542                 }
    543                 p->found = FALSE;
    544             }
    545             else {
    546                 p->value.realnum = strtod(s, &end);
    547                 if (*end == '\0') {
    548                     p->found = TRUE;
    549                 }
    550                 else {
    551                     if (markUsed) {
    552                         xf86DrvMsg(scrnIndex, X_WARNING,
    553                                    "Option \"%s\" requires a floating point "
    554                                    "value\n", p->name);
    555                     }
    556                     p->found = FALSE;
    557                 }
    558             }
    559             break;
    560         case OPTV_BOOLEAN:
    561             if (GetBoolValue(p, s)) {
    562                 p->found = TRUE;
    563             }
    564             else {
    565                 if (markUsed) {
    566                     xf86DrvMsg(scrnIndex, X_WARNING,
    567                                "Option \"%s\" requires a boolean value\n",
    568                                p->name);
    569                 }
    570                 p->found = FALSE;
    571             }
    572             break;
    573         case OPTV_PERCENT:
    574         {
    575             char tmp = 0;
    576 
    577             /* awkward match, but %% doesn't increase the match counter,
    578              * hence 100 looks the same as 100% to the caller of sccanf
    579              */
    580             if (sscanf(s, "%lf%c", &p->value.realnum, &tmp) != 2 || tmp != '%') {
    581                 if (markUsed) {
    582                     xf86DrvMsg(scrnIndex, X_WARNING,
    583                                "Option \"%s\" requires a percent value\n",
    584                                p->name);
    585                 }
    586                 p->found = FALSE;
    587             }
    588             else {
    589                 p->found = TRUE;
    590             }
    591         }
    592             break;
    593         case OPTV_FREQ:
    594             if (*s == '\0') {
    595                 if (markUsed) {
    596                     xf86DrvMsg(scrnIndex, X_WARNING,
    597                                "Option \"%s\" requires a frequency value\n",
    598                                p->name);
    599                 }
    600                 p->found = FALSE;
    601             }
    602             else {
    603                 double freq = strtod(s, &end);
    604                 int units = 0;
    605 
    606                 if (end != s) {
    607                     p->found = TRUE;
    608                     if (!xf86NameCmp(end, "Hz"))
    609                         units = 1;
    610                     else if (!xf86NameCmp(end, "kHz") || !xf86NameCmp(end, "k"))
    611                         units = 1000;
    612                     else if (!xf86NameCmp(end, "MHz") || !xf86NameCmp(end, "M"))
    613                         units = 1000000;
    614                     else {
    615                         if (markUsed) {
    616                             xf86DrvMsg(scrnIndex, X_WARNING,
    617                                        "Option \"%s\" requires a frequency value\n",
    618                                        p->name);
    619                         }
    620                         p->found = FALSE;
    621                     }
    622                     if (p->found)
    623                         freq *= (double) units;
    624                 }
    625                 else {
    626                     if (markUsed) {
    627                         xf86DrvMsg(scrnIndex, X_WARNING,
    628                                    "Option \"%s\" requires a frequency value\n",
    629                                    p->name);
    630                     }
    631                     p->found = FALSE;
    632                 }
    633                 if (p->found) {
    634                     p->value.freq.freq = freq;
    635                     p->value.freq.units = units;
    636                 }
    637             }
    638             break;
    639         case OPTV_NONE:
    640             /* Should never get here */
    641             p->found = FALSE;
    642             break;
    643         }
    644         if (p->found && markUsed) {
    645             int verb = 2;
    646 
    647             if (wasUsed)
    648                 verb = 4;
    649             xf86DrvMsgVerb(scrnIndex, X_CONFIG, verb, "Option \"%s\"", p->name);
    650             if (!(p->type == OPTV_BOOLEAN && *s == 0)) {
    651                 xf86ErrorFVerb(verb, " \"%s\"", s);
    652             }
    653             xf86ErrorFVerb(verb, "\n");
    654         }
    655     }
    656     else if (p->type == OPTV_BOOLEAN) {
    657         /* Look for matches with options with or without a "No" prefix. */
    658         char *n, *newn;
    659         OptionInfoRec opt;
    660 
    661         n = xf86NormalizeName(p->name);
    662         if (!n) {
    663             p->found = FALSE;
    664             return FALSE;
    665         }
    666         if (strncmp(n, "no", 2) == 0) {
    667             newn = n + 2;
    668         }
    669         else {
    670             free(n);
    671             if (asprintf(&n, "No%s", p->name) == -1) {
    672                 p->found = FALSE;
    673                 return FALSE;
    674             }
    675             newn = n;
    676         }
    677         if ((s = xf86findOptionValue(options, newn)) != NULL) {
    678             if (markUsed)
    679                 xf86MarkOptionUsedByName(options, newn);
    680             if (GetBoolValue(&opt, s)) {
    681                 p->value.boolean = !opt.value.boolean;
    682                 p->found = TRUE;
    683             }
    684             else {
    685                 xf86DrvMsg(scrnIndex, X_WARNING,
    686                            "Option \"%s\" requires a boolean value\n", newn);
    687                 p->found = FALSE;
    688             }
    689         }
    690         else {
    691             p->found = FALSE;
    692         }
    693         if (p->found && markUsed) {
    694             xf86DrvMsgVerb(scrnIndex, X_CONFIG, 2, "Option \"%s\"", newn);
    695             if (*s != 0) {
    696                 xf86ErrorFVerb(2, " \"%s\"", s);
    697             }
    698             xf86ErrorFVerb(2, "\n");
    699         }
    700         free(n);
    701     }
    702     else {
    703         p->found = FALSE;
    704     }
    705     return p->found;
    706 }
    707 
    708 void
    709 xf86ProcessOptions(int scrnIndex, XF86OptionPtr options, OptionInfoPtr optinfo)
    710 {
    711     OptionInfoPtr p;
    712 
    713     for (p = optinfo; p->name != NULL; p++) {
    714         ParseOptionValue(scrnIndex, options, p, TRUE);
    715     }
    716 }
    717 
    718 OptionInfoPtr
    719 xf86TokenToOptinfo(const OptionInfoRec * table, int token)
    720 {
    721     const OptionInfoRec *p, *match = NULL, *set = NULL;
    722 
    723     if (!table) {
    724         ErrorF("xf86TokenToOptinfo: table is NULL\n");
    725         return NULL;
    726     }
    727 
    728     for (p = table; p->token >= 0; p++) {
    729         if (p->token == token) {
    730             match = p;
    731             if (p->found)
    732                 set = p;
    733         }
    734     }
    735 
    736     if (set)
    737         return (OptionInfoPtr) set;
    738     else if (match)
    739         return (OptionInfoPtr) match;
    740     else
    741         return NULL;
    742 }
    743 
    744 const char *
    745 xf86TokenToOptName(const OptionInfoRec * table, int token)
    746 {
    747     const OptionInfoRec *p;
    748 
    749     p = xf86TokenToOptinfo(table, token);
    750     return p ? p->name : NULL;
    751 }
    752 
    753 Bool
    754 xf86IsOptionSet(const OptionInfoRec * table, int token)
    755 {
    756     OptionInfoPtr p;
    757 
    758     p = xf86TokenToOptinfo(table, token);
    759     return p && p->found;
    760 }
    761 
    762 const char *
    763 xf86GetOptValString(const OptionInfoRec * table, int token)
    764 {
    765     OptionInfoPtr p;
    766 
    767     p = xf86TokenToOptinfo(table, token);
    768     if (p && p->found)
    769         return p->value.str;
    770     else
    771         return NULL;
    772 }
    773 
    774 Bool
    775 xf86GetOptValInteger(const OptionInfoRec * table, int token, int *value)
    776 {
    777     OptionInfoPtr p;
    778 
    779     p = xf86TokenToOptinfo(table, token);
    780     if (p && p->found) {
    781         *value = p->value.num;
    782         return TRUE;
    783     }
    784     else
    785         return FALSE;
    786 }
    787 
    788 Bool
    789 xf86GetOptValULong(const OptionInfoRec * table, int token, unsigned long *value)
    790 {
    791     OptionInfoPtr p;
    792 
    793     p = xf86TokenToOptinfo(table, token);
    794     if (p && p->found) {
    795         *value = p->value.num;
    796         return TRUE;
    797     }
    798     else
    799         return FALSE;
    800 }
    801 
    802 Bool
    803 xf86GetOptValReal(const OptionInfoRec * table, int token, double *value)
    804 {
    805     OptionInfoPtr p;
    806 
    807     p = xf86TokenToOptinfo(table, token);
    808     if (p && p->found) {
    809         *value = p->value.realnum;
    810         return TRUE;
    811     }
    812     else
    813         return FALSE;
    814 }
    815 
    816 Bool
    817 xf86GetOptValFreq(const OptionInfoRec * table, int token,
    818                   OptFreqUnits expectedUnits, double *value)
    819 {
    820     OptionInfoPtr p;
    821 
    822     p = xf86TokenToOptinfo(table, token);
    823     if (p && p->found) {
    824         if (p->value.freq.units > 0) {
    825             /* Units give, so the scaling is known. */
    826             switch (expectedUnits) {
    827             case OPTUNITS_HZ:
    828                 *value = p->value.freq.freq;
    829                 break;
    830             case OPTUNITS_KHZ:
    831                 *value = p->value.freq.freq / 1000.0;
    832                 break;
    833             case OPTUNITS_MHZ:
    834                 *value = p->value.freq.freq / 1000000.0;
    835                 break;
    836             }
    837         }
    838         else {
    839             /* No units given, so try to guess the scaling. */
    840             switch (expectedUnits) {
    841             case OPTUNITS_HZ:
    842                 *value = p->value.freq.freq;
    843                 break;
    844             case OPTUNITS_KHZ:
    845                 if (p->value.freq.freq > 1000.0)
    846                     *value = p->value.freq.freq / 1000.0;
    847                 else
    848                     *value = p->value.freq.freq;
    849                 break;
    850             case OPTUNITS_MHZ:
    851                 if (p->value.freq.freq > 1000000.0)
    852                     *value = p->value.freq.freq / 1000000.0;
    853                 else if (p->value.freq.freq > 1000.0)
    854                     *value = p->value.freq.freq / 1000.0;
    855                 else
    856                     *value = p->value.freq.freq;
    857             }
    858         }
    859         return TRUE;
    860     }
    861     else
    862         return FALSE;
    863 }
    864 
    865 Bool
    866 xf86GetOptValBool(const OptionInfoRec * table, int token, Bool *value)
    867 {
    868     OptionInfoPtr p;
    869 
    870     p = xf86TokenToOptinfo(table, token);
    871     if (p && p->found) {
    872         *value = p->value.boolean;
    873         return TRUE;
    874     }
    875     else
    876         return FALSE;
    877 }
    878 
    879 Bool
    880 xf86ReturnOptValBool(const OptionInfoRec * table, int token, Bool def)
    881 {
    882     OptionInfoPtr p;
    883 
    884     p = xf86TokenToOptinfo(table, token);
    885     if (p && p->found) {
    886         return p->value.boolean;
    887     }
    888     else
    889         return def;
    890 }
    891 
    892 int
    893 xf86NameCmp(const char *s1, const char *s2)
    894 {
    895     return xf86nameCompare(s1, s2);
    896 }
    897 
    898 char *
    899 xf86NormalizeName(const char *s)
    900 {
    901     char *ret, *q;
    902     const char *p;
    903 
    904     if (s == NULL)
    905         return NULL;
    906 
    907     ret = malloc(strlen(s) + 1);
    908     for (p = s, q = ret; *p != 0; p++) {
    909         switch (*p) {
    910         case '_':
    911         case ' ':
    912         case '\t':
    913             continue;
    914         default:
    915             if (isupper(*p))
    916                 *q++ = tolower(*p);
    917             else
    918                 *q++ = *p;
    919         }
    920     }
    921     *q = '\0';
    922     return ret;
    923 }