105b261ecSmrg/* 205b261ecSmrg * Copyright (c) 1998-2003 by The XFree86 Project, Inc. 305b261ecSmrg * 405b261ecSmrg * Permission is hereby granted, free of charge, to any person obtaining a 505b261ecSmrg * copy of this software and associated documentation files (the "Software"), 605b261ecSmrg * to deal in the Software without restriction, including without limitation 705b261ecSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 805b261ecSmrg * and/or sell copies of the Software, and to permit persons to whom the 905b261ecSmrg * Software is furnished to do so, subject to the following conditions: 1005b261ecSmrg * 1105b261ecSmrg * The above copyright notice and this permission notice shall be included in 1205b261ecSmrg * all copies or substantial portions of the Software. 1305b261ecSmrg * 1405b261ecSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1505b261ecSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1605b261ecSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1705b261ecSmrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 1805b261ecSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 1905b261ecSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2005b261ecSmrg * OTHER DEALINGS IN THE SOFTWARE. 2105b261ecSmrg * 2205b261ecSmrg * Except as contained in this notice, the name of the copyright holder(s) 2305b261ecSmrg * and author(s) shall not be used in advertising or otherwise to promote 2405b261ecSmrg * the sale, use or other dealings in this Software without prior written 2505b261ecSmrg * authorization from the copyright holder(s) and author(s). 2605b261ecSmrg */ 2705b261ecSmrg 2805b261ecSmrg/* 2905b261ecSmrg * Author: David Dawes <dawes@xfree86.org> 3005b261ecSmrg * 3105b261ecSmrg * This file includes public option handling functions. 3205b261ecSmrg */ 3305b261ecSmrg 3405b261ecSmrg#ifdef HAVE_XORG_CONFIG_H 3505b261ecSmrg#include <xorg-config.h> 3605b261ecSmrg#endif 3705b261ecSmrg 3805b261ecSmrg#include <stdlib.h> 3905b261ecSmrg#include <ctype.h> 4005b261ecSmrg#include <X11/X.h> 4105b261ecSmrg#include "os.h" 4205b261ecSmrg#include "xf86.h" 4335c4bbdfSmrg#include "xf86Opt.h" 4405b261ecSmrg#include "xf86Xinput.h" 4505b261ecSmrg#include "xf86Optrec.h" 466747b715Smrg#include "xf86Parser.h" 471b5d61b8Smrg#include "xf86platformBus.h" /* For OutputClass functions */ 4835c4bbdfSmrg#include "optionstr.h" 4905b261ecSmrg 5035c4bbdfSmrgstatic Bool ParseOptionValue(int scrnIndex, XF86OptionPtr options, 5135c4bbdfSmrg OptionInfoPtr p, Bool markUsed); 5205b261ecSmrg 5305b261ecSmrg/* 5405b261ecSmrg * xf86CollectOptions collects the options from each of the config file 5505b261ecSmrg * sections used by the screen and puts the combined list in pScrn->options. 5605b261ecSmrg * This function requires that the following have been initialised: 5705b261ecSmrg * 5805b261ecSmrg * pScrn->confScreen 5905b261ecSmrg * pScrn->Entities[i]->device 6005b261ecSmrg * pScrn->display 6105b261ecSmrg * pScrn->monitor 6205b261ecSmrg * 6305b261ecSmrg * The extraOpts parameter may optionally contain a list of additional options 6405b261ecSmrg * to include. 6505b261ecSmrg * 6605b261ecSmrg * The order of precedence for options is: 6705b261ecSmrg * 681b5d61b8Smrg * extraOpts, display, confScreen, monitor, device, outputClassOptions 6905b261ecSmrg */ 7005b261ecSmrg 716747b715Smrgvoid 7235c4bbdfSmrgxf86CollectOptions(ScrnInfoPtr pScrn, XF86OptionPtr extraOpts) 7305b261ecSmrg{ 7405b261ecSmrg XF86OptionPtr tmp; 7535c4bbdfSmrg XF86OptionPtr extras = (XF86OptionPtr) extraOpts; 7605b261ecSmrg GDevPtr device; 7735c4bbdfSmrg 7805b261ecSmrg int i; 7905b261ecSmrg 8005b261ecSmrg pScrn->options = NULL; 8105b261ecSmrg 8235c4bbdfSmrg for (i = pScrn->numEntities - 1; i >= 0; i--) { 831b5d61b8Smrg xf86MergeOutputClassOptions(pScrn->entityList[i], &pScrn->options); 841b5d61b8Smrg 8535c4bbdfSmrg device = xf86GetDevFromEntity(pScrn->entityList[i], 8635c4bbdfSmrg pScrn->entityInstanceList[i]); 8735c4bbdfSmrg if (device && device->options) { 8835c4bbdfSmrg tmp = xf86optionListDup(device->options); 8935c4bbdfSmrg if (pScrn->options) 901b5d61b8Smrg pScrn->options = xf86optionListMerge(pScrn->options, tmp); 9135c4bbdfSmrg else 9235c4bbdfSmrg pScrn->options = tmp; 9335c4bbdfSmrg } 9405b261ecSmrg } 9505b261ecSmrg if (pScrn->monitor->options) { 9635c4bbdfSmrg tmp = xf86optionListDup(pScrn->monitor->options); 9735c4bbdfSmrg if (pScrn->options) 9835c4bbdfSmrg pScrn->options = xf86optionListMerge(pScrn->options, tmp); 9935c4bbdfSmrg else 10035c4bbdfSmrg pScrn->options = tmp; 10105b261ecSmrg } 10205b261ecSmrg if (pScrn->confScreen->options) { 10335c4bbdfSmrg tmp = xf86optionListDup(pScrn->confScreen->options); 10435c4bbdfSmrg if (pScrn->options) 10535c4bbdfSmrg pScrn->options = xf86optionListMerge(pScrn->options, tmp); 10635c4bbdfSmrg else 10735c4bbdfSmrg pScrn->options = tmp; 10805b261ecSmrg } 10905b261ecSmrg if (pScrn->display->options) { 11035c4bbdfSmrg tmp = xf86optionListDup(pScrn->display->options); 11135c4bbdfSmrg if (pScrn->options) 11235c4bbdfSmrg pScrn->options = xf86optionListMerge(pScrn->options, tmp); 11335c4bbdfSmrg else 11435c4bbdfSmrg pScrn->options = tmp; 11505b261ecSmrg } 11605b261ecSmrg if (extras) { 11735c4bbdfSmrg tmp = xf86optionListDup(extras); 11835c4bbdfSmrg if (pScrn->options) 11935c4bbdfSmrg pScrn->options = xf86optionListMerge(pScrn->options, tmp); 12035c4bbdfSmrg else 12135c4bbdfSmrg pScrn->options = tmp; 12205b261ecSmrg } 12305b261ecSmrg} 12405b261ecSmrg 12505b261ecSmrg/* 1269ace9065Smrg * xf86CollectInputOptions collects extra options for an InputDevice (other 1279ace9065Smrg * than those added by the config backend). 1289ace9065Smrg * The options are merged into the existing ones and thus take precedence 1299ace9065Smrg * over the others. 13005b261ecSmrg */ 13105b261ecSmrg 1326747b715Smrgvoid 1339ace9065Smrgxf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts) 13405b261ecSmrg{ 13505b261ecSmrg if (defaultOpts) { 13635c4bbdfSmrg XF86OptionPtr tmp = xf86optionListCreate(defaultOpts, -1, 0); 13735c4bbdfSmrg 13835c4bbdfSmrg if (pInfo->options) 13935c4bbdfSmrg pInfo->options = xf86optionListMerge(tmp, pInfo->options); 14035c4bbdfSmrg else 14135c4bbdfSmrg pInfo->options = tmp; 14205b261ecSmrg } 1439ace9065Smrg} 1446747b715Smrg 1459ace9065Smrg/** 1469ace9065Smrg * Duplicate the option list passed in. The returned pointer will be a newly 1479ace9065Smrg * allocated option list and must be freed by the caller. 1489ace9065Smrg */ 14935c4bbdfSmrgXF86OptionPtr 15035c4bbdfSmrgxf86OptionListDuplicate(XF86OptionPtr options) 1519ace9065Smrg{ 15235c4bbdfSmrg XF86OptionPtr o = NULL; 1539ace9065Smrg 15435c4bbdfSmrg while (options) { 15535c4bbdfSmrg o = xf86AddNewOption(o, xf86OptionName(options), 15635c4bbdfSmrg xf86OptionValue(options)); 1579ace9065Smrg options = xf86nextOption(options); 1586747b715Smrg } 1599ace9065Smrg 1609ace9065Smrg return o; 16105b261ecSmrg} 16205b261ecSmrg 16305b261ecSmrg/* Created for new XInput stuff -- essentially extensions to the parser */ 16405b261ecSmrg 16505b261ecSmrgstatic int 16635c4bbdfSmrgLookupIntOption(XF86OptionPtr optlist, const char *name, int deflt, 16735c4bbdfSmrg Bool markUsed) 16805b261ecSmrg{ 16905b261ecSmrg OptionInfoRec o; 17005b261ecSmrg 17105b261ecSmrg o.name = name; 17205b261ecSmrg o.type = OPTV_INTEGER; 17305b261ecSmrg if (ParseOptionValue(-1, optlist, &o, markUsed)) 17435c4bbdfSmrg deflt = o.value.num; 17505b261ecSmrg return deflt; 17605b261ecSmrg} 17705b261ecSmrg 17805b261ecSmrgstatic double 17935c4bbdfSmrgLookupRealOption(XF86OptionPtr optlist, const char *name, double deflt, 18035c4bbdfSmrg Bool markUsed) 18105b261ecSmrg{ 18205b261ecSmrg OptionInfoRec o; 18305b261ecSmrg 18405b261ecSmrg o.name = name; 18505b261ecSmrg o.type = OPTV_REAL; 18605b261ecSmrg if (ParseOptionValue(-1, optlist, &o, markUsed)) 18735c4bbdfSmrg deflt = o.value.realnum; 18805b261ecSmrg return deflt; 18905b261ecSmrg} 19005b261ecSmrg 19105b261ecSmrgstatic char * 19235c4bbdfSmrgLookupStrOption(XF86OptionPtr optlist, const char *name, const char *deflt, 19335c4bbdfSmrg Bool markUsed) 19405b261ecSmrg{ 19505b261ecSmrg OptionInfoRec o; 19605b261ecSmrg 19705b261ecSmrg o.name = name; 19805b261ecSmrg o.type = OPTV_STRING; 19905b261ecSmrg if (ParseOptionValue(-1, optlist, &o, markUsed)) 20005b261ecSmrg deflt = o.value.str; 20105b261ecSmrg if (deflt) 20235c4bbdfSmrg return strdup(deflt); 20305b261ecSmrg else 20435c4bbdfSmrg return NULL; 20505b261ecSmrg} 20605b261ecSmrg 20705b261ecSmrgstatic int 20835c4bbdfSmrgLookupBoolOption(XF86OptionPtr optlist, const char *name, int deflt, 20935c4bbdfSmrg Bool markUsed) 21005b261ecSmrg{ 21105b261ecSmrg OptionInfoRec o; 21205b261ecSmrg 21305b261ecSmrg o.name = name; 21405b261ecSmrg o.type = OPTV_BOOLEAN; 21505b261ecSmrg if (ParseOptionValue(-1, optlist, &o, markUsed)) 216ed6184dfSmrg deflt = o.value.boolean; 21705b261ecSmrg return deflt; 21805b261ecSmrg} 21905b261ecSmrg 2209ace9065Smrgstatic double 22135c4bbdfSmrgLookupPercentOption(XF86OptionPtr optlist, const char *name, double deflt, 22235c4bbdfSmrg Bool markUsed) 2236747b715Smrg{ 2246747b715Smrg OptionInfoRec o; 2256747b715Smrg 2266747b715Smrg o.name = name; 2276747b715Smrg o.type = OPTV_PERCENT; 2286747b715Smrg if (ParseOptionValue(-1, optlist, &o, markUsed)) 22935c4bbdfSmrg deflt = o.value.realnum; 2306747b715Smrg return deflt; 2316747b715Smrg} 2326747b715Smrg 23305b261ecSmrg/* These xf86Set* functions are intended for use by non-screen specific code */ 23405b261ecSmrg 2356747b715Smrgint 23635c4bbdfSmrgxf86SetIntOption(XF86OptionPtr optlist, const char *name, int deflt) 23705b261ecSmrg{ 23805b261ecSmrg return LookupIntOption(optlist, name, deflt, TRUE); 23905b261ecSmrg} 24005b261ecSmrg 2416747b715Smrgdouble 24235c4bbdfSmrgxf86SetRealOption(XF86OptionPtr optlist, const char *name, double deflt) 24305b261ecSmrg{ 24405b261ecSmrg return LookupRealOption(optlist, name, deflt, TRUE); 24505b261ecSmrg} 24605b261ecSmrg 2476747b715Smrgchar * 24835c4bbdfSmrgxf86SetStrOption(XF86OptionPtr optlist, const char *name, const char *deflt) 24905b261ecSmrg{ 25005b261ecSmrg return LookupStrOption(optlist, name, deflt, TRUE); 25105b261ecSmrg} 25205b261ecSmrg 2536747b715Smrgint 25435c4bbdfSmrgxf86SetBoolOption(XF86OptionPtr optlist, const char *name, int deflt) 25505b261ecSmrg{ 25605b261ecSmrg return LookupBoolOption(optlist, name, deflt, TRUE); 25705b261ecSmrg} 25805b261ecSmrg 2596747b715Smrgdouble 26035c4bbdfSmrgxf86SetPercentOption(XF86OptionPtr optlist, const char *name, double deflt) 2616747b715Smrg{ 2626747b715Smrg return LookupPercentOption(optlist, name, deflt, TRUE); 2636747b715Smrg} 2646747b715Smrg 26505b261ecSmrg/* 26605b261ecSmrg * These are like the Set*Option functions, but they don't mark the options 26705b261ecSmrg * as used. 26805b261ecSmrg */ 2696747b715Smrgint 27035c4bbdfSmrgxf86CheckIntOption(XF86OptionPtr optlist, const char *name, int deflt) 27105b261ecSmrg{ 27205b261ecSmrg return LookupIntOption(optlist, name, deflt, FALSE); 27305b261ecSmrg} 27405b261ecSmrg 2756747b715Smrgdouble 27635c4bbdfSmrgxf86CheckRealOption(XF86OptionPtr optlist, const char *name, double deflt) 27705b261ecSmrg{ 27805b261ecSmrg return LookupRealOption(optlist, name, deflt, FALSE); 27905b261ecSmrg} 28005b261ecSmrg 2816747b715Smrgchar * 28235c4bbdfSmrgxf86CheckStrOption(XF86OptionPtr optlist, const char *name, const char *deflt) 28305b261ecSmrg{ 28405b261ecSmrg return LookupStrOption(optlist, name, deflt, FALSE); 28505b261ecSmrg} 28605b261ecSmrg 2876747b715Smrgint 28835c4bbdfSmrgxf86CheckBoolOption(XF86OptionPtr optlist, const char *name, int deflt) 28905b261ecSmrg{ 29005b261ecSmrg return LookupBoolOption(optlist, name, deflt, FALSE); 29105b261ecSmrg} 29205b261ecSmrg 2936747b715Smrgdouble 29435c4bbdfSmrgxf86CheckPercentOption(XF86OptionPtr optlist, const char *name, double deflt) 2956747b715Smrg{ 2966747b715Smrg return LookupPercentOption(optlist, name, deflt, FALSE); 2976747b715Smrg} 29835c4bbdfSmrg 29905b261ecSmrg/* 30035c4bbdfSmrg * xf86AddNewOption() has the required property of replacing the option value 30105b261ecSmrg * if the option is already present. 30205b261ecSmrg */ 30335c4bbdfSmrgXF86OptionPtr 30435c4bbdfSmrgxf86ReplaceIntOption(XF86OptionPtr optlist, const char *name, const int val) 30505b261ecSmrg{ 30605b261ecSmrg char tmp[16]; 30735c4bbdfSmrg 30835c4bbdfSmrg snprintf(tmp, sizeof(tmp), "%i", val); 30935c4bbdfSmrg return xf86AddNewOption(optlist, name, tmp); 31005b261ecSmrg} 31105b261ecSmrg 31235c4bbdfSmrgXF86OptionPtr 31335c4bbdfSmrgxf86ReplaceRealOption(XF86OptionPtr optlist, const char *name, const double val) 31405b261ecSmrg{ 31505b261ecSmrg char tmp[32]; 31635c4bbdfSmrg 31735c4bbdfSmrg snprintf(tmp, sizeof(tmp), "%f", val); 31835c4bbdfSmrg return xf86AddNewOption(optlist, name, tmp); 31905b261ecSmrg} 32005b261ecSmrg 32135c4bbdfSmrgXF86OptionPtr 32235c4bbdfSmrgxf86ReplaceBoolOption(XF86OptionPtr optlist, const char *name, const Bool val) 32305b261ecSmrg{ 32435c4bbdfSmrg return xf86AddNewOption(optlist, name, val ? "True" : "False"); 32505b261ecSmrg} 32605b261ecSmrg 32735c4bbdfSmrgXF86OptionPtr 32835c4bbdfSmrgxf86ReplacePercentOption(XF86OptionPtr optlist, const char *name, 32935c4bbdfSmrg const double val) 3306747b715Smrg{ 3316747b715Smrg char tmp[16]; 33235c4bbdfSmrg 33335c4bbdfSmrg snprintf(tmp, sizeof(tmp), "%lf%%", val); 33435c4bbdfSmrg return xf86AddNewOption(optlist, name, tmp); 3356747b715Smrg} 3366747b715Smrg 33735c4bbdfSmrgXF86OptionPtr 33835c4bbdfSmrgxf86ReplaceStrOption(XF86OptionPtr optlist, const char *name, const char *val) 33905b261ecSmrg{ 34035c4bbdfSmrg return xf86AddNewOption(optlist, name, val); 34105b261ecSmrg} 34205b261ecSmrg 34335c4bbdfSmrgXF86OptionPtr 34435c4bbdfSmrgxf86AddNewOption(XF86OptionPtr head, const char *name, const char *val) 34505b261ecSmrg{ 34605b261ecSmrg /* XXX These should actually be allocated in the parser library. */ 347475c125cSmrg char *tmp = val ? strdup(val) : NULL; 34805b261ecSmrg char *tmp_name = strdup(name); 34905b261ecSmrg 35005b261ecSmrg return xf86addNewOption(head, tmp_name, tmp); 35105b261ecSmrg} 35205b261ecSmrg 35335c4bbdfSmrgXF86OptionPtr 35405b261ecSmrgxf86NewOption(char *name, char *value) 35505b261ecSmrg{ 35605b261ecSmrg return xf86newOption(name, value); 35705b261ecSmrg} 35805b261ecSmrg 35935c4bbdfSmrgXF86OptionPtr 36035c4bbdfSmrgxf86NextOption(XF86OptionPtr list) 36105b261ecSmrg{ 36205b261ecSmrg return xf86nextOption(list); 36305b261ecSmrg} 36405b261ecSmrg 36535c4bbdfSmrgXF86OptionPtr 36605b261ecSmrgxf86OptionListCreate(const char **options, int count, int used) 36705b261ecSmrg{ 36835c4bbdfSmrg return xf86optionListCreate(options, count, used); 36905b261ecSmrg} 37005b261ecSmrg 37135c4bbdfSmrgXF86OptionPtr 37235c4bbdfSmrgxf86OptionListMerge(XF86OptionPtr head, XF86OptionPtr tail) 37305b261ecSmrg{ 37435c4bbdfSmrg return xf86optionListMerge(head, tail); 37505b261ecSmrg} 37605b261ecSmrg 3776747b715Smrgvoid 37835c4bbdfSmrgxf86OptionListFree(XF86OptionPtr opt) 37905b261ecSmrg{ 38035c4bbdfSmrg xf86optionListFree(opt); 38105b261ecSmrg} 38205b261ecSmrg 3836747b715Smrgchar * 38435c4bbdfSmrgxf86OptionName(XF86OptionPtr opt) 38505b261ecSmrg{ 38635c4bbdfSmrg return xf86optionName(opt); 38705b261ecSmrg} 38805b261ecSmrg 3896747b715Smrgchar * 39035c4bbdfSmrgxf86OptionValue(XF86OptionPtr opt) 39105b261ecSmrg{ 39235c4bbdfSmrg return xf86optionValue(opt); 39305b261ecSmrg} 39405b261ecSmrg 3956747b715Smrgvoid 39635c4bbdfSmrgxf86OptionListReport(XF86OptionPtr parm) 39705b261ecSmrg{ 39805b261ecSmrg XF86OptionPtr opts = parm; 39905b261ecSmrg 40035c4bbdfSmrg while (opts) { 40135c4bbdfSmrg if (xf86optionValue(opts)) 40235c4bbdfSmrg xf86ErrorFVerb(5, "\tOption \"%s\" \"%s\"\n", 40335c4bbdfSmrg xf86optionName(opts), xf86optionValue(opts)); 40435c4bbdfSmrg else 40535c4bbdfSmrg xf86ErrorFVerb(5, "\tOption \"%s\"\n", xf86optionName(opts)); 40635c4bbdfSmrg opts = xf86nextOption(opts); 40705b261ecSmrg } 40805b261ecSmrg} 40905b261ecSmrg 41005b261ecSmrg/* End of XInput-caused section */ 41105b261ecSmrg 41235c4bbdfSmrgXF86OptionPtr 41335c4bbdfSmrgxf86FindOption(XF86OptionPtr options, const char *name) 41405b261ecSmrg{ 41505b261ecSmrg return xf86findOption(options, name); 41605b261ecSmrg} 41705b261ecSmrg 41835c4bbdfSmrgconst char * 41935c4bbdfSmrgxf86FindOptionValue(XF86OptionPtr options, const char *name) 42005b261ecSmrg{ 42105b261ecSmrg return xf86findOptionValue(options, name); 42205b261ecSmrg} 42305b261ecSmrg 4246747b715Smrgvoid 42535c4bbdfSmrgxf86MarkOptionUsed(XF86OptionPtr option) 42605b261ecSmrg{ 42705b261ecSmrg if (option != NULL) 42835c4bbdfSmrg option->opt_used = TRUE; 42905b261ecSmrg} 43005b261ecSmrg 4316747b715Smrgvoid 43235c4bbdfSmrgxf86MarkOptionUsedByName(XF86OptionPtr options, const char *name) 43305b261ecSmrg{ 43405b261ecSmrg XF86OptionPtr opt; 43505b261ecSmrg 43605b261ecSmrg opt = xf86findOption(options, name); 43705b261ecSmrg if (opt != NULL) 43835c4bbdfSmrg opt->opt_used = TRUE; 43905b261ecSmrg} 44005b261ecSmrg 4416747b715SmrgBool 44235c4bbdfSmrgxf86CheckIfOptionUsed(XF86OptionPtr option) 44305b261ecSmrg{ 44405b261ecSmrg if (option != NULL) 44535c4bbdfSmrg return option->opt_used; 44605b261ecSmrg else 44735c4bbdfSmrg return FALSE; 44805b261ecSmrg} 44905b261ecSmrg 4506747b715SmrgBool 45135c4bbdfSmrgxf86CheckIfOptionUsedByName(XF86OptionPtr options, const char *name) 45205b261ecSmrg{ 45305b261ecSmrg XF86OptionPtr opt; 45405b261ecSmrg 45505b261ecSmrg opt = xf86findOption(options, name); 45605b261ecSmrg if (opt != NULL) 45735c4bbdfSmrg return opt->opt_used; 45805b261ecSmrg else 45935c4bbdfSmrg return FALSE; 46005b261ecSmrg} 46105b261ecSmrg 4626747b715Smrgvoid 46335c4bbdfSmrgxf86ShowUnusedOptions(int scrnIndex, XF86OptionPtr opt) 46405b261ecSmrg{ 46505b261ecSmrg while (opt) { 46635c4bbdfSmrg if (opt->opt_name && !opt->opt_used) { 46735c4bbdfSmrg xf86DrvMsg(scrnIndex, X_WARNING, "Option \"%s\" is not used\n", 46835c4bbdfSmrg opt->opt_name); 46935c4bbdfSmrg } 47035c4bbdfSmrg opt = opt->list.next; 47105b261ecSmrg } 47205b261ecSmrg} 47305b261ecSmrg 47405b261ecSmrgstatic Bool 47505b261ecSmrgGetBoolValue(OptionInfoPtr p, const char *s) 47605b261ecSmrg{ 477ed6184dfSmrg return xf86getBoolValue(&p->value.boolean, s); 47805b261ecSmrg} 47905b261ecSmrg 48005b261ecSmrgstatic Bool 48135c4bbdfSmrgParseOptionValue(int scrnIndex, XF86OptionPtr options, OptionInfoPtr p, 48235c4bbdfSmrg Bool markUsed) 48305b261ecSmrg{ 48435c4bbdfSmrg const char *s; 48535c4bbdfSmrg char *end; 48605b261ecSmrg Bool wasUsed = FALSE; 48705b261ecSmrg 48805b261ecSmrg if ((s = xf86findOptionValue(options, p->name)) != NULL) { 48935c4bbdfSmrg if (markUsed) { 49035c4bbdfSmrg wasUsed = xf86CheckIfOptionUsedByName(options, p->name); 49135c4bbdfSmrg xf86MarkOptionUsedByName(options, p->name); 49235c4bbdfSmrg } 49335c4bbdfSmrg switch (p->type) { 49435c4bbdfSmrg case OPTV_INTEGER: 49535c4bbdfSmrg if (*s == '\0') { 49635c4bbdfSmrg if (markUsed) { 49735c4bbdfSmrg xf86DrvMsg(scrnIndex, X_WARNING, 49835c4bbdfSmrg "Option \"%s\" requires an integer value\n", 49935c4bbdfSmrg p->name); 50035c4bbdfSmrg } 50135c4bbdfSmrg p->found = FALSE; 50235c4bbdfSmrg } 50335c4bbdfSmrg else { 50435c4bbdfSmrg p->value.num = strtoul(s, &end, 0); 50535c4bbdfSmrg if (*end == '\0') { 50635c4bbdfSmrg p->found = TRUE; 50735c4bbdfSmrg } 50835c4bbdfSmrg else { 50935c4bbdfSmrg if (markUsed) { 51035c4bbdfSmrg xf86DrvMsg(scrnIndex, X_WARNING, 51135c4bbdfSmrg "Option \"%s\" requires an integer value\n", 51235c4bbdfSmrg p->name); 51335c4bbdfSmrg } 51435c4bbdfSmrg p->found = FALSE; 51535c4bbdfSmrg } 51635c4bbdfSmrg } 51735c4bbdfSmrg break; 51835c4bbdfSmrg case OPTV_STRING: 51935c4bbdfSmrg if (*s == '\0') { 52035c4bbdfSmrg if (markUsed) { 52135c4bbdfSmrg xf86DrvMsg(scrnIndex, X_WARNING, 52235c4bbdfSmrg "Option \"%s\" requires a string value\n", 52335c4bbdfSmrg p->name); 52435c4bbdfSmrg } 52535c4bbdfSmrg p->found = FALSE; 52635c4bbdfSmrg } 52735c4bbdfSmrg else { 52835c4bbdfSmrg p->value.str = s; 52935c4bbdfSmrg p->found = TRUE; 53035c4bbdfSmrg } 53135c4bbdfSmrg break; 53235c4bbdfSmrg case OPTV_ANYSTR: 53335c4bbdfSmrg p->value.str = s; 53435c4bbdfSmrg p->found = TRUE; 53535c4bbdfSmrg break; 53635c4bbdfSmrg case OPTV_REAL: 53735c4bbdfSmrg if (*s == '\0') { 53835c4bbdfSmrg if (markUsed) { 53935c4bbdfSmrg xf86DrvMsg(scrnIndex, X_WARNING, 54035c4bbdfSmrg "Option \"%s\" requires a floating point " 54135c4bbdfSmrg "value\n", p->name); 54235c4bbdfSmrg } 54335c4bbdfSmrg p->found = FALSE; 54435c4bbdfSmrg } 54535c4bbdfSmrg else { 54635c4bbdfSmrg p->value.realnum = strtod(s, &end); 54735c4bbdfSmrg if (*end == '\0') { 54835c4bbdfSmrg p->found = TRUE; 54935c4bbdfSmrg } 55035c4bbdfSmrg else { 55135c4bbdfSmrg if (markUsed) { 55235c4bbdfSmrg xf86DrvMsg(scrnIndex, X_WARNING, 55335c4bbdfSmrg "Option \"%s\" requires a floating point " 55435c4bbdfSmrg "value\n", p->name); 55535c4bbdfSmrg } 55635c4bbdfSmrg p->found = FALSE; 55735c4bbdfSmrg } 55835c4bbdfSmrg } 55935c4bbdfSmrg break; 56035c4bbdfSmrg case OPTV_BOOLEAN: 56135c4bbdfSmrg if (GetBoolValue(p, s)) { 56235c4bbdfSmrg p->found = TRUE; 56335c4bbdfSmrg } 56435c4bbdfSmrg else { 56535c4bbdfSmrg if (markUsed) { 56635c4bbdfSmrg xf86DrvMsg(scrnIndex, X_WARNING, 56735c4bbdfSmrg "Option \"%s\" requires a boolean value\n", 56835c4bbdfSmrg p->name); 56935c4bbdfSmrg } 57035c4bbdfSmrg p->found = FALSE; 57135c4bbdfSmrg } 57235c4bbdfSmrg break; 57335c4bbdfSmrg case OPTV_PERCENT: 57435c4bbdfSmrg { 57535c4bbdfSmrg char tmp = 0; 57635c4bbdfSmrg 57735c4bbdfSmrg /* awkward match, but %% doesn't increase the match counter, 57835c4bbdfSmrg * hence 100 looks the same as 100% to the caller of sccanf 57935c4bbdfSmrg */ 58035c4bbdfSmrg if (sscanf(s, "%lf%c", &p->value.realnum, &tmp) != 2 || tmp != '%') { 58135c4bbdfSmrg if (markUsed) { 58235c4bbdfSmrg xf86DrvMsg(scrnIndex, X_WARNING, 58335c4bbdfSmrg "Option \"%s\" requires a percent value\n", 58435c4bbdfSmrg p->name); 58535c4bbdfSmrg } 58635c4bbdfSmrg p->found = FALSE; 58735c4bbdfSmrg } 58835c4bbdfSmrg else { 58935c4bbdfSmrg p->found = TRUE; 59035c4bbdfSmrg } 59135c4bbdfSmrg } 59235c4bbdfSmrg break; 59335c4bbdfSmrg case OPTV_FREQ: 59435c4bbdfSmrg if (*s == '\0') { 59535c4bbdfSmrg if (markUsed) { 59635c4bbdfSmrg xf86DrvMsg(scrnIndex, X_WARNING, 59735c4bbdfSmrg "Option \"%s\" requires a frequency value\n", 59835c4bbdfSmrg p->name); 59935c4bbdfSmrg } 60035c4bbdfSmrg p->found = FALSE; 60135c4bbdfSmrg } 60235c4bbdfSmrg else { 60335c4bbdfSmrg double freq = strtod(s, &end); 60435c4bbdfSmrg int units = 0; 60535c4bbdfSmrg 60635c4bbdfSmrg if (end != s) { 60735c4bbdfSmrg p->found = TRUE; 60835c4bbdfSmrg if (!xf86NameCmp(end, "Hz")) 60935c4bbdfSmrg units = 1; 61035c4bbdfSmrg else if (!xf86NameCmp(end, "kHz") || !xf86NameCmp(end, "k")) 61135c4bbdfSmrg units = 1000; 61235c4bbdfSmrg else if (!xf86NameCmp(end, "MHz") || !xf86NameCmp(end, "M")) 61335c4bbdfSmrg units = 1000000; 61435c4bbdfSmrg else { 61535c4bbdfSmrg if (markUsed) { 61635c4bbdfSmrg xf86DrvMsg(scrnIndex, X_WARNING, 61735c4bbdfSmrg "Option \"%s\" requires a frequency value\n", 61835c4bbdfSmrg p->name); 61935c4bbdfSmrg } 62035c4bbdfSmrg p->found = FALSE; 62135c4bbdfSmrg } 62235c4bbdfSmrg if (p->found) 62335c4bbdfSmrg freq *= (double) units; 62435c4bbdfSmrg } 62535c4bbdfSmrg else { 62635c4bbdfSmrg if (markUsed) { 62735c4bbdfSmrg xf86DrvMsg(scrnIndex, X_WARNING, 62835c4bbdfSmrg "Option \"%s\" requires a frequency value\n", 62935c4bbdfSmrg p->name); 63035c4bbdfSmrg } 63135c4bbdfSmrg p->found = FALSE; 63235c4bbdfSmrg } 63335c4bbdfSmrg if (p->found) { 63435c4bbdfSmrg p->value.freq.freq = freq; 63535c4bbdfSmrg p->value.freq.units = units; 63635c4bbdfSmrg } 63735c4bbdfSmrg } 63835c4bbdfSmrg break; 63935c4bbdfSmrg case OPTV_NONE: 64035c4bbdfSmrg /* Should never get here */ 64135c4bbdfSmrg p->found = FALSE; 64235c4bbdfSmrg break; 64335c4bbdfSmrg } 64435c4bbdfSmrg if (p->found && markUsed) { 64535c4bbdfSmrg int verb = 2; 64635c4bbdfSmrg 64735c4bbdfSmrg if (wasUsed) 64835c4bbdfSmrg verb = 4; 64935c4bbdfSmrg xf86DrvMsgVerb(scrnIndex, X_CONFIG, verb, "Option \"%s\"", p->name); 65035c4bbdfSmrg if (!(p->type == OPTV_BOOLEAN && *s == 0)) { 65135c4bbdfSmrg xf86ErrorFVerb(verb, " \"%s\"", s); 65235c4bbdfSmrg } 65335c4bbdfSmrg xf86ErrorFVerb(verb, "\n"); 65435c4bbdfSmrg } 65535c4bbdfSmrg } 65635c4bbdfSmrg else if (p->type == OPTV_BOOLEAN) { 65735c4bbdfSmrg /* Look for matches with options with or without a "No" prefix. */ 65835c4bbdfSmrg char *n, *newn; 65935c4bbdfSmrg OptionInfoRec opt; 66035c4bbdfSmrg 66135c4bbdfSmrg n = xf86NormalizeName(p->name); 66235c4bbdfSmrg if (!n) { 66335c4bbdfSmrg p->found = FALSE; 66435c4bbdfSmrg return FALSE; 66535c4bbdfSmrg } 66635c4bbdfSmrg if (strncmp(n, "no", 2) == 0) { 66735c4bbdfSmrg newn = n + 2; 66835c4bbdfSmrg } 66935c4bbdfSmrg else { 67035c4bbdfSmrg free(n); 67135c4bbdfSmrg if (asprintf(&n, "No%s", p->name) == -1) { 67235c4bbdfSmrg p->found = FALSE; 67335c4bbdfSmrg return FALSE; 67435c4bbdfSmrg } 67535c4bbdfSmrg newn = n; 67635c4bbdfSmrg } 67735c4bbdfSmrg if ((s = xf86findOptionValue(options, newn)) != NULL) { 67835c4bbdfSmrg if (markUsed) 67935c4bbdfSmrg xf86MarkOptionUsedByName(options, newn); 68035c4bbdfSmrg if (GetBoolValue(&opt, s)) { 681ed6184dfSmrg p->value.boolean = !opt.value.boolean; 68235c4bbdfSmrg p->found = TRUE; 68335c4bbdfSmrg } 68435c4bbdfSmrg else { 68535c4bbdfSmrg xf86DrvMsg(scrnIndex, X_WARNING, 68635c4bbdfSmrg "Option \"%s\" requires a boolean value\n", newn); 68735c4bbdfSmrg p->found = FALSE; 68835c4bbdfSmrg } 68935c4bbdfSmrg } 69035c4bbdfSmrg else { 69135c4bbdfSmrg p->found = FALSE; 69235c4bbdfSmrg } 69335c4bbdfSmrg if (p->found && markUsed) { 69435c4bbdfSmrg xf86DrvMsgVerb(scrnIndex, X_CONFIG, 2, "Option \"%s\"", newn); 69535c4bbdfSmrg if (*s != 0) { 69635c4bbdfSmrg xf86ErrorFVerb(2, " \"%s\"", s); 69735c4bbdfSmrg } 69835c4bbdfSmrg xf86ErrorFVerb(2, "\n"); 69935c4bbdfSmrg } 70035c4bbdfSmrg free(n); 70135c4bbdfSmrg } 70235c4bbdfSmrg else { 70335c4bbdfSmrg p->found = FALSE; 70405b261ecSmrg } 70505b261ecSmrg return p->found; 70605b261ecSmrg} 70705b261ecSmrg 7086747b715Smrgvoid 70935c4bbdfSmrgxf86ProcessOptions(int scrnIndex, XF86OptionPtr options, OptionInfoPtr optinfo) 71005b261ecSmrg{ 71105b261ecSmrg OptionInfoPtr p; 71205b261ecSmrg 71305b261ecSmrg for (p = optinfo; p->name != NULL; p++) { 71435c4bbdfSmrg ParseOptionValue(scrnIndex, options, p, TRUE); 71505b261ecSmrg } 71605b261ecSmrg} 71705b261ecSmrg 7186747b715SmrgOptionInfoPtr 71935c4bbdfSmrgxf86TokenToOptinfo(const OptionInfoRec * table, int token) 72005b261ecSmrg{ 72105b261ecSmrg const OptionInfoRec *p, *match = NULL, *set = NULL; 72205b261ecSmrg 72305b261ecSmrg if (!table) { 72435c4bbdfSmrg ErrorF("xf86TokenToOptinfo: table is NULL\n"); 72535c4bbdfSmrg return NULL; 72605b261ecSmrg } 72705b261ecSmrg 72805b261ecSmrg for (p = table; p->token >= 0; p++) { 72935c4bbdfSmrg if (p->token == token) { 73035c4bbdfSmrg match = p; 73135c4bbdfSmrg if (p->found) 73235c4bbdfSmrg set = p; 73335c4bbdfSmrg } 73405b261ecSmrg } 73505b261ecSmrg 73605b261ecSmrg if (set) 73735c4bbdfSmrg return (OptionInfoPtr) set; 73805b261ecSmrg else if (match) 73935c4bbdfSmrg return (OptionInfoPtr) match; 74005b261ecSmrg else 74135c4bbdfSmrg return NULL; 74205b261ecSmrg} 74305b261ecSmrg 7446747b715Smrgconst char * 74535c4bbdfSmrgxf86TokenToOptName(const OptionInfoRec * table, int token) 74605b261ecSmrg{ 74705b261ecSmrg const OptionInfoRec *p; 74805b261ecSmrg 74905b261ecSmrg p = xf86TokenToOptinfo(table, token); 75035c4bbdfSmrg return p ? p->name : NULL; 75105b261ecSmrg} 75205b261ecSmrg 7536747b715SmrgBool 75435c4bbdfSmrgxf86IsOptionSet(const OptionInfoRec * table, int token) 75505b261ecSmrg{ 75605b261ecSmrg OptionInfoPtr p; 75705b261ecSmrg 75805b261ecSmrg p = xf86TokenToOptinfo(table, token); 7596747b715Smrg return p && p->found; 76005b261ecSmrg} 76105b261ecSmrg 76235c4bbdfSmrgconst char * 76335c4bbdfSmrgxf86GetOptValString(const OptionInfoRec * table, int token) 76405b261ecSmrg{ 76505b261ecSmrg OptionInfoPtr p; 76605b261ecSmrg 76705b261ecSmrg p = xf86TokenToOptinfo(table, token); 76805b261ecSmrg if (p && p->found) 76935c4bbdfSmrg return p->value.str; 77005b261ecSmrg else 77135c4bbdfSmrg return NULL; 77205b261ecSmrg} 77305b261ecSmrg 7746747b715SmrgBool 77535c4bbdfSmrgxf86GetOptValInteger(const OptionInfoRec * table, int token, int *value) 77605b261ecSmrg{ 77705b261ecSmrg OptionInfoPtr p; 77805b261ecSmrg 77905b261ecSmrg p = xf86TokenToOptinfo(table, token); 78005b261ecSmrg if (p && p->found) { 78135c4bbdfSmrg *value = p->value.num; 78235c4bbdfSmrg return TRUE; 78335c4bbdfSmrg } 78435c4bbdfSmrg else 78535c4bbdfSmrg return FALSE; 78605b261ecSmrg} 78705b261ecSmrg 7886747b715SmrgBool 78935c4bbdfSmrgxf86GetOptValULong(const OptionInfoRec * table, int token, unsigned long *value) 79005b261ecSmrg{ 79105b261ecSmrg OptionInfoPtr p; 79205b261ecSmrg 79305b261ecSmrg p = xf86TokenToOptinfo(table, token); 79405b261ecSmrg if (p && p->found) { 79535c4bbdfSmrg *value = p->value.num; 79635c4bbdfSmrg return TRUE; 79735c4bbdfSmrg } 79835c4bbdfSmrg else 79935c4bbdfSmrg return FALSE; 80005b261ecSmrg} 80105b261ecSmrg 8026747b715SmrgBool 80335c4bbdfSmrgxf86GetOptValReal(const OptionInfoRec * table, int token, double *value) 80405b261ecSmrg{ 80505b261ecSmrg OptionInfoPtr p; 80605b261ecSmrg 80705b261ecSmrg p = xf86TokenToOptinfo(table, token); 80805b261ecSmrg if (p && p->found) { 80935c4bbdfSmrg *value = p->value.realnum; 81035c4bbdfSmrg return TRUE; 81135c4bbdfSmrg } 81235c4bbdfSmrg else 81335c4bbdfSmrg return FALSE; 81405b261ecSmrg} 81505b261ecSmrg 8166747b715SmrgBool 81735c4bbdfSmrgxf86GetOptValFreq(const OptionInfoRec * table, int token, 81835c4bbdfSmrg OptFreqUnits expectedUnits, double *value) 81905b261ecSmrg{ 82005b261ecSmrg OptionInfoPtr p; 82105b261ecSmrg 82205b261ecSmrg p = xf86TokenToOptinfo(table, token); 82305b261ecSmrg if (p && p->found) { 82435c4bbdfSmrg if (p->value.freq.units > 0) { 82535c4bbdfSmrg /* Units give, so the scaling is known. */ 82635c4bbdfSmrg switch (expectedUnits) { 82735c4bbdfSmrg case OPTUNITS_HZ: 82835c4bbdfSmrg *value = p->value.freq.freq; 82935c4bbdfSmrg break; 83035c4bbdfSmrg case OPTUNITS_KHZ: 83135c4bbdfSmrg *value = p->value.freq.freq / 1000.0; 83235c4bbdfSmrg break; 83335c4bbdfSmrg case OPTUNITS_MHZ: 83435c4bbdfSmrg *value = p->value.freq.freq / 1000000.0; 83535c4bbdfSmrg break; 83635c4bbdfSmrg } 83735c4bbdfSmrg } 83835c4bbdfSmrg else { 83935c4bbdfSmrg /* No units given, so try to guess the scaling. */ 84035c4bbdfSmrg switch (expectedUnits) { 84135c4bbdfSmrg case OPTUNITS_HZ: 84235c4bbdfSmrg *value = p->value.freq.freq; 84335c4bbdfSmrg break; 84435c4bbdfSmrg case OPTUNITS_KHZ: 84535c4bbdfSmrg if (p->value.freq.freq > 1000.0) 84635c4bbdfSmrg *value = p->value.freq.freq / 1000.0; 84735c4bbdfSmrg else 84835c4bbdfSmrg *value = p->value.freq.freq; 84935c4bbdfSmrg break; 85035c4bbdfSmrg case OPTUNITS_MHZ: 85135c4bbdfSmrg if (p->value.freq.freq > 1000000.0) 85235c4bbdfSmrg *value = p->value.freq.freq / 1000000.0; 85335c4bbdfSmrg else if (p->value.freq.freq > 1000.0) 85435c4bbdfSmrg *value = p->value.freq.freq / 1000.0; 85535c4bbdfSmrg else 85635c4bbdfSmrg *value = p->value.freq.freq; 85735c4bbdfSmrg } 85835c4bbdfSmrg } 85935c4bbdfSmrg return TRUE; 86035c4bbdfSmrg } 86135c4bbdfSmrg else 86235c4bbdfSmrg return FALSE; 86305b261ecSmrg} 86405b261ecSmrg 8656747b715SmrgBool 86635c4bbdfSmrgxf86GetOptValBool(const OptionInfoRec * table, int token, Bool *value) 86705b261ecSmrg{ 86805b261ecSmrg OptionInfoPtr p; 86905b261ecSmrg 87005b261ecSmrg p = xf86TokenToOptinfo(table, token); 87105b261ecSmrg if (p && p->found) { 872ed6184dfSmrg *value = p->value.boolean; 87335c4bbdfSmrg return TRUE; 87435c4bbdfSmrg } 87535c4bbdfSmrg else 87635c4bbdfSmrg return FALSE; 87705b261ecSmrg} 87805b261ecSmrg 8796747b715SmrgBool 88035c4bbdfSmrgxf86ReturnOptValBool(const OptionInfoRec * table, int token, Bool def) 88105b261ecSmrg{ 88205b261ecSmrg OptionInfoPtr p; 88305b261ecSmrg 88405b261ecSmrg p = xf86TokenToOptinfo(table, token); 88505b261ecSmrg if (p && p->found) { 886ed6184dfSmrg return p->value.boolean; 88735c4bbdfSmrg } 88835c4bbdfSmrg else 88935c4bbdfSmrg return def; 89005b261ecSmrg} 89105b261ecSmrg 8926747b715Smrgint 89305b261ecSmrgxf86NameCmp(const char *s1, const char *s2) 89405b261ecSmrg{ 89505b261ecSmrg return xf86nameCompare(s1, s2); 89605b261ecSmrg} 89705b261ecSmrg 89805b261ecSmrgchar * 89905b261ecSmrgxf86NormalizeName(const char *s) 90005b261ecSmrg{ 90105b261ecSmrg char *ret, *q; 90205b261ecSmrg const char *p; 90305b261ecSmrg 90405b261ecSmrg if (s == NULL) 90535c4bbdfSmrg return NULL; 90605b261ecSmrg 9076747b715Smrg ret = malloc(strlen(s) + 1); 90805b261ecSmrg for (p = s, q = ret; *p != 0; p++) { 90935c4bbdfSmrg switch (*p) { 91035c4bbdfSmrg case '_': 91135c4bbdfSmrg case ' ': 91235c4bbdfSmrg case '\t': 91335c4bbdfSmrg continue; 91435c4bbdfSmrg default: 91535c4bbdfSmrg if (isupper(*p)) 91635c4bbdfSmrg *q++ = tolower(*p); 91735c4bbdfSmrg else 91835c4bbdfSmrg *q++ = *p; 91935c4bbdfSmrg } 92005b261ecSmrg } 92105b261ecSmrg *q = '\0'; 92205b261ecSmrg return ret; 92305b261ecSmrg} 924