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