1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2014 Jon Turney
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker *
11*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker * Software.
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker */
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker #include "windowsgl.h"
25*61046927SAndroid Build Coastguard Worker #include "windowsgl_internal.h"
26*61046927SAndroid Build Coastguard Worker
27*61046927SAndroid Build Coastguard Worker #include "glapi.h"
28*61046927SAndroid Build Coastguard Worker #include "wgl.h"
29*61046927SAndroid Build Coastguard Worker
30*61046927SAndroid Build Coastguard Worker #include <dlfcn.h>
31*61046927SAndroid Build Coastguard Worker #include <assert.h>
32*61046927SAndroid Build Coastguard Worker #include <stdio.h>
33*61046927SAndroid Build Coastguard Worker #include <strings.h>
34*61046927SAndroid Build Coastguard Worker
35*61046927SAndroid Build Coastguard Worker static struct _glapi_table *windows_api = NULL;
36*61046927SAndroid Build Coastguard Worker
37*61046927SAndroid Build Coastguard Worker static void *
windows_get_dl_handle(void)38*61046927SAndroid Build Coastguard Worker windows_get_dl_handle(void)
39*61046927SAndroid Build Coastguard Worker {
40*61046927SAndroid Build Coastguard Worker static void *dl_handle = NULL;
41*61046927SAndroid Build Coastguard Worker
42*61046927SAndroid Build Coastguard Worker if (!dl_handle)
43*61046927SAndroid Build Coastguard Worker dl_handle = dlopen("cygnativeGLthunk.dll", RTLD_NOW);
44*61046927SAndroid Build Coastguard Worker
45*61046927SAndroid Build Coastguard Worker return dl_handle;
46*61046927SAndroid Build Coastguard Worker }
47*61046927SAndroid Build Coastguard Worker
48*61046927SAndroid Build Coastguard Worker static void
windows_glapi_create_table(void)49*61046927SAndroid Build Coastguard Worker windows_glapi_create_table(void)
50*61046927SAndroid Build Coastguard Worker {
51*61046927SAndroid Build Coastguard Worker if (windows_api)
52*61046927SAndroid Build Coastguard Worker return;
53*61046927SAndroid Build Coastguard Worker
54*61046927SAndroid Build Coastguard Worker windows_api = _glapi_create_table_from_handle(windows_get_dl_handle(), "gl");
55*61046927SAndroid Build Coastguard Worker assert(windows_api);
56*61046927SAndroid Build Coastguard Worker }
57*61046927SAndroid Build Coastguard Worker
windows_glapi_set_dispatch(void)58*61046927SAndroid Build Coastguard Worker static void windows_glapi_set_dispatch(void)
59*61046927SAndroid Build Coastguard Worker {
60*61046927SAndroid Build Coastguard Worker windows_glapi_create_table();
61*61046927SAndroid Build Coastguard Worker _glapi_set_dispatch(windows_api);
62*61046927SAndroid Build Coastguard Worker }
63*61046927SAndroid Build Coastguard Worker
64*61046927SAndroid Build Coastguard Worker windowsContext *
windows_create_context(int pxfi,windowsContext * shared)65*61046927SAndroid Build Coastguard Worker windows_create_context(int pxfi, windowsContext *shared)
66*61046927SAndroid Build Coastguard Worker {
67*61046927SAndroid Build Coastguard Worker windowsContext *gc;
68*61046927SAndroid Build Coastguard Worker
69*61046927SAndroid Build Coastguard Worker gc = calloc(1, sizeof *gc);
70*61046927SAndroid Build Coastguard Worker if (gc == NULL)
71*61046927SAndroid Build Coastguard Worker return NULL;
72*61046927SAndroid Build Coastguard Worker
73*61046927SAndroid Build Coastguard Worker // create a temporary, invisible window
74*61046927SAndroid Build Coastguard Worker #define GL_TEMP_WINDOW_CLASS "glTempWndClass"
75*61046927SAndroid Build Coastguard Worker {
76*61046927SAndroid Build Coastguard Worker static wATOM glTempWndClass = 0;
77*61046927SAndroid Build Coastguard Worker
78*61046927SAndroid Build Coastguard Worker if (glTempWndClass == 0) {
79*61046927SAndroid Build Coastguard Worker WNDCLASSEX wc;
80*61046927SAndroid Build Coastguard Worker wc.cbSize = sizeof(WNDCLASSEX);
81*61046927SAndroid Build Coastguard Worker wc.style = CS_HREDRAW | CS_VREDRAW;
82*61046927SAndroid Build Coastguard Worker wc.lpfnWndProc = DefWindowProc;
83*61046927SAndroid Build Coastguard Worker wc.cbClsExtra = 0;
84*61046927SAndroid Build Coastguard Worker wc.cbWndExtra = 0;
85*61046927SAndroid Build Coastguard Worker wc.hInstance = GetModuleHandle(NULL);
86*61046927SAndroid Build Coastguard Worker wc.hIcon = 0;
87*61046927SAndroid Build Coastguard Worker wc.hCursor = 0;
88*61046927SAndroid Build Coastguard Worker wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
89*61046927SAndroid Build Coastguard Worker wc.lpszMenuName = NULL;
90*61046927SAndroid Build Coastguard Worker wc.lpszClassName = GL_TEMP_WINDOW_CLASS;
91*61046927SAndroid Build Coastguard Worker wc.hIconSm = 0;
92*61046927SAndroid Build Coastguard Worker RegisterClassEx(&wc);
93*61046927SAndroid Build Coastguard Worker }
94*61046927SAndroid Build Coastguard Worker }
95*61046927SAndroid Build Coastguard Worker
96*61046927SAndroid Build Coastguard Worker HWND hwnd = CreateWindowExA(0,
97*61046927SAndroid Build Coastguard Worker GL_TEMP_WINDOW_CLASS,
98*61046927SAndroid Build Coastguard Worker "glWindow",
99*61046927SAndroid Build Coastguard Worker 0,
100*61046927SAndroid Build Coastguard Worker 0, 0, 0, 0,
101*61046927SAndroid Build Coastguard Worker NULL, NULL, GetModuleHandle(NULL), NULL);
102*61046927SAndroid Build Coastguard Worker HDC hdc = GetDC(hwnd);
103*61046927SAndroid Build Coastguard Worker
104*61046927SAndroid Build Coastguard Worker // We must set the windows pixel format before we can create a WGL context
105*61046927SAndroid Build Coastguard Worker gc->pxfi = pxfi;
106*61046927SAndroid Build Coastguard Worker SetPixelFormat(hdc, gc->pxfi, NULL);
107*61046927SAndroid Build Coastguard Worker
108*61046927SAndroid Build Coastguard Worker gc->ctx = wglCreateContext(hdc);
109*61046927SAndroid Build Coastguard Worker
110*61046927SAndroid Build Coastguard Worker if (shared && gc->ctx)
111*61046927SAndroid Build Coastguard Worker wglShareLists(shared->ctx, gc->ctx);
112*61046927SAndroid Build Coastguard Worker
113*61046927SAndroid Build Coastguard Worker ReleaseDC(hwnd, hdc);
114*61046927SAndroid Build Coastguard Worker DestroyWindow(hwnd);
115*61046927SAndroid Build Coastguard Worker
116*61046927SAndroid Build Coastguard Worker if (!gc->ctx)
117*61046927SAndroid Build Coastguard Worker {
118*61046927SAndroid Build Coastguard Worker free(gc);
119*61046927SAndroid Build Coastguard Worker return NULL;
120*61046927SAndroid Build Coastguard Worker }
121*61046927SAndroid Build Coastguard Worker
122*61046927SAndroid Build Coastguard Worker return gc;
123*61046927SAndroid Build Coastguard Worker }
124*61046927SAndroid Build Coastguard Worker
125*61046927SAndroid Build Coastguard Worker windowsContext *
windows_create_context_attribs(int pxfi,windowsContext * shared,const int * attribList)126*61046927SAndroid Build Coastguard Worker windows_create_context_attribs(int pxfi, windowsContext *shared, const int *attribList)
127*61046927SAndroid Build Coastguard Worker {
128*61046927SAndroid Build Coastguard Worker windowsContext *gc;
129*61046927SAndroid Build Coastguard Worker
130*61046927SAndroid Build Coastguard Worker gc = calloc(1, sizeof *gc);
131*61046927SAndroid Build Coastguard Worker if (gc == NULL)
132*61046927SAndroid Build Coastguard Worker return NULL;
133*61046927SAndroid Build Coastguard Worker
134*61046927SAndroid Build Coastguard Worker // create a temporary, invisible window
135*61046927SAndroid Build Coastguard Worker #define GL_TEMP_WINDOW_CLASS "glTempWndClass"
136*61046927SAndroid Build Coastguard Worker {
137*61046927SAndroid Build Coastguard Worker static wATOM glTempWndClass = 0;
138*61046927SAndroid Build Coastguard Worker
139*61046927SAndroid Build Coastguard Worker if (glTempWndClass == 0) {
140*61046927SAndroid Build Coastguard Worker WNDCLASSEX wc;
141*61046927SAndroid Build Coastguard Worker wc.cbSize = sizeof(WNDCLASSEX);
142*61046927SAndroid Build Coastguard Worker wc.style = CS_HREDRAW | CS_VREDRAW;
143*61046927SAndroid Build Coastguard Worker wc.lpfnWndProc = DefWindowProc;
144*61046927SAndroid Build Coastguard Worker wc.cbClsExtra = 0;
145*61046927SAndroid Build Coastguard Worker wc.cbWndExtra = 0;
146*61046927SAndroid Build Coastguard Worker wc.hInstance = GetModuleHandle(NULL);
147*61046927SAndroid Build Coastguard Worker wc.hIcon = 0;
148*61046927SAndroid Build Coastguard Worker wc.hCursor = 0;
149*61046927SAndroid Build Coastguard Worker wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
150*61046927SAndroid Build Coastguard Worker wc.lpszMenuName = NULL;
151*61046927SAndroid Build Coastguard Worker wc.lpszClassName = GL_TEMP_WINDOW_CLASS;
152*61046927SAndroid Build Coastguard Worker wc.hIconSm = 0;
153*61046927SAndroid Build Coastguard Worker RegisterClassEx(&wc);
154*61046927SAndroid Build Coastguard Worker }
155*61046927SAndroid Build Coastguard Worker }
156*61046927SAndroid Build Coastguard Worker
157*61046927SAndroid Build Coastguard Worker HWND hwnd = CreateWindowExA(0,
158*61046927SAndroid Build Coastguard Worker GL_TEMP_WINDOW_CLASS,
159*61046927SAndroid Build Coastguard Worker "glWindow",
160*61046927SAndroid Build Coastguard Worker 0,
161*61046927SAndroid Build Coastguard Worker 0, 0, 0, 0,
162*61046927SAndroid Build Coastguard Worker NULL, NULL, GetModuleHandle(NULL), NULL);
163*61046927SAndroid Build Coastguard Worker HDC hdc = GetDC(hwnd);
164*61046927SAndroid Build Coastguard Worker HGLRC shareContext = NULL;
165*61046927SAndroid Build Coastguard Worker if (shared)
166*61046927SAndroid Build Coastguard Worker shareContext = shared->ctx;
167*61046927SAndroid Build Coastguard Worker
168*61046927SAndroid Build Coastguard Worker // We must set the windows pixel format before we can create a WGL context
169*61046927SAndroid Build Coastguard Worker gc->pxfi = pxfi;
170*61046927SAndroid Build Coastguard Worker SetPixelFormat(hdc, gc->pxfi, NULL);
171*61046927SAndroid Build Coastguard Worker
172*61046927SAndroid Build Coastguard Worker gc->ctx = wglCreateContextAttribsARB(hdc, shareContext, attribList);
173*61046927SAndroid Build Coastguard Worker
174*61046927SAndroid Build Coastguard Worker ReleaseDC(hwnd, hdc);
175*61046927SAndroid Build Coastguard Worker DestroyWindow(hwnd);
176*61046927SAndroid Build Coastguard Worker
177*61046927SAndroid Build Coastguard Worker if (!gc->ctx)
178*61046927SAndroid Build Coastguard Worker {
179*61046927SAndroid Build Coastguard Worker free(gc);
180*61046927SAndroid Build Coastguard Worker return NULL;
181*61046927SAndroid Build Coastguard Worker }
182*61046927SAndroid Build Coastguard Worker
183*61046927SAndroid Build Coastguard Worker return gc;
184*61046927SAndroid Build Coastguard Worker }
185*61046927SAndroid Build Coastguard Worker
186*61046927SAndroid Build Coastguard Worker void
windows_destroy_context(windowsContext * context)187*61046927SAndroid Build Coastguard Worker windows_destroy_context(windowsContext *context)
188*61046927SAndroid Build Coastguard Worker {
189*61046927SAndroid Build Coastguard Worker wglDeleteContext(context->ctx);
190*61046927SAndroid Build Coastguard Worker context->ctx = NULL;
191*61046927SAndroid Build Coastguard Worker free(context);
192*61046927SAndroid Build Coastguard Worker }
193*61046927SAndroid Build Coastguard Worker
windows_bind_context(windowsContext * context,windowsDrawable * draw,windowsDrawable * read)194*61046927SAndroid Build Coastguard Worker int windows_bind_context(windowsContext *context, windowsDrawable *draw, windowsDrawable *read)
195*61046927SAndroid Build Coastguard Worker {
196*61046927SAndroid Build Coastguard Worker HDC drawDc = draw->callbacks->getdc(draw);
197*61046927SAndroid Build Coastguard Worker
198*61046927SAndroid Build Coastguard Worker if (!draw->pxfi)
199*61046927SAndroid Build Coastguard Worker {
200*61046927SAndroid Build Coastguard Worker SetPixelFormat(drawDc, context->pxfi, NULL);
201*61046927SAndroid Build Coastguard Worker draw->pxfi = context->pxfi;
202*61046927SAndroid Build Coastguard Worker }
203*61046927SAndroid Build Coastguard Worker
204*61046927SAndroid Build Coastguard Worker if ((read != NULL) && (read != draw))
205*61046927SAndroid Build Coastguard Worker {
206*61046927SAndroid Build Coastguard Worker /*
207*61046927SAndroid Build Coastguard Worker If there is a separate read drawable, create a separate read DC, and
208*61046927SAndroid Build Coastguard Worker use the wglMakeContextCurrent extension to make the context current
209*61046927SAndroid Build Coastguard Worker drawing to one DC and reading from the other
210*61046927SAndroid Build Coastguard Worker
211*61046927SAndroid Build Coastguard Worker Should only occur when WGL_ARB_make_current_read extension is present
212*61046927SAndroid Build Coastguard Worker */
213*61046927SAndroid Build Coastguard Worker HDC readDc = read->callbacks->getdc(read);
214*61046927SAndroid Build Coastguard Worker
215*61046927SAndroid Build Coastguard Worker BOOL ret = wglMakeContextCurrentARB(drawDc, readDc, context->ctx);
216*61046927SAndroid Build Coastguard Worker
217*61046927SAndroid Build Coastguard Worker read->callbacks->releasedc(read, readDc);
218*61046927SAndroid Build Coastguard Worker
219*61046927SAndroid Build Coastguard Worker if (!ret) {
220*61046927SAndroid Build Coastguard Worker printf("wglMakeContextCurrentARB error: %08x\n", (int)GetLastError());
221*61046927SAndroid Build Coastguard Worker return false;
222*61046927SAndroid Build Coastguard Worker }
223*61046927SAndroid Build Coastguard Worker }
224*61046927SAndroid Build Coastguard Worker else
225*61046927SAndroid Build Coastguard Worker {
226*61046927SAndroid Build Coastguard Worker /* Otherwise, just use wglMakeCurrent */
227*61046927SAndroid Build Coastguard Worker BOOL ret = wglMakeCurrent(drawDc, context->ctx);
228*61046927SAndroid Build Coastguard Worker if (!ret) {
229*61046927SAndroid Build Coastguard Worker printf("wglMakeCurrent error: %08x\n", (int)GetLastError());
230*61046927SAndroid Build Coastguard Worker return false;
231*61046927SAndroid Build Coastguard Worker }
232*61046927SAndroid Build Coastguard Worker }
233*61046927SAndroid Build Coastguard Worker
234*61046927SAndroid Build Coastguard Worker draw->callbacks->releasedc(draw, drawDc);
235*61046927SAndroid Build Coastguard Worker
236*61046927SAndroid Build Coastguard Worker windows_glapi_set_dispatch();
237*61046927SAndroid Build Coastguard Worker
238*61046927SAndroid Build Coastguard Worker return true;
239*61046927SAndroid Build Coastguard Worker }
240*61046927SAndroid Build Coastguard Worker
windows_unbind_context(windowsContext * context)241*61046927SAndroid Build Coastguard Worker void windows_unbind_context(windowsContext * context)
242*61046927SAndroid Build Coastguard Worker {
243*61046927SAndroid Build Coastguard Worker wglMakeCurrent(NULL, NULL);
244*61046927SAndroid Build Coastguard Worker }
245*61046927SAndroid Build Coastguard Worker
246*61046927SAndroid Build Coastguard Worker /*
247*61046927SAndroid Build Coastguard Worker *
248*61046927SAndroid Build Coastguard Worker */
249*61046927SAndroid Build Coastguard Worker
250*61046927SAndroid Build Coastguard Worker void
windows_swap_buffers(windowsDrawable * draw)251*61046927SAndroid Build Coastguard Worker windows_swap_buffers(windowsDrawable *draw)
252*61046927SAndroid Build Coastguard Worker {
253*61046927SAndroid Build Coastguard Worker HDC drawDc = GetDC(draw->hWnd);
254*61046927SAndroid Build Coastguard Worker SwapBuffers(drawDc);
255*61046927SAndroid Build Coastguard Worker ReleaseDC(draw->hWnd, drawDc);
256*61046927SAndroid Build Coastguard Worker }
257*61046927SAndroid Build Coastguard Worker
258*61046927SAndroid Build Coastguard Worker
259*61046927SAndroid Build Coastguard Worker typedef void (__stdcall * PFNGLADDSWAPHINTRECTWIN) (GLint x, GLint y,
260*61046927SAndroid Build Coastguard Worker GLsizei width,
261*61046927SAndroid Build Coastguard Worker GLsizei height);
262*61046927SAndroid Build Coastguard Worker
263*61046927SAndroid Build Coastguard Worker static void
glAddSwapHintRectWIN(GLint x,GLint y,GLsizei width,GLsizei height)264*61046927SAndroid Build Coastguard Worker glAddSwapHintRectWIN(GLint x, GLint y, GLsizei width,
265*61046927SAndroid Build Coastguard Worker GLsizei height)
266*61046927SAndroid Build Coastguard Worker {
267*61046927SAndroid Build Coastguard Worker PFNGLADDSWAPHINTRECTWIN proc = (PFNGLADDSWAPHINTRECTWIN)wglGetProcAddress("glAddSwapHintRectWIN");
268*61046927SAndroid Build Coastguard Worker if (proc)
269*61046927SAndroid Build Coastguard Worker proc(x, y, width, height);
270*61046927SAndroid Build Coastguard Worker }
271*61046927SAndroid Build Coastguard Worker
272*61046927SAndroid Build Coastguard Worker void
windows_copy_subbuffer(windowsDrawable * draw,int x,int y,int width,int height)273*61046927SAndroid Build Coastguard Worker windows_copy_subbuffer(windowsDrawable *draw,
274*61046927SAndroid Build Coastguard Worker int x, int y, int width, int height)
275*61046927SAndroid Build Coastguard Worker {
276*61046927SAndroid Build Coastguard Worker glAddSwapHintRectWIN(x, y, width, height);
277*61046927SAndroid Build Coastguard Worker windows_swap_buffers(draw);
278*61046927SAndroid Build Coastguard Worker }
279*61046927SAndroid Build Coastguard Worker
280*61046927SAndroid Build Coastguard Worker /*
281*61046927SAndroid Build Coastguard Worker * Helper function for calling a test function on an initial context
282*61046927SAndroid Build Coastguard Worker */
283*61046927SAndroid Build Coastguard Worker static void
windows_call_with_context(void (* proc)(HDC,void *),void * args)284*61046927SAndroid Build Coastguard Worker windows_call_with_context(void (*proc)(HDC, void *), void *args)
285*61046927SAndroid Build Coastguard Worker {
286*61046927SAndroid Build Coastguard Worker // create window class
287*61046927SAndroid Build Coastguard Worker #define WIN_GL_TEST_WINDOW_CLASS "GLTest"
288*61046927SAndroid Build Coastguard Worker {
289*61046927SAndroid Build Coastguard Worker static wATOM glTestWndClass = 0;
290*61046927SAndroid Build Coastguard Worker
291*61046927SAndroid Build Coastguard Worker if (glTestWndClass == 0) {
292*61046927SAndroid Build Coastguard Worker WNDCLASSEX wc;
293*61046927SAndroid Build Coastguard Worker
294*61046927SAndroid Build Coastguard Worker wc.cbSize = sizeof(WNDCLASSEX);
295*61046927SAndroid Build Coastguard Worker wc.style = CS_HREDRAW | CS_VREDRAW;
296*61046927SAndroid Build Coastguard Worker wc.lpfnWndProc = DefWindowProc;
297*61046927SAndroid Build Coastguard Worker wc.cbClsExtra = 0;
298*61046927SAndroid Build Coastguard Worker wc.cbWndExtra = 0;
299*61046927SAndroid Build Coastguard Worker wc.hInstance = GetModuleHandle(NULL);
300*61046927SAndroid Build Coastguard Worker wc.hIcon = 0;
301*61046927SAndroid Build Coastguard Worker wc.hCursor = 0;
302*61046927SAndroid Build Coastguard Worker wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
303*61046927SAndroid Build Coastguard Worker wc.lpszMenuName = NULL;
304*61046927SAndroid Build Coastguard Worker wc.lpszClassName = WIN_GL_TEST_WINDOW_CLASS;
305*61046927SAndroid Build Coastguard Worker wc.hIconSm = 0;
306*61046927SAndroid Build Coastguard Worker glTestWndClass = RegisterClassEx(&wc);
307*61046927SAndroid Build Coastguard Worker }
308*61046927SAndroid Build Coastguard Worker }
309*61046927SAndroid Build Coastguard Worker
310*61046927SAndroid Build Coastguard Worker // create an invisible window for a scratch DC
311*61046927SAndroid Build Coastguard Worker HWND hwnd = CreateWindowExA(0,
312*61046927SAndroid Build Coastguard Worker WIN_GL_TEST_WINDOW_CLASS,
313*61046927SAndroid Build Coastguard Worker "GL Renderer Capabilities Test Window",
314*61046927SAndroid Build Coastguard Worker 0, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL),
315*61046927SAndroid Build Coastguard Worker NULL);
316*61046927SAndroid Build Coastguard Worker if (hwnd) {
317*61046927SAndroid Build Coastguard Worker HDC hdc = GetDC(hwnd);
318*61046927SAndroid Build Coastguard Worker
319*61046927SAndroid Build Coastguard Worker // we must set a pixel format before we can create a context, just use the first one...
320*61046927SAndroid Build Coastguard Worker SetPixelFormat(hdc, 1, NULL);
321*61046927SAndroid Build Coastguard Worker HGLRC hglrc = wglCreateContext(hdc);
322*61046927SAndroid Build Coastguard Worker wglMakeCurrent(hdc, hglrc);
323*61046927SAndroid Build Coastguard Worker
324*61046927SAndroid Build Coastguard Worker // call the test function
325*61046927SAndroid Build Coastguard Worker proc(hdc, args);
326*61046927SAndroid Build Coastguard Worker
327*61046927SAndroid Build Coastguard Worker // clean up
328*61046927SAndroid Build Coastguard Worker wglMakeCurrent(NULL, NULL);
329*61046927SAndroid Build Coastguard Worker wglDeleteContext(hglrc);
330*61046927SAndroid Build Coastguard Worker ReleaseDC(hwnd, hdc);
331*61046927SAndroid Build Coastguard Worker DestroyWindow(hwnd);
332*61046927SAndroid Build Coastguard Worker }
333*61046927SAndroid Build Coastguard Worker }
334*61046927SAndroid Build Coastguard Worker
335*61046927SAndroid Build Coastguard Worker static void
windows_check_render_test(HDC hdc,void * args)336*61046927SAndroid Build Coastguard Worker windows_check_render_test(HDC hdc, void *args)
337*61046927SAndroid Build Coastguard Worker {
338*61046927SAndroid Build Coastguard Worker int *result = (int *)args;
339*61046927SAndroid Build Coastguard Worker
340*61046927SAndroid Build Coastguard Worker /* Rather than play linkage games using stdcall to ensure we get
341*61046927SAndroid Build Coastguard Worker glGetString from opengl32.dll here, use dlsym */
342*61046927SAndroid Build Coastguard Worker void *dlhandle = windows_get_dl_handle();
343*61046927SAndroid Build Coastguard Worker const char *(*proc)(int) = dlsym(dlhandle, "glGetString");
344*61046927SAndroid Build Coastguard Worker const char *gl_renderer = (const char *)proc(GL_RENDERER);
345*61046927SAndroid Build Coastguard Worker
346*61046927SAndroid Build Coastguard Worker if ((!gl_renderer) || (strcasecmp(gl_renderer, "GDI Generic") == 0))
347*61046927SAndroid Build Coastguard Worker *result = false;
348*61046927SAndroid Build Coastguard Worker else
349*61046927SAndroid Build Coastguard Worker *result = true;
350*61046927SAndroid Build Coastguard Worker }
351*61046927SAndroid Build Coastguard Worker
352*61046927SAndroid Build Coastguard Worker int
windows_check_renderer(void)353*61046927SAndroid Build Coastguard Worker windows_check_renderer(void)
354*61046927SAndroid Build Coastguard Worker {
355*61046927SAndroid Build Coastguard Worker int result;
356*61046927SAndroid Build Coastguard Worker windows_call_with_context(windows_check_render_test, &result);
357*61046927SAndroid Build Coastguard Worker return result;
358*61046927SAndroid Build Coastguard Worker }
359*61046927SAndroid Build Coastguard Worker
360*61046927SAndroid Build Coastguard Worker typedef struct {
361*61046927SAndroid Build Coastguard Worker char *gl_extensions;
362*61046927SAndroid Build Coastguard Worker char *wgl_extensions;
363*61046927SAndroid Build Coastguard Worker } windows_extensions_result;
364*61046927SAndroid Build Coastguard Worker
365*61046927SAndroid Build Coastguard Worker static void
windows_extensions_test(HDC hdc,void * args)366*61046927SAndroid Build Coastguard Worker windows_extensions_test(HDC hdc, void *args)
367*61046927SAndroid Build Coastguard Worker {
368*61046927SAndroid Build Coastguard Worker windows_extensions_result *r = (windows_extensions_result *)args;
369*61046927SAndroid Build Coastguard Worker
370*61046927SAndroid Build Coastguard Worker void *dlhandle = windows_get_dl_handle();
371*61046927SAndroid Build Coastguard Worker const char *(*proc)(int) = dlsym(dlhandle, "glGetString");
372*61046927SAndroid Build Coastguard Worker
373*61046927SAndroid Build Coastguard Worker r->gl_extensions = strdup(proc(GL_EXTENSIONS));
374*61046927SAndroid Build Coastguard Worker
375*61046927SAndroid Build Coastguard Worker wglResolveExtensionProcs();
376*61046927SAndroid Build Coastguard Worker r->wgl_extensions = strdup(wglGetExtensionsStringARB(hdc));
377*61046927SAndroid Build Coastguard Worker }
378*61046927SAndroid Build Coastguard Worker
379*61046927SAndroid Build Coastguard Worker void
windows_extensions(char ** gl_extensions,char ** wgl_extensions)380*61046927SAndroid Build Coastguard Worker windows_extensions(char **gl_extensions, char **wgl_extensions)
381*61046927SAndroid Build Coastguard Worker {
382*61046927SAndroid Build Coastguard Worker windows_extensions_result result;
383*61046927SAndroid Build Coastguard Worker
384*61046927SAndroid Build Coastguard Worker *gl_extensions = "";
385*61046927SAndroid Build Coastguard Worker *wgl_extensions = "";
386*61046927SAndroid Build Coastguard Worker
387*61046927SAndroid Build Coastguard Worker windows_call_with_context(windows_extensions_test, &result);
388*61046927SAndroid Build Coastguard Worker
389*61046927SAndroid Build Coastguard Worker *gl_extensions = result.gl_extensions;
390*61046927SAndroid Build Coastguard Worker *wgl_extensions = result.wgl_extensions;
391*61046927SAndroid Build Coastguard Worker }
392