diff options
Diffstat (limited to 'xorg-server/config/fdi2iclass.py')
-rw-r--r-- | xorg-server/config/fdi2iclass.py | 404 |
1 files changed, 202 insertions, 202 deletions
diff --git a/xorg-server/config/fdi2iclass.py b/xorg-server/config/fdi2iclass.py index 9dc06a76f..897444068 100644 --- a/xorg-server/config/fdi2iclass.py +++ b/xorg-server/config/fdi2iclass.py @@ -1,202 +1,202 @@ -#!/usr/bin/python
-#
-# Convert xorg keys from hal FDIs files to xorg.conf InputClass sections.
-# Modified from Martin Pitt's original fdi2mpi.py script:
-# http://cgit.freedesktop.org/media-player-info/tree/tools/fdi2mpi.py
-#
-# (C) 2010 Dan Nicholson
-# (C) 2009 Canonical Ltd.
-# Author: Dan Nicholson <dbn.lists@gmail.com>
-# Author: Martin Pitt <martin.pitt@ubuntu.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# fur- nished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FIT- NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-# THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
-# NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-import sys, xml.dom.minidom
-
-# dict converting <match> tags to Match* entries
-match_table = {
- 'info.product': 'MatchProduct',
- 'input.product': 'MatchProduct',
- 'info.vendor': 'MatchVendor',
- 'input.vendor': 'MatchVendor',
- 'info.device': 'MatchDevicePath',
- 'linux.device_file': 'MatchDevicePath',
- '/org/freedesktop/Hal/devices/computer:system.kernel.name': 'MatchOS',
- '@info.parent:pnp.id': 'MatchPnPID',
-}
-
-# dict converting info.capabilities list to Match* entries
-cap_match_table = {
- 'input.keys': 'MatchIsKeyboard',
- 'input.keyboard': 'MatchIsKeyboard',
- 'input.keypad': 'MatchIsKeyboard',
- 'input.mouse': 'MatchIsPointer',
- 'input.joystick': 'MatchIsJoystick',
- 'input.tablet': 'MatchIsTablet',
- 'input.touchpad': 'MatchIsTouchpad',
- 'input.touchscreen': 'MatchIsTouchscreen',
-}
-
-def device_glob(path):
- '''Convert a contains device path to a glob entry'''
- if path[0] != '/':
- path = '*' + path
- return path + '*'
-
-def parse_match(node):
- '''Parse a <match> tag to a tuple with InputClass values'''
- match = None
- value = None
- booltype = False
-
- # see what type of key we have
- if node.attributes.has_key('key'):
- key = node.attributes['key'].nodeValue
- if key in match_table:
- match = match_table[key]
- elif key == 'info.capabilities':
- booltype = True
-
- # bail out now if it's unrecognized
- if not match and not booltype:
- return (match, value)
-
- if node.attributes.has_key('string'):
- value = node.attributes['string'].nodeValue
- elif node.attributes.has_key('contains'):
- value = node.attributes['contains'].nodeValue
- if match == 'MatchDevicePath':
- value = device_glob(value)
- elif booltype and value in cap_match_table:
- match = cap_match_table[value]
- value = 'yes'
- elif node.attributes.has_key('string_outof'):
- value = node.attributes['string_outof'].nodeValue.replace(';','|')
- elif node.attributes.has_key('contains_outof'):
- all_values = node.attributes['contains_outof'].nodeValue.split(';')
- for v in all_values:
- if match == 'MatchDevicePath':
- v = device_glob(v)
- elif match == 'MatchPnPID' and len(v) < 7:
- v += '*'
- if value:
- value += '|' + v
- else:
- value = v
-
- return (match, value)
-
-def parse_options(node):
- '''Parse the x11_* options and return InputClass entries'''
- driver = ''
- ignore = False
- options = []
- for n in node.childNodes:
- if n.nodeType != xml.dom.minidom.Node.ELEMENT_NODE:
- continue
-
- tag = n.tagName
- key = n.attributes['key'].nodeValue
- value = ''
-
- if n.hasChildNodes():
- content_node = n.childNodes[0]
- assert content_node.nodeType == xml.dom.Node.TEXT_NODE
- value = content_node.nodeValue
-
- if tag == 'match':
- continue
- assert tag in ('addset', 'merge', 'append', 'remove')
-
- if tag == 'remove' and key == 'input.x11_driver':
- ignore = True
- elif key == 'input.x11_driver':
- driver = value
- elif key.startswith('input.x11_options.'):
- option = key.split('.', 2)[2]
- options.append((option, value))
-
- return (driver, ignore, options)
-
-def is_match_node(node):
- '''Check if a node is a <match> element'''
- return node.nodeType == xml.dom.minidom.Node.ELEMENT_NODE and \
- node.tagName == 'match'
-
-def parse_all_matches(node):
- '''Parse a x11 match tag and any parents that don't supply their
- own options'''
- matches = []
-
- while True:
- (key, value) = parse_match(node)
- if key and value:
- matches.append((key, value))
-
- # walk up to a parent match node
- node = node.parentNode
- if node == None or not is_match_node(node):
- break
-
- # leave if there other options at this level
- children = set([n.tagName for n in node.childNodes
- if n.nodeType == xml.dom.minidom.Node.ELEMENT_NODE])
- if children & set(['addset', 'merge', 'append']):
- break
-
- return matches
-
-# stupid counter to give "unique" rule names
-num_sections = 1
-def print_section(matches, driver, ignore, options):
- '''Print a valid InputClass section to stdout'''
- global num_sections
- print 'Section "InputClass"'
- print '\tIdentifier "Converted Class %d"' % num_sections
- num_sections += 1
- for m, v in matches:
- print '\t%s "%s"' % (m, v)
- if driver:
- print '\tDriver "%s"' % driver
- if ignore:
- print '\tOption "Ignore" "yes"'
- for o, v in options:
- print '\tOption "%s" "%s"' % (o, v)
- print 'EndSection'
-
-def parse_fdi(fdi):
- '''Parse x11 matches from fdi'''
- # find all <match> leaf nodes
- num = 0
- for match_node in fdi.getElementsByTagName('match'):
- children = set([n.tagName for n in match_node.childNodes
- if n.nodeType == xml.dom.minidom.Node.ELEMENT_NODE])
-
- # see if there are any options at this level
- (driver, ignore, options) = parse_options(match_node)
- if not driver and not ignore and not options:
- continue
-
- matches = parse_all_matches(match_node)
- if num > 0:
- print
- print_section(matches, driver, ignore, options)
- num += 1
-
-for f in sys.argv[1:]:
- parse_fdi(xml.dom.minidom.parse(f))
+#!/usr/bin/python +# +# Convert xorg keys from hal FDIs files to xorg.conf InputClass sections. +# Modified from Martin Pitt's original fdi2mpi.py script: +# http://cgit.freedesktop.org/media-player-info/tree/tools/fdi2mpi.py +# +# (C) 2010 Dan Nicholson +# (C) 2009 Canonical Ltd. +# Author: Dan Nicholson <dbn.lists@gmail.com> +# Author: Martin Pitt <martin.pitt@ubuntu.com> +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# fur- nished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FIT- NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- +# NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +import sys, xml.dom.minidom + +# dict converting <match> tags to Match* entries +match_table = { + 'info.product': 'MatchProduct', + 'input.product': 'MatchProduct', + 'info.vendor': 'MatchVendor', + 'input.vendor': 'MatchVendor', + 'info.device': 'MatchDevicePath', + 'linux.device_file': 'MatchDevicePath', + '/org/freedesktop/Hal/devices/computer:system.kernel.name': 'MatchOS', + '@info.parent:pnp.id': 'MatchPnPID', +} + +# dict converting info.capabilities list to Match* entries +cap_match_table = { + 'input.keys': 'MatchIsKeyboard', + 'input.keyboard': 'MatchIsKeyboard', + 'input.keypad': 'MatchIsKeyboard', + 'input.mouse': 'MatchIsPointer', + 'input.joystick': 'MatchIsJoystick', + 'input.tablet': 'MatchIsTablet', + 'input.touchpad': 'MatchIsTouchpad', + 'input.touchscreen': 'MatchIsTouchscreen', +} + +def device_glob(path): + '''Convert a contains device path to a glob entry''' + if path[0] != '/': + path = '*' + path + return path + '*' + +def parse_match(node): + '''Parse a <match> tag to a tuple with InputClass values''' + match = None + value = None + booltype = False + + # see what type of key we have + if node.attributes.has_key('key'): + key = node.attributes['key'].nodeValue + if key in match_table: + match = match_table[key] + elif key == 'info.capabilities': + booltype = True + + # bail out now if it's unrecognized + if not match and not booltype: + return (match, value) + + if node.attributes.has_key('string'): + value = node.attributes['string'].nodeValue + elif node.attributes.has_key('contains'): + value = node.attributes['contains'].nodeValue + if match == 'MatchDevicePath': + value = device_glob(value) + elif booltype and value in cap_match_table: + match = cap_match_table[value] + value = 'yes' + elif node.attributes.has_key('string_outof'): + value = node.attributes['string_outof'].nodeValue.replace(';','|') + elif node.attributes.has_key('contains_outof'): + all_values = node.attributes['contains_outof'].nodeValue.split(';') + for v in all_values: + if match == 'MatchDevicePath': + v = device_glob(v) + elif match == 'MatchPnPID' and len(v) < 7: + v += '*' + if value: + value += '|' + v + else: + value = v + + return (match, value) + +def parse_options(node): + '''Parse the x11_* options and return InputClass entries''' + driver = '' + ignore = False + options = [] + for n in node.childNodes: + if n.nodeType != xml.dom.minidom.Node.ELEMENT_NODE: + continue + + tag = n.tagName + key = n.attributes['key'].nodeValue + value = '' + + if n.hasChildNodes(): + content_node = n.childNodes[0] + assert content_node.nodeType == xml.dom.Node.TEXT_NODE + value = content_node.nodeValue + + if tag == 'match': + continue + assert tag in ('addset', 'merge', 'append', 'remove') + + if tag == 'remove' and key == 'input.x11_driver': + ignore = True + elif key == 'input.x11_driver': + driver = value + elif key.startswith('input.x11_options.'): + option = key.split('.', 2)[2] + options.append((option, value)) + + return (driver, ignore, options) + +def is_match_node(node): + '''Check if a node is a <match> element''' + return node.nodeType == xml.dom.minidom.Node.ELEMENT_NODE and \ + node.tagName == 'match' + +def parse_all_matches(node): + '''Parse a x11 match tag and any parents that don't supply their + own options''' + matches = [] + + while True: + (key, value) = parse_match(node) + if key and value: + matches.append((key, value)) + + # walk up to a parent match node + node = node.parentNode + if node == None or not is_match_node(node): + break + + # leave if there other options at this level + children = set([n.tagName for n in node.childNodes + if n.nodeType == xml.dom.minidom.Node.ELEMENT_NODE]) + if children & set(['addset', 'merge', 'append']): + break + + return matches + +# stupid counter to give "unique" rule names +num_sections = 1 +def print_section(matches, driver, ignore, options): + '''Print a valid InputClass section to stdout''' + global num_sections + print 'Section "InputClass"' + print '\tIdentifier "Converted Class %d"' % num_sections + num_sections += 1 + for m, v in matches: + print '\t%s "%s"' % (m, v) + if driver: + print '\tDriver "%s"' % driver + if ignore: + print '\tOption "Ignore" "yes"' + for o, v in options: + print '\tOption "%s" "%s"' % (o, v) + print 'EndSection' + +def parse_fdi(fdi): + '''Parse x11 matches from fdi''' + # find all <match> leaf nodes + num = 0 + for match_node in fdi.getElementsByTagName('match'): + children = set([n.tagName for n in match_node.childNodes + if n.nodeType == xml.dom.minidom.Node.ELEMENT_NODE]) + + # see if there are any options at this level + (driver, ignore, options) = parse_options(match_node) + if not driver and not ignore and not options: + continue + + matches = parse_all_matches(match_node) + if num > 0: + print + print_section(matches, driver, ignore, options) + num += 1 + +for f in sys.argv[1:]: + parse_fdi(xml.dom.minidom.parse(f)) |