135c4bbdfSmrg/*
235c4bbdfSmrg * File: glshim.c
335c4bbdfSmrg * Purpose: GL shim which redirects to a specified DLL
435c4bbdfSmrg *
535c4bbdfSmrg * Copyright (c) Jon TURNEY 2013
635c4bbdfSmrg *
735c4bbdfSmrg * Permission is hereby granted, free of charge, to any person obtaining a
835c4bbdfSmrg * copy of this software and associated documentation files (the "Software"),
935c4bbdfSmrg * to deal in the Software without restriction, including without limitation
1035c4bbdfSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1135c4bbdfSmrg * and/or sell copies of the Software, and to permit persons to whom the
1235c4bbdfSmrg * Software is furnished to do so, subject to the following conditions:
1335c4bbdfSmrg *
1435c4bbdfSmrg * The above copyright notice and this permission notice shall be included in
1535c4bbdfSmrg * all copies or substantial portions of the Software.
1635c4bbdfSmrg *
1735c4bbdfSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1835c4bbdfSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1935c4bbdfSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
2035c4bbdfSmrg * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
2135c4bbdfSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2235c4bbdfSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2335c4bbdfSmrg * DEALINGS IN THE SOFTWARE.
2435c4bbdfSmrg */
2535c4bbdfSmrg
2635c4bbdfSmrg/*
2735c4bbdfSmrg   A GL shim which redirects to a specified DLL
2835c4bbdfSmrg
2935c4bbdfSmrg   XWin is statically linked with this, rather than the system libGL, so that
3035c4bbdfSmrg   GL calls can be directed to mesa cygGL-1.dll, or cygnativeGLthunk.dll
3135c4bbdfSmrg   (which contains cdecl-to-stdcall thunks to the native openGL32.dll)
3235c4bbdfSmrg*/
3335c4bbdfSmrg
3435c4bbdfSmrg#ifdef HAVE_XWIN_CONFIG_H
3535c4bbdfSmrg#include <xwin-config.h>
3635c4bbdfSmrg#endif
3735c4bbdfSmrg
3835c4bbdfSmrg#define GL_GLEXT_LEGACY
3935c4bbdfSmrg#define GL_GLEXT_PROTOTYPES
4035c4bbdfSmrg#include <GL/gl.h>
4135c4bbdfSmrg#undef GL_ARB_imaging
4235c4bbdfSmrg#undef GL_VERSION_1_3
4335c4bbdfSmrg#include <GL/glext.h>
4435c4bbdfSmrg
4535c4bbdfSmrg#include <X11/Xwindows.h>
4635c4bbdfSmrg#include <os.h>
4735c4bbdfSmrg#include "glwindows.h"
4835c4bbdfSmrg#include <glx/glxserver.h>
4935c4bbdfSmrg
5035c4bbdfSmrgextern void *glXGetProcAddressARB(const char *);
5135c4bbdfSmrg
5235c4bbdfSmrgstatic HMODULE hMod = NULL;
5335c4bbdfSmrg
5435c4bbdfSmrg/*
5535c4bbdfSmrg  Implement the __glGetProcAddress function by just using GetProcAddress() on the selected DLL
5635c4bbdfSmrg*/
5735c4bbdfSmrgvoid *glXGetProcAddressARB(const char *symbol)
5835c4bbdfSmrg{
5935c4bbdfSmrg    void *proc;
6035c4bbdfSmrg
6135c4bbdfSmrg    /* Default to the mesa GL implementation if one hasn't been selected yet */
6235c4bbdfSmrg    if (!hMod)
6335c4bbdfSmrg        glWinSelectImplementation(0);
6435c4bbdfSmrg
6535c4bbdfSmrg    proc = GetProcAddress(hMod, symbol);
6635c4bbdfSmrg
6735c4bbdfSmrg    if (glxWinDebugSettings.enableGLcallTrace)
6835c4bbdfSmrg        ErrorF("glXGetProcAddressARB: Resolved '%s' in %p to %p\n", symbol, hMod, proc);
6935c4bbdfSmrg
7035c4bbdfSmrg    return proc;
7135c4bbdfSmrg}
7235c4bbdfSmrg
7335c4bbdfSmrg/*
7435c4bbdfSmrg  Select a GL implementation DLL
7535c4bbdfSmrg*/
7635c4bbdfSmrgint glWinSelectImplementation(int native)
7735c4bbdfSmrg{
7835c4bbdfSmrg    const char *dllname;
7935c4bbdfSmrg
8035c4bbdfSmrg    if (native) {
8135c4bbdfSmrg        dllname = "cygnativeGLthunk.dll";
8235c4bbdfSmrg    }
8335c4bbdfSmrg    else {
8435c4bbdfSmrg        dllname = "cygGL-1.dll";
8535c4bbdfSmrg    }
8635c4bbdfSmrg
8735c4bbdfSmrg    hMod = LoadLibraryEx(dllname, NULL, 0);
8835c4bbdfSmrg    if (hMod == NULL) {
8935c4bbdfSmrg        ErrorF("glWinSelectGLimplementation: Could not load '%s'\n", dllname);
9035c4bbdfSmrg        return -1;
9135c4bbdfSmrg    }
9235c4bbdfSmrg
9335c4bbdfSmrg    ErrorF("glWinSelectGLimplementation: Loaded '%s'\n", dllname);
9435c4bbdfSmrg
9535c4bbdfSmrg    /* Connect __glGetProcAddress() to our implementation of glXGetProcAddressARB() above */
9635c4bbdfSmrg    __glXsetGetProcAddress((glx_gpa_proc)glXGetProcAddressARB);
9735c4bbdfSmrg
9835c4bbdfSmrg    return 0;
9935c4bbdfSmrg}
10035c4bbdfSmrg
10135c4bbdfSmrg#define RESOLVE_RET(proctype, symbol, retval) \
10235c4bbdfSmrg    proctype proc = (proctype)glXGetProcAddressARB(symbol);   \
10335c4bbdfSmrg    if (proc == NULL) return retval;
10435c4bbdfSmrg
10535c4bbdfSmrg#define RESOLVE(proctype, symbol) RESOLVE_RET(proctype, symbol,)
10635c4bbdfSmrg#define RESOLVED_PROC proc
10735c4bbdfSmrg
10835c4bbdfSmrg/* Include generated shims for direct linkage to GL functions which are in the ABI */
1091b5d61b8Smrg#include "generated_gl_shim.ic"
11035c4bbdfSmrg
11135c4bbdfSmrg/*
11235c4bbdfSmrg  Special wrapper for glAddSwapHintRectWIN for copySubBuffers
11335c4bbdfSmrg
11435c4bbdfSmrg  Only used with native GL if the GL_WIN_swap_hint extension is present, so we enable
11535c4bbdfSmrg  GLX_MESA_copy_sub_buffer
11635c4bbdfSmrg*/
11735c4bbdfSmrgtypedef void (__stdcall * PFNGLADDSWAPHINTRECTWIN) (GLint x, GLint y,
11835c4bbdfSmrg                                                    GLsizei width,
11935c4bbdfSmrg                                                    GLsizei height);
12035c4bbdfSmrg
12135c4bbdfSmrgvoid
12235c4bbdfSmrgglAddSwapHintRectWINWrapper(GLint x, GLint y, GLsizei width,
12335c4bbdfSmrg                            GLsizei height)
12435c4bbdfSmrg{
12535c4bbdfSmrg    RESOLVE(PFNGLADDSWAPHINTRECTWIN, "glAddSwapHintRectWIN");
12635c4bbdfSmrg    RESOLVED_PROC(x, y, width, height);
12735c4bbdfSmrg}
128