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 */
22 get_dc_data_ex(HDC hdc
, INT format
, UINT size
, PIXELFORMATDESCRIPTOR
*descr
)
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
, format
, size
, descr
);
81 data
->nb_icd_formats
= 0;
82 TRACE("ICD %S has %u formats for HDC %x.\n", data
->icd_data
? data
->icd_data
->DriverName
: NULL
, 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
);
94 return get_dc_data_ex(hdc
, 0, 0, NULL
);
97 void release_dc_data(struct wgl_dc_data
* dc_data
)
102 struct wgl_context
* get_context(HGLRC hglrc
)
104 struct wgl_context
* context
= (struct wgl_context
*)hglrc
;
111 if(context
->magic
!= 'GLRC')
114 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
123 INT WINAPI
wglDescribePixelFormat(HDC hdc
, INT format
, UINT size
, PIXELFORMATDESCRIPTOR
*descr
)
125 struct wgl_dc_data
* dc_data
= get_dc_data_ex(hdc
, format
, size
, descr
);
130 SetLastError(ERROR_INVALID_HANDLE
);
134 ret
= dc_data
->nb_icd_formats
+ dc_data
->nb_sw_formats
;
138 release_dc_data(dc_data
);
141 if((format
<= 0) || (format
> ret
) || (size
< sizeof(*descr
)))
143 release_dc_data(dc_data
);
144 SetLastError(ERROR_INVALID_PARAMETER
);
148 /* Query ICD if needed */
149 if(format
<= dc_data
->nb_icd_formats
)
151 struct ICD_Data
* icd_data
= dc_data
->icd_data
;
152 /* SetPixelFormat may have NULLified this */
154 icd_data
= IntGetIcdData(hdc
);
155 if(!icd_data
->DrvDescribePixelFormat(hdc
, format
, size
, descr
))
162 /* This is a software format */
163 format
-= dc_data
->nb_icd_formats
;
164 if(!sw_DescribePixelFormat(hdc
, format
, size
, descr
))
170 release_dc_data(dc_data
);
174 INT WINAPI
wglChoosePixelFormat(HDC hdc
, const PIXELFORMATDESCRIPTOR
* ppfd
)
176 PIXELFORMATDESCRIPTOR format
, best
;
177 int i
, count
, best_format
;
178 int bestDBuffer
= -1, bestStereo
= -1;
180 TRACE_(wgl
)( "%p %p: size %u version %u flags %u type %u color %u %u,%u,%u,%u "
181 "accum %u depth %u stencil %u aux %u\n",
182 hdc
, ppfd
, ppfd
->nSize
, ppfd
->nVersion
, ppfd
->dwFlags
, ppfd
->iPixelType
,
183 ppfd
->cColorBits
, ppfd
->cRedBits
, ppfd
->cGreenBits
, ppfd
->cBlueBits
, ppfd
->cAlphaBits
,
184 ppfd
->cAccumBits
, ppfd
->cDepthBits
, ppfd
->cStencilBits
, ppfd
->cAuxBuffers
);
186 count
= wglDescribePixelFormat( hdc
, 0, 0, NULL
);
187 if (!count
) return 0;
190 best
.dwFlags
= PFD_GENERIC_FORMAT
;
191 best
.cAlphaBits
= -1;
192 best
.cColorBits
= -1;
193 best
.cDepthBits
= -1;
194 best
.cStencilBits
= -1;
195 best
.cAuxBuffers
= -1;
197 for (i
= 1; i
<= count
; i
++)
199 if (!wglDescribePixelFormat( hdc
, i
, sizeof(format
), &format
)) continue;
201 if (ppfd
->iPixelType
!= format
.iPixelType
)
203 TRACE( "pixel type mismatch for iPixelFormat=%d\n", i
);
207 /* only use bitmap capable formats for bitmap rendering */
208 if ((ppfd
->dwFlags
& PFD_DRAW_TO_BITMAP
) && !(format
.dwFlags
& PFD_DRAW_TO_BITMAP
))
210 TRACE( "PFD_DRAW_TO_BITMAP mismatch for iPixelFormat=%d\n", i
);
214 /* only use window capable formats for window rendering */
215 if ((ppfd
->dwFlags
& PFD_DRAW_TO_WINDOW
) && !(format
.dwFlags
& PFD_DRAW_TO_WINDOW
))
217 TRACE( "PFD_DRAW_TO_WINDOW mismatch for iPixelFormat=%d\n", i
);
221 /* only use opengl capable formats for opengl rendering */
222 if ((ppfd
->dwFlags
& PFD_SUPPORT_OPENGL
) && !(format
.dwFlags
& PFD_SUPPORT_OPENGL
))
224 TRACE( "PFD_SUPPORT_OPENGL mismatch for iPixelFormat=%d\n", i
);
228 /* only use GDI capable formats for GDI rendering */
229 if ((ppfd
->dwFlags
& PFD_SUPPORT_GDI
) && !(format
.dwFlags
& PFD_SUPPORT_GDI
))
231 TRACE( "PFD_SUPPORT_GDI mismatch for iPixelFormat=%d\n", i
);
235 /* The behavior of PDF_STEREO/PFD_STEREO_DONTCARE and PFD_DOUBLEBUFFER / PFD_DOUBLEBUFFER_DONTCARE
236 * is not very clear on MSDN. They specify that ChoosePixelFormat tries to match pixel formats
237 * with the flag (PFD_STEREO / PFD_DOUBLEBUFFERING) set. Otherwise it says that it tries to match
238 * formats without the given flag set.
239 * A test on Windows using a Radeon 9500pro on WinXP (the driver doesn't support Stereo)
240 * has indicated that a format without stereo is returned when stereo is unavailable.
241 * So in case PFD_STEREO is set, formats that support it should have priority above formats
242 * without. In case PFD_STEREO_DONTCARE is set, stereo is ignored.
244 * To summarize the following is most likely the correct behavior:
245 * stereo not set -> prefer non-stereo formats, but also accept stereo formats
246 * stereo set -> prefer stereo formats, but also accept non-stereo formats
247 * stereo don't care -> it doesn't matter whether we get stereo or not
249 * In Wine we will treat non-stereo the same way as don't care because it makes
250 * format selection even more complicated and second drivers with Stereo advertise
251 * each format twice anyway.
254 /* Doublebuffer, see the comments above */
255 if (!(ppfd
->dwFlags
& PFD_DOUBLEBUFFER_DONTCARE
))
257 if (((ppfd
->dwFlags
& PFD_DOUBLEBUFFER
) != bestDBuffer
) &&
258 ((format
.dwFlags
& PFD_DOUBLEBUFFER
) == (ppfd
->dwFlags
& PFD_DOUBLEBUFFER
)))
261 if (bestDBuffer
!= -1 && (format
.dwFlags
& PFD_DOUBLEBUFFER
) != bestDBuffer
) continue;
264 /* Stereo, see the comments above. */
265 if (!(ppfd
->dwFlags
& PFD_STEREO_DONTCARE
))
267 if (((ppfd
->dwFlags
& PFD_STEREO
) != bestStereo
) &&
268 ((format
.dwFlags
& PFD_STEREO
) == (ppfd
->dwFlags
& PFD_STEREO
)))
271 if (bestStereo
!= -1 && (format
.dwFlags
& PFD_STEREO
) != bestStereo
) continue;
274 /* Below we will do a number of checks to select the 'best' pixelformat.
275 * We assume the precedence cColorBits > cAlphaBits > cDepthBits > cStencilBits -> cAuxBuffers.
276 * The code works by trying to match the most important options as close as possible.
277 * When a reasonable format is found, we will try to match more options.
278 * It appears (see the opengl32 test) that Windows opengl drivers ignore options
279 * like cColorBits, cAlphaBits and friends if they are set to 0, so they are considered
280 * as DONTCARE. At least Serious Sam TSE relies on this behavior. */
282 if (ppfd
->cColorBits
)
284 if (((ppfd
->cColorBits
> best
.cColorBits
) && (format
.cColorBits
> best
.cColorBits
)) ||
285 ((format
.cColorBits
>= ppfd
->cColorBits
) && (format
.cColorBits
< best
.cColorBits
)))
288 if (best
.cColorBits
!= format
.cColorBits
) /* Do further checks if the format is compatible */
290 TRACE( "color mismatch for iPixelFormat=%d\n", i
);
294 if (ppfd
->cAlphaBits
)
296 if (((ppfd
->cAlphaBits
> best
.cAlphaBits
) && (format
.cAlphaBits
> best
.cAlphaBits
)) ||
297 ((format
.cAlphaBits
>= ppfd
->cAlphaBits
) && (format
.cAlphaBits
< best
.cAlphaBits
)))
300 if (best
.cAlphaBits
!= format
.cAlphaBits
)
302 TRACE( "alpha mismatch for iPixelFormat=%d\n", i
);
306 if (ppfd
->cDepthBits
)
308 if (((ppfd
->cDepthBits
> best
.cDepthBits
) && (format
.cDepthBits
> best
.cDepthBits
)) ||
309 ((format
.cDepthBits
>= ppfd
->cDepthBits
) && (format
.cDepthBits
< best
.cDepthBits
)))
312 if (best
.cDepthBits
!= format
.cDepthBits
)
314 TRACE( "depth mismatch for iPixelFormat=%d\n", i
);
318 if (ppfd
->cStencilBits
)
320 if (((ppfd
->cStencilBits
> best
.cStencilBits
) && (format
.cStencilBits
> best
.cStencilBits
)) ||
321 ((format
.cStencilBits
>= ppfd
->cStencilBits
) && (format
.cStencilBits
< best
.cStencilBits
)))
324 if (best
.cStencilBits
!= format
.cStencilBits
)
326 TRACE( "stencil mismatch for iPixelFormat=%d\n", i
);
330 if (ppfd
->cAuxBuffers
)
332 if (((ppfd
->cAuxBuffers
> best
.cAuxBuffers
) && (format
.cAuxBuffers
> best
.cAuxBuffers
)) ||
333 ((format
.cAuxBuffers
>= ppfd
->cAuxBuffers
) && (format
.cAuxBuffers
< best
.cAuxBuffers
)))
336 if (best
.cAuxBuffers
!= format
.cAuxBuffers
)
338 TRACE( "aux mismatch for iPixelFormat=%d\n", i
);
345 /* Prefer HW accelerated formats */
346 if ((format
.dwFlags
& PFD_GENERIC_FORMAT
) && !(best
.dwFlags
& PFD_GENERIC_FORMAT
))
350 bestDBuffer
= format
.dwFlags
& PFD_DOUBLEBUFFER
;
351 bestStereo
= format
.dwFlags
& PFD_STEREO
;
354 TRACE( "returning %u\n", best_format
);
358 BOOL WINAPI
wglCopyContext(HGLRC hglrcSrc
, HGLRC hglrcDst
, UINT mask
)
360 struct wgl_context
* ctx_src
= get_context(hglrcSrc
);
361 struct wgl_context
* ctx_dst
= get_context(hglrcDst
);
363 if(!ctx_src
|| !ctx_dst
)
365 SetLastError(ERROR_INVALID_HANDLE
);
369 /* Check this is the same pixel format */
370 if((ctx_dst
->icd_data
!= ctx_src
->icd_data
) ||
371 (ctx_dst
->pixelformat
!= ctx_src
->pixelformat
))
373 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
377 if(ctx_src
->icd_data
)
378 return ctx_src
->icd_data
->DrvCopyContext(ctx_src
->dhglrc
, ctx_dst
->dhglrc
, mask
);
380 return sw_CopyContext(ctx_src
->dhglrc
, ctx_dst
->dhglrc
, mask
);
383 HGLRC WINAPI
wglCreateContext(HDC hdc
)
385 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
386 struct wgl_context
* context
;
389 TRACE("Creating context for %p.\n", hdc
);
393 WARN("Not a DC handle!\n");
394 SetLastError(ERROR_INVALID_HANDLE
);
398 if(!dc_data
->pixelformat
)
400 WARN("Pixel format not set!\n");
401 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
405 if(!dc_data
->icd_data
)
407 TRACE("Calling SW implementation.\n");
408 dhglrc
= sw_CreateContext(dc_data
);
413 TRACE("Calling ICD.\n");
414 dhglrc
= dc_data
->icd_data
->DrvCreateContext(hdc
);
420 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
424 context
= HeapAlloc(GetProcessHeap(), 0, sizeof(*context
));
427 WARN("Failed to allocate a context!\n");
428 if(!dc_data
->icd_data
)
429 sw_DeleteContext(dhglrc
);
431 dc_data
->icd_data
->DrvDeleteContext(dhglrc
);
432 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
435 /* Copy info from the DC data */
436 context
->dhglrc
= dhglrc
;
437 context
->icd_data
= dc_data
->icd_data
;
438 context
->pixelformat
= dc_data
->pixelformat
;
439 context
->thread_id
= 0;
441 /* Insert into the list */
442 InsertTailList(&ContextListHead
, &context
->ListEntry
);
444 context
->magic
= 'GLRC';
446 return (HGLRC
)context
;
449 HGLRC WINAPI
wglCreateLayerContext(HDC hdc
, int iLayerPlane
)
451 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
452 struct wgl_context
* context
;
457 SetLastError(ERROR_INVALID_HANDLE
);
461 if(!dc_data
->pixelformat
)
463 release_dc_data(dc_data
);
464 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
468 if(!dc_data
->icd_data
)
472 /* Not supported in SW implementation */
473 release_dc_data(dc_data
);
474 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
477 dhglrc
= sw_CreateContext(dc_data
);
481 dhglrc
= dc_data
->icd_data
->DrvCreateLayerContext(hdc
, iLayerPlane
);
486 release_dc_data(dc_data
);
487 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
491 context
= HeapAlloc(GetProcessHeap(), 0, sizeof(*context
));
494 if(!dc_data
->icd_data
)
495 sw_DeleteContext(dhglrc
);
497 dc_data
->icd_data
->DrvDeleteContext(dhglrc
);
498 release_dc_data(dc_data
);
499 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
502 /* Copy info from the DC data */
503 context
->dhglrc
= dhglrc
;
504 context
->icd_data
= dc_data
->icd_data
;
505 context
->pixelformat
= dc_data
->pixelformat
;
506 context
->thread_id
= 0;
508 context
->magic
= 'GLRC';
510 release_dc_data(dc_data
);
511 return (HGLRC
)context
;
514 BOOL WINAPI
wglDeleteContext(HGLRC hglrc
)
516 struct wgl_context
* context
= get_context(hglrc
);
517 LONG thread_id
= GetCurrentThreadId();
521 SetLastError(ERROR_INVALID_HANDLE
);
525 /* Own this context before touching it */
526 if(InterlockedCompareExchange(&context
->thread_id
, thread_id
, 0) != 0)
528 /* We can't delete a context current to another thread */
529 if(context
->thread_id
!= thread_id
)
531 SetLastError(ERROR_BUSY
);
535 /* This is in our thread. Release and try again */
536 if(!wglMakeCurrent(NULL
, NULL
))
538 return wglDeleteContext(hglrc
);
541 if(context
->icd_data
)
542 context
->icd_data
->DrvDeleteContext(context
->dhglrc
);
544 sw_DeleteContext(context
->dhglrc
);
547 RemoveEntryList(&context
->ListEntry
);
548 HeapFree(GetProcessHeap(), 0, context
);
553 BOOL WINAPI
wglDescribeLayerPlane(HDC hdc
,
557 LPLAYERPLANEDESCRIPTOR plpd
)
559 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
563 SetLastError(ERROR_INVALID_HANDLE
);
567 if(iPixelFormat
<= dc_data
->nb_icd_formats
)
568 return dc_data
->icd_data
->DrvDescribeLayerPlane(hdc
, iPixelFormat
, iLayerPlane
, nBytes
, plpd
);
570 /* SW implementation doesn't support this */
574 HGLRC WINAPI
wglGetCurrentContext(void)
576 return IntGetCurrentRC();
579 HDC WINAPI
wglGetCurrentDC(void)
581 return IntGetCurrentDC();
584 PROC WINAPI
wglGetDefaultProcAddress(LPCSTR lpszProc
)
586 /* undocumented... */
590 int WINAPI
wglGetLayerPaletteEntries(HDC hdc
, int iLayerPlane
, int iStart
, int cEntries
, COLORREF
* pcr
)
592 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
596 SetLastError(ERROR_INVALID_HANDLE
);
600 if(!dc_data
->pixelformat
)
602 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
606 if(dc_data
->icd_data
)
607 return dc_data
->icd_data
->DrvGetLayerPaletteEntries(hdc
, iLayerPlane
, iStart
, cEntries
, pcr
);
609 /* SW implementation doesn't support this */
613 INT WINAPI
wglGetPixelFormat(HDC hdc
)
616 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
620 SetLastError(ERROR_INVALID_HANDLE
);
624 ret
= dc_data
->pixelformat
;
625 release_dc_data(dc_data
);
629 PROC WINAPI
wglGetProcAddress(LPCSTR name
)
631 struct wgl_context
* context
= get_context(IntGetCurrentRC());
635 /* This shall fail for opengl 1.1 functions */
636 #define USE_GL_FUNC(func, w, x, y, z) if(!strcmp(name, "gl" #func)) return NULL;
640 if(context
->icd_data
)
641 return context
->icd_data
->DrvGetProcAddress(name
);
642 return sw_GetProcAddress(name
);
645 void APIENTRY
set_api_table(const GLCLTPROCTABLE
* table
)
647 IntSetCurrentDispatchTable(&table
->glDispatchTable
);
650 BOOL WINAPI
wglMakeCurrent(HDC hdc
, HGLRC hglrc
)
652 struct wgl_context
* ctx
= get_context(hglrc
);
653 struct wgl_context
* old_ctx
= get_context(IntGetCurrentRC());
654 const GLCLTPROCTABLE
* apiTable
;
655 LONG thread_id
= (LONG
)GetCurrentThreadId();
659 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
662 ERR("wglMakeCurrent was passed an invalid DC handle.\n");
663 SetLastError(ERROR_INVALID_HANDLE
);
667 /* Check compatibility */
668 if((ctx
->icd_data
!= dc_data
->icd_data
) || (ctx
->pixelformat
!= dc_data
->pixelformat
))
670 /* That's bad, man */
671 ERR("HGLRC %p and HDC %p are not compatible.\n", hglrc
, hdc
);
672 release_dc_data(dc_data
);
673 SetLastError(ERROR_INVALID_HANDLE
);
677 /* Set the thread ID */
678 if(InterlockedCompareExchange(&ctx
->thread_id
, thread_id
, 0) != 0)
680 /* Already current for a thread. Maybe it's us ? */
681 release_dc_data(dc_data
);
682 if(ctx
->thread_id
!= thread_id
)
683 SetLastError(ERROR_BUSY
);
684 return (ctx
->thread_id
== thread_id
);
690 if(old_ctx
->icd_data
)
691 old_ctx
->icd_data
->DrvReleaseContext(old_ctx
->dhglrc
);
693 sw_ReleaseContext(old_ctx
->dhglrc
);
694 InterlockedExchange(&old_ctx
->thread_id
, 0);
697 /* Call the ICD or SW implementation */
700 apiTable
= ctx
->icd_data
->DrvSetContext(hdc
, ctx
->dhglrc
, set_api_table
);
703 ERR("DrvSetContext failed!\n");
705 InterlockedExchange(&ctx
->thread_id
, 0);
706 IntSetCurrentDispatchTable(NULL
);
707 SetLastError(ERROR_INVALID_PARAMETER
);
710 set_api_table(apiTable
);
711 /* Make it current */
712 IntMakeCurrent(hglrc
, hdc
, dc_data
);
716 /* We must set current before, SW implementation relies on it */
717 IntMakeCurrent(hglrc
, hdc
, dc_data
);
718 if(!sw_SetContext(dc_data
, ctx
->dhglrc
))
720 ERR("sw_SetContext failed!\n");
722 IntMakeCurrent(NULL
, NULL
, NULL
);
723 InterlockedExchange(&ctx
->thread_id
, 0);
724 SetLastError(ERROR_INVALID_PARAMETER
);
731 if(old_ctx
->icd_data
)
732 old_ctx
->icd_data
->DrvReleaseContext(old_ctx
->dhglrc
);
734 sw_ReleaseContext(old_ctx
->dhglrc
);
735 InterlockedExchange(&old_ctx
->thread_id
, 0);
737 IntMakeCurrent(NULL
, NULL
, NULL
);
738 IntSetCurrentDispatchTable(NULL
);
739 /* Test conformance (extreme cases) */
740 return hglrc
== NULL
;
744 /* Winetest conformance */
745 DWORD objType
= GetObjectType(hdc
);
746 if (objType
!= OBJ_DC
&& objType
!= OBJ_MEMDC
)
750 ERR("hdc (%p) is not a DC handle (ObjectType: %d)!\n", hdc
, objType
);
752 SetLastError( ERROR_INVALID_HANDLE
);
760 BOOL WINAPI
wglRealizeLayerPalette(HDC hdc
,
764 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
768 SetLastError(ERROR_INVALID_HANDLE
);
772 if(!dc_data
->pixelformat
)
774 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
778 if(dc_data
->icd_data
)
779 return dc_data
->icd_data
->DrvRealizeLayerPalette(hdc
, iLayerPlane
, bRealize
);
781 /* SW implementation doesn't support this */
785 int WINAPI
wglSetLayerPaletteEntries(HDC hdc
,
791 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
795 SetLastError(ERROR_INVALID_HANDLE
);
799 if(!dc_data
->pixelformat
)
801 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
805 if(dc_data
->icd_data
)
806 return dc_data
->icd_data
->DrvSetLayerPaletteEntries(hdc
, iLayerPlane
, iStart
, cEntries
, pcr
);
808 /* SW implementation doesn't support this */
812 BOOL WINAPI
wglSetPixelFormat(HDC hdc
, INT format
, const PIXELFORMATDESCRIPTOR
*descr
)
814 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
818 TRACE("HDC %p, format %i.\n", hdc
, format
);
822 WARN("Not a valid DC!.\n");
823 SetLastError(ERROR_INVALID_HANDLE
);
829 WARN("format == 0!\n");
830 SetLastError(ERROR_INVALID_PARAMETER
);
834 if(dc_data
->pixelformat
)
836 TRACE("DC format already set, %i.\n", dc_data
->pixelformat
);
837 return (format
== dc_data
->pixelformat
);
840 if(format
<= dc_data
->nb_icd_formats
)
842 TRACE("Calling ICD.\n");
843 ret
= dc_data
->icd_data
->DrvSetPixelFormat(hdc
, format
);
847 dc_data
->pixelformat
= format
;
852 sw_format
= format
- dc_data
->nb_icd_formats
;
853 if(sw_format
<= dc_data
->nb_sw_formats
)
855 TRACE("Calling SW implementation.\n");
856 ret
= sw_SetPixelFormat(hdc
, dc_data
, sw_format
);
860 /* This is now officially a software-only HDC */
861 dc_data
->icd_data
= NULL
;
862 dc_data
->pixelformat
= format
;
867 TRACE("Invalid pixel format!\n");
868 SetLastError(ERROR_INVALID_PARAMETER
);
872 BOOL WINAPI
wglShareLists(HGLRC hglrcSrc
, HGLRC hglrcDst
)
874 struct wgl_context
* ctx_src
= get_context(hglrcSrc
);
875 struct wgl_context
* ctx_dst
= get_context(hglrcDst
);
877 if(!ctx_src
|| !ctx_dst
)
879 SetLastError(ERROR_INVALID_HANDLE
);
883 /* Check this is the same pixel format */
884 if((ctx_dst
->icd_data
!= ctx_src
->icd_data
) ||
885 (ctx_dst
->pixelformat
!= ctx_src
->pixelformat
))
887 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
891 if(ctx_src
->icd_data
)
892 return ctx_src
->icd_data
->DrvShareLists(ctx_src
->dhglrc
, ctx_dst
->dhglrc
);
894 return sw_ShareLists(ctx_src
->dhglrc
, ctx_dst
->dhglrc
);
897 BOOL WINAPI DECLSPEC_HOTPATCH
wglSwapBuffers(HDC hdc
)
899 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
903 SetLastError(ERROR_INVALID_HANDLE
);
907 if(!dc_data
->pixelformat
)
909 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
913 if(dc_data
->icd_data
)
914 return dc_data
->icd_data
->DrvSwapBuffers(hdc
);
916 return sw_SwapBuffers(hdc
, dc_data
);
919 BOOL WINAPI
wglSwapLayerBuffers(HDC hdc
, UINT fuPlanes
)
924 DWORD WINAPI
wglSwapMultipleBuffers(UINT count
, CONST WGLSWAP
* toSwap
)
929 /* Clean up on DLL unload */
931 IntDeleteAllContexts(void)
933 struct wgl_context
* context
;
934 LIST_ENTRY
* Entry
= ContextListHead
.Flink
;
936 while (Entry
!= &ContextListHead
)
938 context
= CONTAINING_RECORD(Entry
, struct wgl_context
, ListEntry
);
939 wglDeleteContext((HGLRC
)context
);
940 Entry
= Entry
->Flink
;