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