Major move to visitor paradigm.
authorJosé Fonseca <jfonseca@vmware.com>
Tue, 23 Nov 2010 20:55:07 +0000 (20:55 +0000)
committerJosé Fonseca <jfonseca@vmware.com>
Tue, 23 Nov 2010 20:55:07 +0000 (20:55 +0000)
13 files changed:
CMakeLists.txt
base.py
glapi.py [moved from gl.py with 99% similarity]
glretrace.py
glxtrace.py [moved from glx.py with 52% similarity]
log.cpp
log.hpp
opengl32.py
os.hpp
os_posix.cpp
os_win32.cpp
trace.py [new file with mode: 0644]
wglapi.py [new file with mode: 0644]

index 262eda9..6f2ccfd 100644 (file)
@@ -139,7 +139,7 @@ if (WIN32)
        add_custom_command (
                OUTPUT opengl32.cpp
                COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/opengl32.py > ${CMAKE_CURRENT_BINARY_DIR}/opengl32.cpp
-               DEPENDS opengl32.py gl.py windows.py base.py
+               DEPENDS opengl32.py trace.py wglapi.py glapi.py windows.py base.py
        )
        add_library (opengl SHARED opengl32.def opengl32.cpp log.cpp os_win32.cpp)
        set_target_properties (opengl PROPERTIES
@@ -153,11 +153,12 @@ else ()
 
        # libGL.so
        add_custom_command (
-               OUTPUT glx.cpp
-               COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/glx.py > ${CMAKE_CURRENT_BINARY_DIR}/glx.cpp
-               DEPENDS glx.py gl.py dl.py base.py
+               OUTPUT glxtrace.cpp
+               COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/glxtrace.py > ${CMAKE_CURRENT_BINARY_DIR}/glxtrace.cpp
+               DEPENDS glxtrace.py trace.py glapi.py dl.py base.py
        )
-       add_library (glxtrace SHARED glx.cpp log.cpp os_posix.cpp)
+
+       add_library (glxtrace SHARED glxtrace.cpp log.cpp os_posix.cpp)
        set_target_properties (glxtrace PROPERTIES PREFIX "")
        target_link_libraries (glxtrace dl)
 endif ()
@@ -169,7 +170,7 @@ if (GLEW_INCLUDE_DIR)
        add_custom_command (
                OUTPUT glretrace.cpp
                COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/glretrace.py > ${CMAKE_CURRENT_BINARY_DIR}/glretrace.cpp
-               DEPENDS glretrace.py glx.py gl.py dl.py base.py
+               DEPENDS glretrace.py glapi.py dl.py base.py
        )
 
        include_directories (
diff --git a/base.py b/base.py
index e427bd4..77409bb 100644 (file)
--- a/base.py
+++ b/base.py
@@ -161,20 +161,6 @@ class Type:
     def visit(self, visitor, *args, **kwargs):
         raise NotImplementedError
 
-    def decl(self):
-        pass
-
-    def impl(self):
-        pass
-
-    def dump(self, instance):
-        raise NotImplementedError
-    
-    def wrap_instance(self, instance):
-        pass 
-
-    def unwrap_instance(self, instance):
-        pass
 
 
 class _Void(Type):
@@ -215,9 +201,6 @@ class Literal(Type):
     def visit(self, visitor, *args, **kwargs):
         return visitor.visit_literal(self, *args, **kwargs)
 
-    def dump(self, instance):
-        print '    Log::Literal%s(%s);' % (self.format, instance)
-
 
 class Const(Type):
 
@@ -235,9 +218,6 @@ class Const(Type):
     def visit(self, visitor, *args, **kwargs):
         return visitor.visit_const(self, *args, **kwargs)
 
-    def dump(self, instance):
-        self.type.dump(instance)
-
 
 class Pointer(Type):
 
@@ -248,21 +228,6 @@ class Pointer(Type):
     def visit(self, visitor, *args, **kwargs):
         return visitor.visit_pointer(self, *args, **kwargs)
 
-    def dump(self, instance):
-        print '    if(%s) {' % instance
-        print '        Log::BeginPointer((const void *)%s);' % (instance,)
-        self.type.dump("*" + instance)
-        print '        Log::EndPointer();'
-        print '    }'
-        print '    else'
-        print '        Log::LiteralNull();'
-
-    def wrap_instance(self, instance):
-        self.type.wrap_instance("*" + instance)
-
-    def unwrap_instance(self, instance):
-        self.type.wrap_instance("*" + instance)
-
 
 def ConstPointer(type):
     return Pointer(Const(type))
@@ -277,17 +242,6 @@ class Enum(Concrete):
     def visit(self, visitor, *args, **kwargs):
         return visitor.visit_enum(self, *args, **kwargs)
 
-    def _dump(self, instance):
-        print '    switch(%s) {' % instance
-        for value in self.values:
-            print '    case %s:' % value
-            print '        Log::LiteralNamedConstant("%s", %s);' % (value, value)
-            print '        break;'
-        print '    default:'
-        print '        Log::LiteralSInt(%s);' % instance
-        print '        break;'
-        print '    }'
-
 
 def FakeEnum(type, values):
     return Enum(type.expr, values)
@@ -303,19 +257,6 @@ class Bitmask(Concrete):
     def visit(self, visitor, *args, **kwargs):
         return visitor.visit_bitmask(self, *args, **kwargs)
 
-    def _dump(self, instance):
-        print '    %s l_Value = %s;' % (self.type, instance)
-        print '    Log::BeginBitmask();'
-        for value in self.values:
-            print '    if((l_Value & %s) == %s) {' % (value, value)
-            print '        Log::LiteralNamedConstant("%s", %s);' % (value, value)
-            print '        l_Value &= ~%s;' % value
-            print '    }'
-        print '    if(l_Value) {'
-        self.type.dump("l_Value");
-        print '    }'
-        print '    Log::EndBitmask();'
-
 Flags = Bitmask
 
 
@@ -329,26 +270,6 @@ class Array(Type):
     def visit(self, visitor, *args, **kwargs):
         return visitor.visit_array(self, *args, **kwargs)
 
-    def dump(self, instance):
-        print '    if(%s) {' % instance
-        index = '__i' + self.type.id
-        print '        Log::BeginArray(%s);' % (self.length,)
-        print '        for (int %s = 0; %s < %s; ++%s) {' % (index, index, self.length, index)
-        print '            Log::BeginElement();'
-        self.type.dump('(%s)[%s]' % (instance, index))
-        print '            Log::EndElement();'
-        print '        }'
-        print '        Log::EndArray();'
-        print '    }'
-        print '    else'
-        print '        Log::LiteralNull();'
-
-    def wrap_instance(self, instance):
-        self.type.wrap_instance("*" + instance)
-
-    def unwrap_instance(self, instance):
-        self.type.wrap_instance("*" + instance)
-
 
 class Blob(Type):
 
@@ -360,9 +281,6 @@ class Blob(Type):
     def visit(self, visitor, *args, **kwargs):
         return visitor.visit_blob(self, *args, **kwargs)
 
-    def dump(self, instance):
-        print '    Log::LiteralBlob(%s, %s);' % (instance, self.size)
-
 
 class Struct(Concrete):
 
@@ -374,14 +292,6 @@ class Struct(Concrete):
     def visit(self, visitor, *args, **kwargs):
         return visitor.visit_struct(self, *args, **kwargs)
 
-    def _dump(self, instance):
-        print '    Log::BeginStruct("%s");' % self.name
-        for type, name in self.members:
-            print '    Log::BeginMember("%s");' % (name,)
-            type.dump('(%s).%s' % (instance, name))
-            print '    Log::EndMember();'
-        print '    Log::EndStruct();'
-
 
 class Alias(Type):
 
@@ -392,9 +302,6 @@ class Alias(Type):
     def visit(self, visitor, *args, **kwargs):
         return visitor.visit_alias(self, *args, **kwargs)
 
-    def dump(self, instance):
-        self.type.dump(instance)
-
 
 def Out(type, name):
     arg = Arg(type, name, output=True)
@@ -414,7 +321,7 @@ class Arg:
 
 class Function:
 
-    def __init__(self, type, name, args, call = '__stdcall', fail = None, sideeffects=True):
+    def __init__(self, type, name, args, call = '', fail = None, sideeffects=True, hidden=False):
         self.type = type
         self.name = name
 
@@ -428,6 +335,7 @@ class Function:
         self.call = call
         self.fail = fail
         self.sideeffects = sideeffects
+        self.hidden = False
 
     def prototype(self, name=None):
         if name is not None:
@@ -448,73 +356,10 @@ class Function:
         s += ")"
         return s
 
-    def pointer_type(self):
-        return 'P' + self.name
 
-    def pointer_value(self):
-        return 'p' + self.name
-
-    def wrap_decl(self):
-        ptype = self.pointer_type()
-        pvalue = self.pointer_value()
-        print 'typedef ' + self.prototype('* %s' % ptype) + ';'
-        print 'static %s %s = NULL;' % (ptype, pvalue)
-        print
-
-    def get_true_pointer(self):
-        raise NotImplementedError
-
-    def exit_impl(self):
-        print '            Log::Abort();'
-
-    def fail_impl(self):
-        if self.fail is not None:
-            if self.type is Void:
-                assert self.fail == ''
-                print '            return;' 
-            else:
-                assert self.fail != ''
-                print '            return %s;' % self.fail
-        else:
-            self.exit_impl()
-
-    def wrap_impl(self):
-        pvalue = self.pointer_value()
-        print self.prototype() + ' {'
-        if self.type is Void:
-            result = ''
-        else:
-            print '    %s result;' % self.type
-            result = 'result = '
-        self.get_true_pointer()
-        print '    Log::BeginCall("%s");' % (self.name)
-        for arg in self.args:
-            if not arg.output:
-                arg.type.unwrap_instance(arg.name)
-                print '    Log::BeginArg("%s");' % (arg.name,)
-                arg.type.dump(arg.name)
-                print '    Log::EndArg();'
-        print '    %s%s(%s);' % (result, pvalue, ', '.join([str(arg.name) for arg in self.args]))
-        for arg in self.args:
-            if arg.output:
-                print '    Log::BeginArg("%s");' % (arg.name,)
-                arg.type.dump(arg.name)
-                print '    Log::EndArg();'
-                arg.type.wrap_instance(arg.name)
-        if self.type is not Void:
-            print '    Log::BeginReturn();'
-            self.type.dump("result")
-            print '    Log::EndReturn();'
-            self.type.wrap_instance('result')
-        print '    Log::EndCall();'
-        self.post_call_impl()
-        if self.type is not Void:
-            print '    return result;'
-        print '}'
-        print
-
-    def post_call_impl(self):
-        pass
+def StdFunction(*args, **kwargs):
+    kwargs.setdefault('call', 'GLAPIENTRY')
+    return Function(*args, **kwargs)
 
 
 def FunctionPointer(type, name, args, **kwargs):
@@ -530,9 +375,6 @@ class Interface(Type):
         self.base = base
         self.methods = []
 
-    def dump(self, instance):
-        print '    Log::LiteralOpaque((const void *)%s);' % instance
-
     def itermethods(self):
         if self.base is not None:
             for method in self.base.itermethods():
@@ -541,78 +383,6 @@ class Interface(Type):
             yield method
         raise StopIteration
 
-    def wrap_name(self):
-        return "Wrap" + self.expr
-
-    def wrap_pre_decl(self):
-        print "class %s;" % self.wrap_name()
-
-    def wrap_decl(self):
-        print "class %s : public %s " % (self.wrap_name(), self.name)
-        print "{"
-        print "public:"
-        print "    %s(%s * pInstance);" % (self.wrap_name(), self.name)
-        print "    virtual ~%s();" % self.wrap_name()
-        print
-        for method in self.itermethods():
-            print "    " + method.prototype() + ";"
-        print
-        #print "private:"
-        print "    %s * m_pInstance;" % (self.name,)
-        print "};"
-        print
-
-    def wrap_impl(self):
-        print '%s::%s(%s * pInstance) {' % (self.wrap_name(), self.wrap_name(), self.name)
-        print '    m_pInstance = pInstance;'
-        print '}'
-        print
-        print '%s::~%s() {' % (self.wrap_name(), self.wrap_name())
-        print '}'
-        print
-        for method in self.itermethods():
-            print method.prototype(self.wrap_name() + '::' + method.name) + ' {'
-            if method.type is Void:
-                result = ''
-            else:
-                print '    %s result;' % method.type
-                result = 'result = '
-            print '    Log::BeginCall("%s");' % (self.name + '::' + method.name)
-            print '    Log::BeginArg("this");'
-            print '    Log::LiteralOpaque((const void *)m_pInstance);'
-            print '    Log::EndArg();'
-            for arg in method.args:
-                if not arg.output:
-                    arg.type.unwrap_instance(arg.name)
-                    print '    Log::BeginArg("%s");' % (arg.name,)
-                    arg.type.dump(arg.name)
-                    print '    Log::EndArg();'
-            print '    %sm_pInstance->%s(%s);' % (result, method.name, ', '.join([str(arg.name) for arg in method.args]))
-            for arg in method.args:
-                if arg.output:
-                    print '    Log::BeginArg("%s");' % (arg.name,)
-                    arg.type.dump(arg.name)
-                    print '    Log::EndArg();'
-                    arg.type.wrap_instance(arg.name)
-            if method.type is not Void:
-                print '    Log::BeginReturn("%s");' % method.type
-                method.type.dump("result")
-                print '    Log::EndReturn();'
-                method.type.wrap_instance('result')
-            print '    Log::EndCall();'
-            if method.name == 'QueryInterface':
-                print '    if(*ppvObj == m_pInstance)'
-                print '        *ppvObj = this;'
-            if method.name == 'Release':
-                assert method.type is not Void
-                print '    if(!result)'
-                print '        delete this;'
-            if method.type is not Void:
-                print '    return result;'
-            print '}'
-            print
-        print
-
 
 class Method(Function):
 
@@ -622,20 +392,9 @@ class Method(Function):
 
 towrap = []
 
-class WrapPointer(Pointer):
 
-    def __init__(self, type):
-        Pointer.__init__(self, type)
-        if type not in towrap:
-            towrap.append(type)
-
-    def wrap_instance(self, instance):
-        print "    if(%s)" % instance
-        print "        %s = new %s(%s);" % (instance, self.type.wrap_name(), instance)
-
-    def unwrap_instance(self, instance):
-        print "    if(%s)" % instance
-        print "        %s = static_cast<%s *>(%s)->m_pInstance;" % (instance, self.type.wrap_name(), instance)
+def WrapPointer(type):
+    return Pointer(type)
 
 
 class _String(Type):
@@ -646,9 +405,6 @@ class _String(Type):
     def visit(self, visitor, *args, **kwargs):
         return visitor.visit_string(self, *args, **kwargs)
 
-    def dump(self, instance):
-        print '    Log::LiteralString((const char *)%s);' % instance
-
 String = _String()
 
 
@@ -661,14 +417,42 @@ class Opaque(Type):
     def visit(self, visitor, *args, **kwargs):
         return visitor.visit_opaque(self, *args, **kwargs)
 
-    def dump(self, instance):
-        print '    Log::LiteralOpaque((const void *)%s);' % instance
-
 
 def OpaquePointer(type):
     return Opaque(type.expr + ' *')
 
 
+
+class API:
+
+    def __init__(self, name):
+        self.name = name
+        self.headers = []
+        self.types = set()
+        self.functions = []
+        self.interfaces = []
+
+    def add_type(self, type):
+        if type not in self.types:
+            self.types.add(type)
+
+    def add_function(self, function):
+        self.functions.append(function)
+        for arg in function.args:
+            self.add_type(arg.type)
+        self.add_type(function.type)
+
+    def add_functions(self, functions):
+        for function in functions:
+            self.add_function(function)
+
+    def add_interface(self, interface):
+        self.interfaces.append(interface)
+
+    def add_interfaces(self, interfaces):
+        self.interfaces.extend(interfaces)
+
+
 Bool = Literal("bool", "Bool")
 SChar = Literal("signed char", "SInt")
 UChar = Literal("unsigned char", "UInt")
@@ -685,20 +469,3 @@ Double = Literal("double", "Float")
 SizeT = Literal("size_t", "UInt")
 WString = Literal("wchar_t *", "WString")
 
-
-def wrap():
-    for type in all_types.itervalues():
-        type.decl()
-    print
-    for type in all_types.itervalues():
-        type.impl()
-    print
-    for type in towrap:
-        type.wrap_pre_decl()
-    print
-    for type in towrap:
-        type.wrap_decl()
-    print
-    for type in towrap:
-        type.wrap_impl()
-    print
diff --git a/gl.py b/glapi.py
similarity index 99%
rename from gl.py
rename to glapi.py
index c3f906c..837cca6 100644 (file)
--- a/gl.py
+++ b/glapi.py
 #
 ##########################################################################/
 
+
 from base import *
 
+
 GLboolean = Alias("GLboolean", Bool)
 GLvoid = Alias("GLvoid", Void)
 GLbyte = Alias("GLbyte", SChar)
@@ -2517,6 +2519,10 @@ GLbitfield_client_attrib = Flags(GLbitfield, [
 ])
 
 
+def GlFunction(*args, **kwargs):
+    kwargs.setdefault('call', 'GLAPIENTRY')
+    return Function(*args, **kwargs)
+
 def basic_functions(Function):
     def F(*args, **kwargs):
         kwargs.setdefault('call', 'GLAPIENTRY')
@@ -2933,6 +2939,9 @@ def basic_functions(Function):
     ]
 
 
+glapi = API('GL')
+
+
 def extended_functions(Function):
     def F(*args, **kwargs):
         kwargs.setdefault('call', 'GLAPIENTRY')
@@ -3306,3 +3315,7 @@ def extended_functions(Function):
         F(Void, "glGetQueryObjecti64vEXT", [(GLuint, "id"), (GLenum, "pname"), (OpaquePointer(GLint64EXT), "params")], sideeffects=False),
         F(Void, "glGetQueryObjectui64vEXT", [(GLuint, "id"), (GLenum, "pname"), (OpaquePointer(GLuint64EXT), "params")], sideeffects=False),
     ]
+
+glapi.add_functions(basic_functions(Function))
+glapi.add_functions(extended_functions(Function))
+
index e4473ba..01ba994 100644 (file)
@@ -25,7 +25,7 @@
 
 
 import base
-import gl
+import glapi
 
 
 
@@ -137,8 +137,7 @@ if __name__ == '__main__':
     print '#include "trace_parser.hpp"'
     print
 
-    functions = gl.basic_functions(base.Function) + gl.extended_functions(base.Function)
-    retrace_functions(functions)
+    retrace_functions(glapi.glapi.functions)
 
     print '''
 
similarity index 52%
rename from glx.py
rename to glxtrace.py
index d8884b1..0e7dc57 100644 (file)
--- a/glx.py
 #
 ##########################################################################/
 
-from gl import *
-from dl import *
 
-libgl = Dll("GL")
-libgl.functions = basic_functions(DllFunction)
+from base import *
+from glapi import glapi
+import trace
 
 
-class GlxGetProcAddressFunction(DllFunction):
-
-    def __init__(self, type, name, args):
-        DllFunction.__init__(self, type, name, args)
-        self.functions = []
-
-    def wrap_decl(self):
-        for function in self.functions:
-            function.wrap_decl()
-        DllFunction.wrap_decl(self)
-
-    def wrap_impl(self):
-        for function in self.functions:
-            function.wrap_impl()
-        DllFunction.wrap_impl(self)
-
-    def post_call_impl(self):
-        print '    if(result) {'
-        for function in self.functions:
-            ptype = function.pointer_type()
-            pvalue = function.pointer_value()
-            print '        if(!strcmp("%s", (const char *)procName)) {' % function.name
-            print '            %s = (%s)result;' % (pvalue, ptype)
-            print '            result = (void(*)())&%s;' % function.name;
-            print '        }'
-        print '    }'
-
+glxapi = API("GLX")
 
 PROC = Opaque("__GLXextFuncPtr")
 
-glXgetprocaddress = GlxGetProcAddressFunction(PROC, "glXGetProcAddress", [(Alias("const GLubyte *", String), "procName")])
-libgl.functions.append(glXgetprocaddress)
-
-class GlxFunction(Function):
-
-    def __init__(self, type, name, args, call = '', **kwargs):
-        Function.__init__(self, type, name, args, call=call, **kwargs)
-        
-    def get_true_pointer(self):
-        ptype = self.pointer_type()
-        pvalue = self.pointer_value()
-        print '    if(!%s)' % (pvalue,)
-        self.fail_impl()
-
-glXgetprocaddress.functions += extended_functions(GlxFunction)
+glxapi.add_functions(glapi.functions)
+glxapi.add_functions([
+    Function(PROC, "glXGetProcAddress", [(Alias("const GLubyte *", String), "procName")])
+])
+
+
+class GlxTracer(trace.Tracer):
+
+    def get_function_address(self, function):
+        if function.name == "glXGetProcAddress":
+            return 'dlsym(RTLD_NEXT, "%s")' % (function.name,)
+        else:
+            print '    if (!pglXGetProcAddress) {'
+            print '        pglXGetProcAddress = (PglXGetProcAddress)dlsym(RTLD_NEXT, "glXGetProcAddress");'
+            print '        if (!pglXGetProcAddress)'
+            print '            Log::Abort();'
+            print '    }'
+            return 'pglXGetProcAddress((const GLubyte *)"%s")' % (function.name,)
+
+    def wrap_ret(self, function, instance):
+        if function.name == "glXGetProcAddress":
+            print '    if (%s) {' % instance
+            for f in glxapi.functions:
+                ptype = self.function_pointer_type(f)
+                pvalue = self.function_pointer_value(f)
+                print '        if(!strcmp("%s", (const char *)procName)) {' % f.name
+                print '            %s = (%s)&%s;' % (instance, function.type, f.name);
+                print '        }'
+            print '    }'
 
 
 if __name__ == '__main__':
@@ -93,6 +80,7 @@ if __name__ == '__main__':
     print
     print 'extern "C" {'
     print
-    wrap()
+    tracer = GlxTracer()
+    tracer.trace_api(glxapi)
     print
-    print '}'
+    print '} /* extern "C" */'
diff --git a/log.cpp b/log.cpp
index f0f194b..e634b65 100644 (file)
--- a/log.cpp
+++ b/log.cpp
@@ -50,39 +50,53 @@ static void _Close(void) {
 
 static int reentrancy = 0;
 
-static void _Open(const char *szName, const char *szExtension) {
+static void _Open(const char *szExtension) {
    _Close();
    
    static unsigned dwCounter = 0;
 
-   char szProcessName[PATH_MAX];
    char szFileName[PATH_MAX];
+   const char *lpFileName;
 
-   OS::GetProcessName(szProcessName, PATH_MAX);
-
-   for(;;) {
-      FILE *file;
-      
-      if(dwCounter)
-         snprintf(szFileName, PATH_MAX, "%s.%s.%u.%s", szProcessName, szName, dwCounter, szExtension);
-      else
-         snprintf(szFileName, PATH_MAX, "%s.%s.%s", szProcessName, szName, szExtension);
-      
-      file = fopen(szFileName, "rb");
-      if(file == NULL)
-         break;
-      
-      fclose(file);
-      
-      ++dwCounter;
+   lpFileName = getenv("TRACE_PATH");
+   if (lpFileName) {
+       strncpy(szFileName, lpFileName, PATH_MAX);
+   }
+   else {
+       char szProcessName[PATH_MAX];
+       char szCurrentDir[PATH_MAX];
+       OS::GetProcessName(szProcessName, PATH_MAX);
+       OS::GetCurrentDir(szCurrentDir, PATH_MAX);
+
+       for(;;) {
+          FILE *file;
+          
+          if (dwCounter)
+             snprintf(szFileName, PATH_MAX, "%s%c%s.%u.%s", szCurrentDir, PATH_SEP, szProcessName, dwCounter, szExtension);
+          else
+             snprintf(szFileName, PATH_MAX, "%s%c%s.%s", szCurrentDir, PATH_SEP, szProcessName, szExtension);
+          
+          file = fopen(szFileName, "rb");
+          if(file == NULL)
+             break;
+          
+          fclose(file);
+          
+          ++dwCounter;
+       }
+   }
+
+   {
+       char szMessage[PATH_MAX];
+       snprintf(szMessage, PATH_MAX, "Tracing to %s\n", szFileName);
+       OS::DebugMessage(szMessage);
    }
 
-   fprintf(stderr, "Logging to %s\n", szFileName);
    g_gzFile = gzopen(szFileName, "wb");
 }
 
 static inline void Write(const void *sBuffer, size_t dwBytesToWrite) {
-   if(g_gzFile == NULL)
+   if (g_gzFile == NULL)
       return;
    
    if (reentrancy > 1)
@@ -134,9 +148,11 @@ WriteString(const char *str) {
    Write(str, len);
 }
 
-void Open(const char *name) {
-   _Open(name, "trace");
-   WriteUInt(TRACE_VERSION);
+void Open(void) {
+    if (!g_gzFile) {
+        _Open("trace");
+        WriteUInt(TRACE_VERSION);
+    }
 }
 
 void Close(void) {
@@ -145,6 +161,7 @@ void Close(void) {
 
 void BeginCall(const char *function) {
    OS::AcquireMutex();
+   Open();
    ++reentrancy;
    WriteString(function);
 }
@@ -293,4 +310,9 @@ void Abort(void) {
     OS::Abort();
 }
 
+static void _uninit(void) __attribute__((destructor));
+static void _uninit(void) {
+   Close();
+}
+
 } /* namespace Log */
diff --git a/log.hpp b/log.hpp
index ffa1c2c..7d03e64 100644 (file)
--- a/log.hpp
+++ b/log.hpp
@@ -28,7 +28,7 @@
 
 namespace Log {
 
-    void Open(const char *name);
+    void Open(void);
     void Close(void);
     
     void BeginCall(const char *function);
index f3e2f0e..ca7942f 100644 (file)
 #
 ##########################################################################/
 
-from gl import *
-from windows import *
 
-opengl32 = Dll("opengl32")
-opengl32.functions += basic_functions(DllFunction)
+from wglapi import wglapi
+from trace import Tracer
 
-HGLRC = Alias("HGLRC", HANDLE)
-PROC = Opaque("PROC")
 
-PFD = Flags(DWORD, [
-    "PFD_DOUBLEBUFFER",
-    "PFD_STEREO",
-    "PFD_DRAW_TO_WINDOW",
-    "PFD_DRAW_TO_BITMAP",
-    "PFD_SUPPORT_GDI",
-    "PFD_SUPPORT_OPENGL",
-    "PFD_GENERIC_FORMAT",
-    "PFD_NEED_PALETTE",
-    "PFD_NEED_SYSTEM_PALETTE",
-    "PFD_SWAP_EXCHANGE",
-    "PFD_SWAP_COPY",
-    "PFD_SWAP_LAYER_BUFFERS",
-    "PFD_GENERIC_ACCELERATED",
-    "PFD_SUPPORT_DIRECTDRAW",
-    "PFD_DEPTH_DONTCARE",
-    "PFD_DOUBLEBUFFER_DONTCARE",
-    "PFD_STEREO_DONTCARE",
+public_symbols = set([
+       "glAccum",
+       "glAlphaFunc",
+       "glAreTexturesResident",
+       "glArrayElement",
+       "glBegin",
+       "glBindTexture",
+       "glBitmap",
+       "glBlendFunc",
+       "glCallList",
+       "glCallLists",
+       "glClear",
+       "glClearAccum",
+       "glClearColor",
+       "glClearDepth",
+       "glClearIndex",
+       "glClearStencil",
+       "glClipPlane",
+       "glColor3b",
+       "glColor3bv",
+       "glColor3d",
+       "glColor3dv",
+       "glColor3f",
+       "glColor3fv",
+       "glColor3i",
+       "glColor3iv",
+       "glColor3s",
+       "glColor3sv",
+       "glColor3ub",
+       "glColor3ubv",
+       "glColor3ui",
+       "glColor3uiv",
+       "glColor3us",
+       "glColor3usv",
+       "glColor4b",
+       "glColor4bv",
+       "glColor4d",
+       "glColor4dv",
+       "glColor4f",
+       "glColor4fv",
+       "glColor4i",
+       "glColor4iv",
+       "glColor4s",
+       "glColor4sv",
+       "glColor4ub",
+       "glColor4ubv",
+       "glColor4ui",
+       "glColor4uiv",
+       "glColor4us",
+       "glColor4usv",
+       "glColorMask",
+       "glColorMaterial",
+       "glColorPointer",
+       "glCopyPixels",
+       "glCopyTexImage1D",
+       "glCopyTexImage2D",
+       "glCopyTexSubImage1D",
+       "glCopyTexSubImage2D",
+       "glCullFace",
+#      "glDebugEntry",
+       "glDeleteLists",
+       "glDeleteTextures",
+       "glDepthFunc",
+       "glDepthMask",
+       "glDepthRange",
+       "glDisable",
+       "glDisableClientState",
+       "glDrawArrays",
+       "glDrawBuffer",
+       "glDrawElements",
+       "glDrawPixels",
+       "glEdgeFlag",
+       "glEdgeFlagPointer",
+       "glEdgeFlagv",
+       "glEnable",
+       "glEnableClientState",
+       "glEnd",
+       "glEndList",
+       "glEvalCoord1d",
+       "glEvalCoord1dv",
+       "glEvalCoord1f",
+       "glEvalCoord1fv",
+       "glEvalCoord2d",
+       "glEvalCoord2dv",
+       "glEvalCoord2f",
+       "glEvalCoord2fv",
+       "glEvalMesh1",
+       "glEvalMesh2",
+       "glEvalPoint1",
+       "glEvalPoint2",
+       "glFeedbackBuffer",
+       "glFinish",
+       "glFlush",
+       "glFogf",
+       "glFogfv",
+       "glFogi",
+       "glFogiv",
+       "glFrontFace",
+       "glFrustum",
+       "glGenLists",
+       "glGenTextures",
+       "glGetBooleanv",
+       "glGetClipPlane",
+       "glGetDoublev",
+       "glGetError",
+       "glGetFloatv",
+       "glGetIntegerv",
+       "glGetLightfv",
+       "glGetLightiv",
+       "glGetMapdv",
+       "glGetMapfv",
+       "glGetMapiv",
+       "glGetMaterialfv",
+       "glGetMaterialiv",
+       "glGetPixelMapfv",
+       "glGetPixelMapuiv",
+       "glGetPixelMapusv",
+       "glGetPointerv",
+       "glGetPolygonStipple",
+       "glGetString",
+       "glGetTexEnvfv",
+       "glGetTexEnviv",
+       "glGetTexGendv",
+       "glGetTexGenfv",
+       "glGetTexGeniv",
+       "glGetTexImage",
+       "glGetTexLevelParameterfv",
+       "glGetTexLevelParameteriv",
+       "glGetTexParameterfv",
+       "glGetTexParameteriv",
+       "glHint",
+       "glIndexMask",
+       "glIndexPointer",
+       "glIndexd",
+       "glIndexdv",
+       "glIndexf",
+       "glIndexfv",
+       "glIndexi",
+       "glIndexiv",
+       "glIndexs",
+       "glIndexsv",
+       "glIndexub",
+       "glIndexubv",
+       "glInitNames",
+       "glInterleavedArrays",
+       "glIsEnabled",
+       "glIsList",
+       "glIsTexture",
+       "glLightModelf",
+       "glLightModelfv",
+       "glLightModeli",
+       "glLightModeliv",
+       "glLightf",
+       "glLightfv",
+       "glLighti",
+       "glLightiv",
+       "glLineStipple",
+       "glLineWidth",
+       "glListBase",
+       "glLoadIdentity",
+       "glLoadMatrixd",
+       "glLoadMatrixf",
+       "glLoadName",
+       "glLogicOp",
+       "glMap1d",
+       "glMap1f",
+       "glMap2d",
+       "glMap2f",
+       "glMapGrid1d",
+       "glMapGrid1f",
+       "glMapGrid2d",
+       "glMapGrid2f",
+       "glMaterialf",
+       "glMaterialfv",
+       "glMateriali",
+       "glMaterialiv",
+       "glMatrixMode",
+       "glMultMatrixd",
+       "glMultMatrixf",
+       "glNewList",
+       "glNormal3b",
+       "glNormal3bv",
+       "glNormal3d",
+       "glNormal3dv",
+       "glNormal3f",
+       "glNormal3fv",
+       "glNormal3i",
+       "glNormal3iv",
+       "glNormal3s",
+       "glNormal3sv",
+       "glNormalPointer",
+       "glOrtho",
+       "glPassThrough",
+       "glPixelMapfv",
+       "glPixelMapuiv",
+       "glPixelMapusv",
+       "glPixelStoref",
+       "glPixelStorei",
+       "glPixelTransferf",
+       "glPixelTransferi",
+       "glPixelZoom",
+       "glPointSize",
+       "glPolygonMode",
+       "glPolygonOffset",
+       "glPolygonStipple",
+       "glPopAttrib",
+       "glPopClientAttrib",
+       "glPopMatrix",
+       "glPopName",
+       "glPrioritizeTextures",
+       "glPushAttrib",
+       "glPushClientAttrib",
+       "glPushMatrix",
+       "glPushName",
+       "glRasterPos2d",
+       "glRasterPos2dv",
+       "glRasterPos2f",
+       "glRasterPos2fv",
+       "glRasterPos2i",
+       "glRasterPos2iv",
+       "glRasterPos2s",
+       "glRasterPos2sv",
+       "glRasterPos3d",
+       "glRasterPos3dv",
+       "glRasterPos3f",
+       "glRasterPos3fv",
+       "glRasterPos3i",
+       "glRasterPos3iv",
+       "glRasterPos3s",
+       "glRasterPos3sv",
+       "glRasterPos4d",
+       "glRasterPos4dv",
+       "glRasterPos4f",
+       "glRasterPos4fv",
+       "glRasterPos4i",
+       "glRasterPos4iv",
+       "glRasterPos4s",
+       "glRasterPos4sv",
+       "glReadBuffer",
+       "glReadPixels",
+       "glRectd",
+       "glRectdv",
+       "glRectf",
+       "glRectfv",
+       "glRecti",
+       "glRectiv",
+       "glRects",
+       "glRectsv",
+       "glRenderMode",
+       "glRotated",
+       "glRotatef",
+       "glScaled",
+       "glScalef",
+       "glScissor",
+       "glSelectBuffer",
+       "glShadeModel",
+       "glStencilFunc",
+       "glStencilMask",
+       "glStencilOp",
+       "glTexCoord1d",
+       "glTexCoord1dv",
+       "glTexCoord1f",
+       "glTexCoord1fv",
+       "glTexCoord1i",
+       "glTexCoord1iv",
+       "glTexCoord1s",
+       "glTexCoord1sv",
+       "glTexCoord2d",
+       "glTexCoord2dv",
+       "glTexCoord2f",
+       "glTexCoord2fv",
+       "glTexCoord2i",
+       "glTexCoord2iv",
+       "glTexCoord2s",
+       "glTexCoord2sv",
+       "glTexCoord3d",
+       "glTexCoord3dv",
+       "glTexCoord3f",
+       "glTexCoord3fv",
+       "glTexCoord3i",
+       "glTexCoord3iv",
+       "glTexCoord3s",
+       "glTexCoord3sv",
+       "glTexCoord4d",
+       "glTexCoord4dv",
+       "glTexCoord4f",
+       "glTexCoord4fv",
+       "glTexCoord4i",
+       "glTexCoord4iv",
+       "glTexCoord4s",
+       "glTexCoord4sv",
+       "glTexCoordPointer",
+       "glTexEnvf",
+       "glTexEnvfv",
+       "glTexEnvi",
+       "glTexEnviv",
+       "glTexGend",
+       "glTexGendv",
+       "glTexGenf",
+       "glTexGenfv",
+       "glTexGeni",
+       "glTexGeniv",
+       "glTexImage1D",
+       "glTexImage2D",
+       "glTexParameterf",
+       "glTexParameterfv",
+       "glTexParameteri",
+       "glTexParameteriv",
+       "glTexSubImage1D",
+       "glTexSubImage2D",
+       "glTranslated",
+       "glTranslatef",
+       "glVertex2d",
+       "glVertex2dv",
+       "glVertex2f",
+       "glVertex2fv",
+       "glVertex2i",
+       "glVertex2iv",
+       "glVertex2s",
+       "glVertex2sv",
+       "glVertex3d",
+       "glVertex3dv",
+       "glVertex3f",
+       "glVertex3fv",
+       "glVertex3i",
+       "glVertex3iv",
+       "glVertex3s",
+       "glVertex3sv",
+       "glVertex4d",
+       "glVertex4dv",
+       "glVertex4f",
+       "glVertex4fv",
+       "glVertex4i",
+       "glVertex4iv",
+       "glVertex4s",
+       "glVertex4sv",
+       "glVertexPointer",
+       "glViewport",
+       "wglChoosePixelFormat",
+       "wglCopyContext",
+       "wglCreateContext",
+       "wglCreateLayerContext",
+       "wglDeleteContext",
+       "wglDescribeLayerPlane",
+       "wglDescribePixelFormat",
+       "wglGetCurrentContext",
+       "wglGetCurrentDC",
+       "wglGetDefaultProcAddress",
+       "wglGetLayerPaletteEntries",
+       "wglGetPixelFormat",
+       "wglGetProcAddress",
+       "wglMakeCurrent",
+       "wglRealizeLayerPalette",
+       "wglSetLayerPaletteEntries",
+       "wglSetPixelFormat",
+       "wglShareLists",
+       "wglSwapBuffers",
+       "wglSwapLayerBuffers",
+       "wglSwapMultipleBuffers",
+       "wglUseFontBitmapsA",
+       "wglUseFontBitmapsW",
+       "wglUseFontOutlinesA",
+       "wglUseFontOutlinesW",
 ])
 
-PIXELFORMATDESCRIPTOR = Struct("PIXELFORMATDESCRIPTOR", [
-    (WORD, "nSize"),
-    (WORD, "nVersion"),
-    (PFD, "dwFlags"),
-    (BYTE, "iPixelType"),
-    (BYTE, "cColorBits"),
-    (BYTE, "cRedBits"),
-    (BYTE, "cRedShift"),
-    (BYTE, "cGreenBits"),
-    (BYTE, "cGreenShift"),
-    (BYTE, "cBlueBits"),
-    (BYTE, "cBlueShift"),
-    (BYTE, "cAlphaBits"),
-    (BYTE, "cAlphaShift"),
-    (BYTE, "cAccumBits"),
-    (BYTE, "cAccumRedBits"),
-    (BYTE, "cAccumGreenBits"),
-    (BYTE, "cAccumBlueBits"),
-    (BYTE, "cAccumAlphaBits"),
-    (BYTE, "cDepthBits"),
-    (BYTE, "cStencilBits"),
-    (BYTE, "cAuxBuffers"),
-    (BYTE, "iLayerType"),
-    (BYTE, "bReserved"),
-    (DWORD, "dwLayerMask"),
-    (DWORD, "dwVisibleMask"),
-    (DWORD, "dwDamageMask"),
-])
-
-POINTFLOAT = Struct("POINTFLOAT", [
-    (FLOAT, "x"),
-    (FLOAT, "y"),
-])
-
-GLYPHMETRICSFLOAT = Struct("GLYPHMETRICSFLOAT", [
-    (FLOAT, "gmfBlackBoxX"),
-    (FLOAT, "gmfBlackBoxY"),
-    (POINTFLOAT, "gmfptGlyphOrigin"),
-    (FLOAT, "gmfCellIncX"),
-    (FLOAT, "gmfCellIncY"),
-])
-LPGLYPHMETRICSFLOAT = Pointer(GLYPHMETRICSFLOAT)
-
-COLORREF = Alias("COLORREF", DWORD)
-
-
-LAYERPLANEDESCRIPTOR = Struct("LAYERPLANEDESCRIPTOR", [
-    (WORD, "nSize"),
-    (WORD, "nVersion"),
-    (DWORD, "dwFlags"),
-    (BYTE, "iPixelType"),
-    (BYTE, "cColorBits"),
-    (BYTE, "cRedBits"),
-    (BYTE, "cRedShift"),
-    (BYTE, "cGreenBits"),
-    (BYTE, "cGreenShift"),
-    (BYTE, "cBlueBits"),
-    (BYTE, "cBlueShift"),
-    (BYTE, "cAlphaBits"),
-    (BYTE, "cAlphaShift"),
-    (BYTE, "cAccumBits"),
-    (BYTE, "cAccumRedBits"),
-    (BYTE, "cAccumGreenBits"),
-    (BYTE, "cAccumBlueBits"),
-    (BYTE, "cAccumAlphaBits"),
-    (BYTE, "cDepthBits"),
-    (BYTE, "cStencilBits"),
-    (BYTE, "cAuxBuffers"),
-    (BYTE, "iLayerPlane"),
-    (BYTE, "bReserved"),
-    (COLORREF, "crTransparent"),
-])
-LPLAYERPLANEDESCRIPTOR = Pointer(LAYERPLANEDESCRIPTOR)
-
-WGLSWAP = Struct("WGLSWAP", [
-   (HDC, "hdc"),
-    (UINT, "uiFlags"),
-])
-
-opengl32.functions += [
-    DllFunction(BOOL, "wglCopyContext", [(HGLRC, "hglrcSrc"), (HGLRC, "hglrcDst"), (UINT, "mask")]),
-    DllFunction(HGLRC, "wglCreateContext", [(HDC, "hdc")]),
-    DllFunction(HGLRC, "wglCreateLayerContext", [(HDC, "hdc"), (Int, "iLayerPlane")]),
-    DllFunction(BOOL, "wglDeleteContext", [(HGLRC, "hglrc")]),
-    DllFunction(HGLRC, "wglGetCurrentContext", [], sideeffects=False),
-    DllFunction(HDC, "wglGetCurrentDC", [], sideeffects=False),
-    DllFunction(PROC, "wglGetDefaultProcAddress", [(LPCSTR, "lpszProc")], sideeffects=False),
-    DllFunction(Int, "wglChoosePixelFormat", [(HDC, "hdc"), (Pointer(Const(PIXELFORMATDESCRIPTOR)), "ppfd")]), 
-    DllFunction(Int, "wglDescribePixelFormat", [(HDC, "hdc"), (Int, "iPixelFormat"), (UINT, "nBytes"), Out(Pointer(PIXELFORMATDESCRIPTOR), "ppfd")]),
-    DllFunction(Int, "wglGetPixelFormat", [(HDC, "hdc")], sideeffects=False),
-    DllFunction(BOOL, "wglSetPixelFormat", [(HDC, "hdc"), (Int, "iPixelFormat"), (Pointer(Const(PIXELFORMATDESCRIPTOR)), "ppfd")]),
-    DllFunction(BOOL, "wglMakeCurrent", [(HDC, "hdc"), (HGLRC, "hglrc")]),
-    DllFunction(BOOL, "wglShareLists", [(HGLRC, "hglrc1"), (HGLRC, "hglrc2")]),
-    DllFunction(BOOL, "wglUseFontBitmapsA", [(HDC, "hdc"), (DWORD, "first"), (DWORD, "count"), (DWORD, "listBase")]),
-    DllFunction(BOOL, "wglUseFontBitmapsW", [(HDC, "hdc"), (DWORD, "first"), (DWORD, "count"), (DWORD, "listBase")]),
-    DllFunction(BOOL, "wglSwapBuffers", [(HDC, "hdc")]),
-    DllFunction(BOOL, "wglUseFontOutlinesA", [(HDC, "hdc"), (DWORD, "first"), (DWORD, "count"), (DWORD, "listBase"), (FLOAT, "deviation"), (FLOAT, "extrusion"), (Int, "format"), (LPGLYPHMETRICSFLOAT, "lpgmf")]),
-    DllFunction(BOOL, "wglUseFontOutlinesW", [(HDC, "hdc"), (DWORD, "first"), (DWORD, "count"), (DWORD, "listBase"), (FLOAT, "deviation"), (FLOAT, "extrusion"), (Int, "format"), (LPGLYPHMETRICSFLOAT, "lpgmf")]),
-    DllFunction(BOOL , "wglDescribeLayerPlane", [(HDC, "hdc"), (Int, "iPixelFormat"), (Int, "iLayerPlane"), (UINT, "nBytes"), Out(Pointer(LAYERPLANEDESCRIPTOR), "plpd")]),
-    DllFunction(Int  , "wglSetLayerPaletteEntries", [(HDC, "hdc"), (Int, "iLayerPlane"), (Int, "iStart"), (Int, "cEntries"), (Array(Const(COLORREF), "cEntries"), "pcr")]),
-    DllFunction(Int  , "wglGetLayerPaletteEntries", [(HDC, "hdc"), (Int, "iLayerPlane"), (Int, "iStart"), (Int, "cEntries"), Out(Array(COLORREF, "cEntries"), "pcr")], sideeffects=False),
-    DllFunction(BOOL , "wglRealizeLayerPalette", [(HDC, "hdc"), (Int, "iLayerPlane"), (BOOL, "bRealize")]),
-    DllFunction(BOOL , "wglSwapLayerBuffers", [(HDC, "hdc"), (UINT, "fuPlanes")]),
-    DllFunction(DWORD, "wglSwapMultipleBuffers", [(UINT, "n"), (Array(Const(WGLSWAP), "n"), "ps")]),
-]
-
-
-class WglGetProcAddressFunction(DllFunction):
-
-    def __init__(self, type, name, args, **kwargs):
-        DllFunction.__init__(self, type, name, args, **kwargs)
-        self.functions = []
+class WglTracer(Tracer):
 
-    def wrap_decl(self):
-        for function in self.functions:
-            function.wrap_decl()
-        DllFunction.wrap_decl(self)
-
-    def wrap_impl(self):
-        for function in self.functions:
-            function.wrap_impl()
-        DllFunction.wrap_impl(self)
-
-    def post_call_impl(self):
-        print '    if(result) {'
-        for function in self.functions:
-            ptype = function.pointer_type()
-            pvalue = function.pointer_value()
-            print '        if(!strcmp("%s", lpszProc)) {' % function.name
-            print '            %s = (%s)result;' % (pvalue, ptype)
-            print '            result = (PROC)&%s;' % function.name;
+    def get_function_address(self, function):
+        #print 'DebugBreak();'
+        if function.name in public_symbols:
+            return '__GetProcAddress("%s")' % (function.name,)
+        else:
+            print '        if (!pwglGetProcAddress) {'
+            print '            pwglGetProcAddress = (PwglGetProcAddress)__GetProcAddress("wglGetProcAddress");'
+            print '            if (!pwglGetProcAddress)'
+            print '                Log::Abort();'
             print '        }'
-        print '    }'
-
-
-wglgetprocaddress = WglGetProcAddressFunction(PROC, "wglGetProcAddress", [(LPCSTR, "lpszProc")])
-opengl32.functions.append(wglgetprocaddress)
-
-class WglFunction(Function):
-
-    def get_true_pointer(self):
-        ptype = self.pointer_type()
-        pvalue = self.pointer_value()
-        print '    if(!%s)' % (pvalue,)
-        self.fail_impl()
-
-attribute = FakeEnum(Int, [
-    "WGL_NUMBER_PIXEL_FORMATS_EXT",
-    "WGL_DRAW_TO_WINDOW_EXT",
-    "WGL_DRAW_TO_BITMAP_EXT",
-    "WGL_ACCELERATION_EXT",
-    "WGL_NEED_PALETTE_EXT",
-    "WGL_NEED_SYSTEM_PALETTE_EXT",
-    "WGL_SWAP_LAYER_BUFFERS_EXT",
-    "WGL_SWAP_METHOD_EXT",
-    "WGL_NUMBER_OVERLAYS_EXT",
-    "WGL_NUMBER_UNDERLAYS_EXT",
-    "WGL_TRANSPARENT_EXT",
-    "WGL_TRANSPARENT_VALUE_EXT",
-    "WGL_SHARE_DEPTH_EXT",
-    "WGL_SHARE_STENCIL_EXT",
-    "WGL_SHARE_ACCUM_EXT",
-    "WGL_SUPPORT_GDI_EXT",
-    "WGL_SUPPORT_OPENGL_EXT",
-    "WGL_DOUBLE_BUFFER_EXT",
-    "WGL_STEREO_EXT",
-    "WGL_PIXEL_TYPE_EXT",
-    "WGL_COLOR_BITS_EXT",
-    "WGL_RED_BITS_EXT",
-    "WGL_RED_SHIFT_EXT",
-    "WGL_GREEN_BITS_EXT",
-    "WGL_GREEN_SHIFT_EXT",
-    "WGL_BLUE_BITS_EXT",
-    "WGL_BLUE_SHIFT_EXT",
-    "WGL_ALPHA_BITS_EXT",
-    "WGL_ALPHA_SHIFT_EXT",
-    "WGL_ACCUM_BITS_EXT",
-    "WGL_ACCUM_RED_BITS_EXT",
-    "WGL_ACCUM_GREEN_BITS_EXT",
-    "WGL_ACCUM_BLUE_BITS_EXT",
-    "WGL_ACCUM_ALPHA_BITS_EXT",
-    "WGL_DEPTH_BITS_EXT",
-    "WGL_STENCIL_BITS_EXT",
-    "WGL_AUX_BUFFERS_EXT",
-    "WGL_NO_ACCELERATION_EXT",
-    "WGL_GENERIC_ACCELERATION_EXT",
-    "WGL_FULL_ACCELERATION_EXT",
-    "WGL_SWAP_EXCHANGE_EXT",
-    "WGL_SWAP_COPY_EXT",
-    "WGL_SWAP_UNDEFINED_EXT",
-    "WGL_TYPE_RGBA_EXT",
-    "WGL_TYPE_COLORINDEX_EXT",
-])
+            return 'pwglGetProcAddress("%s")' % (function.name,)
 
-HPBUFFERARB = Alias("HPBUFFERARB", HANDLE)
+    def wrap_ret(self, function, instance):
+        if function.name == "wglGetProcAddress":
+            print '    if (%s) {' % instance
+            for f in wglapi.functions:
+                ptype = self.function_pointer_type(f)
+                pvalue = self.function_pointer_value(f)
+                print '        if (!strcmp("%s", lpszProc)) {' % f.name
+                print '            %s = (%s)&%s;' % (instance, function.type, f.name);
+                print '        }'
+            print '    }'
 
-wglgetprocaddress.functions += extended_functions(WglFunction)
-
-wglgetprocaddress.functions += [
-    # WGL_ARB_extensions_string
-    WglFunction(Const(String), "wglGetExtensionsStringARB", [(HDC, "hdc")], sideeffects=False),
-    # WGL_ARB_pbuffer
-    WglFunction(HPBUFFERARB, "wglCreatePbufferARB", [(HDC, "hDC"), (Int, "iPixelFormat"), (Int, "iWidth"), (Int, "iHeight"), (Pointer(Const(Int)), "piAttribList")]), 
-    WglFunction(HDC, "wglGetPbufferDCARB", [(HPBUFFERARB, "hPbuffer")], sideeffects=False),
-    WglFunction(Int, "wglReleasePbufferDCARB", [(HPBUFFERARB, "hPbuffer"), (HDC, "hDC")]),
-    WglFunction(BOOL, "wglDestroyPbufferARB", [(HPBUFFERARB, "hPbuffer")]), 
-    WglFunction(BOOL, "wglQueryPbufferARB", [(HPBUFFERARB, "hPbuffer"), (Int, "iAttribute"), Out(Pointer(Int), "piValue")]),
-    # WGL_ARB_pixel_format
-    WglFunction(BOOL, "wglGetPixelFormatAttribivARB", [(HDC, "hdc"), (Int, "iPixelFormat"), (Int, "iLayerPlane"), (UINT, "nAttributes"), (Array(attribute, "nAttributes"), "piAttributes"), Out(Array(Int, "nAttributes"), "piValues")], sideeffects=False),
-    WglFunction(BOOL, "wglGetPixelFormatAttribfvARB", [(HDC, "hdc"), (Int, "iPixelFormat"), (Int, "iLayerPlane"), (UINT, "nAttributes"), (Array(attribute, "nAttributes"), "piAttributes"), Out(Array(FLOAT, "nAttributes"), "pfValues")], sideeffects=False),
-    WglFunction(BOOL, "wglChoosePixelFormatARB", [(HDC, "hdc"), (Pointer(Const(Int)), "piAttribIList"), (Pointer(Const(FLOAT)), "pfAttribFList"), (UINT, "nMaxFormats"), Out(Array(Int, "nMaxFormats"), "piFormats"), Out(Pointer(UINT), "nNumFormats")]),
-    # WGL_EXT_extensions_string
-    WglFunction(Const(String), "wglGetExtensionsStringEXT", [], sideeffects=False),
-    # WGL_EXT_pixel_format
-    WglFunction(BOOL, "wglGetPixelFormatAttribivEXT", [(HDC, "hdc"), (Int, "iPixelFormat"), (Int, "iLayerPlane"), (UINT, "nAttributes"), (Array(attribute, "nAttributes"), "piAttributes"), Out(Array(Int, "nAttributes"), "piValues")], sideeffects=False),
-    WglFunction(BOOL, "wglGetPixelFormatAttribfvEXT", [(HDC, "hdc"), (Int, "iPixelFormat"), (Int, "iLayerPlane"), (UINT, "nAttributes"), (Array(attribute, "nAttributes"), "piAttributes"), Out(Array(FLOAT, "nAttributes"), "pfValues")], sideeffects=False),
-    WglFunction(BOOL, "wglChoosePixelFormatEXT", [(HDC, "hdc"), (Pointer(Const(Int)), "piAttribIList"), (Pointer(Const(FLOAT)), "pfAttribFList"), (UINT, "nMaxFormats"), Out(Array(Int, "nMaxFormats"), "piFormats"), Out(Pointer(UINT), "nNumFormats")]),
-]
 
 if __name__ == '__main__':
     print
@@ -281,8 +429,8 @@ if __name__ == '__main__':
     print '#include "glext.h"'
     print '#include "wglext.h"'
     print
-    print '#include "glhelpers.hpp"'
     print '#include "log.hpp"'
+    print '#include "glhelpers.hpp"'
     print
     print '#ifndef PFD_SUPPORT_DIRECTDRAW'
     print '#define PFD_SUPPORT_DIRECTDRAW 0x00002000'
@@ -290,6 +438,8 @@ if __name__ == '__main__':
     print '#ifndef PFD_SUPPORT_COMPOSITION'
     print '#define PFD_SUPPORT_COMPOSITION 0x00008000'
     print '#endif'
+
+    print '#define GLAPIENTRY __stdcall'
     print
     print '#ifdef __MINGW32__'
     print ''
@@ -304,7 +454,32 @@ if __name__ == '__main__':
     print '#endif'
     print
     print 'extern "C" {'
+    print '''
+static HINSTANCE g_hDll = NULL;
+
+static PROC
+__GetProcAddress(LPCSTR lpProcName)
+{
+    if (!g_hDll) {
+        char szDll[MAX_PATH] = {0};
+        
+        if (!GetSystemDirectoryA(szDll, MAX_PATH)) {
+            return NULL;
+        }
+        
+        strcat(szDll, "\\\\opengl32.dll");
+        
+        g_hDll = LoadLibraryA(szDll);
+        if (!g_hDll) {
+            return NULL;
+        }
+    }
+        
+    return GetProcAddress(g_hDll, lpProcName);
+}
+
+    '''
+    tracer = WglTracer()
+    tracer.trace_api(wglapi)
     print
-    wrap()
-    print
-    print '}'
+    print '} /* extern "C" */'
diff --git a/os.hpp b/os.hpp
index 3c24462..94d0cf3 100644 (file)
--- a/os.hpp
+++ b/os.hpp
 #ifndef vsnprintf
 #define vsnprintf _vsnprintf
 #endif
-#endif /* WIN32 */
+#define PATH_SEP '\\'
+#else /* !WIN32 */
+#define PATH_SEP '/'
+#endif /* !WIN32 */
 
 #ifndef PATH_MAX
 #define PATH_MAX 1024
@@ -46,6 +49,9 @@ void AcquireMutex(void);
 void ReleaseMutex(void);
 
 bool GetProcessName(char *str, size_t size);
+bool GetCurrentDir(char *str, size_t size);
+
+void DebugMessage(const char *str);
 
 void Abort(void);
 
index a5be47d..08d9acd 100644 (file)
@@ -24,6 +24,7 @@
  **************************************************************************/
 
 #include <string.h>
+#include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <pthread.h>
@@ -76,6 +77,21 @@ GetProcessName(char *str, size_t size)
     return true;
 }
 
+bool
+GetCurrentDir(char *str, size_t size)
+{
+    char *ret;
+    ret = getcwd(str, size);
+    str[size - 1] = 0;
+    return ret ? true : false;
+}
+
+void
+DebugMessage(const char *message)
+{
+   fflush(stdout);
+   fputs(message, stderr);
+}
 
 void
 Abort(void)
index 04c0343..0849ab0 100755 (executable)
 
 #include <windows.h>
 #include <string.h>
+#include <stdio.h>
 
 #include "os.hpp"
+#include "log.hpp"
 
 
 namespace OS {
@@ -69,7 +71,7 @@ GetProcessName(char *str, size_t size)
 
     lpProcessExt = strrchr(lpProcessName, '.');
     if (lpProcessExt) {
-       *lpProcessExt = '\0';
+        *lpProcessExt = '\0';
     }
 
     strncpy(str, lpProcessName, size);
@@ -77,12 +79,55 @@ GetProcessName(char *str, size_t size)
     return true;
 }
 
+bool
+GetCurrentDir(char *str, size_t size)
+{
+    DWORD ret;
+    ret = GetCurrentDirectoryA(size, str);
+    str[size - 1] = 0;
+    return ret == 0 ? false : true;
+}
+
+void
+DebugMessage(const char *message)
+{
+   OutputDebugStringA(message);
+   if (!IsDebuggerPresent()) {
+      fflush(stdout);
+      fputs(message, stderr);
+      fflush(stderr);
+   }
+}
 
 void
 Abort(void)
 {
+#ifndef NDEBUG
+    DebugBreak();
+#else
     ExitProcess(0);
+#endif
 }
 
 
+
 } /* namespace OS */
+
+
+#if 0
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
+    switch(fdwReason) {
+    case DLL_PROCESS_ATTACH:
+    case DLL_THREAD_ATTACH:
+        return TRUE;
+    case DLL_THREAD_DETACH:
+        return TRUE;
+    case DLL_PROCESS_DETACH:
+        Log::Close();
+        return TRUE;
+    }
+    (void)hinstDLL;
+    (void)lpvReserved;
+    return TRUE;
+}
+#endif
diff --git a/trace.py b/trace.py
new file mode 100644 (file)
index 0000000..9b5c6b6
--- /dev/null
+++ b/trace.py
@@ -0,0 +1,420 @@
+##########################################################################
+#
+# Copyright 2008-2010 VMware, Inc.
+# 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 the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, 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 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 NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS 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.
+#
+##########################################################################/
+
+"""C basic types"""
+
+
+import base
+
+
+all_types = {}
+
+
+class DumpDeclarator(base.OnceVisitor):
+    '''Declare helper functions to dump complex types.'''
+
+    def visit_void(self, literal):
+        pass
+
+    def visit_literal(self, literal):
+        pass
+
+    def visit_string(self, string):
+        pass
+
+    def visit_const(self, const):
+        self.visit(const.type)
+
+    def visit_struct(self, struct):
+        for type, name in struct.members:
+            self.visit(type)
+        print 'static void __traceStruct%s(const %s &value) {' % (struct.id, struct.expr)
+        print '    Log::BeginStruct("%s");' % struct.name
+        for type, name in struct.members:
+            print '    Log::BeginMember("%s");' % (name,)
+            dump_instance(type, 'value.%s' % (name,))
+            print '    Log::EndMember();'
+        print '    Log::EndStruct();'
+        print '}'
+        print
+
+    def visit_array(self, array):
+        self.visit(array.type)
+
+    def visit_blob(self, array):
+        pass
+
+    def visit_enum(self, enum):
+        print 'static void __traceEnum%s(const %s value) {' % (enum.id, enum.expr)
+        print '    switch(value) {'
+        for value in enum.values:
+            print '    case %s:' % value
+            print '        Log::LiteralNamedConstant("%s", %s);' % (value, value)
+            print '        break;'
+        print '    default:'
+        print '        Log::LiteralSInt(value);'
+        print '        break;'
+        print '    }'
+        print '}'
+        print
+
+    def visit_bitmask(self, bitmask):
+        print 'static void __traceBitmask%s(%s value) {' % (bitmask.id, bitmask.type)
+        print '    Log::BeginBitmask();'
+        for value in bitmask.values:
+            print '    if((value & %s) == %s) {' % (value, value)
+            print '        Log::LiteralNamedConstant("%s", %s);' % (value, value)
+            print '        value &= ~%s;' % value
+            print '    }'
+        print '    if(value) {'
+        dump_instance(bitmask.type, "value");
+        print '    }'
+        print '    Log::EndBitmask();'
+        print '}'
+        print
+
+    def visit_pointer(self, pointer):
+        self.visit(pointer.type)
+
+    def visit_alias(self, alias):
+        self.visit(alias.type)
+
+    def visit_opaque(self, opaque):
+        pass
+
+    def visit_interface(self, interface):
+        pass
+
+
+class DumpImplementer(base.Visitor):
+    '''Dump an instance.'''
+
+    def visit_literal(self, literal, instance):
+        print '    Log::Literal%s(%s);' % (literal.format, instance)
+
+    def visit_string(self, string, instance):
+        print '    Log::LiteralString((const char *)%s);' % instance
+
+    def visit_const(self, const, instance):
+        self.visit(const.type, instance)
+
+    def visit_struct(self, struct, instance):
+        print '    __traceStruct%s(%s);' % (struct.id, instance)
+
+    def visit_array(self, array, instance):
+        print '    if(%s) {' % instance
+        index = '__i' + array.type.id
+        print '        Log::BeginArray(%s);' % (array.length,)
+        print '        for (int %s = 0; %s < %s; ++%s) {' % (index, index, array.length, index)
+        print '            Log::BeginElement();'
+        self.visit(array.type, '(%s)[%s]' % (instance, index))
+        print '            Log::EndElement();'
+        print '        }'
+        print '        Log::EndArray();'
+        print '    }'
+        print '    else'
+        print '        Log::LiteralNull();'
+
+    def visit_blob(self, blob, instance):
+        print '    Log::LiteralBlob(%s, %s);' % (instance, blob.size)
+
+    def visit_enum(self, enum, instance):
+        print '    __traceEnum%s(%s);' % (enum.id, instance)
+
+    def visit_bitmask(self, bitmask, instance):
+        print '    __traceBitmask%s(%s);' % (bitmask.id, instance)
+
+    def visit_pointer(self, pointer, instance):
+        print '    if(%s) {' % instance
+        print '        Log::BeginPointer((const void *)%s);' % (instance,)
+        dump_instance(pointer.type, "*" + instance)
+        print '        Log::EndPointer();'
+        print '    }'
+        print '    else'
+        print '        Log::LiteralNull();'
+
+    def visit_alias(self, alias, instance):
+        self.visit(alias.type, instance)
+
+    def visit_opaque(self, opaque, instance):
+        print '    Log::LiteralOpaque((const void *)%s);' % instance
+
+    def visit_interface(self, interface, instance):
+        print '    Log::LiteralOpaque((const void *)%s);' % instance
+
+
+dump_instance = DumpImplementer().visit
+
+
+
+class Wrapper(base.Visitor):
+    '''Wrap an instance.'''
+
+    def visit_void(self, type, instance):
+        raise NotImplementedError
+
+    def visit_literal(self, type, instance):
+        pass
+
+    def visit_string(self, type, instance):
+        pass
+
+    def visit_const(self, type, instance):
+        pass
+
+    def visit_struct(self, struct, instance):
+        for type, name in struct.members:
+            self.visit(type, "(%s).%s" % (instance, name))
+
+    def visit_array(self, array, instance):
+        # XXX: actually it is possible to return an array of pointers
+        pass
+
+    def visit_blob(self, blob, instance):
+        pass
+
+    def visit_enum(self, enum, instance):
+        pass
+
+    def visit_bitmask(self, bitmask, instance):
+        pass
+
+    def visit_pointer(self, pointer, instance):
+        self.visit(pointer.type, "*" + instance)
+
+    def visit_alias(self, alias, instance):
+        self.visit(alias.type, instance)
+
+    def visit_opaque(self, opaque, instance):
+        pass
+    
+    def visit_interface(self, interface, instance):
+        print "    if(%s)" % instance
+        print "        %s = new %s(%s);" % (instance, interface.type.wrap_name(), instance)
+
+
+class Unwrapper(Wrapper):
+
+    def visit_interface(self, interface, instance):
+        print "    if(%s)" % instance
+        print "        %s = static_cast<%s *>(%s)->m_pInstance;" % (instance, interface.type.wrap_name(), instance)
+
+wrap_instance = Wrapper().visit
+unwrap_instance = Unwrapper().visit
+
+
+class Tracer:
+
+    def trace_api(self, api):
+        self.header(api)
+
+        # Includes
+        for header in api.headers:
+            print '#include <%s>' % header
+        print
+
+        # Type dumpers
+        visitor = DumpDeclarator()
+        map(visitor.visit, api.types)
+        print
+
+        # Interfaces wrapers
+        map(self.interface_wrap_name, api.interfaces)
+        map(self.interface_pre_decl, api.interfaces)
+        map(self.interface_decl, api.interfaces)
+        map(self.interface_wrap_impl, api.interfaces)
+        print
+
+        # Function wrappers
+        map(self.trace_function_decl, api.functions)
+        map(self.trace_function_impl, api.functions)
+        print
+
+        self.footer(api)
+
+    def header(self, api):
+        pass
+
+    def footer(self, api):
+        pass
+
+    def function_pointer_type(self, function):
+        return 'P' + function.name
+
+    def function_pointer_value(self, function):
+        return 'p' + function.name
+
+    def trace_function_decl(self, function):
+        ptype = self.function_pointer_type(function)
+        pvalue = self.function_pointer_value(function)
+        print 'typedef ' + function.prototype('* %s' % ptype) + ';'
+        print 'static %s %s = NULL;' % (ptype, pvalue)
+        print
+
+    def trace_function_fail(self, function):
+        if function.fail is not None:
+            if function.type is base.Void:
+                assert function.fail == ''
+                print '            return;' 
+            else:
+                assert function.fail != ''
+                print '            return %s;' % function.fail
+        else:
+            print '            Log::Abort();'
+
+    def get_function_address(self, function):
+        raise NotImplementedError
+
+    def _get_true_pointer(self, function):
+        ptype = self.function_pointer_type(function)
+        pvalue = self.function_pointer_value(function)
+        print '    if(!%s) {' % (pvalue,)
+        print '        %s = (%s)%s;' % (pvalue, ptype, self.get_function_address(function))
+        print '        if(!%s)' % (pvalue,)
+        self.trace_function_fail(function)
+        print '    }'
+
+    def trace_function_impl(self, function):
+        pvalue = self.function_pointer_value(function)
+        print function.prototype() + ' {'
+        if function.type is base.Void:
+            result = ''
+        else:
+            print '    %s __result;' % function.type
+            result = '__result = '
+        self._get_true_pointer(function)
+        print '    Log::BeginCall("%s");' % (function.name)
+        for arg in function.args:
+            if not arg.output:
+                self.unwrap_arg(function, arg)
+                self.dump_arg(function, arg)
+        print '    %s%s(%s);' % (result, pvalue, ', '.join([str(arg.name) for arg in function.args]))
+        for arg in function.args:
+            if arg.output:
+                self.dump_arg(function, arg)
+                self.wrap_arg(function, arg)
+        if function.type is not base.Void:
+            self.dump_ret(function, "__result")
+        print '    Log::EndCall();'
+        if function.type is not base.Void:
+            self.wrap_ret(function, "__result")
+            print '    return __result;'
+        print '}'
+        print
+
+    def dump_arg(self, function, arg):
+        print '    Log::BeginArg("%s");' % (arg.name,)
+        dump_instance(arg.type, arg.name)
+        print '    Log::EndArg();'
+
+    def wrap_arg(self, function, arg):
+        wrap_instance(arg.type, arg.name)
+
+    def unwrap_arg(self, function, arg):
+        unwrap_instance(arg.type, arg.name)
+
+    def dump_ret(self, function, instance):
+        print '    Log::BeginReturn();'
+        dump_instance(function.type, instance)
+        print '    Log::EndReturn();'
+
+    def wrap_ret(self, function, instance):
+        wrap_instance(function.type, instance)
+
+    def unwrap_ret(self, function, instance):
+        unwrap_instance(function.type, instance)
+
+    def interface_wrap_name(self, interface):
+        return "Wrap" + interface.expr
+
+    def interface_pre_decl(self, interface):
+        print "class %s;" % interface.wrap_name()
+
+    def interface_decl(self, interface):
+        print "class %s : public %s " % (interface.wrap_name(), interface.name)
+        print "{"
+        print "public:"
+        print "    %s(%s * pInstance);" % (interface.wrap_name(), interface.name)
+        print "    virtual ~%s();" % interface.wrap_name()
+        print
+        for method in interface.itermethods():
+            print "    " + method.prototype() + ";"
+        print
+        #print "private:"
+        print "    %s * m_pInstance;" % (interface.name,)
+        print "};"
+        print
+
+    def interface_wrap_impl(self, interface):
+        print '%s::%s(%s * pInstance) {' % (interface.wrap_name(), interface.wrap_name(), interface.name)
+        print '    m_pInstance = pInstance;'
+        print '}'
+        print
+        print '%s::~%s() {' % (interface.wrap_name(), interface.wrap_name())
+        print '}'
+        print
+        for method in interface.itermethods():
+            self.trace_method(interface, method)
+        print
+
+    def trace_method(self, interface, method):
+        print method.prototype(interface.wrap_name() + '::' + method.name) + ' {'
+        if method.type is Void:
+            result = ''
+        else:
+            print '    %s __result;' % method.type
+            result = '__result = '
+        print '    Log::BeginCall("%s");' % (interface.name + '::' + method.name)
+        print '    Log::BeginArg("this");'
+        print '    Log::LiteralOpaque((const void *)m_pInstance);'
+        print '    Log::EndArg();'
+        for arg in method.args:
+            if not arg.output:
+                self.unwrap_arg(method, arg)
+                self.dump_arg(method, arg)
+        print '    %sm_pInstance->%s(%s);' % (result, method.name, ', '.join([str(arg.name) for arg in method.args]))
+        for arg in method.args:
+            if arg.output:
+                self.dump_arg(method, arg)
+                self.wrap_arg(method, arg)
+        if method.type is not Void:
+            print '    Log::BeginReturn("%s");' % method.type
+            dump_instance(method.type, "__result")
+            print '    Log::EndReturn();'
+            wrap_instance(method.type, '__result')
+        print '    Log::EndCall();'
+        if method.name == 'QueryInterface':
+            print '    if (*ppvObj == m_pInstance)'
+            print '        *ppvObj = this;'
+        if method.name == 'Release':
+            assert method.type is not Void
+            print '    if (!__result)'
+            print '        delete this;'
+        if method.type is not Void:
+            print '    return __result;'
+        print '}'
+        print
+
+
diff --git a/wglapi.py b/wglapi.py
new file mode 100644 (file)
index 0000000..4f05e6b
--- /dev/null
+++ b/wglapi.py
@@ -0,0 +1,277 @@
+##########################################################################
+#
+# Copyright 2008-2010 VMware, Inc.
+# 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 the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, 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 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 NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS 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.
+#
+##########################################################################/
+
+
+from glapi import *
+from windows import *
+
+
+wglapi = API("WGL")
+wglapi.add_functions(glapi.functions)
+
+
+HGLRC = Alias("HGLRC", HANDLE)
+PROC = Opaque("PROC")
+
+PFD = Flags(DWORD, [
+    "PFD_DOUBLEBUFFER",
+    "PFD_STEREO",
+    "PFD_DRAW_TO_WINDOW",
+    "PFD_DRAW_TO_BITMAP",
+    "PFD_SUPPORT_GDI",
+    "PFD_SUPPORT_OPENGL",
+    "PFD_GENERIC_FORMAT",
+    "PFD_NEED_PALETTE",
+    "PFD_NEED_SYSTEM_PALETTE",
+    "PFD_SWAP_EXCHANGE",
+    "PFD_SWAP_COPY",
+    "PFD_SWAP_LAYER_BUFFERS",
+    "PFD_GENERIC_ACCELERATED",
+    "PFD_SUPPORT_DIRECTDRAW",
+    "PFD_DEPTH_DONTCARE",
+    "PFD_DOUBLEBUFFER_DONTCARE",
+    "PFD_STEREO_DONTCARE",
+])
+
+PIXELFORMATDESCRIPTOR = Struct("PIXELFORMATDESCRIPTOR", [
+    (WORD, "nSize"),
+    (WORD, "nVersion"),
+    (PFD, "dwFlags"),
+    (BYTE, "iPixelType"),
+    (BYTE, "cColorBits"),
+    (BYTE, "cRedBits"),
+    (BYTE, "cRedShift"),
+    (BYTE, "cGreenBits"),
+    (BYTE, "cGreenShift"),
+    (BYTE, "cBlueBits"),
+    (BYTE, "cBlueShift"),
+    (BYTE, "cAlphaBits"),
+    (BYTE, "cAlphaShift"),
+    (BYTE, "cAccumBits"),
+    (BYTE, "cAccumRedBits"),
+    (BYTE, "cAccumGreenBits"),
+    (BYTE, "cAccumBlueBits"),
+    (BYTE, "cAccumAlphaBits"),
+    (BYTE, "cDepthBits"),
+    (BYTE, "cStencilBits"),
+    (BYTE, "cAuxBuffers"),
+    (BYTE, "iLayerType"),
+    (BYTE, "bReserved"),
+    (DWORD, "dwLayerMask"),
+    (DWORD, "dwVisibleMask"),
+    (DWORD, "dwDamageMask"),
+])
+
+POINTFLOAT = Struct("POINTFLOAT", [
+    (FLOAT, "x"),
+    (FLOAT, "y"),
+])
+
+GLYPHMETRICSFLOAT = Struct("GLYPHMETRICSFLOAT", [
+    (FLOAT, "gmfBlackBoxX"),
+    (FLOAT, "gmfBlackBoxY"),
+    (POINTFLOAT, "gmfptGlyphOrigin"),
+    (FLOAT, "gmfCellIncX"),
+    (FLOAT, "gmfCellIncY"),
+])
+LPGLYPHMETRICSFLOAT = Pointer(GLYPHMETRICSFLOAT)
+
+COLORREF = Alias("COLORREF", DWORD)
+
+
+LAYERPLANEDESCRIPTOR = Struct("LAYERPLANEDESCRIPTOR", [
+    (WORD, "nSize"),
+    (WORD, "nVersion"),
+    (DWORD, "dwFlags"),
+    (BYTE, "iPixelType"),
+    (BYTE, "cColorBits"),
+    (BYTE, "cRedBits"),
+    (BYTE, "cRedShift"),
+    (BYTE, "cGreenBits"),
+    (BYTE, "cGreenShift"),
+    (BYTE, "cBlueBits"),
+    (BYTE, "cBlueShift"),
+    (BYTE, "cAlphaBits"),
+    (BYTE, "cAlphaShift"),
+    (BYTE, "cAccumBits"),
+    (BYTE, "cAccumRedBits"),
+    (BYTE, "cAccumGreenBits"),
+    (BYTE, "cAccumBlueBits"),
+    (BYTE, "cAccumAlphaBits"),
+    (BYTE, "cDepthBits"),
+    (BYTE, "cStencilBits"),
+    (BYTE, "cAuxBuffers"),
+    (BYTE, "iLayerPlane"),
+    (BYTE, "bReserved"),
+    (COLORREF, "crTransparent"),
+])
+LPLAYERPLANEDESCRIPTOR = Pointer(LAYERPLANEDESCRIPTOR)
+
+WGLSWAP = Struct("WGLSWAP", [
+   (HDC, "hdc"),
+    (UINT, "uiFlags"),
+])
+
+attribute = FakeEnum(Int, [
+    "WGL_NUMBER_PIXEL_FORMATS_EXT",
+    "WGL_DRAW_TO_WINDOW_EXT",
+    "WGL_DRAW_TO_BITMAP_EXT",
+    "WGL_ACCELERATION_EXT",
+    "WGL_NEED_PALETTE_EXT",
+    "WGL_NEED_SYSTEM_PALETTE_EXT",
+    "WGL_SWAP_LAYER_BUFFERS_EXT",
+    "WGL_SWAP_METHOD_EXT",
+    "WGL_NUMBER_OVERLAYS_EXT",
+    "WGL_NUMBER_UNDERLAYS_EXT",
+    "WGL_TRANSPARENT_EXT",
+    "WGL_TRANSPARENT_VALUE_EXT",
+    "WGL_SHARE_DEPTH_EXT",
+    "WGL_SHARE_STENCIL_EXT",
+    "WGL_SHARE_ACCUM_EXT",
+    "WGL_SUPPORT_GDI_EXT",
+    "WGL_SUPPORT_OPENGL_EXT",
+    "WGL_DOUBLE_BUFFER_EXT",
+    "WGL_STEREO_EXT",
+    "WGL_PIXEL_TYPE_EXT",
+    "WGL_COLOR_BITS_EXT",
+    "WGL_RED_BITS_EXT",
+    "WGL_RED_SHIFT_EXT",
+    "WGL_GREEN_BITS_EXT",
+    "WGL_GREEN_SHIFT_EXT",
+    "WGL_BLUE_BITS_EXT",
+    "WGL_BLUE_SHIFT_EXT",
+    "WGL_ALPHA_BITS_EXT",
+    "WGL_ALPHA_SHIFT_EXT",
+    "WGL_ACCUM_BITS_EXT",
+    "WGL_ACCUM_RED_BITS_EXT",
+    "WGL_ACCUM_GREEN_BITS_EXT",
+    "WGL_ACCUM_BLUE_BITS_EXT",
+    "WGL_ACCUM_ALPHA_BITS_EXT",
+    "WGL_DEPTH_BITS_EXT",
+    "WGL_STENCIL_BITS_EXT",
+    "WGL_AUX_BUFFERS_EXT",
+    "WGL_NO_ACCELERATION_EXT",
+    "WGL_GENERIC_ACCELERATION_EXT",
+    "WGL_FULL_ACCELERATION_EXT",
+    "WGL_SWAP_EXCHANGE_EXT",
+    "WGL_SWAP_COPY_EXT",
+    "WGL_SWAP_UNDEFINED_EXT",
+    "WGL_TYPE_RGBA_EXT",
+    "WGL_TYPE_COLORINDEX_EXT",
+])
+
+HPBUFFERARB = Alias("HPBUFFERARB", HANDLE)
+
+
+wglapi.add_functions([
+    StdFunction(BOOL, "wglCopyContext", [(HGLRC, "hglrcSrc"), (HGLRC, "hglrcDst"), (UINT, "mask")]),
+    StdFunction(HGLRC, "wglCreateContext", [(HDC, "hdc")]),
+    StdFunction(HGLRC, "wglCreateLayerContext", [(HDC, "hdc"), (Int, "iLayerPlane")]),
+    StdFunction(BOOL, "wglDeleteContext", [(HGLRC, "hglrc")]),
+    StdFunction(HGLRC, "wglGetCurrentContext", [], sideeffects=False),
+    StdFunction(HDC, "wglGetCurrentDC", [], sideeffects=False),
+    StdFunction(PROC, "wglGetDefaultProcAddress", [(LPCSTR, "lpszProc")], sideeffects=False),
+    StdFunction(Int, "wglChoosePixelFormat", [(HDC, "hdc"), (Pointer(Const(PIXELFORMATDESCRIPTOR)), "ppfd")]), 
+    StdFunction(Int, "wglDescribePixelFormat", [(HDC, "hdc"), (Int, "iPixelFormat"), (UINT, "nBytes"), Out(Pointer(PIXELFORMATDESCRIPTOR), "ppfd")]),
+    StdFunction(Int, "wglGetPixelFormat", [(HDC, "hdc")], sideeffects=False),
+    StdFunction(BOOL, "wglSetPixelFormat", [(HDC, "hdc"), (Int, "iPixelFormat"), (Pointer(Const(PIXELFORMATDESCRIPTOR)), "ppfd")]),
+    StdFunction(BOOL, "wglMakeCurrent", [(HDC, "hdc"), (HGLRC, "hglrc")]),
+    StdFunction(BOOL, "wglShareLists", [(HGLRC, "hglrc1"), (HGLRC, "hglrc2")]),
+    StdFunction(BOOL, "wglUseFontBitmapsA", [(HDC, "hdc"), (DWORD, "first"), (DWORD, "count"), (DWORD, "listBase")]),
+    StdFunction(BOOL, "wglUseFontBitmapsW", [(HDC, "hdc"), (DWORD, "first"), (DWORD, "count"), (DWORD, "listBase")]),
+    StdFunction(BOOL, "wglSwapBuffers", [(HDC, "hdc")]),
+    StdFunction(BOOL, "wglUseFontOutlinesA", [(HDC, "hdc"), (DWORD, "first"), (DWORD, "count"), (DWORD, "listBase"), (FLOAT, "deviation"), (FLOAT, "extrusion"), (Int, "format"), (LPGLYPHMETRICSFLOAT, "lpgmf")]),
+    StdFunction(BOOL, "wglUseFontOutlinesW", [(HDC, "hdc"), (DWORD, "first"), (DWORD, "count"), (DWORD, "listBase"), (FLOAT, "deviation"), (FLOAT, "extrusion"), (Int, "format"), (LPGLYPHMETRICSFLOAT, "lpgmf")]),
+    StdFunction(BOOL , "wglDescribeLayerPlane", [(HDC, "hdc"), (Int, "iPixelFormat"), (Int, "iLayerPlane"), (UINT, "nBytes"), Out(Pointer(LAYERPLANEDESCRIPTOR), "plpd")]),
+    StdFunction(Int  , "wglSetLayerPaletteEntries", [(HDC, "hdc"), (Int, "iLayerPlane"), (Int, "iStart"), (Int, "cEntries"), (Array(Const(COLORREF), "cEntries"), "pcr")]),
+    StdFunction(Int  , "wglGetLayerPaletteEntries", [(HDC, "hdc"), (Int, "iLayerPlane"), (Int, "iStart"), (Int, "cEntries"), Out(Array(COLORREF, "cEntries"), "pcr")], sideeffects=False),
+    StdFunction(BOOL , "wglRealizeLayerPalette", [(HDC, "hdc"), (Int, "iLayerPlane"), (BOOL, "bRealize")]),
+    StdFunction(BOOL , "wglSwapLayerBuffers", [(HDC, "hdc"), (UINT, "fuPlanes")]),
+    StdFunction(DWORD, "wglSwapMultipleBuffers", [(UINT, "n"), (Array(Const(WGLSWAP), "n"), "ps")]),
+    
+    # WGL_ARB_extensions_string
+    StdFunction(Const(String), "wglGetExtensionsStringARB", [(HDC, "hdc")], sideeffects=False),
+    
+    # WGL_ARB_pbuffer
+    StdFunction(HPBUFFERARB, "wglCreatePbufferARB", [(HDC, "hDC"), (Int, "iPixelFormat"), (Int, "iWidth"), (Int, "iHeight"), (Pointer(Const(Int)), "piAttribList")]), 
+    StdFunction(HDC, "wglGetPbufferDCARB", [(HPBUFFERARB, "hPbuffer")], sideeffects=False),
+    StdFunction(Int, "wglReleasePbufferDCARB", [(HPBUFFERARB, "hPbuffer"), (HDC, "hDC")]),
+    StdFunction(BOOL, "wglDestroyPbufferARB", [(HPBUFFERARB, "hPbuffer")]), 
+    StdFunction(BOOL, "wglQueryPbufferARB", [(HPBUFFERARB, "hPbuffer"), (Int, "iAttribute"), Out(Pointer(Int), "piValue")]),
+    
+    # WGL_ARB_pixel_format
+    StdFunction(BOOL, "wglGetPixelFormatAttribivARB", [(HDC, "hdc"), (Int, "iPixelFormat"), (Int, "iLayerPlane"), (UINT, "nAttributes"), (Array(attribute, "nAttributes"), "piAttributes"), Out(Array(Int, "nAttributes"), "piValues")], sideeffects=False),
+    StdFunction(BOOL, "wglGetPixelFormatAttribfvARB", [(HDC, "hdc"), (Int, "iPixelFormat"), (Int, "iLayerPlane"), (UINT, "nAttributes"), (Array(attribute, "nAttributes"), "piAttributes"), Out(Array(FLOAT, "nAttributes"), "pfValues")], sideeffects=False),
+    StdFunction(BOOL, "wglChoosePixelFormatARB", [(HDC, "hdc"), (Pointer(Const(Int)), "piAttribIList"), (Pointer(Const(FLOAT)), "pfAttribFList"), (UINT, "nMaxFormats"), Out(Array(Int, "nMaxFormats"), "piFormats"), Out(Pointer(UINT), "nNumFormats")]),
+    
+    # WGL_EXT_extensions_string
+    StdFunction(Const(String), "wglGetExtensionsStringEXT", [], sideeffects=False),
+
+    # WGL_EXT_pixel_format
+    StdFunction(BOOL, "wglGetPixelFormatAttribivEXT", [(HDC, "hdc"), (Int, "iPixelFormat"), (Int, "iLayerPlane"), (UINT, "nAttributes"), (Array(attribute, "nAttributes"), "piAttributes"), Out(Array(Int, "nAttributes"), "piValues")], sideeffects=False),
+    StdFunction(BOOL, "wglGetPixelFormatAttribfvEXT", [(HDC, "hdc"), (Int, "iPixelFormat"), (Int, "iLayerPlane"), (UINT, "nAttributes"), (Array(attribute, "nAttributes"), "piAttributes"), Out(Array(FLOAT, "nAttributes"), "pfValues")], sideeffects=False),
+    StdFunction(BOOL, "wglChoosePixelFormatEXT", [(HDC, "hdc"), (Pointer(Const(Int)), "piAttribIList"), (Pointer(Const(FLOAT)), "pfAttribFList"), (UINT, "nMaxFormats"), Out(Array(Int, "nMaxFormats"), "piFormats"), Out(Pointer(UINT), "nNumFormats")]),
+
+    # must be last
+    StdFunction(PROC, "wglGetProcAddress", [(LPCSTR, "lpszProc")]),
+])
+
+if __name__ == '__main__':
+    print
+    print '#define _GDI32_'
+    print
+    print '#include <windows.h>'
+    print '#include <tchar.h>'
+    print '#include <GL/gl.h>'
+    print '#include "glext.h"'
+    print '#include "wglext.h"'
+    print
+    print '#include "glhelpers.hpp"'
+    print '#include "log.hpp"'
+    print
+    print '#ifndef PFD_SUPPORT_DIRECTDRAW'
+    print '#define PFD_SUPPORT_DIRECTDRAW 0x00002000'
+    print '#endif'
+    print '#ifndef PFD_SUPPORT_COMPOSITION'
+    print '#define PFD_SUPPORT_COMPOSITION 0x00008000'
+    print '#endif'
+    print
+    print '#ifdef __MINGW32__'
+    print ''
+    print 'typedef struct _WGLSWAP'
+    print '{'
+    print '    HDC hdc;'
+    print '    UINT uiFlags;'
+    print '} WGLSWAP, *PWGLSWAP, FAR *LPWGLSWAP;'
+    print ''
+    print '#define WGL_SWAPMULTIPLE_MAX 16'
+    print ''
+    print '#endif'
+    print
+    print 'extern "C" {'
+    print
+    wrap()
+    print
+    print '}'