Signed-off-by: falkTX <falktx@falktx.com>pull/272/head
| @@ -21,11 +21,6 @@ | |||||
| START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // Forward class names | |||||
| class Window; | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| /** | /** | ||||
| @@ -30,7 +30,7 @@ START_NAMESPACE_DGL | |||||
| */ | */ | ||||
| struct CairoGraphicsContext : GraphicsContext | struct CairoGraphicsContext : GraphicsContext | ||||
| { | { | ||||
| cairo_t* cairo; // FIXME proper name.. | |||||
| cairo_t* handle; | |||||
| }; | }; | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -56,7 +56,12 @@ public: | |||||
| /** | /** | ||||
| Constructor for an embed Window, typically used in modules or plugins that run inside another host. | Constructor for an embed Window, typically used in modules or plugins that run inside another host. | ||||
| */ | */ | ||||
| explicit Window(Application& app, uintptr_t parentWindowHandle, double scaling, bool resizable); | |||||
| explicit Window(Application& app, | |||||
| uintptr_t parentWindowHandle, | |||||
| uint width, | |||||
| uint height, | |||||
| double scaling, | |||||
| bool resizable); | |||||
| /** | /** | ||||
| Destructor. | Destructor. | ||||
| @@ -68,11 +73,33 @@ public: | |||||
| */ | */ | ||||
| bool isEmbed() const noexcept; | bool isEmbed() const noexcept; | ||||
| /** | |||||
| Check if this window is visible / mapped. | |||||
| Invisible windows do not receive events except resize. | |||||
| @see setVisible(bool) | |||||
| */ | |||||
| bool isVisible() const noexcept; | bool isVisible() const noexcept; | ||||
| /** | |||||
| Set windows visible (or not) according to @a visible. | |||||
| Only valid for standalones, embed windows are always visible. | |||||
| @see isVisible(), hide(), show() | |||||
| */ | |||||
| void setVisible(bool visible); | void setVisible(bool visible); | ||||
| inline void show() { setVisible(true); } | |||||
| inline void hide() { setVisible(true); } | |||||
| /** | |||||
| Show window. | |||||
| This is the same as calling setVisible(true). | |||||
| @see isVisible(), setVisible(bool) | |||||
| */ | |||||
| void show(); | |||||
| /** | |||||
| Hide window. | |||||
| This is the same as calling setVisible(false). | |||||
| @see isVisible(), setVisible(bool) | |||||
| */ | |||||
| void hide(); | |||||
| /** | /** | ||||
| Hide window and notify application of a window close event. | Hide window and notify application of a window close event. | ||||
| @@ -85,6 +112,44 @@ public: | |||||
| */ | */ | ||||
| void close(); | void close(); | ||||
| /** | |||||
| Get width. | |||||
| */ | |||||
| uint getWidth() const noexcept; | |||||
| /** | |||||
| Get height. | |||||
| */ | |||||
| uint getHeight() const noexcept; | |||||
| /** | |||||
| Get size. | |||||
| */ | |||||
| Size<uint> getSize() const noexcept; | |||||
| /** | |||||
| Set width. | |||||
| */ | |||||
| void setWidth(uint width); | |||||
| /** | |||||
| Set height. | |||||
| */ | |||||
| void setHeight(uint height); | |||||
| /** | |||||
| Set size using @a width and @a height values. | |||||
| */ | |||||
| void setSize(uint width, uint height); | |||||
| /** | |||||
| Set size. | |||||
| */ | |||||
| void setSize(const Size<uint>& size); | |||||
| const char* getTitle() const noexcept; | |||||
| void setTitle(const char* title); | |||||
| /** | /** | ||||
| Get the "native" window handle. | Get the "native" window handle. | ||||
| Returned value depends on the platform: | Returned value depends on the platform: | ||||
| @@ -95,6 +160,11 @@ public: | |||||
| */ | */ | ||||
| uintptr_t getNativeWindowHandle() const noexcept; | uintptr_t getNativeWindowHandle() const noexcept; | ||||
| protected: | |||||
| virtual void onDisplayBefore(); | |||||
| virtual void onDisplayAfter(); | |||||
| virtual void onReshape(uint width, uint height); | |||||
| private: | private: | ||||
| struct PrivateData; | struct PrivateData; | ||||
| PrivateData* const pData; | PrivateData* const pData; | ||||
| @@ -180,15 +250,6 @@ END_NAMESPACE_DGL | |||||
| bool getIgnoringKeyRepeat() const noexcept; | bool getIgnoringKeyRepeat() const noexcept; | ||||
| void setIgnoringKeyRepeat(bool ignore) noexcept; | void setIgnoringKeyRepeat(bool ignore) noexcept; | ||||
| uint getWidth() const noexcept; | |||||
| uint getHeight() const noexcept; | |||||
| Size<uint> getSize() const noexcept; | |||||
| void setSize(uint width, uint height); | |||||
| void setSize(Size<uint> size); | |||||
| const char* getTitle() const noexcept; | |||||
| void setTitle(const char* title); | |||||
| void setGeometryConstraints(uint width, uint height, bool aspect); | void setGeometryConstraints(uint width, uint height, bool aspect); | ||||
| void setTransientWinId(uintptr_t winId); | void setTransientWinId(uintptr_t winId); | ||||
| @@ -206,9 +267,6 @@ END_NAMESPACE_DGL | |||||
| protected: | protected: | ||||
| virtual void onDisplayBefore(); | |||||
| virtual void onDisplayAfter(); | |||||
| virtual void onReshape(uint width, uint height); | |||||
| virtual void onClose(); | virtual void onClose(); | ||||
| #ifndef DGL_FILE_BROWSER_DISABLED | #ifndef DGL_FILE_BROWSER_DISABLED | ||||
| @@ -21,6 +21,8 @@ | |||||
| START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
| typedef std::list<DGL_NAMESPACE::Window*>::reverse_iterator WindowListReverseIterator; | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| Application::PrivateData::PrivateData(const bool standalone) | Application::PrivateData::PrivateData(const bool standalone) | ||||
| @@ -97,9 +99,9 @@ void Application::PrivateData::quit() | |||||
| isQuitting = true; | isQuitting = true; | ||||
| #ifndef DPF_TEST_APPLICATION_CPP | #ifndef DPF_TEST_APPLICATION_CPP | ||||
| for (std::list<Window*>::reverse_iterator rit = windows.rbegin(), rite = windows.rend(); rit != rite; ++rit) | |||||
| for (WindowListReverseIterator rit = windows.rbegin(), rite = windows.rend(); rit != rite; ++rit) | |||||
| { | { | ||||
| Window* const window(*rit); | |||||
| DGL_NAMESPACE::Window* const window(*rit); | |||||
| window->close(); | window->close(); | ||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -47,10 +47,10 @@ struct Application::PrivateData { | |||||
| uint visibleWindows; | uint visibleWindows; | ||||
| /** List of windows for this application. Only used during `close`. */ | /** List of windows for this application. Only used during `close`. */ | ||||
| std::list<Window*> windows; | |||||
| std::list<DGL_NAMESPACE::Window*> windows; | |||||
| /** List of idle callbacks for this application. */ | /** List of idle callbacks for this application. */ | ||||
| std::list<IdleCallback*> idleCallbacks; | |||||
| std::list<DGL_NAMESPACE::IdleCallback*> idleCallbacks; | |||||
| /** Constructor and destructor */ | /** Constructor and destructor */ | ||||
| PrivateData(const bool standalone); | PrivateData(const bool standalone); | ||||
| @@ -29,8 +29,13 @@ START_NAMESPACE_DGL | |||||
| Window::Window(Application& app) | Window::Window(Application& app) | ||||
| : pData(new PrivateData(app.pData, this)) {} | : pData(new PrivateData(app.pData, this)) {} | ||||
| 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(Application& app, | |||||
| const uintptr_t parentWindowHandle, | |||||
| const uint width, | |||||
| const uint height, | |||||
| const double scaling, | |||||
| const bool resizable) | |||||
| : pData(new PrivateData(app.pData, this, parentWindowHandle, width, height, scaling, resizable)) {} | |||||
| Window::~Window() | Window::~Window() | ||||
| { | { | ||||
| @@ -49,7 +54,20 @@ bool Window::isVisible() const noexcept | |||||
| void Window::setVisible(const bool visible) | void Window::setVisible(const bool visible) | ||||
| { | { | ||||
| pData->setVisible(visible); | |||||
| if (visible) | |||||
| pData->show(); | |||||
| else | |||||
| pData->hide(); | |||||
| } | |||||
| void Window::show() | |||||
| { | |||||
| pData->show(); | |||||
| } | |||||
| void Window::hide() | |||||
| { | |||||
| pData->hide(); | |||||
| } | } | ||||
| void Window::close() | void Window::close() | ||||
| @@ -57,11 +75,77 @@ void Window::close() | |||||
| pData->close(); | pData->close(); | ||||
| } | } | ||||
| uint Window::getWidth() const noexcept | |||||
| { | |||||
| return puglGetFrame(pData->view).width; | |||||
| } | |||||
| uint Window::getHeight() const noexcept | |||||
| { | |||||
| return puglGetFrame(pData->view).height; | |||||
| } | |||||
| Size<uint> Window::getSize() const noexcept | |||||
| { | |||||
| const PuglRect rect = puglGetFrame(pData->view); | |||||
| return Size<uint>(rect.width, rect.height); | |||||
| } | |||||
| void Window::setWidth(const uint width) | |||||
| { | |||||
| setSize(width, getHeight()); | |||||
| } | |||||
| void Window::setHeight(const uint height) | |||||
| { | |||||
| setSize(getWidth(), height); | |||||
| } | |||||
| void Window::setSize(const uint width, const uint height) | |||||
| { | |||||
| DISTRHO_SAFE_ASSERT_UINT2_RETURN(width > 1 && height > 1, width, height,); | |||||
| puglSetWindowSize(pData->view, width, height); | |||||
| } | |||||
| void Window::setSize(const Size<uint>& size) | |||||
| { | |||||
| setSize(size.getWidth(), size.getHeight()); | |||||
| } | |||||
| const char* Window::getTitle() const noexcept | |||||
| { | |||||
| return puglGetWindowTitle(pData->view); | |||||
| } | |||||
| void Window::setTitle(const char* const title) | |||||
| { | |||||
| puglSetWindowTitle(pData->view, title); | |||||
| } | |||||
| uintptr_t Window::getNativeWindowHandle() const noexcept | uintptr_t Window::getNativeWindowHandle() const noexcept | ||||
| { | { | ||||
| return puglGetNativeWindow(pData->view); | return puglGetNativeWindow(pData->view); | ||||
| } | } | ||||
| void Window::onDisplayBefore() | |||||
| { | |||||
| const GraphicsContext& context(pData->getGraphicsContext()); | |||||
| PrivateData::Fallback::onDisplayBefore(context); | |||||
| } | |||||
| void Window::onDisplayAfter() | |||||
| { | |||||
| const GraphicsContext& context(pData->getGraphicsContext()); | |||||
| PrivateData::Fallback::onDisplayAfter(context); | |||||
| } | |||||
| void Window::onReshape(const uint width, const uint height) | |||||
| { | |||||
| const GraphicsContext& context(pData->getGraphicsContext()); | |||||
| PrivateData::Fallback::onReshape(context, width, height); | |||||
| } | |||||
| #if 0 | #if 0 | ||||
| #if 0 | #if 0 | ||||
| void Window::exec(bool lockWait) | void Window::exec(bool lockWait) | ||||
| @@ -134,44 +218,6 @@ void Window::setGeometryConstraints(const uint width, const uint height, bool as | |||||
| puglUpdateGeometryConstraints(pData->fView, width, height, aspect); | puglUpdateGeometryConstraints(pData->fView, width, height, aspect); | ||||
| } | } | ||||
| uint Window::getWidth() const noexcept | |||||
| { | |||||
| return puglGetFrame(pData->fView).width; | |||||
| } | |||||
| uint Window::getHeight() const noexcept | |||||
| { | |||||
| return puglGetFrame(pData->fView).height; | |||||
| } | |||||
| Size<uint> Window::getSize() const noexcept | |||||
| { | |||||
| const PuglRect rect = puglGetFrame(pData->fView); | |||||
| return Size<uint>(rect.width, rect.height); | |||||
| } | |||||
| void Window::setSize(const uint width, const uint height) | |||||
| { | |||||
| DISTRHO_SAFE_ASSERT_INT2_RETURN(width > 1 && height > 1, width, height,); | |||||
| puglSetWindowSize(pData->fView, width, height); | |||||
| } | |||||
| void Window::setSize(const Size<uint> size) | |||||
| { | |||||
| setSize(size.getWidth(), size.getHeight()); | |||||
| } | |||||
| const char* Window::getTitle() const noexcept | |||||
| { | |||||
| return puglGetWindowTitle(pData->fView); | |||||
| } | |||||
| void Window::setTitle(const char* const title) | |||||
| { | |||||
| puglSetWindowTitle(pData->fView, title); | |||||
| } | |||||
| void Window::setTransientWinId(const uintptr_t winId) | void Window::setTransientWinId(const uintptr_t winId) | ||||
| { | { | ||||
| puglSetTransientFor(pData->fView, winId); | puglSetTransientFor(pData->fView, winId); | ||||
| @@ -189,17 +235,6 @@ Application& Window::getApp() const noexcept | |||||
| } | } | ||||
| #endif | #endif | ||||
| #if 0 | |||||
| const GraphicsContext& Window::getGraphicsContext() const noexcept | |||||
| { | |||||
| GraphicsContext& context = pData->fContext; | |||||
| #ifdef DGL_CAIRO | |||||
| context.cairo = (cairo_t*)puglGetContext(pData->fView); | |||||
| #endif | |||||
| return context; | |||||
| } | |||||
| #endif | |||||
| void Window::_setAutoScaling(double scaling) noexcept | void Window::_setAutoScaling(double scaling) noexcept | ||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(scaling > 0.0,); | DISTRHO_SAFE_ASSERT_RETURN(scaling > 0.0,); | ||||
| @@ -240,21 +275,6 @@ void Window::removeIdleCallback(IdleCallback* const callback) | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| void Window::onDisplayBefore() | |||||
| { | |||||
| PrivateData::Fallback::onDisplayBefore(); | |||||
| } | |||||
| void Window::onDisplayAfter() | |||||
| { | |||||
| PrivateData::Fallback::onDisplayAfter(); | |||||
| } | |||||
| void Window::onReshape(const uint width, const uint height) | |||||
| { | |||||
| PrivateData::Fallback::onReshape(width, height); | |||||
| } | |||||
| void Window::onClose() | void Window::onClose() | ||||
| { | { | ||||
| } | } | ||||
| @@ -21,6 +21,21 @@ | |||||
| START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
| #define DGL_DEBUG_EVENTS | |||||
| #if defined(DEBUG) && defined(DGL_DEBUG_EVENTS) | |||||
| # define DGL_DBG(msg) std::fprintf(stderr, "%s", msg); | |||||
| # define DGL_DBGp(...) std::fprintf(stderr, __VA_ARGS__); | |||||
| # define DGL_DBGF std::fflush(stderr); | |||||
| #else | |||||
| # define DGL_DBG(msg) | |||||
| # define DGL_DBGp(...) | |||||
| # define DGL_DBGF | |||||
| #endif | |||||
| #define DEFAULT_WIDTH 640 | |||||
| #define DEFAULT_HEIGHT 480 | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* const s) | Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* const s) | ||||
| @@ -31,7 +46,7 @@ Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* cons | |||||
| isVisible(false), | isVisible(false), | ||||
| isEmbed(false) | isEmbed(false) | ||||
| { | { | ||||
| init(false); | |||||
| init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); | |||||
| } | } | ||||
| Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* const s, Window& transientWindow) | Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* const s, Window& transientWindow) | ||||
| @@ -42,13 +57,15 @@ Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* cons | |||||
| isVisible(false), | isVisible(false), | ||||
| isEmbed(false) | isEmbed(false) | ||||
| { | { | ||||
| init(false); | |||||
| init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); | |||||
| puglSetTransientFor(view, transientWindow.getNativeWindowHandle()); | puglSetTransientFor(view, transientWindow.getNativeWindowHandle()); | ||||
| } | } | ||||
| Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* const s, | Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* const s, | ||||
| const uintptr_t parentWindowHandle, const double scaling, const bool resizable) | |||||
| const uintptr_t parentWindowHandle, | |||||
| const uint width, const uint height, | |||||
| const double scaling, const bool resizable) | |||||
| : appData(a), | : appData(a), | ||||
| self(s), | self(s), | ||||
| view(puglNewView(appData->world)), | view(puglNewView(appData->world)), | ||||
| @@ -56,11 +73,12 @@ Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* cons | |||||
| isVisible(parentWindowHandle != 0), | isVisible(parentWindowHandle != 0), | ||||
| isEmbed(parentWindowHandle != 0) | isEmbed(parentWindowHandle != 0) | ||||
| { | { | ||||
| init(resizable); | |||||
| init(width, height, resizable); | |||||
| if (isEmbed) | if (isEmbed) | ||||
| { | { | ||||
| appData->oneWindowShown(); | appData->oneWindowShown(); | ||||
| puglSetDefaultSize(view, width, height); | |||||
| puglSetParentWindow(view, parentWindowHandle); | puglSetParentWindow(view, parentWindowHandle); | ||||
| puglShow(view); | puglShow(view); | ||||
| } | } | ||||
| @@ -85,16 +103,15 @@ Window::PrivateData::~PrivateData() | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| void Window::PrivateData::init(const bool resizable) | |||||
| void Window::PrivateData::init(const uint width, const uint height, const bool resizable) | |||||
| { | { | ||||
| appData->windows.push_back(self); | appData->windows.push_back(self); | ||||
| appData->idleCallbacks.push_back(this); | appData->idleCallbacks.push_back(this); | ||||
| memset(graphicsContext, 0, sizeof(graphicsContext)); | |||||
| if (view == nullptr) | if (view == nullptr) | ||||
| { | { | ||||
| /* | |||||
| DGL_DBG("Failed!\n"); | |||||
| */ | |||||
| DGL_DBG("Failed to create Pugl view, everything will fail!\n"); | |||||
| return; | return; | ||||
| } | } | ||||
| @@ -116,231 +133,144 @@ void Window::PrivateData::init(const bool resizable) | |||||
| // puglSetFileSelectedFunc(fView, fileBrowserSelectedCallback); | // puglSetFileSelectedFunc(fView, fileBrowserSelectedCallback); | ||||
| // #endif | // #endif | ||||
| // DGL_DBG("Success!\n"); | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| void Window::PrivateData::close() | |||||
| { | |||||
| // DGL_DBG("Window close\n"); | |||||
| if (isEmbed || isClosed) | |||||
| return; | |||||
| isClosed = true; | |||||
| setVisible(false); | |||||
| appData->oneWindowClosed(); | |||||
| PuglRect rect = puglGetFrame(view); | |||||
| rect.width = width; | |||||
| rect.height = height; | |||||
| puglSetFrame(view, rect); | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| void Window::PrivateData::setVisible(const bool visible) | |||||
| void Window::PrivateData::show() | |||||
| { | { | ||||
| if (isVisible == visible) | |||||
| if (isVisible) | |||||
| { | { | ||||
| // DGL_DBG("Window setVisible matches current state, ignoring request\n"); | |||||
| DGL_DBG("Window show matches current visible state, ignoring request\n"); | |||||
| return; | return; | ||||
| } | } | ||||
| if (isEmbed) | if (isEmbed) | ||||
| { | { | ||||
| // DGL_DBG("Window setVisible cannot be called when embedded\n"); | |||||
| DGL_DBG("Window show cannot be called when embedded\n"); | |||||
| return; | return; | ||||
| } | } | ||||
| // DGL_DBG("Window setVisible called\n"); | |||||
| DGL_DBG("Window show called\n"); | |||||
| isVisible = visible; | |||||
| #if 0 && defined(DISTRHO_OS_MAC) | |||||
| // if (mWindow != nullptr) | |||||
| // { | |||||
| // if (mParentWindow != nullptr) | |||||
| // [mParentWindow addChildWindow:mWindow | |||||
| // ordered:NSWindowAbove]; | |||||
| // } | |||||
| #endif | |||||
| if (visible) | |||||
| if (isClosed) | |||||
| { | { | ||||
| // #if 0 && defined(DISTRHO_OS_MAC) | |||||
| // if (mWindow != nullptr) | |||||
| // { | |||||
| // if (mParentWindow != nullptr) | |||||
| // [mParentWindow addChildWindow:mWindow | |||||
| // ordered:NSWindowAbove]; | |||||
| // } | |||||
| // #endif | |||||
| isClosed = false; | |||||
| appData->oneWindowShown(); | |||||
| const PuglStatus status = puglRealize(view); | |||||
| DISTRHO_SAFE_ASSERT_INT_RETURN(status == PUGL_SUCCESS, status, close()); | |||||
| if (isClosed) | |||||
| { | |||||
| puglRealize(view); | |||||
| #ifdef DISTRHO_OS_WINDOWS | #ifdef DISTRHO_OS_WINDOWS | ||||
| puglWin32ShowWindowCentered(view); | |||||
| puglWin32ShowWindowCentered(view); | |||||
| #else | #else | ||||
| puglShow(view); | |||||
| puglShow(view); | |||||
| #endif | #endif | ||||
| appData->oneWindowShown(); | |||||
| isClosed = false; | |||||
| } | |||||
| else | |||||
| { | |||||
| } | |||||
| else | |||||
| { | |||||
| #ifdef DISTRHO_OS_WINDOWS | #ifdef DISTRHO_OS_WINDOWS | ||||
| puglWin32RestoreWindow(view); | |||||
| puglWin32RestoreWindow(view); | |||||
| #else | #else | ||||
| puglShow(view); | |||||
| puglShow(view); | |||||
| #endif | #endif | ||||
| } | |||||
| } | } | ||||
| else | |||||
| { | |||||
| // #if 0 && defined(DISTRHO_OS_MAC) | |||||
| // if (mWindow != nullptr) | |||||
| // { | |||||
| // if (mParentWindow != nullptr) | |||||
| // [mParentWindow removeChildWindow:mWindow]; | |||||
| // } | |||||
| // #endif | |||||
| puglHide(view); | |||||
| isVisible = true; | |||||
| } | |||||
| // if (fModal.enabled) | |||||
| // exec_fini(); | |||||
| void Window::PrivateData::hide() | |||||
| { | |||||
| if (! isVisible) | |||||
| { | |||||
| DGL_DBG("Window hide matches current visible state, ignoring request\n"); | |||||
| return; | |||||
| } | |||||
| if (isEmbed) | |||||
| { | |||||
| DGL_DBG("Window hide cannot be called when embedded\n"); | |||||
| return; | |||||
| } | } | ||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| DGL_DBG("Window hide called\n"); | |||||
| void Window::PrivateData::idleCallback() | |||||
| { | |||||
| // #if defined(DISTRHO_OS_WINDOWS) && !defined(DGL_FILE_BROWSER_DISABLED) | |||||
| // if (fSelectedFile.isNotEmpty()) | |||||
| #if 0 && defined(DISTRHO_OS_MAC) | |||||
| // if (mWindow != nullptr) | |||||
| // { | // { | ||||
| // char* const buffer = fSelectedFile.getAndReleaseBuffer(); | |||||
| // fView->fileSelectedFunc(fView, buffer); | |||||
| // std::free(buffer); | |||||
| // if (mParentWindow != nullptr) | |||||
| // [mParentWindow removeChildWindow:mWindow]; | |||||
| // } | // } | ||||
| // #endif | |||||
| // | |||||
| // if (fModal.enabled && fModal.parent != nullptr) | |||||
| // fModal.parent->windowSpecificIdle(); | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const PuglEvent* const event) | |||||
| { | |||||
| Window::PrivateData* const pData = (Window::PrivateData*)puglGetHandle(view); | |||||
| return PUGL_SUCCESS; | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| END_NAMESPACE_DGL | |||||
| #if 0 | |||||
| #ifdef DGL_CAIRO | |||||
| # define PUGL_CAIRO | |||||
| # include "../Cairo.hpp" | |||||
| #endif | |||||
| #ifdef DGL_OPENGL | |||||
| # define PUGL_OPENGL | |||||
| # include "../OpenGL.hpp" | |||||
| #endif | #endif | ||||
| #ifndef DPF_TEST_WINDOW_CPP | |||||
| #include "WidgetPrivateData.hpp" | |||||
| #include "pugl-upstream/include/pugl/pugl.h" | |||||
| #include "pugl-extra/extras.h" | |||||
| #endif | |||||
| puglHide(view); | |||||
| extern "C" { | |||||
| #include "pugl-upstream/src/implementation.c" | |||||
| #include "pugl-extra/extras.c" | |||||
| } | |||||
| // if (fModal.enabled) | |||||
| // exec_fini(); | |||||
| #if defined(DISTRHO_OS_HAIKU) | |||||
| # define DGL_DEBUG_EVENTS | |||||
| # include "pugl-upstream/src/haiku.cpp" | |||||
| #elif defined(DISTRHO_OS_MAC) | |||||
| # include "pugl-upstream/src/mac.m" | |||||
| #elif defined(DISTRHO_OS_WINDOWS) | |||||
| # include "ppugl-upstream/src/win.c" | |||||
| # undef max | |||||
| # undef min | |||||
| #else | |||||
| # define DGL_PUGL_USING_X11 | |||||
| extern "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" | |||||
| isVisible = false; | |||||
| } | } | ||||
| #endif | |||||
| #include <inttypes.h> | |||||
| #include <stdarg.h> | |||||
| #include <stdbool.h> | |||||
| #include <stdint.h> | |||||
| #include <stdio.h> | |||||
| #include <string.h> | |||||
| #define FOR_EACH_WIDGET(it) \ | |||||
| for (std::list<Widget*>::iterator it = fWidgets.begin(); it != fWidgets.end(); ++it) | |||||
| #define FOR_EACH_WIDGET_INV(rit) \ | |||||
| for (std::list<Widget*>::reverse_iterator rit = fWidgets.rbegin(); rit != fWidgets.rend(); ++rit) | |||||
| #define DGL_DEBUG_EVENTS | |||||
| // ----------------------------------------------------------------------- | |||||
| #if defined(DEBUG) && defined(DGL_DEBUG_EVENTS) | |||||
| # define DGL_DBG(msg) std::fprintf(stderr, "%s", msg); | |||||
| # define DGL_DBGp(...) std::fprintf(stderr, __VA_ARGS__); | |||||
| # define DGL_DBGF std::fflush(stderr); | |||||
| #else | |||||
| # define DGL_DBG(msg) | |||||
| # define DGL_DBGp(...) | |||||
| # define DGL_DBGF | |||||
| #endif | |||||
| void Window::PrivateData::close() | |||||
| { | |||||
| DGL_DBG("Window close\n"); | |||||
| START_NAMESPACE_DGL | |||||
| if (isEmbed || isClosed) | |||||
| return; | |||||
| // Fallback build-specific Window functions | |||||
| struct Fallback { | |||||
| static void onDisplayBefore(); | |||||
| static void onDisplayAfter(); | |||||
| static void onReshape(uint width, uint height); | |||||
| }; | |||||
| isClosed = true; | |||||
| hide(); | |||||
| appData->oneWindowClosed(); | |||||
| } | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| void Window::PrivateData::addWidget(Widget* const widget) | |||||
| const GraphicsContext& Window::PrivateData::getGraphicsContext() const noexcept | |||||
| { | { | ||||
| fWidgets.push_back(widget); | |||||
| } | |||||
| void Window::PrivateData::removeWidget(Widget* const widget) | |||||
| { | |||||
| fWidgets.remove(widget); | |||||
| GraphicsContext& context((GraphicsContext&)graphicsContext); | |||||
| #ifdef DGL_CAIRO | |||||
| ((CairoGraphicsContext&)context).handle = (cairo_t*)puglGetContext(view); | |||||
| #endif | |||||
| return context; | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| void Window::PrivateData::onPuglClose() | |||||
| void Window::PrivateData::idleCallback() | |||||
| { | { | ||||
| DGL_DBG("PUGL: onClose\n"); | |||||
| // if (fModal.enabled) | |||||
| // exec_fini(); | |||||
| fSelf->onClose(); | |||||
| if (fModal.childFocus != nullptr) | |||||
| fModal.childFocus->fSelf->onClose(); | |||||
| close(); | |||||
| // #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(); | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | |||||
| void Window::PrivateData::onPuglDisplay() | void Window::PrivateData::onPuglDisplay() | ||||
| { | { | ||||
| fSelf->onDisplayBefore(); | |||||
| self->onDisplayBefore(); | |||||
| /* | |||||
| if (fWidgets.size() != 0) | if (fWidgets.size() != 0) | ||||
| { | { | ||||
| const PuglRect rect = puglGetFrame(fView); | const PuglRect rect = puglGetFrame(fView); | ||||
| @@ -353,8 +283,9 @@ void Window::PrivateData::onPuglDisplay() | |||||
| widget->pData->display(width, height, fAutoScaling, false); | widget->pData->display(width, height, fAutoScaling, false); | ||||
| } | } | ||||
| } | } | ||||
| */ | |||||
| fSelf->onDisplayAfter(); | |||||
| self->onDisplayAfter(); | |||||
| } | } | ||||
| void Window::PrivateData::onPuglReshape(const int width, const int height) | void Window::PrivateData::onPuglReshape(const int width, const int height) | ||||
| @@ -363,8 +294,9 @@ void Window::PrivateData::onPuglReshape(const int width, const int height) | |||||
| DGL_DBGp("PUGL: onReshape : %i %i\n", width, height); | DGL_DBGp("PUGL: onReshape : %i %i\n", width, height); | ||||
| fSelf->onReshape(width, height); | |||||
| self->onReshape(width, height); | |||||
| /* | |||||
| FOR_EACH_WIDGET(it) | FOR_EACH_WIDGET(it) | ||||
| { | { | ||||
| Widget* const widget(*it); | Widget* const widget(*it); | ||||
| @@ -372,35 +304,43 @@ void Window::PrivateData::onPuglReshape(const int width, const int height) | |||||
| if (widget->pData->needsFullViewport) | if (widget->pData->needsFullViewport) | ||||
| widget->setSize(width, height); | widget->setSize(width, height); | ||||
| } | } | ||||
| */ | |||||
| } | } | ||||
| void Window::PrivateData::onPuglMouse(const Widget::MouseEvent& ev) | |||||
| { | |||||
| DGL_DBGp("PUGL: onMouse : %i %i %i %i\n", ev.button, ev.press, ev.pos.getX(), ev.pos.getY()); | |||||
| // if (fModal.childFocus != nullptr) | |||||
| // return fModal.childFocus->focus(); | |||||
| static int printEvent(const PuglEvent* event, const char* prefix, const bool verbose); | |||||
| Widget::MouseEvent rev = ev; | |||||
| double x = ev.pos.getX() / fAutoScaling; | |||||
| double y = ev.pos.getY() / fAutoScaling; | |||||
| PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const PuglEvent* const event) | |||||
| { | |||||
| printEvent(event, "pugl event: ", true); | |||||
| Window::PrivateData* const pData = (Window::PrivateData*)puglGetHandle(view); | |||||
| FOR_EACH_WIDGET_INV(rit) | |||||
| switch (event->type) | |||||
| { | { | ||||
| Widget* const widget(*rit); | |||||
| ///< No event | |||||
| case PUGL_NOTHING: | |||||
| break; | |||||
| rev.pos = Point<double>(x - widget->getAbsoluteX(), | |||||
| y - widget->getAbsoluteY()); | |||||
| ///< View moved/resized, a #PuglEventConfigure | |||||
| case PUGL_CONFIGURE: | |||||
| pData->onPuglReshape(event->configure.width, event->configure.height); | |||||
| break; | |||||
| if (widget->isVisible() && widget->onMouse(rev)) | |||||
| break; | |||||
| ///< View must be drawn, a #PuglEventExpose | |||||
| case PUGL_EXPOSE: | |||||
| pData->onPuglDisplay(); | |||||
| break; | |||||
| // TODO | |||||
| default: | |||||
| break; | |||||
| } | } | ||||
| return PUGL_SUCCESS; | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| static inline int | |||||
| printModifiers(const uint32_t mods) | |||||
| static int printModifiers(const uint32_t mods) | |||||
| { | { | ||||
| return fprintf(stderr, "Modifiers:%s%s%s%s\n", | return fprintf(stderr, "Modifiers:%s%s%s%s\n", | ||||
| (mods & PUGL_MOD_SHIFT) ? " Shift" : "", | (mods & PUGL_MOD_SHIFT) ? " Shift" : "", | ||||
| @@ -409,8 +349,7 @@ printModifiers(const uint32_t mods) | |||||
| (mods & PUGL_MOD_SUPER) ? " Super" : ""); | (mods & PUGL_MOD_SUPER) ? " Super" : ""); | ||||
| } | } | ||||
| static inline int | |||||
| printEvent(const PuglEvent* event, const char* prefix, const bool verbose) | |||||
| static int printEvent(const PuglEvent* event, const char* prefix, const bool verbose) | |||||
| { | { | ||||
| #define FFMT "%6.1f" | #define FFMT "%6.1f" | ||||
| #define PFMT FFMT " " FFMT | #define PFMT FFMT " " FFMT | ||||
| @@ -526,9 +465,156 @@ printEvent(const PuglEvent* event, const char* prefix, const bool verbose) | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| // ----------------------------------------------------------------------- | |||||
| void Window::PrivateData::Fallback::onDisplayBefore(const GraphicsContext&) | |||||
| { | |||||
| #ifdef DGL_OPENGL | |||||
| glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |||||
| glLoadIdentity(); | |||||
| #endif | |||||
| } | |||||
| void Window::PrivateData::Fallback::onDisplayAfter(const GraphicsContext&) | |||||
| { | |||||
| } | |||||
| void Window::PrivateData::Fallback::onReshape(const GraphicsContext&, const uint width, const uint height) | |||||
| { | |||||
| #ifdef DGL_OPENGL | |||||
| glEnable(GL_BLEND); | |||||
| glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |||||
| glMatrixMode(GL_PROJECTION); | |||||
| glLoadIdentity(); | |||||
| glOrtho(0.0, static_cast<GLdouble>(width), static_cast<GLdouble>(height), 0.0, 0.0, 1.0); | |||||
| glViewport(0, 0, static_cast<GLsizei>(width), static_cast<GLsizei>(height)); | |||||
| glMatrixMode(GL_MODELVIEW); | |||||
| glLoadIdentity(); | |||||
| #else | |||||
| // unused | |||||
| (void)width; | |||||
| (void)height; | |||||
| #endif | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| END_NAMESPACE_DGL | |||||
| #if 0 | |||||
| #ifdef DGL_CAIRO | |||||
| # define PUGL_CAIRO | |||||
| # include "../Cairo.hpp" | |||||
| #endif | |||||
| #ifdef DGL_OPENGL | |||||
| # define PUGL_OPENGL | |||||
| # include "../OpenGL.hpp" | |||||
| #endif | |||||
| #ifndef DPF_TEST_WINDOW_CPP | |||||
| #include "WidgetPrivateData.hpp" | |||||
| #include "pugl-upstream/include/pugl/pugl.h" | |||||
| #include "pugl-extra/extras.h" | |||||
| #endif | |||||
| extern "C" { | |||||
| #include "pugl-upstream/src/implementation.c" | |||||
| #include "pugl-extra/extras.c" | |||||
| } | |||||
| #if defined(DISTRHO_OS_HAIKU) | |||||
| # define DGL_DEBUG_EVENTS | |||||
| # include "pugl-upstream/src/haiku.cpp" | |||||
| #elif defined(DISTRHO_OS_MAC) | |||||
| # include "pugl-upstream/src/mac.m" | |||||
| #elif defined(DISTRHO_OS_WINDOWS) | |||||
| # include "ppugl-upstream/src/win.c" | |||||
| # undef max | |||||
| # undef min | |||||
| #else | |||||
| # define DGL_PUGL_USING_X11 | |||||
| extern "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 | |||||
| #include <inttypes.h> | |||||
| #include <stdarg.h> | |||||
| #include <stdbool.h> | |||||
| #include <stdint.h> | |||||
| #include <stdio.h> | |||||
| #include <string.h> | |||||
| START_NAMESPACE_DGL | |||||
| #define FOR_EACH_WIDGET(it) \ | |||||
| for (std::list<Widget*>::iterator it = fWidgets.begin(); it != fWidgets.end(); ++it) | |||||
| #define FOR_EACH_WIDGET_INV(rit) \ | |||||
| for (std::list<Widget*>::reverse_iterator rit = fWidgets.rbegin(); rit != fWidgets.rend(); ++rit) | |||||
| // ----------------------------------------------------------------------- | |||||
| void Window::PrivateData::addWidget(Widget* const widget) | |||||
| { | |||||
| fWidgets.push_back(widget); | |||||
| } | |||||
| void Window::PrivateData::removeWidget(Widget* const widget) | |||||
| { | |||||
| fWidgets.remove(widget); | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| void Window::PrivateData::onPuglClose() | |||||
| { | |||||
| DGL_DBG("PUGL: onClose\n"); | |||||
| // if (fModal.enabled) | |||||
| // exec_fini(); | |||||
| fSelf->onClose(); | |||||
| if (fModal.childFocus != nullptr) | |||||
| fModal.childFocus->fSelf->onClose(); | |||||
| close(); | |||||
| } | |||||
| void Window::PrivateData::onPuglMouse(const Widget::MouseEvent& ev) | |||||
| { | |||||
| DGL_DBGp("PUGL: onMouse : %i %i %i %i\n", ev.button, ev.press, ev.pos.getX(), ev.pos.getY()); | |||||
| // if (fModal.childFocus != nullptr) | |||||
| // return fModal.childFocus->focus(); | |||||
| Widget::MouseEvent rev = ev; | |||||
| double x = ev.pos.getX() / fAutoScaling; | |||||
| double y = ev.pos.getY() / fAutoScaling; | |||||
| FOR_EACH_WIDGET_INV(rit) | |||||
| { | |||||
| Widget* const widget(*rit); | |||||
| rev.pos = Point<double>(x - widget->getAbsoluteX(), | |||||
| y - widget->getAbsoluteY()); | |||||
| if (widget->isVisible() && widget->onMouse(rev)) | |||||
| break; | |||||
| } | |||||
| } | |||||
| PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const PuglEvent* const event) | PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const PuglEvent* const event) | ||||
| { | { | ||||
| printEvent(event, "", true); | |||||
| Window::PrivateData* const pData = (Window::PrivateData*)puglGetHandle(view); | Window::PrivateData* const pData = (Window::PrivateData*)puglGetHandle(view); | ||||
| switch (event->type) | switch (event->type) | ||||
| @@ -607,37 +693,5 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| void Window::PrivateData::Fallback::onDisplayBefore() | |||||
| { | |||||
| #ifdef DGL_OPENGL | |||||
| glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |||||
| glLoadIdentity(); | |||||
| #endif | |||||
| } | |||||
| void Window::PrivateData::Fallback::onDisplayAfter() | |||||
| { | |||||
| } | |||||
| void Window::PrivateData::Fallback::onReshape(const uint width, const uint height) | |||||
| { | |||||
| #ifdef DGL_OPENGL | |||||
| glEnable(GL_BLEND); | |||||
| glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |||||
| glMatrixMode(GL_PROJECTION); | |||||
| glLoadIdentity(); | |||||
| glOrtho(0.0, static_cast<GLdouble>(width), static_cast<GLdouble>(height), 0.0, 0.0, 1.0); | |||||
| glViewport(0, 0, static_cast<GLsizei>(width), static_cast<GLsizei>(height)); | |||||
| glMatrixMode(GL_MODELVIEW); | |||||
| glLoadIdentity(); | |||||
| #else | |||||
| // unused | |||||
| (void)width; | |||||
| (void)height; | |||||
| #endif | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| END_NAMESPACE_DGL | END_NAMESPACE_DGL | ||||
| #endif | #endif | ||||
| @@ -40,6 +40,9 @@ struct Window::PrivateData : IdleCallback { | |||||
| /** Pugl view instance. */ | /** Pugl view instance. */ | ||||
| PuglView* const view; | PuglView* const view; | ||||
| /** Reserved space for graphics context. */ | |||||
| mutable uint8_t graphicsContext[sizeof(void*)]; | |||||
| /** Whether this Window is closed (not visible or counted in the Application it is tied to). | /** Whether this Window is closed (not visible or counted in the Application it is tied to). | ||||
| Defaults to true unless embed (embed windows are never closed). */ | Defaults to true unless embed (embed windows are never closed). */ | ||||
| bool isClosed; | bool isClosed; | ||||
| @@ -57,13 +60,17 @@ struct Window::PrivateData : IdleCallback { | |||||
| PrivateData(AppData* appData, Window* self, Window& transientWindow); | PrivateData(AppData* appData, Window* self, Window& transientWindow); | ||||
| /** Constructor for an embed Window, with a few extra hints from the host side. */ | /** Constructor for an embed Window, with a few extra hints from the host side. */ | ||||
| PrivateData(AppData* appData, Window* self, uintptr_t parentWindowHandle, double scaling, bool resizable); | |||||
| PrivateData(AppData* appData, Window* self, uintptr_t parentWindowHandle, | |||||
| uint width, uint height, double scaling, bool resizable); | |||||
| /** Destructor. */ | /** Destructor. */ | ||||
| ~PrivateData() override; | ~PrivateData() override; | ||||
| /** Helper initialization function called at the end of all this class constructors. */ | /** Helper initialization function called at the end of all this class constructors. */ | ||||
| void init(bool resizable); | |||||
| void init(uint width, uint height, bool resizable); | |||||
| void show(); | |||||
| void hide(); | |||||
| /** Hide window and notify application of a window close event. | /** Hide window and notify application of a window close event. | ||||
| * Does nothing if window is embed (that is, not standalone). | * Does nothing if window is embed (that is, not standalone). | ||||
| @@ -74,12 +81,24 @@ struct Window::PrivateData : IdleCallback { | |||||
| */ | */ | ||||
| void close(); | void close(); | ||||
| void setVisible(bool visible); | |||||
| const GraphicsContext& getGraphicsContext() const noexcept; | |||||
| void idleCallback() override; | void idleCallback() override; | ||||
| // pugl events | |||||
| void onPuglDisplay(); | |||||
| void onPuglReshape(int width, int height); | |||||
| // Pugl event handling entry point | |||||
| static PuglStatus puglEventCallback(PuglView* view, const PuglEvent* event); | static PuglStatus puglEventCallback(PuglView* view, const PuglEvent* event); | ||||
| // Fallback build-specific Window functions | |||||
| struct Fallback { | |||||
| static void onDisplayBefore(const GraphicsContext& context); | |||||
| static void onDisplayAfter(const GraphicsContext& context); | |||||
| static void onReshape(const GraphicsContext& context, uint width, uint height); | |||||
| }; | |||||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData) | DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData) | ||||
| }; | }; | ||||
| @@ -161,8 +180,6 @@ END_NAMESPACE_DGL | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| void onPuglClose(); | void onPuglClose(); | ||||
| void onPuglDisplay(); | |||||
| void onPuglReshape(const int width, const int height); | |||||
| void onPuglMouse(const Widget::MouseEvent& ev); | void onPuglMouse(const Widget::MouseEvent& ev); | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| @@ -1 +1 @@ | |||||
| Subproject commit 5a3a1309ad6432d72cdb7f37e3e36383dd6ba372 | |||||
| Subproject commit b0a018a006c5d7d7796074b86c1b69f8671d2d83 | |||||
| @@ -35,6 +35,10 @@ | |||||
| # include <X11/Xlib.h> | # include <X11/Xlib.h> | ||||
| # include <X11/Xutil.h> | # include <X11/Xutil.h> | ||||
| # include <X11/keysym.h> | # include <X11/keysym.h> | ||||
| # ifdef HAVE_XCURSOR | |||||
| # include <X11/Xcursor/Xcursor.h> | |||||
| # include <X11/cursorfont.h> | |||||
| # endif | |||||
| # ifdef HAVE_XRANDR | # ifdef HAVE_XRANDR | ||||
| # include <X11/extensions/Xrandr.h> | # include <X11/extensions/Xrandr.h> | ||||
| # endif | # endif | ||||
| @@ -42,10 +46,6 @@ | |||||
| # include <X11/extensions/sync.h> | # include <X11/extensions/sync.h> | ||||
| # include <X11/extensions/syncconst.h> | # include <X11/extensions/syncconst.h> | ||||
| # endif | # endif | ||||
| # ifdef HAVE_XCURSOR | |||||
| # include <X11/Xcursor/Xcursor.h> | |||||
| # include <X11/cursorfont.h> | |||||
| # endif | |||||
| # ifdef DGL_CAIRO | # ifdef DGL_CAIRO | ||||
| # include <cairo.h> | # include <cairo.h> | ||||
| # include <cairo-xlib.h> | # include <cairo-xlib.h> | ||||
| @@ -85,6 +85,74 @@ START_NAMESPACE_DGL | |||||
| #include "pugl-upstream/src/implementation.c" | #include "pugl-upstream/src/implementation.c" | ||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // missing in pugl, directly returns title char* pointer | |||||
| const char* puglGetWindowTitle(const PuglView* view) | |||||
| { | |||||
| return view->title; | |||||
| } | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // set window size without changing frame x/y position | |||||
| PuglStatus puglSetWindowSize(PuglView* view, unsigned int width, unsigned int height) | |||||
| { | |||||
| #if defined(DISTRHO_OS_HAIKU) || defined(DISTRHO_OS_MAC) | |||||
| // TODO | |||||
| const PuglRect frame = { 0.0, 0.0, (double)width, (double)height }; | |||||
| return puglSetFrame(view, frame); | |||||
| #elif defined(DISTRHO_OS_WINDOWS) | |||||
| // 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)); | |||||
| 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)) | |||||
| return PUGL_UNKNOWN_ERROR; | |||||
| } | |||||
| #else | |||||
| // matches upstream pugl, except we use XResizeWindow instead of XMoveResizeWindow | |||||
| if (view->impl->win) | |||||
| { | |||||
| if (! XResizeWindow(view->world->impl->display, view->impl->win, width, height)) | |||||
| return PUGL_UNKNOWN_ERROR; | |||||
| #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 | |||||
| } | |||||
| #endif | |||||
| view->frame.width = width; | |||||
| view->frame.height = height; | |||||
| return PUGL_SUCCESS; | |||||
| } | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| END_NAMESPACE_DGL | END_NAMESPACE_DGL | ||||
| @@ -31,6 +31,18 @@ START_NAMESPACE_DGL | |||||
| #define PUGL_DISABLE_DEPRECATED | #define PUGL_DISABLE_DEPRECATED | ||||
| #include "pugl-upstream/include/pugl/pugl.h" | #include "pugl-upstream/include/pugl/pugl.h" | ||||
| PUGL_BEGIN_DECLS | |||||
| // missing in pugl, directly returns title char* pointer | |||||
| PUGL_API const char* | |||||
| puglGetWindowTitle(const PuglView* view); | |||||
| // set window size without changing frame x/y position | |||||
| PUGL_API PuglStatus | |||||
| puglSetWindowSize(PuglView* view, unsigned int width, unsigned int height); | |||||
| PUGL_END_DECLS | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| END_NAMESPACE_DGL | END_NAMESPACE_DGL | ||||
| @@ -21,34 +21,10 @@ | |||||
| #include "dgl/src/Application.cpp" | #include "dgl/src/Application.cpp" | ||||
| #include "dgl/src/ApplicationPrivateData.cpp" | #include "dgl/src/ApplicationPrivateData.cpp" | ||||
| #include "distrho/extra/Thread.hpp" | |||||
| START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| class ApplicationQuitter : public Thread | |||||
| { | |||||
| Application& app; | |||||
| public: | |||||
| ApplicationQuitter(Application& a) | |||||
| : Thread("ApplicationQuitter"), | |||||
| app(a) | |||||
| { | |||||
| startThread(); | |||||
| } | |||||
| private: | |||||
| void run() override | |||||
| { | |||||
| d_sleep(2); | |||||
| app.quit(); | |||||
| } | |||||
| }; | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| struct IdleCallbackCounter : IdleCallback | struct IdleCallbackCounter : IdleCallback | ||||
| { | { | ||||
| int counter; | int counter; | ||||
| @@ -45,39 +45,32 @@ endif | |||||
| ifeq ($(HAVE_OPENGL),true) | ifeq ($(HAVE_OPENGL),true) | ||||
| endif | endif | ||||
| ifeq ($(HAVE_VULKAN),true) | |||||
| endif | |||||
| # --------------------------------------------------------------------------------------------------------------------- | # --------------------------------------------------------------------------------------------------------------------- | ||||
| all: $(TARGETS) | all: $(TARGETS) | ||||
| # --------------------------------------------------------------------------------------------------------------------- | # --------------------------------------------------------------------------------------------------------------------- | ||||
| ../build/tests/%: ../build/tests/%.cpp.o | |||||
| @echo "Linking $*" | |||||
| $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) -o $@ | |||||
| @echo "Running test for $*" | |||||
| $(SILENT)$@ | |||||
| define RUN_TEST | |||||
| ${1} | |||||
| endef | |||||
| # valgrind --leak-check=full $@ | # valgrind --leak-check=full $@ | ||||
| ../build/tests/%.cairo: ../build/tests/%.cpp.cairo.o | |||||
| @echo "Linking $*" | |||||
| $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(CAIRO_LIBS) -o $@ | |||||
| @echo "Running test for $*" | |||||
| $(SILENT)$@ | |||||
| run: $(TARGETS) | |||||
| $(foreach TEST,$(TARGETS),$(call RUN_TEST,$(TEST))) | |||||
| ../build/tests/%.opengl: ../build/tests/%.cpp.opengl.o | |||||
| @echo "Linking $*" | |||||
| $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@ | |||||
| @echo "Running test for $*" | |||||
| $(SILENT) $@ | |||||
| # gdb -ex run | |||||
| # --------------------------------------------------------------------------------------------------------------------- | |||||
| ../build/tests/%.vulkan: ../build/tests/%.cpp.vulkan.o | |||||
| @echo "Linking $*" | |||||
| $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(VULKAN_LIBS) -o $@ | |||||
| @echo "Running test for $*" | |||||
| $(SILENT)$@ | |||||
| clean: | |||||
| rm -rf ../build/tests | |||||
| # --------------------------------------------------------------------------------------------------------------------- | # --------------------------------------------------------------------------------------------------------------------- | ||||
| # building steps | |||||
| ../build/tests/%.c.o: %.c | ../build/tests/%.c.o: %.c | ||||
| -@mkdir -p ../build/tests | -@mkdir -p ../build/tests | ||||
| @@ -105,9 +98,23 @@ all: $(TARGETS) | |||||
| $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(OPENGL_FLAGS) -DDGL_VULKAN -c -o $@ | $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(OPENGL_FLAGS) -DDGL_VULKAN -c -o $@ | ||||
| # --------------------------------------------------------------------------------------------------------------------- | # --------------------------------------------------------------------------------------------------------------------- | ||||
| # linking steps | |||||
| clean: | |||||
| rm -rf ../build/tests | |||||
| ../build/tests/%: ../build/tests/%.cpp.o | |||||
| @echo "Linking $*" | |||||
| $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) -o $@ | |||||
| ../build/tests/%.cairo: ../build/tests/%.cpp.cairo.o | |||||
| @echo "Linking $*" | |||||
| $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(CAIRO_LIBS) -o $@ | |||||
| ../build/tests/%.opengl: ../build/tests/%.cpp.opengl.o | |||||
| @echo "Linking $*" | |||||
| $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@ | |||||
| ../build/tests/%.vulkan: ../build/tests/%.cpp.vulkan.o | |||||
| @echo "Linking $*" | |||||
| $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(VULKAN_LIBS) -o $@ | |||||
| # --------------------------------------------------------------------------------------------------------------------- | # --------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -21,9 +21,11 @@ | |||||
| #include "tests.hpp" | #include "tests.hpp" | ||||
| #define DPF_TEST_WINDOW_CPP | #define DPF_TEST_WINDOW_CPP | ||||
| #define DPF_TEST_POINT_CPP | |||||
| #include "dgl/src/pugl.cpp" | #include "dgl/src/pugl.cpp" | ||||
| #include "dgl/src/Application.cpp" | #include "dgl/src/Application.cpp" | ||||
| #include "dgl/src/ApplicationPrivateData.cpp" | #include "dgl/src/ApplicationPrivateData.cpp" | ||||
| #include "dgl/src/Geometry.cpp" | |||||
| #include "dgl/src/Window.cpp" | #include "dgl/src/Window.cpp" | ||||
| #include "dgl/src/WindowPrivateData.cpp" | #include "dgl/src/WindowPrivateData.cpp" | ||||
| @@ -35,11 +37,27 @@ int main() | |||||
| using DGL_NAMESPACE::Window; | using DGL_NAMESPACE::Window; | ||||
| // creating simple window | |||||
| // creating and destroying simple window | |||||
| { | { | ||||
| Application app(true); | Application app(true); | ||||
| Window win(app); | Window win(app); | ||||
| app.idle(); | |||||
| } | |||||
| // creating and destroying simple window, with a delay | |||||
| { | |||||
| Application app(true); | |||||
| ApplicationQuitter appQuitter(app); | |||||
| Window win(app); | |||||
| app.exec(); | |||||
| } | |||||
| // showing and closing simple window, MUST be visible on screen | |||||
| { | |||||
| Application app(true); | |||||
| ApplicationQuitter appQuitter(app); | |||||
| Window win(app); | |||||
| win.show(); | |||||
| app.exec(); | |||||
| } | } | ||||
| // TODO | // TODO | ||||
| @@ -14,10 +14,40 @@ | |||||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
| */ | */ | ||||
| #include "dgl/Base.hpp" | |||||
| #include "dgl/Application.hpp" | |||||
| #include "distrho/extra/Thread.hpp" | |||||
| #define DISTRHO_ASSERT_EQUAL(v1, v2, msg) \ | #define DISTRHO_ASSERT_EQUAL(v1, v2, msg) \ | ||||
| if (v1 != v2) { d_stderr2("Test condition failed: %s; file:%s line:%i", msg, __FILE__, __LINE__); return 1; } | if (v1 != v2) { d_stderr2("Test condition failed: %s; file:%s line:%i", msg, __FILE__, __LINE__); return 1; } | ||||
| #define DISTRHO_ASSERT_NOT_EQUAL(v1, v2, msg) \ | #define DISTRHO_ASSERT_NOT_EQUAL(v1, v2, msg) \ | ||||
| if (v1 == v2) { d_stderr2("Test condition failed: %s; file:%s line:%i", msg, __FILE__, __LINE__); return 1; } | if (v1 == v2) { d_stderr2("Test condition failed: %s; file:%s line:%i", msg, __FILE__, __LINE__); return 1; } | ||||
| START_NAMESPACE_DGL | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| class ApplicationQuitter : public Thread | |||||
| { | |||||
| Application& app; | |||||
| public: | |||||
| ApplicationQuitter(Application& a) | |||||
| : Thread("ApplicationQuitter"), | |||||
| app(a) | |||||
| { | |||||
| startThread(); | |||||
| } | |||||
| private: | |||||
| void run() override | |||||
| { | |||||
| d_sleep(2); | |||||
| app.quit(); | |||||
| } | |||||
| }; | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| END_NAMESPACE_DGL | |||||