Merge branch 'arb_map_buffer_range'
[mesa.git] / src / mesa / glapi / glX_proto_send.py
index 452cd7f4d615b8a8d8e0e12b97b825f5c72bad32..daca1b767a3cbcaf47d3eed20430f91de61b058f 100644 (file)
@@ -1,6 +1,6 @@
-#!/usr/bin/python2
+#!/usr/bin/env python
 
-# (C) Copyright IBM Corporation 2004
+# (C) Copyright IBM Corporation 2004, 2005
 # All Rights Reserved.
 #
 # Permission is hereby granted, free of charge, to any person obtaining a
 #
 # Authors:
 #    Ian Romanick <idr@us.ibm.com>
+#    Jeremy Kolb <jkolb@brandeis.edu>
 
-from xml.sax import saxutils
-from xml.sax import make_parser
-from xml.sax.handler import feature_namespaces
-
-import gl_XML
-import license
-import sys, getopt
-
-
-def printPure():
-       print """#  if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
-#    define PURE __attribute__((pure))
-#  else
-#    define PURE
-#  endif"""
-
-def printFastcall():
-       print """#  if defined(__i386__) && defined(__GNUC__)
-#    define FASTCALL __attribute__((fastcall))
-#  else
-#    define FASTCALL
-#  endif"""
-
-def printVisibility(S, s):
-       print """#  if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
-#    define %s  __attribute__((visibility("%s")))
-#  else
-#    define %s
-#  endif""" % (S, s, S)
-
-def printNoinline():
-       print """#  if defined(__GNUC__)
-#    define NOINLINE __attribute__((noinline))
-#  else
-#    define NOINLINE
-#  endif"""
-
-
-class glXItemFactory(gl_XML.glItemFactory):
-       """Factory to create GLX protocol oriented objects derived from glItem."""
-    
-       def create(self, context, name, attrs):
-               if name == "function":
-                       return glXFunction(context, name, attrs)
-               elif name == "enum":
-                       return glXEnum(context, name, attrs)
-               elif name == "param":
-                       return glXParameter(context, name, attrs)
-               else:
-                       return gl_XML.glItemFactory.create(self, context, name, attrs)
-
-class glXEnumFunction:
-       def __init__(self, name):
-               self.name = name
-               
-               # "enums" is a set of lists.  The element in the set is the
-               # value of the enum.  The list is the list of names for that
-               # value.  For example, [0x8126] = {"POINT_SIZE_MIN",
-               # "POINT_SIZE_MIN_ARB", "POINT_SIZE_MIN_EXT",
-               # "POINT_SIZE_MIN_SGIS"}.
-
-               self.enums = {}
-
-               # "count" is indexed by count values.  Each element of count
-               # is a list of index to "enums" that have that number of
-               # associated data elements.  For example, [4] = 
-               # {GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_EMISSION,
-               # GL_AMBIENT_AND_DIFFUSE} (the enum names are used here,
-               # but the actual hexadecimal values would be in the array).
-
-               self.count = {}
-
+import gl_XML, glX_XML, glX_proto_common, license
+import sys, getopt, copy, string
 
-       def append(self, count, value, name):
-               if self.enums.has_key( value ):
-                       self.enums[value].append(name)
-               else:
-                       if not self.count.has_key(count):
-                               self.count[count] = []
-
-                       self.enums[value] = []
-                       self.enums[value].append(name)
-                       self.count[count].append(value)
+def convertStringForXCB(str):
+    tmp = ""
+    special = [ "ARB" ]
+    i = 0
+    while i < len(str):
+        if str[i:i+3] in special:
+            tmp = '%s_%s' % (tmp, string.lower(str[i:i+3]))
+            i = i + 2;
+        elif str[i].isupper():
+            tmp = '%s_%s' % (tmp, string.lower(str[i]))
+        else:
+            tmp = '%s%s' % (tmp, str[i])
+        i += 1
+    return tmp
 
+def hash_pixel_function(func):
+       """Generate a 'unique' key for a pixel function.  The key is based on
+       the parameters written in the command packet.  This includes any
+       padding that might be added for the original function and the 'NULL
+       image' flag."""
 
-       def signature( self ):
-               sig = ""
-               for i in self.count:
-                       for e in self.count[i]:
-                               sig += "%04x,%u," % (e, i)
-       
-               return sig;
 
+       h = ""
+       hash_pre = ""
+       hash_suf = ""
+       for param in func.parameterIterateGlxSend():
+               if param.is_image():
+                       [dim, junk, junk, junk, junk] = param.get_dimensions()
 
-       def PrintUsingTable(self):
-               """Emit the body of the __gl*_size function using a pair
-               of look-up tables and a mask.  The mask is calculated such
-               that (e & mask) is unique for all the valid values of e for
-               this function.  The result of (e & mask) is used as an index
-               into the first look-up table.  If it matches e, then the
-               same entry of the second table is returned.  Otherwise zero
-               is returned.
-               
-               It seems like this should cause better code to be generated.
-               However, on x86 at least, the resulting .o file is about 20%
-               larger then the switch-statment version.  I am leaving this
-               code in because the results may be different on other
-               platforms (e.g., PowerPC or x86-64)."""
-
-               return 0
-               count = 0
-               for a in self.enums:
-                       count += 1
-
-               # Determine if there is some mask M, such that M = (2^N) - 1,
-               # that will generate unique values for all of the enums.
-
-               mask = 0
-               for i in [1, 2, 3, 4, 5, 6, 7, 8]:
-                       mask = (1 << i) - 1
-
-                       fail = 0;
-                       for a in self.enums:
-                               for b in self.enums:
-                                       if a != b:
-                                               if (a & mask) == (b & mask):
-                                                       fail = 1;
-
-                       if not fail:
-                               break;
-                       else:
-                               mask = 0
+                       d = (dim + 1) & ~1
+                       hash_pre = "%uD%uD_" % (d - 1, d)
 
-               if (mask != 0) and (mask < (2 * count)):
-                       masked_enums = {}
-                       masked_count = {}
+                       if param.img_null_flag:
+                               hash_suf = "_NF"
 
-                       for i in range(0, mask):
-                               masked_enums[i] = "0";
-                               masked_count[i] = 0;
+               h += "%u" % (param.size())
 
-                       for c in self.count:
-                               for e in self.count[c]:
-                                       i = e & mask
-                                       masked_enums[i] = '0x%04x /* %s */' % (e, self.enums[e][0])
-                                       masked_count[i] = c
+               if func.pad_after(param):
+                       h += "4"
 
 
-                       print '    static const GLushort a[%u] = {' % (mask + 1)
-                       for e in masked_enums:
-                               print '        %s, ' % (masked_enums[e])
-                       print '    };'
-
-                       print '    static const GLubyte b[%u] = {' % (mask + 1)
-                       for c in masked_count:
-                               print '        %u, ' % (masked_count[c])
-                       print '    };'
-
-                       print '    const unsigned idx = (e & 0x%02xU);' % (mask)
-                       print ''
-                       print '    return (e == a[idx]) ? (GLint) b[idx] : 0;'
-                       return 1;
-               else:
-                       return 0;
-
-       def PrintUsingSwitch(self):
-               """Emit the body of the __gl*_size function using a 
-               switch-statement."""
+       n = func.name.replace("%uD" % (dim), "")
+       n = "__glx_%s_%uD%uD" % (n, d - 1, d)
 
-               print '    switch( e ) {'
+       h = hash_pre + h + hash_suf
+       return [h, n]
 
-               for c in self.count:
-                       for e in self.count[c]:
-                               first = 1
-
-                               # There may be multiple enums with the same
-                               # value.  This happens has extensions are
-                               # promoted from vendor-specific or EXT to
-                               # ARB and to the core.  Emit the first one as
-                               # a case label, and emit the others as
-                               # commented-out case labels.
-
-                               for j in self.enums[e]:
-                                       if first:
-                                               print '        case %s:' % (j)
-                                               first = 0
-                                       else:
-                                               print '/*      case %s:*/' % (j)
-                                       
-                       print '            return %u;' % (c)
-                                       
-               print '        default: return 0;'
-               print '    }'
-
-
-       def Print(self, name):
-               print 'INTERNAL PURE FASTCALL GLint'
-               print '__gl%s_size( GLenum e )' % (name)
-               print '{'
-
-               if not self.PrintUsingTable():
-                       self.PrintUsingSwitch()
-
-               print '}'
-               print ''
 
+class glx_pixel_function_stub(glX_XML.glx_function):
+       """Dummy class used to generate pixel "utility" functions that are
+       shared by multiple dimension image functions.  For example, these
+       objects are used to generate shared functions used to send GLX
+       protocol for TexImage1D and TexImage2D, TexSubImage1D and
+       TexSubImage2D, etc."""
 
+       def __init__(self, func, name):
+               # The parameters to the utility function are the same as the
+               # parameters to the real function except for the added "pad"
+               # parameters.
 
-class glXEnum(gl_XML.glEnum):
-       def __init__(self, context, name, attrs):
-               gl_XML.glEnum.__init__(self, context, name, attrs)
-               self.glx_functions = []
+               self.name = name
+               self.images = []
+               self.parameters = []
+               self.parameters_by_name = {}
+               for _p in func.parameterIterator():
+                       p = copy.copy(_p)
+                       self.parameters.append(p)
+                       self.parameters_by_name[ p.name ] = p
 
-       def startElement(self, name, attrs):
-               if name == "size":
-                       n = attrs.get('name', None)
-                       if not self.context.glx_enum_functions.has_key( n ):
-                               f = glXEnumFunction( n )
-                               self.context.glx_enum_functions[ f.name ] = f
 
-                       temp = attrs.get('count', None)
-                       try:
-                               c = int(temp)
-                       except Exception,e:
-                               raise RuntimeError('Invalid count value "%s" for enum "%s" in function "%s" when an integer was expected.' % (temp, self.name, n))
+                       if p.is_image():
+                               self.images.append(p)
+                               p.height = "height"
 
-                       self.context.glx_enum_functions[ n ].append( c, self.value, self.name )
-               else:
-                       gl_XML.glEnum.startElement(self, context, name, attrs)
-               return
+                               if p.img_yoff == None:
+                                       p.img_yoff = "yoffset"
 
+                               if p.depth:
+                                       if p.extent == None:
+                                               p.extent = "extent"
 
-class glXParameter(gl_XML.glParameter):
-       def __init__(self, context, name, attrs):
-               self.order = 1;
-               gl_XML.glParameter.__init__(self, context, name, attrs);
+                                       if p.img_woff == None:
+                                               p.img_woff = "woffset"
 
 
-class glXFunction(gl_XML.glFunction):
-       glx_rop = 0
-       glx_sop = 0
-       glx_vendorpriv = 0
+                       pad_name = func.pad_after(p)
+                       if pad_name:
+                               pad = copy.copy(p)
+                               pad.name = pad_name
+                               self.parameters.append(pad)
+                               self.parameters_by_name[ pad.name ] = pad
+                               
 
-       # If this is set to true, it means that GLdouble parameters should be
-       # written to the GLX protocol packet in the order they appear in the
-       # prototype.  This is different from the "classic" ordering.  In the
-       # classic ordering GLdoubles are written to the protocol packet first,
-       # followed by non-doubles.  NV_vertex_program was the first extension
-       # to break with this tradition.
+               self.return_type = func.return_type
 
-       glx_doubles_in_order = 0
+               self.glx_rop = ~0
+               self.glx_sop = 0
+               self.glx_vendorpriv = 0
 
-       vectorequiv = None
-       handcode = 0
-       ignore = 0
-       can_be_large = 0
+               self.glx_doubles_in_order = func.glx_doubles_in_order
 
-       def __init__(self, context, name, attrs):
-               self.vectorequiv = attrs.get('vectorequiv', None)
-               self.count_parameters = None
-               self.counter = None
+               self.vectorequiv = None
                self.output = None
-               self.can_be_large = 0
-               self.reply_always_array = 0
-
-               gl_XML.glFunction.__init__(self, context, name, attrs)
+               self.can_be_large = func.can_be_large
+               self.reply_always_array = func.reply_always_array
+               self.dimensions_in_reply = func.dimensions_in_reply
+               self.img_reset = None
+
+               self.server_handcode = 0
+               self.client_handcode = 0
+               self.ignore = 0
+
+               self.count_parameter_list = func.count_parameter_list
+               self.counter_list = func.counter_list
+               self.offsets_calculated = 0
                return
 
-       def startElement(self, name, attrs):
-               """Process elements within a function that are specific to GLX."""
-
-               if name == "glx":
-                       self.glx_rop = int(attrs.get('rop', "0"))
-                       self.glx_sop = int(attrs.get('sop', "0"))
-                       self.glx_vendorpriv = int(attrs.get('vendorpriv', "0"))
-
-                       if attrs.get('handcode', "false") == "true":
-                               self.handcode = 1
-                       else:
-                               self.handcode = 0
-
-                       if attrs.get('ignore', "false") == "true":
-                               self.ignore = 1
-                       else:
-                               self.ignore = 0
-
-                       if attrs.get('large', "false") == "true":
-                               self.can_be_large = 1
-                       else:
-                               self.can_be_large = 0
-
-                       if attrs.get('doubles_in_order', "false") == "true":
-                               self.glx_doubles_in_order = 1
-                       else:
-                               self.glx_doubles_in_order = 0
-
-                       if attrs.get('always_array', "false") == "true":
-                               self.reply_always_array = 1
-                       else:
-                               self.reply_always_array = 0
-
-               else:
-                       gl_XML.glFunction.startElement(self, name, attrs)
-
-
-       def append(self, tag_name, p):
-               gl_XML.glFunction.append(self, tag_name, p)
-
-               if p.is_variable_length_array():
-                       p.order = 2;
-               elif not self.glx_doubles_in_order and p.p_type.size == 8:
-                       p.order = 0;
-
-               if p.p_count_parameters != None:
-                       self.count_parameters = p.p_count_parameters
-               
-               if p.is_counter:
-                       self.counter = p.name
-                       
-               if p.is_output:
-                       self.output = p
-
-               return
-
-       def variable_length_parameter(self):
-               for param in self.fn_parameters:
-                       if param.is_variable_length_array():
-                               return param
-                       
-               return None
-
-
-       def command_payload_length(self):
-               size = 0
-               size_string = ""
-               for p in self:
-                       if p.is_output: continue
-                       temp = p.size_string()
-                       try:
-                               s = int(temp)
-                               size += s
-                       except Exception,e:
-                               size_string = size_string + " + __GLX_PAD(%s)" % (temp)
-
-               return [size, size_string]
-
-       def command_length(self):
-               [size, size_string] = self.command_payload_length()
-
-               if self.glx_rop != 0:
-                       size += 4
-
-               size = ((size + 3) & ~3)
-               return "%u%s" % (size, size_string)
-
-
-       def opcode_value(self):
-               if self.glx_rop != 0:
-                       return self.glx_rop
-               elif self.glx_sop != 0:
-                       return self.glx_sop
-               elif self.glx_vendorpriv != 0:
-                       return self.glx_vendorpriv
-               else:
-                       return -1
-       
-       def opcode_rop_basename(self):
-               if self.vectorequiv == None:
-                       return self.name
-               else:
-                       return self.vectorequiv
-
-       def opcode_name(self):
-               if self.glx_rop != 0:
-                       return "X_GLrop_%s" % (self.opcode_rop_basename())
-               elif self.glx_sop != 0:
-                       return "X_GLsop_%s" % (self.name)
-               elif self.glx_vendorpriv != 0:
-                       return "X_GLvop_%s" % (self.name)
-               else:
-                       return "ERROR"
-
-       def opcode_real_name(self):
-               if self.glx_vendorpriv != 0:
-                       if self.needs_reply():
-                               return "X_GLXVendorPrivateWithReply"
-                       else:
-                               return "X_GLXVendorPrivate"
-               else:
-                       return self.opcode_name()
-
-
-       def return_string(self):
-               if self.fn_return_type != 'void':
-                       return "return retval;"
-               else:
-                       return "return;"
-
-
-       def needs_reply(self):
-               return self.fn_return_type != 'void' or self.output != None
-
-
-class GlxProto(gl_XML.FilterGLAPISpecBase):
-       name = "glX_proto_send.py (from Mesa)"
 
+class PrintGlxProtoStubs(glX_proto_common.glx_print_proto):
        def __init__(self):
-               gl_XML.FilterGLAPISpecBase.__init__(self)
-               self.factory = glXItemFactory()
-               self.glx_enum_functions = {}
-
-
-       def endElement(self, name):
-               if name == 'OpenGLAPI':
-                       # Once all the parsing is done, we have to go back and
-                       # fix-up some cross references between different
-                       # functions.
-
-                       for k in self.functions:
-                               f = self.functions[k]
-                               if f.vectorequiv != None:
-                                       equiv = self.find_function(f.vectorequiv)
-                                       if equiv != None:
-                                               f.glx_doubles_in_order = equiv.glx_doubles_in_order
-                                               f.glx_rop = equiv.glx_rop
-                                       else:
-                                               raise RuntimeError("Could not find the vector equiv. function %s for %s!" % (f.name, f.vectorequiv))
-               else:
-                       gl_XML.FilterGLAPISpecBase.endElement(self, name)
-               return
+               glX_proto_common.glx_print_proto.__init__(self)
+               self.name = "glX_proto_send.py (from Mesa)"
+               self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004, 2005", "IBM")
 
 
-class PrintGlxProtoStubs(GlxProto):
-       def __init__(self):
-               GlxProto.__init__(self)
                self.last_category = ""
-               self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004", "IBM")
                self.generic_sizes = [3, 4, 6, 8, 12, 16, 24, 32]
+               self.pixel_stubs = {}
+               self.debug = 0
                return
 
        def printRealHeader(self):
@@ -470,13 +165,26 @@ class PrintGlxProtoStubs(GlxProto):
                print '#include <GL/gl.h>'
                print '#include "indirect.h"'
                print '#include "glxclient.h"'
-               print '#include "size.h"'
+               print '#include "indirect_size.h"'
+               print '#include "dispatch.h"'
+               print '#include "glapi.h"'
+               print '#include "glthread.h"'
                print '#include <GL/glxproto.h>'
+               print '#ifdef USE_XCB'
+               print '#include <X11/Xlib-xcb.h>'
+               print '#include <xcb/xcb.h>'
+               print '#include <xcb/glx.h>'
+               print '#endif /* USE_XCB */'
+
                print ''
                print '#define __GLX_PAD(n) (((n) + 3) & ~3)'
                print ''
-               printFastcall()
-               printNoinline()
+               self.printFastcall()
+               self.printNoinline()
+               print ''
+               print '#if !defined __GNUC__ || __GNUC__ < 3'
+               print '#  define __builtin_expect(x, y) x'
+               print '#endif'
                print ''
                print '/* If the size and opcode values are known at compile-time, this will, on'
                print ' * x86 at least, emit them with a single instruction.'
@@ -486,35 +194,77 @@ class PrintGlxProtoStubs(GlxProto):
                print '         temp.s[0] = (size); temp.s[1] = (op); \\'
                print '         *((int *)(dest)) = temp.i; } while(0)'
                print ''
-               print """static NOINLINE CARD32
-read_reply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array )
+               print """NOINLINE CARD32
+__glXReadReply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array )
 {
     xGLXSingleReply reply;
     
     (void) _XReply(dpy, (xReply *) & reply, 0, False);
     if (size != 0) {
-       if ((reply.size >= 1) || reply_is_always_array) {
-           const GLint bytes = (reply_is_always_array) 
-             ? (4 * reply.length) : (reply.size * size);
-           const GLint extra = 4 - (bytes & 3);
-
-           _XRead(dpy, dest, bytes);
-           if ( extra != 0 ) {
-               _XEatData(dpy, extra);
-           }
-       }
-       else {
-           (void) memcpy( dest, &(reply.pad3), size);
-       }
+        if ((reply.length > 0) || reply_is_always_array) {
+            const GLint bytes = (reply_is_always_array) 
+              ? (4 * reply.length) : (reply.size * size);
+            const GLint extra = 4 - (bytes & 3);
+
+            _XRead(dpy, dest, bytes);
+            if ( extra < 4 ) {
+                _XEatData(dpy, extra);
+            }
+        }
+        else {
+            (void) memcpy( dest, &(reply.pad3), size);
+        }
     }
 
     return reply.retval;
 }
 
+NOINLINE void
+__glXReadPixelReply( Display *dpy, __GLXcontext * gc, unsigned max_dim,
+    GLint width, GLint height, GLint depth, GLenum format, GLenum type,
+    void * dest, GLboolean dimensions_in_reply )
+{
+    xGLXSingleReply reply;
+    GLint size;
+    
+    (void) _XReply(dpy, (xReply *) & reply, 0, False);
+
+    if ( dimensions_in_reply ) {
+        width  = reply.pad3;
+        height = reply.pad4;
+        depth  = reply.pad5;
+       
+       if ((height == 0) || (max_dim < 2)) { height = 1; }
+       if ((depth  == 0) || (max_dim < 3)) { depth  = 1; }
+    }
+
+    size = reply.length * 4;
+    if (size != 0) {
+        void * buf = Xmalloc( size );
+
+        if ( buf == NULL ) {
+            _XEatData(dpy, size);
+            __glXSetError(gc, GL_OUT_OF_MEMORY);
+        }
+        else {
+            const GLint extra = 4 - (size & 3);
+
+            _XRead(dpy, buf, size);
+            if ( extra < 4 ) {
+                _XEatData(dpy, extra);
+            }
+
+            __glEmptyImage(gc, 3, width, height, depth, format, type,
+                           buf, dest);
+            Xfree(buf);
+        }
+    }
+}
+
 #define X_GLXSingle 0
 
-static NOINLINE GLubyte *
-setup_single_request( __GLXcontext * gc, GLint sop, GLint cmdlen )
+NOINLINE FASTCALL GLubyte *
+__glXSetupSingleRequest( __GLXcontext * gc, GLint sop, GLint cmdlen )
 {
     xGLXSingleReq * req;
     Display * const dpy = gc->currentDpy;
@@ -528,8 +278,8 @@ setup_single_request( __GLXcontext * gc, GLint sop, GLint cmdlen )
     return (GLubyte *)(req) + sz_xGLXSingleReq;
 }
 
-static NOINLINE GLubyte *
-setup_vendor_request( __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen )
+NOINLINE FASTCALL GLubyte *
+__glXSetupVendorRequest( __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen )
 {
     xGLXVendorPrivateReq * req;
     Display * const dpy = gc->currentDpy;
@@ -543,23 +293,118 @@ setup_vendor_request( __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen )
     req->contextTag = gc->currentContextTag;
     return (GLubyte *)(req) + sz_xGLXVendorPrivateReq;
 }
+
+const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 };
+
+#define zero                        (__glXDefaultPixelStore+0)
+#define one                         (__glXDefaultPixelStore+8)
+#define default_pixel_store_1D      (__glXDefaultPixelStore+4)
+#define default_pixel_store_1D_size 20
+#define default_pixel_store_2D      (__glXDefaultPixelStore+4)
+#define default_pixel_store_2D_size 20
+#define default_pixel_store_3D      (__glXDefaultPixelStore+0)
+#define default_pixel_store_3D_size 36
+#define default_pixel_store_4D      (__glXDefaultPixelStore+0)
+#define default_pixel_store_4D_size 36
 """
 
                for size in self.generic_sizes:
                        self.print_generic_function(size)
                return
 
-       def printFunction(self, f):
-               if f.fn_offset < 0 or f.handcode or f.ignore: return
 
-               if f.glx_rop != 0 or f.vectorequiv != None:
-                       self.printRenderFunction(f)
-               elif f.glx_sop != 0 or f.glx_vendorpriv != 0:
-                       self.printSingleFunction(f)
+       def printBody(self, api):
+
+               self.pixel_stubs = {}
+               generated_stubs = []
+
+               for func in api.functionIterateGlx():
+                       if func.client_handcode: continue
+
+                       # If the function is a pixel function with a certain
+                       # GLX protocol signature, create a fake stub function
+                       # for it.  For example, create a single stub function
+                       # that is used to implement both glTexImage1D and
+                       # glTexImage2D.
+
+                       if func.glx_rop != 0:
+                               do_it = 0
+                               for image in func.get_images():
+                                       if image.img_pad_dimensions:
+                                               do_it = 1
+                                               break
+
+
+                               if do_it:
+                                       [h, n] = hash_pixel_function(func)
+
+
+                                       self.pixel_stubs[ func.name ] = n
+                                       if h not in generated_stubs:
+                                               generated_stubs.append(h)
+
+                                               fake_func = glx_pixel_function_stub( func, n )
+                                               self.printFunction(fake_func, fake_func.name)
+
+
+                       self.printFunction(func, func.name)
+                       if func.glx_sop and func.glx_vendorpriv:
+                               self.printFunction(func, func.glx_vendorpriv_names[0])
+
+               return
+
+
+       def printFunction(self, func, name):
+               footer = '}\n'
+               if func.glx_rop == ~0:
+                       print 'static %s' % (func.return_type)
+                       print '%s( unsigned opcode, unsigned dim, %s )' % (func.name, func.get_parameter_string())
+                       print '{'
                else:
-                       print "/* Missing GLX protocol for %s. */" % (f.name)
+                       if func.has_different_protocol(name):
+                               if func.return_type == "void":
+                                       ret_string = ''
+                               else:
+                                       ret_string = "return "
+
+                               func_name = func.static_glx_name(name)
+                               print '#define %s %d' % (func.opcode_vendor_name(name), func.glx_vendorpriv)
+                               print '%s gl%s(%s)' % (func.return_type, func_name, func.get_parameter_string())
+                               print '{'
+                               print '    __GLXcontext * const gc = __glXGetCurrentContext();'
+                               print ''
+                               print '#ifdef GLX_DIRECT_RENDERING'
+                               print '    if (gc->driContext) {'
+                               print '    %sCALL_%s(GET_DISPATCH(), (%s));' % (ret_string, func.name, func.get_called_parameter_string())
+                               print '    } else'
+                               print '#endif'
+                               print '    {'
+
+                               footer = '}\n}\n'
+                       else:
+                               print '#define %s %d' % (func.opcode_name(), func.opcode_value())
+
+                               print '%s __indirect_gl%s(%s)' % (func.return_type, name, func.get_parameter_string())
+                               print '{'
+
+
+               if func.glx_rop != 0 or func.vectorequiv != None:
+                       if len(func.images):
+                               self.printPixelFunction(func)
+                       else:
+                               self.printRenderFunction(func)
+               elif func.glx_sop != 0 or func.glx_vendorpriv != 0:
+                       self.printSingleFunction(func, name)
+                       pass
+               else:
+                       print "/* Missing GLX protocol for %s. */" % (name)
+
+               print footer
+               return
+
 
        def print_generic_function(self, n):
+               size = (n + 3) & ~3
                print """static FASTCALL NOINLINE void
 generic_%u_byte( GLint rop, const void * ptr )
 {
@@ -569,178 +414,457 @@ generic_%u_byte( GLint rop, const void * ptr )
     emit_header(gc->pc, rop, cmdlen);
     (void) memcpy((void *)(gc->pc + 4), ptr, %u);
     gc->pc += cmdlen;
-    if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }
+    if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }
 }
-""" % (n, n + 4, n)
-
+""" % (n, size + 4, size)
+               return
 
-       def common_emit_one_arg(self, p, offset, pc, indent, adjust):
-               if p.is_output: return
 
-               t = p.p_type
+       def common_emit_one_arg(self, p, pc, adjust, extra_offset):
                if p.is_array():
                        src_ptr = p.name
                else:
                        src_ptr = "&" + p.name
 
-               print '%s    (void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
-                       % (indent, pc, offset + adjust, src_ptr, p.size_string() )
+               if p.is_padding:
+                       print '(void) memset((void *)(%s + %u), 0, %s);' \
+                           % (pc, p.offset + adjust, p.size_string() )
+               elif not extra_offset:
+                       print '(void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
+                           % (pc, p.offset + adjust, src_ptr, p.size_string() )
+               else:
+                       print '(void) memcpy((void *)(%s + %u + %s), (void *)(%s), %s);' \
+                           % (pc, p.offset + adjust, extra_offset, src_ptr, p.size_string() )
 
-       def common_emit_args(self, f, pc, indent, adjust, skip_vla):
-               # First emit all of the fixed-length 8-byte (i.e., GLdouble)
-               # parameters.
+       def common_emit_args(self, f, pc, adjust, skip_vla):
+               extra_offset = None
+
+               for p in f.parameterIterateGlxSend( not skip_vla ):
+                       if p.name != f.img_reset:
+                               self.common_emit_one_arg(p, pc, adjust, extra_offset)
+                               
+                               if p.is_variable_length():
+                                       temp = p.size_string()
+                                       if extra_offset:
+                                               extra_offset += " + %s" % (temp)
+                                       else:
+                                               extra_offset = temp
+
+               return
 
-               offset = 0
 
-               if skip_vla:
-                       r = [0, 1]
+       def pixel_emit_args(self, f, pc, large):
+               """Emit the arguments for a pixel function.  This differs from
+               common_emit_args in that pixel functions may require padding
+               be inserted (i.e., for the missing width field for
+               TexImage1D), and they may also require a 'NULL image' flag
+               be inserted before the image data."""
+
+               if large:
+                       adjust = 8
                else:
-                       r = [0, 1, 2]
+                       adjust = 4
 
-               for order in r:
-                       for p in f:
-                               if p.is_output or p.order != order: continue
+               for param in f.parameterIterateGlxSend():
+                       if not param.is_image():
+                               self.common_emit_one_arg(param, pc, adjust, None)
 
-                               self.common_emit_one_arg(p, offset, pc, indent, adjust)
-                               offset += p.size()
+                               if f.pad_after(param):
+                                       print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc, (param.offset + param.size()) + adjust)
 
+                       else:
+                               [dim, width, height, depth, extent] = param.get_dimensions()
+                               if f.glx_rop == ~0:
+                                       dim_str = "dim"
+                               else:
+                                       dim_str = str(dim)
+
+                               if param.is_padding:
+                                       print '(void) memset((void *)(%s + %u), 0, %s);' \
+                                       % (pc, (param.offset - 4) + adjust, param.size_string() )
+
+                               if param.img_null_flag:
+                                       if large:
+                                               print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc, (param.offset - 4) + adjust)
+                                       else:
+                                               print '(void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (pc, (param.offset - 4) + adjust, param.name)
 
-               return offset
 
+                               pixHeaderPtr = "%s + %u" % (pc, adjust)
+                               pcPtr = "%s + %u" % (pc, param.offset + adjust)
 
-       def common_func_print_just_header(self, f):
-               print '#define %s %d' % (f.opcode_name(), f.opcode_value())
+                               if not large:
+                                       if param.img_send_null:
+                                               condition = '(compsize > 0) && (%s != NULL)' % (param.name)
+                                       else:
+                                               condition = 'compsize > 0'
 
-               print '%s' % (f.fn_return_type)
-               print '__indirect_gl%s(%s)' % (f.name, f.get_parameter_string())
-               print '{'
+                                       print 'if (%s) {' % (condition)
+                                       print '    (*gc->fillImage)(gc, %s, %s, %s, %s, %s, %s, %s, %s, %s);' % (dim_str, width, height, depth, param.img_format, param.img_type, param.name, pcPtr, pixHeaderPtr)
+                                       print '} else {'
+                                       print '    (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (pixHeaderPtr, dim, dim)
+                                       print '}'
+                               else:
+                                       print '__glXSendLargeImage(gc, compsize, %s, %s, %s, %s, %s, %s, %s, %s, %s);' % (dim_str, width, height, depth, param.img_format, param.img_type, param.name, pcPtr, pixHeaderPtr)
 
+               return
 
-       def common_func_print_header(self, f):
-               self.common_func_print_just_header(f)
 
+       def large_emit_begin(self, f, op_name = None):
+               if not op_name:
+                       op_name = f.opcode_real_name()
+
+               print 'const GLint op = %s;' % (op_name)
+               print 'const GLuint cmdlenLarge = cmdlen + 4;'
+               print 'GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);'
+               print '(void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);'
+               print '(void) memcpy((void *)(pc + 4), (void *)(&op), 4);'
+               return
+
+
+       def common_func_print_just_start(self, f, name):
                print '    __GLXcontext * const gc = __glXGetCurrentContext();'
-               print '    Display * const dpy = gc->currentDpy;'
-                       
-               if f.fn_return_type != 'void':
-                       print '    %s retval = (%s) 0;' % (f.fn_return_type, f.fn_return_type)
 
-               if f.count_parameters != None:
-                       print '    const GLuint compsize = __gl%s_size(%s);' % (f.name, f.count_parameters)
+               # The only reason that single and vendor private commands need
+               # a variable called 'dpy' is becuase they use the SyncHandle
+               # macro.  For whatever brain-dead reason, that macro is hard-
+               # coded to use a variable called 'dpy' instead of taking a
+               # parameter.
+
+               # FIXME Simplify the logic related to skip_condition and
+               # FIXME condition_list in this function.  Basically, remove
+               # FIXME skip_condition, and just append the "dpy != NULL" type
+               # FIXME condition to condition_list from the start.  The only
+               # FIXME reason it's done in this confusing way now is to
+               # FIXME minimize the diffs in the generated code.
+
+               if not f.glx_rop:
+                       for p in f.parameterIterateOutputs():
+                               if p.is_image() and (p.img_format != "GL_COLOR_INDEX" or p.img_type != "GL_BITMAP"):
+                                       print '    const __GLXattribute * const state = gc->client_state_private;'
+                                       break
+
+                       print '    Display * const dpy = gc->currentDpy;'
+                       skip_condition = "dpy != NULL"
+               elif f.can_be_large:
+                       skip_condition = "gc->currentDpy != NULL"
+               else:
+                       skip_condition = None
 
-               print '    const GLuint cmdlen = %s;' % (f.command_length())
 
-               if f.counter != None:
-                       print '    if (%s < 0) %s' % (f.counter, f.return_string())
+               if f.return_type != 'void':
+                       print '    %s retval = (%s) 0;' % (f.return_type, f.return_type)
 
-               if f.can_be_large:
-                       print '    if (dpy == NULL) return;'
-                       print '    if ( ((gc->pc + cmdlen) > gc->bufEnd)'
-                       print '         || (cmdlen > gc->maxSmallRenderCommandSize)) {'
-                       print '        (void) __glXFlushRenderBuffer(gc, gc->pc);'
-                       print '    }'
+
+               if name != None and name not in f.glx_vendorpriv_names:
+                       print '#ifndef USE_XCB'
+               self.emit_packet_size_calculation(f, 0)
+               if name != None and name not in f.glx_vendorpriv_names:
+                       print '#endif'
+
+               condition_list = []
+               for p in f.parameterIterateCounters():
+                       condition_list.append( "%s >= 0" % (p.name) )
+                       # 'counter' parameters cannot be negative
+                       print "    if (%s < 0) {" % p.name
+                       print "        __glXSetError(gc, GL_INVALID_VALUE);"
+                       if f.return_type != 'void':
+                               print "        return 0;"
+                       else:
+                               print "        return;"
+                       print "    }"
+
+               if skip_condition:
+                       condition_list.append( skip_condition )
+
+               if len( condition_list ) > 0:
+                       if len( condition_list ) > 1:
+                               skip_condition = "(%s)" % (string.join( condition_list, ") && (" ))
+                       else:
+                               skip_condition = "%s" % (condition_list.pop(0))
+
+                       print '    if (__builtin_expect(%s, 1)) {' % (skip_condition)
+                       return 1
                else:
-                       print '    (void) dpy;'
+                       return 0
 
-               return
 
+       def printSingleFunction(self, f, name):
+               self.common_func_print_just_start(f, name)
+
+               if self.debug:
+                       print '        printf( "Enter %%s...\\n", "gl%s" );' % (f.name)
 
-       def printSingleFunction(self, f):
-               self.common_func_print_header(f)
+               if name not in f.glx_vendorpriv_names:
 
-               print '    if (dpy != NULL) {'
+                       # XCB specific:
+                       print '#ifdef USE_XCB'
+                       if self.debug:
+                               print '        printf("\\tUsing XCB.\\n");'
+                       print '        xcb_connection_t *c = XGetXCBConnection(dpy);'
+                       print '        (void) __glXFlushRenderBuffer(gc, gc->pc);'
+                       xcb_name = 'xcb_glx%s' % convertStringForXCB(name)
+
+                       iparams=[]
+                       extra_iparams = []
+                       output = None
+                       for p in f.parameterIterator():
+                               if p.is_output:
+                                       output = p
+
+                                       if p.is_image():
+                                               if p.img_format != "GL_COLOR_INDEX" or p.img_type != "GL_BITMAP":
+                                                       extra_iparams.append("state->storePack.swapEndian")
+                                               else:
+                                                       extra_iparams.append("0")
+                                       
+                                               # Hardcode this in.  lsb_first param (apparently always GL_FALSE)
+                                               # also present in GetPolygonStipple, but taken care of above.
+                                               if xcb_name == "xcb_glx_read_pixels": 
+                                                       extra_iparams.append("0")
+                               else:
+                                       iparams.append(p.name)
+
+
+                       xcb_request = '%s(%s)' % (xcb_name, ", ".join(["c", "gc->currentContextTag"] + iparams + extra_iparams))
+
+                       if f.needs_reply():
+                               print '        %s_reply_t *reply = %s_reply(c, %s, NULL);' % (xcb_name, xcb_name, xcb_request)
+                               if output and f.reply_always_array:
+                                       print '        (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output.name, xcb_name, xcb_name, output.get_base_type_string())
+
+                               elif output and not f.reply_always_array:
+                                       if not output.is_image():
+                                               print '        if (%s_data_length(reply) == 0)' % (xcb_name)
+                                               print '            (void)memcpy(%s, &reply->datum, sizeof(reply->datum));' % (output.name)
+                                               print '        else'
+                                       print '        (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output.name, xcb_name, xcb_name, output.get_base_type_string())
+
+
+                               if f.return_type != 'void':
+                                       print '        retval = reply->ret_val;'
+                               print '        free(reply);'
+                       else:
+                               print '        ' + xcb_request + ';'
+                       print '#else'
+                       # End of XCB specific.
 
-               if f.fn_parameters != []:
+
+               if f.parameters != []:
                        pc_decl = "GLubyte const * pc ="
                else:
                        pc_decl = "(void)"
 
-               if f.glx_vendorpriv != 0:
-                       print '        %s setup_vendor_request(gc, %s, %s, cmdlen);' % (pc_decl, f.opcode_real_name(), f.opcode_name())
+               if name in f.glx_vendorpriv_names:
+                       print '        %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl, f.opcode_real_name(), f.opcode_vendor_name(name))
                else:
-                       print '        %s setup_single_request(gc, %s, cmdlen);' % (pc_decl, f.opcode_name())
+                       print '        %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl, f.opcode_name())
 
-               self.common_emit_args(f, "pc", "    ", 0, 0)
+               self.common_emit_args(f, "pc", 0, 0)
 
-               if f.needs_reply():
-                       if f.output != None:
-                               output_size = f.output.p_type.size
-                               output_str = f.output.name
-                       else:
-                               output_size = 0
-                               output_str = "NULL"
+               images = f.get_images()
+
+               for img in images:
+                       if img.is_output:
+                               o = f.command_fixed_length() - 4
+                               print '        *(int32_t *)(pc + %u) = 0;' % (o)
+                               if img.img_format != "GL_COLOR_INDEX" or img.img_type != "GL_BITMAP":
+                                       print '        * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o)
+               
+                               if f.img_reset:
+                                       print '        * (int8_t *)(pc + %u) = %s;' % (o + 1, f.img_reset)
 
-                       if f.fn_return_type != 'void':
-                               return_str = " retval = (%s)" % (f.fn_return_type)
+
+               return_name = ''
+               if f.needs_reply():
+                       if f.return_type != 'void':
+                               return_name = " retval"
+                               return_str = " retval = (%s)" % (f.return_type)
                        else:
                                return_str = " (void)"
 
-                       if f.reply_always_array:
-                               aa = "GL_TRUE"
-                       else:
-                               aa = "GL_FALSE"
+                       got_reply = 0
+
+                       for p in f.parameterIterateOutputs():
+                               if p.is_image():
+                                       [dim, w, h, d, junk] = p.get_dimensions()
+                                       if f.dimensions_in_reply:
+                                               print "        __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim, p.img_format, p.img_type, p.name)
+                                       else:
+                                               print "        __glXReadPixelReply(dpy, gc, %u, %s, %s, %s, %s, %s, %s, GL_FALSE);" % (dim, w, h, d, p.img_format, p.img_type, p.name)
+
+                                       got_reply = 1
+                               else:
+                                       if f.reply_always_array:
+                                               aa = "GL_TRUE"
+                                       else:
+                                               aa = "GL_FALSE"
+
+                                       # gl_parameter.size() returns the size
+                                       # of the entire data item.  If the
+                                       # item is a fixed-size array, this is
+                                       # the size of the whole array.  This
+                                       # is not what __glXReadReply wants. It
+                                       # wants the size of a single data
+                                       # element in the reply packet.
+                                       # Dividing by the array size (1 for
+                                       # non-arrays) gives us this.
+
+                                       s = p.size() / p.get_element_count()
+                                       print "       %s __glXReadReply(dpy, %s, %s, %s);" % (return_str, s, p.name, aa)
+                                       got_reply = 1
+
+
+                       # If a reply wasn't read to fill an output parameter,
+                       # read a NULL reply to get the return value.
+
+                       if not got_reply:
+                               print "       %s __glXReadReply(dpy, 0, NULL, GL_FALSE);" % (return_str)
 
-                       print "       %s read_reply(gc->currentDpy, %s, %s, %s);" % (return_str, output_size, output_str, aa)
 
-               print '        UnlockDisplay(gc->currentDpy); SyncHandle();'
+               elif self.debug:
+                       # Only emit the extra glFinish call for functions
+                       # that don't already require a reply from the server.
+                       print '        __indirect_glFinish();'
+
+               if self.debug:
+                       print '        printf( "Exit %%s.\\n", "gl%s" );' % (name)
+
+
+               print '        UnlockDisplay(dpy); SyncHandle();'
+
+               if name not in f.glx_vendorpriv_names:
+                       print '#endif /* USE_XCB */'
+
                print '    }'
-               print '    %s' % f.return_string()
-               print '}'
-               print ''
+               print '    return%s;' % (return_name)
+               return
+
+
+       def printPixelFunction(self, f):
+               if self.pixel_stubs.has_key( f.name ):
+                       # Normally gl_function::get_parameter_string could be
+                       # used.  However, this call needs to have the missing
+                       # dimensions (e.g., a fake height value for
+                       # glTexImage1D) added in.
+
+                       p_string = ""
+                       for param in f.parameterIterateGlxSend():
+                               if param.is_padding:
+                                       continue
+
+                               p_string += ", " + param.name
+
+                               if param.is_image():
+                                       [dim, junk, junk, junk, junk] = param.get_dimensions()
+
+                               if f.pad_after(param):
+                                       p_string += ", 1"
+
+                       print '    %s(%s, %u%s );' % (self.pixel_stubs[f.name] , f.opcode_name(), dim, p_string)
+                       return
+
+
+               if self.common_func_print_just_start(f, None):
+                       trailer = "    }"
+               else:
+                       trailer = None
+
+
+               if f.can_be_large:
+                       print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
+                       print '    if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
+                       print '        (void) __glXFlushRenderBuffer(gc, gc->pc);'
+                       print '    }'
+
+               if f.glx_rop == ~0:
+                       opcode = "opcode"
+               else:
+                       opcode = f.opcode_real_name()
+
+               print 'emit_header(gc->pc, %s, cmdlen);' % (opcode)
+
+               self.pixel_emit_args( f, "gc->pc", 0 )
+               print 'gc->pc += cmdlen;'
+               print 'if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
+
+               if f.can_be_large:
+                       print '}'
+                       print 'else {'
+
+                       self.large_emit_begin(f, opcode)
+                       self.pixel_emit_args(f, "pc", 1)
+
+                       print '}'
+
+               if trailer: print trailer
                return
 
 
        def printRenderFunction(self, f):
-               if f.variable_length_parameter() == None and len(f.fn_parameters) == 1:
-                       p = f.fn_parameters[0]
-                       if p.is_pointer:
-                               [cmdlen, size_string] = f.command_payload_length()
+               # There is a class of GL functions that take a single pointer
+               # as a parameter.  This pointer points to a fixed-size chunk
+               # of data, and the protocol for this functions is very
+               # regular.  Since they are so regular and there are so many
+               # of them, special case them with generic functions.  On
+               # x86, this saves about 26KB in the libGL.so binary.
+
+               if f.variable_length_parameter() == None and len(f.parameters) == 1:
+                       p = f.parameters[0]
+                       if p.is_pointer():
+                               cmdlen = f.command_fixed_length()
                                if cmdlen in self.generic_sizes:
-                                       self.common_func_print_just_header(f)
                                        print '    generic_%u_byte( %s, %s );' % (cmdlen, f.opcode_real_name(), p.name)
-                                       print '}'
-                                       print ''
                                        return
 
-               self.common_func_print_header(f)
+               if self.common_func_print_just_start(f, None):
+                       trailer = "    }"
+               else:
+                       trailer = None
+
+               if self.debug:
+                       print 'printf( "Enter %%s...\\n", "gl%s" );' % (f.name)
 
                if f.can_be_large:
-                       print '    if (cmdlen <= gc->maxSmallRenderCommandSize) {'
-                       indent = "    "
-               else:
-                       indent = ""
+                       print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
+                       print '    if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
+                       print '        (void) __glXFlushRenderBuffer(gc, gc->pc);'
+                       print '    }'
 
-               print '%s    emit_header(gc->pc, %s, cmdlen);' % (indent, f.opcode_real_name())
+               print 'emit_header(gc->pc, %s, cmdlen);' % (f.opcode_real_name())
 
-               self.common_emit_args(f, "gc->pc", indent, 4, 0)
-               print '%s    gc->pc += cmdlen;' % (indent)
-               print '%s    if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }' % (indent)
+               self.common_emit_args(f, "gc->pc", 4, 0)
+               print 'gc->pc += cmdlen;'
+               print 'if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
 
                if f.can_be_large:
-                       print '    }'
-                       print '    else {'
-                       print '        const GLint op = %s;' % (f.opcode_real_name())
-                       print '        const GLuint cmdlenLarge = cmdlen + 4;'
-                       print '        (void) memcpy((void *)(gc->pc + 0), (void *)(&op), 4);'
-                       print '        (void) memcpy((void *)(gc->pc + 4), (void *)(&cmdlenLarge), 4);'
-                       offset = self.common_emit_args(f, "gc->pc", indent, 8, 1)
-                       
+                       print '}'
+                       print 'else {'
+
+                       self.large_emit_begin(f)
+                       self.common_emit_args(f, "pc", 8, 1)
+
                        p = f.variable_length_parameter()
-                       print '        __glXSendLargeCommand(gc, gc->pc, %u, %s, %s);' % (offset + 8, p.name, p.size_string())
-                       print '    }'
+                       print '    __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (p.offset + 8, p.name, p.size_string())
+                       print '}'
 
-               print '}'
-               print ''
+               if self.debug:
+                       print '__indirect_glFinish();'
+                       print 'printf( "Exit %%s.\\n", "gl%s" );' % (f.name)
+
+               if trailer: print trailer
                return
 
 
-class PrintGlxProtoInit_c(GlxProto):
+class PrintGlxProtoInit_c(gl_XML.gl_print_base):
        def __init__(self):
-               GlxProto.__init__(self)
-               self.last_category = ""
+               gl_XML.gl_print_base.__init__(self)
+
+               self.name = "glX_proto_send.py (from Mesa)"
                self.license = license.bsd_license_template % ( \
 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
+               return
 
 
        def printRealHeader(self):
@@ -795,150 +919,92 @@ __GLapi * __glXNewIndirectAPI( void )
     return glAPI;
 }
 """
+               return
 
-       def printFunction(self, f):
-               if f.fn_offset < 0 or f.ignore: return
-               
-               if f.category != self.last_category:
-                       self.last_category = f.category
-                       print ''
-                       print '    /* %s */' % (self.last_category)
-                       print ''
-                       
-               print '    glAPI->%s = __indirect_gl%s;' % (f.name, f.name)
 
+       def printBody(self, api):
+               for [name, number] in api.categoryIterate():
+                       if number != None:
+                               preamble = '\n    /* %3u. %s */\n\n' % (int(number), name)
+                       else:
+                               preamble = '\n    /* %s */\n\n' % (name)
+
+                       for func in api.functionIterateByCategory(name):
+                               if func.client_supported_for_indirect():
+                                       print '%s    glAPI->%s = __indirect_gl%s;' % (preamble, func.name, func.name)
+                                       preamble = ''
+
+               return
 
-class PrintGlxProtoInit_h(GlxProto):
+
+class PrintGlxProtoInit_h(gl_XML.gl_print_base):
        def __init__(self):
-               GlxProto.__init__(self)
-               self.last_category = ""
+               gl_XML.gl_print_base.__init__(self)
+
+               self.name = "glX_proto_send.py (from Mesa)"
                self.license = license.bsd_license_template % ( \
 """Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
 (C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
+               self.header_tag = "_INDIRECT_H_"
+
+               self.last_category = ""
+               return
 
 
        def printRealHeader(self):
-               print """
-/**
+               print """/**
  * \\file
  * Prototypes for indirect rendering functions.
  *
  * \\author Kevin E. Martin <kevin@precisioninsight.com>
  * \\author Ian Romanick <idr@us.ibm.com>
  */
-
-#if !defined( _INDIRECT_H_ )
-#  define _INDIRECT_H_
-
 """
-               printVisibility( "HIDDEN", "hidden" )
-
-
-       def printRealFooter(self):
-               print "#  undef HIDDEN"
-               print "#endif /* !defined( _INDIRECT_H_ ) */"
-
-       def printFunction(self, f):
-               if f.fn_offset < 0 or f.ignore: return
-               print 'extern HIDDEN %s __indirect_gl%s(%s);' % (f.fn_return_type, f.name, f.get_parameter_string())
+               self.printVisibility( "HIDDEN", "hidden" )
+               self.printFastcall()
+               self.printNoinline()
 
+               print """
+#include "glxclient.h"
 
-class PrintGlxSizeStubs(GlxProto):
-       def __init__(self):
-               GlxProto.__init__(self)
-               self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004", "IBM")
-               self.aliases = []
-               self.glx_enum_sigs = {}
-
-       def printRealHeader(self):
-               print ''
-               print '#include <GL/gl.h>'
-               print '#include "indirect_size.h"'
-               
-               print ''
-               printPure()
-               print ''
-               printFastcall()
-               print ''
-               printVisibility( "INTERNAL", "internal" )
-               print ''
-               print ''
-               print '#ifdef HAVE_ALIAS'
-               print '#  define ALIAS2(from,to) \\'
-               print '    INTERNAL PURE FASTCALL GLint __gl ## from ## _size( GLenum e ) \\'
-               print '        __attribute__ ((alias( # to )));'
-               print '#  define ALIAS(from,to) ALIAS2( from, __gl ## to ## _size )'
-               print '#else'
-               print '#  define ALIAS(from,to) \\'
-               print '    INTERNAL PURE FASTCALL GLint __gl ## from ## _size( GLenum e ) \\'
-               print '    { return __gl ## to ## _size( e ); }'
-               print '#endif'
-               print ''
-               print ''
-
-       def printRealFooter(self):
-               for a in self.aliases:
-                       print a
-
-       def printFunction(self, f):
-               if self.glx_enum_functions.has_key(f.name):
-                       ef = self.glx_enum_functions[f.name]
-
-                       sig = ef.signature();
-                       if self.glx_enum_sigs.has_key(sig):
-                               n = self.glx_enum_sigs[sig];
-                               a = 'ALIAS( %s, %s )' % (f.name, n)
-                               self.aliases.append(a)
-                       else:
-                               ef.Print( f.name )
-                               self.glx_enum_sigs[sig] = f.name;
+extern HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
+    void * dest, GLboolean reply_is_always_array );
 
+extern HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
+    __GLXcontext * gc, unsigned max_dim, GLint width, GLint height,
+    GLint depth, GLenum format, GLenum type, void * dest,
+    GLboolean dimensions_in_reply );
 
-                               
-class PrintGlxSizeStubs_h(GlxProto):
-       def __init__(self):
-               GlxProto.__init__(self)
-               self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004", "IBM")
-               self.aliases = []
-               self.glx_enum_sigs = {}
+extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
+    __GLXcontext * gc, GLint sop, GLint cmdlen );
 
-       def printRealHeader(self):
-               print """
-/**
- * \\file
- * Prototypes for functions used to determine the number of data elements in
- * various GLX protocol messages.
- *
- * \\author Ian Romanick <idr@us.ibm.com>
- */
+extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
+    __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen );
+"""
 
-#if !defined( _GLXSIZE_H_ )
-#  define _GLXSIZE_H_
 
-"""
-               printPure();
-               print ''
-               printFastcall();
-               print ''
-               printVisibility( "INTERNAL", "internal" );
-               print ''
+       def printBody(self, api):
+               for func in api.functionIterateGlx():
+                       params = func.get_parameter_string()
 
-       def printRealFooter(self):
-               print ''
-               print "#  undef INTERNAL"
-               print "#  undef PURE"
-               print "#  undef FASTCALL"
-               print "#endif /* !defined( _GLXSIZE_H_ ) */"
+                       print 'extern HIDDEN %s __indirect_gl%s(%s);' % (func.return_type, func.name, params)
 
+                       for n in func.entry_points:
+                               if func.has_different_protocol(n):
+                                       asdf = func.static_glx_name(n)
+                                       if asdf not in func.static_entry_points:
+                                               print 'extern HIDDEN %s gl%s(%s);' % (func.return_type, asdf, params)
+                                       else:
+                                               print 'GLAPI %s GLAPIENTRY gl%s(%s);' % (func.return_type, asdf, params)
+                                               
+                                       break
 
-       def printFunction(self, f):
-               if self.glx_enum_functions.has_key(f.name):
-                       ef = self.glx_enum_functions[f.name]
-                       print 'extern INTERNAL PURE FASTCALL GLint __gl%s_size(GLenum);' % (f.name)
 
 
 def show_usage():
-       print "Usage: %s [-f input_file_name] [-m output_mode]" % sys.argv[0]
+       print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys.argv[0]
+       print "    -m output_mode   Output mode can be one of 'proto', 'init_c' or 'init_h'."
+       print "    -d               Enable extra debug information in the generated code."
        sys.exit(1)
 
 
@@ -946,36 +1012,31 @@ if __name__ == '__main__':
        file_name = "gl_API.xml"
 
        try:
-               (args, trail) = getopt.getopt(sys.argv[1:], "f:m:")
+               (args, trail) = getopt.getopt(sys.argv[1:], "f:m:d")
        except Exception,e:
                show_usage()
 
+       debug = 0
        mode = "proto"
        for (arg,val) in args:
                if arg == "-f":
                        file_name = val
                elif arg == "-m":
                        mode = val
+               elif arg == "-d":
+                       debug = 1
 
        if mode == "proto":
-               dh = PrintGlxProtoStubs()
+               printer = PrintGlxProtoStubs()
        elif mode == "init_c":
-               dh = PrintGlxProtoInit_c()
+               printer = PrintGlxProtoInit_c()
        elif mode == "init_h":
-               dh = PrintGlxProtoInit_h()
-       elif mode == "size_c":
-               dh = PrintGlxSizeStubs()
-       elif mode == "size_h":
-               dh = PrintGlxSizeStubs_h()
+               printer = PrintGlxProtoInit_h()
        else:
                show_usage()
 
-       parser = make_parser()
-       parser.setFeature(feature_namespaces, 0)
-       parser.setContentHandler(dh)
 
-       f = open(file_name)
+       printer.debug = debug
+       api = gl_XML.parse_GL_API( file_name, glX_XML.glx_item_factory() )
 
-       dh.printHeader()
-       parser.parse(f)
-       dh.printFooter()
+       printer.Print( api )