2 * GLX implementation that uses Windows OpenGL library
3 * (Indirect rendering path)
5 * Authors: Alexander Gottwald
8 * Portions of this file are copied from GL/apple/indirect.c,
9 * which contains the following copyright:
11 * Copyright (c) 2002 Greg Parker. All Rights Reserved.
12 * Copyright (c) 2002 Apple Computer, Inc.
14 * Portions of this file are copied from xf86glx.c,
15 * which contains the following copyright:
17 * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
18 * All Rights Reserved.
20 * Permission is hereby granted, free of charge, to any person obtaining a
21 * copy of this software and associated documentation files (the "Software"),
22 * to deal in the Software without restriction, including without limitation
23 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
24 * and/or sell copies of the Software, and to permit persons to whom the
25 * Software is furnished to do so, subject to the following conditions:
27 * The above copyright notice and this permission notice shall be included in
28 * all copies or substantial portions of the Software.
30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
33 * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
34 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
35 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
36 * DEALINGS IN THE SOFTWARE.
38 * Except as contained in this notice, the name(s) of the above copyright
39 * holders shall not be used in advertising or otherwise to promote the sale,
40 * use or other dealings in this Software without prior written authorization.
45 #ifdef HAVE_DIX_CONFIG_H
46 #include <dix-config.h>
49 #include "glwindows.h"
50 #include <glcontextmodes.h>
55 #define GLWIN_DEBUG_HWND(hwnd) \
56 if (glWinDebugSettings.dumpHWND) { \
58 if (GetWindowText(hwnd, buffer, sizeof(buffer))==0) *buffer=0; \
59 GLWIN_DEBUG_MSG("Got HWND %s (%p)\n", buffer, hwnd); \
63 /* ggs: needed to call back to glx with visual configs */
64 extern void GlxSetVisualConfigs(int nconfigs
, __GLXvisualConfig
*configs
, void **configprivs
);
66 glWinDebugSettingsRec glWinDebugSettings
= { 1, 0, 0, 0, 0};
68 static void glWinInitDebugSettings(void)
72 envptr
= getenv("GLWIN_ENABLE_DEBUG");
74 glWinDebugSettings
.enableDebug
= (atoi(envptr
) == 1);
76 envptr
= getenv("GLWIN_ENABLE_TRACE");
78 glWinDebugSettings
.enableTrace
= (atoi(envptr
) == 1);
80 envptr
= getenv("GLWIN_DUMP_PFD");
82 glWinDebugSettings
.dumpPFD
= (atoi(envptr
) == 1);
84 envptr
= getenv("GLWIN_DUMP_HWND");
86 glWinDebugSettings
.dumpHWND
= (atoi(envptr
) == 1);
88 envptr
= getenv("GLWIN_DUMP_DC");
90 glWinDebugSettings
.dumpDC
= (atoi(envptr
) == 1);
93 static char errorbuffer
[1024];
94 const char *glWinErrorMessage(void)
97 FORMAT_MESSAGE_FROM_SYSTEM
|
98 FORMAT_MESSAGE_IGNORE_INSERTS
,
101 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
102 (LPTSTR
) &errorbuffer
,
106 snprintf(errorbuffer
, sizeof(errorbuffer
), "Unknown error in FormatMessage: %08x!\n", (unsigned)GetLastError());
112 * GLX implementation that uses Win32's OpenGL
116 * Server-side GLX uses these functions which are normally defined
120 GLuint
__glFloorLog2(GLuint val
)
131 /* some prototypes */
132 static Bool
glWinScreenProbe(int screen
);
133 static Bool
glWinInitVisuals(VisualPtr
*visualp
, DepthPtr
*depthp
,
134 int *nvisualp
, int *ndepthp
,
135 int *rootDepthp
, VisualID
*defaultVisp
,
136 unsigned long sizes
, int bitsPerRGB
);
137 static void glWinSetVisualConfigs(int nconfigs
, __GLXvisualConfig
*configs
,
139 static __GLinterface
*glWinCreateContext(__GLimports
*imports
,
140 __GLcontextModes
*mode
,
141 __GLinterface
*shareGC
);
142 static void glWinCreateBuffer(__GLXdrawablePrivate
*glxPriv
);
143 static void glWinResetExtension(void);
146 * This structure is statically allocated in the __glXScreens[]
147 * structure. This struct is not used anywhere other than in
148 * __glXScreenInit to initialize each of the active screens
149 * (__glXActiveScreens[]). Several of the fields must be initialized by
150 * the screenProbe routine before they are copied to the active screens
151 * struct. In particular, the contextCreate, pGlxVisual, numVisuals,
152 * and numUsableVisuals fields must be initialized.
154 static __GLXscreenInfo __glDDXScreenInfo
= {
155 glWinScreenProbe
, /* Must be generic and handle all screens */
156 glWinCreateContext
, /* Substitute screen's createContext routine */
157 glWinCreateBuffer
, /* Substitute screen's createBuffer routine */
158 NULL
, /* Set up pGlxVisual in probe */
159 NULL
, /* Set up pVisualPriv in probe */
160 0, /* Set up numVisuals in probe */
161 0, /* Set up numUsableVisuals in probe */
162 "Vendor String", /* GLXvendor is overwritten by __glXScreenInit */
163 "Version String", /* GLXversion is overwritten by __glXScreenInit */
164 "Extensions String", /* GLXextensions is overwritten by __glXScreenInit */
165 NULL
/* WrappedPositionWindow is overwritten */
168 void *__glXglDDXScreenInfo(void) {
169 return &__glDDXScreenInfo
;
172 static __GLXextensionInfo __glDDXExtensionInfo
= {
176 glWinSetVisualConfigs
179 void *__glXglDDXExtensionInfo(void) {
180 return &__glDDXExtensionInfo
;
185 static GLboolean
glWinDestroyContext(__GLcontext
*gc
);
186 static GLboolean
glWinLoseCurrent(__GLcontext
*gc
);
187 static GLboolean
glWinMakeCurrent(__GLcontext
*gc
);
188 static GLboolean
glWinShareContext(__GLcontext
*gc
, __GLcontext
*gcShare
);
189 static GLboolean
glWinCopyContext(__GLcontext
*dst
, const __GLcontext
*src
,
191 static GLboolean
glWinForceCurrent(__GLcontext
*gc
);
193 /* Drawing surface notification callbacks */
194 static GLboolean
glWinNotifyResize(__GLcontext
*gc
);
195 static void glWinNotifyDestroy(__GLcontext
*gc
);
196 static void glWinNotifySwapBuffers(__GLcontext
*gc
);
198 /* Dispatch table override control for external agents like libGLS */
199 static struct __GLdispatchStateRec
* glWinDispatchExec(__GLcontext
*gc
);
200 static void glWinBeginDispatchOverride(__GLcontext
*gc
);
201 static void glWinEndDispatchOverride(__GLcontext
*gc
);
204 static void pfdOut(const PIXELFORMATDESCRIPTOR
*pfd
);
206 static __GLexports glWinExports
= {
216 glWinNotifySwapBuffers
,
219 glWinBeginDispatchOverride
,
220 glWinEndDispatchOverride
223 glWinScreenRec glWinScreens
[MAXSCREENS
];
225 /* __GLdrawablePrivate->private */
228 /* xp_surface_id sid; */
231 struct __GLcontextRec
{
232 struct __GLinterfaceRec interface
; /* required to be first */
234 HGLRC ctx
; /* Windows GL Context */
236 HDC dc
; /* Windows Device Context */
237 winWindowInfoRec winInfo
; /* Window info from XWin */
239 PIXELFORMATDESCRIPTOR pfd
; /* Pixelformat flags */
240 int pixelFormat
; /* Pixelformat index */
242 unsigned isAttached
:1; /* Flag to track if context is attached */
245 static HDC
glWinMakeDC(__GLcontext
*gc
)
249 /*if (gc->winInfo.hrgn == NULL)
251 GLWIN_DEBUG_MSG("Creating region from RECT(%ld,%ld,%ld,%ld):",
252 gc->winInfo.rect.left,
253 gc->winInfo.rect.top,
254 gc->winInfo.rect.right,
255 gc->winInfo.rect.bottom);
256 gc->winInfo.hrgn = CreateRectRgnIndirect(&gc->winInfo.rect);
257 GLWIN_DEBUG_MSG2("%p\n", gc->winInfo.hrgn);
260 if (glWinDebugSettings
.enableTrace
)
261 GLWIN_DEBUG_HWND(gc
->winInfo
.hwnd
);
263 dc
= GetDC(gc
->winInfo
.hwnd
);
264 /*dc = GetDCEx(gc->winInfo.hwnd, gc->winInfo.hrgn,
265 DCX_WINDOW | DCX_NORESETATTRS ); */
268 ErrorF("GetDC error: %s\n", glWinErrorMessage());
272 static void unattach(__GLcontext
*gc
)
275 GLWIN_DEBUG_MSG("unattach (ctx %p)\n", gc
->ctx
);
278 ErrorF("called unattach on an unattached context\n");
284 ret
= wglDeleteContext(gc
->ctx
);
286 ErrorF("wglDeleteContext error: %s\n", glWinErrorMessage());
290 if (gc
->winInfo
.hrgn
)
292 ret
= DeleteObject(gc
->winInfo
.hrgn
);
294 ErrorF("DeleteObject error: %s\n", glWinErrorMessage());
295 gc
->winInfo
.hrgn
= NULL
;
301 static BOOL
glWinAdjustHWND(__GLcontext
*gc
, WindowPtr pWin
)
308 GLWIN_DEBUG_MSG("glWinAdjustHWND (ctx %p, pWin %p)\n", gc
->ctx
, pWin
);
312 GLWIN_DEBUG_MSG("Deferring until window is created\n");
316 oldhwnd
= gc
->winInfo
.hwnd
;
317 winGetWindowInfo(pWin
, &gc
->winInfo
);
319 GLWIN_DEBUG_HWND(gc
->winInfo
.hwnd
);
320 if (gc
->winInfo
.hwnd
== NULL
)
322 GLWIN_DEBUG_MSG("Deferring until window is created\n");
326 dc
= glWinMakeDC(gc
);
328 if (glWinDebugSettings
.dumpDC
)
329 GLWIN_DEBUG_MSG("Got HDC %p\n", dc
);
331 gc
->pixelFormat
= ChoosePixelFormat(dc
, &gc
->pfd
);
332 if (gc
->pixelFormat
== 0)
334 ErrorF("ChoosePixelFormat error: %s\n", glWinErrorMessage());
335 ReleaseDC(gc
->winInfo
.hwnd
, dc
);
339 ret
= SetPixelFormat(dc
, gc
->pixelFormat
, &gc
->pfd
);
341 ErrorF("SetPixelFormat error: %s\n", glWinErrorMessage());
342 ReleaseDC(gc
->winInfo
.hwnd
, dc
);
346 newctx
= wglCreateContext(dc
);
347 if (newctx
== NULL
) {
348 ErrorF("wglCreateContext error: %s\n", glWinErrorMessage());
349 ReleaseDC(gc
->winInfo
.hwnd
, dc
);
353 GLWIN_DEBUG_MSG("wglCreateContext (ctx %p)\n", newctx
);
355 if (!wglShareLists(gc
->ctx
, newctx
))
357 ErrorF("wglShareLists error: %s\n", glWinErrorMessage());
358 ReleaseDC(gc
->winInfo
.hwnd
, dc
);
362 if (oldhwnd
!= gc
->winInfo
.hwnd
)
364 GLWIN_DEBUG_MSG("Trying wglCopyContext\n");
365 if (!wglCopyContext(gc
->ctx
, newctx
, GL_ALL_ATTRIB_BITS
))
367 ErrorF("wglCopyContext error: %s\n", glWinErrorMessage());
368 ReleaseDC(gc
->winInfo
.hwnd
, dc
);
373 if (!wglDeleteContext(gc
->ctx
))
375 ErrorF("wglDeleteContext error: %s\n", glWinErrorMessage());
380 if (!wglMakeCurrent(dc
, gc
->ctx
)) {
381 ErrorF("glMakeCurrent error: %s\n", glWinErrorMessage());
382 ReleaseDC(gc
->winInfo
.hwnd
, dc
);
386 ReleaseDC(gc
->winInfo
.hwnd
, dc
);
391 static BOOL
glWinCreateContextReal(__GLcontext
*gc
, WindowPtr pWin
)
396 GLWIN_DEBUG_MSG("glWinCreateContextReal (pWin %p)\n", pWin
);
400 GLWIN_DEBUG_MSG("Deferring until window is created\n");
404 winGetWindowInfo(pWin
, &gc
->winInfo
);
406 GLWIN_DEBUG_HWND(gc
->winInfo
.hwnd
);
407 if (gc
->winInfo
.hwnd
== NULL
)
409 GLWIN_DEBUG_MSG("Deferring until window is created\n");
414 dc
= glWinMakeDC(gc
);
416 if (glWinDebugSettings
.dumpDC
)
417 GLWIN_DEBUG_MSG("Got HDC %p\n", dc
);
419 gc
->pixelFormat
= ChoosePixelFormat(dc
, &gc
->pfd
);
420 if (gc
->pixelFormat
== 0)
422 ErrorF("ChoosePixelFormat error: %s\n", glWinErrorMessage());
423 ReleaseDC(gc
->winInfo
.hwnd
, dc
);
427 ret
= SetPixelFormat(dc
, gc
->pixelFormat
, &gc
->pfd
);
429 ErrorF("SetPixelFormat error: %s\n", glWinErrorMessage());
430 ReleaseDC(gc
->winInfo
.hwnd
, dc
);
434 gc
->ctx
= wglCreateContext(dc
);
435 if (gc
->ctx
== NULL
) {
436 ErrorF("wglCreateContext error: %s\n", glWinErrorMessage());
437 ReleaseDC(gc
->winInfo
.hwnd
, dc
);
441 GLWIN_DEBUG_MSG("glWinCreateContextReal (ctx %p)\n", gc
->ctx
);
443 if (!wglMakeCurrent(dc
, gc
->ctx
)) {
444 ErrorF("glMakeCurrent error: %s\n", glWinErrorMessage());
445 ReleaseDC(gc
->winInfo
.hwnd
, dc
);
449 ReleaseDC(gc
->winInfo
.hwnd
, dc
);
454 static void attach(__GLcontext
*gc
, __GLdrawablePrivate
*glPriv
)
456 __GLXdrawablePrivate
*glxPriv
= (__GLXdrawablePrivate
*)glPriv
->other
;
458 GLWIN_DEBUG_MSG("attach (ctx %p)\n", gc
->ctx
);
462 ErrorF("called attach on an attached context\n");
466 if (glxPriv
->type
== DRAWABLE_WINDOW
)
468 WindowPtr pWin
= (WindowPtr
) glxPriv
->pDraw
;
471 GLWIN_DEBUG_MSG("Deferring ChoosePixelFormat until window is created\n");
474 if (glWinCreateContextReal(gc
, pWin
))
476 gc
->isAttached
= TRUE
;
477 GLWIN_DEBUG_MSG("attached\n");
483 static GLboolean
glWinLoseCurrent(__GLcontext
*gc
)
485 GLWIN_TRACE_MSG("glWinLoseCurrent (ctx %p)\n", gc
->ctx
);
487 __glXLastContext
= NULL
; /* Mesa does this; why? */
492 /* Context manipulation; return GL_FALSE on failure */
493 static GLboolean
glWinDestroyContext(__GLcontext
*gc
)
495 GLWIN_DEBUG_MSG("glWinDestroyContext (ctx %p)\n", gc
->ctx
);
509 static GLboolean
glWinMakeCurrent(__GLcontext
*gc
)
511 __GLdrawablePrivate
*glPriv
= gc
->interface
.imports
.getDrawablePrivate(gc
);
515 GLWIN_TRACE_MSG(" (ctx %p)\n", gc
->ctx
);
520 if (gc
->ctx
== NULL
) {
521 ErrorF("Context is NULL\n");
525 dc
= glWinMakeDC(gc
);
526 ret
= wglMakeCurrent(dc
, gc
->ctx
);
528 ErrorF("glMakeCurrent error: %s\n", glWinErrorMessage());
529 ReleaseDC(gc
->winInfo
.hwnd
, dc
);
531 return ret
?GL_TRUE
:GL_FALSE
;
534 static GLboolean
glWinShareContext(__GLcontext
*gc
, __GLcontext
*gcShare
)
536 GLWIN_DEBUG_MSG("glWinShareContext unimplemented\n");
541 static GLboolean
glWinCopyContext(__GLcontext
*dst
, const __GLcontext
*src
,
546 GLWIN_DEBUG_MSG("glWinCopyContext\n");
548 ret
= wglCopyContext(src
->ctx
, dst
->ctx
, mask
);
551 ErrorF("wglCopyContext error: %s\n", glWinErrorMessage());
558 static GLboolean
glWinForceCurrent(__GLcontext
*gc
)
560 GLWIN_TRACE_MSG(" (ctx %p)\n", gc
->ctx
);
565 /* Drawing surface notification callbacks */
567 static GLboolean
glWinNotifyResize(__GLcontext
*gc
)
569 GLWIN_DEBUG_MSG("unimplemented glWinNotifyResize");
573 static void glWinNotifyDestroy(__GLcontext
*gc
)
575 GLWIN_DEBUG_MSG("unimplemented glWinNotifyDestroy");
578 static void glWinNotifySwapBuffers(__GLcontext
*gc
)
580 GLWIN_DEBUG_MSG("unimplemented glWinNotifySwapBuffers");
583 /* Dispatch table override control for external agents like libGLS */
584 static struct __GLdispatchStateRec
* glWinDispatchExec(__GLcontext
*gc
)
586 GLWIN_DEBUG_MSG("unimplemented glWinDispatchExec");
590 static void glWinBeginDispatchOverride(__GLcontext
*gc
)
592 GLWIN_DEBUG_MSG("unimplemented glWinBeginDispatchOverride");
595 static void glWinEndDispatchOverride(__GLcontext
*gc
)
597 GLWIN_DEBUG_MSG("unimplemented glWinEndDispatchOverride");
600 #define DUMP_PFD_FLAG(flag) \
601 if (pfd->dwFlags & flag) { \
602 ErrorF("%s%s", pipesym, #flag); \
606 static void pfdOut(const PIXELFORMATDESCRIPTOR
*pfd
)
608 const char *pipesym
= ""; /* will be set after first flag dump */
609 ErrorF("PIXELFORMATDESCRIPTOR:\n");
610 ErrorF("nSize = %u\n", pfd
->nSize
);
611 ErrorF("nVersion = %u\n", pfd
->nVersion
);
612 ErrorF("dwFlags = %lu = {", pfd
->dwFlags
);
613 DUMP_PFD_FLAG(PFD_MAIN_PLANE
);
614 DUMP_PFD_FLAG(PFD_OVERLAY_PLANE
);
615 DUMP_PFD_FLAG(PFD_UNDERLAY_PLANE
);
616 DUMP_PFD_FLAG(PFD_DOUBLEBUFFER
);
617 DUMP_PFD_FLAG(PFD_STEREO
);
618 DUMP_PFD_FLAG(PFD_DRAW_TO_WINDOW
);
619 DUMP_PFD_FLAG(PFD_DRAW_TO_BITMAP
);
620 DUMP_PFD_FLAG(PFD_SUPPORT_GDI
);
621 DUMP_PFD_FLAG(PFD_SUPPORT_OPENGL
);
622 DUMP_PFD_FLAG(PFD_GENERIC_FORMAT
);
623 DUMP_PFD_FLAG(PFD_NEED_PALETTE
);
624 DUMP_PFD_FLAG(PFD_NEED_SYSTEM_PALETTE
);
625 DUMP_PFD_FLAG(PFD_SWAP_EXCHANGE
);
626 DUMP_PFD_FLAG(PFD_SWAP_COPY
);
627 DUMP_PFD_FLAG(PFD_SWAP_LAYER_BUFFERS
);
628 DUMP_PFD_FLAG(PFD_GENERIC_ACCELERATED
);
629 DUMP_PFD_FLAG(PFD_DEPTH_DONTCARE
);
630 DUMP_PFD_FLAG(PFD_DOUBLEBUFFER_DONTCARE
);
631 DUMP_PFD_FLAG(PFD_STEREO_DONTCARE
);
634 ErrorF("iPixelType = %hu = %s\n", pfd
->iPixelType
,
635 (pfd
->iPixelType
== PFD_TYPE_RGBA
? "PFD_TYPE_RGBA" : "PFD_TYPE_COLORINDEX"));
636 ErrorF("cColorBits = %hhu\n", pfd
->cColorBits
);
637 ErrorF("cRedBits = %hhu\n", pfd
->cRedBits
);
638 ErrorF("cRedShift = %hhu\n", pfd
->cRedShift
);
639 ErrorF("cGreenBits = %hhu\n", pfd
->cGreenBits
);
640 ErrorF("cGreenShift = %hhu\n", pfd
->cGreenShift
);
641 ErrorF("cBlueBits = %hhu\n", pfd
->cBlueBits
);
642 ErrorF("cBlueShift = %hhu\n", pfd
->cBlueShift
);
643 ErrorF("cAlphaBits = %hhu\n", pfd
->cAlphaBits
);
644 ErrorF("cAlphaShift = %hhu\n", pfd
->cAlphaShift
);
645 ErrorF("cAccumBits = %hhu\n", pfd
->cAccumBits
);
646 ErrorF("cAccumRedBits = %hhu\n", pfd
->cAccumRedBits
);
647 ErrorF("cAccumGreenBits = %hhu\n", pfd
->cAccumGreenBits
);
648 ErrorF("cAccumBlueBits = %hhu\n", pfd
->cAccumBlueBits
);
649 ErrorF("cAccumAlphaBits = %hhu\n", pfd
->cAccumAlphaBits
);
650 ErrorF("cDepthBits = %hhu\n", pfd
->cDepthBits
);
651 ErrorF("cStencilBits = %hhu\n", pfd
->cStencilBits
);
652 ErrorF("cAuxBuffers = %hhu\n", pfd
->cAuxBuffers
);
653 ErrorF("iLayerType = %hhu\n", pfd
->iLayerType
);
654 ErrorF("bReserved = %hhu\n", pfd
->bReserved
);
655 ErrorF("dwLayerMask = %lu\n", pfd
->dwLayerMask
);
656 ErrorF("dwVisibleMask = %lu\n", pfd
->dwVisibleMask
);
657 ErrorF("dwDamageMask = %lu\n", pfd
->dwDamageMask
);
661 static int makeFormat(__GLcontextModes
*mode
, PIXELFORMATDESCRIPTOR
*pfdret
)
663 PIXELFORMATDESCRIPTOR pfd
= {
664 sizeof(PIXELFORMATDESCRIPTOR
), /* size of this pfd */
665 1, /* version number */
666 PFD_DRAW_TO_WINDOW
| /* support window */
667 PFD_SUPPORT_OPENGL
, /* support OpenGL */
668 PFD_TYPE_RGBA
, /* RGBA type */
669 24, /* 24-bit color depth */
670 0, 0, 0, 0, 0, 0, /* color bits ignored */
671 0, /* no alpha buffer */
672 0, /* shift bit ignored */
673 0, /* no accumulation buffer */
674 0, 0, 0, 0, /* accum bits ignored */
675 0, /* 32-bit z-buffer */
676 0, /* no stencil buffer */
677 0, /* no auxiliary buffer */
678 PFD_MAIN_PLANE
, /* main layer */
680 0, 0, 0 /* layer masks ignored */
683 /* disable anything but rgba. must get rgba to work first */
687 if (mode
->stereoMode
) {
688 result
->dwFlags
|= PFD_STEREO
;
690 if (mode
->doubleBufferMode
) {
691 result
->dwFlags
|= PFD_DOUBLEBUFFER
;
694 if (mode
->colorIndexMode
) {
695 /* ignored, see above */
696 result
->iPixelType
= PFD_TYPE_COLORINDEX
;
697 result
->cColorBits
= mode
->redBits
+ mode
->greenBits
+ mode
->blueBits
;
698 result
->cRedBits
= mode
->redBits
;
699 result
->cRedShift
= 0; /* FIXME */
700 result
->cGreenBits
= mode
->greenBits
;
701 result
->cGreenShift
= 0; /* FIXME */
702 result
->cBlueBits
= mode
->blueBits
;
703 result
->cBlueShift
= 0; /* FIXME */
704 result
->cAlphaBits
= mode
->alphaBits
;
705 result
->cAlphaShift
= 0; /* FIXME */
709 result
->iPixelType
= PFD_TYPE_RGBA
;
710 result
->cColorBits
= mode
->redBits
+ mode
->greenBits
+ mode
->blueBits
;
711 result
->cRedBits
= mode
->redBits
;
712 result
->cRedShift
= 0; /* FIXME */
713 result
->cGreenBits
= mode
->greenBits
;
714 result
->cGreenShift
= 0; /* FIXME */
715 result
->cBlueBits
= mode
->blueBits
;
716 result
->cBlueShift
= 0; /* FIXME */
717 result
->cAlphaBits
= mode
->alphaBits
;
718 result
->cAlphaShift
= 0; /* FIXME */
721 if (mode
->haveAccumBuffer
) {
722 result
->cAccumBits
= mode
->accumRedBits
+ mode
->accumGreenBits
723 + mode
->accumBlueBits
+ mode
->accumAlphaBits
;
724 result
->cAccumRedBits
= mode
->accumRedBits
;
725 result
->cAccumGreenBits
= mode
->accumGreenBits
;
726 result
->cAccumBlueBits
= mode
->accumBlueBits
;
727 result
->cAccumAlphaBits
= mode
->accumAlphaBits
;
730 if (mode
->haveDepthBuffer
) {
731 result
->cDepthBits
= mode
->depthBits
;
733 if (mode
->haveStencilBuffer
) {
734 result
->cStencilBits
= mode
->stencilBits
;
737 /* result->cAuxBuffers = mode->numAuxBuffers; */
739 /* mode->level ignored */
741 /* mode->pixmapMode ? */
748 static __GLinterface
*glWinCreateContext(__GLimports
*imports
,
749 __GLcontextModes
*mode
,
750 __GLinterface
*shareGC
)
754 GLWIN_DEBUG_MSG("glWinCreateContext\n");
756 result
= (__GLcontext
*)calloc(1, sizeof(__GLcontext
));
760 result
->interface
.imports
= *imports
;
761 result
->interface
.exports
= glWinExports
;
763 if (makeFormat(mode
, &result
->pfd
))
765 ErrorF("makeFormat failed\n");
770 if (glWinDebugSettings
.dumpPFD
)
771 pfdOut(&result
->pfd
);
773 GLWIN_DEBUG_MSG("glWinCreateContext done\n");
774 return (__GLinterface
*)result
;
778 glWinRealizeWindow(WindowPtr pWin
)
780 /* If this window has GL contexts, tell them to reattach */
781 /* reattaching is bad: display lists and parameters get lost */
783 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
784 glWinScreenRec
*screenPriv
= &glWinScreens
[pScreen
->myNum
];
785 __GLXdrawablePrivate
*glxPriv
;
787 GLWIN_DEBUG_MSG("glWinRealizeWindow\n");
789 /* Allow the window to be created (RootlessRealizeWindow is inside our wrap) */
790 pScreen
->RealizeWindow
= screenPriv
->RealizeWindow
;
791 result
= pScreen
->RealizeWindow(pWin
);
792 pScreen
->RealizeWindow
= glWinRealizeWindow
;
794 /* Re-attach this window's GL contexts, if any. */
795 glxPriv
= __glXFindDrawablePrivate(pWin
->drawable
.id
);
799 __GLdrawablePrivate
*glPriv
= &glxPriv
->glPriv
;
800 GLWIN_DEBUG_MSG("glWinRealizeWindow is GL drawable!\n");
802 /* GL contexts bound to this window for drawing */
803 for (gx
= glxPriv
->drawGlxc
; gx
!= NULL
; gx
= gx
->next
) {
804 gc
= (__GLcontext
*)gx
->gc
;
808 GLWIN_DEBUG_MSG("context is already bound! Adjusting HWND.\n");
809 glWinAdjustHWND(gc
, pWin
);
818 /* GL contexts bound to this window for reading */
819 for (gx
= glxPriv
->readGlxc
; gx
!= NULL
; gx
= gx
->next
) {
820 gc
= (__GLcontext
*)gx
->gc
;
824 GLWIN_DEBUG_MSG("context is already bound! Adjusting HWND.\n");
825 glWinAdjustHWND(gc
, pWin
);
840 glWinCopyWindow(WindowPtr pWindow
, DDXPointRec ptOldOrg
, RegionPtr prgnSrc
)
842 ScreenPtr pScreen
= pWindow
->drawable
.pScreen
;
843 glWinScreenRec
*screenPriv
= &glWinScreens
[pScreen
->myNum
];
844 __GLXdrawablePrivate
*glxPriv
;
846 GLWIN_TRACE_MSG(" (pWindow %p)\n", pWindow
);
848 /* Check if the window is attached and discard any drawing request */
849 glxPriv
= __glXFindDrawablePrivate(pWindow
->drawable
.id
);
853 /* GL contexts bound to this window for drawing */
854 for (gx
= glxPriv
->drawGlxc
; gx
!= NULL
; gx
= gx
->next
) {
856 GLWIN_DEBUG_MSG("glWinCopyWindow - calling glDrawBuffer\n");
857 glDrawBuffer(GL_FRONT);
863 /* GL contexts bound to this window for reading */
864 for (gx
= glxPriv
->readGlxc
; gx
!= NULL
; gx
= gx
->next
) {
869 GLWIN_DEBUG_MSG("glWinCopyWindow - passing to hw layer\n");
871 pScreen
->CopyWindow
= screenPriv
->CopyWindow
;
872 pScreen
->CopyWindow(pWindow
, ptOldOrg
, prgnSrc
);
873 pScreen
->CopyWindow
= glWinCopyWindow
;
877 glWinUnrealizeWindow(WindowPtr pWin
)
879 /* If this window has GL contexts, tell them to unattach */
881 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
882 glWinScreenRec
*screenPriv
= &glWinScreens
[pScreen
->myNum
];
883 __GLXdrawablePrivate
*glxPriv
;
885 GLWIN_DEBUG_MSG("glWinUnrealizeWindow\n");
887 /* The Aqua window may have already been destroyed (windows
888 * are unrealized from top down)
891 /* Unattach this window's GL contexts, if any. */
892 glxPriv
= __glXFindDrawablePrivate(pWin
->drawable
.id
);
896 GLWIN_DEBUG_MSG("glWinUnealizeWindow is GL drawable!\n");
898 /* GL contexts bound to this window for drawing */
899 for (gx
= glxPriv
->drawGlxc
; gx
!= NULL
; gx
= gx
->next
) {
900 gc
= (__GLcontext
*)gx
->gc
;
904 /* GL contexts bound to this window for reading */
905 for (gx
= glxPriv
->readGlxc
; gx
!= NULL
; gx
= gx
->next
) {
906 gc
= (__GLcontext
*)gx
->gc
;
911 pScreen
->UnrealizeWindow
= screenPriv
->UnrealizeWindow
;
912 result
= pScreen
->UnrealizeWindow(pWin
);
913 pScreen
->UnrealizeWindow
= glWinUnrealizeWindow
;
920 * In the case the driver has no GLX visuals we'll use these.
921 * [0] = RGB, double buffered
922 * [1] = RGB, double buffered, stencil, accum
924 /* Originally copied from Mesa */
926 static int numConfigs
= 0;
927 static __GLXvisualConfig
*visualConfigs
= NULL
;
928 static void **visualPrivates
= NULL
;
930 #define NUM_FALLBACK_CONFIGS 2
931 static __GLXvisualConfig FallbackConfigs
[NUM_FALLBACK_CONFIGS
] = {
936 -1, -1, -1, 0, /* rgba sizes */
937 -1, -1, -1, 0, /* rgba masks */
938 0, 0, 0, 0, /* rgba accum sizes */
939 True
, /* doubleBuffer */
946 GLX_NONE_EXT
, /* visualRating */
947 0, /* transparentPixel */
948 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
949 0 /* transparentIndex */
955 -1, -1, -1, 0, /* rgba sizes */
956 -1, -1, -1, 0, /* rgba masks */
957 16, 16, 16, 0, /* rgba accum sizes */
958 True
, /* doubleBuffer */
965 GLX_NONE_EXT
, /* visualRating */
966 0, /* transparentPixel */
967 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
968 0 /* transparentIndex */
972 static __GLXvisualConfig NullConfig
= {
976 -1, -1, -1, 0, /* rgba sizes */
977 -1, -1, -1, 0, /* rgba masks */
978 0, 0, 0, 0, /* rgba accum sizes */
979 False
, /* doubleBuffer */
986 GLX_NONE_EXT
, /* visualRating */
987 0, /* transparentPixel */
988 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
989 0 /* transparentIndex */
992 static inline int count_bits(uint32_t x
)
994 x
= x
- ((x
>> 1) & 0x55555555);
995 x
= (x
& 0x33333333) + ((x
>> 2) & 0x33333333);
996 x
= (x
+ (x
>> 4)) & 0x0f0f0f0f;
1002 /* Mostly copied from Mesa's xf86glx.c */
1003 static Bool
init_visuals(int *nvisualp
, VisualPtr
*visualp
,
1004 VisualID
*defaultVisp
,
1005 int ndepth
, DepthPtr pdepth
,
1010 int numVisuals
= *nvisualp
;
1013 VisualPtr pVisual
= *visualp
;
1014 VisualPtr pVisualNew
= NULL
;
1015 VisualID
*orig_vid
= NULL
;
1016 __GLcontextModes
*modes
= NULL
;
1017 __GLXvisualConfig
*pNewVisualConfigs
= NULL
;
1018 void **glXVisualPriv
;
1019 void **pNewVisualPriv
;
1023 GLWIN_DEBUG_MSG("init_visuals\n");
1026 numNewConfigs
= numConfigs
;
1028 numNewConfigs
= NUM_FALLBACK_CONFIGS
;
1030 /* Alloc space for the list of new GLX visuals */
1031 pNewVisualConfigs
= (__GLXvisualConfig
*)
1032 __glXMalloc(numNewConfigs
* sizeof(__GLXvisualConfig
));
1033 if (!pNewVisualConfigs
) {
1037 /* Alloc space for the list of new GLX visual privates */
1038 pNewVisualPriv
= (void **) __glXMalloc(numNewConfigs
* sizeof(void *));
1039 if (!pNewVisualPriv
) {
1040 __glXFree(pNewVisualConfigs
);
1045 ** If SetVisualConfigs was not called, then use default GLX
1048 if (numConfigs
== 0) {
1049 memcpy(pNewVisualConfigs
, FallbackConfigs
,
1050 NUM_FALLBACK_CONFIGS
* sizeof(__GLXvisualConfig
));
1051 memset(pNewVisualPriv
, 0, NUM_FALLBACK_CONFIGS
* sizeof(void *));
1054 /* copy driver's visual config info */
1055 for (i
= 0; i
< numConfigs
; i
++) {
1056 pNewVisualConfigs
[i
] = visualConfigs
[i
];
1057 pNewVisualPriv
[i
] = visualPrivates
[i
];
1061 /* Count the number of RGB and CI visual configs */
1064 for (i
= 0; i
< numNewConfigs
; i
++) {
1065 if (pNewVisualConfigs
[i
].rgba
)
1071 /* Count the total number of visuals to compute */
1073 for (i
= 0; i
< numVisuals
; i
++) {
1076 count
= ((pVisual
[i
].class == TrueColor
1077 || pVisual
[i
].class == DirectColor
)
1078 ? numRGBconfigs
: numCIconfigs
);
1080 count
= 1; /* preserve the existing visual */
1082 numNewVisuals
+= count
;
1085 /* Reset variables for use with the next screen/driver's visual configs */
1086 visualConfigs
= NULL
;
1089 /* Alloc temp space for the list of orig VisualIDs for each new visual */
1090 orig_vid
= (VisualID
*)__glXMalloc(numNewVisuals
* sizeof(VisualID
));
1092 __glXFree(pNewVisualPriv
);
1093 __glXFree(pNewVisualConfigs
);
1097 /* Alloc space for the list of glXVisuals */
1098 modes
= _gl_context_modes_create(numNewVisuals
, sizeof(__GLcontextModes
));
1099 if (modes
== NULL
) {
1100 __glXFree(orig_vid
);
1101 __glXFree(pNewVisualPriv
);
1102 __glXFree(pNewVisualConfigs
);
1106 /* Alloc space for the list of glXVisualPrivates */
1107 glXVisualPriv
= (void **)__glXMalloc(numNewVisuals
* sizeof(void *));
1108 if (!glXVisualPriv
) {
1109 _gl_context_modes_destroy( modes
);
1110 __glXFree(orig_vid
);
1111 __glXFree(pNewVisualPriv
);
1112 __glXFree(pNewVisualConfigs
);
1116 /* Alloc space for the new list of the X server's visuals */
1117 pVisualNew
= (VisualPtr
)__glXMalloc(numNewVisuals
* sizeof(VisualRec
));
1119 __glXFree(glXVisualPriv
);
1120 _gl_context_modes_destroy( modes
);
1121 __glXFree(orig_vid
);
1122 __glXFree(pNewVisualPriv
);
1123 __glXFree(pNewVisualConfigs
);
1127 /* Initialize the new visuals */
1128 found_default
= FALSE
;
1129 glWinScreens
[screenInfo
.numScreens
-1].modes
= modes
;
1130 for (i
= j
= 0; i
< numVisuals
; i
++) {
1131 int is_rgb
= (pVisual
[i
].class == TrueColor
||
1132 pVisual
[i
].class == DirectColor
);
1136 /* We don't support non-rgb visuals for GL. But we don't
1137 want to remove them either, so just pass them through
1138 with null glX configs */
1140 pVisualNew
[j
] = pVisual
[i
];
1141 pVisualNew
[j
].vid
= FakeClientID(0);
1143 /* Check for the default visual */
1144 if (!found_default
&& pVisual
[i
].vid
== *defaultVisp
) {
1145 *defaultVisp
= pVisualNew
[j
].vid
;
1146 found_default
= TRUE
;
1149 /* Save the old VisualID */
1150 orig_vid
[j
] = pVisual
[i
].vid
;
1152 /* Initialize the glXVisual */
1153 _gl_copy_visual_to_context_mode( modes
, & NullConfig
);
1154 modes
->visualID
= pVisualNew
[j
].vid
;
1161 for (k
= 0; k
< numNewConfigs
; k
++) {
1162 if (pNewVisualConfigs
[k
].rgba
!= is_rgb
)
1165 assert( modes
!= NULL
);
1167 /* Initialize the new visual */
1168 pVisualNew
[j
] = pVisual
[i
];
1169 pVisualNew
[j
].vid
= FakeClientID(0);
1171 /* Check for the default visual */
1172 if (!found_default
&& pVisual
[i
].vid
== *defaultVisp
) {
1173 *defaultVisp
= pVisualNew
[j
].vid
;
1174 found_default
= TRUE
;
1177 /* Save the old VisualID */
1178 orig_vid
[j
] = pVisual
[i
].vid
;
1180 /* Initialize the glXVisual */
1181 _gl_copy_visual_to_context_mode( modes
, & pNewVisualConfigs
[k
] );
1182 modes
->visualID
= pVisualNew
[j
].vid
;
1185 * If the class is -1, then assume the X visual information
1186 * is identical to what GLX needs, and take them from the X
1187 * visual. NOTE: if class != -1, then all other fields MUST
1190 if (modes
->visualType
== GLX_NONE
) {
1191 modes
->visualType
= _gl_convert_from_x_visual_type( pVisual
[i
].class );
1192 modes
->redBits
= count_bits(pVisual
[i
].redMask
);
1193 modes
->greenBits
= count_bits(pVisual
[i
].greenMask
);
1194 modes
->blueBits
= count_bits(pVisual
[i
].blueMask
);
1195 modes
->alphaBits
= modes
->alphaBits
;
1196 modes
->redMask
= pVisual
[i
].redMask
;
1197 modes
->greenMask
= pVisual
[i
].greenMask
;
1198 modes
->blueMask
= pVisual
[i
].blueMask
;
1199 modes
->alphaMask
= modes
->alphaMask
;
1200 modes
->rgbBits
= (is_rgb
)
1201 ? (modes
->redBits
+ modes
->greenBits
+
1202 modes
->blueBits
+ modes
->alphaBits
)
1206 /* Save the device-dependent private for this visual */
1207 glXVisualPriv
[j
] = pNewVisualPriv
[k
];
1210 modes
= modes
->next
;
1214 assert(j
<= numNewVisuals
);
1216 /* Save the GLX visuals in the screen structure */
1217 glWinScreens
[screenInfo
.numScreens
-1].num_vis
= numNewVisuals
;
1218 glWinScreens
[screenInfo
.numScreens
-1].priv
= glXVisualPriv
;
1220 /* Set up depth's VisualIDs */
1221 for (i
= 0; i
< ndepth
; i
++) {
1223 VisualID
*pVids
= NULL
;
1226 /* Count the new number of VisualIDs at this depth */
1227 for (j
= 0; j
< pdepth
[i
].numVids
; j
++)
1228 for (k
= 0; k
< numNewVisuals
; k
++)
1229 if (pdepth
[i
].vids
[j
] == orig_vid
[k
])
1232 /* Allocate a new list of VisualIDs for this depth */
1233 pVids
= (VisualID
*)__glXMalloc(numVids
* sizeof(VisualID
));
1235 /* Initialize the new list of VisualIDs for this depth */
1236 for (j
= 0; j
< pdepth
[i
].numVids
; j
++)
1237 for (k
= 0; k
< numNewVisuals
; k
++)
1238 if (pdepth
[i
].vids
[j
] == orig_vid
[k
])
1239 pVids
[n
++] = pVisualNew
[k
].vid
;
1241 /* Update this depth's list of VisualIDs */
1242 __glXFree(pdepth
[i
].vids
);
1243 pdepth
[i
].vids
= pVids
;
1244 pdepth
[i
].numVids
= numVids
;
1247 /* Update the X server's visuals */
1248 *nvisualp
= numNewVisuals
;
1249 *visualp
= pVisualNew
;
1251 /* Free the old list of the X server's visuals */
1254 /* Clean up temporary allocations */
1255 __glXFree(orig_vid
);
1256 __glXFree(pNewVisualPriv
);
1257 __glXFree(pNewVisualConfigs
);
1259 /* Free the private list created by DDX HW driver */
1261 xfree(visualPrivates
);
1262 visualPrivates
= NULL
;
1268 static void fixup_visuals(int screen
)
1270 ScreenPtr pScreen
= screenInfo
.screens
[screen
];
1271 glWinScreenRec
*pScr
= &glWinScreens
[screen
];
1272 __GLcontextModes
*modes
;
1275 GLWIN_DEBUG_MSG("fixup_visuals\n");
1277 for (modes
= pScr
->modes
; modes
!= NULL
; modes
= modes
->next
) {
1278 const int vis_class
= _gl_convert_to_x_visual_type( modes
->visualType
);
1279 const int nplanes
= (modes
->rgbBits
- modes
->alphaBits
);
1280 VisualPtr pVis
= pScreen
->visuals
;
1282 /* Find a visual that matches the GLX visual's class and size */
1283 for (j
= 0; j
< pScreen
->numVisuals
; j
++) {
1284 if (pVis
[j
].class == vis_class
&&
1285 pVis
[j
].nplanes
== nplanes
) {
1287 /* Fixup the masks */
1288 modes
->redMask
= pVis
[j
].redMask
;
1289 modes
->greenMask
= pVis
[j
].greenMask
;
1290 modes
->blueMask
= pVis
[j
].blueMask
;
1292 /* Recalc the sizes */
1293 modes
->redBits
= count_bits(modes
->redMask
);
1294 modes
->greenBits
= count_bits(modes
->greenMask
);
1295 modes
->blueBits
= count_bits(modes
->blueMask
);
1301 static void init_screen_visuals(int screen
)
1303 ScreenPtr pScreen
= screenInfo
.screens
[screen
];
1304 __GLcontextModes
*modes
;
1308 GLWIN_DEBUG_MSG("init_screen_visuals\n");
1310 used
= (int *)__glXMalloc(pScreen
->numVisuals
* sizeof(int));
1311 __glXMemset(used
, 0, pScreen
->numVisuals
* sizeof(int));
1314 for ( modes
= glWinScreens
[screen
].modes
1316 ; modes
= modes
->next
) {
1317 const int vis_class
= _gl_convert_to_x_visual_type( modes
->visualType
);
1318 const int nplanes
= (modes
->rgbBits
- modes
->alphaBits
);
1319 const VisualPtr pVis
= pScreen
->visuals
;
1321 for (j
= 0; j
< pScreen
->numVisuals
; j
++) {
1323 if (pVis
[j
].class == vis_class
&&
1324 pVis
[j
].nplanes
== nplanes
&&
1325 pVis
[j
].redMask
== modes
->redMask
&&
1326 pVis
[j
].greenMask
== modes
->greenMask
&&
1327 pVis
[j
].blueMask
== modes
->blueMask
&&
1331 /* Create the XMesa visual */
1333 XMesaCreateVisual(pScreen
,
1336 (modes
->alphaBits
> 0),
1337 modes
->doubleBufferMode
,
1339 GL_TRUE
, /* ximage_flag */
1342 modes
->accumRedBits
,
1343 modes
->accumGreenBits
,
1344 modes
->accumBlueBits
,
1345 modes
->accumAlphaBits
,
1348 modes
->visualRating
);
1351 /* Set the VisualID */
1352 modes
->visualID
= pVis
[j
].vid
;
1354 /* Mark this visual used */
1360 if ( j
== pScreen
->numVisuals
) {
1361 ErrorF("No matching visual for __GLcontextMode with "
1362 "visual class = %d (%d), nplanes = %u\n",
1365 (modes
->rgbBits
- modes
->alphaBits
) );
1367 else if ( modes
->visualID
== -1 ) {
1368 FatalError( "Matching visual found, but visualID still -1!\n" );
1377 /* glWinScreens[screen].xm_vis = pXMesaVisual; */
1380 static Bool
glWinScreenProbe(int screen
)
1383 glWinScreenRec
*screenPriv
;
1385 GLWIN_DEBUG_MSG("glWinScreenProbe\n");
1388 * Set up the current screen's visuals.
1390 __glDDXScreenInfo
.modes
= glWinScreens
[screen
].modes
;
1391 __glDDXScreenInfo
.pVisualPriv
= glWinScreens
[screen
].priv
;
1392 __glDDXScreenInfo
.numVisuals
=
1393 __glDDXScreenInfo
.numUsableVisuals
= glWinScreens
[screen
].num_vis
;
1396 * Set the current screen's createContext routine. This could be
1397 * wrapped by a DDX GLX context creation routine.
1399 __glDDXScreenInfo
.createContext
= glWinCreateContext
;
1402 * The ordering of the rgb compenents might have been changed by the
1403 * driver after mi initialized them.
1405 fixup_visuals(screen
);
1408 * Find the GLX visuals that are supported by this screen and create
1411 init_screen_visuals(screen
);
1413 /* Wrap RealizeWindow and UnrealizeWindow on this screen */
1414 pScreen
= screenInfo
.screens
[screen
];
1415 screenPriv
= &glWinScreens
[screen
];
1416 screenPriv
->RealizeWindow
= pScreen
->RealizeWindow
;
1417 pScreen
->RealizeWindow
= glWinRealizeWindow
;
1418 screenPriv
->UnrealizeWindow
= pScreen
->UnrealizeWindow
;
1419 pScreen
->UnrealizeWindow
= glWinUnrealizeWindow
;
1420 screenPriv
->CopyWindow
= pScreen
->CopyWindow
;
1421 pScreen
->CopyWindow
= glWinCopyWindow
;
1426 static GLboolean
glWinSwapBuffers(__GLXdrawablePrivate
*glxPriv
)
1428 /* swap buffers on only *one* of the contexts
1429 * (e.g. the last one for drawing)
1431 __GLcontext
*gc
= (__GLcontext
*)glxPriv
->drawGlxc
->gc
;
1435 GLWIN_TRACE_MSG("glWinSwapBuffers (ctx %p)\n", (gc
!=NULL
?gc
->ctx
:NULL
));
1437 if (gc
!= NULL
&& gc
->ctx
!= NULL
)
1439 dc
= glWinMakeDC(gc
);
1443 ret
= SwapBuffers(dc
);
1445 ErrorF("SwapBuffers failed: %s\n", glWinErrorMessage());
1447 ReleaseDC(gc
->winInfo
.hwnd
, dc
);
1455 static void glWinDestroyDrawablePrivate(__GLdrawablePrivate
*glPriv
)
1457 GLWIN_DEBUG_MSG("glWinDestroyDrawablePrivate\n");
1459 /* It doesn't work to call DRIDestroySurface here, the drawable's
1460 already gone.. But dri.c notices the window destruction and
1461 frees the surface itself. */
1463 free(glPriv
->private);
1464 glPriv
->private = NULL
;
1468 static void glWinCreateBuffer(__GLXdrawablePrivate
*glxPriv
)
1470 GLWinDrawableRec
*winPriv
= malloc(sizeof(GLWinDrawableRec
));
1471 __GLdrawablePrivate
*glPriv
= &glxPriv
->glPriv
;
1473 /*winPriv->sid = 0; */
1474 winPriv
->pDraw
= NULL
;
1476 GLWIN_DEBUG_MSG("glWinCreateBuffer\n");
1478 /* replace swapBuffers (original is never called) */
1479 glxPriv
->swapBuffers
= glWinSwapBuffers
;
1481 /* stash private data */
1482 glPriv
->private = winPriv
;
1483 glPriv
->freePrivate
= glWinDestroyDrawablePrivate
;
1486 static void glWinResetExtension(void)
1488 GLWIN_DEBUG_MSG("glWinResetExtension\n");
1491 /* based on code in apples/indirect.c which is based on i830_dri.c */
1493 glWinInitVisualConfigs(void)
1495 int lclNumConfigs
= 0;
1496 __GLXvisualConfig
*lclVisualConfigs
= NULL
;
1497 void **lclVisualPrivates
= NULL
;
1499 int depth
, aux
, buffers
, stencil
, accum
;
1502 GLWIN_DEBUG_MSG("glWinInitVisualConfigs ");
1504 /* count num configs:
1505 2 Z buffer (0, 24 bit)
1507 2 buffers (single, double)
1508 2 stencil (0, 8 bit)
1512 lclNumConfigs
= 2 * 2 * 2 * 2 * 2; /* 32 */
1515 lclVisualConfigs
= xcalloc(sizeof(__GLXvisualConfig
), lclNumConfigs
);
1516 lclVisualPrivates
= xcalloc(sizeof(void *), lclNumConfigs
);
1518 /* fill in configs */
1519 if (NULL
!= lclVisualConfigs
) {
1520 i
= 0; /* current buffer */
1521 for (depth
= 0; depth
< 2; depth
++) {
1522 for (aux
= 0; aux
< 2; aux
++) {
1523 for (buffers
= 0; buffers
< 2; buffers
++) {
1524 for (stencil
= 0; stencil
< 2; stencil
++) {
1525 for (accum
= 0; accum
< 2; accum
++) {
1526 lclVisualConfigs
[i
].vid
= -1;
1527 lclVisualConfigs
[i
].class = -1;
1528 lclVisualConfigs
[i
].rgba
= TRUE
;
1529 lclVisualConfigs
[i
].redSize
= -1;
1530 lclVisualConfigs
[i
].greenSize
= -1;
1531 lclVisualConfigs
[i
].blueSize
= -1;
1532 lclVisualConfigs
[i
].redMask
= -1;
1533 lclVisualConfigs
[i
].greenMask
= -1;
1534 lclVisualConfigs
[i
].blueMask
= -1;
1535 lclVisualConfigs
[i
].alphaMask
= 0;
1537 lclVisualConfigs
[i
].accumRedSize
= 16;
1538 lclVisualConfigs
[i
].accumGreenSize
= 16;
1539 lclVisualConfigs
[i
].accumBlueSize
= 16;
1540 lclVisualConfigs
[i
].accumAlphaSize
= 16;
1543 lclVisualConfigs
[i
].accumRedSize
= 0;
1544 lclVisualConfigs
[i
].accumGreenSize
= 0;
1545 lclVisualConfigs
[i
].accumBlueSize
= 0;
1546 lclVisualConfigs
[i
].accumAlphaSize
= 0;
1548 lclVisualConfigs
[i
].doubleBuffer
= buffers
? TRUE
: FALSE
;
1549 lclVisualConfigs
[i
].stereo
= FALSE
;
1550 lclVisualConfigs
[i
].bufferSize
= -1;
1552 lclVisualConfigs
[i
].depthSize
= depth
? 24 : 0;
1553 lclVisualConfigs
[i
].stencilSize
= stencil
? 8 : 0;
1554 lclVisualConfigs
[i
].auxBuffers
= aux
? 2 : 0;
1555 lclVisualConfigs
[i
].level
= 0;
1556 lclVisualConfigs
[i
].visualRating
= GLX_NONE_EXT
;
1557 lclVisualConfigs
[i
].transparentPixel
= 0;
1558 lclVisualConfigs
[i
].transparentRed
= 0;
1559 lclVisualConfigs
[i
].transparentGreen
= 0;
1560 lclVisualConfigs
[i
].transparentBlue
= 0;
1561 lclVisualConfigs
[i
].transparentAlpha
= 0;
1562 lclVisualConfigs
[i
].transparentIndex
= 0;
1570 if (i
!= lclNumConfigs
)
1571 GLWIN_DEBUG_MSG("glWinInitVisualConfigs failed to alloc visual configs");
1573 GlxSetVisualConfigs(lclNumConfigs
, lclVisualConfigs
, lclVisualPrivates
);
1576 /* Copied from Mesa */
1577 static void glWinSetVisualConfigs(int nconfigs
, __GLXvisualConfig
*configs
,
1580 GLWIN_DEBUG_MSG("glWinSetVisualConfigs\n");
1582 numConfigs
= nconfigs
;
1583 visualConfigs
= configs
;
1584 visualPrivates
= privates
;
1587 /* Copied from Mesa */
1588 static Bool
glWinInitVisuals(VisualPtr
*visualp
, DepthPtr
*depthp
,
1589 int *nvisualp
, int *ndepthp
,
1590 int *rootDepthp
, VisualID
*defaultVisp
,
1591 unsigned long sizes
, int bitsPerRGB
)
1593 glWinInitDebugSettings();
1595 GLWIN_DEBUG_MSG("glWinInitVisuals\n");
1597 if (0 == numConfigs
) /* if no configs */
1598 glWinInitVisualConfigs(); /* ensure the visula configs are setup */
1601 * Setup the visuals supported by this particular screen.
1603 return init_visuals(nvisualp
, visualp
, defaultVisp
,
1604 *ndepthp
, *depthp
, *rootDepthp
);