2 * Mesa 3-D graphics library
4 * Copyright (C) 2011 Morgan Armand <morgan.devel@gmail.com>
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
28 #define WGL_WGLEXT_PROTOTYPES
31 #include <GL/wglext.h>
34 #include "stw_context.h"
35 #include "stw_device.h"
36 #include "stw_ext_context.h"
38 #include "util/u_debug.h"
41 wglCreateContext_t wglCreateContext_func
= 0;
42 wglDeleteContext_t wglDeleteContext_func
= 0;
46 * The implementation of this function is tricky. The OPENGL32.DLL library
47 * remaps the context IDs returned by our stw_create_context_attribs()
48 * function to different values returned to the caller of wglCreateContext().
49 * That is, DHGLRC (driver) handles are not equivalent to HGLRC (public)
52 * So we need to generate a new HGLRC ID here. We do that by calling
53 * the regular wglCreateContext() function. Then, we replace the newly-
54 * created stw_context with a new stw_context that reflects the arguments
58 wglCreateContextAttribsARB(HDC hDC
, HGLRC hShareContext
, const int *attribList
)
62 int majorVersion
= 1, minorVersion
= 0, layerPlane
= 0;
63 int contextFlags
= 0x0;
64 int profileMask
= WGL_CONTEXT_CORE_PROFILE_BIT_ARB
;
67 const int contextFlagsAll
= (WGL_CONTEXT_DEBUG_BIT_ARB
|
68 WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
);
70 /* parse attrib_list */
72 for (i
= 0; !done
&& attribList
[i
]; i
++) {
73 switch (attribList
[i
]) {
74 case WGL_CONTEXT_MAJOR_VERSION_ARB
:
75 majorVersion
= attribList
[++i
];
77 case WGL_CONTEXT_MINOR_VERSION_ARB
:
78 minorVersion
= attribList
[++i
];
80 case WGL_CONTEXT_LAYER_PLANE_ARB
:
81 layerPlane
= attribList
[++i
];
83 case WGL_CONTEXT_FLAGS_ARB
:
84 contextFlags
= attribList
[++i
];
86 case WGL_CONTEXT_PROFILE_MASK_ARB
:
87 profileMask
= attribList
[++i
];
95 SetLastError(ERROR_INVALID_PARAMETER
);
101 /* check contextFlags */
102 if (contextFlags
& ~contextFlagsAll
) {
103 SetLastError(ERROR_INVALID_PARAMETER
);
107 /* check profileMask */
108 if (profileMask
!= WGL_CONTEXT_CORE_PROFILE_BIT_ARB
&&
109 profileMask
!= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB
&&
110 profileMask
!= WGL_CONTEXT_ES_PROFILE_BIT_EXT
) {
111 SetLastError(ERROR_INVALID_PROFILE_ARB
);
115 /* check version (generate ERROR_INVALID_VERSION_ARB if bad) */
116 if (majorVersion
<= 0 ||
118 (profileMask
!= WGL_CONTEXT_ES_PROFILE_BIT_EXT
&&
119 ((majorVersion
== 1 && minorVersion
> 5) ||
120 (majorVersion
== 2 && minorVersion
> 1) ||
121 (majorVersion
== 3 && minorVersion
> 3) ||
122 (majorVersion
== 4 && minorVersion
> 5) ||
123 majorVersion
> 4)) ||
124 (profileMask
== WGL_CONTEXT_ES_PROFILE_BIT_EXT
&&
125 ((majorVersion
== 1 && minorVersion
> 1) ||
126 (majorVersion
== 2 && minorVersion
> 0) ||
127 (majorVersion
== 3 && minorVersion
> 1) ||
128 majorVersion
> 3))) {
129 SetLastError(ERROR_INVALID_VERSION_ARB
);
133 if ((contextFlags
& WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
) &&
135 SetLastError(ERROR_INVALID_VERSION_ARB
);
139 /* Get pointer to OPENGL32.DLL's wglCreate/DeleteContext() functions */
140 if (!wglCreateContext_func
|| !wglDeleteContext_func
) {
141 /* Get the OPENGL32.DLL library */
142 HMODULE opengl_lib
= GetModuleHandleA("opengl32.dll");
144 _debug_printf("wgl: GetModuleHandleA(\"opengl32.dll\") failed\n");
148 /* Get pointer to wglCreateContext() function */
149 wglCreateContext_func
= (wglCreateContext_t
)
150 GetProcAddress(opengl_lib
, "wglCreateContext");
151 if (!wglCreateContext_func
) {
152 _debug_printf("wgl: failed to get wglCreateContext()\n");
156 /* Get pointer to wglDeleteContext() function */
157 wglDeleteContext_func
= (wglDeleteContext_t
)
158 GetProcAddress(opengl_lib
, "wglDeleteContext");
159 if (!wglDeleteContext_func
) {
160 _debug_printf("wgl: failed to get wglDeleteContext()\n");
165 /* Call wglCreateContext to get a valid context ID */
166 context
= wglCreateContext_func(hDC
);
169 /* Now replace the context we just created with a new one that reflects
170 * the attributes passed to this function.
172 DHGLRC dhglrc
, c
, share_dhglrc
= 0;
174 /* Convert public HGLRC to driver DHGLRC */
175 if (stw_dev
&& stw_dev
->callbacks
.pfnGetDhglrc
) {
176 dhglrc
= stw_dev
->callbacks
.pfnGetDhglrc(context
);
178 share_dhglrc
= stw_dev
->callbacks
.pfnGetDhglrc(hShareContext
);
182 dhglrc
= (DHGLRC
)(INT_PTR
)context
;
183 share_dhglrc
= (DHGLRC
)(INT_PTR
)hShareContext
;
186 c
= stw_create_context_attribs(hDC
, layerPlane
, share_dhglrc
,
187 majorVersion
, minorVersion
,
188 contextFlags
, profileMask
,
191 wglDeleteContext_func(context
);
200 /** Defined by WGL_ARB_make_current_read */
202 wglMakeContextCurrentARB(HDC hDrawDC
, HDC hReadDC
, HGLRC hglrc
)
206 if (stw_dev
&& stw_dev
->callbacks
.pfnGetDhglrc
) {
207 /* Convert HGLRC to DHGLRC */
208 dhglrc
= stw_dev
->callbacks
.pfnGetDhglrc(hglrc
);
211 return stw_make_current(hDrawDC
, hReadDC
, dhglrc
);