[PATCH] xfree86: Add option parsing for percent options.

Peter Hutterer peter.hutterer at who-t.net
Wed May 12 23:07:44 PDT 2010


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 at who-t.net>
---
This would be quite useful in a few input drivers, especially now that we
have xorg.conf snippets. Best example here are the synaptics Area options,
where it'd be much easier to just specify the bottom area as 80% instead of
guessing what the touchpad may have.

One question is of course if we should allow the values to be floats instead
of ints, not sure if we need something like 0.2% but I guess it might not
hurt, either.

 hw/xfree86/common/xf86Opt.h    |    4 +++
 hw/xfree86/common/xf86Option.c |   48 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+), 0 deletions(-)

diff --git a/hw/xfree86/common/xf86Opt.h b/hw/xfree86/common/xf86Opt.h
index ce3d767..479c513 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 int xf86SetPercentOption(pointer list, const char *name, int 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 int xf86CheckPercentOption(pointer list, const char *name, int 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 int 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 a2868bf..ab86ace 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, int deflt, Bool markUsed)
+{
+    OptionInfoRec o;
+
+    o.name = name;
+    o.type = OPTV_PERCENT;
+    if (ParseOptionValue(-1, optlist, &o, markUsed))
+	deflt = o.value.num;
+    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);
 }
 
+int
+xf86SetPercentOption(pointer optlist, const char *name, int 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);
 }
 
+
+int
+xf86CheckPercentOption(pointer optlist, const char *name, int 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 int val)
+{
+    char tmp[16];
+    sprintf(tmp, "%d%%", val);
+    return xf86AddNewOption(optlist,name,tmp);
+}
+
+pointer
 xf86ReplaceStrOption(pointer optlist, const char *name, const char* val)
 {
       return xf86AddNewOption(optlist,name,val);
@@ -533,6 +565,22 @@ ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p,
 		p->found = FALSE;
 	    }
 	    break;
+	case OPTV_PERCENT:
+	    {
+		char tmp[2];
+		/* awkward match, but %% doesn't increase the match counter,
+		 * hence 100 looks the same as 100% to the caller of sccanf
+		 */
+		if (sscanf(s, "%ld%1[%]", &p->value.num, tmp) != 2) {
+		    if (markUsed)
+			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,
-- 
1.7.0.1


More information about the xorg-devel mailing list