1706f2543Smrg/*
2706f2543Smrg * File: glwrap.c
3706f2543Smrg * Purpose: Wrapper functions for Win32 OpenGL functions
4706f2543Smrg *
5706f2543Smrg * Authors: Alexander Gottwald
6706f2543Smrg *          Jon TURNEY
7706f2543Smrg *
8706f2543Smrg * Copyright (c) Jon TURNEY 2009
9706f2543Smrg * Copyright (c) Alexander Gottwald 2004
10706f2543Smrg *
11706f2543Smrg *
12706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a
13706f2543Smrg * copy of this software and associated documentation files (the "Software"),
14706f2543Smrg * to deal in the Software without restriction, including without limitation
15706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the
17706f2543Smrg * Software is furnished to do so, subject to the following conditions:
18706f2543Smrg *
19706f2543Smrg * The above copyright notice and this permission notice shall be included in
20706f2543Smrg * all copies or substantial portions of the Software.
21706f2543Smrg *
22706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25706f2543Smrg * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
26706f2543Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27706f2543Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28706f2543Smrg * DEALINGS IN THE SOFTWARE.
29706f2543Smrg */
30706f2543Smrg
31706f2543Smrg// define USE_OPENGL32 makes gl.h declare gl*() function prototypes with stdcall linkage,
32706f2543Smrg// so our generated wrappers will correctly link with the functions in opengl32.dll
33706f2543Smrg#define USE_OPENGL32
34706f2543Smrg
35706f2543Smrg#ifdef HAVE_XWIN_CONFIG_H
36706f2543Smrg#include <xwin-config.h>
37706f2543Smrg#endif
38706f2543Smrg
39706f2543Smrg#include <X11/Xwindows.h>
40706f2543Smrg#include <GL/gl.h>
41706f2543Smrg#include <GL/glext.h>
42706f2543Smrg#include <glx/glxserver.h>
43706f2543Smrg#include <glx/glxext.h>
44706f2543Smrg#include <glx/glapi.h>
45706f2543Smrg#include <glx/dispatch.h>
46706f2543Smrg#include <glwindows.h>
47706f2543Smrg
48706f2543Smrgstatic unsigned int glWinIndirectProcCalls = 0;
49706f2543Smrgstatic unsigned int glWinDirectProcCalls = 0;
50706f2543Smrg
51706f2543Smrgvoid
52706f2543SmrgglWinCallDelta(void)
53706f2543Smrg{
54706f2543Smrg  static unsigned int glWinIndirectProcCallsLast = 0;
55706f2543Smrg  static unsigned int glWinDirectProcCallsLast = 0;
56706f2543Smrg  if ((glWinIndirectProcCalls != glWinIndirectProcCallsLast) ||
57706f2543Smrg      (glWinDirectProcCalls != glWinDirectProcCallsLast))
58706f2543Smrg    {
59706f2543Smrg      if (glxWinDebugSettings.enableTrace)
60706f2543Smrg        {
61706f2543Smrg          ErrorF("after %d direct and %d indirect GL calls\n",
62706f2543Smrg                 glWinDirectProcCalls - glWinDirectProcCallsLast,
63706f2543Smrg                 glWinIndirectProcCalls - glWinIndirectProcCallsLast);
64706f2543Smrg        }
65706f2543Smrg      glWinDirectProcCallsLast = glWinDirectProcCalls;
66706f2543Smrg      glWinIndirectProcCallsLast = glWinIndirectProcCalls;
67706f2543Smrg    }
68706f2543Smrg}
69706f2543Smrg
70706f2543Smrgstatic PROC
71706f2543SmrgglWinResolveHelper(PROC *cache, char *symbol)
72706f2543Smrg{
73706f2543Smrg  PROC proc = NULL;
74706f2543Smrg
75706f2543Smrg  /* If not yet cached, call wglGetProcAddress */
76706f2543Smrg  if ((*cache) == NULL)
77706f2543Smrg    {
78706f2543Smrg      proc = wglGetProcAddress(symbol);
79706f2543Smrg      if (proc == NULL)
80706f2543Smrg        {
81706f2543Smrg          ErrorF("glwrap: Can't resolve \"%s\"\n", symbol);
82706f2543Smrg          (*cache) = (PROC)-1;
83706f2543Smrg        }
84706f2543Smrg      else
85706f2543Smrg        {
86706f2543Smrg          ErrorF("glwrap: Resolved \"%s\"\n", symbol);
87706f2543Smrg          (*cache) = proc;
88706f2543Smrg        }
89706f2543Smrg    }
90706f2543Smrg  /* Cached wglGetProcAddress failure */
91706f2543Smrg  else if ((*cache) == (PROC)-1)
92706f2543Smrg    {
93706f2543Smrg      proc = 0;
94706f2543Smrg    }
95706f2543Smrg  /* Cached wglGetProcAddress result */
96706f2543Smrg  else
97706f2543Smrg    {
98706f2543Smrg      proc = (*cache);
99706f2543Smrg    }
100706f2543Smrg
101706f2543Smrg  return proc;
102706f2543Smrg}
103706f2543Smrg
104706f2543Smrg#define RESOLVE_RET(proctype, symbol, retval) \
105706f2543Smrg    static PROC cache = NULL; \
106706f2543Smrg    __stdcall proctype proc = (proctype)glWinResolveHelper(&cache, symbol); \
107706f2543Smrg    if (proc == NULL) { \
108706f2543Smrg        __glXErrorCallBack(0); \
109706f2543Smrg        return retval; \
110706f2543Smrg    } \
111706f2543Smrg    glWinIndirectProcCalls++;
112706f2543Smrg
113706f2543Smrg#define RESOLVE(proctype, symbol) RESOLVE_RET(proctype, symbol,)
114706f2543Smrg
115706f2543Smrg#define RESOLVED_PROC(proctype) proc
116706f2543Smrg
117706f2543Smrg/*
118706f2543Smrg  Include generated cdecl wrappers for stdcall gl*() functions in opengl32.dll
119706f2543Smrg
120706f2543Smrg  OpenGL 1.2 and upward is treated as extensions, function address must
121706f2543Smrg  found using wglGetProcAddress(), but also stdcall so still need wrappers...
122706f2543Smrg
123706f2543Smrg  Include generated dispatch table setup function
124706f2543Smrg*/
125706f2543Smrg
126706f2543Smrg#include "generated_gl_wrappers.c"
127706f2543Smrg
128706f2543Smrg/*
129706f2543Smrg  Special non-static wrapper for glGetString for debug output
130706f2543Smrg*/
131706f2543Smrg
132706f2543Smrgconst GLubyte* glGetStringWrapperNonstatic(GLenum name)
133706f2543Smrg{
134706f2543Smrg  return glGetString(name);
135706f2543Smrg}
136706f2543Smrg
137706f2543Smrg/*
138706f2543Smrg  Special non-static wrapper for glAddSwapHintRectWIN for copySubBuffers
139706f2543Smrg*/
140706f2543Smrg
141706f2543Smrgtypedef void (__stdcall *PFNGLADDSWAPHINTRECTWIN)(GLint x, GLint y, GLsizei width, GLsizei height);
142706f2543Smrg
143706f2543Smrgvoid glAddSwapHintRectWINWrapperNonstatic(GLint x, GLint y, GLsizei width, GLsizei height)
144706f2543Smrg{
145706f2543Smrg  RESOLVE(PFNGLADDSWAPHINTRECTWIN, "glAddSwapHintRectWIN");
146706f2543Smrg  proc(x, y, width, height);
147706f2543Smrg}
148706f2543Smrg
149