mirror of
https://github.com/glfw/glfw.git
synced 2025-10-05 06:06:36 +00:00
Merge remote-tracking branch 'glfw/transparent-window' into cosier/transparent_windows
This commit is contained in:
commit
6d4708f78a
1
.gitignore
vendored
1
.gitignore
vendored
@ -15,6 +15,7 @@ MinSizeRel
|
|||||||
RelWithDebInfo
|
RelWithDebInfo
|
||||||
*.xcodeproj
|
*.xcodeproj
|
||||||
.vs
|
.vs
|
||||||
|
*.VC.opendb
|
||||||
|
|
||||||
# CMake files
|
# CMake files
|
||||||
Makefile
|
Makefile
|
||||||
|
@ -172,6 +172,7 @@ static GLfloat angle = 0.f;
|
|||||||
/* OpenGL draw function & timing */
|
/* OpenGL draw function & timing */
|
||||||
static void draw(void)
|
static void draw(void)
|
||||||
{
|
{
|
||||||
|
glClearColor(0., 0., 0., 0.);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
@ -297,7 +298,6 @@ static void init(void)
|
|||||||
glEnable(GL_NORMALIZE);
|
glEnable(GL_NORMALIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* program entry */
|
/* program entry */
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@ -311,6 +311,9 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
glfwWindowHint(GLFW_DEPTH_BITS, 16);
|
glfwWindowHint(GLFW_DEPTH_BITS, 16);
|
||||||
|
glfwWindowHint(GLFW_ALPHA_BITS, 8);
|
||||||
|
glfwWindowHint(GLFW_TRANSPARENT, GLFW_TRUE);
|
||||||
|
glfwWindowHint(GLFW_DECORATED, GLFW_TRUE);
|
||||||
|
|
||||||
window = glfwCreateWindow( 300, 300, "Gears", NULL, NULL );
|
window = glfwCreateWindow( 300, 300, "Gears", NULL, NULL );
|
||||||
if (!window)
|
if (!window)
|
||||||
|
@ -788,6 +788,7 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
#define GLFW_CENTER_CURSOR 0x00020009
|
#define GLFW_CENTER_CURSOR 0x00020009
|
||||||
|
|
||||||
|
|
||||||
/*! @brief Framebuffer bit depth hint.
|
/*! @brief Framebuffer bit depth hint.
|
||||||
*
|
*
|
||||||
* Framebuffer bit depth [hint](@ref GLFW_RED_BITS).
|
* Framebuffer bit depth [hint](@ref GLFW_RED_BITS).
|
||||||
|
@ -87,13 +87,21 @@ static int getEGLConfigAttrib(EGLConfig config, int attrib)
|
|||||||
//
|
//
|
||||||
static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* desired,
|
const _GLFWfbconfig* desired,
|
||||||
EGLConfig* result)
|
EGLConfig* result,
|
||||||
|
GLFWbool findTransparent)
|
||||||
{
|
{
|
||||||
EGLConfig* nativeConfigs;
|
EGLConfig* nativeConfigs;
|
||||||
_GLFWfbconfig* usableConfigs;
|
_GLFWfbconfig* usableConfigs;
|
||||||
const _GLFWfbconfig* closest;
|
const _GLFWfbconfig* closest;
|
||||||
int i, nativeCount, usableCount;
|
int i, nativeCount, usableCount;
|
||||||
|
|
||||||
|
#if defined(_GLFW_X11)
|
||||||
|
XVisualInfo visualTemplate = {0};
|
||||||
|
if ( !(_glfw.xrender.major || _glfw.xrender.minor) ) {
|
||||||
|
findTransparent = GLFW_FALSE;
|
||||||
|
}
|
||||||
|
#endif // _GLFW_X11
|
||||||
|
|
||||||
eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount);
|
eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount);
|
||||||
if (!nativeCount)
|
if (!nativeCount)
|
||||||
{
|
{
|
||||||
@ -107,6 +115,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
|||||||
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
|
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
|
||||||
usableCount = 0;
|
usableCount = 0;
|
||||||
|
|
||||||
|
selectionloop:
|
||||||
for (i = 0; i < nativeCount; i++)
|
for (i = 0; i < nativeCount; i++)
|
||||||
{
|
{
|
||||||
const EGLConfig n = nativeConfigs[i];
|
const EGLConfig n = nativeConfigs[i];
|
||||||
@ -124,6 +133,28 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
|||||||
// Only consider EGLConfigs with associated Visuals
|
// Only consider EGLConfigs with associated Visuals
|
||||||
if (!getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID))
|
if (!getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if( findTransparent ) {
|
||||||
|
int n_vi;
|
||||||
|
XVisualInfo *visualinfo;
|
||||||
|
XRenderPictFormat *pictFormat;
|
||||||
|
|
||||||
|
visualinfo = XGetVisualInfo(_glfw.x11.display, VisualIDMask, &visualTemplate, &n_vi);
|
||||||
|
if (!visualinfo)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pictFormat = XRenderFindVisualFormat(_glfw.x11.display, visualinfo->visual);
|
||||||
|
if( !pictFormat ) {
|
||||||
|
XFree( visualinfo );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !pictFormat->direct.alphaMask ) {
|
||||||
|
XFree( visualinfo );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
XFree( visualinfo );
|
||||||
|
}
|
||||||
#endif // _GLFW_X11
|
#endif // _GLFW_X11
|
||||||
|
|
||||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||||
@ -159,6 +190,12 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
|||||||
u->handle = (uintptr_t) n;
|
u->handle = (uintptr_t) n;
|
||||||
usableCount++;
|
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);
|
closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);
|
||||||
if (closest)
|
if (closest)
|
||||||
@ -455,7 +492,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
if (ctxconfig->share)
|
if (ctxconfig->share)
|
||||||
share = ctxconfig->share->context.egl.handle;
|
share = ctxconfig->share->context.egl.handle;
|
||||||
|
|
||||||
if (!chooseEGLConfig(ctxconfig, fbconfig, &config))
|
if (!chooseEGLConfig(ctxconfig, fbconfig, &config, fbconfig->alphaMask))
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||||
"EGL: Failed to find a suitable EGLConfig");
|
"EGL: Failed to find a suitable EGLConfig");
|
||||||
@ -689,7 +726,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
// Returns the Visual and depth of the chosen EGLConfig
|
// Returns the Visual and depth of the chosen EGLConfig
|
||||||
//
|
//
|
||||||
#if defined(_GLFW_X11)
|
#if defined(_GLFW_X11)
|
||||||
GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig,
|
GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig,
|
const _GLFWfbconfig* fbconfig,
|
||||||
Visual** visual, int* depth)
|
Visual** visual, int* depth)
|
||||||
{
|
{
|
||||||
@ -699,7 +737,8 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig,
|
|||||||
EGLint visualID = 0, count = 0;
|
EGLint visualID = 0, count = 0;
|
||||||
const long vimask = VisualScreenMask | VisualIDMask;
|
const long vimask = VisualScreenMask | VisualIDMask;
|
||||||
|
|
||||||
if (!chooseEGLConfig(ctxconfig, fbconfig, &native))
|
|
||||||
|
if (!chooseEGLConfig(ctxconfig, fbconfig, &native, wndconfig->alphaMask))
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||||
"EGL: Failed to find a suitable EGLConfig");
|
"EGL: Failed to find a suitable EGLConfig");
|
||||||
|
@ -211,7 +211,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
const _GLFWctxconfig* ctxconfig,
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig);
|
const _GLFWfbconfig* fbconfig);
|
||||||
#if defined(_GLFW_X11)
|
#if defined(_GLFW_X11)
|
||||||
GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig,
|
GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig,
|
const _GLFWfbconfig* fbconfig,
|
||||||
Visual** visual, int* depth);
|
Visual** visual, int* depth);
|
||||||
#endif /*_GLFW_X11*/
|
#endif /*_GLFW_X11*/
|
||||||
|
@ -47,7 +47,11 @@ static int getGLXFBConfigAttrib(GLXFBConfig fbconfig, int attrib)
|
|||||||
|
|
||||||
// Return the GLXFBConfig most closely matching the specified hints
|
// 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;
|
GLXFBConfig* nativeConfigs;
|
||||||
_GLFWfbconfig* usableConfigs;
|
_GLFWfbconfig* usableConfigs;
|
||||||
@ -55,8 +59,10 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* res
|
|||||||
int i, nativeCount, usableCount;
|
int i, nativeCount, usableCount;
|
||||||
const char* vendor;
|
const char* vendor;
|
||||||
GLFWbool trustWindowBit = GLFW_TRUE;
|
GLFWbool trustWindowBit = GLFW_TRUE;
|
||||||
XVisualInfo *visual;
|
|
||||||
XRenderPictFormat *pict_format;
|
if ( !(_glfw.xrender.major || _glfw.xrender.minor) ) {
|
||||||
|
findTransparent = GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
// HACK: This is a (hopefully temporary) workaround for Chromium
|
// HACK: This is a (hopefully temporary) workaround for Chromium
|
||||||
// (VirtualBox GL) not setting the window bit on any GLXFBConfigs
|
// (VirtualBox GL) not setting the window bit on any GLXFBConfigs
|
||||||
@ -75,7 +81,8 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* res
|
|||||||
|
|
||||||
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
|
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
|
||||||
usableCount = 0;
|
usableCount = 0;
|
||||||
|
|
||||||
|
selectionloop:
|
||||||
for (i = 0; i < nativeCount; i++)
|
for (i = 0; i < nativeCount; i++)
|
||||||
{
|
{
|
||||||
const GLXFBConfig n = nativeConfigs[i];
|
const GLXFBConfig n = nativeConfigs[i];
|
||||||
@ -92,13 +99,30 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* res
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
visual = glXGetVisualFromFBConfig(_glfw.x11.display, n);
|
if( findTransparent ) {
|
||||||
pict_format = XRenderFindVisualFormat(_glfw.x11.display, visual->visual);
|
XVisualInfo *visualinfo;
|
||||||
u->alphaMask = pict_format->direct.alphaMask > 0;
|
XRenderPictFormat *pictFormat;
|
||||||
|
|
||||||
u->redBits = getGLXFBConfigAttrib(n, GLX_RED_SIZE);
|
visualinfo = glXGetVisualFromFBConfig(_glfw.x11.display, n);
|
||||||
u->greenBits = getGLXFBConfigAttrib(n, GLX_GREEN_SIZE);
|
if (!visualinfo)
|
||||||
u->blueBits = getGLXFBConfigAttrib(n, GLX_BLUE_SIZE);
|
continue;
|
||||||
|
|
||||||
|
pictFormat = XRenderFindVisualFormat(_glfw.x11.display, visualinfo->visual);
|
||||||
|
if( !pictFormat ) {
|
||||||
|
XFree( visualinfo );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !pictFormat->direct.alphaMask ) {
|
||||||
|
XFree( visualinfo );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
XFree( visualinfo );
|
||||||
|
}
|
||||||
|
|
||||||
|
u->redBits = getFBConfigAttrib(n, GLX_RED_SIZE);
|
||||||
|
u->greenBits = getFBConfigAttrib(n, GLX_GREEN_SIZE);
|
||||||
|
u->blueBits = getFBConfigAttrib(n, GLX_BLUE_SIZE);
|
||||||
|
|
||||||
u->alphaBits = getGLXFBConfigAttrib(n, GLX_ALPHA_SIZE);
|
u->alphaBits = getGLXFBConfigAttrib(n, GLX_ALPHA_SIZE);
|
||||||
u->depthBits = getGLXFBConfigAttrib(n, GLX_DEPTH_SIZE);
|
u->depthBits = getGLXFBConfigAttrib(n, GLX_DEPTH_SIZE);
|
||||||
@ -125,6 +149,12 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* res
|
|||||||
u->handle = (uintptr_t) n;
|
u->handle = (uintptr_t) n;
|
||||||
usableCount++;
|
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);
|
closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);
|
||||||
if (closest)
|
if (closest)
|
||||||
@ -249,7 +279,7 @@ static void destroyContextGLX(_GLFWwindow* window)
|
|||||||
GLFWbool _glfwInitGLX(void)
|
GLFWbool _glfwInitGLX(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
const char* sonames[] =
|
const char* sonames_glx[] =
|
||||||
{
|
{
|
||||||
#if defined(_GLFW_GLX_LIBRARY)
|
#if defined(_GLFW_GLX_LIBRARY)
|
||||||
_GLFW_GLX_LIBRARY,
|
_GLFW_GLX_LIBRARY,
|
||||||
@ -265,9 +295,9 @@ GLFWbool _glfwInitGLX(void)
|
|||||||
if (_glfw.glx.handle)
|
if (_glfw.glx.handle)
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
|
|
||||||
for (i = 0; sonames[i]; i++)
|
for (i = 0; sonames_glx[i]; i++)
|
||||||
{
|
{
|
||||||
_glfw.glx.handle = dlopen(sonames[i], RTLD_LAZY | RTLD_GLOBAL);
|
_glfw.glx.handle = dlopen(sonames_glx[i], RTLD_LAZY | RTLD_GLOBAL);
|
||||||
if (_glfw.glx.handle)
|
if (_glfw.glx.handle)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -449,7 +479,8 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
|||||||
if (ctxconfig->share)
|
if (ctxconfig->share)
|
||||||
share = ctxconfig->share->context.glx.handle;
|
share = ctxconfig->share->context.glx.handle;
|
||||||
|
|
||||||
if (!chooseGLXFBConfig(fbconfig, &native))
|
if (!chooseGLXFBConfig(fbconfig, &native, window->transparent))
|
||||||
|
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||||
"GLX: Failed to find a suitable GLXFBConfig");
|
"GLX: Failed to find a suitable GLXFBConfig");
|
||||||
@ -629,14 +660,15 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
|||||||
|
|
||||||
// Returns the Visual and depth of the chosen GLXFBConfig
|
// 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,
|
const _GLFWfbconfig* fbconfig,
|
||||||
Visual** visual, int* depth)
|
Visual** visual, int* depth)
|
||||||
{
|
{
|
||||||
GLXFBConfig native;
|
GLXFBConfig native;
|
||||||
XVisualInfo* result;
|
XVisualInfo* result;
|
||||||
|
|
||||||
if (!chooseGLXFBConfig(fbconfig, &native))
|
if (!chooseGLXFBConfig(fbconfig, &native, wndconfig->transparent))
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||||
"GLX: Failed to find a suitable GLXFBConfig");
|
"GLX: Failed to find a suitable GLXFBConfig");
|
||||||
@ -652,7 +684,7 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig,
|
|||||||
}
|
}
|
||||||
|
|
||||||
*visual = result->visual;
|
*visual = result->visual;
|
||||||
*depth = result->depth;
|
*depth = result->depth;
|
||||||
|
|
||||||
XFree(result);
|
XFree(result);
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
|
@ -72,6 +72,7 @@ typedef struct __GLXFBConfig* GLXFBConfig;
|
|||||||
typedef struct __GLXcontext* GLXContext;
|
typedef struct __GLXcontext* GLXContext;
|
||||||
typedef void (*__GLXextproc)(void);
|
typedef void (*__GLXextproc)(void);
|
||||||
|
|
||||||
|
// libGL.so function pointer typedefs
|
||||||
typedef int (*PFNGLXGETFBCONFIGATTRIBPROC)(Display*,GLXFBConfig,int,int*);
|
typedef int (*PFNGLXGETFBCONFIGATTRIBPROC)(Display*,GLXFBConfig,int,int*);
|
||||||
typedef const char* (*PFNGLXGETCLIENTSTRINGPROC)(Display*,int);
|
typedef const char* (*PFNGLXGETCLIENTSTRINGPROC)(Display*,int);
|
||||||
typedef Bool (*PFNGLXQUERYEXTENSIONPROC)(Display*,int*,int*);
|
typedef Bool (*PFNGLXQUERYEXTENSIONPROC)(Display*,int*,int*);
|
||||||
@ -92,7 +93,6 @@ typedef int (*PFNGLXSWAPINTERVALMESAPROC)(int);
|
|||||||
typedef int (*PFNGLXSWAPINTERVALSGIPROC)(int);
|
typedef int (*PFNGLXSWAPINTERVALSGIPROC)(int);
|
||||||
typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display*,GLXFBConfig,GLXContext,Bool,const int*);
|
typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display*,GLXFBConfig,GLXContext,Bool,const int*);
|
||||||
|
|
||||||
// libGL.so function pointer typedefs
|
|
||||||
#define glXGetFBConfigs _glfw.glx.GetFBConfigs
|
#define glXGetFBConfigs _glfw.glx.GetFBConfigs
|
||||||
#define glXGetFBConfigAttrib _glfw.glx.GetFBConfigAttrib
|
#define glXGetFBConfigAttrib _glfw.glx.GetFBConfigAttrib
|
||||||
#define glXGetClientString _glfw.glx.GetClientString
|
#define glXGetClientString _glfw.glx.GetClientString
|
||||||
@ -168,14 +168,14 @@ typedef struct _GLFWlibraryGLX
|
|||||||
|
|
||||||
} _GLFWlibraryGLX;
|
} _GLFWlibraryGLX;
|
||||||
|
|
||||||
|
|
||||||
GLFWbool _glfwInitGLX(void);
|
GLFWbool _glfwInitGLX(void);
|
||||||
void _glfwTerminateGLX(void);
|
void _glfwTerminateGLX(void);
|
||||||
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||||
const _GLFWctxconfig* ctxconfig,
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig);
|
const _GLFWfbconfig* fbconfig);
|
||||||
void _glfwDestroyContextGLX(_GLFWwindow* window);
|
void _glfwDestroyContextGLX(_GLFWwindow* window);
|
||||||
GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig,
|
GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig,
|
const _GLFWfbconfig* fbconfig,
|
||||||
Visual** visual, int* depth);
|
Visual** visual, int* depth);
|
||||||
|
|
||||||
|
@ -299,6 +299,7 @@ struct _GLFWwndconfig
|
|||||||
GLFWbool resizable;
|
GLFWbool resizable;
|
||||||
GLFWbool visible;
|
GLFWbool visible;
|
||||||
GLFWbool decorated;
|
GLFWbool decorated;
|
||||||
|
GLFWbool transparent;
|
||||||
GLFWbool focused;
|
GLFWbool focused;
|
||||||
GLFWbool autoIconify;
|
GLFWbool autoIconify;
|
||||||
GLFWbool floating;
|
GLFWbool floating;
|
||||||
@ -404,6 +405,7 @@ struct _GLFWwindow
|
|||||||
// Window settings and state
|
// Window settings and state
|
||||||
GLFWbool resizable;
|
GLFWbool resizable;
|
||||||
GLFWbool decorated;
|
GLFWbool decorated;
|
||||||
|
GLFWbool transparent;
|
||||||
GLFWbool autoIconify;
|
GLFWbool autoIconify;
|
||||||
GLFWbool floating;
|
GLFWbool floating;
|
||||||
GLFWbool shouldClose;
|
GLFWbool shouldClose;
|
||||||
|
@ -83,6 +83,20 @@ static int choosePixelFormat(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
const int n = i + 1;
|
const int n = i + 1;
|
||||||
_GLFWfbconfig* u = usableConfigs + usableCount;
|
_GLFWfbconfig* u = usableConfigs + usableCount;
|
||||||
|
PIXELFORMATDESCRIPTOR pfd;
|
||||||
|
|
||||||
|
if (window->transparent) {
|
||||||
|
if (!DescribePixelFormat(window->context.wgl.dc,
|
||||||
|
n,
|
||||||
|
sizeof(PIXELFORMATDESCRIPTOR),
|
||||||
|
&pfd))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(pfd.dwFlags & PFD_SUPPORT_COMPOSITION))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (_glfw.wgl.ARB_pixel_format)
|
if (_glfw.wgl.ARB_pixel_format)
|
||||||
{
|
{
|
||||||
@ -152,11 +166,9 @@ static int choosePixelFormat(_GLFWwindow* window,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PIXELFORMATDESCRIPTOR pfd;
|
|
||||||
|
|
||||||
// Get pixel format attributes through legacy PFDs
|
// Get pixel format attributes through legacy PFDs
|
||||||
|
|
||||||
if (!DescribePixelFormat(window->context.wgl.dc,
|
if (!window->transparent && !DescribePixelFormat(window->context.wgl.dc,
|
||||||
n,
|
n,
|
||||||
sizeof(PIXELFORMATDESCRIPTOR),
|
sizeof(PIXELFORMATDESCRIPTOR),
|
||||||
&pfd))
|
&pfd))
|
||||||
@ -205,6 +217,15 @@ static int choosePixelFormat(_GLFWwindow* window,
|
|||||||
u->alphaMask = 1;
|
u->alphaMask = 1;
|
||||||
usableCount++;
|
usableCount++;
|
||||||
}
|
}
|
||||||
|
// Reiterate the selection loop without looking for transparency supporting
|
||||||
|
// formats if no matching pixelformat for a transparent window were found.
|
||||||
|
if (window->transparent && !usableCount) {
|
||||||
|
window->transparent = GLFW_FALSE;
|
||||||
|
free(usableConfigs);
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: No pixel format found for transparent window. Ignoring transparency.");
|
||||||
|
return choosePixelFormat(window, desired, result);
|
||||||
|
}
|
||||||
|
|
||||||
if (!usableCount)
|
if (!usableCount)
|
||||||
{
|
{
|
||||||
@ -486,6 +507,101 @@ void _glfwTerminateWGL(void)
|
|||||||
attribs[index++] = v; \
|
attribs[index++] = v; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reliably check windows version as done in VersionHelpers.h
|
||||||
|
// needed for transparent window
|
||||||
|
static inline GLFWbool
|
||||||
|
isWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
|
||||||
|
{
|
||||||
|
OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0,{ 0 }, 0, 0 };
|
||||||
|
DWORDLONG const dwlConditionMask = VerSetConditionMask(
|
||||||
|
VerSetConditionMask(
|
||||||
|
VerSetConditionMask(
|
||||||
|
0, VER_MAJORVERSION, VER_GREATER_EQUAL),
|
||||||
|
VER_MINORVERSION, VER_GREATER_EQUAL),
|
||||||
|
VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||||
|
|
||||||
|
osvi.dwMajorVersion = wMajorVersion;
|
||||||
|
osvi.dwMinorVersion = wMinorVersion;
|
||||||
|
osvi.wServicePackMajor = wServicePackMajor;
|
||||||
|
|
||||||
|
return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLFWbool isWindows8OrGreater()
|
||||||
|
{
|
||||||
|
GLFWbool isWin8OrGreater = isWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0) ? GLFW_TRUE: GLFW_FALSE;
|
||||||
|
return isWin8OrGreater;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLFWbool setupTransparentWindow(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
if (!isCompositionEnabled) {
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: Composition needed for transparent window is disabled");
|
||||||
|
}
|
||||||
|
if (!DwmEnableBlurBehindWindow) {
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: Unable to load DwmEnableBlurBehindWindow required for transparent window");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
HWND handle = window->win32.handle;
|
||||||
|
|
||||||
|
DWM_BLURBEHIND bb = { 0 };
|
||||||
|
bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
|
||||||
|
bb.hRgnBlur = CreateRectRgn(0, 0, -1, -1); // makes the window transparent
|
||||||
|
bb.fEnable = TRUE;
|
||||||
|
hr = DwmEnableBlurBehindWindow(handle, &bb);
|
||||||
|
|
||||||
|
if (!SUCCEEDED(hr)) {
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: Failed to enable blur behind window required for transparent window");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decorated windows on Windows 8+ don't repaint the transparent background
|
||||||
|
// leaving a trail behind animations.
|
||||||
|
// Hack: making the window layered with a transparency color key seems to fix this.
|
||||||
|
// Normally, when specifying a transparency color key to be used when composing
|
||||||
|
// the layered window, all pixels painted by the window in this color will be transparent.
|
||||||
|
// That doesn't seem to be the case anymore on Windows 8+, at least when used with
|
||||||
|
// DwmEnableBlurBehindWindow + negative region.
|
||||||
|
if (window->decorated && isWindows8OrGreater())
|
||||||
|
{
|
||||||
|
long style = GetWindowLongPtrW(handle, GWL_EXSTYLE);
|
||||||
|
if (!style) {
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: Failed to retrieve extended styles. GetLastError: %d",
|
||||||
|
GetLastError());
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
style |= WS_EX_LAYERED;
|
||||||
|
if (!SetWindowLongPtrW(handle, GWL_EXSTYLE, style))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: Failed to add layered style. GetLastError: %d",
|
||||||
|
GetLastError());
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
if (!SetLayeredWindowAttributes(handle,
|
||||||
|
// Using a color key not equal to black to fix the trailing issue.
|
||||||
|
// When set to black, something is making the hit test not resize with the
|
||||||
|
// window frame.
|
||||||
|
RGB(0, 193, 48),
|
||||||
|
255,
|
||||||
|
LWA_COLORKEY))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: Failed to set layered window. GetLastError: %d",
|
||||||
|
GetLastError());
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
// Create the OpenGL or OpenGL ES context
|
// Create the OpenGL or OpenGL ES context
|
||||||
//
|
//
|
||||||
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||||
@ -666,8 +782,54 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||||||
ctxconfig->major,
|
ctxconfig->major,
|
||||||
ctxconfig->minor);
|
ctxconfig->minor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (error == (0xc0070000 | ERROR_INVALID_PROFILE_ARB))
|
else if (error == (0xc0070000 | ERROR_INVALID_PROFILE_ARB)) {
|
||||||
|
// TODO: _glfwInputError
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->transparent)
|
||||||
|
{
|
||||||
|
if (!setupTransparentWindow(window))
|
||||||
|
window->transparent = GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef setWGLattrib
|
||||||
|
|
||||||
|
// Destroy the OpenGL context
|
||||||
|
//
|
||||||
|
void _glfwDestroyContextWGL(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
if (window->context.wgl.handle)
|
||||||
|
{
|
||||||
|
wglDeleteContext(window->context.wgl.handle);
|
||||||
|
window->context.wgl.handle = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Analyzes the specified context for possible recreation
|
||||||
|
//
|
||||||
|
int _glfwAnalyzeContextWGL(_GLFWwindow* window,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
|
const _GLFWfbconfig* fbconfig)
|
||||||
|
{
|
||||||
|
GLFWbool required = GLFW_FALSE;
|
||||||
|
|
||||||
|
if (_glfw.wgl.extensionsLoaded)
|
||||||
|
return _GLFW_RECREATION_NOT_NEEDED;
|
||||||
|
|
||||||
|
_glfwPlatformMakeContextCurrent(window);
|
||||||
|
loadExtensions();
|
||||||
|
|
||||||
|
if (ctxconfig->api == GLFW_OPENGL_API)
|
||||||
|
{
|
||||||
|
if (ctxconfig->forward)
|
||||||
|
{
|
||||||
|
if (!_glfw.wgl.ARB_create_context)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||||
"WGL: Driver does not support the requested OpenGL profile");
|
"WGL: Driver does not support the requested OpenGL profile");
|
||||||
|
@ -128,6 +128,8 @@ static GLFWbool loadLibraries(void)
|
|||||||
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled");
|
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled");
|
||||||
_glfw.win32.dwmapi.Flush = (PFN_DwmFlush)
|
_glfw.win32.dwmapi.Flush = (PFN_DwmFlush)
|
||||||
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmFlush");
|
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmFlush");
|
||||||
|
_glfw.win32.dwmapi.EnableBlurBehindWindow = (PFN_DwmEnableBlurBehindWindow)
|
||||||
|
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow");
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfw.win32.shcore.instance = LoadLibraryA("shcore.dll");
|
_glfw.win32.shcore.instance = LoadLibraryA("shcore.dll");
|
||||||
|
@ -153,7 +153,22 @@ typedef enum PROCESS_DPI_AWARENESS
|
|||||||
|
|
||||||
// HACK: Define macros that some dinput.h variants don't
|
// HACK: Define macros that some dinput.h variants don't
|
||||||
#ifndef DIDFT_OPTIONAL
|
#ifndef DIDFT_OPTIONAL
|
||||||
#define DIDFT_OPTIONAL 0x80000000
|
#define DIDFT_OPTIONAL 0x80000000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(_DWMAPI_H_)
|
||||||
|
// Blur behind data structures
|
||||||
|
#define DWM_BB_ENABLE 0x00000001 // fEnable has been specified
|
||||||
|
#define DWM_BB_BLURREGION 0x00000002 // hRgnBlur has been specified
|
||||||
|
#define DWM_BB_TRANSITIONONMAXIMIZED 0x00000004 // fTransitionOnMaximized has been specified
|
||||||
|
|
||||||
|
typedef struct _DWM_BLURBEHIND
|
||||||
|
{
|
||||||
|
DWORD dwFlags;
|
||||||
|
BOOL fEnable;
|
||||||
|
HRGN hRgnBlur;
|
||||||
|
BOOL fTransitionOnMaximized;
|
||||||
|
} DWM_BLURBEHIND, *PDWM_BLURBEHIND;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// winmm.dll function pointer typedefs
|
// winmm.dll function pointer typedefs
|
||||||
@ -179,9 +194,13 @@ typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,PCHANGEF
|
|||||||
// dwmapi.dll function pointer typedefs
|
// dwmapi.dll function pointer typedefs
|
||||||
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
|
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
|
||||||
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
|
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
|
||||||
|
|
||||||
#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
|
#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
|
||||||
#define DwmFlush _glfw.win32.dwmapi.Flush
|
#define DwmFlush _glfw.win32.dwmapi.Flush
|
||||||
|
|
||||||
|
typedef HRESULT(WINAPI * PFN_DwmEnableBlurBehindWindow)(HWND, const DWM_BLURBEHIND*);
|
||||||
|
#define DwmEnableBlurBehindWindow _glfw.win32.dwmapi.EnableBlurBehindWindow
|
||||||
|
|
||||||
// shcore.dll function pointer typedefs
|
// shcore.dll function pointer typedefs
|
||||||
typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
|
typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
|
||||||
#define _glfw_SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness
|
#define _glfw_SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness
|
||||||
@ -286,6 +305,7 @@ typedef struct _GLFWlibraryWin32
|
|||||||
HINSTANCE instance;
|
HINSTANCE instance;
|
||||||
PFN_DwmIsCompositionEnabled IsCompositionEnabled;
|
PFN_DwmIsCompositionEnabled IsCompositionEnabled;
|
||||||
PFN_DwmFlush Flush;
|
PFN_DwmFlush Flush;
|
||||||
|
PFN_DwmEnableBlurBehindWindow EnableBlurBehindWindow;
|
||||||
} dwmapi;
|
} dwmapi;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -182,6 +182,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
|||||||
window->monitor = (_GLFWmonitor*) monitor;
|
window->monitor = (_GLFWmonitor*) monitor;
|
||||||
window->resizable = wndconfig.resizable;
|
window->resizable = wndconfig.resizable;
|
||||||
window->decorated = wndconfig.decorated;
|
window->decorated = wndconfig.decorated;
|
||||||
|
window->transparent = wndconfig.transparent;
|
||||||
window->autoIconify = wndconfig.autoIconify;
|
window->autoIconify = wndconfig.autoIconify;
|
||||||
window->floating = wndconfig.floating;
|
window->floating = wndconfig.floating;
|
||||||
window->transparent = wndconfig.alphaMask;
|
window->transparent = wndconfig.alphaMask;
|
||||||
@ -252,6 +253,7 @@ void glfwDefaultWindowHints(void)
|
|||||||
_glfw.hints.window.resizable = GLFW_TRUE;
|
_glfw.hints.window.resizable = GLFW_TRUE;
|
||||||
_glfw.hints.window.visible = GLFW_TRUE;
|
_glfw.hints.window.visible = GLFW_TRUE;
|
||||||
_glfw.hints.window.decorated = GLFW_TRUE;
|
_glfw.hints.window.decorated = GLFW_TRUE;
|
||||||
|
_glfw.hints.window.transparent = GLFW_FALSE;
|
||||||
_glfw.hints.window.focused = GLFW_TRUE;
|
_glfw.hints.window.focused = GLFW_TRUE;
|
||||||
_glfw.hints.window.autoIconify = GLFW_TRUE;
|
_glfw.hints.window.autoIconify = GLFW_TRUE;
|
||||||
|
|
||||||
@ -735,6 +737,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
|
|||||||
return window->resizable;
|
return window->resizable;
|
||||||
case GLFW_DECORATED:
|
case GLFW_DECORATED:
|
||||||
return window->decorated;
|
return window->decorated;
|
||||||
|
case GLFW_TRANSPARENT:
|
||||||
|
return window->transparent;
|
||||||
case GLFW_FLOATING:
|
case GLFW_FLOATING:
|
||||||
return window->floating;
|
return window->floating;
|
||||||
case GLFW_AUTO_ICONIFY:
|
case GLFW_AUTO_ICONIFY:
|
||||||
|
194
src/x11_init.c
194
src/x11_init.c
@ -480,7 +480,7 @@ static GLFWbool initExtensions(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
_glfw.x11.xi.handle = dlopen("libXi.so.6", RTLD_LAZY | RTLD_GLOBAL);
|
_glfw.x11.xi.handle = dlopen("libXi.so.6", RTLD_LAZY | RTLD_GLOBAL);
|
||||||
if (_glfw.x11.xi.handle)
|
if (_glfw.x11.xi.handle)
|
||||||
{
|
{
|
||||||
_glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion)
|
_glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion)
|
||||||
dlsym(_glfw.x11.xi.handle, "XIQueryVersion");
|
dlsym(_glfw.x11.xi.handle, "XIQueryVersion");
|
||||||
@ -505,66 +505,72 @@ static GLFWbool initExtensions(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfw.x11.randr.handle = dlopen("libXrandr.so.2", RTLD_LAZY | RTLD_GLOBAL);
|
// Check for RandR extension
|
||||||
if (_glfw.x11.randr.handle)
|
if (XRRQueryExtension(_glfw.x11.display,
|
||||||
{
|
&_glfw.x11.randr.eventBase,
|
||||||
_glfw.x11.randr.AllocGamma = (PFN_XRRAllocGamma)
|
&_glfw.x11.randr.errorBase)) {
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRAllocGamma");
|
|
||||||
_glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRFreeGamma");
|
|
||||||
_glfw.x11.randr.FreeCrtcInfo = (PFN_XRRFreeCrtcInfo)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRFreeCrtcInfo");
|
|
||||||
_glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRFreeGamma");
|
|
||||||
_glfw.x11.randr.FreeOutputInfo = (PFN_XRRFreeOutputInfo)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRFreeOutputInfo");
|
|
||||||
_glfw.x11.randr.FreeScreenResources = (PFN_XRRFreeScreenResources)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRFreeScreenResources");
|
|
||||||
_glfw.x11.randr.GetCrtcGamma = (PFN_XRRGetCrtcGamma)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGamma");
|
|
||||||
_glfw.x11.randr.GetCrtcGammaSize = (PFN_XRRGetCrtcGammaSize)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGammaSize");
|
|
||||||
_glfw.x11.randr.GetCrtcInfo = (PFN_XRRGetCrtcInfo)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRGetCrtcInfo");
|
|
||||||
_glfw.x11.randr.GetOutputInfo = (PFN_XRRGetOutputInfo)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRGetOutputInfo");
|
|
||||||
_glfw.x11.randr.GetOutputPrimary = (PFN_XRRGetOutputPrimary)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRGetOutputPrimary");
|
|
||||||
_glfw.x11.randr.GetScreenResourcesCurrent = (PFN_XRRGetScreenResourcesCurrent)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRGetScreenResourcesCurrent");
|
|
||||||
_glfw.x11.randr.QueryExtension = (PFN_XRRQueryExtension)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRQueryExtension");
|
|
||||||
_glfw.x11.randr.QueryVersion = (PFN_XRRQueryVersion)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRQueryVersion");
|
|
||||||
_glfw.x11.randr.SelectInput = (PFN_XRRSelectInput)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRSelectInput");
|
|
||||||
_glfw.x11.randr.SetCrtcConfig = (PFN_XRRSetCrtcConfig)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRSetCrtcConfig");
|
|
||||||
_glfw.x11.randr.SetCrtcGamma = (PFN_XRRSetCrtcGamma)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRSetCrtcGamma");
|
|
||||||
_glfw.x11.randr.UpdateConfiguration = (PFN_XRRUpdateConfiguration)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRUpdateConfiguration");
|
|
||||||
|
|
||||||
if (XRRQueryExtension(_glfw.x11.display,
|
_glfw.x11.randr.handle = dlopen("libXrandr.so.2", RTLD_LAZY | RTLD_GLOBAL);
|
||||||
&_glfw.x11.randr.eventBase,
|
|
||||||
&_glfw.x11.randr.errorBase))
|
if (_glfw.x11.randr.handle)
|
||||||
{
|
{
|
||||||
if (XRRQueryVersion(_glfw.x11.display,
|
_glfw.x11.randr.AllocGamma = (PFN_XRRAllocGamma)
|
||||||
&_glfw.x11.randr.major,
|
dlsym(_glfw.x11.randr.handle, "XRRAllocGamma");
|
||||||
&_glfw.x11.randr.minor))
|
_glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma)
|
||||||
{
|
dlsym(_glfw.x11.randr.handle, "XRRFreeGamma");
|
||||||
// The GLFW RandR path requires at least version 1.3
|
_glfw.x11.randr.FreeCrtcInfo = (PFN_XRRFreeCrtcInfo)
|
||||||
if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3)
|
dlsym(_glfw.x11.randr.handle, "XRRFreeCrtcInfo");
|
||||||
_glfw.x11.randr.available = GLFW_TRUE;
|
_glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma)
|
||||||
}
|
dlsym(_glfw.x11.randr.handle, "XRRFreeGamma");
|
||||||
else
|
_glfw.x11.randr.FreeOutputInfo = (PFN_XRRFreeOutputInfo)
|
||||||
{
|
dlsym(_glfw.x11.randr.handle, "XRRFreeOutputInfo");
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfw.x11.randr.FreeScreenResources = (PFN_XRRFreeScreenResources)
|
||||||
"X11: Failed to query RandR version");
|
dlsym(_glfw.x11.randr.handle, "XRRFreeScreenResources");
|
||||||
}
|
_glfw.x11.randr.GetCrtcGamma = (PFN_XRRGetCrtcGamma)
|
||||||
}
|
dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGamma");
|
||||||
}
|
_glfw.x11.randr.GetCrtcGammaSize = (PFN_XRRGetCrtcGammaSize)
|
||||||
|
dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGammaSize");
|
||||||
|
_glfw.x11.randr.GetCrtcInfo = (PFN_XRRGetCrtcInfo)
|
||||||
|
dlsym(_glfw.x11.randr.handle, "XRRGetCrtcInfo");
|
||||||
|
_glfw.x11.randr.GetOutputInfo = (PFN_XRRGetOutputInfo)
|
||||||
|
dlsym(_glfw.x11.randr.handle, "XRRGetOutputInfo");
|
||||||
|
_glfw.x11.randr.GetOutputPrimary = (PFN_XRRGetOutputPrimary)
|
||||||
|
dlsym(_glfw.x11.randr.handle, "XRRGetOutputPrimary");
|
||||||
|
_glfw.x11.randr.GetScreenResourcesCurrent = (PFN_XRRGetScreenResourcesCurrent)
|
||||||
|
dlsym(_glfw.x11.randr.handle, "XRRGetScreenResourcesCurrent");
|
||||||
|
_glfw.x11.randr.QueryExtension = (PFN_XRRQueryExtension)
|
||||||
|
dlsym(_glfw.x11.randr.handle, "XRRQueryExtension");
|
||||||
|
_glfw.x11.randr.QueryVersion = (PFN_XRRQueryVersion)
|
||||||
|
dlsym(_glfw.x11.randr.handle, "XRRQueryVersion");
|
||||||
|
_glfw.x11.randr.SelectInput = (PFN_XRRSelectInput)
|
||||||
|
dlsym(_glfw.x11.randr.handle, "XRRSelectInput");
|
||||||
|
_glfw.x11.randr.SetCrtcConfig = (PFN_XRRSetCrtcConfig)
|
||||||
|
dlsym(_glfw.x11.randr.handle, "XRRSetCrtcConfig");
|
||||||
|
_glfw.x11.randr.SetCrtcGamma = (PFN_XRRSetCrtcGamma)
|
||||||
|
dlsym(_glfw.x11.randr.handle, "XRRSetCrtcGamma");
|
||||||
|
_glfw.x11.randr.UpdateConfiguration = (PFN_XRRUpdateConfiguration)
|
||||||
|
dlsym(_glfw.x11.randr.handle, "XRRUpdateConfiguration");
|
||||||
|
|
||||||
|
if (XRRQueryExtension(_glfw.x11.display,
|
||||||
|
&_glfw.x11.randr.eventBase,
|
||||||
|
&_glfw.x11.randr.errorBase))
|
||||||
|
{
|
||||||
|
if (XRRQueryVersion(_glfw.x11.display,
|
||||||
|
&_glfw.x11.randr.major,
|
||||||
|
&_glfw.x11.randr.minor))
|
||||||
|
{
|
||||||
|
// The GLFW RandR path requires at least version 1.3
|
||||||
|
if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3)
|
||||||
|
_glfw.x11.randr.available = GLFW_TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"X11: Failed to query RandR version");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (_glfw.x11.randr.available)
|
if (_glfw.x11.randr.available)
|
||||||
{
|
{
|
||||||
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display,
|
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display,
|
||||||
@ -719,6 +725,76 @@ static GLFWbool initExtensions(void)
|
|||||||
_glfw.x11.MOTIF_WM_HINTS =
|
_glfw.x11.MOTIF_WM_HINTS =
|
||||||
XInternAtom(_glfw.x11.display, "_MOTIF_WM_HINTS", False);
|
XInternAtom(_glfw.x11.display, "_MOTIF_WM_HINTS", False);
|
||||||
|
|
||||||
|
|
||||||
|
const char* sonames_xrender[] =
|
||||||
|
{
|
||||||
|
#if defined(__CYGWIN__)
|
||||||
|
"libXrender-1.so",
|
||||||
|
#else
|
||||||
|
"libXrender.so.1",
|
||||||
|
"libXrender.so",
|
||||||
|
#endif
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
// Find or create window manager atoms
|
||||||
|
_glfw.x11.WM_PROTOCOLS = XInternAtom(_glfw.x11.display,
|
||||||
|
"WM_PROTOCOLS",
|
||||||
|
False);
|
||||||
|
_glfw.x11.WM_STATE = XInternAtom(_glfw.x11.display, "WM_STATE", False);
|
||||||
|
_glfw.x11.WM_DELETE_WINDOW = XInternAtom(_glfw.x11.display,
|
||||||
|
"WM_DELETE_WINDOW",
|
||||||
|
False);
|
||||||
|
_glfw.x11.MOTIF_WM_HINTS = XInternAtom(_glfw.x11.display,
|
||||||
|
"_MOTIF_WM_HINTS",
|
||||||
|
False);
|
||||||
|
|
||||||
|
#if defined(_GLFW_HAS_XF86VM)
|
||||||
|
// Check for XF86VidMode extension
|
||||||
|
_glfw.x11.vidmode.available =
|
||||||
|
XF86VidModeQueryExtension(_glfw.x11.display,
|
||||||
|
&_glfw.x11.vidmode.eventBase,
|
||||||
|
&_glfw.x11.vidmode.errorBase);
|
||||||
|
#endif /*_GLFW_HAS_XF86VM*/
|
||||||
|
|
||||||
|
// Xrender support is optional and not a requirement for GLX/EGL
|
||||||
|
// to work. Xrender is required for selecting a FB config that
|
||||||
|
// supports a picture format with an alpha mask, which in turn
|
||||||
|
// is required for transparent windows. I Xrender is not supported
|
||||||
|
// the GLFW_TRANSPARENT window hint is ignored.
|
||||||
|
int i;
|
||||||
|
for (i = 0; sonames_xrender[i]; i++)
|
||||||
|
{
|
||||||
|
_glfw.xrender.handle = dlopen(sonames_xrender[i], RTLD_LAZY | RTLD_GLOBAL);
|
||||||
|
if (_glfw.xrender.handle)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_glfw.xrender.errorBase = 0;
|
||||||
|
_glfw.xrender.eventBase = 0;
|
||||||
|
_glfw.xrender.major = 0;
|
||||||
|
_glfw.xrender.minor = 0;
|
||||||
|
if (_glfw.xrender.handle) do {
|
||||||
|
int errorBase, eventBase, major, minor;
|
||||||
|
_glfw.xrender.QueryExtension =
|
||||||
|
dlsym(_glfw.xrender.handle, "XRenderQueryExtension");
|
||||||
|
_glfw.xrender.QueryVersion =
|
||||||
|
dlsym(_glfw.xrender.handle, "XRenderQueryVersion");
|
||||||
|
_glfw.xrender.FindVisualFormat =
|
||||||
|
dlsym(_glfw.xrender.handle, "XRenderFindVisualFormat");
|
||||||
|
|
||||||
|
if ( !XRenderQueryExtension(_glfw.x11.display, &errorBase, &eventBase)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ( !XRenderQueryVersion(_glfw.x11.display, &major, &minor)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.xrender.errorBase = errorBase;
|
||||||
|
_glfw.xrender.eventBase = eventBase;
|
||||||
|
_glfw.xrender.major = major;
|
||||||
|
_glfw.xrender.minor = minor;
|
||||||
|
} while(0);
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,10 +162,20 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(Vk
|
|||||||
#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.x11.display)
|
#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.x11.display)
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 x11
|
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 x11
|
||||||
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11
|
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11 ; _GLFWlibraryXrender xrender
|
||||||
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 x11
|
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 x11
|
||||||
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorX11 x11
|
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorX11 x11
|
||||||
|
|
||||||
|
// libXrender.so function pointer typedefs
|
||||||
|
typedef Bool (*PFNXRENDERQUERYEXTENSIONPROC)(Display*,int*,int*);
|
||||||
|
typedef Status (*PFNXRENDERQUERYVERSIONPROC)(Display*dpy,int*,int*);
|
||||||
|
typedef XRenderPictFormat* (*PFNXRENDERFINDVISUALFORMATPROC)(Display*,Visual const *);
|
||||||
|
|
||||||
|
// libXrender.so function identifier overlays
|
||||||
|
#define XRenderQueryExtension _glfw.xrender.QueryExtension
|
||||||
|
#define XRenderQueryVersion _glfw.xrender.QueryVersion
|
||||||
|
#define XRenderFindVisualFormat _glfw.xrender.FindVisualFormat
|
||||||
|
|
||||||
|
|
||||||
// X11-specific per-window data
|
// X11-specific per-window data
|
||||||
//
|
//
|
||||||
@ -374,6 +384,22 @@ typedef struct _GLFWlibraryX11
|
|||||||
|
|
||||||
} _GLFWlibraryX11;
|
} _GLFWlibraryX11;
|
||||||
|
|
||||||
|
// Xrender-specific global data
|
||||||
|
typedef struct _GLFWlibraryXrender
|
||||||
|
{
|
||||||
|
int major, minor;
|
||||||
|
int eventBase;
|
||||||
|
int errorBase;
|
||||||
|
|
||||||
|
// dlopen handle for libGL.so.1
|
||||||
|
void* handle;
|
||||||
|
|
||||||
|
// Xrender functions (subset required for transparent window)
|
||||||
|
PFNXRENDERQUERYEXTENSIONPROC QueryExtension;
|
||||||
|
PFNXRENDERQUERYVERSIONPROC QueryVersion;
|
||||||
|
PFNXRENDERFINDVISUALFORMATPROC FindVisualFormat;
|
||||||
|
} _GLFWlibraryXrender;
|
||||||
|
|
||||||
// X11-specific per-monitor data
|
// X11-specific per-monitor data
|
||||||
//
|
//
|
||||||
typedef struct _GLFWmonitorX11
|
typedef struct _GLFWmonitorX11
|
||||||
|
@ -1828,8 +1828,14 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||||||
if (ctxconfig->client == GLFW_NO_API ||
|
if (ctxconfig->client == GLFW_NO_API ||
|
||||||
ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
|
ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
|
||||||
{
|
{
|
||||||
visual = DefaultVisual(_glfw.x11.display, _glfw.x11.screen);
|
|
||||||
depth = DefaultDepth(_glfw.x11.display, _glfw.x11.screen);
|
#if defined(_GLFW_GLX)
|
||||||
|
if (!_glfwChooseVisualGLX(wndconfig, ctxconfig, fbconfig, &visual, &depth))
|
||||||
|
return GLFW_FALSE;
|
||||||
|
#elif defined(_GLFW_EGL)
|
||||||
|
if (!_glfwChooseVisualEGL(wndconfig, ctxconfig, fbconfig, &visual, &depth))
|
||||||
|
return GLFW_FALSE;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!createNativeWindow(window, wndconfig, visual, depth))
|
if (!createNativeWindow(window, wndconfig, visual, depth))
|
||||||
|
Loading…
Reference in New Issue
Block a user