xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

gen_gl_wrappers.py (17186B)


      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 
     27 import sys, time, pdb, string, cProfile
     28 from reg import *
     29 
     30 # Default input / log files
     31 errFilename = None
     32 diagFilename = 'diag.txt'
     33 regFilename = 'gl.xml'
     34 outFilename = 'gen_gl_wrappers.c'
     35 
     36 protect=True
     37 prefix="gl"
     38 preresolve=False
     39 wrapper=False
     40 shim=False
     41 thunk=False
     42 thunkdefs=False
     43 staticwrappers=False
     44 nodebug=False
     45 
     46 # list of WGL extension functions we use
     47 used_wgl_ext_fns = {key: 1 for key in [
     48     "wglSwapIntervalEXT",
     49     "wglGetExtensionsStringARB",
     50     "wglDestroyPbufferARB",
     51     "wglGetPbufferDCARB",
     52     "wglReleasePbufferDCARB",
     53     "wglCreatePbufferARB",
     54     "wglMakeContextCurrentARB",
     55     "wglChoosePixelFormatARB",
     56     "wglGetPixelFormatAttribivARB",
     57     "wglGetPixelFormatAttribivARB"
     58 ]}
     59 
     60 if __name__ == '__main__':
     61     i = 1
     62     while (i < len(sys.argv)):
     63         arg = sys.argv[i]
     64         i = i + 1
     65         if (arg == '-noprotect'):
     66             print('Disabling inclusion protection in output headers', file=sys.stderr)
     67             protect = False
     68         elif (arg == '-registry'):
     69             regFilename = sys.argv[i]
     70             i = i+1
     71             print('Using registry', regFilename, file=sys.stderr)
     72         elif (arg == '-outfile'):
     73             outFilename = sys.argv[i]
     74             i = i+1
     75         elif (arg == '-preresolve'):
     76             preresolve=True
     77         elif (arg == '-wrapper'):
     78             wrapper=True
     79         elif (arg == '-shim'):
     80             shim=True
     81         elif (arg == '-thunk'):
     82             thunk=True
     83         elif (arg == '-thunkdefs'):
     84             thunkdefs=True
     85         elif (arg == '-staticwrappers'):
     86             staticwrappers=True
     87         elif (arg == '-prefix'):
     88             prefix = sys.argv[i]
     89             i = i+1
     90         elif (arg == '-nodebug'):
     91             nodebug = True
     92         elif (arg[0:1] == '-'):
     93             print('Unrecognized argument:', arg, file=sys.stderr)
     94             exit(1)
     95 
     96 print('Generating', outFilename, file=sys.stderr)
     97 
     98 # Load & parse registry
     99 reg = Registry()
    100 tree = etree.parse(regFilename)
    101 reg.loadElementTree(tree)
    102 
    103 if shim:
    104     versions = '1\.[012]'
    105 else:
    106     versions = '.*'
    107 
    108 genOpts = CGeneratorOptions(
    109         apiname           = prefix,
    110         profile           = 'compatibility',
    111         versions          = versions,
    112         emitversions      = versions,
    113         defaultExtensions = prefix,                   # Default extensions for GL
    114         protectFile       = protect,
    115         protectFeature    = protect,
    116         protectProto      = protect,
    117         )
    118 
    119 # create error/warning & diagnostic files
    120 if (errFilename):
    121     errWarn = open(errFilename,'w')
    122 else:
    123     errWarn = sys.stderr
    124 diag = open(diagFilename, 'w')
    125 
    126 def ParseCmdRettype(cmd):
    127     proto=noneStr(cmd.elem.find('proto'))
    128     rettype=noneStr(proto.text)
    129     if rettype.lower()!="void ":
    130         plist = ([t for t in proto.itertext()])
    131         rettype = ''.join(plist[:-1])
    132     rettype=rettype.strip()
    133     return rettype
    134 
    135 def ParseCmdParams(cmd):
    136     params = cmd.elem.findall('param')
    137     plist=[]
    138     for param in params:
    139         # construct the formal parameter definition from ptype and name
    140         # elements, also using any text found around these in the
    141         # param element, in the order it appears in the document
    142         paramtype = ''
    143         # also extract the formal parameter name from the name element
    144         paramname = ''
    145         for t in param.iter():
    146             if t.tag == 'ptype' or t.tag == 'param':
    147                 paramtype = paramtype + noneStr(t.text)
    148             if t.tag == 'name':
    149                 paramname = t.text + '_'
    150                 paramtype = paramtype + ' ' + paramname
    151             if t.tail is not None:
    152                 paramtype = paramtype + t.tail.strip()
    153         plist.append((paramtype, paramname))
    154     return plist
    155 
    156 class PreResolveOutputGenerator(OutputGenerator):
    157     def __init__(self,
    158                  errFile = sys.stderr,
    159                  warnFile = sys.stderr,
    160                  diagFile = sys.stdout):
    161         OutputGenerator.__init__(self, errFile, warnFile, diagFile)
    162         self.wrappers={}
    163     def beginFile(self, genOpts):
    164         self.outFile.write('/* Automatically generated from %s - DO NOT EDIT */\n\n'%regFilename)
    165     def endFile(self):
    166         self.outFile.write('\nvoid ' + prefix + 'ResolveExtensionProcs(void)\n{\n')
    167         for funcname in self.wrappers.keys():
    168             self.outFile.write( '  PRERESOLVE(PFN' + funcname.upper() + 'PROC, "' + funcname + '");\n')
    169         self.outFile.write('}\n\n')
    170     def beginFeature(self, interface, emit):
    171         OutputGenerator.beginFeature(self, interface, emit)
    172     def endFeature(self):
    173         OutputGenerator.endFeature(self)
    174     def genType(self, typeinfo, name):
    175         OutputGenerator.genType(self, typeinfo, name)
    176     def genEnum(self, enuminfo, name):
    177         OutputGenerator.genEnum(self, enuminfo, name)
    178     def genCmd(self, cmd, name):
    179         OutputGenerator.genCmd(self, cmd, name)
    180 
    181         if prefix == 'wgl' and not name in used_wgl_ext_fns:
    182             return
    183 
    184         self.outFile.write('RESOLVE_DECL(PFN' + name.upper() + 'PROC);\n')
    185         self.wrappers[name]=1
    186 
    187 class WrapperOutputGenerator(OutputGenerator):
    188     def __init__(self,
    189                  errFile = sys.stderr,
    190                  warnFile = sys.stderr,
    191                  diagFile = sys.stdout):
    192         OutputGenerator.__init__(self, errFile, warnFile, diagFile)
    193     def beginFile(self, genOpts):
    194         self.outFile.write('/* Automatically generated from %s - DO NOT EDIT */\n\n'%regFilename)
    195     def endFile(self):
    196         pass
    197     def beginFeature(self, interface, emit):
    198         OutputGenerator.beginFeature(self, interface, emit)
    199         self.OldVersion = self.featureName.startswith('GL_VERSION_1_0') or self.featureName.startswith('GL_VERSION_1_1')
    200     def endFeature(self):
    201         OutputGenerator.endFeature(self)
    202     def genType(self, typeinfo, name):
    203         OutputGenerator.genType(self, typeinfo, name)
    204     def genEnum(self, enuminfo, name):
    205         OutputGenerator.genEnum(self, enuminfo, name)
    206     def genCmd(self, cmd, name):
    207         OutputGenerator.genCmd(self, cmd, name)
    208 
    209         if prefix == 'wgl' and not name in used_wgl_ext_fns:
    210             return
    211 
    212         rettype=ParseCmdRettype(cmd)
    213 
    214         if staticwrappers: self.outFile.write("static ")
    215         self.outFile.write("%s %sWrapper("%(rettype, name))
    216         plist=ParseCmdParams(cmd)
    217         Comma=""
    218         if len(plist):
    219             for ptype, pname in plist:
    220                 self.outFile.write("%s%s"%(Comma, ptype))
    221                 Comma=", "
    222         else:
    223             self.outFile.write("void")
    224 
    225         self.outFile.write(")\n{\n")
    226 
    227         # for GL 1.0 and 1.1 functions, generate stdcall wrappers which call the function directly
    228         if self.OldVersion:
    229             if not nodebug:
    230                 self.outFile.write('  if (glxWinDebugSettings.enable%scallTrace) ErrorF("%s\\n");\n'%(prefix.upper(), name))
    231                 self.outFile.write("  glWinDirectProcCalls++;\n")
    232                 self.outFile.write("\n")
    233 
    234             if rettype.lower()=="void":
    235                 self.outFile.write("  %s( "%(name))
    236             else:
    237                 self.outFile.write("  return %s( "%(name))
    238 
    239             Comma=""
    240             for ptype, pname in plist:
    241                 self.outFile.write("%s%s"%(Comma, pname))
    242                 Comma=", "
    243 
    244         # for GL 1.2+ functions, generate stdcall wrappers which use wglGetProcAddress()
    245         else:
    246             if rettype.lower()=="void":
    247                 self.outFile.write('  RESOLVE(PFN%sPROC, "%s");\n'%(name.upper(), name))
    248 
    249                 if not nodebug:
    250                     self.outFile.write("\n")
    251                     self.outFile.write('  if (glxWinDebugSettings.enable%scallTrace) ErrorF("%s\\n");\n'%(prefix.upper(), name))
    252                     self.outFile.write("\n")
    253 
    254                 self.outFile.write("  RESOLVED_PROC(PFN%sPROC)( """%(name.upper()))
    255             else:
    256                 self.outFile.write('  RESOLVE_RET(PFN%sPROC, "%s", FALSE);\n'%(name.upper(), name))
    257 
    258                 if not nodebug:
    259                     self.outFile.write("\n")
    260                     self.outFile.write('  if (glxWinDebugSettings.enable%scallTrace) ErrorF("%s\\n");\n'%(prefix.upper(), name))
    261                     self.outFile.write("\n")
    262 
    263                 self.outFile.write("  return RESOLVED_PROC(PFN%sPROC)("%(name.upper()))
    264 
    265             Comma=""
    266             for ptype, pname in plist:
    267                 self.outFile.write("%s%s"%(Comma, pname))
    268                 Comma=", "
    269         self.outFile.write(" );\n}\n\n")
    270 
    271 class ThunkOutputGenerator(OutputGenerator):
    272     def __init__(self,
    273                  errFile = sys.stderr,
    274                  warnFile = sys.stderr,
    275                  diagFile = sys.stdout):
    276         OutputGenerator.__init__(self, errFile, warnFile, diagFile)
    277     def beginFile(self, genOpts):
    278         self.outFile.write('/* Automatically generated from %s - DO NOT EDIT */\n\n'%regFilename)
    279     def endFile(self):
    280         pass
    281     def beginFeature(self, interface, emit):
    282         OutputGenerator.beginFeature(self, interface, emit)
    283         self.OldVersion = (self.featureName in ['GL_VERSION_1_0', 'GL_VERSION_1_1'])
    284     def endFeature(self):
    285         OutputGenerator.endFeature(self)
    286     def genType(self, typeinfo, name):
    287         OutputGenerator.genType(self, typeinfo, name)
    288     def genEnum(self, enuminfo, name):
    289         OutputGenerator.genEnum(self, enuminfo, name)
    290     def genCmd(self, cmd, name):
    291         OutputGenerator.genCmd(self, cmd, name)
    292 
    293         rettype=ParseCmdRettype(cmd)
    294         self.outFile.write("%s %sWrapper("%(rettype, name))
    295         plist=ParseCmdParams(cmd)
    296 
    297         Comma=""
    298         if len(plist):
    299             for ptype, pname in plist:
    300                 self.outFile.write("%s%s"%(Comma, ptype))
    301                 Comma=", "
    302         else:
    303             self.outFile.write("void")
    304 
    305         self.outFile.write(")\n{\n")
    306 
    307         # for GL 1.0 and 1.1 functions, generate stdcall thunk wrappers which call the function directly
    308         if self.OldVersion:
    309             if rettype.lower()=="void":
    310                 self.outFile.write("  %s( "%(name))
    311             else:
    312                 self.outFile.write("  return %s( "%(name))
    313 
    314             Comma=""
    315             for ptype, pname in plist:
    316                 self.outFile.write("%s%s"%(Comma, pname))
    317                 Comma=", "
    318 
    319         # for GL 1.2+ functions, generate wrappers which use wglGetProcAddress()
    320         else:
    321             if rettype.lower()=="void":
    322                 self.outFile.write('  RESOLVE(PFN%sPROC, "%s");\n'%(name.upper(), name))
    323                 self.outFile.write("  RESOLVED_PROC(PFN%sPROC)( """%(name.upper()))
    324             else:
    325                 self.outFile.write('  RESOLVE_RET(PFN%sPROC, "%s", FALSE);\n'%(name.upper(), name))
    326                 self.outFile.write("  return RESOLVED_PROC(PFN%sPROC)("%(name.upper()))
    327 
    328             Comma=""
    329             for ptype, pname in plist:
    330                 self.outFile.write("%s%s"%(Comma, pname))
    331                 Comma=", "
    332         self.outFile.write(" );\n}\n\n")
    333 
    334 class ThunkDefsOutputGenerator(OutputGenerator):
    335     def __init__(self,
    336                  errFile = sys.stderr,
    337                  warnFile = sys.stderr,
    338                  diagFile = sys.stdout):
    339         OutputGenerator.__init__(self, errFile, warnFile, diagFile)
    340     def beginFile(self, genOpts):
    341         self.outFile.write("EXPORTS\n"); # this must be the first line for libtool to realize this is a .def file
    342         self.outFile.write('; Automatically generated from %s - DO NOT EDIT\n\n'%regFilename)
    343     def endFile(self):
    344         pass
    345     def beginFeature(self, interface, emit):
    346         OutputGenerator.beginFeature(self, interface, emit)
    347     def endFeature(self):
    348         OutputGenerator.endFeature(self)
    349     def genType(self, typeinfo, name):
    350         OutputGenerator.genType(self, typeinfo, name)
    351     def genEnum(self, enuminfo, name):
    352         OutputGenerator.genEnum(self, enuminfo, name)
    353     def genCmd(self, cmd, name):
    354         OutputGenerator.genCmd(self, cmd, name)
    355 
    356         # export the wrapper function with the name of the function it wraps
    357         self.outFile.write("%s = %sWrapper\n"%(name, name))
    358 
    359 class ShimOutputGenerator(OutputGenerator):
    360     def __init__(self,
    361                  errFile = sys.stderr,
    362                  warnFile = sys.stderr,
    363                  diagFile = sys.stdout):
    364         OutputGenerator.__init__(self, errFile, warnFile, diagFile)
    365     def beginFile(self, genOpts):
    366         self.outFile.write('/* Automatically generated from %s - DO NOT EDIT */\n\n'%regFilename)
    367     def endFile(self):
    368         pass
    369     def beginFeature(self, interface, emit):
    370         OutputGenerator.beginFeature(self, interface, emit)
    371         self.OldVersion = (self.featureName in ['GL_VERSION_1_0', 'GL_VERSION_1_1', 'GL_VERSION_1_2', 'GL_ARB_imaging', 'GL_ARB_multitexture', 'GL_ARB_texture_compression'])
    372     def endFeature(self):
    373         OutputGenerator.endFeature(self)
    374     def genType(self, typeinfo, name):
    375         OutputGenerator.genType(self, typeinfo, name)
    376     def genEnum(self, enuminfo, name):
    377         OutputGenerator.genEnum(self, enuminfo, name)
    378     def genCmd(self, cmd, name):
    379         OutputGenerator.genCmd(self, cmd, name)
    380 
    381         if not self.OldVersion:
    382             return
    383 
    384         # for GL functions which are in the ABI, generate a shim which calls the function via GetProcAddress
    385         rettype=ParseCmdRettype(cmd)
    386         self.outFile.write("%s %s("%(rettype, name))
    387         plist=ParseCmdParams(cmd)
    388 
    389         Comma=""
    390         if len(plist):
    391             for ptype, pname in plist:
    392                 self.outFile.write("%s%s"%(Comma, ptype))
    393                 Comma=", "
    394         else:
    395             self.outFile.write("void")
    396 
    397         self.outFile.write(")\n{\n")
    398 
    399         self.outFile.write('  typedef %s (* PFN%sPROC)(' % (rettype, name.upper()))
    400 
    401         if len(plist):
    402             Comma=""
    403             for ptype, pname in plist:
    404                 self.outFile.write("%s %s"%(Comma, ptype))
    405                 Comma=", "
    406         else:
    407             self.outFile.write("void")
    408 
    409         self.outFile.write(');\n')
    410 
    411         if rettype.lower()=="void":
    412             self.outFile.write('  RESOLVE(PFN%sPROC, "%s");\n'%(name.upper(), name))
    413             self.outFile.write('  RESOLVED_PROC(')
    414         else:
    415             self.outFile.write('  RESOLVE_RET(PFN%sPROC, "%s", 0);\n'%(name.upper(), name))
    416             self.outFile.write('  return RESOLVED_PROC(')
    417 
    418         Comma=""
    419         for ptype, pname in plist:
    420             self.outFile.write("%s%s"%(Comma, pname))
    421             Comma=", "
    422 
    423         self.outFile.write(" );\n}\n\n")
    424 
    425 def genHeaders():
    426     outFile = open(outFilename,"w")
    427 
    428     if preresolve:
    429         gen = PreResolveOutputGenerator(errFile=errWarn,
    430                                         warnFile=errWarn,
    431                                         diagFile=diag)
    432         gen.outFile=outFile
    433         reg.setGenerator(gen)
    434         reg.apiGen(genOpts)
    435 
    436     if wrapper:
    437         gen = WrapperOutputGenerator(errFile=errWarn,
    438                                      warnFile=errWarn,
    439                                      diagFile=diag)
    440         gen.outFile=outFile
    441         reg.setGenerator(gen)
    442         reg.apiGen(genOpts)
    443 
    444     if shim:
    445         gen = ShimOutputGenerator(errFile=errWarn,
    446                                   warnFile=errWarn,
    447                                   diagFile=diag)
    448         gen.outFile=outFile
    449         reg.setGenerator(gen)
    450         reg.apiGen(genOpts)
    451 
    452     if thunk:
    453         gen = ThunkOutputGenerator(errFile=errWarn,
    454                                    warnFile=errWarn,
    455                                    diagFile=diag)
    456         gen.outFile=outFile
    457         reg.setGenerator(gen)
    458         reg.apiGen(genOpts)
    459 
    460 
    461     if thunkdefs:
    462         gen = ThunkDefsOutputGenerator(errFile=errWarn,
    463                                        warnFile=errWarn,
    464                                        diagFile=diag)
    465         gen.outFile=outFile
    466         reg.setGenerator(gen)
    467         reg.apiGen(genOpts)
    468 
    469     outFile.close()
    470 
    471 genHeaders()