Add GLFW_TRANSPARENT and X11 implementation

This is a squashed extract of several commits, minimally edited to
ensure it compiles.

Related to #197.
Related to #715.
This commit is contained in:
Wolfgang Draxinger
2016-02-22 18:08:15 +01:00
committed by Camilla Löwy
parent eed94448fd
commit 019609b6cd
11 changed files with 180 additions and 16 deletions
+41 -5
View File
@@ -47,7 +47,10 @@ static int getGLXFBConfigAttrib(GLXFBConfig fbconfig, int attrib)
// Return the GLXFBConfig most closely matching the specified hints
//
static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* result)
static GLFWbool chooseGLXFBConfig(
const _GLFWfbconfig* desired,
GLXFBConfig* result,
GLFWbool findTransparent)
{
GLXFBConfig* nativeConfigs;
_GLFWfbconfig* usableConfigs;
@@ -56,6 +59,10 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* res
const char* vendor;
GLFWbool trustWindowBit = GLFW_TRUE;
if ( !(_glfw.xrender.major || _glfw.xrender.minor) ) {
findTransparent = GLFW_FALSE;
}
// HACK: This is a (hopefully temporary) workaround for Chromium
// (VirtualBox GL) not setting the window bit on any GLXFBConfigs
vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR);
@@ -73,6 +80,7 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* res
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
usableCount = 0;
selectionloop:
for (i = 0; i < nativeCount; i++)
{
const GLXFBConfig n = nativeConfigs[i];
@@ -89,6 +97,27 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* res
continue;
}
if( findTransparent ) {
XVisualInfo *visualinfo;
XRenderPictFormat *pictFormat;
visualinfo = glXGetVisualFromFBConfig(_glfw.x11.display, n);
if (!visualinfo)
continue;
pictFormat = XRenderFindVisualFormat(_glfw.x11.display, visualinfo->visual);
if( !pictFormat ) {
XFree( visualinfo );
continue;
}
if( !pictFormat->direct.alphaMask ) {
XFree( visualinfo );
continue;
}
XFree( visualinfo );
}
u->redBits = getGLXFBConfigAttrib(n, GLX_RED_SIZE);
u->greenBits = getGLXFBConfigAttrib(n, GLX_GREEN_SIZE);
u->blueBits = getGLXFBConfigAttrib(n, GLX_BLUE_SIZE);
@@ -118,6 +147,12 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* res
u->handle = (uintptr_t) n;
usableCount++;
}
// reiterate the selection loop without looking for transparency supporting
// formats if no matchig FB configs for a transparent window were found.
if( findTransparent && !usableCount ) {
findTransparent = GLFW_FALSE;
goto selectionloop;
}
closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);
if (closest)
@@ -442,7 +477,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
if (ctxconfig->share)
share = ctxconfig->share->context.glx.handle;
if (!chooseGLXFBConfig(fbconfig, &native))
if (!chooseGLXFBConfig(fbconfig, &native, window->transparent))
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"GLX: Failed to find a suitable GLXFBConfig");
@@ -622,14 +657,15 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
// Returns the Visual and depth of the chosen GLXFBConfig
//
GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig,
GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth)
{
GLXFBConfig native;
XVisualInfo* result;
if (!chooseGLXFBConfig(fbconfig, &native))
if (!chooseGLXFBConfig(fbconfig, &native, wndconfig->transparent))
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"GLX: Failed to find a suitable GLXFBConfig");
@@ -645,7 +681,7 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig,
}
*visual = result->visual;
*depth = result->depth;
*depth = result->depth;
XFree(result);
return GLFW_TRUE;