glx: Use FBCONFIG type for fbconfig parameter of CreateNewContext and CreatePixmap
[free-sw/xcb/proto] / xcbgen / xtypes.py
index d4b16e2..14c318a 100644 (file)
@@ -1,7 +1,7 @@
 '''
 This module contains the classes which represent XCB data types.
 '''
-from expr import Field, Expression
+from xcbgen.expr import Field, Expression
 import __main__
 
 class Type(object):
@@ -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.
@@ -114,10 +117,12 @@ class Enum(SimpleType):
 
     Public fields added:
     values contains a list of (name, value) tuples.  value is empty, or a number.
+    bits contains a list of (name, bitnum) tuples.  items only appear if specified as a bit. bitnum is a number.
     '''
     def __init__(self, name, elt):
         SimpleType.__init__(self, name, 4)
         self.values = []
+        self.bits = []
         for item in list(elt):
             # First check if we're using a default value
             if len(list(item)) == 0:
@@ -129,8 +134,8 @@ class Enum(SimpleType):
             if value.tag == 'value':
                 self.values.append((item.get('name'), value.text))
             elif value.tag == 'bit':
-                # XXX replace this with a simple number, please.
-                self.values.append((item.get('name'), '(1 << %s)' % value.text))
+                self.values.append((item.get('name'), '%u' % (1 << int(value.text, 0))))
+                self.bits.append((item.get('name'), value.text))
 
     def resolve(self, module):
         self.resolved = True
@@ -150,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)
@@ -175,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:
@@ -192,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):
@@ -213,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
@@ -241,7 +249,7 @@ class PadType(Type):
         Type.__init__(self, tcard8.name)
         self.is_pad = True
         self.size = 1
-        self.nmemb = 1 if (elt == None) else int(elt.get('bytes'))
+        self.nmemb = 1 if (elt == None) else int(elt.get('bytes'), 0)
 
     def resolve(self, module):
         self.resolved = True
@@ -264,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:
@@ -286,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 
@@ -329,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):
     '''
@@ -348,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.