stw: use proper stw_context pointers in shared interface
[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 struct stw_context *ctx_head = NULL;
44
45 static HDC current_hdc = NULL;
46 static struct stw_context *current_hrc = NULL;
47
48 BOOL
49 stw_copy_context(
50 struct stw_context *src,
51 struct stw_context *dst,
52 UINT mask )
53 {
54 (void) src;
55 (void) dst;
56 (void) mask;
57
58 return FALSE;
59 }
60
61 struct stw_context *
62 stw_create_context(
63 HDC hdc,
64 int iLayerPlane )
65 {
66 uint pfi;
67 const struct pixelformat_info *pf = NULL;
68 struct stw_context *ctx = NULL;
69 GLvisual *visual = NULL;
70 struct pipe_context *pipe = NULL;
71
72 if (iLayerPlane != 0)
73 return NULL;
74
75 pfi = stw_pixelformat_get( hdc );
76 if (pfi == 0)
77 return NULL;
78
79 pf = pixelformat_get_info( pfi - 1 );
80
81 ctx = CALLOC_STRUCT( stw_context );
82 if (ctx == NULL)
83 return NULL;
84
85 ctx->hdc = hdc;
86 ctx->color_bits = GetDeviceCaps( ctx->hdc, BITSPIXEL );
87
88 /* Create visual based on flags
89 */
90 visual = _mesa_create_visual(
91 GL_TRUE,
92 (pf->flags & PF_FLAG_DOUBLEBUFFER) ? GL_TRUE : GL_FALSE,
93 GL_FALSE,
94 pf->color.redbits,
95 pf->color.greenbits,
96 pf->color.bluebits,
97 pf->alpha.alphabits,
98 0,
99 pf->depth.depthbits,
100 pf->depth.stencilbits,
101 0,
102 0,
103 0,
104 0,
105 (pf->flags & PF_FLAG_MULTISAMPLED) ? stw_query_samples() : 0 );
106 if (visual == NULL)
107 goto fail;
108
109 pipe = stw_dev->stw_winsys->create_context( stw_dev->screen );
110 if (pipe == NULL)
111 goto fail;
112
113 assert(!pipe->priv);
114 pipe->priv = hdc;
115
116 ctx->st = st_create_context( pipe, visual, NULL );
117 if (ctx->st == NULL)
118 goto fail;
119
120 ctx->st->ctx->DriverCtx = ctx;
121
122 ctx->next = ctx_head;
123 ctx_head = ctx;
124
125 return ctx;
126
127 fail:
128 if (visual)
129 _mesa_destroy_visual( visual );
130
131 if (pipe)
132 pipe->destroy( pipe );
133
134 FREE( ctx );
135 return NULL;
136 }
137
138
139 BOOL
140 stw_delete_context(
141 struct stw_context *hglrc )
142 {
143 struct stw_context **link = &ctx_head;
144 struct stw_context *ctx = ctx_head;
145
146 while (ctx != NULL) {
147 if (ctx == hglrc) {
148 GLcontext *glctx = ctx->st->ctx;
149 GET_CURRENT_CONTEXT( glcurctx );
150 struct stw_framebuffer *fb;
151
152 /* Unbind current if deleting current context.
153 */
154 if (glcurctx == glctx)
155 st_make_current( NULL, NULL, NULL );
156
157 fb = framebuffer_from_hdc( ctx->hdc );
158 if (fb)
159 framebuffer_destroy( fb );
160
161 if (WindowFromDC( ctx->hdc ) != NULL)
162 ReleaseDC( WindowFromDC( ctx->hdc ), ctx->hdc );
163
164 st_destroy_context( ctx->st );
165
166 *link = ctx->next;
167 FREE( ctx );
168 return TRUE;
169 }
170
171 link = &ctx->next;
172 ctx = ctx->next;
173 }
174
175 return FALSE;
176 }
177
178 /* Find the width and height of the window named by hdc.
179 */
180 static void
181 get_window_size( HDC hdc, GLuint *width, GLuint *height )
182 {
183 if (WindowFromDC( hdc )) {
184 RECT rect;
185
186 GetClientRect( WindowFromDC( hdc ), &rect );
187 *width = rect.right - rect.left;
188 *height = rect.bottom - rect.top;
189 }
190 else {
191 *width = GetDeviceCaps( hdc, HORZRES );
192 *height = GetDeviceCaps( hdc, VERTRES );
193 }
194 }
195
196 struct stw_context *
197 stw_get_current_context( void )
198 {
199 return current_hrc;
200 }
201
202 HDC
203 stw_get_current_dc( void )
204 {
205 return current_hdc;
206 }
207
208 BOOL
209 stw_make_current(
210 HDC hdc,
211 struct stw_context *hglrc )
212 {
213 struct stw_context *ctx = ctx_head;
214 GET_CURRENT_CONTEXT( glcurctx );
215 struct stw_framebuffer *fb;
216 GLuint width = 0;
217 GLuint height = 0;
218
219 current_hdc = hdc;
220 current_hrc = hglrc;
221
222 if (hdc == NULL || hglrc == NULL) {
223 st_make_current( NULL, NULL, NULL );
224 return TRUE;
225 }
226
227 while (ctx != NULL) {
228 if (ctx == hglrc)
229 break;
230 ctx = ctx->next;
231 }
232 if (ctx == NULL)
233 return FALSE;
234
235 /* Return if already current.
236 */
237 if (glcurctx != NULL) {
238 struct stw_context *curctx = (struct stw_context *) glcurctx->DriverCtx;
239
240 if (curctx != NULL && curctx == ctx && ctx->hdc == hdc)
241 return TRUE;
242 }
243
244 fb = framebuffer_from_hdc( hdc );
245
246 if (hdc != NULL)
247 get_window_size( hdc, &width, &height );
248
249 /* Lazy creation of framebuffers.
250 */
251 if (fb == NULL && ctx != NULL && hdc != NULL) {
252 GLvisual *visual = &ctx->st->ctx->Visual;
253
254 fb = framebuffer_create( hdc, visual, width, height );
255 if (fb == NULL)
256 return FALSE;
257
258 fb->dib_hDC = CreateCompatibleDC( hdc );
259 fb->hbmDIB = NULL;
260 fb->pbPixels = NULL;
261 }
262
263 if (ctx && fb) {
264 st_make_current( ctx->st, fb->stfb, fb->stfb );
265 framebuffer_resize( fb, width, height );
266 ctx->hdc = hdc;
267 ctx->st->pipe->priv = hdc;
268 }
269 else {
270 /* Detach */
271 st_make_current( NULL, NULL, NULL );
272 }
273
274 return TRUE;
275 }
276
277 struct stw_context *
278 stw_context_from_hdc(
279 HDC hdc )
280 {
281 struct stw_context *ctx = ctx_head;
282
283 while (ctx != NULL) {
284 if (ctx->hdc == hdc)
285 return ctx;
286 ctx = ctx->next;
287 }
288 return NULL;
289 }
290
291
292