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 /* FIXME: suboptimal */
23 struct wgl_dc_data
* data
;
24 DWORD objType
= GetObjectType(hdc
);
33 /* Look for the right data identifier */
36 hwnd
= WindowFromDC(hdc
);
40 flags
= WGL_DC_OBJ_DC
;
42 else if(objType
== OBJ_MEMDC
)
51 EnterCriticalSection(&dc_data_cs
);
55 if(data
->owner
.u
== id
.u
)
57 LeaveCriticalSection(&dc_data_cs
);
62 data
= HeapAlloc(GetProcessHeap(), 0, sizeof(*data
));
65 LeaveCriticalSection(&dc_data_cs
);
68 /* initialize the structure */
71 data
->pixelformat
= 0;
74 data
->icd_data
= IntGetIcdData(hdc
);
75 /* Get the number of available formats for this DC once and for all */
77 data
->nb_icd_formats
= data
->icd_data
->DrvDescribePixelFormat(hdc
, 0, 0, NULL
);
79 data
->nb_icd_formats
= 0;
80 TRACE("ICD %S has %u formats for HDC %x.\n", data
->icd_data
->DriverName
, data
->nb_icd_formats
, hdc
);
81 data
->nb_sw_formats
= sw_DescribePixelFormat(hdc
, 0, 0, NULL
);
82 data
->next
= dc_data_list
;
84 LeaveCriticalSection(&dc_data_cs
);
88 void release_dc_data(struct wgl_dc_data
* dc_data
)
93 struct wgl_context
* get_context(HGLRC hglrc
)
95 struct wgl_context
* context
= (struct wgl_context
*)hglrc
;
102 if(context
->magic
!= 'GLRC')
105 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
114 INT WINAPI
wglDescribePixelFormat(HDC hdc
, INT format
, UINT size
, PIXELFORMATDESCRIPTOR
*descr
)
116 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
121 SetLastError(ERROR_INVALID_HANDLE
);
125 ret
= dc_data
->nb_icd_formats
+ dc_data
->nb_sw_formats
;
129 release_dc_data(dc_data
);
132 if((format
== 0) || (format
> ret
) || (size
!= sizeof(*descr
)))
134 release_dc_data(dc_data
);
135 SetLastError(ERROR_INVALID_PARAMETER
);
139 /* Query ICD if needed */
140 if(format
<= dc_data
->nb_icd_formats
)
142 if(!dc_data
->icd_data
->DrvDescribePixelFormat(hdc
, format
, size
, descr
))
149 /* This is a software format */
150 format
-= dc_data
->nb_icd_formats
;
151 if(!sw_DescribePixelFormat(hdc
, format
, size
, descr
))
157 release_dc_data(dc_data
);
161 INT WINAPI
wglChoosePixelFormat(HDC hdc
, const PIXELFORMATDESCRIPTOR
* ppfd
)
163 PIXELFORMATDESCRIPTOR format
, best
;
164 int i
, count
, best_format
;
165 int bestDBuffer
= -1, bestStereo
= -1;
167 TRACE_(wgl
)( "%p %p: size %u version %u flags %u type %u color %u %u,%u,%u,%u "
168 "accum %u depth %u stencil %u aux %u\n",
169 hdc
, ppfd
, ppfd
->nSize
, ppfd
->nVersion
, ppfd
->dwFlags
, ppfd
->iPixelType
,
170 ppfd
->cColorBits
, ppfd
->cRedBits
, ppfd
->cGreenBits
, ppfd
->cBlueBits
, ppfd
->cAlphaBits
,
171 ppfd
->cAccumBits
, ppfd
->cDepthBits
, ppfd
->cStencilBits
, ppfd
->cAuxBuffers
);
173 count
= wglDescribePixelFormat( hdc
, 0, 0, NULL
);
174 if (!count
) return 0;
178 best
.cAlphaBits
= -1;
179 best
.cColorBits
= -1;
180 best
.cDepthBits
= -1;
181 best
.cStencilBits
= -1;
182 best
.cAuxBuffers
= -1;
184 for (i
= 1; i
<= count
; i
++)
186 if (!wglDescribePixelFormat( hdc
, i
, sizeof(format
), &format
)) continue;
188 if (ppfd
->iPixelType
!= format
.iPixelType
)
190 TRACE( "pixel type mismatch for iPixelFormat=%d\n", i
);
194 /* only use bitmap capable formats for bitmap rendering */
195 if ((ppfd
->dwFlags
& PFD_DRAW_TO_BITMAP
) != (format
.dwFlags
& PFD_DRAW_TO_BITMAP
))
197 TRACE( "PFD_DRAW_TO_BITMAP mismatch for iPixelFormat=%d\n", i
);
201 /* only use window capable formats for window rendering */
202 if ((ppfd
->dwFlags
& PFD_DRAW_TO_WINDOW
) != (format
.dwFlags
& PFD_DRAW_TO_WINDOW
))
204 TRACE( "PFD_DRAW_TO_WINDOW mismatch for iPixelFormat=%d\n", i
);
208 /* only use opengl capable formats for opengl rendering */
209 if ((ppfd
->dwFlags
& PFD_SUPPORT_OPENGL
) != (format
.dwFlags
& PFD_SUPPORT_OPENGL
))
211 TRACE( "PFD_SUPPORT_OPENGL mismatch for iPixelFormat=%d\n", i
);
215 /* only use GDI capable formats for GDI rendering */
216 if ((ppfd
->dwFlags
& PFD_SUPPORT_GDI
) != (format
.dwFlags
& PFD_SUPPORT_GDI
))
218 TRACE( "PFD_SUPPORT_GDI mismatch for iPixelFormat=%d\n", i
);
222 /* The behavior of PDF_STEREO/PFD_STEREO_DONTCARE and PFD_DOUBLEBUFFER / PFD_DOUBLEBUFFER_DONTCARE
223 * is not very clear on MSDN. They specify that ChoosePixelFormat tries to match pixel formats
224 * with the flag (PFD_STEREO / PFD_DOUBLEBUFFERING) set. Otherwise it says that it tries to match
225 * formats without the given flag set.
226 * A test on Windows using a Radeon 9500pro on WinXP (the driver doesn't support Stereo)
227 * has indicated that a format without stereo is returned when stereo is unavailable.
228 * So in case PFD_STEREO is set, formats that support it should have priority above formats
229 * without. In case PFD_STEREO_DONTCARE is set, stereo is ignored.
231 * To summarize the following is most likely the correct behavior:
232 * stereo not set -> prefer non-stereo formats, but also accept stereo formats
233 * stereo set -> prefer stereo formats, but also accept non-stereo formats
234 * stereo don't care -> it doesn't matter whether we get stereo or not
236 * In Wine we will treat non-stereo the same way as don't care because it makes
237 * format selection even more complicated and second drivers with Stereo advertise
238 * each format twice anyway.
241 /* Doublebuffer, see the comments above */
242 if (!(ppfd
->dwFlags
& PFD_DOUBLEBUFFER_DONTCARE
))
244 if (((ppfd
->dwFlags
& PFD_DOUBLEBUFFER
) != bestDBuffer
) &&
245 ((format
.dwFlags
& PFD_DOUBLEBUFFER
) == (ppfd
->dwFlags
& PFD_DOUBLEBUFFER
)))
248 if (bestDBuffer
!= -1 && (format
.dwFlags
& PFD_DOUBLEBUFFER
) != bestDBuffer
) continue;
251 /* Stereo, see the comments above. */
252 if (!(ppfd
->dwFlags
& PFD_STEREO_DONTCARE
))
254 if (((ppfd
->dwFlags
& PFD_STEREO
) != bestStereo
) &&
255 ((format
.dwFlags
& PFD_STEREO
) == (ppfd
->dwFlags
& PFD_STEREO
)))
258 if (bestStereo
!= -1 && (format
.dwFlags
& PFD_STEREO
) != bestStereo
) continue;
261 /* Below we will do a number of checks to select the 'best' pixelformat.
262 * We assume the precedence cColorBits > cAlphaBits > cDepthBits > cStencilBits -> cAuxBuffers.
263 * The code works by trying to match the most important options as close as possible.
264 * When a reasonable format is found, we will try to match more options.
265 * It appears (see the opengl32 test) that Windows opengl drivers ignore options
266 * like cColorBits, cAlphaBits and friends if they are set to 0, so they are considered
267 * as DONTCARE. At least Serious Sam TSE relies on this behavior. */
269 if (ppfd
->cColorBits
)
271 if (((ppfd
->cColorBits
> best
.cColorBits
) && (format
.cColorBits
> best
.cColorBits
)) ||
272 ((format
.cColorBits
>= ppfd
->cColorBits
) && (format
.cColorBits
< best
.cColorBits
)))
275 if (best
.cColorBits
!= format
.cColorBits
) /* Do further checks if the format is compatible */
277 TRACE( "color mismatch for iPixelFormat=%d\n", i
);
281 if (ppfd
->cAlphaBits
)
283 if (((ppfd
->cAlphaBits
> best
.cAlphaBits
) && (format
.cAlphaBits
> best
.cAlphaBits
)) ||
284 ((format
.cAlphaBits
>= ppfd
->cAlphaBits
) && (format
.cAlphaBits
< best
.cAlphaBits
)))
287 if (best
.cAlphaBits
!= format
.cAlphaBits
)
289 TRACE( "alpha mismatch for iPixelFormat=%d\n", i
);
293 if (ppfd
->cDepthBits
)
295 if (((ppfd
->cDepthBits
> best
.cDepthBits
) && (format
.cDepthBits
> best
.cDepthBits
)) ||
296 ((format
.cDepthBits
>= ppfd
->cDepthBits
) && (format
.cDepthBits
< best
.cDepthBits
)))
299 if (best
.cDepthBits
!= format
.cDepthBits
)
301 TRACE( "depth mismatch for iPixelFormat=%d\n", i
);
305 if (ppfd
->cStencilBits
)
307 if (((ppfd
->cStencilBits
> best
.cStencilBits
) && (format
.cStencilBits
> best
.cStencilBits
)) ||
308 ((format
.cStencilBits
>= ppfd
->cStencilBits
) && (format
.cStencilBits
< best
.cStencilBits
)))
311 if (best
.cStencilBits
!= format
.cStencilBits
)
313 TRACE( "stencil mismatch for iPixelFormat=%d\n", i
);
317 if (ppfd
->cAuxBuffers
)
319 if (((ppfd
->cAuxBuffers
> best
.cAuxBuffers
) && (format
.cAuxBuffers
> best
.cAuxBuffers
)) ||
320 ((format
.cAuxBuffers
>= ppfd
->cAuxBuffers
) && (format
.cAuxBuffers
< best
.cAuxBuffers
)))
323 if (best
.cAuxBuffers
!= format
.cAuxBuffers
)
325 TRACE( "aux mismatch for iPixelFormat=%d\n", i
);
334 bestDBuffer
= format
.dwFlags
& PFD_DOUBLEBUFFER
;
335 bestStereo
= format
.dwFlags
& PFD_STEREO
;
338 TRACE( "returning %u\n", best_format
);
342 BOOL WINAPI
wglCopyContext(HGLRC hglrcSrc
, HGLRC hglrcDst
, UINT mask
)
344 struct wgl_context
* ctx_src
= get_context(hglrcSrc
);
345 struct wgl_context
* ctx_dst
= get_context(hglrcDst
);
347 if(!ctx_src
|| !ctx_dst
)
349 SetLastError(ERROR_INVALID_HANDLE
);
353 /* Check this is the same pixel format */
354 if((ctx_dst
->icd_data
!= ctx_src
->icd_data
) ||
355 (ctx_dst
->pixelformat
!= ctx_src
->pixelformat
))
357 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
361 if(ctx_src
->icd_data
)
362 return ctx_src
->icd_data
->DrvCopyContext(ctx_src
->dhglrc
, ctx_dst
->dhglrc
, mask
);
364 return sw_CopyContext(ctx_src
->dhglrc
, ctx_dst
->dhglrc
, mask
);
367 HGLRC WINAPI
wglCreateContext(HDC hdc
)
369 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
370 struct wgl_context
* context
;
373 TRACE("Creating context for %p, format %i\n", hdc
);
377 WARN("Not a DC handle!\n");
378 SetLastError(ERROR_INVALID_HANDLE
);
382 if(!dc_data
->pixelformat
)
384 WARN("Pixel format not set!\n");
385 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
389 if(!dc_data
->icd_data
)
391 TRACE("Calling SW implementation.\n");
392 dhglrc
= sw_CreateContext(dc_data
);
397 TRACE("Calling ICD.\n");
398 dhglrc
= dc_data
->icd_data
->DrvCreateContext(hdc
);
404 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
408 context
= HeapAlloc(GetProcessHeap(), 0, sizeof(*context
));
411 WARN("Failed to allocate a context!\n");
412 if(!dc_data
->icd_data
)
413 sw_DeleteContext(dhglrc
);
415 dc_data
->icd_data
->DrvDeleteContext(dhglrc
);
416 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
419 /* Copy info from the DC data */
420 context
->dhglrc
= dhglrc
;
421 context
->icd_data
= dc_data
->icd_data
;
422 context
->pixelformat
= dc_data
->pixelformat
;
423 context
->thread_id
= 0;
425 context
->magic
= 'GLRC';
427 return (HGLRC
)context
;
430 HGLRC WINAPI
wglCreateLayerContext(HDC hdc
, int iLayerPlane
)
432 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
433 struct wgl_context
* context
;
438 SetLastError(ERROR_INVALID_HANDLE
);
442 if(!dc_data
->pixelformat
)
444 release_dc_data(dc_data
);
445 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
449 if(!dc_data
->icd_data
)
453 /* Not supported in SW implementation */
454 release_dc_data(dc_data
);
455 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
458 dhglrc
= sw_CreateContext(dc_data
);
462 dhglrc
= dc_data
->icd_data
->DrvCreateLayerContext(hdc
, iLayerPlane
);
467 release_dc_data(dc_data
);
468 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
472 context
= HeapAlloc(GetProcessHeap(), 0, sizeof(*context
));
475 if(!dc_data
->icd_data
)
476 sw_DeleteContext(dhglrc
);
478 dc_data
->icd_data
->DrvDeleteContext(dhglrc
);
479 release_dc_data(dc_data
);
480 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
483 /* Copy info from the DC data */
484 context
->dhglrc
= dhglrc
;
485 context
->icd_data
= dc_data
->icd_data
;
486 context
->pixelformat
= dc_data
->pixelformat
;
487 context
->thread_id
= 0;
489 context
->magic
= 'GLRC';
491 release_dc_data(dc_data
);
492 return (HGLRC
)context
;
495 BOOL WINAPI
wglDeleteContext(HGLRC hglrc
)
497 struct wgl_context
* context
= get_context(hglrc
);
498 LONG thread_id
= GetCurrentThreadId();
502 SetLastError(ERROR_INVALID_HANDLE
);
506 /* Own this context before touching it */
507 if(InterlockedCompareExchange(&context
->thread_id
, thread_id
, 0) != 0)
509 /* We can't delete a context current to another thread */
510 if(context
->thread_id
!= thread_id
)
512 SetLastError(ERROR_BUSY
);
516 /* This is in our thread. Release and try again */
517 if(!wglMakeCurrent(NULL
, NULL
))
519 return wglDeleteContext(hglrc
);
522 if(context
->icd_data
)
523 context
->icd_data
->DrvDeleteContext(context
->dhglrc
);
525 sw_DeleteContext(context
->dhglrc
);
528 HeapFree(GetProcessHeap(), 0, context
);
533 BOOL WINAPI
wglDescribeLayerPlane(HDC hdc
,
537 LPLAYERPLANEDESCRIPTOR plpd
)
539 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
543 SetLastError(ERROR_INVALID_HANDLE
);
547 if(iPixelFormat
<= dc_data
->nb_icd_formats
)
548 return dc_data
->icd_data
->DrvDescribeLayerPlane(hdc
, iPixelFormat
, iLayerPlane
, nBytes
, plpd
);
550 /* SW implementation doesn't support this */
554 HGLRC WINAPI
wglGetCurrentContext(void)
556 return IntGetCurrentRC();
559 HDC WINAPI
wglGetCurrentDC(void)
561 return IntGetCurrentDC();
564 PROC WINAPI
wglGetDefaultProcAddress(LPCSTR lpszProc
)
566 /* undocumented... */
570 int WINAPI
wglGetLayerPaletteEntries(HDC hdc
, int iLayerPlane
, int iStart
, int cEntries
, COLORREF
* pcr
)
572 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
576 SetLastError(ERROR_INVALID_HANDLE
);
580 if(!dc_data
->pixelformat
)
582 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
586 if(dc_data
->icd_data
)
587 return dc_data
->icd_data
->DrvGetLayerPaletteEntries(hdc
, iLayerPlane
, iStart
, cEntries
, pcr
);
589 /* SW implementation doesn't support this */
593 INT WINAPI
wglGetPixelFormat(HDC hdc
)
596 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
600 SetLastError(ERROR_INVALID_HANDLE
);
604 ret
= dc_data
->pixelformat
;
605 release_dc_data(dc_data
);
609 PROC WINAPI
wglGetProcAddress(LPCSTR name
)
611 struct wgl_context
* context
= get_context(IntGetCurrentRC());
615 /* This shall fail for opengl 1.1 functions */
616 #define USE_GL_FUNC(func, w, x, y, z) if(!strcmp(name, "gl" #func)) return NULL;
620 if(context
->icd_data
)
621 return context
->icd_data
->DrvGetProcAddress(name
);
622 return sw_GetProcAddress(name
);
625 void APIENTRY
set_api_table(const GLCLTPROCTABLE
* table
)
627 IntSetCurrentDispatchTable(&table
->glDispatchTable
);
630 BOOL WINAPI
wglMakeCurrent(HDC hdc
, HGLRC hglrc
)
632 struct wgl_context
* ctx
= get_context(hglrc
);
633 struct wgl_context
* old_ctx
= get_context(IntGetCurrentRC());
634 const GLCLTPROCTABLE
* apiTable
;
635 LONG thread_id
= (LONG
)GetCurrentThreadId();
639 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
642 ERR("wglMakeCurrent was passed an invalid DC handle.\n");
643 SetLastError(ERROR_INVALID_HANDLE
);
647 /* Check compatibility */
648 if((ctx
->icd_data
!= dc_data
->icd_data
) || (ctx
->pixelformat
!= dc_data
->pixelformat
))
650 /* That's bad, man */
651 ERR("HGLRC %p and HDC %p are not compatible.\n", hglrc
, hdc
);
652 release_dc_data(dc_data
);
653 SetLastError(ERROR_INVALID_HANDLE
);
657 /* Set the thread ID */
658 if(InterlockedCompareExchange(&ctx
->thread_id
, thread_id
, 0) != 0)
660 /* Already current for a thread. Maybe it's us ? */
661 release_dc_data(dc_data
);
662 if(ctx
->thread_id
!= thread_id
)
663 SetLastError(ERROR_BUSY
);
664 return (ctx
->thread_id
== thread_id
);
670 if(old_ctx
->icd_data
)
671 old_ctx
->icd_data
->DrvReleaseContext(old_ctx
->dhglrc
);
673 sw_ReleaseContext(old_ctx
->dhglrc
);
674 InterlockedExchange(&old_ctx
->thread_id
, 0);
677 /* Call the ICD or SW implementation */
680 apiTable
= ctx
->icd_data
->DrvSetContext(hdc
, ctx
->dhglrc
, set_api_table
);
683 ERR("DrvSetContext failed!\n");
685 InterlockedExchange(&ctx
->thread_id
, 0);
686 IntSetCurrentDispatchTable(&StubTable
.glDispatchTable
);
687 SetLastError(ERROR_INVALID_PARAMETER
);
690 set_api_table(apiTable
);
691 /* Make it current */
692 IntMakeCurrent(hglrc
, hdc
, dc_data
);
696 /* We must set current before, SW implementation relies on it */
697 IntMakeCurrent(hglrc
, hdc
, dc_data
);
698 if(!sw_SetContext(dc_data
, ctx
->dhglrc
))
700 ERR("sw_SetContext failed!\n");
702 IntMakeCurrent(NULL
, NULL
, NULL
);
703 InterlockedExchange(&ctx
->thread_id
, 0);
704 SetLastError(ERROR_INVALID_PARAMETER
);
711 if(old_ctx
->icd_data
)
712 old_ctx
->icd_data
->DrvReleaseContext(old_ctx
->dhglrc
);
714 sw_ReleaseContext(old_ctx
->dhglrc
);
715 InterlockedExchange(&old_ctx
->thread_id
, 0);
717 IntMakeCurrent(NULL
, NULL
, NULL
);
718 /* Reset the no-op table */
719 set_api_table(&StubTable
);
720 /* Test conformance (extreme cases) */
721 return hglrc
== NULL
;
725 /* Winetest conformance */
726 if (GetObjectType( hdc
) != OBJ_DC
&& GetObjectType( hdc
) != OBJ_MEMDC
)
728 ERR( "Error: hdc is not a DC handle!\n");
729 SetLastError( ERROR_INVALID_HANDLE
);
737 BOOL WINAPI
wglRealizeLayerPalette(HDC hdc
,
741 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
745 SetLastError(ERROR_INVALID_HANDLE
);
749 if(!dc_data
->pixelformat
)
751 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
755 if(dc_data
->icd_data
)
756 return dc_data
->icd_data
->DrvRealizeLayerPalette(hdc
, iLayerPlane
, bRealize
);
758 /* SW implementation doesn't support this */
762 int WINAPI
wglSetLayerPaletteEntries(HDC hdc
,
768 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
772 SetLastError(ERROR_INVALID_HANDLE
);
776 if(!dc_data
->pixelformat
)
778 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
782 if(dc_data
->icd_data
)
783 return dc_data
->icd_data
->DrvSetLayerPaletteEntries(hdc
, iLayerPlane
, iStart
, cEntries
, pcr
);
785 /* SW implementation doesn't support this */
789 BOOL WINAPI
wglSetPixelFormat(HDC hdc
, INT format
, const PIXELFORMATDESCRIPTOR
*descr
)
791 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
795 TRACE("HDC %p, format %i.\n", hdc
, format
);
799 WARN("Not a valid DC!.\n");
800 SetLastError(ERROR_INVALID_HANDLE
);
806 WARN("format == 0!\n");
807 SetLastError(ERROR_INVALID_PARAMETER
);
811 if(dc_data
->pixelformat
)
813 TRACE("DC format already set, %i.\n", dc_data
->pixelformat
);
814 return (format
== dc_data
->pixelformat
);
817 if(format
<= dc_data
->nb_icd_formats
)
819 TRACE("Calling ICD.\n");
820 ret
= dc_data
->icd_data
->DrvSetPixelFormat(hdc
, format
);
824 dc_data
->pixelformat
= format
;
829 sw_format
= format
- dc_data
->nb_icd_formats
;
830 if(sw_format
<= dc_data
->nb_sw_formats
)
832 TRACE("Calling SW implementation.\n");
833 ret
= sw_SetPixelFormat(hdc
, dc_data
, sw_format
);
837 /* This is now officially a software-only HDC */
838 dc_data
->icd_data
= NULL
;
839 dc_data
->pixelformat
= format
;
844 TRACE("Invalid pixel format!\n");
845 SetLastError(ERROR_INVALID_PARAMETER
);
849 BOOL WINAPI
wglShareLists(HGLRC hglrcSrc
, HGLRC hglrcDst
)
851 struct wgl_context
* ctx_src
= get_context(hglrcSrc
);
852 struct wgl_context
* ctx_dst
= get_context(hglrcDst
);
854 if(!ctx_src
|| !ctx_dst
)
856 SetLastError(ERROR_INVALID_HANDLE
);
860 /* Check this is the same pixel format */
861 if((ctx_dst
->icd_data
!= ctx_src
->icd_data
) ||
862 (ctx_dst
->pixelformat
!= ctx_src
->pixelformat
))
864 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
868 if(ctx_src
->icd_data
)
869 return ctx_src
->icd_data
->DrvShareLists(ctx_src
->dhglrc
, ctx_dst
->dhglrc
);
871 return sw_ShareLists(ctx_src
->dhglrc
, ctx_dst
->dhglrc
);
874 BOOL WINAPI DECLSPEC_HOTPATCH
wglSwapBuffers(HDC hdc
)
876 struct wgl_dc_data
* dc_data
= get_dc_data(hdc
);
880 SetLastError(ERROR_INVALID_HANDLE
);
884 if(!dc_data
->pixelformat
)
886 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
890 if(dc_data
->icd_data
)
891 return dc_data
->icd_data
->DrvSwapBuffers(hdc
);
893 return sw_SwapBuffers(hdc
, dc_data
);
896 BOOL WINAPI
wglSwapLayerBuffers(HDC hdc
, UINT fuPlanes
)
901 DWORD WINAPI
wglSwapMultipleBuffers(UINT count
, CONST WGLSWAP
* toSwap
)