Browse Source

Add the needed bits to make window visible, setting size

Signed-off-by: falkTX <falktx@falktx.com>
pull/272/head
falkTX 4 years ago
parent
commit
05c6d04adb
15 changed files with 642 additions and 385 deletions
  1. +0
    -5
      dgl/Application.hpp
  2. +1
    -1
      dgl/Cairo.hpp
  3. +73
    -15
      dgl/Window.hpp
  4. +4
    -2
      dgl/src/ApplicationPrivateData.cpp
  5. +2
    -2
      dgl/src/ApplicationPrivateData.hpp
  6. +87
    -67
      dgl/src/Window.cpp
  7. +287
    -233
      dgl/src/WindowPrivateData.cpp
  8. +22
    -5
      dgl/src/WindowPrivateData.hpp
  9. +1
    -1
      dgl/src/pugl-upstream
  10. +72
    -4
      dgl/src/pugl.cpp
  11. +12
    -0
      dgl/src/pugl.hpp
  12. +0
    -24
      tests/Application.cpp
  13. +30
    -23
      tests/Makefile
  14. +20
    -2
      tests/Window.cpp
  15. +31
    -1
      tests/tests.hpp

+ 0
- 5
dgl/Application.hpp View File

@@ -21,11 +21,6 @@

START_NAMESPACE_DGL

// --------------------------------------------------------------------------------------------------------------------
// Forward class names

class Window;

// --------------------------------------------------------------------------------------------------------------------

/**


+ 1
- 1
dgl/Cairo.hpp View File

@@ -30,7 +30,7 @@ START_NAMESPACE_DGL
*/
struct CairoGraphicsContext : GraphicsContext
{
cairo_t* cairo; // FIXME proper name..
cairo_t* handle;
};

// -----------------------------------------------------------------------


+ 73
- 15
dgl/Window.hpp View File

@@ -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


+ 4
- 2
dgl/src/ApplicationPrivateData.cpp View File

@@ -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


+ 2
- 2
dgl/src/ApplicationPrivateData.hpp View File

@@ -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);


+ 87
- 67
dgl/src/Window.cpp View File

@@ -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()
{
}


+ 287
- 233
dgl/src/WindowPrivateData.cpp View File

@@ -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

+ 22
- 5
dgl/src/WindowPrivateData.hpp View File

@@ -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
dgl/src/pugl-upstream

@@ -1 +1 @@
Subproject commit 5a3a1309ad6432d72cdb7f37e3e36383dd6ba372
Subproject commit b0a018a006c5d7d7796074b86c1b69f8671d2d83

+ 72
- 4
dgl/src/pugl.cpp View File

@@ -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

+ 12
- 0
dgl/src/pugl.hpp View File

@@ -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


+ 0
- 24
tests/Application.cpp View File

@@ -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;


+ 30
- 23
tests/Makefile View File

@@ -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 $@

# ---------------------------------------------------------------------------------------------------------------------



+ 20
- 2
tests/Window.cpp View File

@@ -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


+ 31
- 1
tests/tests.hpp View File

@@ -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

Loading…
Cancel
Save