Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xwin / glx / gen_gl_wrappers.py
CommitLineData
a09e091a
JB
1#!/usr/bin/python3
2#
3# python script to generate cdecl to stdcall wrappers for GL functions
4# adapted from genheaders.py
5#
6# Copyright (c) 2013 The Khronos Group Inc.
7#
8# Permission is hereby granted, free of charge, to any person obtaining a
9# copy of this software and/or associated documentation files (the
10# "Materials"), to deal in the Materials without restriction, including
11# without limitation the rights to use, copy, modify, merge, publish,
12# distribute, sublicense, and/or sell copies of the Materials, and to
13# permit persons to whom the Materials are furnished to do so, subject to
14# the following conditions:
15#
16# The above copyright notice and this permission notice shall be included
17# in all copies or substantial portions of the Materials.
18#
19# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
26
27import sys, time, pdb, string, cProfile
28from reg import *
29
30# Default input / log files
31errFilename = None
32diagFilename = 'diag.txt'
33regFilename = 'gl.xml'
34outFilename = 'gen_gl_wrappers.c'
35
36protect=True
37prefix="gl"
38preresolve=False
39wrapper=False
40shim=False
41thunk=False
42thunkdefs=False
43staticwrappers=False
44nodebug=False
45
46#exclude base WGL API
47WinGDI={key: 1 for key in [
48 "wglCopyContext"
49 ,"wglCreateContext"
50 ,"wglCreateLayerContext"
51 ,"wglDeleteContext"
52 ,"wglGetCurrentContext"
53 ,"wglGetCurrentDC"
54 ,"wglGetProcAddress"
55 ,"wglMakeCurrent"
56 ,"wglShareLists"
57 ,"wglUseFontBitmapsA"
58 ,"wglUseFontBitmapsW"
59 ,"wglUseFontBitmaps"
60 ,"SwapBuffers"
61 ,"wglUseFontOutlinesA"
62 ,"wglUseFontOutlinesW"
63 ,"wglUseFontOutlines"
64 ,"wglDescribeLayerPlane"
65 ,"wglSetLayerPaletteEntries"
66 ,"wglGetLayerPaletteEntries"
67 ,"wglRealizeLayerPalette"
68 ,"wglSwapLayerBuffers"
69 ,"wglSwapMultipleBuffers"
70 ,"ChoosePixelFormat"
71 ,"DescribePixelFormat"
72 ,"GetEnhMetaFilePixelFormat"
73 ,"GetPixelFormat"
74 ,"SetPixelFormat"
75]}
76
77if __name__ == '__main__':
78 i = 1
79 while (i < len(sys.argv)):
80 arg = sys.argv[i]
81 i = i + 1
82 if (arg == '-noprotect'):
83 print('Disabling inclusion protection in output headers', file=sys.stderr)
84 protect = False
85 elif (arg == '-registry'):
86 regFilename = sys.argv[i]
87 i = i+1
88 print('Using registry', regFilename, file=sys.stderr)
89 elif (arg == '-outfile'):
90 outFilename = sys.argv[i]
91 i = i+1
92 elif (arg == '-preresolve'):
93 preresolve=True
94 elif (arg == '-wrapper'):
95 wrapper=True
96 elif (arg == '-shim'):
97 shim=True
98 elif (arg == '-thunk'):
99 thunk=True
100 elif (arg == '-thunkdefs'):
101 thunkdefs=True
102 elif (arg == '-staticwrappers'):
103 staticwrappers=True
104 elif (arg == '-prefix'):
105 prefix = sys.argv[i]
106 i = i+1
107 elif (arg == '-nodebug'):
108 nodebug = True
109 elif (arg[0:1] == '-'):
110 print('Unrecognized argument:', arg, file=sys.stderr)
111 exit(1)
112
113print('Generating', outFilename, file=sys.stderr)
114
115# Load & parse registry
116reg = Registry()
117tree = etree.parse(regFilename)
118reg.loadElementTree(tree)
119
120allVersions = '.*'
121
122genOpts = CGeneratorOptions(
123 apiname = prefix,
124 profile = 'compatibility',
125 versions = allVersions,
126 emitversions = allVersions,
127 defaultExtensions = prefix, # Default extensions for GL
128 protectFile = protect,
129 protectFeature = protect,
130 protectProto = protect,
131 )
132
133# create error/warning & diagnostic files
134if (errFilename):
135 errWarn = open(errFilename,'w')
136else:
137 errWarn = sys.stderr
138diag = open(diagFilename, 'w')
139
140class PreResolveOutputGenerator(OutputGenerator):
141 def __init__(self,
142 errFile = sys.stderr,
143 warnFile = sys.stderr,
144 diagFile = sys.stdout):
145 OutputGenerator.__init__(self, errFile, warnFile, diagFile)
146 self.wrappers={}
147 def beginFile(self, genOpts):
148 self.outFile.write('/* Automatically generated from %s - DO NOT EDIT */\n\n'%regFilename)
149 def endFile(self):
150 self.outFile.write('\nvoid ' + prefix + 'ResolveExtensionProcs(void)\n{\n')
151 for funcname in self.wrappers.keys():
152 self.outFile.write( ' PRERESOLVE(PFN' + funcname.upper() + 'PROC, "' + funcname + '");\n')
153 self.outFile.write('}\n\n')
154 def beginFeature(self, interface, emit):
155 OutputGenerator.beginFeature(self, interface, emit)
156 def endFeature(self):
157 OutputGenerator.endFeature(self)
158 def genType(self, typeinfo, name):
159 OutputGenerator.genType(self, typeinfo, name)
160 def genEnum(self, enuminfo, name):
161 OutputGenerator.genEnum(self, enuminfo, name)
162 def genCmd(self, cmd, name):
163 OutputGenerator.genCmd(self, cmd, name)
164
165 if name in WinGDI:
166 return
167
168 self.outFile.write('RESOLVE_DECL(PFN' + name.upper() + 'PROC);\n')
169 self.wrappers[name]=1
170
171class WrapperOutputGenerator(OutputGenerator):
172 def __init__(self,
173 errFile = sys.stderr,
174 warnFile = sys.stderr,
175 diagFile = sys.stdout):
176 OutputGenerator.__init__(self, errFile, warnFile, diagFile)
177 def beginFile(self, genOpts):
178 self.outFile.write('/* Automatically generated from %s - DO NOT EDIT */\n\n'%regFilename)
179 def endFile(self):
180 pass
181 def beginFeature(self, interface, emit):
182 OutputGenerator.beginFeature(self, interface, emit)
183 self.OldVersion = self.featureName.startswith('GL_VERSION_1_0') or self.featureName.startswith('GL_VERSION_1_1')
184 def endFeature(self):
185 OutputGenerator.endFeature(self)
186 def genType(self, typeinfo, name):
187 OutputGenerator.genType(self, typeinfo, name)
188 def genEnum(self, enuminfo, name):
189 OutputGenerator.genEnum(self, enuminfo, name)
190 def genCmd(self, cmd, name):
191 OutputGenerator.genCmd(self, cmd, name)
192
193 if name in WinGDI:
194 return
195
196 proto=noneStr(cmd.elem.find('proto'))
197 rettype=noneStr(proto.text)
198 if rettype.lower()!="void ":
199 plist = ([t for t in proto.itertext()])
200 rettype = ''.join(plist[:-1])
201 rettype=rettype.strip()
202 if staticwrappers: self.outFile.write("static ")
203 self.outFile.write("%s %sWrapper("%(rettype, name))
204 params = cmd.elem.findall('param')
205 plist=[]
206 for param in params:
207 paramlist = ([t for t in param.itertext()])
208 paramtype = ''.join(paramlist[:-1])
209 paramname = paramlist[-1]
210 plist.append((paramtype, paramname))
211 Comma=""
212 if len(plist):
213 for ptype, pname in plist:
214 self.outFile.write("%s%s%s_"%(Comma, ptype, pname))
215 Comma=", "
216 else:
217 self.outFile.write("void")
218
219 self.outFile.write(")\n{\n")
220
221 # for GL 1.0 and 1.1 functions, generate stdcall wrappers which call the function directly
222 if self.OldVersion:
223 if not nodebug:
224 self.outFile.write(' if (glxWinDebugSettings.enable%scallTrace) ErrorF("%s\\n");\n'%(prefix.upper(), name))
225 self.outFile.write(" glWinDirectProcCalls++;\n")
226 self.outFile.write("\n")
227
228 if rettype.lower()=="void":
229 self.outFile.write(" %s( "%(name))
230 else:
231 self.outFile.write(" return %s( "%(name))
232
233 Comma=""
234 for ptype, pname in plist:
235 self.outFile.write("%s%s_"%(Comma, pname))
236 Comma=", "
237
238 # for GL 1.2+ functions, generate stdcall wrappers which use wglGetProcAddress()
239 else:
240 if rettype.lower()=="void":
241 self.outFile.write(' RESOLVE(PFN%sPROC, "%s");\n'%(name.upper(), name))
242
243 if not nodebug:
244 self.outFile.write("\n")
245 self.outFile.write(' if (glxWinDebugSettings.enable%scallTrace) ErrorF("%s\\n");\n'%(prefix.upper(), name))
246 self.outFile.write("\n")
247
248 self.outFile.write(" RESOLVED_PROC(PFN%sPROC)( """%(name.upper()))
249 else:
250 self.outFile.write(' RESOLVE_RET(PFN%sPROC, "%s", FALSE);\n'%(name.upper(), name))
251
252 if not nodebug:
253 self.outFile.write("\n")
254 self.outFile.write(' if (glxWinDebugSettings.enable%scallTrace) ErrorF("%s\\n");\n'%(prefix.upper(), name))
255 self.outFile.write("\n")
256
257 self.outFile.write(" return RESOLVED_PROC(PFN%sPROC)("%(name.upper()))
258
259 Comma=""
260 for ptype, pname in plist:
261 self.outFile.write("%s%s_"%(Comma, pname))
262 Comma=", "
263 self.outFile.write(" );\n}\n\n")
264
265class ThunkOutputGenerator(OutputGenerator):
266 def __init__(self,
267 errFile = sys.stderr,
268 warnFile = sys.stderr,
269 diagFile = sys.stdout):
270 OutputGenerator.__init__(self, errFile, warnFile, diagFile)
271 def beginFile(self, genOpts):
272 self.outFile.write('/* Automatically generated from %s - DO NOT EDIT */\n\n'%regFilename)
273 def endFile(self):
274 pass
275 def beginFeature(self, interface, emit):
276 OutputGenerator.beginFeature(self, interface, emit)
277 self.OldVersion = self.featureName.startswith('GL_VERSION_1_0') or self.featureName.startswith('GL_VERSION_1_1')
278 def endFeature(self):
279 OutputGenerator.endFeature(self)
280 def genType(self, typeinfo, name):
281 OutputGenerator.genType(self, typeinfo, name)
282 def genEnum(self, enuminfo, name):
283 OutputGenerator.genEnum(self, enuminfo, name)
284 def genCmd(self, cmd, name):
285 OutputGenerator.genCmd(self, cmd, name)
286
287 proto=noneStr(cmd.elem.find('proto'))
288 rettype=noneStr(proto.text)
289 if rettype.lower()!="void ":
290 plist = ([t for t in proto.itertext()])
291 rettype = ''.join(plist[:-1])
292 rettype=rettype.strip()
293 self.outFile.write("%s %sWrapper("%(rettype, name))
294 params = cmd.elem.findall('param')
295 plist=[]
296 for param in params:
297 paramlist = ([t for t in param.itertext()])
298 paramtype = ''.join(paramlist[:-1])
299 paramname = paramlist[-1]
300 plist.append((paramtype, paramname))
301 Comma=""
302 if len(plist):
303 for ptype, pname in plist:
304 self.outFile.write("%s%s%s_"%(Comma, ptype, pname))
305 Comma=", "
306 else:
307 self.outFile.write("void")
308
309 self.outFile.write(")\n{\n")
310
311 # for GL 1.0 and 1.1 functions, generate stdcall thunk wrappers which call the function directly
312 if self.OldVersion:
313 if rettype.lower()=="void":
314 self.outFile.write(" %s( "%(name))
315 else:
316 self.outFile.write(" return %s( "%(name))
317
318 Comma=""
319 for ptype, pname in plist:
320 self.outFile.write("%s%s_"%(Comma, pname))
321 Comma=", "
322
323 # for GL 1.2+ functions, generate wrappers which use wglGetProcAddress()
324 else:
325 if rettype.lower()=="void":
326 self.outFile.write(' RESOLVE(PFN%sPROC, "%s");\n'%(name.upper(), name))
327 self.outFile.write(" RESOLVED_PROC(PFN%sPROC)( """%(name.upper()))
328 else:
329 self.outFile.write(' RESOLVE_RET(PFN%sPROC, "%s", FALSE);\n'%(name.upper(), name))
330 self.outFile.write(" return RESOLVED_PROC(PFN%sPROC)("%(name.upper()))
331
332 Comma=""
333 for ptype, pname in plist:
334 self.outFile.write("%s%s_"%(Comma, pname))
335 Comma=", "
336 self.outFile.write(" );\n}\n\n")
337
338class ThunkDefsOutputGenerator(OutputGenerator):
339 def __init__(self,
340 errFile = sys.stderr,
341 warnFile = sys.stderr,
342 diagFile = sys.stdout):
343 OutputGenerator.__init__(self, errFile, warnFile, diagFile)
344 def beginFile(self, genOpts):
345 self.outFile.write("EXPORTS\n"); # this must be the first line for libtool to realize this is a .def file
346 self.outFile.write('; Automatically generated from %s - DO NOT EDIT\n\n'%regFilename)
347 def endFile(self):
348 pass
349 def beginFeature(self, interface, emit):
350 OutputGenerator.beginFeature(self, interface, emit)
351 def endFeature(self):
352 OutputGenerator.endFeature(self)
353 def genType(self, typeinfo, name):
354 OutputGenerator.genType(self, typeinfo, name)
355 def genEnum(self, enuminfo, name):
356 OutputGenerator.genEnum(self, enuminfo, name)
357 def genCmd(self, cmd, name):
358 OutputGenerator.genCmd(self, cmd, name)
359
360 # export the wrapper function with the name of the function it wraps
361 self.outFile.write("%s = %sWrapper\n"%(name, name))
362
363class ShimOutputGenerator(OutputGenerator):
364 def __init__(self,
365 errFile = sys.stderr,
366 warnFile = sys.stderr,
367 diagFile = sys.stdout):
368 OutputGenerator.__init__(self, errFile, warnFile, diagFile)
369 def beginFile(self, genOpts):
370 self.outFile.write('/* Automatically generated from %s - DO NOT EDIT */\n\n'%regFilename)
371 def endFile(self):
372 pass
373 def beginFeature(self, interface, emit):
374 OutputGenerator.beginFeature(self, interface, emit)
375 self.OldVersion = self.featureName.startswith('GL_VERSION_1_0') or self.featureName.startswith('GL_VERSION_1_1') or self.featureName.startswith('GL_VERSION_1_2') or self.featureName.startswith('GL_ARB_imaging') or self.featureName.startswith('GL_ARB_multitexture') or self.featureName.startswith('GL_ARB_texture_compression')
376 def endFeature(self):
377 OutputGenerator.endFeature(self)
378 def genType(self, typeinfo, name):
379 OutputGenerator.genType(self, typeinfo, name)
380 def genEnum(self, enuminfo, name):
381 OutputGenerator.genEnum(self, enuminfo, name)
382 def genCmd(self, cmd, name):
383 OutputGenerator.genCmd(self, cmd, name)
384
385 if not self.OldVersion:
386 return
387
388 # for GL functions which are in the ABI, generate a shim which calls the function via GetProcAddress
389 proto=noneStr(cmd.elem.find('proto'))
390 rettype=noneStr(proto.text)
391 if rettype.lower()!="void ":
392 plist = ([t for t in proto.itertext()])
393 rettype = ''.join(plist[:-1])
394 rettype=rettype.strip()
395 self.outFile.write("%s %s("%(rettype, name))
396 params = cmd.elem.findall('param')
397 plist=[]
398 for param in params:
399 paramlist = ([t for t in param.itertext()])
400 paramtype = ''.join(paramlist[:-1])
401 paramname = paramlist[-1]
402 plist.append((paramtype, paramname))
403 Comma=""
404 if len(plist):
405 for ptype, pname in plist:
406 self.outFile.write("%s%s%s_"%(Comma, ptype, pname))
407 Comma=", "
408 else:
409 self.outFile.write("void")
410
411 self.outFile.write(")\n{\n")
412
413 self.outFile.write(' typedef %s (* PFN%sPROC)(' % (rettype, name.upper()))
414
415 if len(plist):
416 Comma=""
417 for ptype, pname in plist:
418 self.outFile.write("%s %s %s_"%(Comma, ptype, pname))
419 Comma=", "
420 else:
421 self.outFile.write("void")
422
423 self.outFile.write(');\n')
424
425 if rettype.lower()=="void":
426 self.outFile.write(' RESOLVE(PFN%sPROC, "%s");\n'%(name.upper(), name))
427 self.outFile.write(' RESOLVED_PROC(')
428 else:
429 self.outFile.write(' RESOLVE_RET(PFN%sPROC, "%s", 0);\n'%(name.upper(), name))
430 self.outFile.write(' return RESOLVED_PROC(')
431
432 Comma=""
433 for ptype, pname in plist:
434 self.outFile.write("%s%s_"%(Comma, pname))
435 Comma=", "
436
437 self.outFile.write(" );\n}\n\n")
438
439def genHeaders():
440 outFile = open(outFilename,"w")
441
442 if preresolve:
443 gen = PreResolveOutputGenerator(errFile=errWarn,
444 warnFile=errWarn,
445 diagFile=diag)
446 gen.outFile=outFile
447 reg.setGenerator(gen)
448 reg.apiGen(genOpts)
449
450 if wrapper:
451 gen = WrapperOutputGenerator(errFile=errWarn,
452 warnFile=errWarn,
453 diagFile=diag)
454 gen.outFile=outFile
455 reg.setGenerator(gen)
456 reg.apiGen(genOpts)
457
458 if shim:
459 gen = ShimOutputGenerator(errFile=errWarn,
460 warnFile=errWarn,
461 diagFile=diag)
462 gen.outFile=outFile
463 reg.setGenerator(gen)
464 reg.apiGen(genOpts)
465
466 if thunk:
467 gen = ThunkOutputGenerator(errFile=errWarn,
468 warnFile=errWarn,
469 diagFile=diag)
470 gen.outFile=outFile
471 reg.setGenerator(gen)
472 reg.apiGen(genOpts)
473
474
475 if thunkdefs:
476 gen = ThunkDefsOutputGenerator(errFile=errWarn,
477 warnFile=errWarn,
478 diagFile=diag)
479 gen.outFile=outFile
480 reg.setGenerator(gen)
481 reg.apiGen(genOpts)
482
483 outFile.close()
484
485genHeaders()