2 * Copyright (c) 1998-2003 by The XFree86 Project, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
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).
29 * Author: David Dawes <dawes@xfree86.org>
31 * This file includes public option handling functions.
34 #ifdef HAVE_XORG_CONFIG_H
35 #include <xorg-config.h>
43 #include "xf86Xinput.h"
44 #include "xf86Optrec.h"
46 static Bool
ParseOptionValue(int scrnIndex
, pointer options
, OptionInfoPtr p
,
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:
55 * pScrn->Entities[i]->device
59 * The extraOpts parameter may optionally contain a list of additional options
62 * The order of precedence for options is:
64 * extraOpts, display, confScreen, monitor, device
68 xf86CollectOptions(ScrnInfoPtr pScrn
, pointer extraOpts
)
71 XF86OptionPtr extras
= (XF86OptionPtr
)extraOpts
;
76 pScrn
->options
= NULL
;
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
);
84 xf86optionListMerge(pScrn
->options
,tmp
);
89 if (pScrn
->monitor
->options
) {
90 tmp
= xf86optionListDup(pScrn
->monitor
->options
);
92 pScrn
->options
= xf86optionListMerge(pScrn
->options
, tmp
);
96 if (pScrn
->confScreen
->options
) {
97 tmp
= xf86optionListDup(pScrn
->confScreen
->options
);
99 pScrn
->options
= xf86optionListMerge(pScrn
->options
, tmp
);
101 pScrn
->options
= tmp
;
103 if (pScrn
->display
->options
) {
104 tmp
= xf86optionListDup(pScrn
->display
->options
);
106 pScrn
->options
= xf86optionListMerge(pScrn
->options
, tmp
);
108 pScrn
->options
= tmp
;
111 tmp
= xf86optionListDup(extras
);
113 pScrn
->options
= xf86optionListMerge(pScrn
->options
, tmp
);
115 pScrn
->options
= tmp
;
120 * xf86CollectInputOptions collects the options for an InputDevice.
121 * This function requires that the following has been initialised:
125 * The extraOpts parameter may optionally contain a list of additional options
128 * The order of precedence for options is:
130 * extraOpts, pInfo->conf_idev->extraOptions,
131 * pInfo->conf_idev->commonOptions, defaultOpts
135 xf86CollectInputOptions(InputInfoPtr pInfo
, const char **defaultOpts
,
139 XF86OptionPtr extras
= (XF86OptionPtr
)extraOpts
;
141 pInfo
->options
= NULL
;
143 pInfo
->options
= xf86OptionListCreate(defaultOpts
, -1, 0);
145 if (pInfo
->conf_idev
&& pInfo
->conf_idev
->commonOptions
) {
146 tmp
= xf86optionListDup(pInfo
->conf_idev
->commonOptions
);
148 pInfo
->options
= xf86optionListMerge(pInfo
->options
, tmp
);
150 pInfo
->options
= tmp
;
152 if (pInfo
->conf_idev
&& pInfo
->conf_idev
->extraOptions
) {
153 tmp
= xf86optionListDup(pInfo
->conf_idev
->extraOptions
);
155 pInfo
->options
= xf86optionListMerge(pInfo
->options
, tmp
);
157 pInfo
->options
= tmp
;
160 tmp
= xf86optionListDup(extras
);
162 pInfo
->options
= xf86optionListMerge(pInfo
->options
, tmp
);
164 pInfo
->options
= tmp
;
168 /* Created for new XInput stuff -- essentially extensions to the parser */
171 LookupIntOption(pointer optlist
, const char *name
, int deflt
, Bool markUsed
)
176 o
.type
= OPTV_INTEGER
;
177 if (ParseOptionValue(-1, optlist
, &o
, markUsed
))
184 LookupRealOption(pointer optlist
, const char *name
, double deflt
,
191 if (ParseOptionValue(-1, optlist
, &o
, markUsed
))
192 deflt
= o
.value
.realnum
;
198 LookupStrOption(pointer optlist
, const char *name
, char *deflt
, Bool markUsed
)
203 o
.type
= OPTV_STRING
;
204 if (ParseOptionValue(-1, optlist
, &o
, markUsed
))
207 return xstrdup(deflt
);
214 LookupBoolOption(pointer optlist
, const char *name
, int deflt
, Bool markUsed
)
219 o
.type
= OPTV_BOOLEAN
;
220 if (ParseOptionValue(-1, optlist
, &o
, markUsed
))
221 deflt
= o
.value
.bool;
225 /* These xf86Set* functions are intended for use by non-screen specific code */
228 xf86SetIntOption(pointer optlist
, const char *name
, int deflt
)
230 return LookupIntOption(optlist
, name
, deflt
, TRUE
);
235 xf86SetRealOption(pointer optlist
, const char *name
, double deflt
)
237 return LookupRealOption(optlist
, name
, deflt
, TRUE
);
242 xf86SetStrOption(pointer optlist
, const char *name
, char *deflt
)
244 return LookupStrOption(optlist
, name
, deflt
, TRUE
);
249 xf86SetBoolOption(pointer optlist
, const char *name
, int deflt
)
251 return LookupBoolOption(optlist
, name
, deflt
, TRUE
);
255 * These are like the Set*Option functions, but they don't mark the options
259 xf86CheckIntOption(pointer optlist
, const char *name
, int deflt
)
261 return LookupIntOption(optlist
, name
, deflt
, FALSE
);
266 xf86CheckRealOption(pointer optlist
, const char *name
, double deflt
)
268 return LookupRealOption(optlist
, name
, deflt
, FALSE
);
273 xf86CheckStrOption(pointer optlist
, const char *name
, char *deflt
)
275 return LookupStrOption(optlist
, name
, deflt
, FALSE
);
280 xf86CheckBoolOption(pointer optlist
, const char *name
, int deflt
)
282 return LookupBoolOption(optlist
, name
, deflt
, FALSE
);
286 * addNewOption() has the required property of replacing the option value
287 * if the option is already present.
290 xf86ReplaceIntOption(pointer optlist
, const char *name
, const int val
)
293 sprintf(tmp
,"%i",val
);
294 return xf86AddNewOption(optlist
,name
,tmp
);
298 xf86ReplaceRealOption(pointer optlist
, const char *name
, const double val
)
301 snprintf(tmp
,32,"%f",val
);
302 return xf86AddNewOption(optlist
,name
,tmp
);
306 xf86ReplaceBoolOption(pointer optlist
, const char *name
, const Bool val
)
308 return xf86AddNewOption(optlist
,name
,val
?"True":"False");
312 xf86ReplaceStrOption(pointer optlist
, const char *name
, const char* val
)
314 return xf86AddNewOption(optlist
,name
,val
);
318 xf86AddNewOption(pointer head
, const char *name
, const char *val
)
320 /* XXX These should actually be allocated in the parser library. */
321 char *tmp
= strdup(val
);
322 char *tmp_name
= strdup(name
);
324 return xf86addNewOption(head
, tmp_name
, tmp
);
329 xf86NewOption(char *name
, char *value
)
331 return xf86newOption(name
, value
);
336 xf86NextOption(pointer list
)
338 return xf86nextOption(list
);
342 xf86OptionListCreate(const char **options
, int count
, int used
)
344 return xf86optionListCreate(options
, count
, used
);
348 xf86OptionListMerge(pointer head
, pointer tail
)
350 return xf86optionListMerge(head
, tail
);
354 xf86OptionListFree(pointer opt
)
356 xf86optionListFree(opt
);
360 xf86OptionName(pointer opt
)
362 return xf86optionName(opt
);
366 xf86OptionValue(pointer opt
)
368 return xf86optionValue(opt
);
372 xf86OptionListReport(pointer parm
)
374 XF86OptionPtr opts
= parm
;
377 if (xf86optionValue(opts
))
378 xf86ErrorFVerb(5, "\tOption \"%s\" \"%s\"\n",
379 xf86optionName(opts
), xf86optionValue(opts
));
381 xf86ErrorFVerb( 5, "\tOption \"%s\"\n", xf86optionName(opts
));
382 opts
= xf86nextOption(opts
);
386 /* End of XInput-caused section */
389 xf86FindOption(pointer options
, const char *name
)
391 return xf86findOption(options
, name
);
396 xf86FindOptionValue(pointer options
, const char *name
)
398 return xf86findOptionValue(options
, name
);
403 xf86MarkOptionUsed(pointer option
)
406 ((XF86OptionPtr
)option
)->opt_used
= TRUE
;
411 xf86MarkOptionUsedByName(pointer options
, const char *name
)
415 opt
= xf86findOption(options
, name
);
417 opt
->opt_used
= TRUE
;
421 xf86CheckIfOptionUsed(pointer option
)
424 return ((XF86OptionPtr
)option
)->opt_used
;
430 xf86CheckIfOptionUsedByName(pointer options
, const char *name
)
434 opt
= xf86findOption(options
, name
);
436 return opt
->opt_used
;
442 xf86ShowUnusedOptions(int scrnIndex
, pointer options
)
444 XF86OptionPtr opt
= options
;
447 if (opt
->opt_name
&& !opt
->opt_used
) {
448 xf86DrvMsg(scrnIndex
, X_WARNING
, "Option \"%s\" is not used\n",
451 opt
= opt
->list
.next
;
457 GetBoolValue(OptionInfoPtr p
, const char *s
)
460 p
->value
.bool = TRUE
;
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
;
485 ParseOptionValue(int scrnIndex
, pointer options
, OptionInfoPtr p
,
489 Bool wasUsed
= FALSE
;
491 if ((s
= xf86findOptionValue(options
, p
->name
)) != NULL
) {
493 wasUsed
= xf86CheckIfOptionUsedByName(options
, p
->name
);
494 xf86MarkOptionUsedByName(options
, p
->name
);
499 xf86DrvMsg(scrnIndex
, X_WARNING
,
500 "Option \"%s\" requires an integer value\n",
504 p
->value
.num
= strtoul(s
, &end
, 0);
508 xf86DrvMsg(scrnIndex
, X_WARNING
,
509 "Option \"%s\" requires an integer value\n",
517 xf86DrvMsg(scrnIndex
, X_WARNING
,
518 "Option \"%s\" requires an string value\n",
532 xf86DrvMsg(scrnIndex
, X_WARNING
,
533 "Option \"%s\" requires a floating point value\n",
537 p
->value
.realnum
= strtod(s
, &end
);
541 xf86DrvMsg(scrnIndex
, X_WARNING
,
542 "Option \"%s\" requires a floating point value\n",
549 if (GetBoolValue(p
, s
)) {
552 xf86DrvMsg(scrnIndex
, X_WARNING
,
553 "Option \"%s\" requires a boolean value\n", p
->name
);
559 xf86DrvMsg(scrnIndex
, X_WARNING
,
560 "Option \"%s\" requires a frequency value\n",
564 double freq
= strtod(s
, &end
);
569 if (!xf86NameCmp(end
, "Hz"))
571 else if (!xf86NameCmp(end
, "kHz") ||
572 !xf86NameCmp(end
, "k"))
574 else if (!xf86NameCmp(end
, "MHz") ||
575 !xf86NameCmp(end
, "M"))
578 xf86DrvMsg(scrnIndex
, X_WARNING
,
579 "Option \"%s\" requires a frequency value\n",
584 freq
*= (double)units
;
586 xf86DrvMsg(scrnIndex
, X_WARNING
,
587 "Option \"%s\" requires a frequency value\n",
592 p
->value
.freq
.freq
= freq
;
593 p
->value
.freq
.units
= units
;
598 /* Should never get here */
602 if (p
->found
&& markUsed
) {
606 xf86DrvMsgVerb(scrnIndex
, X_CONFIG
, verb
, "Option \"%s\"", p
->name
);
607 if (!(p
->type
== OPTV_BOOLEAN
&& *s
== 0)) {
608 xf86ErrorFVerb(verb
, " \"%s\"", s
);
610 xf86ErrorFVerb(verb
, "\n");
612 } else if (p
->type
== OPTV_BOOLEAN
) {
613 /* Look for matches with options with or without a "No" prefix. */
617 n
= xf86NormalizeName(p
->name
);
622 if (strncmp(n
, "no", 2) == 0) {
626 n
= xalloc(strlen(p
->name
) + 2 + 1);
635 if ((s
= xf86findOptionValue(options
, newn
)) != NULL
) {
637 xf86MarkOptionUsedByName(options
, newn
);
638 if (GetBoolValue(&opt
, s
)) {
639 p
->value
.bool = !opt
.value
.bool;
642 xf86DrvMsg(scrnIndex
, X_WARNING
,
643 "Option \"%s\" requires a boolean value\n", newn
);
649 if (p
->found
&& markUsed
) {
650 xf86DrvMsgVerb(scrnIndex
, X_CONFIG
, 2, "Option \"%s\"", newn
);
652 xf86ErrorFVerb(2, " \"%s\"", s
);
654 xf86ErrorFVerb(2, "\n");
665 xf86ProcessOptions(int scrnIndex
, pointer options
, OptionInfoPtr optinfo
)
669 for (p
= optinfo
; p
->name
!= NULL
; p
++) {
670 ParseOptionValue(scrnIndex
, options
, p
, TRUE
);
675 _X_EXPORT OptionInfoPtr
676 xf86TokenToOptinfo(const OptionInfoRec
*table
, int token
)
678 const OptionInfoRec
*p
, *match
= NULL
, *set
= NULL
;
681 ErrorF("xf86TokenToOptinfo: table is NULL\n");
685 for (p
= table
; p
->token
>= 0; p
++) {
686 if (p
->token
== token
) {
694 return (OptionInfoPtr
)set
;
696 return (OptionInfoPtr
)match
;
702 _X_EXPORT
const char *
703 xf86TokenToOptName(const OptionInfoRec
*table
, int token
)
705 const OptionInfoRec
*p
;
707 p
= xf86TokenToOptinfo(table
, token
);
713 xf86IsOptionSet(const OptionInfoRec
*table
, int token
)
717 p
= xf86TokenToOptinfo(table
, token
);
718 return (p
&& p
->found
);
723 xf86GetOptValString(const OptionInfoRec
*table
, int token
)
727 p
= xf86TokenToOptinfo(table
, token
);
736 xf86GetOptValInteger(const OptionInfoRec
*table
, int token
, int *value
)
740 p
= xf86TokenToOptinfo(table
, token
);
742 *value
= p
->value
.num
;
750 xf86GetOptValULong(const OptionInfoRec
*table
, int token
, unsigned long *value
)
754 p
= xf86TokenToOptinfo(table
, token
);
756 *value
= p
->value
.num
;
764 xf86GetOptValReal(const OptionInfoRec
*table
, int token
, double *value
)
768 p
= xf86TokenToOptinfo(table
, token
);
770 *value
= p
->value
.realnum
;
778 xf86GetOptValFreq(const OptionInfoRec
*table
, int token
,
779 OptFreqUnits expectedUnits
, double *value
)
783 p
= xf86TokenToOptinfo(table
, token
);
785 if (p
->value
.freq
.units
> 0) {
786 /* Units give, so the scaling is known. */
787 switch (expectedUnits
) {
789 *value
= p
->value
.freq
.freq
;
792 *value
= p
->value
.freq
.freq
/ 1000.0;
795 *value
= p
->value
.freq
.freq
/ 1000000.0;
799 /* No units given, so try to guess the scaling. */
800 switch (expectedUnits
) {
802 *value
= p
->value
.freq
.freq
;
805 if (p
->value
.freq
.freq
> 1000.0)
806 *value
= p
->value
.freq
.freq
/ 1000.0;
808 *value
= p
->value
.freq
.freq
;
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;
816 *value
= p
->value
.freq
.freq
;
826 xf86GetOptValBool(const OptionInfoRec
*table
, int token
, Bool
*value
)
830 p
= xf86TokenToOptinfo(table
, token
);
832 *value
= p
->value
.bool;
840 xf86ReturnOptValBool(const OptionInfoRec
*table
, int token
, Bool def
)
844 p
= xf86TokenToOptinfo(table
, token
);
846 return p
->value
.bool;
853 xf86NameCmp(const char *s1
, const char *s2
)
855 return xf86nameCompare(s1
, s2
);
859 xf86NormalizeName(const char *s
)
867 ret
= xalloc(strlen(s
) + 1);
868 for (p
= s
, q
= ret
; *p
!= 0; p
++) {