| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -189,7 +189,7 @@ void Window::setOffsetY(const int y) | |||||
| void Window::setOffset(const int x, const int y) | void Window::setOffset(const int x, const int y) | ||||
| { | { | ||||
| puglSetWindowOffset(pData->view, x, y); | |||||
| puglSetPosition(pData->view, x, y); | |||||
| } | } | ||||
| void Window::setOffset(const Point<int>& offset) | void Window::setOffset(const Point<int>& offset) | ||||
| @@ -289,7 +289,7 @@ void Window::setSize(uint width, uint height) | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| puglSetWindowSize(pData->view, width, height); | |||||
| puglSetSizeAndDefault(pData->view, width, height); | |||||
| } | } | ||||
| } | } | ||||
| @@ -326,10 +326,7 @@ bool Window::setClipboard(const char* const mimeType, const void* const data, co | |||||
| const void* Window::getClipboard(const char*& mimeType, size_t& dataSize) | const void* Window::getClipboard(const char*& mimeType, size_t& dataSize) | ||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(!pData->ignoreEvents, nullptr); | |||||
| pData->ignoreEvents = true; | |||||
| const void* const clipboard = puglGetClipboard(pData->view, &mimeType, &dataSize); | |||||
| pData->ignoreEvents = false; | |||||
| const void* const clipboard = nullptr; // puglGetClipboard(pData->view, &mimeType, &dataSize); | |||||
| return clipboard; | return clipboard; | ||||
| } | } | ||||
| @@ -400,10 +397,10 @@ void Window::repaint(const Rectangle<uint>& rect) noexcept | |||||
| return; | return; | ||||
| PuglRect prect = { | PuglRect prect = { | ||||
| static_cast<double>(rect.getX()), | |||||
| static_cast<double>(rect.getY()), | |||||
| static_cast<double>(rect.getWidth()), | |||||
| static_cast<double>(rect.getHeight()), | |||||
| static_cast<PuglCoord>(rect.getX()), | |||||
| static_cast<PuglCoord>(rect.getY()), | |||||
| static_cast<PuglSpan>(rect.getWidth()), | |||||
| static_cast<PuglSpan>(rect.getHeight()), | |||||
| }; | }; | ||||
| if (pData->autoScaling) | if (pData->autoScaling) | ||||
| { | { | ||||
| @@ -52,39 +52,63 @@ START_NAMESPACE_DGL | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| static double getDesktopScaleFactor(const PuglView* const view) | |||||
| static double getScaleFactorFromParent(const PuglView* const view) | |||||
| { | { | ||||
| // allow custom scale for testing | // allow custom scale for testing | ||||
| if (const char* const scale = getenv("DPF_SCALE_FACTOR")) | if (const char* const scale = getenv("DPF_SCALE_FACTOR")) | ||||
| return std::max(1.0, std::atof(scale)); | return std::max(1.0, std::atof(scale)); | ||||
| if (view != nullptr) | if (view != nullptr) | ||||
| return puglGetDesktopScaleFactor(view); | |||||
| return puglGetScaleFactorFromParent(view); | |||||
| return 1.0; | return 1.0; | ||||
| } | } | ||||
| static PuglView* puglNewViewWithTransientParent(PuglWorld* const world, PuglView* const transientParentView) | |||||
| { | |||||
| DISTRHO_SAFE_ASSERT_RETURN(world != nullptr, nullptr); | |||||
| if (PuglView* const view = puglNewView(world)) | |||||
| { | |||||
| puglSetTransientParent(view, puglGetNativeWindow(transientParentView)); | |||||
| return view; | |||||
| } | |||||
| return nullptr; | |||||
| } | |||||
| static PuglView* puglNewViewWithParentWindow(PuglWorld* const world, const uintptr_t parentWindowHandle) | |||||
| { | |||||
| DISTRHO_SAFE_ASSERT_RETURN(world != nullptr, nullptr); | |||||
| if (PuglView* const view = puglNewView(world)) | |||||
| { | |||||
| puglSetParentWindow(view, parentWindowHandle); | |||||
| return view; | |||||
| } | |||||
| return nullptr; | |||||
| } | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| Window::PrivateData::PrivateData(Application& a, Window* const s) | Window::PrivateData::PrivateData(Application& a, Window* const s) | ||||
| : app(a), | : app(a), | ||||
| appData(a.pData), | appData(a.pData), | ||||
| self(s), | self(s), | ||||
| view(puglNewView(appData->world)), | |||||
| transientParentView(nullptr), | |||||
| view(appData->world != nullptr ? puglNewView(appData->world) : nullptr), | |||||
| topLevelWidgets(), | topLevelWidgets(), | ||||
| isClosed(true), | isClosed(true), | ||||
| isVisible(false), | isVisible(false), | ||||
| isEmbed(false), | isEmbed(false), | ||||
| usesSizeRequest(false), | usesSizeRequest(false), | ||||
| scaleFactor(getDesktopScaleFactor(view)), | |||||
| scaleFactor(getScaleFactorFromParent(view)), | |||||
| autoScaling(false), | autoScaling(false), | ||||
| autoScaleFactor(1.0), | autoScaleFactor(1.0), | ||||
| minWidth(0), | minWidth(0), | ||||
| minHeight(0), | minHeight(0), | ||||
| keepAspectRatio(false), | keepAspectRatio(false), | ||||
| ignoreIdleCallbacks(false), | ignoreIdleCallbacks(false), | ||||
| ignoreEvents(false), | |||||
| filenameToRenderInto(nullptr), | filenameToRenderInto(nullptr), | ||||
| #ifndef DGL_FILE_BROWSER_DISABLED | #ifndef DGL_FILE_BROWSER_DISABLED | ||||
| fileBrowserHandle(nullptr), | fileBrowserHandle(nullptr), | ||||
| @@ -98,8 +122,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, PrivateData* c | |||||
| : app(a), | : app(a), | ||||
| appData(a.pData), | appData(a.pData), | ||||
| self(s), | self(s), | ||||
| view(puglNewView(appData->world)), | |||||
| transientParentView(ppData->view), | |||||
| view(puglNewViewWithTransientParent(appData->world, ppData->view)), | |||||
| topLevelWidgets(), | topLevelWidgets(), | ||||
| isClosed(true), | isClosed(true), | ||||
| isVisible(false), | isVisible(false), | ||||
| @@ -112,15 +135,12 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, PrivateData* c | |||||
| minHeight(0), | minHeight(0), | ||||
| keepAspectRatio(false), | keepAspectRatio(false), | ||||
| ignoreIdleCallbacks(false), | ignoreIdleCallbacks(false), | ||||
| ignoreEvents(false), | |||||
| filenameToRenderInto(nullptr), | filenameToRenderInto(nullptr), | ||||
| #ifndef DGL_FILE_BROWSER_DISABLED | #ifndef DGL_FILE_BROWSER_DISABLED | ||||
| fileBrowserHandle(nullptr), | fileBrowserHandle(nullptr), | ||||
| #endif | #endif | ||||
| modal(ppData) | modal(ppData) | ||||
| { | { | ||||
| puglSetTransientFor(view, puglGetNativeWindow(transientParentView)); | |||||
| initPre(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); | initPre(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); | ||||
| } | } | ||||
| @@ -130,30 +150,25 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, | |||||
| : app(a), | : app(a), | ||||
| appData(a.pData), | appData(a.pData), | ||||
| self(s), | self(s), | ||||
| view(puglNewView(appData->world)), | |||||
| transientParentView(nullptr), | |||||
| view(puglNewViewWithParentWindow(appData->world, parentWindowHandle)), | |||||
| topLevelWidgets(), | topLevelWidgets(), | ||||
| isClosed(parentWindowHandle == 0), | isClosed(parentWindowHandle == 0), | ||||
| isVisible(parentWindowHandle != 0), | isVisible(parentWindowHandle != 0), | ||||
| isEmbed(parentWindowHandle != 0), | isEmbed(parentWindowHandle != 0), | ||||
| usesSizeRequest(false), | usesSizeRequest(false), | ||||
| scaleFactor(scale != 0.0 ? scale : getDesktopScaleFactor(view)), | |||||
| scaleFactor(scale != 0.0 ? scale : getScaleFactorFromParent(view)), | |||||
| autoScaling(false), | autoScaling(false), | ||||
| autoScaleFactor(1.0), | autoScaleFactor(1.0), | ||||
| minWidth(0), | minWidth(0), | ||||
| minHeight(0), | minHeight(0), | ||||
| keepAspectRatio(false), | keepAspectRatio(false), | ||||
| ignoreIdleCallbacks(false), | ignoreIdleCallbacks(false), | ||||
| ignoreEvents(false), | |||||
| filenameToRenderInto(nullptr), | filenameToRenderInto(nullptr), | ||||
| #ifndef DGL_FILE_BROWSER_DISABLED | #ifndef DGL_FILE_BROWSER_DISABLED | ||||
| fileBrowserHandle(nullptr), | fileBrowserHandle(nullptr), | ||||
| #endif | #endif | ||||
| modal() | modal() | ||||
| { | { | ||||
| if (isEmbed) | |||||
| puglSetParentWindow(view, parentWindowHandle); | |||||
| initPre(DEFAULT_WIDTH, DEFAULT_HEIGHT, resizable); | initPre(DEFAULT_WIDTH, DEFAULT_HEIGHT, resizable); | ||||
| } | } | ||||
| @@ -164,21 +179,19 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, | |||||
| : app(a), | : app(a), | ||||
| appData(a.pData), | appData(a.pData), | ||||
| self(s), | self(s), | ||||
| view(appData->world != nullptr ? puglNewView(appData->world) : nullptr), | |||||
| transientParentView(nullptr), | |||||
| view(puglNewViewWithParentWindow(appData->world, parentWindowHandle)), | |||||
| topLevelWidgets(), | topLevelWidgets(), | ||||
| isClosed(parentWindowHandle == 0), | isClosed(parentWindowHandle == 0), | ||||
| isVisible(parentWindowHandle != 0 && view != nullptr), | isVisible(parentWindowHandle != 0 && view != nullptr), | ||||
| isEmbed(parentWindowHandle != 0), | isEmbed(parentWindowHandle != 0), | ||||
| usesSizeRequest(isVST3), | usesSizeRequest(isVST3), | ||||
| scaleFactor(scale != 0.0 ? scale : getDesktopScaleFactor(view)), | |||||
| scaleFactor(scale != 0.0 ? scale : getScaleFactorFromParent(view)), | |||||
| autoScaling(false), | autoScaling(false), | ||||
| autoScaleFactor(1.0), | autoScaleFactor(1.0), | ||||
| minWidth(0), | minWidth(0), | ||||
| minHeight(0), | minHeight(0), | ||||
| keepAspectRatio(false), | keepAspectRatio(false), | ||||
| ignoreIdleCallbacks(false), | ignoreIdleCallbacks(false), | ||||
| ignoreEvents(false), | |||||
| filenameToRenderInto(nullptr), | filenameToRenderInto(nullptr), | ||||
| #ifndef DGL_FILE_BROWSER_DISABLED | #ifndef DGL_FILE_BROWSER_DISABLED | ||||
| fileBrowserHandle(nullptr), | fileBrowserHandle(nullptr), | ||||
| @@ -230,11 +243,11 @@ void Window::PrivateData::initPre(const uint width, const uint height, const boo | |||||
| } | } | ||||
| puglSetMatchingBackendForCurrentBuild(view); | puglSetMatchingBackendForCurrentBuild(view); | ||||
| puglSetHandle(view, this); | |||||
| puglClearMinSize(view); | |||||
| puglSetWindowSize(view, width, height); | |||||
| // FIXME? | |||||
| // puglClearMinSize(view); | |||||
| puglSetHandle(view, this); | |||||
| puglSetViewHint(view, PUGL_RESIZABLE, resizable ? PUGL_TRUE : PUGL_FALSE); | puglSetViewHint(view, PUGL_RESIZABLE, resizable ? PUGL_TRUE : PUGL_FALSE); | ||||
| puglSetViewHint(view, PUGL_IGNORE_KEY_REPEAT, PUGL_FALSE); | puglSetViewHint(view, PUGL_IGNORE_KEY_REPEAT, PUGL_FALSE); | ||||
| #if DGL_USE_RGBA | #if DGL_USE_RGBA | ||||
| @@ -249,6 +262,9 @@ void Window::PrivateData::initPre(const uint width, const uint height, const boo | |||||
| #endif | #endif | ||||
| // PUGL_SAMPLES ?? | // PUGL_SAMPLES ?? | ||||
| puglSetEventFunc(view, puglEventCallback); | puglSetEventFunc(view, puglEventCallback); | ||||
| // setting default size triggers system-level calls, do it last | |||||
| puglSetSizeHint(view, PUGL_DEFAULT_SIZE, width, height); | |||||
| } | } | ||||
| bool Window::PrivateData::initPost() | bool Window::PrivateData::initPost() | ||||
| @@ -314,8 +330,8 @@ void Window::PrivateData::show() | |||||
| appData->oneWindowShown(); | appData->oneWindowShown(); | ||||
| // FIXME | // FIXME | ||||
| PuglRect rect = puglGetFrame(view); | |||||
| puglSetWindowSize(view, static_cast<uint>(rect.width), static_cast<uint>(rect.height)); | |||||
| // PuglRect rect = puglGetFrame(view); | |||||
| // puglSetWindowSize(view, static_cast<uint>(rect.width), static_cast<uint>(rect.height)); | |||||
| #if defined(DISTRHO_OS_WINDOWS) | #if defined(DISTRHO_OS_WINDOWS) | ||||
| puglWin32ShowCentered(view); | puglWin32ShowCentered(view); | ||||
| @@ -378,11 +394,7 @@ void Window::PrivateData::focus() | |||||
| if (! isEmbed) | if (! isEmbed) | ||||
| puglRaiseWindow(view); | puglRaiseWindow(view); | ||||
| #if defined(HAVE_X11) && !defined(DISTRHO_OS_MAC) && !defined(DISTRHO_OS_WINDOWS) | |||||
| puglX11GrabFocus(view); | |||||
| #else | |||||
| puglGrabFocus(view); | puglGrabFocus(view); | ||||
| #endif | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -393,10 +405,7 @@ void Window::PrivateData::setResizable(const bool resizable) | |||||
| DGL_DBG("Window setResizable called\n"); | DGL_DBG("Window setResizable called\n"); | ||||
| puglSetViewHint(view, PUGL_RESIZABLE, resizable ? PUGL_TRUE : PUGL_FALSE); | |||||
| #ifdef DISTRHO_OS_WINDOWS | |||||
| puglWin32SetWindowResizable(view, resizable); | |||||
| #endif | |||||
| puglSetResizable(view, resizable); | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -795,8 +804,6 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu | |||||
| ///< View must be drawn, a #PuglEventExpose | ///< View must be drawn, a #PuglEventExpose | ||||
| case PUGL_EXPOSE: | case PUGL_EXPOSE: | ||||
| if (pData->ignoreEvents) | |||||
| break; | |||||
| // unused x, y, width, height (double) | // unused x, y, width, height (double) | ||||
| pData->onPuglExpose(); | pData->onPuglExpose(); | ||||
| break; | break; | ||||
| @@ -810,8 +817,6 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu | |||||
| case PUGL_FOCUS_IN: | case PUGL_FOCUS_IN: | ||||
| ///< Keyboard focus left view, a #PuglEventFocus | ///< Keyboard focus left view, a #PuglEventFocus | ||||
| case PUGL_FOCUS_OUT: | case PUGL_FOCUS_OUT: | ||||
| if (pData->ignoreEvents) | |||||
| break; | |||||
| pData->onPuglFocus(event->type == PUGL_FOCUS_IN, | pData->onPuglFocus(event->type == PUGL_FOCUS_IN, | ||||
| static_cast<CrossingMode>(event->focus.mode)); | static_cast<CrossingMode>(event->focus.mode)); | ||||
| break; | break; | ||||
| @@ -821,8 +826,6 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu | |||||
| ///< Key released, a #PuglEventKey | ///< Key released, a #PuglEventKey | ||||
| case PUGL_KEY_RELEASE: | case PUGL_KEY_RELEASE: | ||||
| { | { | ||||
| if (pData->ignoreEvents) | |||||
| break; | |||||
| // unused x, y, xRoot, yRoot (double) | // unused x, y, xRoot, yRoot (double) | ||||
| Widget::KeyboardEvent ev; | Widget::KeyboardEvent ev; | ||||
| ev.mod = event->key.state; | ev.mod = event->key.state; | ||||
| @@ -846,8 +849,6 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu | |||||
| ///< Character entered, a #PuglEventText | ///< Character entered, a #PuglEventText | ||||
| case PUGL_TEXT: | case PUGL_TEXT: | ||||
| { | { | ||||
| if (pData->ignoreEvents) | |||||
| break; | |||||
| // unused x, y, xRoot, yRoot (double) | // unused x, y, xRoot, yRoot (double) | ||||
| Widget::CharacterInputEvent ev; | Widget::CharacterInputEvent ev; | ||||
| ev.mod = event->text.state; | ev.mod = event->text.state; | ||||
| @@ -872,13 +873,11 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu | |||||
| ///< Mouse button released, a #PuglEventButton | ///< Mouse button released, a #PuglEventButton | ||||
| case PUGL_BUTTON_RELEASE: | case PUGL_BUTTON_RELEASE: | ||||
| { | { | ||||
| if (pData->ignoreEvents) | |||||
| break; | |||||
| Widget::MouseEvent ev; | Widget::MouseEvent ev; | ||||
| ev.mod = event->button.state; | ev.mod = event->button.state; | ||||
| ev.flags = event->button.flags; | ev.flags = event->button.flags; | ||||
| ev.time = static_cast<uint>(event->button.time * 1000.0 + 0.5); | ev.time = static_cast<uint>(event->button.time * 1000.0 + 0.5); | ||||
| ev.button = event->button.button; | |||||
| ev.button = event->button.button + 1; | |||||
| ev.press = event->type == PUGL_BUTTON_PRESS; | ev.press = event->type == PUGL_BUTTON_PRESS; | ||||
| ev.pos = Point<double>(event->button.x, event->button.y); | ev.pos = Point<double>(event->button.x, event->button.y); | ||||
| ev.absolutePos = ev.pos; | ev.absolutePos = ev.pos; | ||||
| @@ -889,8 +888,6 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu | |||||
| ///< Pointer moved, a #PuglEventMotion | ///< Pointer moved, a #PuglEventMotion | ||||
| case PUGL_MOTION: | case PUGL_MOTION: | ||||
| { | { | ||||
| if (pData->ignoreEvents) | |||||
| break; | |||||
| Widget::MotionEvent ev; | Widget::MotionEvent ev; | ||||
| ev.mod = event->motion.state; | ev.mod = event->motion.state; | ||||
| ev.flags = event->motion.flags; | ev.flags = event->motion.flags; | ||||
| @@ -904,8 +901,6 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu | |||||
| ///< Scrolled, a #PuglEventScroll | ///< Scrolled, a #PuglEventScroll | ||||
| case PUGL_SCROLL: | case PUGL_SCROLL: | ||||
| { | { | ||||
| if (pData->ignoreEvents) | |||||
| break; | |||||
| Widget::ScrollEvent ev; | Widget::ScrollEvent ev; | ||||
| ev.mod = event->scroll.state; | ev.mod = event->scroll.state; | ||||
| ev.flags = event->scroll.flags; | ev.flags = event->scroll.flags; | ||||
| @@ -924,8 +919,6 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu | |||||
| ///< Timer triggered, a #PuglEventTimer | ///< Timer triggered, a #PuglEventTimer | ||||
| case PUGL_TIMER: | case PUGL_TIMER: | ||||
| if (pData->ignoreEvents) | |||||
| break; | |||||
| if (IdleCallback* const idleCallback = reinterpret_cast<IdleCallback*>(event->timer.id)) | if (IdleCallback* const idleCallback = reinterpret_cast<IdleCallback*>(event->timer.id)) | ||||
| idleCallback->idleCallback(); | idleCallback->idleCallback(); | ||||
| break; | break; | ||||
| @@ -937,6 +930,14 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu | |||||
| ///< Recursive loop left, a #PuglEventLoopLeave | ///< Recursive loop left, a #PuglEventLoopLeave | ||||
| case PUGL_LOOP_LEAVE: | case PUGL_LOOP_LEAVE: | ||||
| break; | break; | ||||
| ///< Data offered from clipboard, a #PuglDataOfferEvent | |||||
| case PUGL_DATA_OFFER: | |||||
| break; | |||||
| ///< Data available from clipboard, a #PuglDataEvent | |||||
| case PUGL_DATA: | |||||
| break; | |||||
| } | } | ||||
| return PUGL_SUCCESS; | return PUGL_SUCCESS; | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -45,7 +45,7 @@ struct Window::PrivateData : IdleCallback { | |||||
| PuglView* view; | PuglView* view; | ||||
| /** Pugl view instance of the transient parent window. */ | /** Pugl view instance of the transient parent window. */ | ||||
| PuglView* const transientParentView; | |||||
| // PuglView* const transientParentView; | |||||
| /** Reserved space for graphics context. */ | /** Reserved space for graphics context. */ | ||||
| mutable uint8_t graphicsContext[sizeof(void*)]; | mutable uint8_t graphicsContext[sizeof(void*)]; | ||||
| @@ -80,9 +80,6 @@ struct Window::PrivateData : IdleCallback { | |||||
| /** Whether to ignore idle callback requests, useful for temporary windows. */ | /** Whether to ignore idle callback requests, useful for temporary windows. */ | ||||
| bool ignoreIdleCallbacks; | bool ignoreIdleCallbacks; | ||||
| /** Whether to ignore pugl events (except create and destroy), used for puglGetClipboard. */ | |||||
| bool ignoreEvents; | |||||
| /** Render to a picture file when non-null, automatically free+unset after saving. */ | /** Render to a picture file when non-null, automatically free+unset after saving. */ | ||||
| char* filenameToRenderInto; | char* filenameToRenderInto; | ||||
| @@ -1 +1 @@ | |||||
| Subproject commit b1d9703ecbdb0a033fe0b9acdf58b90f7d81a8e5 | |||||
| Subproject commit 9691a6810283ffd5a99b1cc974fc638e80f94979 | |||||
| @@ -16,10 +16,24 @@ | |||||
| #include "pugl.hpp" | #include "pugl.hpp" | ||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // include base headers | |||||
| #ifdef DGL_CAIRO | |||||
| # include <cairo/cairo.h> | |||||
| #endif | |||||
| #ifdef DGL_OPENGL | |||||
| # include "../OpenGL-include.hpp" | |||||
| #endif | |||||
| #ifdef DGL_VULKAN | |||||
| # include <vulkan/vulkan_core.h> | |||||
| #endif | |||||
| /* we will include all header files used in pugl in their C++ friendly form, then pugl stuff in custom namespace */ | /* we will include all header files used in pugl in their C++ friendly form, then pugl stuff in custom namespace */ | ||||
| #include <cassert> | #include <cassert> | ||||
| #include <cmath> | #include <cmath> | ||||
| #include <cstdlib> | #include <cstdlib> | ||||
| #include <cstdio> | |||||
| #include <cstring> | #include <cstring> | ||||
| #include <ctime> | #include <ctime> | ||||
| @@ -57,9 +71,10 @@ | |||||
| # endif | # endif | ||||
| #else | #else | ||||
| # include <dlfcn.h> | # include <dlfcn.h> | ||||
| # include <limits.h> | |||||
| # include <unistd.h> | # include <unistd.h> | ||||
| # include <sys/select.h> | # include <sys/select.h> | ||||
| # include <sys/time.h> | |||||
| // # include <sys/time.h> | |||||
| # include <X11/X.h> | # include <X11/X.h> | ||||
| # include <X11/Xatom.h> | # include <X11/Xatom.h> | ||||
| # include <X11/Xlib.h> | # include <X11/Xlib.h> | ||||
| @@ -68,7 +83,7 @@ | |||||
| # include <X11/keysym.h> | # include <X11/keysym.h> | ||||
| # ifdef HAVE_XCURSOR | # ifdef HAVE_XCURSOR | ||||
| # include <X11/Xcursor/Xcursor.h> | # include <X11/Xcursor/Xcursor.h> | ||||
| # include <X11/cursorfont.h> | |||||
| // # include <X11/cursorfont.h> | |||||
| # endif | # endif | ||||
| # ifdef HAVE_XRANDR | # ifdef HAVE_XRANDR | ||||
| # include <X11/extensions/Xrandr.h> | # include <X11/extensions/Xrandr.h> | ||||
| @@ -78,15 +93,12 @@ | |||||
| # include <X11/extensions/syncconst.h> | # include <X11/extensions/syncconst.h> | ||||
| # endif | # endif | ||||
| # ifdef DGL_CAIRO | # ifdef DGL_CAIRO | ||||
| # include <cairo.h> | |||||
| # include <cairo-xlib.h> | # include <cairo-xlib.h> | ||||
| # endif | # endif | ||||
| # ifdef DGL_OPENGL | # ifdef DGL_OPENGL | ||||
| # include <GL/gl.h> | |||||
| # include <GL/glx.h> | # include <GL/glx.h> | ||||
| # endif | # endif | ||||
| # ifdef DGL_VULKAN | # ifdef DGL_VULKAN | ||||
| # include <vulkan/vulkan_core.h> | |||||
| # include <vulkan/vulkan_xlib.h> | # include <vulkan/vulkan_xlib.h> | ||||
| # endif | # endif | ||||
| #endif | #endif | ||||
| @@ -101,6 +113,8 @@ | |||||
| #ifndef DISTRHO_OS_MAC | #ifndef DISTRHO_OS_MAC | ||||
| START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
| #else | |||||
| USE_NAMESPACE_DGL | |||||
| #endif | #endif | ||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -113,9 +127,6 @@ START_NAMESPACE_DGL | |||||
| # define PuglWrapperView DISTRHO_MACOS_NAMESPACE_MACRO(DGL_NAMESPACE, PuglWrapperView) | # define PuglWrapperView DISTRHO_MACOS_NAMESPACE_MACRO(DGL_NAMESPACE, PuglWrapperView) | ||||
| # define PuglWindow DISTRHO_MACOS_NAMESPACE_MACRO(DGL_NAMESPACE, PuglWindow) | # define PuglWindow DISTRHO_MACOS_NAMESPACE_MACRO(DGL_NAMESPACE, PuglWindow) | ||||
| # endif | # endif | ||||
| # ifndef __MAC_10_9 | |||||
| # define NSModalResponseOK NSOKButton | |||||
| # endif | |||||
| # pragma clang diagnostic push | # pragma clang diagnostic push | ||||
| # pragma clang diagnostic ignored "-Wdeprecated-declarations" | # pragma clang diagnostic ignored "-Wdeprecated-declarations" | ||||
| # import "pugl-upstream/src/mac.m" | # import "pugl-upstream/src/mac.m" | ||||
| @@ -159,7 +170,7 @@ START_NAMESPACE_DGL | |||||
| #include "pugl-upstream/src/implementation.c" | #include "pugl-upstream/src/implementation.c" | ||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // expose backend enter | |||||
| // DGL specific, expose backend enter | |||||
| bool puglBackendEnter(PuglView* const view) | bool puglBackendEnter(PuglView* const view) | ||||
| { | { | ||||
| @@ -167,109 +178,39 @@ bool puglBackendEnter(PuglView* const view) | |||||
| } | } | ||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // expose backend leave | |||||
| void puglBackendLeave(PuglView* const view) | |||||
| { | |||||
| view->backend->leave(view, nullptr); | |||||
| } | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // clear minimum size to 0 | |||||
| void puglClearMinSize(PuglView* const view) | |||||
| { | |||||
| view->minWidth = 0; | |||||
| view->minHeight = 0; | |||||
| } | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // missing in pugl, directly returns transient parent | |||||
| // DGL specific, expose backend leave | |||||
| PuglNativeView puglGetTransientParent(const PuglView* const view) | |||||
| bool puglBackendLeave(PuglView* const view) | |||||
| { | { | ||||
| return view->transientParent; | |||||
| return view->backend->leave(view, nullptr) == PUGL_SUCCESS; | |||||
| } | } | ||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // missing in pugl, directly returns title char* pointer | |||||
| // DGL specific, assigns backend that matches current DGL build | |||||
| const char* puglGetWindowTitle(const PuglView* const view) | |||||
| void puglSetMatchingBackendForCurrentBuild(PuglView* const view) | |||||
| { | { | ||||
| return view->title; | |||||
| #ifdef DGL_CAIRO | |||||
| puglSetBackend(view, puglCairoBackend()); | |||||
| #endif | |||||
| #ifdef DGL_OPENGL | |||||
| puglSetBackend(view, puglGlBackend()); | |||||
| #endif | |||||
| #ifdef DGL_VULKAN | |||||
| puglSetBackend(view, puglVulkanBackend()); | |||||
| #endif | |||||
| if (view->backend == nullptr) | |||||
| puglSetBackend(view, puglStubBackend()); | |||||
| } | } | ||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // get global scale factor | |||||
| double puglGetDesktopScaleFactor(const PuglView* const view) | |||||
| { | |||||
| #if defined(DISTRHO_OS_MAC) | |||||
| if (NSWindow* const window = view->impl->window ? view->impl->window | |||||
| : [view->impl->wrapperView window]) | |||||
| return [window screen].backingScaleFactor; | |||||
| return [NSScreen mainScreen].backingScaleFactor; | |||||
| #elif defined(DISTRHO_OS_WINDOWS) | |||||
| if (const HMODULE Shcore = LoadLibraryA("Shcore.dll")) | |||||
| { | |||||
| typedef HRESULT(WINAPI* PFN_GetProcessDpiAwareness)(HANDLE, DWORD*); | |||||
| typedef HRESULT(WINAPI* PFN_GetScaleFactorForMonitor)(HMONITOR, DWORD*); | |||||
| # if defined(__GNUC__) && (__GNUC__ >= 9) | |||||
| # pragma GCC diagnostic push | |||||
| # pragma GCC diagnostic ignored "-Wcast-function-type" | |||||
| # endif | |||||
| const PFN_GetProcessDpiAwareness GetProcessDpiAwareness | |||||
| = (PFN_GetProcessDpiAwareness)GetProcAddress(Shcore, "GetProcessDpiAwareness"); | |||||
| const PFN_GetScaleFactorForMonitor GetScaleFactorForMonitor | |||||
| = (PFN_GetScaleFactorForMonitor)GetProcAddress(Shcore, "GetScaleFactorForMonitor"); | |||||
| # if defined(__GNUC__) && (__GNUC__ >= 9) | |||||
| # pragma GCC diagnostic pop | |||||
| # endif | |||||
| DWORD dpiAware = 0; | |||||
| if (GetProcessDpiAwareness && GetScaleFactorForMonitor | |||||
| && GetProcessDpiAwareness(NULL, &dpiAware) == 0 && dpiAware != 0) | |||||
| { | |||||
| const HMONITOR hMon = MonitorFromWindow(view->impl->hwnd, MONITOR_DEFAULTTOPRIMARY); | |||||
| DWORD scaleFactor = 0; | |||||
| if (GetScaleFactorForMonitor(hMon, &scaleFactor) == 0 && scaleFactor != 0) | |||||
| { | |||||
| FreeLibrary(Shcore); | |||||
| return static_cast<double>(scaleFactor) / 100.0; | |||||
| } | |||||
| } | |||||
| FreeLibrary(Shcore); | |||||
| } | |||||
| #elif defined(HAVE_X11) | |||||
| XrmInitialize(); | |||||
| if (char* const rms = XResourceManagerString(view->world->impl->display)) | |||||
| { | |||||
| if (const XrmDatabase sdb = XrmGetStringDatabase(rms)) | |||||
| { | |||||
| char* type = nullptr; | |||||
| XrmValue ret; | |||||
| if (XrmGetResource(sdb, "Xft.dpi", "String", &type, &ret) | |||||
| && ret.addr != nullptr | |||||
| && type != nullptr | |||||
| && std::strncmp("String", type, 6) == 0) | |||||
| { | |||||
| if (const double dpi = std::atof(ret.addr)) | |||||
| return dpi / 96; | |||||
| } | |||||
| } | |||||
| } | |||||
| #else | |||||
| // unused | |||||
| (void)view; | |||||
| #endif | |||||
| // clear minimum size to 0 | |||||
| return 1.0; | |||||
| } | |||||
| // void puglClearMinSize(PuglView* const view) | |||||
| // { | |||||
| // view->sizeHints[PUGL_MIN_SIZE].width = 0; | |||||
| // view->sizeHints[PUGL_MIN_SIZE].height = 0; | |||||
| // } | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // bring view window into the foreground, aka "raise" window | // bring view window into the foreground, aka "raise" window | ||||
| @@ -284,48 +225,55 @@ void puglRaiseWindow(PuglView* const view) | |||||
| SetForegroundWindow(view->impl->hwnd); | SetForegroundWindow(view->impl->hwnd); | ||||
| SetActiveWindow(view->impl->hwnd); | SetActiveWindow(view->impl->hwnd); | ||||
| #else | #else | ||||
| XRaiseWindow(view->impl->display, view->impl->win); | |||||
| XRaiseWindow(view->world->impl->display, view->impl->win); | |||||
| #endif | #endif | ||||
| } | } | ||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // set backend that matches current build | |||||
| // get scale factor from parent window if possible, fallback to puglGetScaleFactor | |||||
| void puglSetMatchingBackendForCurrentBuild(PuglView* const view) | |||||
| double puglGetScaleFactorFromParent(const PuglView* const view) | |||||
| { | { | ||||
| #ifdef DGL_CAIRO | |||||
| puglSetBackend(view, puglCairoBackend()); | |||||
| #endif | |||||
| #ifdef DGL_OPENGL | |||||
| puglSetBackend(view, puglGlBackend()); | |||||
| #endif | |||||
| #ifdef DGL_VULKAN | |||||
| puglSetBackend(view, puglVulkanBackend()); | |||||
| const PuglNativeView parent = view->parent ? view->parent : view->transientParent ? view->transientParent : 0; | |||||
| #if defined(DISTRHO_OS_MAC) | |||||
| NSWindow* const window = parent != 0 ? [(NSView*)parent window] | |||||
| : view->impl->window ? view->impl->window : [view->impl->wrapperView window]); | |||||
| NSScreen* const screen = window != nullptr ? [window screen] : [NSScreen mainScreen]; | |||||
| return [screen backingScaleFactor]; | |||||
| #elif defined(DISTRHO_OS_WINDOWS) | |||||
| const HWND hwnd = parent != 0 ? (HWND)parent : view->impl->hwnd; | |||||
| return puglWinGetViewScaleFactor(hwnd); | |||||
| #else | |||||
| return puglGetScaleFactor(view); | |||||
| // unused | |||||
| (void)parent; | |||||
| #endif | #endif | ||||
| if (view->backend == nullptr) | |||||
| puglSetBackend(view, puglStubBackend()); | |||||
| } | } | ||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // Combine puglSetMinSize and puglSetAspectRatio | |||||
| // Combined puglSetSizeHint using PUGL_MIN_SIZE and PUGL_FIXED_ASPECT | |||||
| PuglStatus puglSetGeometryConstraints(PuglView* const view, const uint width, const uint height, const bool aspect) | PuglStatus puglSetGeometryConstraints(PuglView* const view, const uint width, const uint height, const bool aspect) | ||||
| { | { | ||||
| view->minWidth = (int)width; | |||||
| view->minHeight = (int)height; | |||||
| if (aspect) { | |||||
| view->minAspectX = (int)width; | |||||
| view->minAspectY = (int)height; | |||||
| view->maxAspectX = (int)width; | |||||
| view->maxAspectY = (int)height; | |||||
| view->sizeHints[PUGL_MIN_SIZE].width = width; | |||||
| view->sizeHints[PUGL_MIN_SIZE].height = height; | |||||
| if (aspect) | |||||
| { | |||||
| view->sizeHints[PUGL_FIXED_ASPECT].width = width; | |||||
| view->sizeHints[PUGL_FIXED_ASPECT].height = height; | |||||
| } | } | ||||
| #if defined(DISTRHO_OS_MAC) | #if defined(DISTRHO_OS_MAC) | ||||
| puglSetMinSize(view, width, height); | |||||
| if (view->impl->window) | |||||
| { | |||||
| PuglStatus status; | |||||
| if ((status = updateSizeHint(view, PUGL_MIN_SIZE)) != PUGL_SUCCESS) | |||||
| return status; | |||||
| if (aspect) { | |||||
| puglSetAspectRatio(view, width, height, width, height); | |||||
| if (aspect && (status = updateSizeHint(view, PUGL_FIXED_ASPECT)) != PUGL_SUCCESS) | |||||
| return status; | |||||
| } | } | ||||
| #elif defined(DISTRHO_OS_WINDOWS) | #elif defined(DISTRHO_OS_WINDOWS) | ||||
| // nothing | // nothing | ||||
| @@ -333,92 +281,90 @@ PuglStatus puglSetGeometryConstraints(PuglView* const view, const uint width, co | |||||
| if (const PuglStatus status = updateSizeHints(view)) | if (const PuglStatus status = updateSizeHints(view)) | ||||
| return status; | return status; | ||||
| XFlush(view->impl->display); | |||||
| XFlush(view->world->impl->display); | |||||
| #endif | #endif | ||||
| return PUGL_SUCCESS; | return PUGL_SUCCESS; | ||||
| } | } | ||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // set window offset without changing size | |||||
| // set view as resizable (or not) during runtime | |||||
| PuglStatus puglSetWindowOffset(PuglView* const view, const int x, const int y) | |||||
| void puglSetResizable(PuglView* const view, const bool resizable) | |||||
| { | { | ||||
| // TODO custom setFrame version | |||||
| PuglRect rect = puglGetFrame(view); | |||||
| rect.x = x; | |||||
| rect.y = y; | |||||
| return puglSetFrame(view, rect); | |||||
| puglSetViewHint(view, PUGL_RESIZABLE, resizable ? PUGL_TRUE : PUGL_FALSE); | |||||
| #if defined(DISTRHO_OS_MAC) | |||||
| if (PuglWindow* const window = view->impl->window) | |||||
| { | |||||
| const uint style = (NSClosableWindowMask | NSTitledWindowMask | NSMiniaturizableWindowMask) | |||||
| | (resizable ? NSResizableWindowMask : 0x0); | |||||
| [window setStyleMask:style]; | |||||
| } | |||||
| // FIXME use [view setAutoresizingMask:NSViewNotSizable] ? | |||||
| #elif defined(DISTRHO_OS_WINDOWS) | |||||
| if (const HWND hwnd = view->impl->hwnd) | |||||
| { | |||||
| const uint winFlags = resizable ? GetWindowLong(hwnd, GWL_STYLE) | (WS_SIZEBOX | WS_MAXIMIZEBOX) | |||||
| : GetWindowLong(hwnd, GWL_STYLE) & ~(WS_SIZEBOX | WS_MAXIMIZEBOX); | |||||
| SetWindowLong(hwnd, GWL_STYLE, winFlags); | |||||
| } | |||||
| #else | |||||
| updateSizeHints(view); | |||||
| #endif | |||||
| } | } | ||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // set window size with default size and without changing frame x/y position | |||||
| // set window size while also changing default | |||||
| PuglStatus puglSetWindowSize(PuglView* const view, const uint width, const uint height) | |||||
| PuglStatus puglSetSizeAndDefault(PuglView* view, uint width, uint height) | |||||
| { | { | ||||
| view->defaultWidth = width; | |||||
| view->defaultHeight = height; | |||||
| view->frame.width = width; | |||||
| view->frame.height = height; | |||||
| if (width > INT16_MAX || height > INT16_MAX) | |||||
| return PUGL_BAD_PARAMETER; | |||||
| view->sizeHints[PUGL_DEFAULT_SIZE].width = view->frame.width = static_cast<PuglSpan>(width); | |||||
| view->sizeHints[PUGL_DEFAULT_SIZE].height = view->frame.height = static_cast<PuglSpan>(height); | |||||
| #if defined(DISTRHO_OS_MAC) | #if defined(DISTRHO_OS_MAC) | ||||
| // replace setFrame with setFrameSize | |||||
| // mostly matches upstream pugl, simplified | |||||
| PuglInternals* const impl = view->impl; | PuglInternals* const impl = view->impl; | ||||
| const PuglRect frame = view->frame; | const PuglRect frame = view->frame; | ||||
| const NSRect framePx = rectToNsRect(frame); | const NSRect framePx = rectToNsRect(frame); | ||||
| const NSRect framePt = nsRectToPoints(view, framePx); | const NSRect framePt = nsRectToPoints(view, framePx); | ||||
| if (impl->window) | |||||
| if (PuglWindow* const window = view->impl->window) | |||||
| { | { | ||||
| // Resize window to fit new content rect | |||||
| const NSRect screenPt = rectToScreen(viewScreen(view), framePt); | const NSRect screenPt = rectToScreen(viewScreen(view), framePt); | ||||
| const NSRect winFrame = [impl->window frameRectForContentRect:screenPt]; | |||||
| [impl->window setFrame:winFrame display:NO]; | |||||
| const NSRect winFrame = [window frameRectForContentRect:screenPt]; | |||||
| [window setFrame:winFrame display:NO]; | |||||
| } | } | ||||
| // Resize views | |||||
| const NSSize sizePx = NSMakeSize(frame.width, frame.height); | const NSSize sizePx = NSMakeSize(frame.width, frame.height); | ||||
| const NSSize sizePt = [impl->drawView convertSizeFromBacking:sizePx]; | const NSSize sizePt = [impl->drawView convertSizeFromBacking:sizePx]; | ||||
| [impl->wrapperView setFrameSize:(impl->window ? sizePt : framePt.size)]; | |||||
| [impl->wrapperView setFrameSize:sizePt]; | |||||
| [impl->drawView setFrameSize:sizePt]; | [impl->drawView setFrameSize:sizePt]; | ||||
| #elif defined(DISTRHO_OS_WINDOWS) | #elif defined(DISTRHO_OS_WINDOWS) | ||||
| // matches upstream pugl, except we add SWP_NOMOVE flag | |||||
| if (view->impl->hwnd) | |||||
| // matches upstream pugl, except we re-enter context after resize | |||||
| if (const HWND hwnd = view->impl->hwnd) | |||||
| { | { | ||||
| const PuglRect frame = view->frame; | |||||
| RECT rect = { (long)frame.x, | |||||
| (long)frame.y, | |||||
| (long)frame.x + (long)frame.width, | |||||
| (long)frame.y + (long)frame.height }; | |||||
| const RECT rect = adjustedWindowRect(view, view->frame.x, view->frame.y, | |||||
| static_cast<long>(width), static_cast<long>(height)); | |||||
| AdjustWindowRectEx(&rect, puglWinGetWindowFlags(view), FALSE, puglWinGetWindowExFlags(view)); | |||||
| if (SetWindowPos(view->impl->hwnd, | |||||
| HWND_TOP, | |||||
| rect.left, | |||||
| rect.top, | |||||
| rect.right - rect.left, | |||||
| rect.bottom - rect.top, | |||||
| SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER)) | |||||
| { | |||||
| // make sure to return context back to ourselves | |||||
| view->backend->enter(view, nullptr); | |||||
| return PUGL_SUCCESS; | |||||
| } | |||||
| if (!SetWindowPos(hwnd, HWND_TOP, 0, 0, rect.right - rect.left, rect.bottom - rect.top, | |||||
| SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE)) | |||||
| return PUGL_UNKNOWN_ERROR; | |||||
| return PUGL_UNKNOWN_ERROR; | |||||
| // make sure to return context back to ourselves | |||||
| puglBackendEnter(view); | |||||
| } | } | ||||
| #else | #else | ||||
| // matches upstream pugl, except we use XResizeWindow instead of XMoveResizeWindow | |||||
| if (view->impl->win) | |||||
| // matches upstream pugl, all in one | |||||
| if (const Window window = view->impl->win) | |||||
| { | { | ||||
| Display* const display = view->impl->display; | |||||
| Display* const display = view->world->impl->display; | |||||
| if (! XResizeWindow(display, view->impl->win, width, height)) | |||||
| if (! XResizeWindow(display, window, width, height)) | |||||
| return PUGL_UNKNOWN_ERROR; | return PUGL_UNKNOWN_ERROR; | ||||
| if (const PuglStatus status = updateSizeHints(view)) | if (const PuglStatus status = updateSizeHints(view)) | ||||
| @@ -456,6 +402,10 @@ void puglFallbackOnResize(PuglView* const view) | |||||
| glViewport(0, 0, static_cast<GLsizei>(view->frame.width), static_cast<GLsizei>(view->frame.height)); | glViewport(0, 0, static_cast<GLsizei>(view->frame.width), static_cast<GLsizei>(view->frame.height)); | ||||
| glMatrixMode(GL_MODELVIEW); | glMatrixMode(GL_MODELVIEW); | ||||
| glLoadIdentity(); | glLoadIdentity(); | ||||
| #else | |||||
| return; | |||||
| // unused | |||||
| (void)view; | |||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -603,67 +553,33 @@ void puglWin32ShowCentered(PuglView* const view) | |||||
| SetFocus(impl->hwnd); | SetFocus(impl->hwnd); | ||||
| } | } | ||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // win32 specific, set or unset WS_SIZEBOX style flag | |||||
| void puglWin32SetWindowResizable(PuglView* const view, const bool resizable) | |||||
| { | |||||
| PuglInternals* impl = view->impl; | |||||
| DISTRHO_SAFE_ASSERT_RETURN(impl->hwnd != nullptr,); | |||||
| const int winFlags = resizable ? GetWindowLong(impl->hwnd, GWL_STYLE) | WS_SIZEBOX | |||||
| : GetWindowLong(impl->hwnd, GWL_STYLE) & ~WS_SIZEBOX; | |||||
| SetWindowLong(impl->hwnd, GWL_STYLE, winFlags); | |||||
| } | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| #elif defined(HAVE_X11) | #elif defined(HAVE_X11) | ||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // X11 specific, safer way to grab focus | |||||
| PuglStatus puglX11GrabFocus(const PuglView* const view) | |||||
| { | |||||
| const PuglInternals* const impl = view->impl; | |||||
| XWindowAttributes wa; | |||||
| std::memset(&wa, 0, sizeof(wa)); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(XGetWindowAttributes(impl->display, impl->win, &wa), PUGL_UNKNOWN_ERROR); | |||||
| if (wa.map_state == IsViewable) | |||||
| { | |||||
| XRaiseWindow(impl->display, impl->win); | |||||
| XSetInputFocus(impl->display, impl->win, RevertToPointerRoot, CurrentTime); | |||||
| XSync(impl->display, False); | |||||
| } | |||||
| return PUGL_SUCCESS; | |||||
| } | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // X11 specific, set dialog window type and pid hints | // X11 specific, set dialog window type and pid hints | ||||
| void puglX11SetWindowTypeAndPID(const PuglView* const view, const bool isStandalone) | void puglX11SetWindowTypeAndPID(const PuglView* const view, const bool isStandalone) | ||||
| { | { | ||||
| const PuglInternals* const impl = view->impl; | |||||
| const PuglInternals* const impl = view->impl; | |||||
| Display* const display = view->world->impl->display; | |||||
| const pid_t pid = getpid(); | const pid_t pid = getpid(); | ||||
| const Atom _nwp = XInternAtom(impl->display, "_NET_WM_PID", False); | |||||
| XChangeProperty(impl->display, impl->win, _nwp, XA_CARDINAL, 32, PropModeReplace, (const uchar*)&pid, 1); | |||||
| const Atom _nwp = XInternAtom(display, "_NET_WM_PID", False); | |||||
| XChangeProperty(display, impl->win, _nwp, XA_CARDINAL, 32, PropModeReplace, (const uchar*)&pid, 1); | |||||
| const Atom _wt = XInternAtom(impl->display, "_NET_WM_WINDOW_TYPE", False); | |||||
| const Atom _wt = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False); | |||||
| Atom _wts[2]; | Atom _wts[2]; | ||||
| int numAtoms = 0; | int numAtoms = 0; | ||||
| if (! isStandalone) | if (! isStandalone) | ||||
| _wts[numAtoms++] = XInternAtom(impl->display, "_NET_WM_WINDOW_TYPE_DIALOG", False); | |||||
| _wts[numAtoms++] = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DIALOG", False); | |||||
| _wts[numAtoms++] = XInternAtom(impl->display, "_NET_WM_WINDOW_TYPE_NORMAL", False); | |||||
| _wts[numAtoms++] = XInternAtom(display, "_NET_WM_WINDOW_TYPE_NORMAL", False); | |||||
| XChangeProperty(impl->display, impl->win, _wt, XA_ATOM, 32, PropModeReplace, (const uchar*)&_wts, numAtoms); | |||||
| XChangeProperty(display, impl->win, _wt, XA_ATOM, 32, PropModeReplace, (const uchar*)&_wts, numAtoms); | |||||
| } | } | ||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -19,7 +19,7 @@ | |||||
| #include "../Base.hpp" | #include "../Base.hpp" | ||||
| /* we will include all header files used in pugl in their C++ friendly form, then pugl stuff in custom namespace */ | |||||
| /* we will include all header files used in pugl.h in their C++ friendly form, then pugl stuff in custom namespace */ | |||||
| #include <cstddef> | #include <cstddef> | ||||
| #ifdef DISTRHO_PROPER_CPP11_SUPPORT | #ifdef DISTRHO_PROPER_CPP11_SUPPORT | ||||
| # include <cstdbool> | # include <cstdbool> | ||||
| @@ -29,75 +29,58 @@ | |||||
| # include <stdint.h> | # include <stdint.h> | ||||
| #endif | #endif | ||||
| // hidden api | |||||
| #define PUGL_API | #define PUGL_API | ||||
| #define PUGL_DISABLE_DEPRECATED | #define PUGL_DISABLE_DEPRECATED | ||||
| #define PUGL_NO_INCLUDE_GL_H | |||||
| #define PUGL_NO_INCLUDE_GLU_H | #define PUGL_NO_INCLUDE_GLU_H | ||||
| // do not set extern "C" | |||||
| // #define __cplusplus_backup __cplusplus | |||||
| // #undef __cplusplus | |||||
| // give warning if defined as something else | |||||
| // #define PUGL_BEGIN_DECLS | |||||
| // #define PUGL_END_DECLS | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| #ifndef DISTRHO_OS_MAC | |||||
| START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
| #else | |||||
| USE_NAMESPACE_DGL | |||||
| #endif | |||||
| #include "pugl-upstream/include/pugl/pugl.h" | #include "pugl-upstream/include/pugl/pugl.h" | ||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| PUGL_BEGIN_DECLS | |||||
| // DGL specific, expose backend enter | |||||
| bool puglBackendEnter(PuglView* view); | |||||
| // expose backend enter | |||||
| PUGL_API bool | |||||
| puglBackendEnter(PuglView* view); | |||||
| // DGL specific, expose backend leave | |||||
| bool puglBackendLeave(PuglView* view); | |||||
| // expose backend leave | |||||
| PUGL_API void | |||||
| puglBackendLeave(PuglView* view); | |||||
| // DGL specific, assigns backend that matches current DGL build | |||||
| void puglSetMatchingBackendForCurrentBuild(PuglView* view); | |||||
| // clear minimum size to 0 | // clear minimum size to 0 | ||||
| PUGL_API void | |||||
| puglClearMinSize(PuglView* view); | |||||
| // missing in pugl, directly returns transient parent | |||||
| PUGL_API PuglNativeView | |||||
| puglGetTransientParent(const PuglView* view); | |||||
| // missing in pugl, directly returns title char* pointer | |||||
| PUGL_API const char* | |||||
| puglGetWindowTitle(const PuglView* view); | |||||
| // get global scale factor | |||||
| PUGL_API double | |||||
| puglGetDesktopScaleFactor(const PuglView* view); | |||||
| void puglClearMinSize(PuglView* view); | |||||
| // bring view window into the foreground, aka "raise" window | // bring view window into the foreground, aka "raise" window | ||||
| PUGL_API void | |||||
| puglRaiseWindow(PuglView* view); | |||||
| void puglRaiseWindow(PuglView* view); | |||||
| // DGL specific, assigns backend that matches current DGL build | |||||
| PUGL_API void | |||||
| puglSetMatchingBackendForCurrentBuild(PuglView* view); | |||||
| // get scale factor from parent window if possible, fallback to puglGetScaleFactor | |||||
| double puglGetScaleFactorFromParent(const PuglView* view); | |||||
| // Combine puglSetMinSize and puglSetAspectRatio | |||||
| PUGL_API PuglStatus | |||||
| puglSetGeometryConstraints(PuglView* view, uint width, uint height, bool aspect); | |||||
| // combined puglSetSizeHint using PUGL_MIN_SIZE, PUGL_MIN_ASPECT and PUGL_MAX_ASPECT | |||||
| PuglStatus puglSetGeometryConstraints(PuglView* view, uint width, uint height, bool aspect); | |||||
| // set window offset without changing size | |||||
| PUGL_API PuglStatus | |||||
| puglSetWindowOffset(PuglView* view, int x, int y); | |||||
| // set view as resizable (or not) during runtime | |||||
| void puglSetResizable(PuglView* view, bool resizable); | |||||
| // set window size with default size and without changing frame x/y position | |||||
| PUGL_API PuglStatus | |||||
| puglSetWindowSize(PuglView* view, uint width, uint height); | |||||
| // set window size while also changing default | |||||
| PuglStatus puglSetSizeAndDefault(PuglView* view, uint width, uint height); | |||||
| // DGL specific, build-specific drawing prepare | // DGL specific, build-specific drawing prepare | ||||
| PUGL_API void | |||||
| puglOnDisplayPrepare(PuglView* view); | |||||
| void puglOnDisplayPrepare(PuglView* view); | |||||
| // DGL specific, build-specific fallback resize | // DGL specific, build-specific fallback resize | ||||
| PUGL_API void | |||||
| puglFallbackOnResize(PuglView* view); | |||||
| void puglFallbackOnResize(PuglView* view); | |||||
| #if defined(DISTRHO_OS_MAC) | #if defined(DISTRHO_OS_MAC) | ||||
| @@ -127,28 +110,18 @@ puglWin32RestoreWindow(PuglView* view); | |||||
| PUGL_API void | PUGL_API void | ||||
| puglWin32ShowCentered(PuglView* view); | puglWin32ShowCentered(PuglView* view); | ||||
| // win32 specific, set or unset WS_SIZEBOX style flag | |||||
| PUGL_API void | |||||
| puglWin32SetWindowResizable(PuglView* view, bool resizable); | |||||
| #elif defined(HAVE_X11) | #elif defined(HAVE_X11) | ||||
| // X11 specific, safer way to grab focus | |||||
| PUGL_API PuglStatus | |||||
| puglX11GrabFocus(const PuglView* view); | |||||
| // X11 specific, set dialog window type and pid hints | // X11 specific, set dialog window type and pid hints | ||||
| PUGL_API void | |||||
| puglX11SetWindowTypeAndPID(const PuglView* view, bool isStandalone); | |||||
| void puglX11SetWindowTypeAndPID(const PuglView* view, bool isStandalone); | |||||
| #endif | #endif | ||||
| PUGL_END_DECLS | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| #ifndef DISTRHO_OS_MAC | |||||
| END_NAMESPACE_DGL | END_NAMESPACE_DGL | ||||
| #endif | |||||
| // #define __cplusplus __cplusplus_backup | |||||
| // #undef __cplusplus_backup | |||||
| #endif // DGL_PUGL_HPP_INCLUDED | #endif // DGL_PUGL_HPP_INCLUDED | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -234,7 +234,7 @@ public: | |||||
| #ifdef DISTRHO_PLUGIN_TARGET_VST3 | #ifdef DISTRHO_PLUGIN_TARGET_VST3 | ||||
| void setSizeForVST3(const uint width, const uint height) | void setSizeForVST3(const uint width, const uint height) | ||||
| { | { | ||||
| puglSetWindowSize(pData->view, width, height); | |||||
| puglSetSizeAndDefault(pData->view, width, height); | |||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -0,0 +1,9 @@ | |||||
| puglClearMinSize needed? | |||||
| clipboard todo | |||||
| puglSetWindowSize was used on first show, still needed? | |||||
| pugl namespace details finalized | |||||
| window starts centered for screen or parent finalized | |||||