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