2 * COPYRIGHT: See COPYING in the top level directory
4 * FILE: dll/opengl/opengl32/wgl.c
5 * PURPOSE: OpenGL32 DLL, WGL functions
10 #include <pseh/pseh2.h>
12 WINE_DEFAULT_DEBUG_CHANNEL(wgl
);
14 static CRITICAL_SECTION dc_data_cs
= {NULL
, -1, 0, 0, 0, 0};
15 static struct wgl_dc_data
* dc_data_list
= NULL
;
17 LIST_ENTRY ContextListHead
;
19 /* FIXME: suboptimal */
25 struct wgl_dc_data
* data
;
26 DWORD objType
= GetObjectType(hdc
);
35 /* Look for the right data identifier */
38 hwnd
= WindowFromDC(hdc
);
42 flags
= WGL_DC_OBJ_DC
;
44 else if(objType
== OBJ_MEMDC
)
53 EnterCriticalSection(&dc_data_cs
);
57 if(data
->owner
.u
== id
.u
)
59 LeaveCriticalSection(&dc_data_cs
);
64 data
= HeapAlloc(GetProcessHeap(), 0, sizeof(*data
));
67 LeaveCriticalSection(&dc_data_cs
);
70 /* initialize the structure */
73 data
->pixelformat
= 0;
76 data
->icd_data
= IntGetIcdData(hdc
);
77 /* Get the number of available formats for this DC once and for all */
79 data
->nb_icd_formats
= data
->icd_data
->DrvDescribePixelFormat(hdc
, 0, 0, NULL
);
81 data
->nb_icd_formats
= 0;
82 TRACE("ICD %S has %u formats for HDC %x.\n", data
->icd_data
->DriverName
, data
->nb_icd_formats
, hdc
);
83 data
->nb_sw_formats
= sw_DescribePixelFormat(hdc
, 0, 0, NULL
);
84 data
->next
= dc_data_list
;
86 LeaveCriticalSection(&dc_data_cs
);
90 void release_dc_data(struct wgl_dc_data
* dc_data
)
95 struct wgl_context
* get_context(HGLRC hglrc
)
97 struct wgl_context
* context
= (struct wgl_context
*)hglrc
;
104 if(context
->magic
!= 'GLRC')
107 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
116 INT WINAPI
wglDescribePixelFormat(HDC hdc
, INT format
, UINT size
, PIXELFORMATDESCRIPTOR
*descr
)
118 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
123 SetLastError(ERROR_INVALID_HANDLE
);
127 ret
= dc_data
->nb_icd_formats
+ dc_data
->nb_sw_formats
;
131 release_dc_data(dc_data
);
134 if((format
== 0) || (format
> ret
) || (size
!= sizeof(*descr
)))
136 release_dc_data(dc_data
);
137 SetLastError(ERROR_INVALID_PARAMETER
);
141 /* Query ICD if needed */
142 if(format
<= dc_data
->nb_icd_formats
)
144 struct ICD_Data
* icd_data
= dc_data
->icd_data
;
145 /* SetPixelFormat may have NULLified this */
147 icd_data
= IntGetIcdData(hdc
);
148 if(!icd_data
->DrvDescribePixelFormat(hdc
, format
, size
, descr
))
155 /* This is a software format */
156 format
-= dc_data
->nb_icd_formats
;
157 if(!sw_DescribePixelFormat(hdc
, format
, size
, descr
))
163 release_dc_data(dc_data
);
167 INT WINAPI
wglChoosePixelFormat(HDC hdc
, const PIXELFORMATDESCRIPTOR
* ppfd
)
169 PIXELFORMATDESCRIPTOR format
, best
;
170 int i
, count
, best_format
;
171 int bestDBuffer
= -1, bestStereo
= -1;
173 TRACE_(wgl
)( "%p %p: size %u version %u flags %u type %u color %u %u,%u,%u,%u "
174 "accum %u depth %u stencil %u aux %u\n",
175 hdc
, ppfd
, ppfd
->nSize
, ppfd
->nVersion
, ppfd
->dwFlags
, ppfd
->iPixelType
,
176 ppfd
->cColorBits
, ppfd
->cRedBits
, ppfd
->cGreenBits
, ppfd
->cBlueBits
, ppfd
->cAlphaBits
,
177 ppfd
->cAccumBits
, ppfd
->cDepthBits
, ppfd
->cStencilBits
, ppfd
->cAuxBuffers
);
179 count
= wglDescribePixelFormat( hdc
, 0, 0, NULL
);
180 if (!count
) return 0;
183 best
.dwFlags
= PFD_GENERIC_FORMAT
;
184 best
.cAlphaBits
= -1;
185 best
.cColorBits
= -1;
186 best
.cDepthBits
= -1;
187 best
.cStencilBits
= -1;
188 best
.cAuxBuffers
= -1;
190 for (i
= 1; i
<= count
; i
++)
192 if (!wglDescribePixelFormat( hdc
, i
, sizeof(format
), &format
)) continue;
194 if (ppfd
->iPixelType
!= format
.iPixelType
)
196 TRACE( "pixel type mismatch for iPixelFormat=%d\n", i
);
200 /* only use bitmap capable formats for bitmap rendering */
201 if ((ppfd
->dwFlags
& PFD_DRAW_TO_BITMAP
) != (format
.dwFlags
& PFD_DRAW_TO_BITMAP
))
203 TRACE( "PFD_DRAW_TO_BITMAP mismatch for iPixelFormat=%d\n", i
);
207 /* only use window capable formats for window rendering */
208 if ((ppfd
->dwFlags
& PFD_DRAW_TO_WINDOW
) != (format
.dwFlags
& PFD_DRAW_TO_WINDOW
))
210 TRACE( "PFD_DRAW_TO_WINDOW mismatch for iPixelFormat=%d\n", i
);
214 /* only use opengl capable formats for opengl rendering */
215 if ((ppfd
->dwFlags
& PFD_SUPPORT_OPENGL
) != (format
.dwFlags
& PFD_SUPPORT_OPENGL
))
217 TRACE( "PFD_SUPPORT_OPENGL mismatch for iPixelFormat=%d\n", i
);
221 /* only use GDI capable formats for GDI rendering */
222 if ((ppfd
->dwFlags
& PFD_SUPPORT_GDI
) != (format
.dwFlags
& PFD_SUPPORT_GDI
))
224 TRACE( "PFD_SUPPORT_GDI mismatch for iPixelFormat=%d\n", i
);
228 /* The behavior of PDF_STEREO/PFD_STEREO_DONTCARE and PFD_DOUBLEBUFFER / PFD_DOUBLEBUFFER_DONTCARE
229 * is not very clear on MSDN. They specify that ChoosePixelFormat tries to match pixel formats
230 * with the flag (PFD_STEREO / PFD_DOUBLEBUFFERING) set. Otherwise it says that it tries to match
231 * formats without the given flag set.
232 * A test on Windows using a Radeon 9500pro on WinXP (the driver doesn't support Stereo)
233 * has indicated that a format without stereo is returned when stereo is unavailable.
234 * So in case PFD_STEREO is set, formats that support it should have priority above formats
235 * without. In case PFD_STEREO_DONTCARE is set, stereo is ignored.
237 * To summarize the following is most likely the correct behavior:
238 * stereo not set -> prefer non-stereo formats, but also accept stereo formats
239 * stereo set -> prefer stereo formats, but also accept non-stereo formats
240 * stereo don't care -> it doesn't matter whether we get stereo or not
242 * In Wine we will treat non-stereo the same way as don't care because it makes
243 * format selection even more complicated and second drivers with Stereo advertise
244 * each format twice anyway.
247 /* Doublebuffer, see the comments above */
248 if (!(ppfd
->dwFlags
& PFD_DOUBLEBUFFER_DONTCARE
))
250 if (((ppfd
->dwFlags
& PFD_DOUBLEBUFFER
) != bestDBuffer
) &&
251 ((format
.dwFlags
& PFD_DOUBLEBUFFER
) == (ppfd
->dwFlags
& PFD_DOUBLEBUFFER
)))
254 if (bestDBuffer
!= -1 && (format
.dwFlags
& PFD_DOUBLEBUFFER
) != bestDBuffer
) continue;
257 /* Stereo, see the comments above. */
258 if (!(ppfd
->dwFlags
& PFD_STEREO_DONTCARE
))
260 if (((ppfd
->dwFlags
& PFD_STEREO
) != bestStereo
) &&
261 ((format
.dwFlags
& PFD_STEREO
) == (ppfd
->dwFlags
& PFD_STEREO
)))
264 if (bestStereo
!= -1 && (format
.dwFlags
& PFD_STEREO
) != bestStereo
) continue;
267 /* Below we will do a number of checks to select the 'best' pixelformat.
268 * We assume the precedence cColorBits > cAlphaBits > cDepthBits > cStencilBits -> cAuxBuffers.
269 * The code works by trying to match the most important options as close as possible.
270 * When a reasonable format is found, we will try to match more options.
271 * It appears (see the opengl32 test) that Windows opengl drivers ignore options
272 * like cColorBits, cAlphaBits and friends if they are set to 0, so they are considered
273 * as DONTCARE. At least Serious Sam TSE relies on this behavior. */
275 if (ppfd
->cColorBits
)
277 if (((ppfd
->cColorBits
> best
.cColorBits
) && (format
.cColorBits
> best
.cColorBits
)) ||
278 ((format
.cColorBits
>= ppfd
->cColorBits
) && (format
.cColorBits
< best
.cColorBits
)))
281 if (best
.cColorBits
!= format
.cColorBits
) /* Do further checks if the format is compatible */
283 TRACE( "color mismatch for iPixelFormat=%d\n", i
);
287 if (ppfd
->cAlphaBits
)
289 if (((ppfd
->cAlphaBits
> best
.cAlphaBits
) && (format
.cAlphaBits
> best
.cAlphaBits
)) ||
290 ((format
.cAlphaBits
>= ppfd
->cAlphaBits
) && (format
.cAlphaBits
< best
.cAlphaBits
)))
293 if (best
.cAlphaBits
!= format
.cAlphaBits
)
295 TRACE( "alpha mismatch for iPixelFormat=%d\n", i
);
299 if (ppfd
->cDepthBits
)
301 if (((ppfd
->cDepthBits
> best
.cDepthBits
) && (format
.cDepthBits
> best
.cDepthBits
)) ||
302 ((format
.cDepthBits
>= ppfd
->cDepthBits
) && (format
.cDepthBits
< best
.cDepthBits
)))
305 if (best
.cDepthBits
!= format
.cDepthBits
)
307 TRACE( "depth mismatch for iPixelFormat=%d\n", i
);
311 if (ppfd
->cStencilBits
)
313 if (((ppfd
->cStencilBits
> best
.cStencilBits
) && (format
.cStencilBits
> best
.cStencilBits
)) ||
314 ((format
.cStencilBits
>= ppfd
->cStencilBits
) && (format
.cStencilBits
< best
.cStencilBits
)))
317 if (best
.cStencilBits
!= format
.cStencilBits
)
319 TRACE( "stencil mismatch for iPixelFormat=%d\n", i
);
323 if (ppfd
->cAuxBuffers
)
325 if (((ppfd
->cAuxBuffers
> best
.cAuxBuffers
) && (format
.cAuxBuffers
> best
.cAuxBuffers
)) ||
326 ((format
.cAuxBuffers
>= ppfd
->cAuxBuffers
) && (format
.cAuxBuffers
< best
.cAuxBuffers
)))
329 if (best
.cAuxBuffers
!= format
.cAuxBuffers
)
331 TRACE( "aux mismatch for iPixelFormat=%d\n", i
);
338 /* Prefer HW accelerated formats */
339 if ((format
.dwFlags
& PFD_GENERIC_FORMAT
) && !(best
.dwFlags
& PFD_GENERIC_FORMAT
))
343 bestDBuffer
= format
.dwFlags
& PFD_DOUBLEBUFFER
;
344 bestStereo
= format
.dwFlags
& PFD_STEREO
;
347 TRACE( "returning %u\n", best_format
);
351 BOOL WINAPI
wglCopyContext(HGLRC hglrcSrc
, HGLRC hglrcDst
, UINT mask
)
353 struct wgl_context
* ctx_src
= get_context(hglrcSrc
);
354 struct wgl_context
* ctx_dst
= get_context(hglrcDst
);
356 if(!ctx_src
|| !ctx_dst
)
358 SetLastError(ERROR_INVALID_HANDLE
);
362 /* Check this is the same pixel format */
363 if((ctx_dst
->icd_data
!= ctx_src
->icd_data
) ||
364 (ctx_dst
->pixelformat
!= ctx_src
->pixelformat
))
366 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
370 if(ctx_src
->icd_data
)
371 return ctx_src
->icd_data
->DrvCopyContext(ctx_src
->dhglrc
, ctx_dst
->dhglrc
, mask
);
373 return sw_CopyContext(ctx_src
->dhglrc
, ctx_dst
->dhglrc
, mask
);
376 HGLRC WINAPI
wglCreateContext(HDC hdc
)
378 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
379 struct wgl_context
* context
;
382 TRACE("Creating context for %p, format %i\n", hdc
);
386 WARN("Not a DC handle!\n");
387 SetLastError(ERROR_INVALID_HANDLE
);
391 if(!dc_data
->pixelformat
)
393 WARN("Pixel format not set!\n");
394 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
398 if(!dc_data
->icd_data
)
400 TRACE("Calling SW implementation.\n");
401 dhglrc
= sw_CreateContext(dc_data
);
406 TRACE("Calling ICD.\n");
407 dhglrc
= dc_data
->icd_data
->DrvCreateContext(hdc
);
413 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
417 context
= HeapAlloc(GetProcessHeap(), 0, sizeof(*context
));
420 WARN("Failed to allocate a context!\n");
421 if(!dc_data
->icd_data
)
422 sw_DeleteContext(dhglrc
);
424 dc_data
->icd_data
->DrvDeleteContext(dhglrc
);
425 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
428 /* Copy info from the DC data */
429 context
->dhglrc
= dhglrc
;
430 context
->icd_data
= dc_data
->icd_data
;
431 context
->pixelformat
= dc_data
->pixelformat
;
432 context
->thread_id
= 0;
434 /* Insert into the list */
435 InsertTailList(&ContextListHead
, &context
->ListEntry
);
437 context
->magic
= 'GLRC';
439 return (HGLRC
)context
;
442 HGLRC WINAPI
wglCreateLayerContext(HDC hdc
, int iLayerPlane
)
444 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
445 struct wgl_context
* context
;
450 SetLastError(ERROR_INVALID_HANDLE
);
454 if(!dc_data
->pixelformat
)
456 release_dc_data(dc_data
);
457 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
461 if(!dc_data
->icd_data
)
465 /* Not supported in SW implementation */
466 release_dc_data(dc_data
);
467 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
470 dhglrc
= sw_CreateContext(dc_data
);
474 dhglrc
= dc_data
->icd_data
->DrvCreateLayerContext(hdc
, iLayerPlane
);
479 release_dc_data(dc_data
);
480 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
484 context
= HeapAlloc(GetProcessHeap(), 0, sizeof(*context
));
487 if(!dc_data
->icd_data
)
488 sw_DeleteContext(dhglrc
);
490 dc_data
->icd_data
->DrvDeleteContext(dhglrc
);
491 release_dc_data(dc_data
);
492 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
495 /* Copy info from the DC data */
496 context
->dhglrc
= dhglrc
;
497 context
->icd_data
= dc_data
->icd_data
;
498 context
->pixelformat
= dc_data
->pixelformat
;
499 context
->thread_id
= 0;
501 context
->magic
= 'GLRC';
503 release_dc_data(dc_data
);
504 return (HGLRC
)context
;
507 BOOL WINAPI
wglDeleteContext(HGLRC hglrc
)
509 struct wgl_context
* context
= get_context(hglrc
);
510 LONG thread_id
= GetCurrentThreadId();
514 SetLastError(ERROR_INVALID_HANDLE
);
518 /* Own this context before touching it */
519 if(InterlockedCompareExchange(&context
->thread_id
, thread_id
, 0) != 0)
521 /* We can't delete a context current to another thread */
522 if(context
->thread_id
!= thread_id
)
524 SetLastError(ERROR_BUSY
);
528 /* This is in our thread. Release and try again */
529 if(!wglMakeCurrent(NULL
, NULL
))
531 return wglDeleteContext(hglrc
);
534 if(context
->icd_data
)
535 context
->icd_data
->DrvDeleteContext(context
->dhglrc
);
537 sw_DeleteContext(context
->dhglrc
);
540 RemoveEntryList(&context
->ListEntry
);
541 HeapFree(GetProcessHeap(), 0, context
);
546 BOOL WINAPI
wglDescribeLayerPlane(HDC hdc
,
550 LPLAYERPLANEDESCRIPTOR plpd
)
552 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
556 SetLastError(ERROR_INVALID_HANDLE
);
560 if(iPixelFormat
<= dc_data
->nb_icd_formats
)
561 return dc_data
->icd_data
->DrvDescribeLayerPlane(hdc
, iPixelFormat
, iLayerPlane
, nBytes
, plpd
);
563 /* SW implementation doesn't support this */
567 HGLRC WINAPI
wglGetCurrentContext(void)
569 return IntGetCurrentRC();
572 HDC WINAPI
wglGetCurrentDC(void)
574 return IntGetCurrentDC();
577 PROC WINAPI
wglGetDefaultProcAddress(LPCSTR lpszProc
)
579 /* undocumented... */
583 int WINAPI
wglGetLayerPaletteEntries(HDC hdc
, int iLayerPlane
, int iStart
, int cEntries
, COLORREF
* pcr
)
585 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
589 SetLastError(ERROR_INVALID_HANDLE
);
593 if(!dc_data
->pixelformat
)
595 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
599 if(dc_data
->icd_data
)
600 return dc_data
->icd_data
->DrvGetLayerPaletteEntries(hdc
, iLayerPlane
, iStart
, cEntries
, pcr
);
602 /* SW implementation doesn't support this */
606 INT WINAPI
wglGetPixelFormat(HDC hdc
)
609 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
613 SetLastError(ERROR_INVALID_HANDLE
);
617 ret
= dc_data
->pixelformat
;
618 release_dc_data(dc_data
);
622 PROC WINAPI
wglGetProcAddress(LPCSTR name
)
624 struct wgl_context
* context
= get_context(IntGetCurrentRC());
628 /* This shall fail for opengl 1.1 functions */
629 #define USE_GL_FUNC(func, w, x, y, z) if(!strcmp(name, "gl" #func)) return NULL;
633 if(context
->icd_data
)
634 return context
->icd_data
->DrvGetProcAddress(name
);
635 return sw_GetProcAddress(name
);
638 void APIENTRY
set_api_table(const GLCLTPROCTABLE
* table
)
640 IntSetCurrentDispatchTable(&table
->glDispatchTable
);
643 BOOL WINAPI
wglMakeCurrent(HDC hdc
, HGLRC hglrc
)
645 struct wgl_context
* ctx
= get_context(hglrc
);
646 struct wgl_context
* old_ctx
= get_context(IntGetCurrentRC());
647 const GLCLTPROCTABLE
* apiTable
;
648 LONG thread_id
= (LONG
)GetCurrentThreadId();
652 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
655 ERR("wglMakeCurrent was passed an invalid DC handle.\n");
656 SetLastError(ERROR_INVALID_HANDLE
);
660 /* Check compatibility */
661 if((ctx
->icd_data
!= dc_data
->icd_data
) || (ctx
->pixelformat
!= dc_data
->pixelformat
))
663 /* That's bad, man */
664 ERR("HGLRC %p and HDC %p are not compatible.\n", hglrc
, hdc
);
665 release_dc_data(dc_data
);
666 SetLastError(ERROR_INVALID_HANDLE
);
670 /* Set the thread ID */
671 if(InterlockedCompareExchange(&ctx
->thread_id
, thread_id
, 0) != 0)
673 /* Already current for a thread. Maybe it's us ? */
674 release_dc_data(dc_data
);
675 if(ctx
->thread_id
!= thread_id
)
676 SetLastError(ERROR_BUSY
);
677 return (ctx
->thread_id
== thread_id
);
683 if(old_ctx
->icd_data
)
684 old_ctx
->icd_data
->DrvReleaseContext(old_ctx
->dhglrc
);
686 sw_ReleaseContext(old_ctx
->dhglrc
);
687 InterlockedExchange(&old_ctx
->thread_id
, 0);
690 /* Call the ICD or SW implementation */
693 apiTable
= ctx
->icd_data
->DrvSetContext(hdc
, ctx
->dhglrc
, set_api_table
);
696 ERR("DrvSetContext failed!\n");
698 InterlockedExchange(&ctx
->thread_id
, 0);
699 IntSetCurrentDispatchTable(&StubTable
.glDispatchTable
);
700 SetLastError(ERROR_INVALID_PARAMETER
);
703 set_api_table(apiTable
);
704 /* Make it current */
705 IntMakeCurrent(hglrc
, hdc
, dc_data
);
709 /* We must set current before, SW implementation relies on it */
710 IntMakeCurrent(hglrc
, hdc
, dc_data
);
711 if(!sw_SetContext(dc_data
, ctx
->dhglrc
))
713 ERR("sw_SetContext failed!\n");
715 IntMakeCurrent(NULL
, NULL
, NULL
);
716 InterlockedExchange(&ctx
->thread_id
, 0);
717 SetLastError(ERROR_INVALID_PARAMETER
);
724 if(old_ctx
->icd_data
)
725 old_ctx
->icd_data
->DrvReleaseContext(old_ctx
->dhglrc
);
727 sw_ReleaseContext(old_ctx
->dhglrc
);
728 InterlockedExchange(&old_ctx
->thread_id
, 0);
730 IntMakeCurrent(NULL
, NULL
, NULL
);
731 /* Reset the no-op table */
732 set_api_table(&StubTable
);
733 /* Test conformance (extreme cases) */
734 return hglrc
== NULL
;
738 /* Winetest conformance */
739 if (GetObjectType( hdc
) != OBJ_DC
&& GetObjectType( hdc
) != OBJ_MEMDC
)
741 ERR( "Error: hdc is not a DC handle!\n");
742 SetLastError( ERROR_INVALID_HANDLE
);
750 BOOL WINAPI
wglRealizeLayerPalette(HDC hdc
,
754 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
758 SetLastError(ERROR_INVALID_HANDLE
);
762 if(!dc_data
->pixelformat
)
764 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
768 if(dc_data
->icd_data
)
769 return dc_data
->icd_data
->DrvRealizeLayerPalette(hdc
, iLayerPlane
, bRealize
);
771 /* SW implementation doesn't support this */
775 int WINAPI
wglSetLayerPaletteEntries(HDC hdc
,
781 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
785 SetLastError(ERROR_INVALID_HANDLE
);
789 if(!dc_data
->pixelformat
)
791 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
795 if(dc_data
->icd_data
)
796 return dc_data
->icd_data
->DrvSetLayerPaletteEntries(hdc
, iLayerPlane
, iStart
, cEntries
, pcr
);
798 /* SW implementation doesn't support this */
802 BOOL WINAPI
wglSetPixelFormat(HDC hdc
, INT format
, const PIXELFORMATDESCRIPTOR
*descr
)
804 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
808 TRACE("HDC %p, format %i.\n", hdc
, format
);
812 WARN("Not a valid DC!.\n");
813 SetLastError(ERROR_INVALID_HANDLE
);
819 WARN("format == 0!\n");
820 SetLastError(ERROR_INVALID_PARAMETER
);
824 if(dc_data
->pixelformat
)
826 TRACE("DC format already set, %i.\n", dc_data
->pixelformat
);
827 return (format
== dc_data
->pixelformat
);
830 if(format
<= dc_data
->nb_icd_formats
)
832 TRACE("Calling ICD.\n");
833 ret
= dc_data
->icd_data
->DrvSetPixelFormat(hdc
, format
);
837 dc_data
->pixelformat
= format
;
842 sw_format
= format
- dc_data
->nb_icd_formats
;
843 if(sw_format
<= dc_data
->nb_sw_formats
)
845 TRACE("Calling SW implementation.\n");
846 ret
= sw_SetPixelFormat(hdc
, dc_data
, sw_format
);
850 /* This is now officially a software-only HDC */
851 dc_data
->icd_data
= NULL
;
852 dc_data
->pixelformat
= format
;
857 TRACE("Invalid pixel format!\n");
858 SetLastError(ERROR_INVALID_PARAMETER
);
862 BOOL WINAPI
wglShareLists(HGLRC hglrcSrc
, HGLRC hglrcDst
)
864 struct wgl_context
* ctx_src
= get_context(hglrcSrc
);
865 struct wgl_context
* ctx_dst
= get_context(hglrcDst
);
867 if(!ctx_src
|| !ctx_dst
)
869 SetLastError(ERROR_INVALID_HANDLE
);
873 /* Check this is the same pixel format */
874 if((ctx_dst
->icd_data
!= ctx_src
->icd_data
) ||
875 (ctx_dst
->pixelformat
!= ctx_src
->pixelformat
))
877 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
881 if(ctx_src
->icd_data
)
882 return ctx_src
->icd_data
->DrvShareLists(ctx_src
->dhglrc
, ctx_dst
->dhglrc
);
884 return sw_ShareLists(ctx_src
->dhglrc
, ctx_dst
->dhglrc
);
887 BOOL WINAPI DECLSPEC_HOTPATCH
wglSwapBuffers(HDC hdc
)
889 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
893 SetLastError(ERROR_INVALID_HANDLE
);
897 if(!dc_data
->pixelformat
)
899 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
903 if(dc_data
->icd_data
)
904 return dc_data
->icd_data
->DrvSwapBuffers(hdc
);
906 return sw_SwapBuffers(hdc
, dc_data
);
909 BOOL WINAPI
wglSwapLayerBuffers(HDC hdc
, UINT fuPlanes
)
914 DWORD WINAPI
wglSwapMultipleBuffers(UINT count
, CONST WGLSWAP
* toSwap
)
919 /* Clean up on DLL unload */
921 IntDeleteAllContexts(void)
923 struct wgl_context
* context
;
924 LIST_ENTRY
* Entry
= ContextListHead
.Flink
;
926 while (Entry
!= &ContextListHead
)
928 context
= CONTAINING_RECORD(Entry
, struct wgl_context
, ListEntry
);
929 wglDeleteContext((HGLRC
)context
);
930 Entry
= ContextListHead
.Flink
;