diff options
author | David Robillard <d@drobilla.net> | 2021-05-24 14:12:17 -0400 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2021-05-24 15:14:41 -0400 |
commit | f535b6eaeed44093bed7d90b4be76363c2e2e4f4 (patch) | |
tree | 035478b033d349e06e8339d0217cf93aa607b268 /src | |
parent | 830862ed8345a9620d2ff75293666e46972e2692 (diff) | |
download | pugl-f535b6eaeed44093bed7d90b4be76363c2e2e4f4.tar.gz pugl-f535b6eaeed44093bed7d90b4be76363c2e2e4f4.tar.bz2 pugl-f535b6eaeed44093bed7d90b4be76363c2e2e4f4.zip |
Separate stub backends from other backends
Stub backends were a dependency of other backends to allow some code reuse.
However, that can cause conflicting symbols if multiple backends are linked
into the same binary, which should be possible.
To avoid this, move the shared code into the platform implementation, and
export those symbols so that backends can use them. This adds some semi-public
platform-specific API that can only be used by backends included with pugl.
They are undocumented, subject to change at any time without a corresponding
version change, and may not be used by third parties (for example by custom
backends in an application).
Diffstat (limited to 'src')
-rw-r--r-- | src/stub.h | 14 | ||||
-rw-r--r-- | src/win.c | 156 | ||||
-rw-r--r-- | src/win.h | 120 | ||||
-rw-r--r-- | src/win_cairo.c | 4 | ||||
-rw-r--r-- | src/win_stub.c | 42 | ||||
-rw-r--r-- | src/win_vulkan.c | 9 | ||||
-rw-r--r-- | src/x11.c | 20 | ||||
-rw-r--r-- | src/x11.h | 5 | ||||
-rw-r--r-- | src/x11_cairo.c | 2 | ||||
-rw-r--r-- | src/x11_stub.c | 24 | ||||
-rw-r--r-- | src/x11_vulkan.c | 4 |
11 files changed, 217 insertions, 183 deletions
@@ -1,5 +1,5 @@ /* - Copyright 2012-2020 David Robillard <d@drobilla.net> + Copyright 2012-2021 David Robillard <d@drobilla.net> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -24,28 +24,28 @@ PUGL_BEGIN_DECLS static inline PuglStatus -puglStubConfigure(PuglView* view) +puglStubConfigure(PuglView* const view) { (void)view; return PUGL_SUCCESS; } static inline PuglStatus -puglStubCreate(PuglView* view) +puglStubCreate(PuglView* const view) { (void)view; return PUGL_SUCCESS; } static inline PuglStatus -puglStubDestroy(PuglView* view) +puglStubDestroy(PuglView* const view) { (void)view; return PUGL_SUCCESS; } static inline PuglStatus -puglStubEnter(PuglView* view, const PuglEventExpose* expose) +puglStubEnter(PuglView* const view, const PuglEventExpose* const expose) { (void)view; (void)expose; @@ -53,7 +53,7 @@ puglStubEnter(PuglView* view, const PuglEventExpose* expose) } static inline PuglStatus -puglStubLeave(PuglView* view, const PuglEventExpose* expose) +puglStubLeave(PuglView* const view, const PuglEventExpose* const expose) { (void)view; (void)expose; @@ -61,7 +61,7 @@ puglStubLeave(PuglView* view, const PuglEventExpose* expose) } static inline void* -puglStubGetContext(PuglView* view) +puglStubGetContext(PuglView* const view) { (void)view; return NULL; @@ -1,5 +1,5 @@ /* - Copyright 2012-2020 David Robillard <d@drobilla.net> + Copyright 2012-2021 David Robillard <d@drobilla.net> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -17,10 +17,8 @@ #include "win.h" #include "implementation.h" -#include "stub.h" #include "pugl/pugl.h" -#include "pugl/stub.h" #include <windows.h> #include <windowsx.h> @@ -101,6 +99,24 @@ puglRegisterWindowClass(const char* name) return RegisterClassEx(&wc); } +static unsigned +puglWinGetWindowFlags(const PuglView* const view) +{ + const bool resizable = view->hints[PUGL_RESIZABLE]; + const unsigned sizeFlags = resizable ? (WS_SIZEBOX | WS_MAXIMIZEBOX) : 0u; + + return (WS_CLIPCHILDREN | WS_CLIPSIBLINGS | + (view->parent + ? WS_CHILD + : (WS_POPUPWINDOW | WS_CAPTION | WS_MINIMIZEBOX | sizeFlags))); +} + +static unsigned +puglWinGetWindowExFlags(const PuglView* const view) +{ + return WS_EX_NOINHERITLAYOUT | (view->parent ? 0u : WS_EX_APPWINDOW); +} + PuglWorldInternals* puglInitWorldInternals(PuglWorldType PUGL_UNUSED(type), PuglWorldFlags PUGL_UNUSED(flags)) @@ -1141,3 +1157,137 @@ puglSetCursor(PuglView* view, PuglCursor cursor) return PUGL_SUCCESS; } + +// Semi-public platform API used by backends + +PuglWinPFD +puglWinGetPixelFormatDescriptor(const PuglHints hints) +{ + const int rgbBits = (hints[PUGL_RED_BITS] + // + hints[PUGL_GREEN_BITS] + // + hints[PUGL_BLUE_BITS]); + + const DWORD dwFlags = hints[PUGL_DOUBLE_BUFFER] ? PFD_DOUBLEBUFFER : 0u; + + PuglWinPFD pfd; + ZeroMemory(&pfd, sizeof(pfd)); + pfd.nSize = sizeof(pfd); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | dwFlags; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = (BYTE)rgbBits; + pfd.cRedBits = (BYTE)hints[PUGL_RED_BITS]; + pfd.cGreenBits = (BYTE)hints[PUGL_GREEN_BITS]; + pfd.cBlueBits = (BYTE)hints[PUGL_BLUE_BITS]; + pfd.cAlphaBits = (BYTE)hints[PUGL_ALPHA_BITS]; + pfd.cDepthBits = (BYTE)hints[PUGL_DEPTH_BITS]; + pfd.cStencilBits = (BYTE)hints[PUGL_STENCIL_BITS]; + pfd.iLayerType = PFD_MAIN_PLANE; + return pfd; +} + +PuglStatus +puglWinCreateWindow(PuglView* const view, + const char* const title, + HWND* const hwnd, + HDC* const hdc) +{ + const char* className = (const char*)view->world->className; + const unsigned winFlags = puglWinGetWindowFlags(view); + const unsigned winExFlags = puglWinGetWindowExFlags(view); + + if (view->frame.width == 0.0 && view->frame.height == 0.0) { + if (view->defaultWidth == 0.0 && view->defaultHeight == 0.0) { + return PUGL_BAD_CONFIGURATION; + } + + RECT desktopRect; + GetClientRect(GetDesktopWindow(), &desktopRect); + + const int screenWidth = desktopRect.right - desktopRect.left; + const int screenHeight = desktopRect.bottom - desktopRect.top; + + view->frame.width = view->defaultWidth; + view->frame.height = view->defaultHeight; + view->frame.x = screenWidth / 2.0 - view->frame.width / 2.0; + view->frame.y = screenHeight / 2.0 - view->frame.height / 2.0; + } + + // The meaning of "parent" depends on the window type (WS_CHILD) + PuglNativeView parent = view->parent ? view->parent : view->transientParent; + + // Calculate total window size to accommodate requested view size + RECT wr = {(long)view->frame.x, + (long)view->frame.y, + (long)view->frame.width, + (long)view->frame.height}; + AdjustWindowRectEx(&wr, winFlags, FALSE, winExFlags); + + // Create window and get drawing context + if (!(*hwnd = CreateWindowEx(winExFlags, + className, + title, + winFlags, + CW_USEDEFAULT, + CW_USEDEFAULT, + wr.right - wr.left, + wr.bottom - wr.top, + (HWND)parent, + NULL, + NULL, + NULL))) { + return PUGL_REALIZE_FAILED; + } else if (!(*hdc = GetDC(*hwnd))) { + DestroyWindow(*hwnd); + *hwnd = NULL; + return PUGL_REALIZE_FAILED; + } + + return PUGL_SUCCESS; +} + +PuglStatus +puglWinConfigure(PuglView* view) +{ + PuglInternals* const impl = view->impl; + PuglStatus st = PUGL_SUCCESS; + + if ((st = puglWinCreateWindow(view, "Pugl", &impl->hwnd, &impl->hdc))) { + return st; + } + + impl->pfd = puglWinGetPixelFormatDescriptor(view->hints); + impl->pfId = ChoosePixelFormat(impl->hdc, &impl->pfd); + + if (!SetPixelFormat(impl->hdc, impl->pfId, &impl->pfd)) { + ReleaseDC(impl->hwnd, impl->hdc); + DestroyWindow(impl->hwnd); + impl->hwnd = NULL; + impl->hdc = NULL; + return PUGL_SET_FORMAT_FAILED; + } + + return PUGL_SUCCESS; +} + +PuglStatus +puglWinEnter(PuglView* view, const PuglEventExpose* expose) +{ + if (expose) { + PAINTSTRUCT ps; + BeginPaint(view->impl->hwnd, &ps); + } + + return PUGL_SUCCESS; +} + +PuglStatus +puglWinLeave(PuglView* view, const PuglEventExpose* expose) +{ + if (expose) { + PAINTSTRUCT ps; + EndPaint(view->impl->hwnd, &ps); + } + + return PUGL_SUCCESS; +} @@ -1,5 +1,5 @@ /* - Copyright 2012-2020 David Robillard <d@drobilla.net> + Copyright 2012-2021 David Robillard <d@drobilla.net> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -19,6 +19,8 @@ #include "implementation.h" +#include "pugl/pugl.h" + #include <windows.h> #include <stdbool.h> @@ -40,117 +42,27 @@ struct PuglInternalsImpl { bool mouseTracked; }; -static inline PuglWinPFD -puglWinGetPixelFormatDescriptor(const PuglHints hints) -{ - const int rgbBits = (hints[PUGL_RED_BITS] + // - hints[PUGL_GREEN_BITS] + // - hints[PUGL_BLUE_BITS]); - - const DWORD dwFlags = hints[PUGL_DOUBLE_BUFFER] ? PFD_DOUBLEBUFFER : 0u; - - PuglWinPFD pfd; - ZeroMemory(&pfd, sizeof(pfd)); - pfd.nSize = sizeof(pfd); - pfd.nVersion = 1; - pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | dwFlags; - pfd.iPixelType = PFD_TYPE_RGBA; - pfd.cColorBits = (BYTE)rgbBits; - pfd.cRedBits = (BYTE)hints[PUGL_RED_BITS]; - pfd.cGreenBits = (BYTE)hints[PUGL_GREEN_BITS]; - pfd.cBlueBits = (BYTE)hints[PUGL_BLUE_BITS]; - pfd.cAlphaBits = (BYTE)hints[PUGL_ALPHA_BITS]; - pfd.cDepthBits = (BYTE)hints[PUGL_DEPTH_BITS]; - pfd.cStencilBits = (BYTE)hints[PUGL_STENCIL_BITS]; - pfd.iLayerType = PFD_MAIN_PLANE; - return pfd; -} - -static inline unsigned -puglWinGetWindowFlags(const PuglView* const view) -{ - const bool resizable = view->hints[PUGL_RESIZABLE]; - const unsigned sizeFlags = resizable ? (WS_SIZEBOX | WS_MAXIMIZEBOX) : 0u; - - return (WS_CLIPCHILDREN | WS_CLIPSIBLINGS | - (view->parent - ? WS_CHILD - : (WS_POPUPWINDOW | WS_CAPTION | WS_MINIMIZEBOX | sizeFlags))); -} - -static inline unsigned -puglWinGetWindowExFlags(const PuglView* const view) -{ - return WS_EX_NOINHERITLAYOUT | (view->parent ? 0u : WS_EX_APPWINDOW); -} - -static inline PuglStatus +PUGL_API +PuglWinPFD +puglWinGetPixelFormatDescriptor(const PuglHints hints); + +PUGL_API +PuglStatus puglWinCreateWindow(PuglView* const view, const char* const title, HWND* const hwnd, - HDC* const hdc) -{ - const char* className = (const char*)view->world->className; - const unsigned winFlags = puglWinGetWindowFlags(view); - const unsigned winExFlags = puglWinGetWindowExFlags(view); - - if (view->frame.width == 0.0 && view->frame.height == 0.0) { - if (view->defaultWidth == 0.0 && view->defaultHeight == 0.0) { - return PUGL_BAD_CONFIGURATION; - } - - RECT desktopRect; - GetClientRect(GetDesktopWindow(), &desktopRect); - - const int screenWidth = desktopRect.right - desktopRect.left; - const int screenHeight = desktopRect.bottom - desktopRect.top; - - view->frame.width = view->defaultWidth; - view->frame.height = view->defaultHeight; - view->frame.x = screenWidth / 2.0 - view->frame.width / 2.0; - view->frame.y = screenHeight / 2.0 - view->frame.height / 2.0; - } - - // The meaning of "parent" depends on the window type (WS_CHILD) - PuglNativeView parent = view->parent ? view->parent : view->transientParent; - - // Calculate total window size to accommodate requested view size - RECT wr = {(long)view->frame.x, - (long)view->frame.y, - (long)view->frame.width, - (long)view->frame.height}; - AdjustWindowRectEx(&wr, winFlags, FALSE, winExFlags); - - // Create window and get drawing context - if (!(*hwnd = CreateWindowEx(winExFlags, - className, - title, - winFlags, - CW_USEDEFAULT, - CW_USEDEFAULT, - wr.right - wr.left, - wr.bottom - wr.top, - (HWND)parent, - NULL, - NULL, - NULL))) { - return PUGL_REALIZE_FAILED; - } else if (!(*hdc = GetDC(*hwnd))) { - DestroyWindow(*hwnd); - *hwnd = NULL; - return PUGL_REALIZE_FAILED; - } - - return PUGL_SUCCESS; -} + HDC* const hdc); +PUGL_API PuglStatus -puglWinStubConfigure(PuglView* view); +puglWinConfigure(PuglView* view); +PUGL_API PuglStatus -puglWinStubEnter(PuglView* view, const PuglEventExpose* expose); +puglWinEnter(PuglView* view, const PuglEventExpose* expose); +PUGL_API PuglStatus -puglWinStubLeave(PuglView* view, const PuglEventExpose* expose); +puglWinLeave(PuglView* view, const PuglEventExpose* expose); #endif // PUGL_DETAIL_WIN_H diff --git a/src/win_cairo.c b/src/win_cairo.c index 9dc5ce0..c9b9703 100644 --- a/src/win_cairo.c +++ b/src/win_cairo.c @@ -1,5 +1,5 @@ /* - Copyright 2012-2020 David Robillard <d@drobilla.net> + Copyright 2012-2021 David Robillard <d@drobilla.net> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -65,7 +65,7 @@ puglWinCairoDestroyDrawContext(PuglView* view) static PuglStatus puglWinCairoConfigure(PuglView* view) { - const PuglStatus st = puglWinStubConfigure(view); + const PuglStatus st = puglWinConfigure(view); if (!st) { view->impl->surface = diff --git a/src/win_stub.c b/src/win_stub.c index cf86390..6b0cb23 100644 --- a/src/win_stub.c +++ b/src/win_stub.c @@ -1,5 +1,5 @@ /* - Copyright 2012-2020 David Robillard <d@drobilla.net> + Copyright 2012-2021 David Robillard <d@drobilla.net> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -20,50 +20,22 @@ #include "pugl/stub.h" -PuglStatus +static PuglStatus puglWinStubConfigure(PuglView* view) { - PuglInternals* const impl = view->impl; - PuglStatus st = PUGL_SUCCESS; - - if ((st = puglWinCreateWindow(view, "Pugl", &impl->hwnd, &impl->hdc))) { - return st; - } - - impl->pfd = puglWinGetPixelFormatDescriptor(view->hints); - impl->pfId = ChoosePixelFormat(impl->hdc, &impl->pfd); - - if (!SetPixelFormat(impl->hdc, impl->pfId, &impl->pfd)) { - ReleaseDC(impl->hwnd, impl->hdc); - DestroyWindow(impl->hwnd); - impl->hwnd = NULL; - impl->hdc = NULL; - return PUGL_SET_FORMAT_FAILED; - } - - return PUGL_SUCCESS; + return puglWinConfigure(view); } -PuglStatus +static PuglStatus puglWinStubEnter(PuglView* view, const PuglEventExpose* expose) { - if (expose) { - PAINTSTRUCT ps; - BeginPaint(view->impl->hwnd, &ps); - } - - return PUGL_SUCCESS; + return puglWinEnter(view, expose); } -PuglStatus +static PuglStatus puglWinStubLeave(PuglView* view, const PuglEventExpose* expose) { - if (expose) { - PAINTSTRUCT ps; - EndPaint(view->impl->hwnd, &ps); - } - - return PUGL_SUCCESS; + return puglWinLeave(view, expose); } const PuglBackend* diff --git a/src/win_vulkan.c b/src/win_vulkan.c index a892a16..e2d9bb4 100644 --- a/src/win_vulkan.c +++ b/src/win_vulkan.c @@ -1,5 +1,5 @@ /* - Copyright 2012-2020 David Robillard <d@drobilla.net> + Copyright 2012-2021 David Robillard <d@drobilla.net> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -20,7 +20,6 @@ #include "types.h" #include "win.h" -#include "pugl/stub.h" #include "pugl/vulkan.h" #include <vulkan/vulkan.h> @@ -81,11 +80,11 @@ puglGetDeviceProcAddrFunc(const PuglVulkanLoader* loader) const PuglBackend* puglVulkanBackend() { - static const PuglBackend backend = {puglWinStubConfigure, + static const PuglBackend backend = {puglWinConfigure, puglStubCreate, puglStubDestroy, - puglWinStubEnter, - puglWinStubLeave, + puglWinEnter, + puglWinLeave, puglStubGetContext}; return &backend; @@ -1451,3 +1451,23 @@ puglSetCursor(PuglView* const view, const PuglCursor cursor) return PUGL_FAILURE; #endif } + +// Semi-public platform API used by backends + +PuglStatus +puglX11Configure(PuglView* view) +{ + PuglInternals* const impl = view->impl; + XVisualInfo pat = {0}; + int n = 0; + + pat.screen = impl->screen; + impl->vi = XGetVisualInfo(impl->display, VisualScreenMask, &pat, &n); + + view->hints[PUGL_RED_BITS] = impl->vi->bits_per_rgb; + view->hints[PUGL_GREEN_BITS] = impl->vi->bits_per_rgb; + view->hints[PUGL_BLUE_BITS] = impl->vi->bits_per_rgb; + view->hints[PUGL_ALPHA_BITS] = 0; + + return PUGL_SUCCESS; +} @@ -1,5 +1,5 @@ /* - Copyright 2012-2020 David Robillard <d@drobilla.net> + Copyright 2012-2021 David Robillard <d@drobilla.net> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -73,7 +73,8 @@ struct PuglInternalsImpl { #endif }; +PUGL_API PuglStatus -puglX11StubConfigure(PuglView* view); +puglX11Configure(PuglView* view); #endif // PUGL_DETAIL_X11_H diff --git a/src/x11_cairo.c b/src/x11_cairo.c index a0e7d08..d562fc5 100644 --- a/src/x11_cairo.c +++ b/src/x11_cairo.c @@ -152,7 +152,7 @@ puglX11CairoGetContext(PuglView* view) const PuglBackend* puglCairoBackend(void) { - static const PuglBackend backend = {puglX11StubConfigure, + static const PuglBackend backend = {puglX11Configure, puglX11CairoCreate, puglX11CairoDestroy, puglX11CairoEnter, diff --git a/src/x11_stub.c b/src/x11_stub.c index de89a86..856f90c 100644 --- a/src/x11_stub.c +++ b/src/x11_stub.c @@ -1,5 +1,5 @@ /* - Copyright 2012-2020 David Robillard <d@drobilla.net> + Copyright 2012-2021 David Robillard <d@drobilla.net> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -22,31 +22,11 @@ #include "pugl/pugl.h" -#include <X11/Xutil.h> - -PuglStatus -puglX11StubConfigure(PuglView* view) -{ - PuglInternals* const impl = view->impl; - XVisualInfo pat = {0}; - int n = 0; - - pat.screen = impl->screen; - impl->vi = XGetVisualInfo(impl->display, VisualScreenMask, &pat, &n); - - view->hints[PUGL_RED_BITS] = impl->vi->bits_per_rgb; - view->hints[PUGL_GREEN_BITS] = impl->vi->bits_per_rgb; - view->hints[PUGL_BLUE_BITS] = impl->vi->bits_per_rgb; - view->hints[PUGL_ALPHA_BITS] = 0; - - return PUGL_SUCCESS; -} - const PuglBackend* puglStubBackend(void) { static const PuglBackend backend = { - puglX11StubConfigure, + puglX11Configure, puglStubCreate, puglStubDestroy, puglStubEnter, diff --git a/src/x11_vulkan.c b/src/x11_vulkan.c index f0334ce..857c41b 100644 --- a/src/x11_vulkan.c +++ b/src/x11_vulkan.c @@ -1,5 +1,5 @@ /* - Copyright 2012-2020 David Robillard <d@drobilla.net> + Copyright 2012-2021 David Robillard <d@drobilla.net> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -81,7 +81,7 @@ puglGetDeviceProcAddrFunc(const PuglVulkanLoader* loader) const PuglBackend* puglVulkanBackend(void) { - static const PuglBackend backend = {puglX11StubConfigure, + static const PuglBackend backend = {puglX11Configure, puglStubCreate, puglStubDestroy, puglStubEnter, |