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"
39 wglCreateContext_t wglCreateContext_func
= 0;
40 wglDeleteContext_t wglDeleteContext_func
= 0;
44 * The implementation of this function is tricky. The OPENGL32.DLL library
45 * remaps the context IDs returned by our stw_create_context_attribs()
46 * function to different values returned to the caller of wglCreateContext().
47 * That is, DHGLRC (driver) handles are not equivalent to HGLRC (public)
50 * So we need to generate a new HGLRC ID here. We do that by calling
51 * the regular wglCreateContext() function. Then, we replace the newly-
52 * created stw_context with a new stw_context that reflects the arguments
56 wglCreateContextAttribsARB(HDC hDC
, HGLRC hShareContext
, const int *attribList
)
60 int majorVersion
= 1, minorVersion
= 0, layerPlane
= 0;
61 int contextFlags
= 0x0;
62 int profileMask
= WGL_CONTEXT_CORE_PROFILE_BIT_ARB
;
65 const int contextFlagsAll
= (WGL_CONTEXT_DEBUG_BIT_ARB
|
66 WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
);
68 /* parse attrib_list */
70 for (i
= 0; !done
&& attribList
[i
]; i
++) {
71 switch (attribList
[i
]) {
72 case WGL_CONTEXT_MAJOR_VERSION_ARB
:
73 majorVersion
= attribList
[++i
];
75 case WGL_CONTEXT_MINOR_VERSION_ARB
:
76 minorVersion
= attribList
[++i
];
78 case WGL_CONTEXT_LAYER_PLANE_ARB
:
79 layerPlane
= attribList
[++i
];
81 case WGL_CONTEXT_FLAGS_ARB
:
82 contextFlags
= attribList
[++i
];
84 case WGL_CONTEXT_PROFILE_MASK_ARB
:
85 profileMask
= attribList
[++i
];
93 SetLastError(ERROR_INVALID_PARAMETER
);
99 /* check contextFlags */
100 if (contextFlags
& ~contextFlagsAll
) {
101 SetLastError(ERROR_INVALID_PARAMETER
);
105 /* check profileMask */
106 if (profileMask
!= WGL_CONTEXT_CORE_PROFILE_BIT_ARB
&&
107 profileMask
!= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB
&&
108 profileMask
!= WGL_CONTEXT_ES_PROFILE_BIT_EXT
) {
109 SetLastError(ERROR_INVALID_PROFILE_ARB
);
113 /* check version (generate ERROR_INVALID_VERSION_ARB if bad) */
114 if (majorVersion
<= 0 ||
116 (profileMask
!= WGL_CONTEXT_ES_PROFILE_BIT_EXT
&&
117 ((majorVersion
== 1 && minorVersion
> 5) ||
118 (majorVersion
== 2 && minorVersion
> 1) ||
119 (majorVersion
== 3 && minorVersion
> 3) ||
120 (majorVersion
== 4 && minorVersion
> 5) ||
121 majorVersion
> 4)) ||
122 (profileMask
== WGL_CONTEXT_ES_PROFILE_BIT_EXT
&&
123 ((majorVersion
== 1 && minorVersion
> 1) ||
124 (majorVersion
== 2 && minorVersion
> 0) ||
125 (majorVersion
== 3 && minorVersion
> 1) ||
126 majorVersion
> 3))) {
127 SetLastError(ERROR_INVALID_VERSION_ARB
);
131 if ((contextFlags
& WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
) &&
133 SetLastError(ERROR_INVALID_VERSION_ARB
);
137 /* Get pointer to OPENGL32.DLL's wglCreate/DeleteContext() functions */
138 if (!wglCreateContext_func
|| !wglDeleteContext_func
) {
139 /* Get the OPENGL32.DLL library */
140 HMODULE opengl_lib
= GetModuleHandleA("opengl32.dll");
142 _debug_printf("wgl: GetModuleHandleA(\"opengl32.dll\") failed\n");
146 /* Get pointer to wglCreateContext() function */
147 wglCreateContext_func
= (wglCreateContext_t
)
148 GetProcAddress(opengl_lib
, "wglCreateContext");
149 if (!wglCreateContext_func
) {
150 _debug_printf("wgl: failed to get wglCreateContext()\n");
154 /* Get pointer to wglDeleteContext() function */
155 wglDeleteContext_func
= (wglDeleteContext_t
)
156 GetProcAddress(opengl_lib
, "wglDeleteContext");
157 if (!wglDeleteContext_func
) {
158 _debug_printf("wgl: failed to get wglDeleteContext()\n");
163 /* Call wglCreateContext to get a valid context ID */
164 context
= wglCreateContext_func(hDC
);
167 /* Now replace the context we just created with a new one that reflects
168 * the attributes passed to this function.
170 DHGLRC dhglrc
, c
, share_dhglrc
= 0;
172 /* Convert public HGLRC to driver DHGLRC */
173 if (stw_dev
&& stw_dev
->callbacks
.wglCbGetDhglrc
) {
174 dhglrc
= stw_dev
->callbacks
.wglCbGetDhglrc(context
);
176 share_dhglrc
= stw_dev
->callbacks
.wglCbGetDhglrc(hShareContext
);
180 dhglrc
= (DHGLRC
) context
;
181 share_dhglrc
= (DHGLRC
) hShareContext
;
184 c
= stw_create_context_attribs(hDC
, layerPlane
, share_dhglrc
,
185 majorVersion
, minorVersion
,
186 contextFlags
, profileMask
,
189 wglDeleteContext_func(context
);