Signed-off-by: falkTX <falktx@falktx.com>pull/272/head
| @@ -27,9 +27,9 @@ examples: dgl | |||||
| $(MAKE) all -C examples/Parameters | $(MAKE) all -C examples/Parameters | ||||
| $(MAKE) all -C examples/States | $(MAKE) all -C examples/States | ||||
| ifeq ($(HAVE_CAIRO),true) | |||||
| $(MAKE) all -C examples/CairoUI | |||||
| endif | |||||
| # ifeq ($(HAVE_CAIRO),true) | |||||
| # $(MAKE) all -C examples/CairoUI | |||||
| # endif | |||||
| ifneq ($(MACOS_OR_WINDOWS),true) | ifneq ($(MACOS_OR_WINDOWS),true) | ||||
| # ExternalUI is WIP | # ExternalUI is WIP | ||||
| @@ -301,11 +301,14 @@ public: | |||||
| */ | */ | ||||
| void setAbsolutePos(const Point<int>& pos) noexcept; | void setAbsolutePos(const Point<int>& pos) noexcept; | ||||
| #if 0 | |||||
| // TODO: should we remove this? | |||||
| /** | /** | ||||
| Get this widget's window application. | Get this widget's window application. | ||||
| Same as calling getParentWindow().getApp(). | Same as calling getParentWindow().getApp(). | ||||
| */ | */ | ||||
| Application& getParentApp() const noexcept; | Application& getParentApp() const noexcept; | ||||
| #endif | |||||
| /** | /** | ||||
| Get parent window, as passed in the constructor. | Get parent window, as passed in the constructor. | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2020 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 | ||||
| @@ -77,8 +77,8 @@ public: | |||||
| #endif // DGL_FILE_BROWSER_DISABLED | #endif // DGL_FILE_BROWSER_DISABLED | ||||
| explicit Window(Application& app); | explicit Window(Application& app); | ||||
| explicit Window(Application& app, Window& parent); | |||||
| explicit Window(Application& app, intptr_t parentId, double scaling, bool resizable); | |||||
| explicit Window(Window& transientParentWindow); | |||||
| explicit Window(Application& app, uintptr_t parentWindowHandle, double scaling, bool resizable); | |||||
| virtual ~Window(); | virtual ~Window(); | ||||
| void show(); | void show(); | ||||
| @@ -88,6 +88,7 @@ public: | |||||
| void focus(); | void focus(); | ||||
| void repaint() noexcept; | void repaint() noexcept; | ||||
| void repaint(const Rectangle<uint>& rect) noexcept; | |||||
| #ifndef DGL_FILE_BROWSER_DISABLED | #ifndef DGL_FILE_BROWSER_DISABLED | ||||
| bool openFileBrowser(const FileBrowserOptions& options); | bool openFileBrowser(const FileBrowserOptions& options); | ||||
| @@ -96,10 +97,13 @@ public: | |||||
| bool isEmbed() const noexcept; | bool isEmbed() const noexcept; | ||||
| bool isVisible() const noexcept; | bool isVisible() const noexcept; | ||||
| void setVisible(bool yesNo); | |||||
| void setVisible(bool visible); | |||||
| bool isResizable() const noexcept; | bool isResizable() const noexcept; | ||||
| void setResizable(bool yesNo); | |||||
| void setResizable(bool resizable); | |||||
| bool getIgnoringKeyRepeat() const noexcept; | |||||
| void setIgnoringKeyRepeat(bool ignore) noexcept; | |||||
| uint getWidth() const noexcept; | uint getWidth() const noexcept; | ||||
| uint getHeight() const noexcept; | uint getHeight() const noexcept; | ||||
| @@ -115,11 +119,20 @@ public: | |||||
| double getScaling() const noexcept; | double getScaling() const noexcept; | ||||
| bool getIgnoringKeyRepeat() const noexcept; | |||||
| void setIgnoringKeyRepeat(bool ignore) noexcept; | |||||
| #if 0 | |||||
| // should this be removed? | |||||
| Application& getApp() const noexcept; | Application& getApp() const noexcept; | ||||
| uintptr_t getWindowId() const noexcept; | |||||
| #endif | |||||
| /** | |||||
| Get the "native" window handle. | |||||
| Returned value depends on the platform: | |||||
| - HaikuOS: This is a pointer to a `BView`. | |||||
| - MacOS: This is a pointer to an `NSView*`. | |||||
| - Windows: This is a `HWND`. | |||||
| - Everything else: This is an [X11] `Window`. | |||||
| */ | |||||
| uintptr_t getNativeWindowHandle() const noexcept; | |||||
| const GraphicsContext& getGraphicsContext() const noexcept; | const GraphicsContext& getGraphicsContext() const noexcept; | ||||
| @@ -157,7 +170,16 @@ private: | |||||
| bool handlePluginKeyboard(const bool press, const uint key); | bool handlePluginKeyboard(const bool press, const uint key); | ||||
| bool handlePluginSpecial(const bool press, const Key key); | bool handlePluginSpecial(const bool press, const Key key); | ||||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Window) | |||||
| // Prevent copies | |||||
| #ifdef DISTRHO_PROPER_CPP11_SUPPORT | |||||
| Window& operator=(Window&) = delete; | |||||
| Window& operator=(const Window&) = delete; | |||||
| #else | |||||
| Window& operator=(Window&); | |||||
| Window& operator=(const Window&); | |||||
| #endif | |||||
| DISTRHO_LEAK_DETECTOR(Window); | |||||
| }; | }; | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -35,7 +35,7 @@ void Application::idle() | |||||
| void Application::exec(const uint idleTime) | void Application::exec(const uint idleTime) | ||||
| { | { | ||||
| while (!pData->isQuitting) | |||||
| while (! pData->isQuitting) | |||||
| pData->idle(idleTime); | pData->idle(idleTime); | ||||
| } | } | ||||
| @@ -47,6 +47,8 @@ struct Application::PrivateData { | |||||
| { | { | ||||
| puglSetWorldHandle(world, this); | puglSetWorldHandle(world, this); | ||||
| // puglSetLogLevel(world, PUGL_LOG_LEVEL_DEBUG); | |||||
| // TODO puglSetClassName | // TODO puglSetClassName | ||||
| } | } | ||||
| @@ -58,6 +60,7 @@ struct Application::PrivateData { | |||||
| windows.clear(); | windows.clear(); | ||||
| idleCallbacks.clear(); | idleCallbacks.clear(); | ||||
| d_stdout("calling puglFreeWorld"); | |||||
| puglFreeWorld(world); | puglFreeWorld(world); | ||||
| } | } | ||||
| @@ -27,7 +27,7 @@ START_NAMESPACE_DGL | |||||
| #ifndef DISTRHO_OS_HAIKU | #ifndef DISTRHO_OS_HAIKU | ||||
| ImageAboutWindow::ImageAboutWindow(Window& parent, const Image& image) | ImageAboutWindow::ImageAboutWindow(Window& parent, const Image& image) | ||||
| : Window(parent.getApp(), parent), | |||||
| : Window(parent), | |||||
| Widget((Window&)*this), | Widget((Window&)*this), | ||||
| fImgBackground(image) | fImgBackground(image) | ||||
| { | { | ||||
| @@ -37,7 +37,7 @@ ImageAboutWindow::ImageAboutWindow(Window& parent, const Image& image) | |||||
| } | } | ||||
| ImageAboutWindow::ImageAboutWindow(Widget* widget, const Image& image) | ImageAboutWindow::ImageAboutWindow(Widget* widget, const Image& image) | ||||
| : Window(widget->getParentApp(), widget->getParentWindow()), | |||||
| : Window(widget->getParentWindow()), | |||||
| Widget((Window&)*this), | Widget((Window&)*this), | ||||
| fImgBackground(image) | fImgBackground(image) | ||||
| { | { | ||||
| @@ -179,10 +179,12 @@ void Widget::setAbsolutePos(const Point<int>& pos) noexcept | |||||
| pData->parent.repaint(); | pData->parent.repaint(); | ||||
| } | } | ||||
| #if 0 | |||||
| Application& Widget::getParentApp() const noexcept | Application& Widget::getParentApp() const noexcept | ||||
| { | { | ||||
| return pData->parent.getApp(); | return pData->parent.getApp(); | ||||
| } | } | ||||
| #endif | |||||
| Window& Widget::getParentWindow() const noexcept | Window& Widget::getParentWindow() const noexcept | ||||
| { | { | ||||
| @@ -14,34 +14,27 @@ | |||||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
| */ | */ | ||||
| // we need this for now | |||||
| //#define PUGL_GRAB_FOCUS 1 | |||||
| // #include "../Base.hpp" | |||||
| #include "WindowPrivateData.hpp" | #include "WindowPrivateData.hpp" | ||||
| // #include "../../distrho/extra/String.hpp" | |||||
| START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // Window | // Window | ||||
| Window::Window(Application& app) | Window::Window(Application& app) | ||||
| : pData(new PrivateData(app, this)) {} | |||||
| : pData(new PrivateData(app.pData, this)) {} | |||||
| Window::Window(Application& app, Window& parent) | |||||
| : pData(new PrivateData(app, this, parent)) {} | |||||
| Window::Window(Window& transientParentWindow) | |||||
| : pData(new PrivateData(transientParentWindow.pData->fAppData, this, transientParentWindow)) {} | |||||
| Window::Window(Application& app, intptr_t parentId, double scaling, bool resizable) | |||||
| : pData(new PrivateData(app, this, parentId, scaling, resizable)) {} | |||||
| Window::Window(Application& app, const uintptr_t parentWindowHandle, const double scaling, const bool resizable) | |||||
| : pData(new PrivateData(app.pData, this, parentWindowHandle, scaling, resizable)) {} | |||||
| Window::~Window() | Window::~Window() | ||||
| { | { | ||||
| delete pData; | delete pData; | ||||
| } | } | ||||
| #if 0 | |||||
| void Window::show() | void Window::show() | ||||
| { | { | ||||
| pData->setVisible(true); | pData->setVisible(true); | ||||
| @@ -57,14 +50,19 @@ void Window::close() | |||||
| pData->close(); | pData->close(); | ||||
| } | } | ||||
| #if 0 | |||||
| void Window::exec(bool lockWait) | void Window::exec(bool lockWait) | ||||
| { | { | ||||
| pData->exec(lockWait); | pData->exec(lockWait); | ||||
| } | } | ||||
| #endif | |||||
| void Window::focus() | void Window::focus() | ||||
| { | { | ||||
| pData->focus(); | |||||
| if (! pData->fUsingEmbed) | |||||
| puglRaiseWindow(pData->fView); | |||||
| puglGrabFocus(pData->fView); | |||||
| } | } | ||||
| void Window::repaint() noexcept | void Window::repaint() noexcept | ||||
| @@ -72,6 +70,17 @@ void Window::repaint() noexcept | |||||
| puglPostRedisplay(pData->fView); | puglPostRedisplay(pData->fView); | ||||
| } | } | ||||
| void Window::repaint(const Rectangle<uint>& rect) noexcept | |||||
| { | |||||
| const PuglRect prect = { | |||||
| static_cast<double>(rect.getX()), | |||||
| static_cast<double>(rect.getY()), | |||||
| static_cast<double>(rect.getWidth()), | |||||
| static_cast<double>(rect.getHeight()), | |||||
| }; | |||||
| puglPostRedisplayRect(pData->fView, prect); | |||||
| } | |||||
| bool Window::isEmbed() const noexcept | bool Window::isEmbed() const noexcept | ||||
| { | { | ||||
| return pData->fUsingEmbed; | return pData->fUsingEmbed; | ||||
| @@ -82,88 +91,107 @@ bool Window::isVisible() const noexcept | |||||
| return pData->fVisible; | return pData->fVisible; | ||||
| } | } | ||||
| void Window::setVisible(bool yesNo) | |||||
| void Window::setVisible(const bool visible) | |||||
| { | { | ||||
| pData->setVisible(yesNo); | |||||
| pData->setVisible(visible); | |||||
| } | } | ||||
| bool Window::isResizable() const noexcept | bool Window::isResizable() const noexcept | ||||
| { | { | ||||
| return pData->fResizable; | |||||
| return puglGetViewHint(pData->fView, PUGL_RESIZABLE) == PUGL_TRUE; | |||||
| } | } | ||||
| void Window::setResizable(bool yesNo) | |||||
| void Window::setResizable(const bool resizable) | |||||
| { | { | ||||
| pData->setResizable(yesNo); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(pData->fUsingEmbed,); | |||||
| if (pData->fUsingEmbed) | |||||
| { | |||||
| DGL_DBG("Window setResizable cannot be called when embedded\n"); | |||||
| return; | |||||
| } | |||||
| DGL_DBG("Window setResizable called\n"); | |||||
| puglSetViewHint(pData->fView, PUGL_RESIZABLE, resizable ? PUGL_TRUE : PUGL_FALSE); | |||||
| #ifdef DISTRHO_OS_WINDOWS | |||||
| puglWin32SetWindowResizable(pData->fView, resizable); | |||||
| #endif | |||||
| } | } | ||||
| void Window::setGeometryConstraints(uint width, uint height, bool aspect) | |||||
| bool Window::getIgnoringKeyRepeat() const noexcept | |||||
| { | { | ||||
| pData->setGeometryConstraints(width, height, aspect); | |||||
| return puglGetViewHint(pData->fView, PUGL_IGNORE_KEY_REPEAT) == PUGL_TRUE; | |||||
| } | } | ||||
| uint Window::getWidth() const noexcept | |||||
| void Window::setIgnoringKeyRepeat(const bool ignore) noexcept | |||||
| { | { | ||||
| return pData->fWidth; | |||||
| puglSetViewHint(pData->fView, PUGL_IGNORE_KEY_REPEAT, ignore); | |||||
| } | } | ||||
| uint Window::getHeight() const noexcept | |||||
| void Window::setGeometryConstraints(const uint width, const uint height, bool aspect) | |||||
| { | { | ||||
| return pData->fHeight; | |||||
| // Did you forget to set DISTRHO_UI_USER_RESIZABLE ? | |||||
| DISTRHO_SAFE_ASSERT_RETURN(isResizable(),); | |||||
| puglUpdateGeometryConstraints(pData->fView, width, height, aspect); | |||||
| } | } | ||||
| Size<uint> Window::getSize() const noexcept | |||||
| uint Window::getWidth() const noexcept | |||||
| { | { | ||||
| return Size<uint>(pData->fWidth, pData->fHeight); | |||||
| return puglGetFrame(pData->fView).width; | |||||
| } | } | ||||
| void Window::setSize(uint width, uint height) | |||||
| uint Window::getHeight() const noexcept | |||||
| { | { | ||||
| pData->setSize(width, height); | |||||
| return puglGetFrame(pData->fView).height; | |||||
| } | } | ||||
| void Window::setSize(Size<uint> size) | |||||
| Size<uint> Window::getSize() const noexcept | |||||
| { | { | ||||
| pData->setSize(size.getWidth(), size.getHeight()); | |||||
| const PuglRect rect = puglGetFrame(pData->fView); | |||||
| return Size<uint>(rect.width, rect.height); | |||||
| } | } | ||||
| const char* Window::getTitle() const noexcept | |||||
| void Window::setSize(const uint width, const uint height) | |||||
| { | { | ||||
| return pData->getTitle(); | |||||
| DISTRHO_SAFE_ASSERT_INT2_RETURN(width > 1 && height > 1, width, height,); | |||||
| puglSetWindowSize(pData->fView, width, height); | |||||
| } | } | ||||
| void Window::setTitle(const char* title) | |||||
| void Window::setSize(const Size<uint> size) | |||||
| { | { | ||||
| pData->setTitle(title); | |||||
| setSize(size.getWidth(), size.getHeight()); | |||||
| } | } | ||||
| void Window::setTransientWinId(uintptr_t winId) | |||||
| const char* Window::getTitle() const noexcept | |||||
| { | { | ||||
| pData->setTransientWinId(winId); | |||||
| return puglGetWindowTitle(pData->fView); | |||||
| } | } | ||||
| double Window::getScaling() const noexcept | |||||
| void Window::setTitle(const char* const title) | |||||
| { | { | ||||
| return pData->getScaling(); | |||||
| puglSetWindowTitle(pData->fView, title); | |||||
| } | } | ||||
| bool Window::getIgnoringKeyRepeat() const noexcept | |||||
| void Window::setTransientWinId(const uintptr_t winId) | |||||
| { | { | ||||
| return pData->getIgnoringKeyRepeat(); | |||||
| puglSetTransientFor(pData->fView, winId); | |||||
| } | } | ||||
| void Window::setIgnoringKeyRepeat(bool ignore) noexcept | |||||
| double Window::getScaling() const noexcept | |||||
| { | { | ||||
| pData->setIgnoringKeyRepeat(ignore); | |||||
| return pData->fScaling; | |||||
| } | } | ||||
| #endif | |||||
| #if 0 | |||||
| Application& Window::getApp() const noexcept | Application& Window::getApp() const noexcept | ||||
| { | { | ||||
| return pData->fApp; | return pData->fApp; | ||||
| } | } | ||||
| #endif | |||||
| uintptr_t Window::getWindowId() const noexcept | |||||
| uintptr_t Window::getNativeWindowHandle() const noexcept | |||||
| { | { | ||||
| return puglGetNativeWindow(pData->fView); | return puglGetNativeWindow(pData->fView); | ||||
| } | } | ||||
| @@ -177,10 +205,13 @@ const GraphicsContext& Window::getGraphicsContext() const noexcept | |||||
| #endif | #endif | ||||
| return context; | return context; | ||||
| } | } | ||||
| #endif | |||||
| void Window::_setAutoScaling(double scaling) noexcept | void Window::_setAutoScaling(double scaling) noexcept | ||||
| { | { | ||||
| pData->setAutoScaling(scaling); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(scaling > 0.0,); | |||||
| pData->fAutoScaling = scaling; | |||||
| } | } | ||||
| void Window::_addWidget(Widget* const widget) | void Window::_addWidget(Widget* const widget) | ||||
| @@ -195,9 +226,8 @@ void Window::_removeWidget(Widget* const widget) | |||||
| void Window::_idle() | void Window::_idle() | ||||
| { | { | ||||
| pData->idle(); | |||||
| pData->windowSpecificIdle(); | |||||
| } | } | ||||
| #endif | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -205,14 +235,14 @@ void Window::addIdleCallback(IdleCallback* const callback) | |||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(callback != nullptr,) | DISTRHO_SAFE_ASSERT_RETURN(callback != nullptr,) | ||||
| pData->fApp.pData->idleCallbacks.push_back(callback); | |||||
| pData->fAppData->idleCallbacks.push_back(callback); | |||||
| } | } | ||||
| void Window::removeIdleCallback(IdleCallback* const callback) | void Window::removeIdleCallback(IdleCallback* const callback) | ||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(callback != nullptr,) | DISTRHO_SAFE_ASSERT_RETURN(callback != nullptr,) | ||||
| pData->fApp.pData->idleCallbacks.remove(callback); | |||||
| pData->fAppData->idleCallbacks.remove(callback); | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -242,21 +272,20 @@ void Window::fileBrowserSelected(const char*) | |||||
| } | } | ||||
| #endif | #endif | ||||
| #if 0 | |||||
| bool Window::handlePluginKeyboard(const bool press, const uint key) | bool Window::handlePluginKeyboard(const bool press, const uint key) | ||||
| { | { | ||||
| return pData->handlePluginKeyboard(press, key); | |||||
| // TODO | |||||
| return false; | |||||
| // return pData->handlePluginKeyboard(press, key); | |||||
| } | } | ||||
| bool Window::handlePluginSpecial(const bool press, const Key key) | bool Window::handlePluginSpecial(const bool press, const Key key) | ||||
| { | { | ||||
| return pData->handlePluginSpecial(press, key); | |||||
| // TODO | |||||
| return false; | |||||
| // return pData->handlePluginSpecial(press, key); | |||||
| } | } | ||||
| #endif | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| END_NAMESPACE_DGL | END_NAMESPACE_DGL | ||||
| #undef DBG | |||||
| #undef DBGF | |||||
| @@ -27,6 +27,7 @@ | |||||
| extern "C" { | extern "C" { | ||||
| #include "pugl-upstream/src/implementation.c" | #include "pugl-upstream/src/implementation.c" | ||||
| #include "pugl-extra/extras.c" | |||||
| } | } | ||||
| #if defined(DISTRHO_OS_HAIKU) | #if defined(DISTRHO_OS_HAIKU) | ||||
| @@ -41,18 +42,336 @@ extern "C" { | |||||
| # undef max | # undef max | ||||
| # undef min | # undef min | ||||
| #else | #else | ||||
| # include <sys/types.h> | |||||
| # include <unistd.h> | |||||
| # define DGL_PUGL_USING_X11 | |||||
| extern "C" { | extern "C" { | ||||
| # include "pugl-upstream/src/x11.c" | # include "pugl-upstream/src/x11.c" | ||||
| // # ifdef DGL_CAIRO | |||||
| // # include "pugl-upstream/src/x11_cairo.c" | |||||
| // # endif | |||||
| # ifdef DGL_OPENGL | |||||
| # include "pugl-upstream/src/x11_gl.c" | |||||
| # endif | |||||
| # define PUGL_DETAIL_X11_H_INCLUDED | |||||
| # include "pugl-extra/x11.c" | |||||
| } | } | ||||
| #endif | #endif | ||||
| #include <inttypes.h> | |||||
| #include <stdarg.h> | |||||
| #include <stdbool.h> | |||||
| #include <stdint.h> | |||||
| #include <stdio.h> | |||||
| #include <string.h> | |||||
| START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| void DGL::Window::PrivateData::Fallback::onDisplayBefore() | |||||
| void Window::PrivateData::init(const bool resizable) | |||||
| { | |||||
| if (fSelf == nullptr || fView == nullptr) | |||||
| { | |||||
| DGL_DBG("Failed!\n"); | |||||
| return; | |||||
| } | |||||
| // #ifdef DGL_CAIRO | |||||
| // puglSetBackend(fView, puglCairoBackend()); | |||||
| // #endif | |||||
| #ifdef DGL_OPENGL | |||||
| puglSetBackend(fView, puglGlBackend()); | |||||
| #endif | |||||
| puglSetHandle(fView, this); | |||||
| puglSetViewHint(fView, PUGL_RESIZABLE, resizable ? PUGL_TRUE : PUGL_FALSE); | |||||
| puglSetViewHint(fView, PUGL_IGNORE_KEY_REPEAT, PUGL_FALSE); | |||||
| puglSetEventFunc(fView, puglEventCallback); | |||||
| // #ifndef DGL_FILE_BROWSER_DISABLED | |||||
| // puglSetFileSelectedFunc(fView, fileBrowserSelectedCallback); | |||||
| // #endif | |||||
| fAppData->windows.push_back(fSelf); | |||||
| DGL_DBG("Success!\n"); | |||||
| } | |||||
| void Window::PrivateData::setVisible(const bool visible) | |||||
| { | |||||
| if (fVisible == visible) | |||||
| { | |||||
| DGL_DBG("Window setVisible matches current state, ignoring request\n"); | |||||
| return; | |||||
| } | |||||
| if (fUsingEmbed) | |||||
| { | |||||
| DGL_DBG("Window setVisible cannot be called when embedded\n"); | |||||
| return; | |||||
| } | |||||
| DGL_DBG("Window setVisible called\n"); | |||||
| fVisible = visible; | |||||
| if (visible) | |||||
| { | |||||
| #if 0 && defined(DISTRHO_OS_MAC) | |||||
| if (mWindow != nullptr) | |||||
| { | |||||
| if (mParentWindow != nullptr) | |||||
| [mParentWindow addChildWindow:mWindow | |||||
| ordered:NSWindowAbove]; | |||||
| } | |||||
| #endif | |||||
| if (fFirstInit) | |||||
| { | |||||
| puglRealize(fView); | |||||
| #ifdef DISTRHO_OS_WINDOWS | |||||
| puglShowWindowCentered(fView); | |||||
| #else | |||||
| puglShowWindow(fView); | |||||
| #endif | |||||
| fAppData->oneWindowShown(); | |||||
| fFirstInit = false; | |||||
| } | |||||
| else | |||||
| { | |||||
| #ifdef DISTRHO_OS_WINDOWS | |||||
| puglWin32RestoreWindow(fView); | |||||
| #else | |||||
| puglShowWindow(fView); | |||||
| #endif | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| #if 0 && defined(DISTRHO_OS_MAC) | |||||
| if (mWindow != nullptr) | |||||
| { | |||||
| if (mParentWindow != nullptr) | |||||
| [mParentWindow removeChildWindow:mWindow]; | |||||
| } | |||||
| #endif | |||||
| puglHideWindow(fView); | |||||
| // if (fModal.enabled) | |||||
| // exec_fini(); | |||||
| } | |||||
| } | |||||
| void Window::PrivateData::windowSpecificIdle() | |||||
| { | |||||
| #if defined(DISTRHO_OS_WINDOWS) && !defined(DGL_FILE_BROWSER_DISABLED) | |||||
| if (fSelectedFile.isNotEmpty()) | |||||
| { | |||||
| char* const buffer = fSelectedFile.getAndReleaseBuffer(); | |||||
| fView->fileSelectedFunc(fView, buffer); | |||||
| std::free(buffer); | |||||
| } | |||||
| #endif | |||||
| if (fModal.enabled && fModal.parent != nullptr) | |||||
| fModal.parent->windowSpecificIdle(); | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| static inline int | |||||
| printModifiers(const uint32_t mods) | |||||
| { | |||||
| return fprintf(stderr, "Modifiers:%s%s%s%s\n", | |||||
| (mods & PUGL_MOD_SHIFT) ? " Shift" : "", | |||||
| (mods & PUGL_MOD_CTRL) ? " Ctrl" : "", | |||||
| (mods & PUGL_MOD_ALT) ? " Alt" : "", | |||||
| (mods & PUGL_MOD_SUPER) ? " Super" : ""); | |||||
| } | |||||
| static inline int | |||||
| printEvent(const PuglEvent* event, const char* prefix, const bool verbose) | |||||
| { | |||||
| #define FFMT "%6.1f" | |||||
| #define PFMT FFMT " " FFMT | |||||
| #define PRINT(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) | |||||
| switch (event->type) { | |||||
| case PUGL_NOTHING: | |||||
| return 0; | |||||
| case PUGL_KEY_PRESS: | |||||
| return PRINT("%sKey press code %3u key U+%04X\n", | |||||
| prefix, | |||||
| event->key.keycode, | |||||
| event->key.key); | |||||
| case PUGL_KEY_RELEASE: | |||||
| return PRINT("%sKey release code %3u key U+%04X\n", | |||||
| prefix, | |||||
| event->key.keycode, | |||||
| event->key.key); | |||||
| case PUGL_TEXT: | |||||
| return PRINT("%sText entry code %3u char U+%04X (%s)\n", | |||||
| prefix, | |||||
| event->text.keycode, | |||||
| event->text.character, | |||||
| event->text.string); | |||||
| case PUGL_BUTTON_PRESS: | |||||
| case PUGL_BUTTON_RELEASE: | |||||
| return (PRINT("%sMouse %u %s at " PFMT " ", | |||||
| prefix, | |||||
| event->button.button, | |||||
| (event->type == PUGL_BUTTON_PRESS) ? "down" : "up ", | |||||
| event->button.x, | |||||
| event->button.y) + | |||||
| printModifiers(event->scroll.state)); | |||||
| case PUGL_SCROLL: | |||||
| return (PRINT("%sScroll %5.1f %5.1f at " PFMT " ", | |||||
| prefix, | |||||
| event->scroll.dx, | |||||
| event->scroll.dy, | |||||
| event->scroll.x, | |||||
| event->scroll.y) + | |||||
| printModifiers(event->scroll.state)); | |||||
| case PUGL_POINTER_IN: | |||||
| return PRINT("%sMouse enter at " PFMT "\n", | |||||
| prefix, | |||||
| event->crossing.x, | |||||
| event->crossing.y); | |||||
| case PUGL_POINTER_OUT: | |||||
| return PRINT("%sMouse leave at " PFMT "\n", | |||||
| prefix, | |||||
| event->crossing.x, | |||||
| event->crossing.y); | |||||
| case PUGL_FOCUS_IN: | |||||
| return PRINT("%sFocus in %i\n", | |||||
| prefix, | |||||
| event->focus.mode); | |||||
| case PUGL_FOCUS_OUT: | |||||
| return PRINT("%sFocus out %i\n", | |||||
| prefix, | |||||
| event->focus.mode); | |||||
| case PUGL_CLIENT: | |||||
| return PRINT("%sClient %" PRIXPTR " %" PRIXPTR "\n", | |||||
| prefix, | |||||
| event->client.data1, | |||||
| event->client.data2); | |||||
| case PUGL_TIMER: | |||||
| return PRINT("%sTimer %" PRIuPTR "\n", prefix, event->timer.id); | |||||
| default: | |||||
| break; | |||||
| } | |||||
| if (verbose) { | |||||
| switch (event->type) { | |||||
| case PUGL_CREATE: | |||||
| return fprintf(stderr, "%sCreate\n", prefix); | |||||
| case PUGL_DESTROY: | |||||
| return fprintf(stderr, "%sDestroy\n", prefix); | |||||
| case PUGL_MAP: | |||||
| return fprintf(stderr, "%sMap\n", prefix); | |||||
| case PUGL_UNMAP: | |||||
| return fprintf(stderr, "%sUnmap\n", prefix); | |||||
| case PUGL_UPDATE: | |||||
| return fprintf(stderr, "%sUpdate\n", prefix); | |||||
| case PUGL_CONFIGURE: | |||||
| return PRINT("%sConfigure " PFMT " " PFMT "\n", | |||||
| prefix, | |||||
| event->configure.x, | |||||
| event->configure.y, | |||||
| event->configure.width, | |||||
| event->configure.height); | |||||
| case PUGL_EXPOSE: | |||||
| return PRINT("%sExpose " PFMT " " PFMT "\n", | |||||
| prefix, | |||||
| event->expose.x, | |||||
| event->expose.y, | |||||
| event->expose.width, | |||||
| event->expose.height); | |||||
| case PUGL_CLOSE: | |||||
| return PRINT("%sClose\n", prefix); | |||||
| case PUGL_MOTION: | |||||
| return PRINT("%sMouse motion at " PFMT "\n", | |||||
| prefix, | |||||
| event->motion.x, | |||||
| event->motion.y); | |||||
| default: | |||||
| return PRINT("%sUnknown event type %d\n", prefix, (int)event->type); | |||||
| } | |||||
| } | |||||
| #undef PRINT | |||||
| #undef PFMT | |||||
| #undef FFMT | |||||
| return 0; | |||||
| } | |||||
| PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const PuglEvent* const event) | |||||
| { | |||||
| printEvent(event, "", true); | |||||
| Window::PrivateData* const pData = (Window::PrivateData*)puglGetHandle(view); | |||||
| switch (event->type) | |||||
| { | |||||
| ///< No event | |||||
| case PUGL_NOTHING: | |||||
| break; | |||||
| ///< View created, a #PuglEventCreate | |||||
| case PUGL_CREATE: | |||||
| #ifdef DGL_PUGL_USING_X11 | |||||
| if (! pData->fUsingEmbed) | |||||
| puglExtraSetWindowTypeAndPID(view); | |||||
| #endif | |||||
| break; | |||||
| ///< View destroyed, a #PuglEventDestroy | |||||
| case PUGL_DESTROY: | |||||
| break; | |||||
| ///< View moved/resized, a #PuglEventConfigure | |||||
| case PUGL_CONFIGURE: | |||||
| pData->onPuglReshape(event->configure.width, event->configure.height); | |||||
| break; | |||||
| case PUGL_MAP: ///< View made visible, a #PuglEventMap | |||||
| case PUGL_UNMAP: ///< View made invisible, a #PuglEventUnmap | |||||
| break; | |||||
| ///< View ready to draw, a #PuglEventUpdate | |||||
| case PUGL_UPDATE: | |||||
| break; | |||||
| ///< View must be drawn, a #PuglEventExpose | |||||
| case PUGL_EXPOSE: | |||||
| pData->onPuglDisplay(); | |||||
| break; | |||||
| ///< View will be closed, a #PuglEventClose | |||||
| case PUGL_CLOSE: | |||||
| pData->onPuglClose(); | |||||
| break; | |||||
| case PUGL_FOCUS_IN: ///< Keyboard focus entered view, a #PuglEventFocus | |||||
| case PUGL_FOCUS_OUT: ///< Keyboard focus left view, a #PuglEventFocus | |||||
| case PUGL_KEY_PRESS: ///< Key pressed, a #PuglEventKey | |||||
| case PUGL_KEY_RELEASE: ///< Key released, a #PuglEventKey | |||||
| case PUGL_TEXT: ///< Character entered, a #PuglEventText | |||||
| case PUGL_POINTER_IN: ///< Pointer entered view, a #PuglEventCrossing | |||||
| case PUGL_POINTER_OUT: ///< Pointer left view, a #PuglEventCrossing | |||||
| case PUGL_BUTTON_PRESS: ///< Mouse button pressed, a #PuglEventButton | |||||
| case PUGL_BUTTON_RELEASE: ///< Mouse button released, a #PuglEventButton | |||||
| case PUGL_MOTION: ///< Pointer moved, a #PuglEventMotion | |||||
| case PUGL_SCROLL: ///< Scrolled, a #PuglEventScroll | |||||
| case PUGL_CLIENT: ///< Custom client message, a #PuglEventClient | |||||
| case PUGL_TIMER: ///< Timer triggered, a #PuglEventTimer | |||||
| break; | |||||
| } | |||||
| return PUGL_SUCCESS; | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| void Window::PrivateData::Fallback::onDisplayBefore() | |||||
| { | { | ||||
| #ifdef DGL_OPENGL | #ifdef DGL_OPENGL | ||||
| glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||||
| @@ -60,11 +379,11 @@ void DGL::Window::PrivateData::Fallback::onDisplayBefore() | |||||
| #endif | #endif | ||||
| } | } | ||||
| void DGL::Window::PrivateData::Fallback::onDisplayAfter() | |||||
| void Window::PrivateData::Fallback::onDisplayAfter() | |||||
| { | { | ||||
| } | } | ||||
| void DGL::Window::PrivateData::Fallback::onReshape(const uint width, const uint height) | |||||
| void Window::PrivateData::Fallback::onReshape(const uint width, const uint height) | |||||
| { | { | ||||
| #ifdef DGL_OPENGL | #ifdef DGL_OPENGL | ||||
| glEnable(GL_BLEND); | glEnable(GL_BLEND); | ||||
| @@ -0,0 +1,29 @@ | |||||
| /* | |||||
| Copyright (C) 2012-2020 Filipe Coelho <falktx@falktx.com> | |||||
| 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 permission notice appear in all copies. | |||||
| THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |||||
| WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |||||
| MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |||||
| ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||||
| WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |||||
| ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |||||
| OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||||
| */ | |||||
| /** | |||||
| @file extras.c pugl extra implementations for DPF. | |||||
| */ | |||||
| #include "extras.h" | |||||
| #include "../pugl-upstream/src/implementation.h" | |||||
| const char* | |||||
| puglGetWindowTitle(const PuglView* view) | |||||
| { | |||||
| return view->title; | |||||
| } | |||||
| @@ -0,0 +1,50 @@ | |||||
| /* | |||||
| Copyright (C) 2012-2020 Filipe Coelho <falktx@falktx.com> | |||||
| 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 permission notice appear in all copies. | |||||
| THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |||||
| WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |||||
| MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |||||
| ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||||
| WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |||||
| ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |||||
| OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||||
| */ | |||||
| /** | |||||
| @file pugl.h pugl extra API for DPF. | |||||
| */ | |||||
| #ifndef PUGL_EXTRAS_PUGL_H | |||||
| #define PUGL_EXTRAS_PUGL_H | |||||
| #include "../pugl-upstream/include/pugl/pugl.h" | |||||
| PUGL_BEGIN_DECLS | |||||
| PUGL_API const char* | |||||
| puglGetWindowTitle(const PuglView* view); | |||||
| PUGL_API int | |||||
| puglGetViewHint(const PuglView* view, PuglViewHint hint); | |||||
| PUGL_API void | |||||
| puglRaiseWindow(PuglView* view); | |||||
| PUGL_API void | |||||
| puglSetWindowSize(PuglView* view, unsigned int width, unsigned int height); | |||||
| PUGL_API void | |||||
| puglUpdateGeometryConstraints(PuglView* view, unsigned int width, unsigned int height, bool aspect); | |||||
| #ifdef DISTRHO_OS_WINDOWS | |||||
| PUGL_API void | |||||
| puglWin32SetWindowResizable(PuglView* view, bool resizable); | |||||
| #endif | |||||
| PUGL_END_DECLS | |||||
| #endif // PUGL_EXTRAS_PUGL_H | |||||
| @@ -0,0 +1,81 @@ | |||||
| /* | |||||
| Copyright 2012-2019 David Robillard <http://drobilla.net> | |||||
| Copyright 2019-2020 Filipe Coelho <falktx@falktx.com> | |||||
| 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 permission notice appear in all copies. | |||||
| THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |||||
| WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |||||
| MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |||||
| ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||||
| WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |||||
| ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |||||
| OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||||
| */ | |||||
| /** | |||||
| @file mac.cpp HaikuOS implementation. | |||||
| */ | |||||
| #include "haiku.h" | |||||
| #include "pugl/detail/implementation.h" | |||||
| PuglStatus | |||||
| puglGrabFocus(PuglView* view) | |||||
| { | |||||
| view->impl->bView->MakeFocus(true); | |||||
| return PUGL_SUCCESS; | |||||
| } | |||||
| // extras follow | |||||
| void | |||||
| puglRaiseWindow(PuglView* view) | |||||
| { | |||||
| } | |||||
| void | |||||
| puglSetWindowSize(PuglView* view, unsigned int width, unsigned int height) | |||||
| { | |||||
| bView->ResizeTo(width, height); | |||||
| if (bWindow != nullptr && bWindow->LockLooper()) | |||||
| { | |||||
| bWindow->MoveTo(50, 50); | |||||
| bWindow->ResizeTo(width, height); | |||||
| if (! forced) | |||||
| bWindow->Flush(); | |||||
| bWindow->UnlockLooper(); | |||||
| } | |||||
| // TODO resizable | |||||
| } | |||||
| void setVisible(const bool yesNo) | |||||
| { | |||||
| if (bWindow != nullptr) | |||||
| { | |||||
| if (bWindow->LockLooper()) | |||||
| { | |||||
| if (yesNo) | |||||
| bWindow->Show(); | |||||
| else | |||||
| bWindow->Hide(); | |||||
| // TODO use flush? | |||||
| bWindow->Sync(); | |||||
| bWindow->UnlockLooper(); | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| if (yesNo) | |||||
| bView->Show(); | |||||
| else | |||||
| bView->Hide(); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,35 @@ | |||||
| /* | |||||
| Copyright 2012-2019 David Robillard <http://drobilla.net> | |||||
| Copyright 2019-2020 Filipe Coelho <falktx@falktx.com> | |||||
| 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 permission notice appear in all copies. | |||||
| THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |||||
| WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |||||
| MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |||||
| ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||||
| WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |||||
| ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |||||
| OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||||
| */ | |||||
| /** | |||||
| @file haiku.h Shared definitions for HaikuOS implementation. | |||||
| */ | |||||
| #include "pugl/pugl.h" | |||||
| #include <Application.h> | |||||
| #include <Window.h> | |||||
| // using? interface/ | |||||
| struct PuglWorldInternalsImpl { | |||||
| BApplication* app; | |||||
| }; | |||||
| struct PuglInternalsImpl { | |||||
| BViewType* view; | |||||
| BWindow* window; | |||||
| }; | |||||
| @@ -0,0 +1,48 @@ | |||||
| /* | |||||
| Copyright (C) 2012-2020 Filipe Coelho <falktx@falktx.com> | |||||
| 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 permission notice appear in all copies. | |||||
| THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |||||
| WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |||||
| MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |||||
| ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||||
| WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |||||
| ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |||||
| OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||||
| */ | |||||
| /** | |||||
| @file mac.m MacOS extra implementation for DPF. | |||||
| */ | |||||
| #include "pugl/detail/mac.h" | |||||
| void | |||||
| puglRaiseWindow(PuglView* view) | |||||
| { | |||||
| } | |||||
| void | |||||
| puglSetWindowSize(PuglView* view, unsigned int width, unsigned int height) | |||||
| { | |||||
| // NOTE: pugl mac code does nothing with x and y | |||||
| const PuglRect frame = { 0.0, 0.0, (double)width, (double)height }; | |||||
| puglSetFrame(view, frame); | |||||
| } | |||||
| void | |||||
| puglUpdateGeometryConstraints(PuglView* view, unsigned int width, unsigned int height, bool aspect) | |||||
| { | |||||
| // NOTE this is a combination of puglSetMinSize and puglSetAspectRatio | |||||
| view->minWidth = width; | |||||
| view->minHeight = height; | |||||
| [view->impl->window setContentMinSize:sizePoints(view, width, height)]; | |||||
| if (aspect) { | |||||
| [view->impl->window setContentAspectRatio:sizePoints(view, width, height)]; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,118 @@ | |||||
| /* | |||||
| Copyright (C) 2012-2020 Filipe Coelho <falktx@falktx.com> | |||||
| 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 permission notice appear in all copies. | |||||
| THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |||||
| WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |||||
| MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |||||
| ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||||
| WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |||||
| ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |||||
| OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||||
| */ | |||||
| /** | |||||
| @file win.c Windows extra implementation for DPF. | |||||
| */ | |||||
| #include "pugl/detail/win.h" | |||||
| #include "pugl/detail/implementation.h" | |||||
| void | |||||
| puglRaiseWindow(PuglView* view) | |||||
| { | |||||
| SetForegroundWindow(view->impl->hwnd); | |||||
| SetActiveWindow(view->impl->hwnd); | |||||
| return PUGL_SUCCESS; | |||||
| } | |||||
| void | |||||
| puglSetWindowSize(PuglView* view, unsigned int width, unsigned int height) | |||||
| { | |||||
| view->frame.width = width; | |||||
| view->frame.height = height; | |||||
| // NOTE the following code matches upstream pugl, except we add SWP_NOMOVE flag | |||||
| if (view->impl->hwnd) { | |||||
| RECT rect = { (long)frame.x, | |||||
| (long)frame.y, | |||||
| (long)frame.x + (long)frame.width, | |||||
| (long)frame.y + (long)frame.height }; | |||||
| AdjustWindowRectEx(&rect, puglWinGetWindowFlags(view), | |||||
| FALSE, | |||||
| puglWinGetWindowExFlags(view)); | |||||
| 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); | |||||
| } | |||||
| } | |||||
| void | |||||
| puglUpdateGeometryConstraints(PuglView* view, unsigned int width, unsigned int height, bool aspect) | |||||
| { | |||||
| // NOTE this is a combination of puglSetMinSize and puglSetAspectRatio, but stilL TODO on pugl | |||||
| Display* display = view->world->impl->display; | |||||
| view->minWidth = width; | |||||
| view->minHeight = height; | |||||
| if (aspect) { | |||||
| view->minAspectX = width; | |||||
| view->minAspectY = height; | |||||
| view->maxAspectX = width; | |||||
| view->maxAspectY = height; | |||||
| } | |||||
| } | |||||
| void | |||||
| puglWin32RestoreWindow(PuglView* view) | |||||
| { | |||||
| PuglInternals* impl = view->impl; | |||||
| ShowWindow(impl->hwnd, SW_RESTORE); | |||||
| SetFocus(impl->hwnd); | |||||
| } | |||||
| void | |||||
| puglWin32ShowWindowCentered(PuglView* view) | |||||
| { | |||||
| PuglInternals* impl = view->impl; | |||||
| RECT rectChild, rectParent; | |||||
| if (impl->transientParent != 0 && | |||||
| GetWindowRect(impl->hwnd, &rectChild) && | |||||
| GetWindowRect(impl->transientParent, &rectParent)) | |||||
| { | |||||
| SetWindowPos(impl->hwnd, (HWND)impl->transientParent, | |||||
| rectParent.left + (rectChild.right-rectChild.left)/2, | |||||
| rectParent.top + (rectChild.bottom-rectChild.top)/2, | |||||
| 0, 0, SWP_SHOWWINDOW|SWP_NOSIZE); | |||||
| } | |||||
| else | |||||
| { | |||||
| ShowWindow(hwnd, SW_SHOWNORMAL); | |||||
| } | |||||
| SetFocus(impl->hwnd); | |||||
| } | |||||
| void | |||||
| puglWin32SetWindowResizable(PuglView* view, bool resizable) | |||||
| { | |||||
| PuglInternals* impl = view->impl; | |||||
| const int winFlags = resizable ? GetWindowLong(hwnd, GWL_STYLE) | WS_SIZEBOX | |||||
| : GetWindowLong(hwnd, GWL_STYLE) & ~WS_SIZEBOX; | |||||
| SetWindowLong(impl->hwnd, GWL_STYLE, winFlags); | |||||
| } | |||||
| @@ -0,0 +1,111 @@ | |||||
| /* | |||||
| Copyright (C) 2012-2020 Filipe Coelho <falktx@falktx.com> | |||||
| 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 permission notice appear in all copies. | |||||
| THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |||||
| WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |||||
| MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |||||
| ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||||
| WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |||||
| ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |||||
| OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||||
| */ | |||||
| /** | |||||
| @file x11.c X11 extra implementation for DPF. | |||||
| */ | |||||
| // NOTE can't import this file twice! | |||||
| #ifndef PUGL_DETAIL_X11_H_INCLUDED | |||||
| #include "../pugl-upstream/src/x11.h" | |||||
| #endif | |||||
| #include "../pugl-upstream/src/implementation.h" | |||||
| #include <sys/types.h> | |||||
| #include <unistd.h> | |||||
| void | |||||
| puglRaiseWindow(PuglView* view) | |||||
| { | |||||
| XRaiseWindow(view->impl->display, view->impl->win); | |||||
| } | |||||
| void | |||||
| puglSetWindowSize(PuglView* view, unsigned int width, unsigned int height) | |||||
| { | |||||
| view->frame.width = width; | |||||
| view->frame.height = height; | |||||
| if (view->impl->win) { | |||||
| #if 0 | |||||
| if (! fResizable) | |||||
| { | |||||
| XSizeHints sizeHints; | |||||
| memset(&sizeHints, 0, sizeof(sizeHints)); | |||||
| sizeHints.flags = PSize|PMinSize|PMaxSize; | |||||
| sizeHints.width = static_cast<int>(width); | |||||
| sizeHints.height = static_cast<int>(height); | |||||
| sizeHints.min_width = static_cast<int>(width); | |||||
| sizeHints.min_height = static_cast<int>(height); | |||||
| sizeHints.max_width = static_cast<int>(width); | |||||
| sizeHints.max_height = static_cast<int>(height); | |||||
| XSetWMNormalHints(xDisplay, xWindow, &sizeHints); | |||||
| } | |||||
| #endif | |||||
| XResizeWindow(view->world->impl->display, view->impl->win, width, height); | |||||
| } | |||||
| } | |||||
| void | |||||
| puglUpdateGeometryConstraints(PuglView* view, unsigned int width, unsigned int height, bool aspect) | |||||
| { | |||||
| // NOTE this is a combination of puglSetMinSize and puglSetAspectRatio | |||||
| Display* display = view->world->impl->display; | |||||
| view->minWidth = width; | |||||
| view->minHeight = height; | |||||
| if (aspect) { | |||||
| view->minAspectX = width; | |||||
| view->minAspectY = height; | |||||
| view->maxAspectX = width; | |||||
| view->maxAspectY = height; | |||||
| } | |||||
| #if 0 | |||||
| if (view->impl->win) { | |||||
| XSizeHints sizeHints = getSizeHints(view); | |||||
| XSetNormalHints(display, view->impl->win, &sizeHints); | |||||
| // NOTE old code used this instead | |||||
| // XSetWMNormalHints(display, view->impl->win, &sizeHints); | |||||
| } | |||||
| #endif | |||||
| } | |||||
| void | |||||
| puglExtraSetWindowTypeAndPID(PuglView* view) | |||||
| { | |||||
| PuglInternals* const impl = view->impl; | |||||
| 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 _wt = XInternAtom(impl->display, "_NET_WM_WINDOW_TYPE", False); | |||||
| // Setting the window to both dialog and normal will produce a decorated floating dialog | |||||
| // Order is important: DIALOG needs to come before NORMAL | |||||
| const Atom _wts[2] = { | |||||
| XInternAtom(impl->display, "_NET_WM_WINDOW_TYPE_DIALOG", False), | |||||
| XInternAtom(impl->display, "_NET_WM_WINDOW_TYPE_NORMAL", False) | |||||
| }; | |||||
| XChangeProperty(impl->display, impl->win, _wt, XA_ATOM, 32, PropModeReplace, (const uchar*)&_wts, 2); | |||||
| } | |||||
| @@ -22,6 +22,7 @@ | |||||
| #endif | #endif | ||||
| #if DISTRHO_PLUGIN_HAS_UI | #if DISTRHO_PLUGIN_HAS_UI | ||||
| # define DISTRHO_UI_IS_STANDALONE 0 | |||||
| # include "DistrhoUIInternal.hpp" | # include "DistrhoUIInternal.hpp" | ||||
| #endif | #endif | ||||
| @@ -38,7 +38,6 @@ Window* d_lastUiWindow = nullptr; | |||||
| // ----------------------------------------------------------------------------------------------------------- | // ----------------------------------------------------------------------------------------------------------- | ||||
| #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | ||||
| static inline | |||||
| UI* createUiWrapper(void* const dspPtr, const uintptr_t winId, const double scaleFactor, const char* const bundlePath) | UI* createUiWrapper(void* const dspPtr, const uintptr_t winId, const double scaleFactor, const char* const bundlePath) | ||||
| { | { | ||||
| d_lastUiDspPtr = dspPtr; | d_lastUiDspPtr = dspPtr; | ||||
| @@ -53,7 +52,6 @@ UI* createUiWrapper(void* const dspPtr, const uintptr_t winId, const double scal | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| #else | #else | ||||
| static inline | |||||
| UI* createUiWrapper(void* const dspPtr, Window* const window) | UI* createUiWrapper(void* const dspPtr, Window* const window) | ||||
| { | { | ||||
| d_lastUiDspPtr = dspPtr; | d_lastUiDspPtr = dspPtr; | ||||
| @@ -14,6 +14,7 @@ | |||||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
| */ | */ | ||||
| #define DISTRHO_UI_IS_STANDALONE 1 | |||||
| #include "DistrhoUIInternal.hpp" | #include "DistrhoUIInternal.hpp" | ||||
| #if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS | #if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS | ||||
| @@ -203,7 +203,7 @@ public: | |||||
| return fUI->isRunning(); | return fUI->isRunning(); | ||||
| } | } | ||||
| intptr_t getWindowId() const noexcept | |||||
| uintptr_t getNativeWindowHandle() const noexcept | |||||
| { | { | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -223,9 +223,9 @@ public: | |||||
| return glWindow.isVisible(); | return glWindow.isVisible(); | ||||
| } | } | ||||
| intptr_t getWindowId() const noexcept | |||||
| uintptr_t getNativeWindowHandle() const noexcept | |||||
| { | { | ||||
| return glWindow.getWindowId(); | |||||
| return glWindow.getNativeWindowHandle(); | |||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -14,6 +14,7 @@ | |||||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
| */ | */ | ||||
| #define DISTRHO_UI_IS_STANDALONE 0 | |||||
| #include "DistrhoUIInternal.hpp" | #include "DistrhoUIInternal.hpp" | ||||
| #include "../extra/String.hpp" | #include "../extra/String.hpp" | ||||
| @@ -100,7 +101,7 @@ public: | |||||
| fUiResize->ui_resize(fUiResize->handle, fUI.getWidth(), fUI.getHeight()); | fUiResize->ui_resize(fUiResize->handle, fUI.getWidth(), fUI.getHeight()); | ||||
| if (widget != nullptr) | if (widget != nullptr) | ||||
| *widget = (LV2UI_Widget)fUI.getWindowId(); | |||||
| *widget = (LV2UI_Widget)fUI.getNativeWindowHandle(); | |||||
| #if DISTRHO_PLUGIN_WANT_STATE | #if DISTRHO_PLUGIN_WANT_STATE | ||||
| // tell the DSP we're ready to receive msgs | // tell the DSP we're ready to receive msgs | ||||