summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2010-05-18 11:12:49 +1000
committerKeith Packard <keithp@keithp.com>2010-05-18 15:43:51 -0700
commitd88ba7721d2d3b58cdc664fd4c23a3c5e2a5f909 (patch)
tree80b64d2ed0c450d093156b1be4ca626228eeb78c
parent673eb707ce6737284c4886265ba149c5587a74e2 (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.c5
-rw-r--r--hw/xfree86/common/xf86Opt.h4
-rw-r--r--hw/xfree86/common/xf86Option.c47
-rw-r--r--hw/xfree86/common/xf86ShowOpts.c2
-rw-r--r--hw/xfree86/doc/sgml/DESIGN.sgml6
-rw-r--r--hw/xwin/winconfig.c37
-rw-r--r--hw/xwin/winconfig.h2
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);