3 # (C) Copyright IBM Corporation 2004, 2005
6 # Permission is hereby granted, free of charge, to any person obtaining a
7 # copy of this software and associated documentation files (the "Software"),
8 # to deal in the Software without restriction, including without limitation
9 # on the rights to use, copy, modify, merge, publish, distribute, sub
10 # license, and/or sell copies of the Software, and to permit persons to whom
11 # the Software is furnished to do so, subject to the following conditions:
13 # The above copyright notice and this permission notice (including the next
14 # paragraph) shall be included in all copies or substantial portions of the
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20 # IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
26 # Ian Romanick <idr@us.ibm.com>
28 from xml
.sax
import saxutils
29 from xml
.sax
import make_parser
30 from xml
.sax
.handler
import feature_namespaces
35 import sys
, getopt
, copy
38 class SizeStubFunctionIterator(glX_XML
.glXFunctionIterator
):
39 """Iterate over functions that need "size" information.
41 Iterate over the functions that have variable sized data. First the
42 "set"-type functions are iterated followed by the "get"-type
46 def __init__(self
, context
):
54 for f
in gl_XML
.glFunctionIterator(context
):
55 if context
.glx_enum_functions
.has_key(f
.name
):
56 ef
= context
.glx_enum_functions
[f
.name
]
58 set_functions
.append(f
)
60 get_functions
.append(f
)
63 if (context
.which_functions
& PrintGlxSizeStubs_c
.do_set
) != 0:
64 self
.data
+= set_functions
65 elif context
.get_alias_set
:
66 extra_data
= set_functions
68 if (context
.which_functions
& PrintGlxSizeStubs_c
.do_get
) != 0:
69 self
.data
+= get_functions
72 for f
in extra_data
+ self
.data
:
73 sig
= context
.glx_enum_functions
[f
.name
].signature()
75 if not context
.glx_enum_sigs
.has_key(sig
):
76 context
.glx_enum_sigs
[sig
] = f
.name
;
82 if self
.index
== len(self
.data
):
85 f
= self
.data
[ self
.index
]
91 class glXServerEnumFunction(glX_XML
.glXEnumFunction
):
92 def signature( self
):
94 sig
= glX_XML
.glXEnumFunction
.signature(self
)
96 f
= self
.context
.find_function( self
.name
)
97 p
= f
.variable_length_parameter()
100 sig
+= "%u" % (p
.p_type
.size
)
102 print '%s' % (self
.name
)
110 def Print(self
, name
):
111 f
= self
.context
.find_function( self
.name
)
112 self
.context
.common_func_print_just_header( f
)
116 for p
in f
.parameterIterator(1, 1):
117 if f
.count_parameter_list
.count(p
.name
) or p
.name
== f
.counter
:
118 self
.context
.common_emit_one_arg(p
, o
, "pc", " ", 0)
123 print ' GLsizei compsize;'
126 self
.context
.common_emit_fixups(fixup
)
129 print ' compsize = %s;' % (context
.size_call(context
, f
))
130 p
= f
.variable_length_parameter()
131 print ' return __GLX_PAD(%s);' % (p
.size_string())
137 class PrintGlxSizeStubs_common(glX_XML
.GlxProto
):
140 do_get_alias_set
= (1 << 2)
142 def __init__(self
, which_functions
):
143 glX_XML
.GlxProto
.__init
__(self
)
144 self
.license
= license
.bsd_license_template
% ( "(C) Copyright IBM Corporation 2004", "IBM")
146 self
.glx_enum_sigs
= {}
147 self
.name
= "glX_proto_size.py (from Mesa)"
148 self
.which_functions
= which_functions
150 if (((which_functions
& PrintGlxSizeStubs_common
.do_set
) != 0) and ((which_functions
& PrintGlxSizeStubs_common
.do_get
) != 0)) or ((which_functions
& PrintGlxSizeStubs_common
.do_get_alias_set
) != 0):
151 self
.get_alias_set
= 1
153 self
.get_alias_set
= 0
156 def functionIterator(self
):
157 return SizeStubFunctionIterator(self
)
160 class PrintGlxSizeStubs_c(PrintGlxSizeStubs_common
):
161 def printRealHeader(self
):
163 print '#include <GL/gl.h>'
164 print '#include "indirect_size.h"'
167 self
.printHaveAlias()
173 self
.printVisibility( "INTERNAL", "internal" )
176 print '#ifdef HAVE_ALIAS'
177 print '# define ALIAS2(from,to) \\'
178 print ' INTERNAL PURE FASTCALL GLint __gl ## from ## _size( GLenum e ) \\'
179 print ' __attribute__ ((alias( # to )));'
180 print '# define ALIAS(from,to) ALIAS2( from, __gl ## to ## _size )'
182 print '# define ALIAS(from,to) \\'
183 print ' INTERNAL PURE FASTCALL GLint __gl ## from ## _size( GLenum e ) \\'
184 print ' { return __gl ## to ## _size( e ); }'
190 def printRealFooter(self
):
191 for a
in self
.aliases
:
195 def printFunction(self
, f
):
196 ef
= self
.glx_enum_functions
[f
.name
]
197 n
= self
.glx_enum_sigs
[ ef
.signature() ];
200 a
= 'ALIAS( %s, %s )' % (f
.name
, n
)
201 self
.aliases
.append(a
)
207 class PrintGlxSizeStubs_h(PrintGlxSizeStubs_common
):
208 def printRealHeader(self
):
211 * Prototypes for functions used to determine the number of data elements in
212 * various GLX protocol messages.
214 * \\author Ian Romanick <idr@us.ibm.com>
219 self
.printFastcall();
221 self
.printVisibility( "INTERNAL", "internal" );
225 def printFunction(self
, f
):
226 ef
= self
.glx_enum_functions
[f
.name
]
227 print 'extern INTERNAL PURE FASTCALL GLint __gl%s_size(GLenum);' % (f
.name
)
230 class PrintGlxReqSize_h(glX_XML
.GlxProto
):
232 glX_XML
.GlxProto
.__init
__(self
)
233 self
.name
= "glX_proto_size.py (from Mesa)"
234 self
.license
= license
.bsd_license_template
% ( "(C) Copyright IBM Corporation 2005", "IBM")
236 self
.glx_enum_sigs
= {}
237 self
.header_tag
= "_INDIRECT_REQSIZE_H_"
240 def printRealHeader(self
):
241 self
.printVisibility("HIDDEN", "hidden")
247 def printFunction(self
, f
):
248 if f
.glx_rop
== 0: return
251 for p
in f
.parameterIterator(1,2):
256 if self
.glx_enum_functions
.has_key(f
.name
) or f
.image
or has_counter
:
257 print 'extern PURE HIDDEN int __glX%sReqSize(const GLbyte *pc, Bool swap);' % (f
.name
)
260 class PrintGlxReqSize_c(glX_XML
.GlxProto
):
262 glX_XML
.GlxProto
.__init
__(self
)
263 self
.name
= "glX_proto_size.py (from Mesa)"
264 self
.license
= license
.bsd_license_template
% ( "(C) Copyright IBM Corporation 2005", "IBM")
266 self
.glx_enum_sigs
= {}
267 self
.counter_sigs
= {}
270 def createEnumFunction(self
, n
):
271 return glXServerEnumFunction(n
, self
)
274 def printRealHeader(self
):
276 print '#include <GL/gl.h>'
277 print '#include <byteswap.h>'
278 print '#include "glxserver.h"'
279 print '#include "indirect_size.h"'
280 print '#include "indirect_reqsize.h"'
283 print '#define __GLX_PAD(x) (((x) + 3) & ~3)'
285 self
.printHaveAlias()
287 print '#ifdef HAVE_ALIAS'
288 print '# define ALIAS2(from,to) \\'
289 print ' GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap ) \\'
290 print ' __attribute__ ((alias( # to )));'
291 print '# define ALIAS(from,to) ALIAS2( from, __glX ## to ## ReqSize )'
293 print '# define ALIAS(from,to) \\'
294 print ' GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap ) \\'
295 print ' { return __glX ## to ## ReqSize( pc, swap ); }'
301 def printRealFooter(self
):
302 for a
in self
.aliases
:
306 def printFunction(self
, f
):
307 if f
.glx_rop
== 0 or f
.server_handcode
: return
309 if self
.glx_enum_functions
.has_key(f
.name
):
310 ef
= self
.glx_enum_functions
[f
.name
]
312 sig
= ef
.signature();
313 if self
.glx_enum_sigs
.has_key(sig
):
314 n
= self
.glx_enum_sigs
[sig
];
315 a
= 'ALIAS( %s, %s )' % (f
.name
, n
)
316 self
.aliases
.append(a
)
319 self
.glx_enum_sigs
[sig
] = f
.name
;
321 self
.printPixelFunction(f
)
323 for p
in f
.parameterIterator(1,2):
324 if p
.counter
and not p
.is_output
:
325 self
.printCountedFunction(f
)
329 def common_emit_fixups(self
, fixup
):
330 """Utility function to emit conditional byte-swaps."""
335 print ' %-14s = bswap_32( %s );' % (name
, name
)
341 def common_emit_one_arg(self
, p
, offset
, pc
, indent
, adjust
):
342 dst
= '%s %s' % (p
.p_type_string
, p
.name
)
343 src
= '(%s *)' % (p
.p_type_string
)
344 print '%s%-18s = *%11s(%s + %u);' % (indent
, dst
, src
, pc
, offset
+ adjust
);
348 def common_func_print_just_header(self
, f
):
350 print '__glX%sReqSize( const GLbyte * pc, Bool swap )' % (f
.name
)
354 def printPixelFunction(self
, f
):
355 self
.common_func_print_just_header(f
)
357 [dim
, w
, h
, d
, junk
] = f
.dimensions()
359 offset
= f
.offset_of_first_parameter()
361 print ' GLint row_length = * (GLint *)(pc + 4);'
364 fixup
= ['row_length', 'skip_rows', 'alignment']
365 print ' GLint image_height = 0;'
366 print ' GLint skip_images = 0;'
367 print ' GLint skip_rows = * (GLint *)(pc + 8);'
368 print ' GLint alignment = * (GLint *)(pc + 16);'
370 fixup
= ['row_length', 'image_height', 'skip_rows', 'skip_images', 'alignment']
371 print ' GLint image_height = * (GLint *)(pc + 8);'
372 print ' GLint skip_rows = * (GLint *)(pc + 16);'
373 print ' GLint skip_images = * (GLint *)(pc + 20);'
374 print ' GLint alignment = * (GLint *)(pc + 32);'
376 for p
in f
.parameterIterator(1, 2):
377 if p
.name
in [w
, h
, d
, f
.image
.img_format
, f
.image
.img_type
, f
.image
.img_target
]:
378 self
.common_emit_one_arg(p
, offset
, "pc", " ", 0 )
379 fixup
.append( p
.name
)
385 self
.common_emit_fixups(fixup
)
388 print ' return __glXImageSize(%s, %s, %s, %s, %s, %s,' % (f
.image
.img_format
, f
.image
.img_type
, f
.image
.img_target
, w
, h
, d
)
389 print ' image_height, row_length, skip_images,'
390 print ' skip_rows, alignment);'
396 def printCountedFunction(self
, f
):
406 # Calculate the offset of each counter parameter and the
407 # size string for the variable length parameter(s). While
408 # that is being done, calculate a unique signature for this
411 for p
in f
.parameterIterator(1,2):
413 param_offsets
[ p
.name
] = offset
414 fixup
.append( p
.name
)
415 params
.append( [p
, offset
] )
420 sig
+= "(%u,%u)" % (param_offsets
[p
.counter
], s
)
421 size
+= '%s%s' % (plus
, p
.size_string())
428 # If the calculate signature matches a function that has
429 # already be emitted, don't emit this function. Instead, add
430 # it to the list of function aliases.
432 if self
.counter_sigs
.has_key(sig
):
433 n
= self
.counter_sigs
[sig
];
434 a
= 'ALIAS( %s, %s )' % (f
.name
, n
)
435 self
.aliases
.append(a
)
437 self
.counter_sigs
[sig
] = f
.name
439 self
.common_func_print_just_header(f
)
441 for [p
, offset
] in params
:
442 self
.common_emit_one_arg(p
, offset
, "pc", " ", 0 )
446 self
.common_emit_fixups(fixup
)
449 print ' return __GLX_PAD(%s);' % (size
)
457 print "Usage: %s [-f input_file_name] -m output_mode [--only-get | --only-set] [--get-alias-set]" % sys
.argv
[0]
458 print " -m output_mode Output mode can be one of 'size_c' or 'size_h'."
459 print " --only-get Only emit 'get'-type functions."
460 print " --only-set Only emit 'set'-type functions."
461 print " --get-alias-set When only 'get'-type functions are emitted, allow them"
462 print " to be aliases to 'set'-type funcitons."
464 print "By default, both 'get' and 'set'-type functions are emitted."
468 if __name__
== '__main__':
469 file_name
= "gl_API.xml"
472 (args
, trail
) = getopt
.getopt(sys
.argv
[1:], "f:m:h:", ["only-get", "only-set", "get-alias-set", "header-tag"])
478 which_functions
= PrintGlxSizeStubs_common
.do_get | PrintGlxSizeStubs_common
.do_set
480 for (arg
,val
) in args
:
485 elif arg
== "--only-get":
486 which_functions
= PrintGlxSizeStubs_common
.do_get
487 elif arg
== "--only-set":
488 which_functions
= PrintGlxSizeStubs_common
.do_set
489 elif arg
== "--get-alias-set":
490 which_functions |
= PrintGlxSizeStubs_common
.do_get_alias_set
491 elif (arg
== '-h') or (arg
== "--header-tag"):
495 dh
= PrintGlxSizeStubs_c( which_functions
)
496 elif mode
== "size_h":
497 dh
= PrintGlxSizeStubs_h( which_functions
)
499 dh
.header_tag
= header_tag
500 elif mode
== "reqsize_c":
501 dh
= PrintGlxReqSize_c()
502 elif mode
== "reqsize_h":
503 dh
= PrintGlxReqSize_h()
507 parser
= make_parser()
508 parser
.setFeature(feature_namespaces
, 0)
509 parser
.setContentHandler(dh
)