diff --git a/.gitignore b/.gitignore index 9d2d504b..48b251d9 100644 --- a/.gitignore +++ b/.gitignore @@ -102,3 +102,7 @@ tests/triangle-vulkan tests/window tests/windows +# IDE caches +.cache/ +.idea/ +.vscode/ \ No newline at end of file diff --git a/src/cocoa_init.m b/src/cocoa_init.m index b3831df1..d925b4bd 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -525,6 +525,7 @@ GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform) _glfwGetGammaRampCocoa, _glfwSetGammaRampCocoa, _glfwCreateWindowCocoa, + _glfwAttachWindowCocoa, _glfwDestroyWindowCocoa, _glfwSetWindowTitleCocoa, _glfwSetWindowIconCocoa, @@ -694,4 +695,3 @@ void _glfwTerminateCocoa(void) } #endif // _GLFW_COCOA - diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index 9f7d191d..76d79226 100644 --- a/src/cocoa_platform.h +++ b/src/cocoa_platform.h @@ -215,6 +215,7 @@ int _glfwInitCocoa(void); void _glfwTerminateCocoa(void); GLFWbool _glfwCreateWindowCocoa(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); +GLFWbool _glfwAttachWindowCocoa(_GLFWwindow* window, intptr_t native, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); void _glfwDestroyWindowCocoa(_GLFWwindow* window); void _glfwSetWindowTitleCocoa(_GLFWwindow* window, const char* title); void _glfwSetWindowIconCocoa(_GLFWwindow* window, int count, const GLFWimage* images); @@ -299,4 +300,3 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); void _glfwDestroyContextNSGL(_GLFWwindow* window); - diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 9d794940..a83e6149 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -988,6 +988,15 @@ GLFWbool _glfwCreateWindowCocoa(_GLFWwindow* window, } // autoreleasepool } +GLFWbool _glfwAttachWindowCocoa(_GLFWwindow* window, + intptr_t native, + const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) { + _glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa window attachment is not implemented"); + return GLFW_FALSE; +} + void _glfwDestroyWindowCocoa(_GLFWwindow* window) { @autoreleasepool { @@ -2055,4 +2064,3 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* handle) } #endif // _GLFW_COCOA - diff --git a/src/internal.h b/src/internal.h index fe0369aa..05c1f5cc 100644 --- a/src/internal.h +++ b/src/internal.h @@ -532,6 +532,7 @@ struct _GLFWwindow GLFWbool focusOnShow; GLFWbool mousePassthrough; GLFWbool shouldClose; + GLFWbool external; void* userPointer; GLFWbool doublebuffer; GLFWvidmode videoMode; @@ -706,6 +707,7 @@ struct _GLFWplatform void (*setGammaRamp)(_GLFWmonitor*,const GLFWgammaramp*); // window GLFWbool (*createWindow)(_GLFWwindow*,const _GLFWwndconfig*,const _GLFWctxconfig*,const _GLFWfbconfig*); + GLFWbool (*attachWindow)(_GLFWwindow*, intptr_t, const _GLFWwndconfig*,const _GLFWctxconfig*,const _GLFWfbconfig*); void (*destroyWindow)(_GLFWwindow*); void (*setWindowTitle)(_GLFWwindow*,const char*); void (*setWindowIcon)(_GLFWwindow*,int,const GLFWimage*); diff --git a/src/null_init.c b/src/null_init.c index 34ddc04a..1ff95e37 100644 --- a/src/null_init.c +++ b/src/null_init.c @@ -69,6 +69,7 @@ GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform) _glfwGetGammaRampNull, _glfwSetGammaRampNull, _glfwCreateWindowNull, + _glfwAttachWindowNull, _glfwDestroyWindowNull, _glfwSetWindowTitleNull, _glfwSetWindowIconNull, @@ -261,4 +262,3 @@ void _glfwTerminateNull(void) _glfwTerminateOSMesa(); _glfwTerminateEGL(); } - diff --git a/src/null_platform.h b/src/null_platform.h index fb9374b4..64209880 100644 --- a/src/null_platform.h +++ b/src/null_platform.h @@ -210,6 +210,7 @@ GLFWbool _glfwGetGammaRampNull(_GLFWmonitor* monitor, GLFWgammaramp* ramp); void _glfwSetGammaRampNull(_GLFWmonitor* monitor, const GLFWgammaramp* ramp); GLFWbool _glfwCreateWindowNull(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); +GLFWbool _glfwAttachWindowNull(_GLFWwindow* window, intptr_t native, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); void _glfwDestroyWindowNull(_GLFWwindow* window); void _glfwSetWindowTitleNull(_GLFWwindow* window, const char* title); void _glfwSetWindowIconNull(_GLFWwindow* window, int count, const GLFWimage* images); @@ -269,4 +270,3 @@ GLFWbool _glfwGetPhysicalDevicePresentationSupportNull(VkInstance instance, VkPh VkResult _glfwCreateWindowSurfaceNull(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface); void _glfwPollMonitorsNull(void); - diff --git a/src/null_window.c b/src/null_window.c index c2aafbad..0bd6b9f5 100644 --- a/src/null_window.c +++ b/src/null_window.c @@ -104,6 +104,39 @@ static int createNativeWindow(_GLFWwindow* window, return GLFW_TRUE; } +static int attachNativeWindow(_GLFWwindow* window, + intptr_t native, + const _GLFWwndconfig* wndconfig, + const _GLFWfbconfig* fbconfig) +{ + if (window->monitor) + fitToMonitor(window); + else + { + if (wndconfig->xpos == GLFW_ANY_POSITION && wndconfig->ypos == GLFW_ANY_POSITION) + { + window->null.xpos = 17; + window->null.ypos = 17; + } + else + { + window->null.xpos = wndconfig->xpos; + window->null.ypos = wndconfig->ypos; + } + + window->null.width = wndconfig->width; + window->null.height = wndconfig->height; + } + + window->null.visible = wndconfig->visible; + window->null.decorated = wndconfig->decorated; + window->null.maximized = wndconfig->maximized; + window->null.floating = wndconfig->floating; + window->null.transparent = fbconfig->transparent; + window->null.opacity = 1.f; + + return GLFW_TRUE; +} ////////////////////////////////////////////////////////////////////////// @@ -164,6 +197,61 @@ GLFWbool _glfwCreateWindowNull(_GLFWwindow* window, return GLFW_TRUE; } +GLFWbool _glfwAttachWindowNull(_GLFWwindow* window, + intptr_t native, + const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) +{ + if (!attachNativeWindow(window, native, wndconfig, fbconfig)) + return GLFW_FALSE; + + if (ctxconfig->client != GLFW_NO_API) + { + if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API || + ctxconfig->source == GLFW_OSMESA_CONTEXT_API) + { + if (!_glfwInitOSMesa()) + return GLFW_FALSE; + if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig)) + return GLFW_FALSE; + } + else if (ctxconfig->source == GLFW_EGL_CONTEXT_API) + { + if (!_glfwInitEGL()) + return GLFW_FALSE; + if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig)) + return GLFW_FALSE; + } + + if (!_glfwRefreshContextAttribs(window, ctxconfig)) + return GLFW_FALSE; + } + + if (wndconfig->mousePassthrough) + _glfwSetWindowMousePassthroughNull(window, GLFW_TRUE); + + if (window->monitor) + { + _glfwShowWindowNull(window); + _glfwFocusWindowNull(window); + acquireMonitor(window); + + if (wndconfig->centerCursor) + _glfwCenterCursorInContentArea(window); + } + else + { + if (wndconfig->visible) + { + _glfwShowWindowNull(window); + if (wndconfig->focused) + _glfwFocusWindowNull(window); + } + } + + return GLFW_TRUE; +} void _glfwDestroyWindowNull(_GLFWwindow* window) { @@ -715,4 +803,3 @@ VkResult _glfwCreateWindowSurfaceNull(VkInstance instance, // This seems like the most appropriate error to return here return VK_ERROR_EXTENSION_NOT_PRESENT; } - diff --git a/src/win32_init.c b/src/win32_init.c index 739c9c33..baec5aea 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -672,6 +672,7 @@ GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform) _glfwGetGammaRampWin32, _glfwSetGammaRampWin32, _glfwCreateWindowWin32, + _glfwAttachWindowWin32, _glfwDestroyWindowWin32, _glfwSetWindowTitleWin32, _glfwSetWindowIconWin32, @@ -777,4 +778,3 @@ void _glfwTerminateWin32(void) } #endif // _GLFW_WIN32 - diff --git a/src/win32_platform.h b/src/win32_platform.h index 1db31584..c7add55b 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -544,6 +544,7 @@ void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor); void _glfwGetHMONITORContentScaleWin32(HMONITOR handle, float* xscale, float* yscale); GLFWbool _glfwCreateWindowWin32(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); +GLFWbool _glfwAttachWindowWin32(_GLFWwindow* window, intptr_t native, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); void _glfwDestroyWindowWin32(_GLFWwindow* window); void _glfwSetWindowTitleWin32(_GLFWwindow* window, const char* title); void _glfwSetWindowIconWin32(_GLFWwindow* window, int count, const GLFWimage* images); @@ -625,4 +626,3 @@ void _glfwTerminateWGL(void); GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); - diff --git a/src/win32_window.c b/src/win32_window.c index db3bed6e..257e956d 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1524,6 +1524,11 @@ GLFWbool _glfwCreateWindowWin32(_GLFWwindow* window, return GLFW_TRUE; } +GLFWbool _glfwAttachWindowWin32(_GLFWwindow* window, intptr_t native, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig) { + _glfwInputError(GLFW_PLATFORM_ERROR, "Win32 window attachment is not implemented"); + return GLFW_FALSE; +} + void _glfwDestroyWindowWin32(_GLFWwindow* window) { if (window->monitor) @@ -2542,4 +2547,3 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle) } #endif // _GLFW_WIN32 - diff --git a/src/window.c b/src/window.c index 1117df2f..ad3f55e3 100644 --- a/src/window.c +++ b/src/window.c @@ -252,8 +252,55 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, return (GLFWwindow*) window; } -void glfwDefaultWindowHints(void) -{ +GLFWAPI GLFWwindow* glfwAttachWindow(intptr_t nativeWindow, GLFWwindow* share) { + _GLFWfbconfig fbconfig; + _GLFWctxconfig ctxconfig; + _GLFWwndconfig wndconfig; + _GLFWwindow* window; + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + fbconfig = _glfw.hints.framebuffer; + ctxconfig = _glfw.hints.context; + wndconfig = _glfw.hints.window; + + ctxconfig.share = (_GLFWwindow*) share; + if (ctxconfig.share) + { + if (ctxconfig.client == GLFW_NO_API || + ctxconfig.share->context.client == GLFW_NO_API) + { + _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); + return NULL; + } + } + + if (!_glfwIsValidContextConfig(&ctxconfig)) + return NULL; + + window = calloc(1, sizeof(_GLFWwindow)); + window->next = _glfw.windowListHead; + _glfw.windowListHead = window; + + window->autoIconify = wndconfig.autoIconify; + window->cursorMode = GLFW_CURSOR_NORMAL; + window->external = GLFW_TRUE; + + window->minwidth = GLFW_DONT_CARE; + window->minheight = GLFW_DONT_CARE; + window->maxwidth = GLFW_DONT_CARE; + window->maxheight = GLFW_DONT_CARE; + window->numer = GLFW_DONT_CARE; + window->denom = GLFW_DONT_CARE; + + if (!_glfw.platform.attachWindow(window, nativeWindow, &wndconfig, &ctxconfig, &fbconfig)) + return NULL; + + return (GLFWwindow*) window; +} + +void glfwDefaultWindowHints(void) { + _GLFW_REQUIRE_INIT(); // The default is OpenGL with minimum version 1.0 @@ -1150,4 +1197,3 @@ GLFWAPI void glfwPostEmptyEvent(void) _GLFW_REQUIRE_INIT(); _glfw.platform.postEmptyEvent(); } - diff --git a/src/wl_init.c b/src/wl_init.c index a4692b52..ffecd6da 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -443,6 +443,7 @@ GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform) _glfwGetGammaRampWayland, _glfwSetGammaRampWayland, _glfwCreateWindowWayland, + _glfwAttachWindowWayland, _glfwDestroyWindowWayland, _glfwSetWindowTitleWayland, _glfwSetWindowIconWayland, @@ -946,4 +947,3 @@ void _glfwTerminateWayland(void) } #endif // _GLFW_WAYLAND - diff --git a/src/wl_platform.h b/src/wl_platform.h index d00e28fe..0e539629 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -610,6 +610,7 @@ int _glfwInitWayland(void); void _glfwTerminateWayland(void); GLFWbool _glfwCreateWindowWayland(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); +GLFWbool _glfwAttachWindowWayland(_GLFWwindow* window, intptr_t native, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); void _glfwDestroyWindowWayland(_GLFWwindow* window); void _glfwSetWindowTitleWayland(_GLFWwindow* window, const char* title); void _glfwSetWindowIconWayland(_GLFWwindow* window, int count, const GLFWimage* images); diff --git a/src/wl_window.c b/src/wl_window.c index 76c6a763..4bf86da1 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -967,6 +967,38 @@ static GLFWbool createNativeSurface(_GLFWwindow* window, return GLFW_TRUE; } +static GLFWbool attachNativeSurface(_GLFWwindow* window, + intptr_t native, + const _GLFWwndconfig* wndconfig, + const _GLFWfbconfig* fbconfig) { + if (!native) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: supplied wl_surface is null"); + return GLFW_FALSE; + } + window->wl.surface = (struct wl_surface*) native; + + wl_proxy_set_tag((struct wl_proxy*) window->wl.surface, &_glfw.wl.tag); + wl_surface_add_listener(window->wl.surface, + &surfaceListener, + window); + + window->wl.width = wndconfig->width; + window->wl.height = wndconfig->height; + window->wl.contentScale = 1; + window->wl.title = _glfw_strdup(wndconfig->title); + window->wl.appId = _glfw_strdup(wndconfig->wl.appId); + + + window->wl.maximized = wndconfig->maximized; + + window->wl.transparent = fbconfig->transparent; + if (!window->wl.transparent) + setContentAreaOpaque(window); + + return GLFW_TRUE; +} + static void setCursorImage(_GLFWwindow* window, _GLFWcursorWayland* cursorWayland) { @@ -2046,7 +2078,8 @@ GLFWbool _glfwCreateWindowWayland(_GLFWwindow* window, if (wndconfig->mousePassthrough) _glfwSetWindowMousePassthroughWayland(window, GLFW_TRUE); - if (window->monitor || wndconfig->visible) + // don't + if (!window->external && (window->monitor || wndconfig->visible)) { if (!createShellObjects(window)) return GLFW_FALSE; @@ -2055,6 +2088,52 @@ GLFWbool _glfwCreateWindowWayland(_GLFWwindow* window, return GLFW_TRUE; } +GLFWbool _glfwAttachWindowWayland(_GLFWwindow* window, + intptr_t native, + const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) { + + if (!attachNativeSurface(window, native, wndconfig, fbconfig)) + return GLFW_FALSE; + if (ctxconfig->client != GLFW_NO_API) + { + if (ctxconfig->source == GLFW_EGL_CONTEXT_API || + ctxconfig->source == GLFW_NATIVE_CONTEXT_API) + { + window->wl.egl.window = wl_egl_window_create(window->wl.surface, + wndconfig->width, + wndconfig->height); + if (!window->wl.egl.window) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to create EGL window"); + return GLFW_FALSE; + } + + if (!_glfwInitEGL()) + return GLFW_FALSE; + if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig)) + return GLFW_FALSE; + } + else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API) + { + if (!_glfwInitOSMesa()) + return GLFW_FALSE; + if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig)) + return GLFW_FALSE; + } + + if (!_glfwRefreshContextAttribs(window, ctxconfig)) + return GLFW_FALSE; + } + + if (wndconfig->mousePassthrough) + _glfwSetWindowMousePassthroughWayland(window, GLFW_TRUE); + + return GLFW_TRUE; +} + void _glfwDestroyWindowWayland(_GLFWwindow* window) { if (window == _glfw.wl.pointerFocus) @@ -2324,7 +2403,7 @@ void _glfwMaximizeWindowWayland(_GLFWwindow* window) void _glfwShowWindowWayland(_GLFWwindow* window) { - if (!window->wl.libdecor.frame && !window->wl.xdg.toplevel) + if (!window->external && (!window->wl.libdecor.frame && !window->wl.xdg.toplevel)) { // NOTE: The XDG surface and role are created here so command-line applications // with off-screen windows do not appear in for example the Unity dock @@ -3173,4 +3252,3 @@ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* handle) } #endif // _GLFW_WAYLAND - diff --git a/src/x11_init.c b/src/x11_init.c index c90b593c..8d527708 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -1204,6 +1204,7 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform) _glfwGetGammaRampX11, _glfwSetGammaRampX11, _glfwCreateWindowX11, + _glfwAttachWindowX11, _glfwDestroyWindowX11, _glfwSetWindowTitleX11, _glfwSetWindowIconX11, @@ -1653,4 +1654,3 @@ void _glfwTerminateX11(void) } #endif // _GLFW_X11 - diff --git a/src/x11_monitor.c b/src/x11_monitor.c index ae626643..270eb4a7 100644 --- a/src/x11_monitor.c +++ b/src/x11_monitor.c @@ -615,4 +615,3 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* handle) } #endif // _GLFW_X11 - diff --git a/src/x11_platform.h b/src/x11_platform.h index cdea3957..fc7cdae9 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -902,6 +902,7 @@ int _glfwInitX11(void); void _glfwTerminateX11(void); GLFWbool _glfwCreateWindowX11(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); +GLFWbool _glfwAttachWindowX11(_GLFWwindow* window, intptr_t native, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); void _glfwDestroyWindowX11(_GLFWwindow* window); void _glfwSetWindowTitleX11(_GLFWwindow* window, const char* title); void _glfwSetWindowIconX11(_GLFWwindow* window, int count, const GLFWimage* images); @@ -1001,4 +1002,3 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig, Visual** visual, int* depth); - diff --git a/src/x11_window.c b/src/x11_window.c index 3c76d3a9..dd7331c0 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -2042,6 +2042,15 @@ GLFWbool _glfwCreateWindowX11(_GLFWwindow* window, return GLFW_TRUE; } +GLFWbool _glfwAttachWindowX11(_GLFWwindow* window, + intptr_t native, + const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) { + _glfwInputError(GLFW_PLATFORM_ERROR, "X11 window attachment is not implemented"); + return GLFW_FALSE; +} + void _glfwDestroyWindowX11(_GLFWwindow* window) { if (_glfw.x11.disabledCursorWindow == window) @@ -3350,4 +3359,3 @@ GLFWAPI const char* glfwGetX11SelectionString(void) } #endif // _GLFW_X11 -