#!/usr/bin/python # -*- coding: utf-8 -*- # # inf2mondb.py: convert .inf files for monitors to MonitorDB # # Matt Wilson # # Copyright 2002 Red Hat, Inc. # # Some fixes by Onur Küçük # # This software may be freely redistributed under the terms of the GNU # library public license. import sys import string import re def usage(): print "Usage: inf2mondb.py filename.inf" sys.exit(1) if len(sys.argv) < 2: usage() try: f = open(sys.argv[1], 'r') except IOError, (errno, str): print "Unable to open %s: %s" % (sys.argv[1], str) sys.exit(1) lines = f.readlines() f.close() # the current section section = None # monitors - a dictionary keyed off manufacturers monitors = {} # a dictionary of manufacturers we're looking at manufacturers = {} # registry sections mapped back to the install sections regsections = {} # install sections that map back to monitor definitions instsections = {} # a big fat dictionary of strings to use later on. strings = {} class Monitor: def __repr__(self): return "%s; %s; %s; %s; %s" % (self.man, self.descr, self.edid, self.hsync, self.vsync) def __init__(self, man, id, edid): self.descr = "" self.man = man self.hsync = "" self.vsync = "" self.id = id self.edid = edid sectRe = re.compile(r'\[*\]') sectSplit = re.compile(r'[\[\]]') infoSplit = re.compile(r'[%=\\;]') # This RE is for EISA info lines # %D5259A%=D5259A, Monitor\HWP0487 monitor1Re = re.compile(r'%*.%.*=.*,.*Monitor\\') # This one is for legacy entries # %3020% =PB3020, MonID_PB3020 monitor2Re = re.compile(r'%*.%.*=.*,.*MonID_') # sync values that might be in the strings section sync_keys = {} for line in lines: tmp = string.strip(line) if tmp and tmp[0] == ';': continue if sectRe.search (line, 1): section = string.lower(sectSplit.split (line)[1]) continue if section == "manufacturer": tmp = infoSplit.split (line) if len(tmp) > 1: manufacturer = string.lower(tmp[1]) if manufacturers.has_key (tmp[1]): raise RuntimeError, "Duplicate manufacturer entries" else: manufacturers[string.lower(string.strip(tmp[3].split(",")[0]))] = string.lower(string.strip(tmp[1])) # if we're in a manufacturer section, we need to jot down # the devices elif manufacturers.has_key(section): # Find monitor inf IDs and EISA ids: monre = None # EISA entries # %D5259A%=D5259A, Monitor\HWP0487 if monitor1Re.search(line, 1): monre = monitor1Re # older non EISA entries # %3020% =PB3020, MonID_PB3020 elif monitor2Re.search(line, 1): monre = monitor2Re if monre: end = monre.search(line, 1).end() id = string.strip(string.split(line, '%')[1]) if monre == monitor1Re: # all EDID ID strings are 7 chars edid = string.strip(line[end:])[0:7] else: edid = "0" # we need to get the install section for this device rhs = string.strip(string.split (line, '=')[1]) install = string.lower(string.strip(string.split (rhs, ',')[0])) if instsections.has_key (install): instsections[install].append ((section, id)) else: instsections[install] = [ (section, id) ] if not monitors.has_key (section): monitors[section] = {} monitors[section][id] = Monitor(section, id, edid) elif section == "strings": tmp = string.strip(tmp) if not tmp: continue tmp = string.split (line, '=') if len (tmp) < 2: continue key = string.lower(string.strip(tmp[0])) tmp = string.split(string.strip(tmp[1]), '"') if len (tmp) > 1: value = tmp[1] else: value = tmp[0] strings[key] = string.strip(value) # Deal with sync lines in the strings section if sync_keys.has_key(key): sync = string.split(value, ",") for (man, mon) in sync_keys[key]: monitors[man][mon].hsync = string.strip(sync[0]) monitors[man][mon].vsync = string.strip(sync[1]) # these are the sections that tell us which AddReg to use # AddReg=PBCOM14L.AddReg, 1024, DPMS elif instsections.has_key(section): if string.find (line, "AddReg=") >= 0: rhs = string.split (line, '=')[1] # PBCOM14L.AddReg, 1024, DPMS registry = string.lower(string.strip(string.split(rhs, ',')[0])) # add this monitor to the list of monitors that will # use this registry entry if regsections.has_key(registry): regsections[registry].append (section) else: regsections[registry] = [ section ] # these are the actual AddReg entries. Look up in our table # to find which elif regsections.has_key(section): if string.find(line, 'HKR') >= 0: ids = regsections[section] # make a list of all the monitors pointing to # this registry section via install sections mons = [] for id in ids: mons = mons + instsections[id] if string.find(line, 'HKR,"MODES') >= 0: modes = string.split(line, '"') sync = string.split(modes[3], ',') for (man, mon) in mons: monitors[man][mon].hsync = string.strip(sync[0]) monitors[man][mon].vsync = string.strip(sync[1]) else: # Sync lines must be somewhere else, maybe in the strings section keyval = None try: keyval = string.split(line,",")[4] except IndexError: pass if keyval and string.find(keyval, "KeyValue") >= 0: keyval = string.replace(string.strip(keyval), "%", "").lower() sync_keys[keyval] = mons for man in manufacturers.keys(): for monitor in monitors[man].values(): # OK, I know it's hacked up to look up these strings way down # here, but .inf format is CRAP. try: monitor.descr = strings[string.lower(monitor.id)] except KeyError: monitor.descr = monitor.id try: monitor.man = strings[string.lower(manufacturers[man])] except: monitor.man = manufacturers[man] print monitor