Signed-off-by: falkTX <falktx@falktx.com>pull/272/head
@@ -21,11 +21,6 @@ | |||
START_NAMESPACE_DGL | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
// Forward class names | |||
class Window; | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
/** | |||
@@ -30,7 +30,7 @@ START_NAMESPACE_DGL | |||
*/ | |||
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. | |||
*/ | |||
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. | |||
@@ -68,11 +73,33 @@ public: | |||
*/ | |||
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; | |||
/** | |||
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); | |||
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. | |||
@@ -85,6 +112,44 @@ public: | |||
*/ | |||
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. | |||
Returned value depends on the platform: | |||
@@ -95,6 +160,11 @@ public: | |||
*/ | |||
uintptr_t getNativeWindowHandle() const noexcept; | |||
protected: | |||
virtual void onDisplayBefore(); | |||
virtual void onDisplayAfter(); | |||
virtual void onReshape(uint width, uint height); | |||
private: | |||
struct PrivateData; | |||
PrivateData* const pData; | |||
@@ -180,15 +250,6 @@ END_NAMESPACE_DGL | |||
bool getIgnoringKeyRepeat() const 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 setTransientWinId(uintptr_t winId); | |||
@@ -206,9 +267,6 @@ END_NAMESPACE_DGL | |||
protected: | |||
virtual void onDisplayBefore(); | |||
virtual void onDisplayAfter(); | |||
virtual void onReshape(uint width, uint height); | |||
virtual void onClose(); | |||
#ifndef DGL_FILE_BROWSER_DISABLED | |||
@@ -21,6 +21,8 @@ | |||
START_NAMESPACE_DGL | |||
typedef std::list<DGL_NAMESPACE::Window*>::reverse_iterator WindowListReverseIterator; | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
Application::PrivateData::PrivateData(const bool standalone) | |||
@@ -97,9 +99,9 @@ void Application::PrivateData::quit() | |||
isQuitting = true; | |||
#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(); | |||
} | |||
#endif | |||
@@ -47,10 +47,10 @@ struct Application::PrivateData { | |||
uint visibleWindows; | |||
/** 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. */ | |||
std::list<IdleCallback*> idleCallbacks; | |||
std::list<DGL_NAMESPACE::IdleCallback*> idleCallbacks; | |||
/** Constructor and destructor */ | |||
PrivateData(const bool standalone); | |||
@@ -29,8 +29,13 @@ START_NAMESPACE_DGL | |||
Window::Window(Application& app) | |||
: 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() | |||
{ | |||
@@ -49,7 +54,20 @@ bool Window::isVisible() const noexcept | |||
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() | |||
@@ -57,11 +75,77 @@ void Window::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 | |||
{ | |||
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 | |||
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); | |||
} | |||
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) | |||
{ | |||
puglSetTransientFor(pData->fView, winId); | |||
@@ -189,17 +235,6 @@ Application& Window::getApp() const noexcept | |||
} | |||
#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 | |||
{ | |||
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() | |||
{ | |||
} | |||
@@ -21,6 +21,21 @@ | |||
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) | |||
@@ -31,7 +46,7 @@ Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* cons | |||
isVisible(false), | |||
isEmbed(false) | |||
{ | |||
init(false); | |||
init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); | |||
} | |||
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), | |||
isEmbed(false) | |||
{ | |||
init(false); | |||
init(DEFAULT_WIDTH, DEFAULT_HEIGHT, false); | |||
puglSetTransientFor(view, transientWindow.getNativeWindowHandle()); | |||
} | |||
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), | |||
self(s), | |||
view(puglNewView(appData->world)), | |||
@@ -56,11 +73,12 @@ Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* cons | |||
isVisible(parentWindowHandle != 0), | |||
isEmbed(parentWindowHandle != 0) | |||
{ | |||
init(resizable); | |||
init(width, height, resizable); | |||
if (isEmbed) | |||
{ | |||
appData->oneWindowShown(); | |||
puglSetDefaultSize(view, width, height); | |||
puglSetParentWindow(view, parentWindowHandle); | |||
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->idleCallbacks.push_back(this); | |||
memset(graphicsContext, 0, sizeof(graphicsContext)); | |||
if (view == nullptr) | |||
{ | |||
/* | |||
DGL_DBG("Failed!\n"); | |||
*/ | |||
DGL_DBG("Failed to create Pugl view, everything will fail!\n"); | |||
return; | |||
} | |||
@@ -116,231 +133,144 @@ void Window::PrivateData::init(const bool resizable) | |||
// puglSetFileSelectedFunc(fView, fileBrowserSelectedCallback); | |||
// #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; | |||
} | |||
if (isEmbed) | |||
{ | |||
// DGL_DBG("Window setVisible cannot be called when embedded\n"); | |||
DGL_DBG("Window show cannot be called when embedded\n"); | |||
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 | |||
puglWin32ShowWindowCentered(view); | |||
puglWin32ShowWindowCentered(view); | |||
#else | |||
puglShow(view); | |||
puglShow(view); | |||
#endif | |||
appData->oneWindowShown(); | |||
isClosed = false; | |||
} | |||
else | |||
{ | |||
} | |||
else | |||
{ | |||
#ifdef DISTRHO_OS_WINDOWS | |||
puglWin32RestoreWindow(view); | |||
puglWin32RestoreWindow(view); | |||
#else | |||
puglShow(view); | |||
puglShow(view); | |||
#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 | |||
#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() | |||
{ | |||
fSelf->onDisplayBefore(); | |||
self->onDisplayBefore(); | |||
/* | |||
if (fWidgets.size() != 0) | |||
{ | |||
const PuglRect rect = puglGetFrame(fView); | |||
@@ -353,8 +283,9 @@ void Window::PrivateData::onPuglDisplay() | |||
widget->pData->display(width, height, fAutoScaling, false); | |||
} | |||
} | |||
*/ | |||
fSelf->onDisplayAfter(); | |||
self->onDisplayAfter(); | |||
} | |||
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); | |||
fSelf->onReshape(width, height); | |||
self->onReshape(width, height); | |||
/* | |||
FOR_EACH_WIDGET(it) | |||
{ | |||
Widget* const widget(*it); | |||
@@ -372,35 +304,43 @@ void Window::PrivateData::onPuglReshape(const int width, const int height) | |||
if (widget->pData->needsFullViewport) | |||
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", | |||
(mods & PUGL_MOD_SHIFT) ? " Shift" : "", | |||
@@ -409,8 +349,7 @@ printModifiers(const uint32_t mods) | |||
(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 PFMT FFMT " " FFMT | |||
@@ -526,9 +465,156 @@ printEvent(const PuglEvent* event, const char* prefix, const bool verbose) | |||
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) | |||
{ | |||
printEvent(event, "", true); | |||
Window::PrivateData* const pData = (Window::PrivateData*)puglGetHandle(view); | |||
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 | |||
#endif |
@@ -40,6 +40,9 @@ struct Window::PrivateData : IdleCallback { | |||
/** Pugl view instance. */ | |||
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). | |||
Defaults to true unless embed (embed windows are never closed). */ | |||
bool isClosed; | |||
@@ -57,13 +60,17 @@ struct Window::PrivateData : IdleCallback { | |||
PrivateData(AppData* appData, Window* self, Window& transientWindow); | |||
/** 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. */ | |||
~PrivateData() override; | |||
/** 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. | |||
* Does nothing if window is embed (that is, not standalone). | |||
@@ -74,12 +81,24 @@ struct Window::PrivateData : IdleCallback { | |||
*/ | |||
void close(); | |||
void setVisible(bool visible); | |||
const GraphicsContext& getGraphicsContext() const noexcept; | |||
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); | |||
// 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) | |||
}; | |||
@@ -161,8 +180,6 @@ END_NAMESPACE_DGL | |||
// ------------------------------------------------------------------- | |||
void onPuglClose(); | |||
void onPuglDisplay(); | |||
void onPuglReshape(const int width, const int height); | |||
void onPuglMouse(const Widget::MouseEvent& ev); | |||
// ------------------------------------------------------------------- | |||
@@ -1 +1 @@ | |||
Subproject commit 5a3a1309ad6432d72cdb7f37e3e36383dd6ba372 | |||
Subproject commit b0a018a006c5d7d7796074b86c1b69f8671d2d83 |
@@ -35,6 +35,10 @@ | |||
# include <X11/Xlib.h> | |||
# include <X11/Xutil.h> | |||
# include <X11/keysym.h> | |||
# ifdef HAVE_XCURSOR | |||
# include <X11/Xcursor/Xcursor.h> | |||
# include <X11/cursorfont.h> | |||
# endif | |||
# ifdef HAVE_XRANDR | |||
# include <X11/extensions/Xrandr.h> | |||
# endif | |||
@@ -42,10 +46,6 @@ | |||
# include <X11/extensions/sync.h> | |||
# include <X11/extensions/syncconst.h> | |||
# endif | |||
# ifdef HAVE_XCURSOR | |||
# include <X11/Xcursor/Xcursor.h> | |||
# include <X11/cursorfont.h> | |||
# endif | |||
# ifdef DGL_CAIRO | |||
# include <cairo.h> | |||
# include <cairo-xlib.h> | |||
@@ -85,6 +85,74 @@ START_NAMESPACE_DGL | |||
#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 |
@@ -31,6 +31,18 @@ START_NAMESPACE_DGL | |||
#define PUGL_DISABLE_DEPRECATED | |||
#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 | |||
@@ -21,34 +21,10 @@ | |||
#include "dgl/src/Application.cpp" | |||
#include "dgl/src/ApplicationPrivateData.cpp" | |||
#include "distrho/extra/Thread.hpp" | |||
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 | |||
{ | |||
int counter; | |||
@@ -45,39 +45,32 @@ endif | |||
ifeq ($(HAVE_OPENGL),true) | |||
endif | |||
ifeq ($(HAVE_VULKAN),true) | |||
endif | |||
# --------------------------------------------------------------------------------------------------------------------- | |||
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 $@ | |||
../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 | |||
-@mkdir -p ../build/tests | |||
@@ -105,9 +98,23 @@ all: $(TARGETS) | |||
$(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" | |||
#define DPF_TEST_WINDOW_CPP | |||
#define DPF_TEST_POINT_CPP | |||
#include "dgl/src/pugl.cpp" | |||
#include "dgl/src/Application.cpp" | |||
#include "dgl/src/ApplicationPrivateData.cpp" | |||
#include "dgl/src/Geometry.cpp" | |||
#include "dgl/src/Window.cpp" | |||
#include "dgl/src/WindowPrivateData.cpp" | |||
@@ -35,11 +37,27 @@ int main() | |||
using DGL_NAMESPACE::Window; | |||
// creating simple window | |||
// creating and destroying simple window | |||
{ | |||
Application app(true); | |||
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 | |||
@@ -14,10 +14,40 @@ | |||
* 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) \ | |||
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) \ | |||
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 |