Initial revision
[mesa.git] / src / mesa / drivers / windows / wgl.c
1 /* $Id: wgl.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
2
3 /*
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *
18 */
19
20 /*
21 * File name : wgl.c
22 * WGL stuff. Added by Oleg Letsinsky, ajl@ultersys.ru
23 * Some things originated from the 3Dfx WGL functions
24 */
25
26 #ifdef WIN32
27
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31
32 #include <windows.h>
33
34 #include <GL/gl.h>
35 #include <GL/glu.h>
36
37 #ifdef __cplusplus
38 }
39 #endif
40
41 #include <stdio.h>
42 #include <tchar.h>
43 #include "wmesadef.h"
44 #include "GL/wmesa.h"
45 #include "types.h"
46
47 #define MAX_MESA_ATTRS 20
48
49 struct __extensions__
50 {
51 PROC proc;
52 char *name;
53 };
54
55 struct __pixelformat__
56 {
57 PIXELFORMATDESCRIPTOR pfd;
58 GLboolean doubleBuffered;
59 };
60
61 struct __extensions__ ext[] = {
62
63 #ifdef GL_EXT_polygon_offset
64 { (PROC)glPolygonOffsetEXT, "glPolygonOffsetEXT" },
65 #endif
66 { (PROC)glBlendEquationEXT, "glBlendEquationEXT" },
67 { (PROC)glBlendColorEXT, "glBlendColorExt" },
68 { (PROC)glVertexPointerEXT, "glVertexPointerEXT" },
69 { (PROC)glNormalPointerEXT, "glNormalPointerEXT" },
70 { (PROC)glColorPointerEXT, "glColorPointerEXT" },
71 { (PROC)glIndexPointerEXT, "glIndexPointerEXT" },
72 { (PROC)glTexCoordPointerEXT, "glTexCoordPointer" },
73 { (PROC)glEdgeFlagPointerEXT, "glEdgeFlagPointerEXT" },
74 { (PROC)glGetPointervEXT, "glGetPointervEXT" },
75 { (PROC)glArrayElementEXT, "glArrayElementEXT" },
76 { (PROC)glDrawArraysEXT, "glDrawArrayEXT" },
77 { (PROC)glAreTexturesResidentEXT, "glAreTexturesResidentEXT" },
78 { (PROC)glBindTextureEXT, "glBindTextureEXT" },
79 { (PROC)glDeleteTexturesEXT, "glDeleteTexturesEXT" },
80 { (PROC)glGenTexturesEXT, "glGenTexturesEXT" },
81 { (PROC)glIsTextureEXT, "glIsTextureEXT" },
82 { (PROC)glPrioritizeTexturesEXT, "glPrioritizeTexturesEXT" },
83 { (PROC)glCopyTexSubImage3DEXT, "glCopyTexSubImage3DEXT" },
84 { (PROC)glTexImage3DEXT, "glTexImage3DEXT" },
85 { (PROC)glTexSubImage3DEXT, "glTexSubImage3DEXT" },
86 { (PROC)glColorTableEXT, "glColorTableEXT" },
87 { (PROC)glColorSubTableEXT, "glColorSubTableEXT" },
88 { (PROC)glGetColorTableEXT, "glGetColorTableEXT" },
89 { (PROC)glGetColorTableParameterfvEXT, "glGetColorTableParameterfvEXT" },
90 { (PROC)glGetColorTableParameterivEXT, "glGetColorTableParameterivEXT" },
91 { (PROC)glPointParameterfEXT, "glPointParameterfEXT" },
92 { (PROC)glPointParameterfvEXT, "glPointParameterfvEXT" },
93 { (PROC)glBlendFuncSeparateINGR, "glBlendFuncSeparateINGR" },
94 { (PROC)glLockArraysEXT, "glLockArraysEXT" },
95 { (PROC)glUnlockArraysEXT, "glUnlockArraysEXT" }
96 };
97
98 int qt_ext = sizeof(ext) / sizeof(ext[0]);
99
100 struct __pixelformat__ pix[] =
101 {
102 { { sizeof(PIXELFORMATDESCRIPTOR), 1,
103 PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
104 PFD_TYPE_RGBA,
105 24, 8, 0, 8, 8, 8, 16, 8, 24,
106 0, 0, 0, 0, 0, 16, 8, 0, 0, 0, 0, 0, 0 },
107 GL_TRUE
108 },
109 { { sizeof(PIXELFORMATDESCRIPTOR), 1,
110 PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_GENERIC_FORMAT,
111 PFD_TYPE_RGBA,
112 24, 8, 0, 8, 8, 8, 16, 8, 24,
113 0, 0, 0, 0, 0, 16, 8, 0, 0, 0, 0, 0, 0 },
114 GL_FALSE
115 },
116 };
117
118 int qt_pix = sizeof(pix) / sizeof(pix[0]);
119
120 typedef struct {
121 WMesaContext ctx;
122 HDC hdc;
123 } MesaWglCtx;
124
125 #define MESAWGL_CTX_MAX_COUNT 20
126
127 static MesaWglCtx wgl_ctx[MESAWGL_CTX_MAX_COUNT];
128
129 static unsigned ctx_count = 0;
130 static unsigned ctx_current = -1;
131 static unsigned curPFD = 0;
132
133 GLAPI BOOL GLWINAPI wglCopyContext(HGLRC hglrcSrc,HGLRC hglrcDst,UINT mask)
134 {
135 return(FALSE);
136 }
137
138 GLAPI HGLRC GLWINAPI wglCreateContext(HDC hdc)
139 {
140 HWND hWnd;
141 int i = 0;
142 if(!(hWnd = WindowFromDC(hdc)))
143 {
144 SetLastError(0);
145 return(NULL);
146 }
147 if (!ctx_count)
148 {
149 for(i=0;i<MESAWGL_CTX_MAX_COUNT;i++)
150 {
151 wgl_ctx[i].ctx = NULL;
152 wgl_ctx[i].hdc = NULL;
153 }
154 }
155 for( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ )
156 {
157 if ( wgl_ctx[i].ctx == NULL )
158 {
159 wgl_ctx[i].ctx = WMesaCreateContext( hWnd, NULL, GL_TRUE,
160 pix[curPFD-1].doubleBuffered );
161 if (wgl_ctx[i].ctx == NULL)
162 break;
163 wgl_ctx[i].hdc = hdc;
164 ctx_count++;
165 return ((HGLRC)wgl_ctx[i].ctx);
166 }
167 }
168 SetLastError(0);
169 return(NULL);
170 }
171
172 GLAPI BOOL GLWINAPI wglDeleteContext(HGLRC hglrc)
173 {
174 int i;
175 for ( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ )
176 {
177 if ( wgl_ctx[i].ctx == (PWMC) hglrc )
178 {
179 WMesaMakeCurrent((PWMC) hglrc);
180 WMesaDestroyContext();
181 wgl_ctx[i].ctx = NULL;
182 wgl_ctx[i].hdc = NULL;
183 ctx_count--;
184 return(TRUE);
185 }
186 }
187 SetLastError(0);
188 return(FALSE);
189 }
190
191 GLAPI HGLRC GLWINAPI wglCreateLayerContext(HDC hdc,int iLayerPlane)
192 {
193 SetLastError(0);
194 return(NULL);
195 }
196
197 GLAPI HGLRC GLWINAPI wglGetCurrentContext(VOID)
198 {
199 if (ctx_current < 0)
200 return 0;
201 else
202 return (HGLRC) wgl_ctx[ctx_current].ctx;
203 }
204
205 GLAPI HDC GLWINAPI wglGetCurrentDC(VOID)
206 {
207 if (ctx_current < 0)
208 return 0;
209 else
210 return wgl_ctx[ctx_current].hdc;
211 }
212
213 GLAPI BOOL GLWINAPI wglMakeCurrent(HDC hdc,HGLRC hglrc)
214 {
215 int i;
216
217 /* new code suggested by Andy Sy */
218 if (!hdc || !hglrc) {
219 WMesaMakeCurrent(NULL);
220 ctx_current = -1;
221 return TRUE;
222 }
223
224 for ( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ )
225 {
226 if ( wgl_ctx[i].ctx == (PWMC) hglrc )
227 {
228 wgl_ctx[i].hdc = hdc;
229 WMesaMakeCurrent( (WMesaContext) hglrc );
230 ctx_current = i;
231 return TRUE;
232 }
233 }
234 return FALSE;
235 }
236
237 GLAPI BOOL GLWINAPI wglShareLists(HGLRC hglrc1,HGLRC hglrc2)
238 {
239 return(TRUE);
240 }
241
242
243 static FIXED FixedFromDouble(double d)
244 {
245 long l = (long) (d * 65536L);
246 return *(FIXED *)&l;
247 }
248
249
250 GLAPI BOOL GLWINAPI wglUseFontBitmapsA(HDC hdc, DWORD first,
251 DWORD count, DWORD listBase)
252 {
253 int i;
254 GLuint font_list;
255 DWORD size;
256 GLYPHMETRICS gm;
257 HANDLE hBits;
258 LPSTR lpBits;
259 MAT2 mat;
260
261 if (first<0)
262 return FALSE;
263 if (count<0)
264 return FALSE;
265 if (listBase<0)
266 return FALSE;
267
268 font_list = glGenLists( count );
269 if(font_list == 0)
270 return FALSE;
271
272 mat.eM11 = FixedFromDouble(1);
273 mat.eM12 = FixedFromDouble(0);
274 mat.eM21 = FixedFromDouble(0);
275 mat.eM22 = FixedFromDouble(1);
276
277 memset(&gm,0,sizeof(gm));
278
279 for (i = 0; i < count; i++)
280 {
281 glNewList( font_list+i, GL_COMPILE );
282
283 /* allocate space for the bitmap/outline */
284 size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, &gm, 0, NULL, &mat);
285 if (size == GDI_ERROR)
286 {
287 DWORD err;
288 err = GetLastError();
289 return(FALSE);
290 }
291
292 hBits = GlobalAlloc(GHND, size);
293 lpBits = GlobalLock(hBits);
294
295 GetGlyphOutline(hdc, /* handle to device context */
296 first + i, /* character to query */
297 GGO_BITMAP, /* format of data to return */
298 &gm, /* pointer to structure for metrics */
299 size, /* size of buffer for data */
300 lpBits, /* pointer to buffer for data */
301 &mat /* pointer to transformation */
302 /* matrix structure */
303 );
304
305 if (*lpBits == GDI_ERROR)
306 {
307 DWORD err;
308 err = GetLastError();
309
310 GlobalUnlock(hBits);
311 GlobalFree(hBits);
312
313 return(FALSE);
314 }
315
316 glBitmap(gm.gmBlackBoxX,gm.gmBlackBoxY,
317 gm.gmptGlyphOrigin.x,
318 gm.gmptGlyphOrigin.y,
319 gm.gmCellIncX,gm.gmCellIncY,
320 (const GLubyte * )lpBits);
321
322 GlobalUnlock(hBits);
323 GlobalFree(hBits);
324
325 glEndList( );
326 }
327
328 return TRUE;
329 }
330
331 GLAPI BOOL GLWINAPI wglUseFontBitmapsW(HDC hdc,DWORD first,DWORD count,DWORD listBase)
332 {
333 return FALSE;
334 }
335
336 GLAPI BOOL GLWINAPI wglUseFontOutlinesA(HDC hdc,DWORD first,DWORD count,
337 DWORD listBase,FLOAT deviation,
338 FLOAT extrusion,int format,
339 LPGLYPHMETRICSFLOAT lpgmf)
340 {
341 SetLastError(0);
342 return(FALSE);
343 }
344
345 GLAPI BOOL GLWINAPI wglUseFontOutlinesW(HDC hdc,DWORD first,DWORD count,
346 DWORD listBase,FLOAT deviation,
347 FLOAT extrusion,int format,
348 LPGLYPHMETRICSFLOAT lpgmf)
349 {
350 SetLastError(0);
351 return(FALSE);
352 }
353
354 GLAPI BOOL GLWINAPI wglDescribeLayerPlane(HDC hdc,int iPixelFormat,
355 int iLayerPlane,UINT nBytes,
356 LPLAYERPLANEDESCRIPTOR plpd)
357 {
358 SetLastError(0);
359 return(FALSE);
360 }
361
362 GLAPI int GLWINAPI wglSetLayerPaletteEntries(HDC hdc,int iLayerPlane,
363 int iStart,int cEntries,
364 CONST COLORREF *pcr)
365 {
366 SetLastError(0);
367 return(0);
368 }
369
370 GLAPI int GLWINAPI wglGetLayerPaletteEntries(HDC hdc,int iLayerPlane,
371 int iStart,int cEntries,
372 COLORREF *pcr)
373 {
374 SetLastError(0);
375 return(0);
376 }
377
378 GLAPI BOOL GLWINAPI wglRealizeLayerPalette(HDC hdc,int iLayerPlane,BOOL bRealize)
379 {
380 SetLastError(0);
381 return(FALSE);
382 }
383
384 GLAPI BOOL GLWINAPI wglSwapLayerBuffers(HDC hdc,UINT fuPlanes)
385 {
386 if( !hdc )
387 {
388 WMesaSwapBuffers();
389 return(TRUE);
390 }
391 SetLastError(0);
392 return(FALSE);
393 }
394
395 GLAPI int GLWINAPI wglChoosePixelFormat(HDC hdc,
396 CONST PIXELFORMATDESCRIPTOR *ppfd)
397 {
398 int i,best = -1,bestdelta = 0x7FFFFFFF,delta,qt_valid_pix;
399
400 qt_valid_pix = qt_pix;
401 if(ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR) || ppfd->nVersion != 1)
402 {
403 SetLastError(0);
404 return(0);
405 }
406 for(i = 0;i < qt_valid_pix;i++)
407 {
408 delta = 0;
409 if(
410 (ppfd->dwFlags & PFD_DRAW_TO_WINDOW) &&
411 !(pix[i].pfd.dwFlags & PFD_DRAW_TO_WINDOW))
412 continue;
413 if(
414 (ppfd->dwFlags & PFD_DRAW_TO_BITMAP) &&
415 !(pix[i].pfd.dwFlags & PFD_DRAW_TO_BITMAP))
416 continue;
417 if(
418 (ppfd->dwFlags & PFD_SUPPORT_GDI) &&
419 !(pix[i].pfd.dwFlags & PFD_SUPPORT_GDI))
420 continue;
421 if(
422 (ppfd->dwFlags & PFD_SUPPORT_OPENGL) &&
423 !(pix[i].pfd.dwFlags & PFD_SUPPORT_OPENGL))
424 continue;
425 if(
426 !(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) &&
427 ((ppfd->dwFlags & PFD_DOUBLEBUFFER) != (pix[i].pfd.dwFlags & PFD_DOUBLEBUFFER)))
428 continue;
429 if(
430 !(ppfd->dwFlags & PFD_STEREO_DONTCARE) &&
431 ((ppfd->dwFlags & PFD_STEREO) != (pix[i].pfd.dwFlags & PFD_STEREO)))
432 continue;
433 if(ppfd->iPixelType != pix[i].pfd.iPixelType)
434 delta++;
435 if(delta < bestdelta)
436 {
437 best = i + 1;
438 bestdelta = delta;
439 if(bestdelta == 0)
440 break;
441 }
442 }
443 if(best == -1)
444 {
445 SetLastError(0);
446 return(0);
447 }
448 return(best);
449 }
450
451 GLAPI int GLWINAPI wglDescribePixelFormat(HDC hdc,int iPixelFormat,UINT nBytes,
452 LPPIXELFORMATDESCRIPTOR ppfd)
453 {
454 int qt_valid_pix;
455
456 qt_valid_pix = qt_pix;
457 if(iPixelFormat < 1 || iPixelFormat > qt_valid_pix || nBytes != sizeof(PIXELFORMATDESCRIPTOR))
458 {
459 SetLastError(0);
460 return(0);
461 }
462 *ppfd = pix[iPixelFormat - 1].pfd;
463 return(qt_valid_pix);
464 }
465
466 /*
467 * GetProcAddress - return the address of an appropriate extension
468 */
469 GLAPI PROC GLWINAPI wglGetProcAddress(LPCSTR lpszProc)
470 {
471 int i;
472 for(i = 0;i < qt_ext;i++)
473 if(!strcmp(lpszProc,ext[i].name))
474 return(ext[i].proc);
475
476 SetLastError(0);
477 return(NULL);
478 }
479
480 GLAPI int GLWINAPI wglGetPixelFormat(HDC hdc)
481 {
482 if(curPFD == 0)
483 {
484 SetLastError(0);
485 return(0);
486 }
487 return(curPFD);
488 }
489
490 GLAPI BOOL GLWINAPI wglSetPixelFormat(HDC hdc,int iPixelFormat,
491 PIXELFORMATDESCRIPTOR *ppfd)
492 {
493 int qt_valid_pix;
494
495 qt_valid_pix = qt_pix;
496 if(iPixelFormat < 1 || iPixelFormat > qt_valid_pix || ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR))
497 {
498 SetLastError(0);
499 return(FALSE);
500 }
501 curPFD = iPixelFormat;
502 return(TRUE);
503 }
504
505 GLAPI BOOL GLWINAPI wglSwapBuffers(HDC hdc)
506 {
507 if (ctx_current < 0)
508 return FALSE;
509
510 if(wgl_ctx[ctx_current].ctx == NULL) {
511 SetLastError(0);
512 return(FALSE);
513 }
514 WMesaSwapBuffers();
515 return(TRUE);
516 }
517
518 #endif /* WIN32 */