12d3d99f4a2ea48fdae994907d0264ef5ec259fe
[reactos.git] / reactos / lib / opengl32 / wgl.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: lib/opengl32/wgl.c
5 * PURPOSE: OpenGL32 lib, rosglXXX functions
6 * PROGRAMMER: Anich Gregor (blight)
7 * UPDATE HISTORY:
8 * Feb 2, 2004: Created
9 */
10
11 #define WIN32_LEAN_AND_MEAN
12 #include <windows.h>
13 #include "teb.h"
14 #include "opengl32.h"
15
16 #ifdef __cplusplus
17 extern "C" {
18 #endif//__cplusplus
19
20 #ifdef _MSC_VER
21 #define UNIMPLEMENTED DBGPRINT( "UNIMPLEMENTED" )
22 #endif//_MSC_VER
23
24 /* FUNCTION: Append OpenGL Rendering Context (GLRC) to list
25 * ARGUMENTS: [IN] glrc: GLRC to append to list
26 */
27 static
28 void
29 WGL_AppendContext( GLRC *glrc )
30 {
31 /* synchronize */
32 if (WaitForSingleObject( OPENGL32_processdata.glrc_mutex, INFINITE ) ==
33 WAIT_FAILED)
34 {
35 DBGPRINT( "Error: WaitForSingleObject() failed (%d)", GetLastError() );
36 return; /* FIXME: do we have to expect such an error and handle it? */
37 }
38
39 if (OPENGL32_processdata.glrc_list == NULL)
40 OPENGL32_processdata.glrc_list = glrc;
41 else
42 {
43 GLRC *p = OPENGL32_processdata.glrc_list;
44 while (p->next != NULL)
45 p = p->next;
46 p->next = glrc;
47 }
48
49 /* release mutex */
50 if (!ReleaseMutex( OPENGL32_processdata.glrc_mutex ))
51 DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
52 }
53
54
55 /* FUNCTION: Remove OpenGL Rendering Context (GLRC) from list
56 * ARGUMENTS: [IN] glrc: GLRC to remove from list
57 */
58 static
59 void
60 WGL_RemoveContext( GLRC *glrc )
61 {
62 /* synchronize */
63 if (WaitForSingleObject( OPENGL32_processdata.glrc_mutex, INFINITE ) ==
64 WAIT_FAILED)
65 {
66 DBGPRINT( "Error: WaitForSingleObject() failed (%d)", GetLastError() );
67 return; /* FIXME: do we have to expect such an error and handle it? */
68 }
69
70 if (glrc == OPENGL32_processdata.glrc_list)
71 OPENGL32_processdata.glrc_list = glrc->next;
72 else
73 {
74 GLRC *p = OPENGL32_processdata.glrc_list;
75 while (p != NULL)
76 {
77 if (p->next == glrc)
78 {
79 p->next = glrc->next;
80 return;
81 }
82 p = p->next;
83 }
84 DBGPRINT( "Error: GLRC 0x%08x not found in list!", glrc );
85 }
86
87 /* release mutex */
88 if (!ReleaseMutex( OPENGL32_processdata.glrc_mutex ))
89 DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
90 }
91
92 /* FUNCTION: Check wether a GLRC is in the list
93 * ARGUMENTS: [IN] glrc: GLRC to remove from list
94 */
95 static
96 BOOL
97 WGL_ContainsContext( GLRC *glrc )
98 {
99 GLRC *p;
100
101 /* synchronize */
102 if (WaitForSingleObject( OPENGL32_processdata.glrc_mutex, INFINITE ) ==
103 WAIT_FAILED)
104 {
105 DBGPRINT( "Error: WaitForSingleObject() failed (%d)", GetLastError() );
106 return FALSE; /* FIXME: do we have to expect such an error and handle it? */
107 }
108
109 p = OPENGL32_processdata.glrc_list;
110 while (p != NULL)
111 {
112 if (p == glrc)
113 return TRUE;
114 p = p->next;
115 }
116
117 /* release mutex */
118 if (!ReleaseMutex( OPENGL32_processdata.glrc_mutex ))
119 DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
120
121 return FALSE;
122 }
123
124
125 /* FUNCTION: SetContextCallBack passed to DrvSetContext. Gets called whenever
126 * the current GL context (dispatch table) is to be changed - can
127 * be multiple times for one DrvSetContext call.
128 * ARGUMENTS: [IN] table Function pointer table (first DWORD is number of
129 * functions)
130 * RETURNS: unkown
131 */
132 DWORD
133 CALLBACK
134 WGL_SetContextCallBack( const ICDTable *table )
135 {
136 /* UINT i;*/
137 TEB *teb;
138 PROC *tebTable, *tebDispatchTable;
139
140 teb = NtCurrentTeb();
141 tebTable = (PROC *)teb->glTable;
142 tebDispatchTable = (PROC *)teb->glDispatchTable;
143
144 DBGPRINT( "Function count: %d\n", table->num_funcs );
145
146 /* save table */
147 memcpy( tebTable, table->dispatch_table,
148 sizeof (PROC) * table->num_funcs );
149 memset( tebTable + sizeof (PROC) * table->num_funcs, 0,
150 sizeof (table->dispatch_table) - (sizeof (PROC) * table->num_funcs) );
151
152 /* FIXME: pull in software fallbacks -- need mesa */
153 #if 0 /* unused atm */
154 for (i = 0; i < (sizeof (table->dispatch_table) / sizeof (PROC)); i++)
155 {
156 if (tebTable[i] == NULL)
157 {
158 /* FIXME: fallback */
159 DBGPRINT( "Warning: GL proc #%d is NULL!", i );
160 }
161 }
162 #endif
163
164 /* put in empty functions as long as we dont have a fallback */
165 #define X(func, ret, typeargs, args, icdidx, tebidx, stack) \
166 if (tebTable[icdidx] == NULL) \
167 { \
168 DBGPRINT( "Warning: GL proc '%s' is NULL", #func ); \
169 tebTable[icdidx] = (PROC)glEmptyFunc##stack; \
170 }
171 GLFUNCS_MACRO
172 #undef X
173
174 /* fill teb->glDispatchTable for fast calls */
175 #define X(func, ret, typeargs, args, icdidx, tebidx, stack) \
176 if (tebidx >= 0) \
177 tebDispatchTable[tebidx] = tebTable[icdidx];
178 GLFUNCS_MACRO
179 #undef X
180
181 return ERROR_SUCCESS;
182 }
183
184
185 /* FUNCTION: Attempts to find the best matching pixel format for HDC
186 * ARGUMENTS: [IN] pdf PFD describing what kind of format you want
187 * RETURNS: one-based positive format index on success, 0 on failure
188 */
189 #define BUFFERDEPTH_SCORE(want, have) \
190 ((want == 0) ? (0) : ((want < have) ? (1) : ((want > have) ? (3) : (0))))
191 int
192 APIENTRY
193 rosglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd )
194 {
195 GLDRIVERDATA *icd;
196 PIXELFORMATDESCRIPTOR icdPfd;
197 int i;
198 int best = 0;
199 int score, bestScore = 0x7fff; /* used to choose a pfd if no exact match */
200 int icdNumFormats;
201 const DWORD compareFlags = PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP |
202 PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL;
203
204 /* load ICD */
205 icd = OPENGL32_LoadICDForHDC( hdc );
206 if (icd == NULL)
207 return 0;
208
209 /* check input */
210 if (pfd->nSize != sizeof (PIXELFORMATDESCRIPTOR) || pfd->nVersion != 1)
211 {
212 SetLastError( 0 ); /* FIXME: use appropriate errorcode */
213 return 0;
214 }
215
216 /* get number of formats -- FIXME: use 1 or 0 as index? */
217 icdNumFormats = icd->DrvDescribePixelFormat( hdc, 0,
218 sizeof (PIXELFORMATDESCRIPTOR), NULL );
219 if (icdNumFormats == 0)
220 {
221 DBGPRINT( "Error: DrvDescribePixelFormat failed (%d)", GetLastError() );
222 return 0;
223 }
224 DBGPRINT( "Info: Enumerating %d pixelformats", icdNumFormats );
225
226 /* try to find best format */
227 for (i = 0; i < icdNumFormats; i++)
228 {
229 if (icd->DrvDescribePixelFormat( hdc, i + 1,
230 sizeof (PIXELFORMATDESCRIPTOR), &icdPfd ) == 0)
231 {
232 DBGPRINT( "Warning: DrvDescribePixelFormat failed (%d)",
233 GetLastError() );
234 break;
235 }
236
237 /* compare flags */
238 if ((pfd->dwFlags & compareFlags) != (icdPfd.dwFlags & compareFlags))
239 continue;
240 if (!(pfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) &&
241 ((pfd->dwFlags & PFD_DOUBLEBUFFER) != (icdPfd.dwFlags & PFD_DOUBLEBUFFER)))
242 continue;
243 if (!(pfd->dwFlags & PFD_STEREO_DONTCARE) &&
244 ((pfd->dwFlags & PFD_STEREO) != (icdPfd.dwFlags & PFD_STEREO)))
245 continue;
246
247 /* check other attribs */
248 score = 0; /* higher is worse */
249 if (pfd->iPixelType != icdPfd.iPixelType)
250 score += 5; /* this is really bad i think */
251 if (pfd->iLayerType != icdPfd.iLayerType)
252 score += 15; /* this is very very bad ;) */
253
254 score += BUFFERDEPTH_SCORE(pfd->cAlphaBits, icdPfd.cAlphaBits);
255 score += BUFFERDEPTH_SCORE(pfd->cAccumBits, icdPfd.cAccumBits);
256 score += BUFFERDEPTH_SCORE(pfd->cDepthBits, icdPfd.cDepthBits);
257 score += BUFFERDEPTH_SCORE(pfd->cStencilBits, icdPfd.cStencilBits);
258 score += BUFFERDEPTH_SCORE(pfd->cAuxBuffers, icdPfd.cAuxBuffers);
259
260 /* check score */
261 if (score < bestScore)
262 {
263 bestScore = score;
264 best = i + 1;
265 if (bestScore == 0)
266 break;
267 }
268 }
269
270 if (best == 0)
271 SetLastError( 0 ); /* FIXME: set appropriate error */
272
273 DBGPRINT( "Info: Suggesting pixelformat %d", best );
274 return best;
275 }
276
277
278 /* FUNCTION: Copy data specified by mask from one GLRC to another.
279 * ARGUMENTS: [IN] src Source GLRC
280 * [OUT] dst Destination GLRC
281 * [IN] mask Bitfield like given to glPushAttrib()
282 * RETURN: TRUE on success, FALSE on failure
283 */
284 BOOL
285 APIENTRY
286 rosglCopyContext( HGLRC hsrc, HGLRC hdst, UINT mask )
287 {
288 GLRC *src = (GLRC *)hsrc;
289 GLRC *dst = (GLRC *)hdst;
290
291 /* check glrcs */
292 if (!WGL_ContainsContext( src ))
293 {
294 DBGPRINT( "Error: src GLRC not found!" );
295 return FALSE; /* FIXME: SetLastError() */
296 }
297 if (!WGL_ContainsContext( dst ))
298 {
299 DBGPRINT( "Error: dst GLRC not found!" );
300 return FALSE; /* FIXME: SetLastError() */
301 }
302
303 /* I think this is only possible within one ICD */
304 if (src->icd != src->icd)
305 {
306 DBGPRINT( "Error: src and dst GLRC use different ICDs!" );
307 return FALSE;
308 }
309
310 /* copy data (call ICD) */
311 return src->icd->DrvCopyContext( src->hglrc, dst->hglrc, mask );
312 }
313
314
315 /* FUNCTION: Create a new GL Rendering Context for the given plane on
316 * the given DC.
317 * ARGUMENTS: [IN] hdc Handle for DC for which to create context
318 * [IN] layer Layer number to bind (draw?) to
319 * RETURNS: NULL on failure, new GLRC on success
320 */
321 HGLRC
322 APIENTRY
323 rosglCreateLayerContext( HDC hdc, int layer )
324 {
325 /* LONG ret;
326 WCHAR driver[256];
327 DWORD dw, size;*/
328
329 GLDRIVERDATA *icd = NULL;
330 GLRC *glrc;
331 HGLRC drvHglrc = NULL;
332
333 /* if (GetObjectType( hdc ) != OBJ_DC)
334 {
335 DBGPRINT( "Error: hdc is not a DC handle!" );
336 return NULL;
337 }
338 */
339 /* allocate our GLRC */
340 glrc = (GLRC*)HeapAlloc( GetProcessHeap(),
341 HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS, sizeof (GLRC) );
342 if (glrc == NULL)
343 return NULL;
344
345 #if 0 /* old code */
346 /* try to find an ICD */
347 for (dw = 0; drvHglrc == NULL; dw++) /* enumerate values */
348 {
349 size = sizeof (driver) / sizeof (driver[0]);
350 ret = OPENGL32_RegEnumDrivers( dw, driver, &size );
351 if (ret != ERROR_SUCCESS)
352 break;
353
354 icd = OPENGL32_LoadICD( driver );
355 if (icd == NULL) /* try next ICD */
356 continue;
357
358 if (icd->DrvCreateLayerContext)
359 drvHglrc = icd->DrvCreateLayerContext( hdc, layer );
360 if (drvHglrc == NULL)
361 {
362 if (layer == 0)
363 drvHglrc = icd->DrvCreateContext( hdc );
364 else
365 DBGPRINT( "Warning: CreateLayerContext not supported by ICD!" );
366 }
367 if (drvHglrc == NULL) /* try next ICD */
368 {
369 DBGPRINT( "Info: DrvCreateContext (driver = %ws) failed: %d",
370 icd->driver_name, GetLastError() );
371 OPENGL32_UnloadICD( icd );
372 continue;
373 }
374
375 /* the ICD was loaded successfully and we got a HGLRC in drvHglrc */
376 break;
377 }
378
379 if (drvHglrc == NULL || icd == NULL) /* no ICD was found */
380 {
381 /* FIXME: fallback to mesa */
382 DBGPRINT( "Error: No working ICD found!" );
383 HeapFree( GetProcessHeap(), 0, glrc );
384 return NULL;
385 }
386 #endif /* unused */
387
388 /* load ICD */
389 icd = OPENGL32_LoadICDForHDC( hdc );
390 if (icd == NULL)
391 {
392 DBGPRINT( "Couldn't get ICD by HDC :-(" );
393 /* FIXME: fallback? */
394 return NULL;
395 }
396
397 /* create context */
398 if (icd->DrvCreateLayerContext != NULL)
399 drvHglrc = icd->DrvCreateLayerContext( hdc, layer );
400 if (drvHglrc == NULL)
401 {
402 if (layer == 0 && icd->DrvCreateContext != NULL)
403 drvHglrc = icd->DrvCreateContext( hdc );
404 else
405 DBGPRINT( "Warning: CreateLayerContext not supported by ICD!" );
406 }
407
408 if (drvHglrc == NULL)
409 {
410 /* FIXME: fallback to mesa? */
411 DBGPRINT( "Error: DrvCreate[Layer]Context failed! (%d)", GetLastError() );
412 OPENGL32_UnloadICD( icd );
413 HeapFree( GetProcessHeap(), 0, glrc );
414 return NULL;
415 }
416
417 /* we have our GLRC in glrc and the ICD's GLRC in drvHglrc */
418 glrc->hglrc = drvHglrc;
419 glrc->icd = icd;
420
421 /* append glrc to context list */
422 WGL_AppendContext( glrc );
423
424 return (HGLRC)glrc;
425 }
426
427
428 /* FUNCTION: Create a new GL Rendering Context for the given DC.
429 * ARGUMENTS: [IN] hdc Handle for DC for which to create context
430 * RETURNS: NULL on failure, new GLRC on success
431 */
432 HGLRC
433 APIENTRY
434 rosglCreateContext( HDC hdc )
435 {
436 return rosglCreateLayerContext( hdc, 0 );
437 }
438
439
440 /* FUNCTION: Delete an OpenGL context
441 * ARGUMENTS: [IN] hglrc Handle to GLRC to delete; must not be a threads RC!
442 * RETURNS: TRUE on success, FALSE otherwise
443 */
444 BOOL
445 APIENTRY
446 rosglDeleteContext( HGLRC hglrc )
447 {
448 GLRC *glrc = (GLRC *)hglrc;
449
450 /* check if we know about this context */
451 if (!WGL_ContainsContext( glrc ))
452 {
453 DBGPRINT( "Error: hglrc not found!" );
454 return FALSE; /* FIXME: SetLastError() */
455 }
456
457 /* make sure GLRC is not current for some thread */
458 if (glrc->is_current)
459 {
460 DBGPRINT( "Error: GLRC is current for DC 0x%08x", glrc->hdc );
461 return FALSE; /* FIXME: SetLastError() */
462 }
463
464 /* release ICD's context */
465 if (glrc->hglrc != NULL)
466 {
467 if (!glrc->icd->DrvDeleteContext( glrc->hglrc ))
468 {
469 DBGPRINT( "Warning: DrvDeleteContext() failed (%d)", GetLastError() );
470 return FALSE;
471 }
472 }
473
474 /* free resources */
475 OPENGL32_UnloadICD( glrc->icd );
476 WGL_RemoveContext( glrc );
477 HeapFree( GetProcessHeap(), 0, glrc );
478
479 return TRUE;
480 }
481
482
483 BOOL
484 APIENTRY
485 rosglDescribeLayerPlane( HDC hdc, int iPixelFormat, int iLayerPlane,
486 UINT nBytes, LPLAYERPLANEDESCRIPTOR plpd )
487 {
488 UNIMPLEMENTED;
489 return FALSE;
490 }
491
492
493 int
494 APIENTRY
495 rosglDescribePixelFormat( HDC hdc, int iFormat, UINT nBytes,
496 LPPIXELFORMATDESCRIPTOR pfd )
497 {
498 int ret = 0;
499 GLDRIVERDATA *icd = OPENGL32_LoadICDForHDC( hdc );
500
501 if (icd != NULL)
502 {
503 ret = icd->DrvDescribePixelFormat( hdc, iFormat, nBytes, pfd );
504 if (ret == 0)
505 DBGPRINT( "Error: DrvDescribePixelFormat(format=%d) failed (%d)", iFormat, GetLastError() );
506 }
507
508 /* FIXME: implement own functionality? */
509 return ret;
510 }
511
512
513 /* FUNCTION: Return the current GLRC
514 * RETURNS: Current GLRC (NULL if none was set current)
515 */
516 HGLRC
517 APIENTRY
518 rosglGetCurrentContext()
519 {
520 return (HGLRC)(OPENGL32_threaddata->glrc);
521 }
522
523
524 /* FUNCTION: Return the current DC
525 * RETURNS: NULL on failure, current DC otherwise
526 */
527 HDC
528 APIENTRY
529 rosglGetCurrentDC()
530 {
531 /* FIXME: is it correct to return NULL when there is no current GLRC or
532 is there another way to find out the wanted HDC? */
533 if (OPENGL32_threaddata->glrc == NULL)
534 return NULL;
535 return (HDC)(OPENGL32_threaddata->glrc->hdc);
536 }
537
538
539 int
540 APIENTRY
541 rosglGetLayerPaletteEntries( HDC hdc, int iLayerPlane, int iStart,
542 int cEntries, COLORREF *pcr )
543 {
544 UNIMPLEMENTED;
545 return 0;
546 }
547
548
549 int
550 WINAPI
551 rosglGetPixelFormat( HDC hdc )
552 {
553 if (OPENGL32_processdata.cachedHdc == hdc)
554 return OPENGL32_processdata.cachedFormat;
555
556 /* FIXME: create real implementation of this function */
557 DBGPRINT( "Warning: Pixel format not cached, returning 0" );
558
559 return 0;
560 }
561
562
563 /* FUNCTION: Get the address for an OpenGL extension function from the current ICD.
564 * ARGUMENTS: [IN] proc: Name of the function to look for
565 * RETURNS: The address of the proc or NULL on failure.
566 */
567 PROC
568 APIENTRY
569 rosglGetProcAddress( LPCSTR proc )
570 {
571 if (OPENGL32_threaddata->glrc == NULL)
572 {
573 DBGPRINT( "Error: No current GLRC!" );
574 return NULL;
575 }
576
577 if (proc[0] == 'g' && proc[1] == 'l') /* glXXX */
578 {
579 PROC glXXX = OPENGL32_threaddata->glrc->icd->DrvGetProcAddress( proc );
580 if (glXXX)
581 {
582 DBGPRINT( "Info: Proc \"%s\" loaded from ICD.", proc );
583 return glXXX;
584 }
585
586 /* FIXME: go through own functions? */
587 DBGPRINT( "Warning: Unsupported GL extension: %s", proc );
588 }
589 if (proc[0] == 'w' && proc[1] == 'g' && proc[2] == 'l') /* wglXXX */
590 {
591 /* FIXME: support wgl extensions? (there are such IIRC) */
592 DBGPRINT( "Warning: Unsupported WGL extension: %s", proc );
593 }
594 if (proc[0] == 'g' && proc[1] == 'l' && proc[2] == 'u') /* gluXXX */
595 {
596 /* FIXME: do we support these as well? */
597 DBGPRINT( "Warning: GLU extension %s requested, returning NULL", proc );
598 }
599
600 return NULL;
601 }
602
603
604 /* FUNCTION: make the given GLRC the threads current GLRC for hdc
605 * ARGUMENTS: [IN] hdc Handle for a DC to be drawn on
606 * [IN] hglrc Handle for a GLRC to make current
607 * RETURNS: TRUE on success, FALSE otherwise
608 */
609 BOOL
610 APIENTRY
611 rosglMakeCurrent( HDC hdc, HGLRC hglrc )
612 {
613 GLRC *glrc = (GLRC *)hglrc;
614 ICDTable *icdTable = NULL;
615
616 /* flush current context */
617 if (OPENGL32_threaddata->glrc != NULL)
618 {
619 glFlush();
620 }
621
622 /* check hdc */
623 if (GetObjectType( hdc ) != OBJ_DC)
624 {
625 DBGPRINT( "Error: hdc is not a DC handle!" );
626 return FALSE;
627 }
628
629 /* check if we know about this glrc */
630 if (!WGL_ContainsContext( glrc ))
631 {
632 DBGPRINT( "Error: hglrc not found!" );
633 return FALSE; /* FIXME: SetLastError() */
634 }
635
636 /* check if it is available */
637 if (glrc->is_current) /* used by another thread */
638 {
639 DBGPRINT( "Error: hglrc is current for thread 0x%08x", glrc->thread_id );
640 return FALSE; /* FIXME: SetLastError() */
641 }
642
643 /* call the ICD */
644 if (glrc->hglrc != NULL)
645 {
646 icdTable = glrc->icd->DrvSetContext( hdc, glrc->hglrc,
647 WGL_SetContextCallBack );
648 if (icdTable == NULL)
649 {
650 DBGPRINT( "Error: DrvSetContext failed (%d)\n", GetLastError() );
651 return FALSE;
652 }
653 DBGPRINT( "Info: DrvSetContext succeeded!" );
654 }
655
656 /* make it current */
657 if (OPENGL32_threaddata->glrc != NULL)
658 OPENGL32_threaddata->glrc->is_current = FALSE;
659 glrc->is_current = TRUE;
660 glrc->thread_id = GetCurrentThreadId();
661 glrc->hdc = hdc;
662 OPENGL32_threaddata->glrc = glrc;
663
664 if (icdTable != NULL)
665 if (WGL_SetContextCallBack( icdTable ) != ERROR_SUCCESS)
666 {
667 DBGPRINT( "Warning: WGL_SetContextCallBack failed!" );
668 }
669
670 return TRUE;
671 }
672
673
674 BOOL
675 APIENTRY
676 rosglRealizeLayerPalette( HDC hdc, int iLayerPlane, BOOL bRealize )
677 {
678 UNIMPLEMENTED;
679 return FALSE;
680 }
681
682
683 int
684 APIENTRY
685 rosglSetLayerPaletteEntries( HDC hdc, int iLayerPlane, int iStart,
686 int cEntries, CONST COLORREF *pcr )
687 {
688 UNIMPLEMENTED;
689 return 0;
690 }
691
692
693 BOOL
694 WINAPI
695 rosglSetPixelFormat( HDC hdc, int iFormat, CONST PIXELFORMATDESCRIPTOR *pfd )
696 {
697 GLDRIVERDATA *icd;
698
699 icd = OPENGL32_LoadICDForHDC( hdc );
700 if (icd == NULL)
701 return FALSE;
702
703 if (!icd->DrvSetPixelFormat( hdc, iFormat, pfd ))
704 {
705 DBGPRINT( "Warning: DrvSetPixelFormat(format=%d) failed (%d)",
706 iFormat, GetLastError() );
707 return FALSE;
708 }
709
710 OPENGL32_processdata.cachedHdc = hdc;
711 OPENGL32_processdata.cachedFormat = iFormat;
712
713 return TRUE;
714 }
715
716
717 /* FUNCTION: Enable display-list sharing between multiple GLRCs
718 * ARGUMENTS: [IN] hglrc1 GLRC number 1
719 * [IN] hglrc2 GLRC number 2
720 * RETURNS: TRUR on success, FALSE on failure
721 */
722 BOOL
723 APIENTRY
724 rosglShareLists( HGLRC hglrc1, HGLRC hglrc2 )
725 {
726 GLRC *glrc1 = (GLRC *)hglrc1;
727 GLRC *glrc2 = (GLRC *)hglrc2;
728
729 /* check glrcs */
730 if (!WGL_ContainsContext( glrc1 ))
731 {
732 DBGPRINT( "Error: hglrc1 not found!" );
733 return FALSE; /* FIXME: SetLastError() */
734 }
735 if (!WGL_ContainsContext( glrc2 ))
736 {
737 DBGPRINT( "Error: hglrc2 not found!" );
738 return FALSE; /* FIXME: SetLastError() */
739 }
740
741 /* I think this is only possible within one ICD */
742 if (glrc1->icd != glrc2->icd)
743 {
744 DBGPRINT( "Error: hglrc1 and hglrc2 use different ICDs!" );
745 return FALSE;
746 }
747
748 /* share lists (call ICD) */
749 return glrc1->icd->DrvShareLists( glrc1->hglrc, glrc2->hglrc );
750 }
751
752
753 /* FUNCTION: Flushes GL and swaps front/back buffer if appropriate
754 * ARGUMENTS: [IN] hdc Handle to device context to swap buffers for
755 * RETURNS: TRUE on success, FALSE on failure
756 */
757 BOOL
758 APIENTRY
759 rosglSwapBuffers( HDC hdc )
760 {
761 GLDRIVERDATA *icd = OPENGL32_LoadICDForHDC( hdc );
762 if (icd != NULL)
763 {
764 if (!icd->DrvSwapBuffers( hdc ))
765 {
766 DBGPRINT( "Error: DrvSwapBuffers failed (%d)", GetLastError() );
767 return FALSE;
768 }
769 return TRUE;
770 }
771
772 /* FIXME: implement own functionality? */
773 return FALSE;
774 }
775
776
777 BOOL
778 APIENTRY
779 rosglSwapLayerBuffers( HDC hdc, UINT fuPlanes )
780 {
781 UNIMPLEMENTED;
782 return FALSE;
783 }
784
785
786 BOOL
787 APIENTRY
788 rosglUseFontBitmapsA( HDC hdc, DWORD first, DWORD count, DWORD listBase )
789 {
790 UNIMPLEMENTED;
791 return FALSE;
792 }
793
794
795 BOOL
796 APIENTRY
797 rosglUseFontBitmapsW( HDC hdc, DWORD first, DWORD count, DWORD listBase )
798 {
799 UNIMPLEMENTED;
800 return FALSE;
801 }
802
803
804 BOOL
805 APIENTRY
806 rosglUseFontOutlinesA( HDC hdc, DWORD first, DWORD count, DWORD listBase,
807 FLOAT deviation, FLOAT extrusion, int format,
808 LPGLYPHMETRICSFLOAT lpgmf )
809 {
810 UNIMPLEMENTED;
811 return FALSE;
812 }
813
814
815 BOOL
816 APIENTRY
817 rosglUseFontOutlinesW( HDC hdc, DWORD first, DWORD count, DWORD listBase,
818 FLOAT deviation, FLOAT extrusion, int format,
819 LPGLYPHMETRICSFLOAT lpgmf )
820 {
821 UNIMPLEMENTED;
822 return FALSE;
823 }
824
825 #ifdef __cplusplus
826 }; // extern "C"
827 #endif//__cplusplus
828
829 /* EOF */