# Python interface to DRI configuration # Copyright (C) 2003-2006 Felix Kuehling # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Contact: http://fxk.de.vu/ import os import string import re import xml.parsers.expat class Error (Exception): """ Base class for DRIError and XMLError """ def __init__ (self, problem): self.problem = problem def __str__ (self): return self.problem class DRIError (Error): """ Errors interfacing with xdriinfo """ pass class XMLError (Error): """ Errors in the DRI configuration data """ pass def XDriInfo (argStr, dpy = None): """ Call xdriinfo and raise DRIError on different failure conditions """ if dpy != None: dpyStr = "-display " + dpy + " " else: dpyStr = "" infopipe = os.popen ("xdriinfo " + dpyStr + argStr, "r") driInfo = infopipe.read() result = infopipe.close() if result != None: signal = result & 0xff status = result >> 8 if signal != 0: raise DRIError ("XDriInfo killed by signal " + signal + ".") elif status == 127: raise DRIError ("XDriInfo not found.") else: raise DRIError ("XDriInfo returned with non-zero exit code.") return driInfo def StrToValue (str, type): """ Helper: convert str to given type. Raises an XMLError if str is not of the correct type. """ try: if type == "int" or type == "enum": return int (str); elif type == "float": return float (str); else: if str == "true": return 1 elif str == "false": return 0 else: raise ValueError except ValueError: raise XMLError ("invalid value '" + str + "' for type '" + type + "'") def ValueToStr (value, type): """ Helper: convert value of given type to string. """ if type == "int" or type == "enum" or type == "float": return str(value) elif value: return "true" else: return "false" def GetDesc (desc, preferredLangs): """ Helper: get a description with a list of language preferences. If the specified languages are not available then try english. If that doesn't work either, return any description. If there are no descriptions at all, return None. """ for lang in preferredLangs: if desc.has_key (lang): return desc[lang] if desc.has_key ("en"): return desc["en"] if len(desc.values()) > 0: return desc.values()[0] return None class Range: """ An interval """ def __init__ (self, str, type): """ Parse str as a range. Raises an XMLError if str is not a legal range. """ assert type == "int" or type == "enum" or type == "float" list = string.split (str, ":") if len (list) == 0 or len (list) > 2: raise XMLError ("Invalid range '" + str + "'") if len (list) >= 1: self.start = StrToValue (list[0], type) if len (list) == 2: self.end = StrToValue (list[1], type) else: self.end = self.start def __str__ (self): if self.start == self.end: return str(self.start) else: return str(self.start) + ":" + str(self.end) def empty (self): return self.start == self.end class OptDesc: """ An option description in one language with enum values. """ def __init__ (self, lang, text): self.lang = lang self.text = text self.enums = {} def __str__ (self): result = '\n' for value in sort(self.enums.keys()): result = result + '\n' result = result + '' return result class OptInfo: """ All advertised information about an option. """ def __init__ (self, name, type, default, valid = None): """ Initialize option information. Raises XMLError if - type is illegal - default is not a valid value of type - valid attribute is specified for a bool option - valid is specified but illegal """ self.name = name if type != "int" and type != "enum" and type != "float" \ and type != "bool": raise XMLError ("invalid type '" + type + "'") self.type = type self.valid = None if valid: if type == "bool": raise XMLError ( "valid attribute is not allowed with bool options") else: self.valid = [Range(x, type) for x in string.split (valid, ",")] if not self.validate (default): raise XMLError ("default value is out of valid range") else: self.default = StrToValue (default, type) self.desc = {} def __str__ (self): result = '