diff options
author | Peter Harris <pharris@opentext.com> | 2010-12-23 13:02:52 -0500 |
---|---|---|
committer | Peter Harris <pharris@opentext.com> | 2010-12-23 13:02:52 -0500 |
commit | c4497cdbf0640c376cdebb0a9e5ea62458e6ba51 (patch) | |
tree | dce5a070b5a4207a41fc61787c88140b9d4db9c1 | |
parent | 661fe8dd7727c27467e61a0d20dc91557ce3747f (diff) | |
parent | e172bed68294746981eebbaa0c0740c00a0c8bd4 (diff) |
Merge branch 'master' of git://anongit.freedesktop.org/~peterh/xcbproto
-rw-r--r-- | src/xcb.xsd | 1 | ||||
-rw-r--r-- | src/xkb.xml | 33 | ||||
-rw-r--r-- | xcbgen/expr.py | 38 | ||||
-rw-r--r-- | xcbgen/xtypes.py | 189 |
4 files changed, 235 insertions, 26 deletions
diff --git a/src/xcb.xsd b/src/xcb.xsd index 5169b48..7fdf125 100644 --- a/src/xcb.xsd +++ b/src/xcb.xsd @@ -66,6 +66,7 @@ authorization from the authors. <xsd:element ref="switch" minOccurs="0" maxOccurs="unbounded" /> </xsd:choice> </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="optional" /> </xsd:complexType> <!-- switch expression --> diff --git a/src/xkb.xml b/src/xkb.xml index 33d3ea3..157df45 100644 --- a/src/xkb.xml +++ b/src/xkb.xml @@ -401,8 +401,12 @@ authorization from the authors. <struct name="KTMapEntry"> <field name="active" type="BOOL" /> + <!-- Xlib uses a different arrangement of fields <field name="mods_mask" type="CARD8" mask="ModMask" /> <field name="level" type="CARD8" /> + --> + <field name="level" type="CARD8" /> + <field name="mods_mask" type="CARD8" mask="ModMask" /> <field name="mods_mods" type="CARD8" mask="ModMask" /> <field name="mods_vmods" type="CARD16" mask="VMod" /> <pad bytes="2" /> @@ -1626,7 +1630,11 @@ authorization from the authors. <bitcase> <enumref ref="NameDetail">KTLevelNames</enumref> <list name="nLevelsPerType" type="CARD8"> - <fieldref>nKTLevels</fieldref> + <!-- Xlib uses NTypes here - + the spec says nKTLevels is correct, but + it does not work in reality + <fieldref>nKTLevels</fieldref> --> + <fieldref>nTypes</fieldref> </list> <list name="ktLevelNames" type="ATOM"> <sumof ref="nLevelsPerType" /> @@ -1973,9 +1981,16 @@ authorization from the authors. <pad bytes="16" /> <switch name="replies"> <fieldref>reported</fieldref> - <bitcase> + <bitcase name="types"> <enumref ref="GBNDetail">Types</enumref> + <!-- from the spec, this has to be a GetMap reply --> + <field name="getmap_type" type="CARD8" /> + <!-- done 'emulating' GetMap reply header--> <field name="typeDeviceID" type="CARD8" /> + <!-- from the spec, this has to be a GetMap reply --> + <field name="getmap_sequence" type="CARD16" /> + <field name="getmap_length" type="CARD32" /> + <!-- done 'emulating' GetMap reply header--> <pad bytes="2" /> <field name="typeMinKeyCode" type="KEYCODE" /> <field name="typeMaxKeyCode" type="KEYCODE" /> @@ -2058,7 +2073,7 @@ authorization from the authors. </bitcase> </switch> </bitcase> - <bitcase> + <bitcase name="compat_map"> <enumref ref="GBNDetail">CompatMap</enumref> <field name="compatDeviceID" type="CARD8" /> <field name="groupsRtrn" type="CARD8" mask="SetOfGroup" /> @@ -2079,7 +2094,7 @@ authorization from the authors. </popcount> </list> </bitcase> - <bitcase> + <bitcase name="client_symbols"> <enumref ref="GBNDetail">ClientSymbols</enumref> <field name="clientDeviceID" type="CARD8" /> <pad bytes="2" /> @@ -2164,7 +2179,7 @@ authorization from the authors. </bitcase> </switch> </bitcase> - <bitcase> + <bitcase name="server_symbols"> <enumref ref="GBNDetail">ServerSymbols</enumref> <field name="serverDeviceID" type="CARD8" /> <pad bytes="2" /> @@ -2249,7 +2264,7 @@ authorization from the authors. </bitcase> </switch> </bitcase> - <bitcase> + <bitcase name="indicator_maps"> <enumref ref="GBNDetail">IndicatorMaps</enumref> <field name="indicatorDeviceID" type="CARD8" /> <field name="which" type="CARD32" /> @@ -2260,7 +2275,7 @@ authorization from the authors. <fieldref>nIndicators</fieldref> </list> </bitcase> - <bitcase> + <bitcase name="key_names"> <enumref ref="GBNDetail">KeyNames</enumref> <field name="keyDeviceID" type="CARD8" /> <field name="which" type="CARD32" mask="NameDetail" /> @@ -2361,7 +2376,7 @@ authorization from the authors. </bitcase> </switch> </bitcase> - <bitcase> + <bitcase name="other_names"> <enumref ref="GBNDetail">OtherNames</enumref> <field name="otherDeviceID" type="CARD8" /> <field name="which" type="CARD32" mask="NameDetail" /> @@ -2462,7 +2477,7 @@ authorization from the authors. </bitcase> </switch> </bitcase> - <bitcase> + <bitcase name="geometry"> <enumref ref="GBNDetail">Geometry</enumref> <field name="geometryDeviceID" type="CARD8" /> <field name="name" type="ATOM" /> diff --git a/xcbgen/expr.py b/xcbgen/expr.py index 79ad8f6..274c290 100644 --- a/xcbgen/expr.py +++ b/xcbgen/expr.py @@ -40,6 +40,7 @@ class Expression(object): self.lenfield_name = None self.lenfield_type = None + self.lenfield_parent = None self.lenfield = None self.lenwire = False self.bitfield = False @@ -81,15 +82,46 @@ class Expression(object): self.rhs = Expression(list(elt)[0], parent) self.lenfield_name = self.rhs.lenfield_name - + elif elt.tag == 'value': # Constant expression self.nmemb = int(elt.text, 0) + elif elt.tag == 'popcount': + self.op = 'popcount' + self.rhs = Expression(list(elt)[0], parent) + self.lenfield_name = self.rhs.lenfield_name + # xcb_popcount returns 'int' - handle the type in the language-specific part + + elif elt.tag == 'enumref': + self.op = 'enumref' + self.lenfield_name = (elt.get('ref'), elt.text) + + elif elt.tag == 'sumof': + self.op = 'sumof' + self.lenfield_name = elt.get('ref') + else: # Notreached - raise Exception('XXX') - + raise Exception("undefined tag '%s'" % elt.tag) def fixed_size(self): return self.nmemb != None + + def resolve(self, module, parents): + if self.op == 'enumref': + self.lenfield_type = module.get_type(self.lenfield_name[0]) + self.lenfield_name = self.lenfield_name[1] + elif self.op == 'sumof': + # need to find the field with lenfield_name + for p in reversed(parents): + fields = dict([(f.field_name, f) for f in p.fields]) + if self.lenfield_name in fields.keys(): + if p.is_bitcase: + # switch is the anchestor + self.lenfield_parent = p.parents[-1] + else: + self.lenfield_parent = p + self.lenfield_type = fields[self.lenfield_name].field_type + break + diff --git a/xcbgen/xtypes.py b/xcbgen/xtypes.py index 35fcb91..1a6c7ce 100644 --- a/xcbgen/xtypes.py +++ b/xcbgen/xtypes.py @@ -32,6 +32,8 @@ class Type(object): self.is_reply = False self.is_union = False self.is_pad = False + self.is_switch = False + self.is_bitcase = False def resolve(self, module): ''' @@ -73,6 +75,7 @@ class Type(object): complex_type.fields.append(new_field) + class SimpleType(Type): ''' Derived class which represents a cardinal type like CARD32 or char. @@ -152,11 +155,11 @@ class ListType(Type): parent is the structure type containing the list. expr is an Expression object containing the length information, for variable-sized lists. ''' - def __init__(self, elt, member, parent): + def __init__(self, elt, member, *parent): Type.__init__(self, member.name) self.is_list = True self.member = member - self.parent = parent + self.parents = list(parent) if elt.tag == 'list': elts = list(elt) @@ -177,9 +180,10 @@ class ListType(Type): needlen = True # See if the length field is already in the structure. - for field in self.parent.fields: - if field.field_name == lenfield_name: - needlen = False + for parent in self.parents: + for field in parent.fields: + if field.field_name == lenfield_name: + needlen = False # It isn't, so we need to add it to the structure ourself. if needlen: @@ -194,15 +198,17 @@ class ListType(Type): if self.resolved: return self.member.resolve(module) + self.expr.resolve(module, self.parents) # Find my length field again. We need the actual Field object in the expr. # This is needed because we might have added it ourself above. if not self.fixed_size(): - for field in self.parent.fields: - if field.field_name == self.expr.lenfield_name and field.wire: - self.expr.lenfield = field - break - + for parent in self.parents: + for field in parent.fields: + if field.field_name == self.expr.lenfield_name and field.wire: + self.expr.lenfield = field + break + self.resolved = True def fixed_size(self): @@ -215,7 +221,7 @@ class ExprType(Type): Public fields added: expr is an Expression object containing the value of the field. ''' - def __init__(self, elt, member, parent): + def __init__(self, elt, member, *parent): Type.__init__(self, member.name) self.is_expr = True self.member = member @@ -266,6 +272,7 @@ class ComplexType(Type): self.fields = [] self.nmemb = 1 self.size = 0 + self.lenfield_parent = [self] def resolve(self, module): if self.resolved: @@ -288,18 +295,27 @@ class ComplexType(Type): elif child.tag == 'exprfield': field_name = child.get('name') fkey = child.get('type') - type = ExprType(child, module.get_type(fkey), self) + type = ExprType(child, module.get_type(fkey), *self.lenfield_parent) visible = False elif child.tag == 'list': field_name = child.get('name') fkey = child.get('type') - type = ListType(child, module.get_type(fkey), self) + type = ListType(child, module.get_type(fkey), *self.lenfield_parent) visible = True elif child.tag == 'valueparam': field_name = child.get('value-list-name') fkey = 'CARD32' - type = ListType(child, module.get_type(fkey), self) + type = ListType(child, module.get_type(fkey), *self.lenfield_parent) + visible = True + elif child.tag == 'switch': + field_name = child.get('name') + # construct the switch type name from the parent type and the field name + field_type = self.name + (field_name,) + type = SwitchType(field_type, child, *self.lenfield_parent) visible = True + type.make_member_of(module, self, field_type, field_name, visible, True, False) + type.resolve(module) + continue else: # Hit this on Reply continue @@ -331,6 +347,109 @@ class ComplexType(Type): return False return True +class SwitchType(ComplexType): + ''' + Derived class which represents a List of Items. + + Public fields added: + bitcases is an array of Bitcase objects describing the list items + ''' + + def __init__(self, name, elt, *parents): + ComplexType.__init__(self, name, elt) + self.parents = parents + # FIXME: switch cannot store lenfields, so it should just delegate the parents + self.lenfield_parent = list(parents) + [self] + # self.fields contains all possible fields collected from the Bitcase objects, + # whereas self.items contains the Bitcase objects themselves + self.bitcases = [] + + self.is_switch = True + elts = list(elt) + self.expr = Expression(elts[0] if len(elts) else elt, self) + + def resolve(self, module): + if self.resolved: + return +# pads = 0 + + parents = list(self.parents) + [self] + + # Resolve all of our field datatypes. + for index, child in enumerate(list(self.elt)): + if child.tag == 'bitcase': + field_name = child.get('name') + if field_name is None: + field_type = self.name + ('bitcase%d' % index,) + else: + field_type = self.name + (field_name,) + + # use self.parent to indicate anchestor, + # as switch does not contain named fields itself + type = BitcaseType(index, field_type, child, *parents) + # construct the switch type name from the parent type and the field name + if field_name is None: + type.has_name = False + # Get the full type name for the field + field_type = type.name + visible = True + + # add the field to ourself + type.make_member_of(module, self, field_type, field_name, visible, True, False) + + # recursively resolve the type (could be another structure, list) + type.resolve(module) + inserted = False + for new_field in type.fields: + # We dump the _placeholder_byte if any fields are added. + for (idx, field) in enumerate(self.fields): + if field == _placeholder_byte: + self.fields[idx] = new_field + inserted = True + break + if False == inserted: + self.fields.append(new_field) + + self.calc_size() # Figure out how big we are + self.resolved = True + + def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto): + if not self.fixed_size(): + # We need a length field. + # Ask our Expression object for it's name, type, and whether it's on the wire. + lenfid = self.expr.lenfield_type + lenfield_name = self.expr.lenfield_name + lenwire = self.expr.lenwire + needlen = True + + # See if the length field is already in the structure. + for parent in self.parents: + for field in parent.fields: + if field.field_name == lenfield_name: + needlen = False + + # It isn't, so we need to add it to the structure ourself. + if needlen: + type = module.get_type(lenfid) + lenfield_type = module.get_type_name(lenfid) + type.make_member_of(module, complex_type, lenfield_type, lenfield_name, True, lenwire, False) + + # Add ourself to the structure by calling our original method. + Type.make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto) + + # size for switch can only be calculated at runtime + def calc_size(self): + pass + + # note: switch is _always_ of variable size, but we indicate here wether + # it contains elements that are variable-sized themselves + def fixed_size(self): + return False +# for m in self.fields: +# if not m.type.fixed_size(): +# return False +# return True + class Struct(ComplexType): ''' @@ -350,6 +469,48 @@ class Union(ComplexType): out = __main__.output['union'] +class BitcaseType(ComplexType): + ''' + Derived class representing a struct data type. + ''' + def __init__(self, index, name, elt, *parent): + elts = list(elt) + self.expr = Expression(elts[0] if len(elts) else elt, self) + ComplexType.__init__(self, name, elts[1:]) + self.has_name = True + self.index = 1 + self.lenfield_parent = list(parent) + [self] + self.parents = list(parent) + self.is_bitcase = True + + def make_member_of(self, module, switch_type, field_type, field_name, visible, wire, auto): + ''' + register BitcaseType with the corresponding SwitchType + + module is the global module object. + complex_type is the structure object. + see Field for the meaning of the other parameters. + ''' + new_field = Field(self, field_type, field_name, visible, wire, auto) + + # We dump the _placeholder_byte if any bitcases are added. + for (idx, field) in enumerate(switch_type.bitcases): + if field == _placeholder_byte: + switch_type.bitcases[idx] = new_field + return + + switch_type.bitcases.append(new_field) + + def resolve(self, module): + if self.resolved: + return + + self.expr.resolve(module, self.parents+[self]) + + # Resolve the bitcase expression + ComplexType.resolve(self, module) + + class Reply(ComplexType): ''' Derived class representing a reply. Only found as a field of Request. |