inf2mondb 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. #
  4. # inf2mondb.py: convert .inf files for monitors to MonitorDB
  5. #
  6. # Matt Wilson <msw@redhat.com>
  7. #
  8. # Copyright 2002 Red Hat, Inc.
  9. #
  10. # Some fixes by Onur Küçük <onur@pardus.org.tr>
  11. #
  12. # This software may be freely redistributed under the terms of the GNU
  13. # library public license.
  14. import sys
  15. import string
  16. import re
  17. def usage():
  18. print("Usage: inf2mondb.py filename.inf")
  19. sys.exit(1)
  20. if len(sys.argv) < 2:
  21. usage()
  22. try:
  23. f = open(sys.argv[1], 'r')
  24. except IOError as xxx_todo_changeme:
  25. (errno, str) = xxx_todo_changeme.args
  26. print("Unable to open %s: %s" % (sys.argv[1], str))
  27. sys.exit(1)
  28. lines = f.readlines()
  29. f.close()
  30. # the current section
  31. section = None
  32. # monitors - a dictionary keyed off manufacturers
  33. monitors = {}
  34. # a dictionary of manufacturers we're looking at
  35. manufacturers = {}
  36. # registry sections mapped back to the install sections
  37. regsections = {}
  38. # install sections that map back to monitor definitions
  39. instsections = {}
  40. # a big fat dictionary of strings to use later on.
  41. strings = {}
  42. class Monitor:
  43. def __repr__(self):
  44. return "%s; %s; %s; %s; %s" % (self.man,
  45. self.descr,
  46. self.edid,
  47. self.hsync,
  48. self.vsync)
  49. def __init__(self, man, id, edid):
  50. self.descr = ""
  51. self.man = man
  52. self.hsync = ""
  53. self.vsync = ""
  54. self.id = id
  55. self.edid = edid
  56. sectRe = re.compile(r'\[*\]')
  57. sectSplit = re.compile(r'[\[\]]')
  58. infoSplit = re.compile(r'[%=\\;]')
  59. # This RE is for EISA info lines
  60. # %D5259A%=D5259A, Monitor\HWP0487
  61. monitor1Re = re.compile(r'%*.%.*=.*,.*Monitor\\')
  62. # This one is for legacy entries
  63. # %3020% =PB3020, MonID_PB3020
  64. monitor2Re = re.compile(r'%*.%.*=.*,.*MonID_')
  65. # sync values that might be in the strings section
  66. sync_keys = {}
  67. for line in lines:
  68. tmp = string.strip(line)
  69. if tmp and tmp[0] == ';':
  70. continue
  71. if sectRe.search (line, 1):
  72. section = string.lower(sectSplit.split (line)[1])
  73. continue
  74. if section == "manufacturer":
  75. tmp = infoSplit.split (line)
  76. if len(tmp) > 1:
  77. manufacturer = string.lower(tmp[1])
  78. if tmp[1] in manufacturers:
  79. raise RuntimeError("Duplicate manufacturer entries")
  80. else:
  81. manufacturers[string.lower(string.strip(tmp[3].split(",")[0]))] = string.lower(string.strip(tmp[1]))
  82. # if we're in a manufacturer section, we need to jot down
  83. # the devices
  84. elif section in manufacturers:
  85. # Find monitor inf IDs and EISA ids:
  86. monre = None
  87. # EISA entries
  88. # %D5259A%=D5259A, Monitor\HWP0487
  89. if monitor1Re.search(line, 1):
  90. monre = monitor1Re
  91. # older non EISA entries
  92. # %3020% =PB3020, MonID_PB3020
  93. elif monitor2Re.search(line, 1):
  94. monre = monitor2Re
  95. if monre:
  96. end = monre.search(line, 1).end()
  97. id = string.strip(string.split(line, '%')[1])
  98. if monre == monitor1Re:
  99. # all EDID ID strings are 7 chars
  100. edid = string.strip(line[end:])[0:7]
  101. else:
  102. edid = "0"
  103. # we need to get the install section for this device
  104. rhs = string.strip(string.split (line, '=')[1])
  105. install = string.lower(string.strip(string.split (rhs, ',')[0]))
  106. if install in instsections:
  107. instsections[install].append ((section, id))
  108. else:
  109. instsections[install] = [ (section, id) ]
  110. if section not in monitors:
  111. monitors[section] = {}
  112. monitors[section][id] = Monitor(section, id, edid)
  113. elif section == "strings":
  114. tmp = string.strip(tmp)
  115. if not tmp:
  116. continue
  117. tmp = string.split (line, '=')
  118. if len (tmp) < 2:
  119. continue
  120. key = string.lower(string.strip(tmp[0]))
  121. tmp = string.split(string.strip(tmp[1]), '"')
  122. if len (tmp) > 1:
  123. value = tmp[1]
  124. else:
  125. value = tmp[0]
  126. strings[key] = string.strip(value)
  127. # Deal with sync lines in the strings section
  128. if key in sync_keys:
  129. sync = string.split(value, ",")
  130. for (man, mon) in sync_keys[key]:
  131. monitors[man][mon].hsync = string.strip(sync[0])
  132. monitors[man][mon].vsync = string.strip(sync[1])
  133. # these are the sections that tell us which AddReg to use
  134. # AddReg=PBCOM14L.AddReg, 1024, DPMS
  135. elif section in instsections:
  136. if string.find (line, "AddReg=") >= 0:
  137. rhs = string.split (line, '=')[1]
  138. # PBCOM14L.AddReg, 1024, DPMS
  139. registry = string.lower(string.strip(string.split(rhs, ',')[0]))
  140. # add this monitor to the list of monitors that will
  141. # use this registry entry
  142. if registry in regsections:
  143. regsections[registry].append (section)
  144. else:
  145. regsections[registry] = [ section ]
  146. # these are the actual AddReg entries. Look up in our table
  147. # to find which
  148. elif section in regsections:
  149. if string.find(line, 'HKR') >= 0:
  150. ids = regsections[section]
  151. # make a list of all the monitors pointing to
  152. # this registry section via install sections
  153. mons = []
  154. for id in ids:
  155. mons = mons + instsections[id]
  156. if string.find(line, 'HKR,"MODES') >= 0:
  157. modes = string.split(line, '"')
  158. sync = string.split(modes[3], ',')
  159. for (man, mon) in mons:
  160. monitors[man][mon].hsync = string.strip(sync[0])
  161. monitors[man][mon].vsync = string.strip(sync[1])
  162. else:
  163. # Sync lines must be somewhere else, maybe in the strings section
  164. keyval = None
  165. try:
  166. keyval = string.split(line,",")[4]
  167. except IndexError:
  168. pass
  169. if keyval and string.find(keyval, "KeyValue") >= 0:
  170. keyval = string.replace(string.strip(keyval), "%", "").lower()
  171. sync_keys[keyval] = mons
  172. for man in list(manufacturers.keys()):
  173. for monitor in list(monitors[man].values()):
  174. # OK, I know it's hacked up to look up these strings way down
  175. # here, but .inf format is CRAP.
  176. try:
  177. monitor.descr = strings[string.lower(monitor.id)]
  178. except KeyError:
  179. monitor.descr = monitor.id
  180. try:
  181. monitor.man = strings[string.lower(manufacturers[man])]
  182. except:
  183. monitor.man = manufacturers[man]
  184. print(monitor)