#!/usr/bin/env python3
# (C) Copyright 2015, NVIDIA CORPORATION.
# All Rights Reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# on the rights to use, copy, modify, merge, publish, distribute, sub
# license, and/or sell copies of the Software, and to permit persons to whom
# the Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# Authors:
# Kyle Brenneman <kbrenneman@nvidia.com>
"""
Generates src/GL/g_libglglxwrapper.c from Khronos's glx.xml file.
This script generates stubs for every known extension function as well.
"""
import sys
import genCommon
_LIBGLX_FUNCTIONS = frozenset((
"glXChooseVisual",
"glXCopyContext",
"glXCreateContext",
"glXCreateGLXPixmap",
"glXDestroyContext",
"glXDestroyGLXPixmap",
"glXGetConfig",
"glXIsDirect",
"glXMakeCurrent",
"glXSwapBuffers",
"glXUseXFont",
"glXWaitGL",
"glXWaitX",
"glXQueryServerString",
"glXGetClientString",
"glXQueryExtensionsString",
"glXChooseFBConfig",
"glXCreateNewContext",
"glXCreatePbuffer",
"glXCreatePixmap",
"glXCreateWindow",
"glXDestroyPbuffer",
"glXDestroyPixmap",
"glXDestroyWindow",
"glXGetFBConfigAttrib",
"glXGetFBConfigs",
"glXGetSelectedEvent",
"glXGetVisualFromFBConfig",
"glXMakeContextCurrent",
"glXQueryContext",
"glXQueryDrawable",
"glXSelectEvent",
"glXGetCurrentContext",
"glXGetCurrentDrawable",
"glXGetCurrentReadDrawable",
"glXGetProcAddress",
"glXGetProcAddressARB",
"glXQueryExtension",
"glXQueryVersion",
))
# These are functions to skip when we generate the entrypoint stubs. They
# require some additional typedefs that probably won't be available.
_SKIP_GLX_FUNCTIONS = frozenset((
"glXAssociateDMPbufferSGIX",
"glXCreateGLXVideoSourceSGIX",
"glXDestroyGLXVideoSourceSGIX",
))
def generateGLXExtensionStubFunction(func):
text = ""
text += "typedef {f.rt} (*fn_{f.name}_ptr)({f.decArgs});\n"
text += "static fn_{f.name}_ptr __real_{f.name};\n"
text += "static glvnd_mutex_t __mutex_{f.name} = GLVND_MUTEX_INITIALIZER;\n"
text += "PUBLIC {f.rt} {f.name}({f.decArgs})\n"
text += "{{\n"
text += " fn_{f.name}_ptr _real = "
text += "(fn_{f.name}_ptr) LOAD_GLX_FUNC({f.name});\n"
text += " if(_real != NULL) {{\n"
if (func.hasReturn()):
text += " return _real({f.callArgs});\n"
text += " }} else {{\n"
text += " return {retVal};\n"
else:
text += " _real({f.callArgs});\n"
text += " }}\n"
text += "}}\n\n"
return text.format(f=func, retVal=getDefaultReturnValue(func))
def generateGLXCoreStubFunction(func):
text = "PUBLIC {f.rt} {f.name}({f.decArgs})\n"
text += "{{\n"
text += " "
if (func.hasReturn()):
text += "return "
text += "__GLXGL_CORE_FUNCTIONS.ptr_{f.name}({f.callArgs});\n"
text += "}}\n\n"
return text.format(f=func)
def generateLibGLXStubs(functions):
text = r"""
/*
* THIS FILE IS AUTOMATICALLY GENERATED BY gen_noop.pl
* DO NOT EDIT!!
*/
#include <X11/Xlib.h>
#include <GL/glx.h>
#include "compiler.h"
#include "libglxgl.h"
#include "glvnd_pthread.h"
""".lstrip("\n")
text += "#define LOAD_GLX_FUNC(name) __glXGLLoadGLXFunction(#name, (__GLXextFuncPtr *) &__real_##name, &__mutex_##name)\n\n"
for func in functions:
if (func.name in _LIBGLX_FUNCTIONS):
text += generateGLXCoreStubFunction(func)
else:
text += generateGLXExtensionStubFunction(func)
return text
def getDefaultReturnValue(func):
POINTER_TYPE_NAMES = frozenset((
"__GLXextFuncPtr",
"GLXFBConfig", "GLXFBConfigSGIX",
"GLXContext",
))
XID_TYPE_NAMES = frozenset((
"GLXContextID",
"GLXWindow",
"GLXPbuffer",
"GLXPixmap",
"GLXDrawable",
"GLXFBConfigID",
"GLXContextID",
"GLXWindow",
"GLXPbuffer",
"GLXPbufferSGIX",
"GLXVideoSourceSGIX",
))
if (not func.hasReturn()):
return ""
if (func.rt.endswith("*")):
return "NULL"
if (func.rt in POINTER_TYPE_NAMES):
return "NULL"
if (func.rt in XID_TYPE_NAMES):
return "None"
if (func.rt == "Bool"):
return "False"
if (func.rt.startswith("GLX")):
raise ValueError("Unknown GLX typedef: %r" % (func.rt,))
return "0"
def _main():
functions = genCommon.getFunctions(sys.argv[1:])
functions = [f for f in functions if(f.name not in _SKIP_GLX_FUNCTIONS)]
sys.stdout.write(generateLibGLXStubs(functions))
if (__name__ == "__main__"):
_main()