stw: fix uninitialized variable issue
[mesa.git] / src / gallium / state_trackers / wgl / shared / stw_context.c
1 /**************************************************************************
2 *
3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include <windows.h>
29
30 #include "main/mtypes.h"
31 #include "main/context.h"
32 #include "pipe/p_compiler.h"
33 #include "pipe/p_context.h"
34 #include "state_tracker/st_context.h"
35 #include "state_tracker/st_public.h"
36 #include "shared/stw_device.h"
37 #include "shared/stw_winsys.h"
38 #include "shared/stw_framebuffer.h"
39 #include "shared/stw_pixelformat.h"
40 #include "stw_public.h"
41 #include "stw_context.h"
42
43 static HDC current_hdc = NULL;
44 static UINT_PTR current_hglrc = 0;
45
46 BOOL
47 stw_copy_context(
48 UINT_PTR hglrcSrc,
49 UINT_PTR hglrcDst,
50 UINT mask )
51 {
52 struct stw_context *src;
53 struct stw_context *dst;
54 BOOL ret = FALSE;
55
56 pipe_mutex_lock( stw_dev->mutex );
57
58 src = stw_lookup_context( hglrcSrc );
59 dst = stw_lookup_context( hglrcDst );
60
61 if (src && dst) {
62 /* FIXME */
63 (void) src;
64 (void) dst;
65 (void) mask;
66 }
67
68 pipe_mutex_unlock( stw_dev->mutex );
69
70 return ret;
71 }
72
73 UINT_PTR
74 stw_create_layer_context(
75 HDC hdc,
76 int iLayerPlane )
77 {
78 uint pfi;
79 const struct pixelformat_info *pf = NULL;
80 struct stw_context *ctx = NULL;
81 GLvisual *visual = NULL;
82 struct pipe_context *pipe = NULL;
83 UINT_PTR hglrc = 0;
84
85 if(!stw_dev)
86 return 0;
87
88 if (iLayerPlane != 0)
89 return 0;
90
91 pfi = stw_pixelformat_get( hdc );
92 if (pfi == 0)
93 return 0;
94
95 pf = pixelformat_get_info( pfi - 1 );
96
97 ctx = CALLOC_STRUCT( stw_context );
98 if (ctx == NULL)
99 return 0;
100
101 ctx->hdc = hdc;
102 ctx->color_bits = GetDeviceCaps( ctx->hdc, BITSPIXEL );
103
104 /* Create visual based on flags
105 */
106 visual = _mesa_create_visual(
107 GL_TRUE,
108 (pf->flags & PF_FLAG_DOUBLEBUFFER) ? GL_TRUE : GL_FALSE,
109 GL_FALSE,
110 pf->color.redbits,
111 pf->color.greenbits,
112 pf->color.bluebits,
113 pf->alpha.alphabits,
114 0,
115 pf->depth.depthbits,
116 pf->depth.stencilbits,
117 0,
118 0,
119 0,
120 0,
121 (pf->flags & PF_FLAG_MULTISAMPLED) ? stw_query_samples() : 0 );
122 if (visual == NULL)
123 goto fail;
124
125 pipe = stw_dev->stw_winsys->create_context( stw_dev->screen );
126 if (pipe == NULL)
127 goto fail;
128
129 assert(!pipe->priv);
130 pipe->priv = hdc;
131
132 ctx->st = st_create_context( pipe, visual, NULL );
133 if (ctx->st == NULL)
134 goto fail;
135
136 ctx->st->ctx->DriverCtx = ctx;
137
138 pipe_mutex_lock( stw_dev->mutex );
139 {
140 UINT_PTR i;
141
142 for (i = 0; i < STW_CONTEXT_MAX; i++) {
143 if (stw_dev->ctx_array[i].ctx == NULL) {
144 /* success:
145 */
146 stw_dev->ctx_array[i].ctx = ctx;
147 hglrc = i + 1;
148 break;
149 }
150 }
151 }
152 pipe_mutex_unlock( stw_dev->mutex );
153
154 /* Success?
155 */
156 if (hglrc != 0)
157 return hglrc;
158
159 fail:
160 if (visual)
161 _mesa_destroy_visual( visual );
162
163 if (pipe)
164 pipe->destroy( pipe );
165
166 FREE( ctx );
167 return 0;
168 }
169
170 BOOL
171 stw_delete_context(
172 UINT_PTR hglrc )
173 {
174 struct stw_context *ctx ;
175 BOOL ret = FALSE;
176
177 if (!stw_dev)
178 return FALSE;
179
180 pipe_mutex_lock( stw_dev->mutex );
181
182 ctx = stw_lookup_context(hglrc);
183 if (ctx) {
184 GLcontext *glctx = ctx->st->ctx;
185 GET_CURRENT_CONTEXT( glcurctx );
186 struct stw_framebuffer *fb;
187
188 /* Unbind current if deleting current context.
189 */
190 if (glcurctx == glctx)
191 st_make_current( NULL, NULL, NULL );
192
193 fb = framebuffer_from_hdc( ctx->hdc );
194 if (fb)
195 framebuffer_destroy( fb );
196
197 if (WindowFromDC( ctx->hdc ) != NULL)
198 ReleaseDC( WindowFromDC( ctx->hdc ), ctx->hdc );
199
200 st_destroy_context( ctx->st );
201
202 FREE( ctx );
203
204 stw_dev->ctx_array[hglrc - 1].ctx = NULL;
205
206 ret = TRUE;
207 }
208
209 pipe_mutex_unlock( stw_dev->mutex );
210
211 return ret;
212 }
213
214 BOOL
215 stw_release_context(
216 UINT_PTR hglrc )
217 {
218 BOOL ret = FALSE;
219
220 if (!stw_dev)
221 return ret;
222
223 pipe_mutex_lock( stw_dev->mutex );
224 {
225 struct stw_context *ctx;
226
227 /* XXX: The expectation is that ctx is the same context which is
228 * current for this thread. We should check that and return False
229 * if not the case.
230 */
231 ctx = stw_lookup_context( hglrc );
232 if (ctx == NULL)
233 goto done;
234
235 if (stw_make_current( NULL, 0 ) == FALSE)
236 goto done;
237
238 ret = TRUE;
239 }
240 done:
241 pipe_mutex_unlock( stw_dev->mutex );
242
243 return ret;
244 }
245
246 /* Find the width and height of the window named by hdc.
247 */
248 static void
249 get_window_size( HDC hdc, GLuint *width, GLuint *height )
250 {
251 if (WindowFromDC( hdc )) {
252 RECT rect;
253
254 GetClientRect( WindowFromDC( hdc ), &rect );
255 *width = rect.right - rect.left;
256 *height = rect.bottom - rect.top;
257 }
258 else {
259 *width = GetDeviceCaps( hdc, HORZRES );
260 *height = GetDeviceCaps( hdc, VERTRES );
261 }
262 }
263
264 UINT_PTR
265 stw_get_current_context( void )
266 {
267 return current_hglrc;
268 }
269
270 HDC
271 stw_get_current_dc( void )
272 {
273 return current_hdc;
274 }
275
276 BOOL
277 stw_make_current(
278 HDC hdc,
279 UINT_PTR hglrc )
280 {
281 struct stw_context *ctx;
282 GET_CURRENT_CONTEXT( glcurctx );
283 struct stw_framebuffer *fb;
284 GLuint width = 0;
285 GLuint height = 0;
286
287 if (!stw_dev)
288 return FALSE;
289
290 pipe_mutex_lock( stw_dev->mutex );
291 ctx = stw_lookup_context( hglrc );
292 pipe_mutex_unlock( stw_dev->mutex );
293
294 if (ctx == NULL)
295 return FALSE;
296
297 current_hdc = hdc;
298 current_hglrc = hglrc;
299
300 if (hdc == NULL || hglrc == 0) {
301 st_make_current( NULL, NULL, NULL );
302 return TRUE;
303 }
304
305 /* Return if already current.
306 */
307 if (glcurctx != NULL) {
308 struct stw_context *curctx = (struct stw_context *) glcurctx->DriverCtx;
309
310 if (curctx != NULL && curctx == ctx && ctx->hdc == hdc)
311 return TRUE;
312 }
313
314 fb = framebuffer_from_hdc( hdc );
315
316 if (hdc != NULL)
317 get_window_size( hdc, &width, &height );
318
319 /* Lazy creation of framebuffers.
320 */
321 if (fb == NULL && ctx != NULL && hdc != NULL) {
322 GLvisual *visual = &ctx->st->ctx->Visual;
323
324 fb = framebuffer_create( hdc, visual, width, height );
325 if (fb == NULL)
326 return FALSE;
327
328 fb->dib_hDC = CreateCompatibleDC( hdc );
329 fb->hbmDIB = NULL;
330 fb->pbPixels = NULL;
331 }
332
333 if (ctx && fb) {
334 st_make_current( ctx->st, fb->stfb, fb->stfb );
335 framebuffer_resize( fb, width, height );
336 ctx->hdc = hdc;
337 ctx->st->pipe->priv = hdc;
338 }
339 else {
340 /* Detach */
341 st_make_current( NULL, NULL, NULL );
342 }
343
344 return TRUE;
345 }