diff options
-rw-r--r-- | meson.build | 10 | ||||
-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 |
12 files changed, 221 insertions, 189 deletions
diff --git a/meson.build b/meson.build index d966b26..d91ef6b 100644 --- a/meson.build +++ b/meson.build @@ -356,22 +356,21 @@ endif # Build Cairo backend if cairo_dep.found() name = 'pugl_' + platform + '_cairo' + version_suffix - sources = ['src/' + platform + '_cairo' + extension, - 'src/' + platform + '_stub' + extension] + sources = ['src/' + platform + '_cairo' + extension] cairo_backend = build_target( name, sources, version: meson.project_version(), include_directories: include_directories(['include']), c_args: library_args, - dependencies: [pugl_dep, cairo_dep, stub_backend_dep], + dependencies: [pugl_dep, cairo_dep], gnu_symbol_visibility: 'hidden', install: true, target_type: library_type) cairo_backend_dep = declare_dependency( link_with: cairo_backend, - dependencies: [pugl_dep, cairo_dep, stub_backend_dep]) + dependencies: [pugl_dep, cairo_dep]) pkg.generate(cairo_backend, name: 'Pugl Cairo', @@ -384,8 +383,7 @@ endif # Build Vulkan backend if vulkan_dep.found() name = 'pugl_' + platform + '_vulkan' + version_suffix - sources = ['src/' + platform + '_vulkan' + extension, - 'src/' + platform + '_stub' + extension] + sources = ['src/' + platform + '_vulkan' + extension] vulkan_deps = [pugl_dep, vulkan_dep, dl_dep] vulkan_c_args = library_args @@ -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, |