diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2010-05-18 11:12:49 +1000 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2010-05-18 15:43:51 -0700 |
commit | d88ba7721d2d3b58cdc664fd4c23a3c5e2a5f909 (patch) | |
tree | 80b64d2ed0c450d093156b1be4ca626228eeb78c | |
parent | 673eb707ce6737284c4886265ba149c5587a74e2 (diff) |
xfree86: Add option parsing for percent options.
In some cases, an option of "50%" would be preferable over fixed value
configuration - especially if the actual values are autoprobed.
Add a new set of functions to parse percent values from configurations.
The percent value parsing differs slightly - if the option is not to marked
as used (e.g. xf86CheckPercentOption()), no warning is emitted to the log
file if the value is not a percent value. This allows double-options (either
as % or as absolute number) without warnings.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Dan Nicholson <dbn.lists@gmail.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r-- | hw/xfree86/common/xf86Configure.c | 5 | ||||
-rw-r--r-- | hw/xfree86/common/xf86Opt.h | 4 | ||||
-rw-r--r-- | hw/xfree86/common/xf86Option.c | 47 | ||||
-rw-r--r-- | hw/xfree86/common/xf86ShowOpts.c | 2 | ||||
-rw-r--r-- | hw/xfree86/doc/sgml/DESIGN.sgml | 6 | ||||
-rw-r--r-- | hw/xwin/winconfig.c | 37 | ||||
-rw-r--r-- | hw/xwin/winconfig.h | 2 |
7 files changed, 102 insertions, 1 deletions
diff --git a/hw/xfree86/common/xf86Configure.c b/hw/xfree86/common/xf86Configure.c index ef61e4698..c590bda49 100644 --- a/hw/xfree86/common/xf86Configure.c +++ b/hw/xfree86/common/xf86Configure.c @@ -339,6 +339,8 @@ optionTypeToSting(OptionValueType type) return "[<bool>]"; case OPTV_FREQ: return "<freq>"; + case OPTV_PERCENT: + return "<percent>"; default: return ""; } @@ -384,7 +386,8 @@ configureDeviceSection (int screennum) " ### Available Driver options are:-\n" " ### Values: <i>: integer, <f>: float, " "<bool>: \"True\"/\"False\",\n" - " ### <string>: \"String\", <freq>: \"<f> Hz/kHz/MHz\"\n" + " ### <string>: \"String\", <freq>: \"<f> Hz/kHz/MHz\",\n" + " ### <percent>: \"<f>%\"\n" " ### [arg]: arg optional\n"; ptr->dev_comment = xstrdup(descrip); if (ptr->dev_comment) { diff --git a/hw/xfree86/common/xf86Opt.h b/hw/xfree86/common/xf86Opt.h index ce3d76724..d75d3bf87 100644 --- a/hw/xfree86/common/xf86Opt.h +++ b/hw/xfree86/common/xf86Opt.h @@ -51,6 +51,7 @@ typedef enum { OPTV_ANYSTR, /* Any string, including an empty one */ OPTV_REAL, OPTV_BOOLEAN, + OPTV_PERCENT, OPTV_FREQ } OptionValueType; @@ -72,10 +73,12 @@ extern _X_EXPORT int xf86SetIntOption(pointer optlist, const char *name, int def extern _X_EXPORT double xf86SetRealOption(pointer optlist, const char *name, double deflt); extern _X_EXPORT char *xf86SetStrOption(pointer optlist, const char *name, char *deflt); extern _X_EXPORT int xf86SetBoolOption(pointer list, const char *name, int deflt ); +extern _X_EXPORT double xf86SetPercentOption(pointer list, const char *name, double deflt ); extern _X_EXPORT int xf86CheckIntOption(pointer optlist, const char *name, int deflt); extern _X_EXPORT double xf86CheckRealOption(pointer optlist, const char *name, double deflt); extern _X_EXPORT char *xf86CheckStrOption(pointer optlist, const char *name, char *deflt); extern _X_EXPORT int xf86CheckBoolOption(pointer list, const char *name, int deflt ); +extern _X_EXPORT double xf86CheckPercentOption(pointer list, const char *name, double deflt ); extern _X_EXPORT pointer xf86AddNewOption(pointer head, const char *name, const char *val ); extern _X_EXPORT pointer xf86NewOption(char *name, char *value ); extern _X_EXPORT pointer xf86NextOption(pointer list ); @@ -109,5 +112,6 @@ extern _X_EXPORT char *xf86NormalizeName(const char *s); extern _X_EXPORT pointer xf86ReplaceIntOption(pointer optlist, const char *name, const int val); extern _X_EXPORT pointer xf86ReplaceRealOption(pointer optlist, const char *name, const double val); extern _X_EXPORT pointer xf86ReplaceBoolOption(pointer optlist, const char *name, const Bool val); +extern _X_EXPORT pointer xf86ReplacePercentOption(pointer optlist, const char *name, const double val); extern _X_EXPORT pointer xf86ReplaceStrOption(pointer optlist, const char *name, const char* val); #endif diff --git a/hw/xfree86/common/xf86Option.c b/hw/xfree86/common/xf86Option.c index 699204ce5..8be893cc3 100644 --- a/hw/xfree86/common/xf86Option.c +++ b/hw/xfree86/common/xf86Option.c @@ -223,6 +223,18 @@ LookupBoolOption(pointer optlist, const char *name, int deflt, Bool markUsed) return deflt; } +static int +LookupPercentOption(pointer optlist, const char *name, double deflt, Bool markUsed) +{ + OptionInfoRec o; + + o.name = name; + o.type = OPTV_PERCENT; + if (ParseOptionValue(-1, optlist, &o, markUsed)) + deflt = o.value.realnum; + return deflt; +} + /* These xf86Set* functions are intended for use by non-screen specific code */ int @@ -252,6 +264,12 @@ xf86SetBoolOption(pointer optlist, const char *name, int deflt) return LookupBoolOption(optlist, name, deflt, TRUE); } +double +xf86SetPercentOption(pointer optlist, const char *name, double deflt) +{ + return LookupPercentOption(optlist, name, deflt, TRUE); +} + /* * These are like the Set*Option functions, but they don't mark the options * as used. @@ -283,6 +301,12 @@ xf86CheckBoolOption(pointer optlist, const char *name, int deflt) return LookupBoolOption(optlist, name, deflt, FALSE); } + +double +xf86CheckPercentOption(pointer optlist, const char *name, double deflt) +{ + return LookupPercentOption(optlist, name, deflt, FALSE); +} /* * addNewOption() has the required property of replacing the option value * if the option is already present. @@ -310,6 +334,14 @@ xf86ReplaceBoolOption(pointer optlist, const char *name, const Bool val) } pointer +xf86ReplacePercentOption(pointer optlist, const char *name, const double val) +{ + char tmp[16]; + sprintf(tmp, "%lf%%", val); + return xf86AddNewOption(optlist,name,tmp); +} + +pointer xf86ReplaceStrOption(pointer optlist, const char *name, const char* val) { return xf86AddNewOption(optlist,name,val); @@ -533,6 +565,21 @@ ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p, p->found = FALSE; } break; + case OPTV_PERCENT: + { + char tmp = 0; + /* awkward match, but %% doesn't increase the match counter, + * hence 100 looks the same as 100% to the caller of sccanf + */ + if (sscanf(s, "%lf%c", &p->value.realnum, &tmp) != 2 || tmp != '%') { + xf86DrvMsg(scrnIndex, X_WARNING, + "Option \"%s\" requires a percent value\n", p->name); + p->found = FALSE; + } else { + p->found = TRUE; + } + } + break; case OPTV_FREQ: if (*s == '\0') { xf86DrvMsg(scrnIndex, X_WARNING, diff --git a/hw/xfree86/common/xf86ShowOpts.c b/hw/xfree86/common/xf86ShowOpts.c index ff4b651c1..eac25d701 100644 --- a/hw/xfree86/common/xf86ShowOpts.c +++ b/hw/xfree86/common/xf86ShowOpts.c @@ -70,6 +70,8 @@ optionTypeToSting(OptionValueType type) return "<bool>"; case OPTV_FREQ: return "<freq>"; + case OPTV_PERCENT: + return "<percent>"; default: return "<undef>"; } diff --git a/hw/xfree86/doc/sgml/DESIGN.sgml b/hw/xfree86/doc/sgml/DESIGN.sgml index e95df7999..8999e0cb0 100644 --- a/hw/xfree86/doc/sgml/DESIGN.sgml +++ b/hw/xfree86/doc/sgml/DESIGN.sgml @@ -2528,6 +2528,7 @@ Next, the higher level functions that most drivers would use. OPTV_ANYSTR, /* Any string, including an empty one */ OPTV_REAL, OPTV_BOOLEAN, + OPTV_PERCENT, OPTV_FREQ } OptionValueType; @@ -2555,6 +2556,11 @@ Next, the higher level functions that most drivers would use. &s.code;freq.units&e.code; is set to &s.code;0&e.code;, and &s.code;freq.freq&e.code; is unscaled. + &s.code;OPTV_PERCENT&e.code; can be used for option values that are + specified in percent (e.g. "20%"). These values are a floating point + number with a percent sign appended. If the percent sign is missing, + the parser will fail to match the value. + Typical usage is to setup an array of &s.code;OptionInfoRecs&e.code; with all fields initialised. The &s.code;value&e.code; and &s.code;found&e.code; fields get diff --git a/hw/xwin/winconfig.c b/hw/xwin/winconfig.c index 971d381a3..c2dd05693 100644 --- a/hw/xwin/winconfig.c +++ b/hw/xwin/winconfig.c @@ -673,6 +673,18 @@ winSetRealOption (pointer optlist, const char *name, double deflt) deflt = o.value.realnum; return deflt; } + +double +winSetPercentOption (pointer optlist, const char *name, double deflt) +{ + OptionInfoRec o; + + o.name = name; + o.type = OPTV_PERCENT; + if (ParseOptionValue (-1, optlist, &o)) + deflt = o.value.realnum; + return deflt; +} #endif @@ -851,6 +863,31 @@ ParseOptionValue (int scrnIndex, pointer options, OptionInfoPtr p) p->found = FALSE; } break; + case OPTV_PERCENT: + if (*s == '\0') + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires a percent value\n", + p->name); + p->found = FALSE; + } + else + { + double percent = strtod (s, &end); + + if (end != s && winNameCompare (end, "%")) + { + p->found = TRUE; + p->value.realnum = percent; + } + else + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires a frequency value\n", + p->name); + p->found = FALSE; + } + } case OPTV_FREQ: if (*s == '\0') { diff --git a/hw/xwin/winconfig.h b/hw/xwin/winconfig.h index 058884abc..4699ca8ef 100644 --- a/hw/xwin/winconfig.h +++ b/hw/xwin/winconfig.h @@ -256,6 +256,7 @@ typedef enum OPTV_ANYSTR, /* Any string, including an empty one */ OPTV_REAL, OPTV_BOOLEAN, + OPTV_PERCENT, OPTV_FREQ } OptionValueType; @@ -289,6 +290,7 @@ char *winSetStrOption (pointer optlist, const char *name, char *deflt); int winSetBoolOption (pointer optlist, const char *name, int deflt); int winSetIntOption (pointer optlist, const char *name, int deflt); double winSetRealOption (pointer optlist, const char *name, double deflt); +double winSetPercentOption (pointer optlist, const char *name, double deflt); #ifdef XWIN_XF86CONFIG XF86OptionPtr winFindOption (XF86OptionPtr list, const char *name); char *winFindOptionValue (XF86OptionPtr list, const char *name); |