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