mirror of
https://github.com/glfw/glfw.git
synced 2025-10-05 06:06:36 +00:00
Merge 9a2890d611
into f4fb25b63d
This commit is contained in:
commit
3b0ae359ba
2
.gitignore
vendored
2
.gitignore
vendored
@ -14,6 +14,8 @@ Release
|
||||
MinSizeRel
|
||||
RelWithDebInfo
|
||||
*.xcodeproj
|
||||
.vs
|
||||
*.VC.opendb
|
||||
|
||||
# CMake files
|
||||
Makefile
|
||||
|
@ -228,6 +228,10 @@ newly created full screen windows. Possible values are `GLFW_TRUE` and
|
||||
|
||||
@subsubsection window_hints_fb Framebuffer related hints
|
||||
|
||||
@anchor GLFW_TRANSPARENT_hint
|
||||
__GLFW_TRANSPARENT__ specifies whether the framebuffer will support transparency
|
||||
in the background. Possible values are `GLFW_TRUE` and `GLFW_FALSE`.
|
||||
|
||||
@anchor GLFW_RED_BITS
|
||||
@anchor GLFW_GREEN_BITS
|
||||
@anchor GLFW_BLUE_BITS
|
||||
|
@ -172,6 +172,7 @@ static GLfloat angle = 0.f;
|
||||
/* OpenGL draw function & timing */
|
||||
static void draw(void)
|
||||
{
|
||||
glClearColor(0., 0., 0., 0.);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glPushMatrix();
|
||||
@ -297,7 +298,6 @@ static void init(void)
|
||||
glEnable(GL_NORMALIZE);
|
||||
}
|
||||
|
||||
|
||||
/* program entry */
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@ -311,6 +311,9 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
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 );
|
||||
if (!window)
|
||||
|
@ -788,6 +788,7 @@ extern "C" {
|
||||
*/
|
||||
#define GLFW_CENTER_CURSOR 0x00020009
|
||||
|
||||
|
||||
/*! @brief Framebuffer bit depth hint.
|
||||
*
|
||||
* Framebuffer bit depth [hint](@ref GLFW_RED_BITS).
|
||||
@ -868,6 +869,11 @@ extern "C" {
|
||||
* Framebuffer double buffering [hint](@ref GLFW_DOUBLEBUFFER).
|
||||
*/
|
||||
#define GLFW_DOUBLEBUFFER 0x00021010
|
||||
/*! @brief Framebuffer transparency hint.
|
||||
*
|
||||
* Framebuffer transparency [hint](@ref GLFW_TRANSPARENT_hint).
|
||||
*/
|
||||
#define GLFW_TRANSPARENT 0x00021011
|
||||
/*! @brief Context client API hint and attribute.
|
||||
*
|
||||
* Context client API [hint](@ref GLFW_CLIENT_API_hint) and
|
||||
|
@ -413,7 +413,11 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
||||
|
||||
- (BOOL)isOpaque
|
||||
{
|
||||
return YES;
|
||||
// Set to NO even if transparent is not used;
|
||||
// The NSView/GLFWContentView does not need to be opaque anyway,
|
||||
// and to avoid keeping track of alphaMask inside the NSView we
|
||||
// just return NO here instead.
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)canBecomeKeyView
|
||||
@ -1081,6 +1085,12 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
if (wndconfig->ns.retina)
|
||||
[window->ns.view setWantsBestResolutionOpenGLSurface:YES];
|
||||
|
||||
if (_glfw.hints.framebuffer.transparent)
|
||||
{
|
||||
[window->ns.object setOpaque:NO];
|
||||
[window->ns.object setBackgroundColor:[NSColor clearColor]];
|
||||
}
|
||||
|
||||
[window->ns.object setContentView:window->ns.view];
|
||||
[window->ns.object makeFirstResponder:window->ns.view];
|
||||
[window->ns.object setTitle:[NSString stringWithUTF8String:wndconfig->title]];
|
||||
|
@ -93,6 +93,14 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
||||
_GLFWfbconfig* usableConfigs;
|
||||
const _GLFWfbconfig* closest;
|
||||
int i, nativeCount, usableCount;
|
||||
GLFWbool findTransparent = desired->transparent;
|
||||
|
||||
#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);
|
||||
if (!nativeCount)
|
||||
@ -107,6 +115,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
||||
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
|
||||
usableCount = 0;
|
||||
|
||||
selectionloop:
|
||||
for (i = 0; i < nativeCount; i++)
|
||||
{
|
||||
const EGLConfig n = nativeConfigs[i];
|
||||
@ -124,6 +133,28 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
||||
// Only consider EGLConfigs with associated Visuals
|
||||
if (!getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID))
|
||||
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
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
@ -159,6 +190,12 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
||||
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)
|
||||
@ -699,6 +736,7 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig,
|
||||
EGLint visualID = 0, count = 0;
|
||||
const long vimask = VisualScreenMask | VisualIDMask;
|
||||
|
||||
|
||||
if (!chooseEGLConfig(ctxconfig, fbconfig, &native))
|
||||
{
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
@ -766,4 +804,3 @@ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle)
|
||||
|
||||
return window->context.egl.surface;
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,11 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* res
|
||||
int i, nativeCount, usableCount;
|
||||
const char* vendor;
|
||||
GLFWbool trustWindowBit = GLFW_TRUE;
|
||||
GLFWbool findTransparent = desired->transparent;
|
||||
|
||||
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
|
||||
@ -64,6 +69,7 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* res
|
||||
|
||||
nativeConfigs =
|
||||
glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, &nativeCount);
|
||||
|
||||
if (!nativeConfigs || !nativeCount)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned");
|
||||
@ -73,6 +79,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 +96,29 @@ 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 +148,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)
|
||||
@ -683,4 +719,3 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
|
||||
|
||||
return window->context.glx.window;
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,7 @@ typedef struct __GLXFBConfig* GLXFBConfig;
|
||||
typedef struct __GLXcontext* GLXContext;
|
||||
typedef void (*__GLXextproc)(void);
|
||||
|
||||
// libGL.so function pointer typedefs
|
||||
typedef int (*PFNGLXGETFBCONFIGATTRIBPROC)(Display*,GLXFBConfig,int,int*);
|
||||
typedef const char* (*PFNGLXGETCLIENTSTRINGPROC)(Display*,int);
|
||||
typedef Bool (*PFNGLXQUERYEXTENSIONPROC)(Display*,int*,int*);
|
||||
@ -92,7 +93,6 @@ typedef int (*PFNGLXSWAPINTERVALMESAPROC)(int);
|
||||
typedef int (*PFNGLXSWAPINTERVALSGIPROC)(int);
|
||||
typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display*,GLXFBConfig,GLXContext,Bool,const int*);
|
||||
|
||||
// libGL.so function pointer typedefs
|
||||
#define glXGetFBConfigs _glfw.glx.GetFBConfigs
|
||||
#define glXGetFBConfigAttrib _glfw.glx.GetFBConfigAttrib
|
||||
#define glXGetClientString _glfw.glx.GetClientString
|
||||
@ -168,7 +168,6 @@ typedef struct _GLFWlibraryGLX
|
||||
|
||||
} _GLFWlibraryGLX;
|
||||
|
||||
|
||||
GLFWbool _glfwInitGLX(void);
|
||||
void _glfwTerminateGLX(void);
|
||||
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
|
@ -357,7 +357,8 @@ struct _GLFWfbconfig
|
||||
int auxBuffers;
|
||||
GLFWbool stereo;
|
||||
int samples;
|
||||
GLFWbool sRGB;
|
||||
GLFWbool sRGB;
|
||||
GLFWbool transparent;
|
||||
GLFWbool doublebuffer;
|
||||
uintptr_t handle;
|
||||
};
|
||||
|
@ -296,6 +296,12 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (fbconfig->transparent)
|
||||
{
|
||||
GLint opaque = 0;
|
||||
[window->context.nsgl.object setValues:&opaque forParameter:NSOpenGLCPSurfaceOpacity];
|
||||
}
|
||||
|
||||
[window->context.nsgl.object setView:window->ns.view];
|
||||
|
||||
window->context.makeCurrent = makeContextCurrentNSGL;
|
||||
|
@ -56,7 +56,8 @@ static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib
|
||||
//
|
||||
static int choosePixelFormat(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
const _GLFWfbconfig* fbconfig,
|
||||
const GLFWbool transparent)
|
||||
{
|
||||
_GLFWfbconfig* usableConfigs;
|
||||
const _GLFWfbconfig* closest;
|
||||
@ -83,6 +84,20 @@ static int choosePixelFormat(_GLFWwindow* window,
|
||||
{
|
||||
const int n = i + 1;
|
||||
_GLFWfbconfig* u = usableConfigs + usableCount;
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
|
||||
if (fbconfig->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)
|
||||
{
|
||||
@ -152,11 +167,9 @@ static int choosePixelFormat(_GLFWwindow* window,
|
||||
}
|
||||
else
|
||||
{
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
|
||||
// Get pixel format attributes through legacy PFDs
|
||||
|
||||
if (!DescribePixelFormat(window->context.wgl.dc,
|
||||
if (!fbconfig->transparent && !DescribePixelFormat(window->context.wgl.dc,
|
||||
n,
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
&pfd))
|
||||
@ -201,8 +214,20 @@ static int choosePixelFormat(_GLFWwindow* window,
|
||||
}
|
||||
|
||||
u->handle = n;
|
||||
|
||||
// always able to go transparent on win dwmapi
|
||||
u->transparent = GLFW_TRUE;
|
||||
|
||||
usableCount++;
|
||||
}
|
||||
// Reiterate the selection loop without looking for transparency supporting
|
||||
// formats if no matching pixelformat for a transparent window were found.
|
||||
if (fbconfig->transparent && !usableCount) {
|
||||
free(usableConfigs);
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"WGL: No pixel format found for transparent window. Ignoring transparency.");
|
||||
return choosePixelFormat(window, ctxconfig, fbconfig, GLFW_FALSE);
|
||||
}
|
||||
|
||||
if (!usableCount)
|
||||
{
|
||||
@ -484,6 +509,101 @@ void _glfwTerminateWGL(void)
|
||||
attribs[index++] = v; \
|
||||
}
|
||||
|
||||
// Reliably check windows version as done in VersionHelpers.h
|
||||
// needed for transparent window
|
||||
static 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 (!DwmIsCompositionEnabled) {
|
||||
_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
|
||||
//
|
||||
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||
@ -509,7 +629,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
pixelFormat = choosePixelFormat(window, ctxconfig, fbconfig);
|
||||
pixelFormat = choosePixelFormat(window, ctxconfig, fbconfig, fbconfig->transparent);
|
||||
if (!pixelFormat)
|
||||
return GLFW_FALSE;
|
||||
|
||||
@ -664,8 +784,9 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||
ctxconfig->major,
|
||||
ctxconfig->minor);
|
||||
}
|
||||
}
|
||||
else if (error == (0xc0070000 | ERROR_INVALID_PROFILE_ARB))
|
||||
}
|
||||
else if (error == (0xc0070000 | ERROR_INVALID_PROFILE_ARB))
|
||||
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: Driver does not support the requested OpenGL profile");
|
||||
@ -713,6 +834,13 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||
}
|
||||
}
|
||||
|
||||
if (fbconfig->transparent)
|
||||
{
|
||||
if (!setupTransparentWindow(window))
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to setup window as transparent as requested");
|
||||
}
|
||||
|
||||
window->context.makeCurrent = makeContextCurrentWGL;
|
||||
window->context.swapBuffers = swapBuffersWGL;
|
||||
window->context.swapInterval = swapIntervalWGL;
|
||||
|
@ -131,6 +131,8 @@ static GLFWbool loadLibraries(void)
|
||||
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled");
|
||||
_glfw.win32.dwmapi.Flush = (PFN_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");
|
||||
|
@ -153,7 +153,22 @@ typedef enum PROCESS_DPI_AWARENESS
|
||||
|
||||
// HACK: Define macros that some dinput.h variants don't
|
||||
#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
|
||||
|
||||
// winmm.dll function pointer typedefs
|
||||
@ -179,9 +194,13 @@ typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,PCHANGEF
|
||||
// dwmapi.dll function pointer typedefs
|
||||
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
|
||||
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
|
||||
|
||||
#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
|
||||
#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
|
||||
typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
|
||||
#define _glfw_SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness
|
||||
@ -286,6 +305,7 @@ typedef struct _GLFWlibraryWin32
|
||||
HINSTANCE instance;
|
||||
PFN_DwmIsCompositionEnabled IsCompositionEnabled;
|
||||
PFN_DwmFlush Flush;
|
||||
PFN_DwmEnableBlurBehindWindow EnableBlurBehindWindow;
|
||||
} dwmapi;
|
||||
|
||||
struct {
|
||||
|
@ -147,6 +147,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
||||
fbconfig = _glfw.hints.framebuffer;
|
||||
ctxconfig = _glfw.hints.context;
|
||||
wndconfig = _glfw.hints.window;
|
||||
fbconfig.transparent = _glfw.hints.framebuffer.transparent ? GLFW_TRUE : GLFW_FALSE;
|
||||
|
||||
wndconfig.width = width;
|
||||
wndconfig.height = height;
|
||||
@ -262,6 +263,7 @@ void glfwDefaultWindowHints(void)
|
||||
_glfw.hints.framebuffer.depthBits = 24;
|
||||
_glfw.hints.framebuffer.stencilBits = 8;
|
||||
_glfw.hints.framebuffer.doublebuffer = GLFW_TRUE;
|
||||
_glfw.hints.framebuffer.transparent = GLFW_FALSE;
|
||||
|
||||
// The default is to select the highest available refresh rate
|
||||
_glfw.hints.refreshRate = GLFW_DONT_CARE;
|
||||
@ -315,6 +317,9 @@ GLFWAPI void glfwWindowHint(int hint, int value)
|
||||
case GLFW_DOUBLEBUFFER:
|
||||
_glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
return;
|
||||
case GLFW_TRANSPARENT:
|
||||
_glfw.hints.framebuffer.transparent = value;
|
||||
return;
|
||||
case GLFW_SAMPLES:
|
||||
_glfw.hints.framebuffer.samples = value;
|
||||
return;
|
||||
|
@ -480,6 +480,7 @@ static GLFWbool initExtensions(void)
|
||||
}
|
||||
|
||||
_glfw.x11.xi.handle = dlopen("libXi.so.6", RTLD_LAZY | RTLD_GLOBAL);
|
||||
|
||||
if (_glfw.x11.xi.handle)
|
||||
{
|
||||
_glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion)
|
||||
@ -505,7 +506,9 @@ static GLFWbool initExtensions(void)
|
||||
}
|
||||
}
|
||||
|
||||
// Check for RandR extension
|
||||
_glfw.x11.randr.handle = dlopen("libXrandr.so.2", RTLD_LAZY | RTLD_GLOBAL);
|
||||
|
||||
if (_glfw.x11.randr.handle)
|
||||
{
|
||||
_glfw.x11.randr.AllocGamma = (PFN_XRRAllocGamma)
|
||||
@ -717,6 +720,76 @@ static GLFWbool initExtensions(void)
|
||||
_glfw.x11.MOTIF_WM_HINTS =
|
||||
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;
|
||||
}
|
||||
|
||||
@ -979,4 +1052,3 @@ const char* _glfwPlatformGetVersionString(void)
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -162,10 +162,20 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(Vk
|
||||
#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.x11.display)
|
||||
|
||||
#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_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
|
||||
//
|
||||
@ -375,6 +385,22 @@ typedef struct _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
|
||||
//
|
||||
typedef struct _GLFWmonitorX11
|
||||
|
Loading…
Reference in New Issue
Block a user