Browse Source

Incomplete but sorta working initial Haiku support, WIP

See https://nextcloud.falktx.com/s/SGsiLLHJ7Qn4PDj/preview
and https://nextcloud.falktx.com/s/w7qsZigFNTHFrmw/preview

Great times ahead!
pull/178/head
falkTX 5 years ago
parent
commit
20a464142a
Signed by: falkTX <falktx@gmail.com> GPG Key ID: 2D3445A829213837
3 changed files with 330 additions and 20 deletions
  1. +64
    -6
      dgl/src/Window.cpp
  2. +266
    -12
      dgl/src/pugl/pugl_haiku.cpp
  3. +0
    -2
      dgl/src/pugl/pugl_win.cpp

+ 64
- 6
dgl/src/Window.cpp View File

@@ -38,6 +38,7 @@
#endif #endif


#if defined(DISTRHO_OS_HAIKU) #if defined(DISTRHO_OS_HAIKU)
# define DGL_DEBUG_EVENTS
# include "pugl/pugl_haiku.cpp" # include "pugl/pugl_haiku.cpp"
#elif defined(DISTRHO_OS_MAC) #elif defined(DISTRHO_OS_MAC)
# define PuglWindow DISTRHO_JOIN_MACRO(PuglWindow, DGL_NAMESPACE) # define PuglWindow DISTRHO_JOIN_MACRO(PuglWindow, DGL_NAMESPACE)
@@ -102,6 +103,8 @@ struct Window::PrivateData {
fWidgets(), fWidgets(),
fModal(), fModal(),
#if defined(DISTRHO_OS_HAIKU) #if defined(DISTRHO_OS_HAIKU)
bApplication(nullptr),
bView(nullptr),
bWindow(nullptr) bWindow(nullptr)
#elif defined(DISTRHO_OS_MAC) #elif defined(DISTRHO_OS_MAC)
fNeedsIdle(true), fNeedsIdle(true),
@@ -140,6 +143,8 @@ struct Window::PrivateData {
fWidgets(), fWidgets(),
fModal(parent.pData), fModal(parent.pData),
#if defined(DISTRHO_OS_HAIKU) #if defined(DISTRHO_OS_HAIKU)
bApplication(nullptr),
bView(nullptr),
bWindow(nullptr) bWindow(nullptr)
#elif defined(DISTRHO_OS_MAC) #elif defined(DISTRHO_OS_MAC)
fNeedsIdle(false), fNeedsIdle(false),
@@ -192,6 +197,8 @@ struct Window::PrivateData {
fWidgets(), fWidgets(),
fModal(), fModal(),
#if defined(DISTRHO_OS_HAIKU) #if defined(DISTRHO_OS_HAIKU)
bApplication(nullptr),
bView(nullptr),
bWindow(nullptr) bWindow(nullptr)
#elif defined(DISTRHO_OS_MAC) #elif defined(DISTRHO_OS_MAC)
fNeedsIdle(parentId == 0), fNeedsIdle(parentId == 0),
@@ -260,7 +267,9 @@ struct Window::PrivateData {
PuglInternals* impl = fView->impl; PuglInternals* impl = fView->impl;


#if defined(DISTRHO_OS_HAIKU) #if defined(DISTRHO_OS_HAIKU)
bWindow = impl->window;
bApplication = impl->app;
bView = impl->view;
bWindow = impl->window;
#elif defined(DISTRHO_OS_MAC) #elif defined(DISTRHO_OS_MAC)
mView = impl->view; mView = impl->view;
mWindow = impl->window; mWindow = impl->window;
@@ -293,7 +302,6 @@ struct Window::PrivateData {
XInternAtom(xDisplay, "_NET_WM_WINDOW_TYPE_NORMAL", False) XInternAtom(xDisplay, "_NET_WM_WINDOW_TYPE_NORMAL", False)
}; };
XChangeProperty(xDisplay, xWindow, _wt, XA_ATOM, 32, PropModeReplace, (const uchar*)&_wts, 2); XChangeProperty(xDisplay, xWindow, _wt, XA_ATOM, 32, PropModeReplace, (const uchar*)&_wts, 2);

} }
#endif #endif
puglEnterContext(fView); puglEnterContext(fView);
@@ -340,6 +348,9 @@ struct Window::PrivateData {
} }


#if defined(DISTRHO_OS_HAIKU) #if defined(DISTRHO_OS_HAIKU)
bApplication = nullptr;
bView = nullptr;
bWindow = nullptr;
#elif defined(DISTRHO_OS_MAC) #elif defined(DISTRHO_OS_MAC)
mView = nullptr; mView = nullptr;
mWindow = nullptr; mWindow = nullptr;
@@ -456,6 +467,10 @@ struct Window::PrivateData {
{ {
DBG("Window focus\n"); DBG("Window focus\n");
#if defined(DISTRHO_OS_HAIKU) #if defined(DISTRHO_OS_HAIKU)
if (bWindow != nullptr)
bWindow->Activate(true);
else
bView->MakeFocus(true);
#elif defined(DISTRHO_OS_MAC) #elif defined(DISTRHO_OS_MAC)
if (mWindow != nullptr) if (mWindow != nullptr)
[mWindow makeKeyWindow]; [mWindow makeKeyWindow];
@@ -493,7 +508,27 @@ struct Window::PrivateData {
setSize(fWidth, fHeight, true); setSize(fWidth, fHeight, true);


#if defined(DISTRHO_OS_HAIKU) #if defined(DISTRHO_OS_HAIKU)
// TODO
if (bWindow != nullptr)
{
if (yesNo)
{

bView->Show();
bWindow->Show();
}
else
bWindow->Hide();

// TODO use flush?
bWindow->Sync();
}
else
{
if (yesNo)
bView->Show();
else
bView->Hide();
}
#elif defined(DISTRHO_OS_MAC) #elif defined(DISTRHO_OS_MAC)
if (yesNo) if (yesNo)
{ {
@@ -599,8 +634,11 @@ struct Window::PrivateData {


#if defined(DISTRHO_OS_HAIKU) #if defined(DISTRHO_OS_HAIKU)
// TODO // TODO
// B_NO_BORDER
// B_TITLED_WINDOW_LOOK
// bWindow->SetFlags();
#elif defined(DISTRHO_OS_MAC) #elif defined(DISTRHO_OS_MAC)
const uint flags(yesNo ? (NSViewWidthSizable|NSViewHeightSizable) : 0x0);
const uint flags = yesNo ? (NSViewWidthSizable|NSViewHeightSizable) : 0x0;
[mView setAutoresizingMask:flags]; [mView setAutoresizingMask:flags];
#elif defined(DISTRHO_OS_WINDOWS) #elif defined(DISTRHO_OS_WINDOWS)
const int winFlags = fResizable ? GetWindowLong(hwnd, GWL_STYLE) | WS_SIZEBOX const int winFlags = fResizable ? GetWindowLong(hwnd, GWL_STYLE) | WS_SIZEBOX
@@ -645,7 +683,16 @@ struct Window::PrivateData {
DBGp("Window setSize called %s, size %i %i, resizable %s\n", forced ? "(forced)" : "(not forced)", width, height, fResizable?"true":"false"); DBGp("Window setSize called %s, size %i %i, resizable %s\n", forced ? "(forced)" : "(not forced)", width, height, fResizable?"true":"false");


#if defined(DISTRHO_OS_HAIKU) #if defined(DISTRHO_OS_HAIKU)
// TODO
bView->ResizeTo(width, height);

if (bWindow != nullptr)
{
bWindow->ResizeTo(width, height);

if (! forced)
bWindow->Flush();
}
// TODO resizable
#elif defined(DISTRHO_OS_MAC) #elif defined(DISTRHO_OS_MAC)
[mView setFrame:NSMakeRect(0, 0, width, height)]; [mView setFrame:NSMakeRect(0, 0, width, height)];


@@ -807,6 +854,15 @@ struct Window::PrivateData {
{ {
puglProcessEvents(fView); puglProcessEvents(fView);


#ifdef DISTRHO_OS_HAIKU
if (bApplication != nullptr)
{
bApplication->Lock();
// bApplication->Loop();
bApplication->Unlock();
}
#endif

#ifdef DISTRHO_OS_MAC #ifdef DISTRHO_OS_MAC
if (fNeedsIdle) if (fNeedsIdle)
{ {
@@ -1192,7 +1248,9 @@ struct Window::PrivateData {
} fModal; } fModal;


#if defined(DISTRHO_OS_HAIKU) #if defined(DISTRHO_OS_HAIKU)
BWindow* bWindow;
BApplication* bApplication;
BView* bView;
BWindow* bWindow;
#elif defined(DISTRHO_OS_MAC) #elif defined(DISTRHO_OS_MAC)
bool fNeedsIdle; bool fNeedsIdle;
NSView<PuglGenericView>* mView; NSView<PuglGenericView>* mView;


+ 266
- 12
dgl/src/pugl/pugl_haiku.cpp View File

@@ -18,21 +18,59 @@
@file pugl_haiku.cpp BeOS/HaikuOS Pugl Implementation. @file pugl_haiku.cpp BeOS/HaikuOS Pugl Implementation.
*/ */


#include <Application.h>
#include <interface/Window.h> #include <interface/Window.h>


#ifdef PUGL_CAIRO #ifdef PUGL_CAIRO
#include <cairo/cairo.h> #include <cairo/cairo.h>
typedef BView BViewType;
#endif #endif
#ifdef PUGL_OPENGL #ifdef PUGL_OPENGL
#include <GL/gl.h> #include <GL/gl.h>
#include <opengl/GLView.h>
typedef BGLView BViewType;
#endif #endif


#include "pugl_internal.h" #include "pugl_internal.h"


class DWindow;

struct PuglInternalsImpl { struct PuglInternalsImpl {
BWindow* window;
BApplication* app;
BViewType* view;
DWindow* window;
}; };


static void
puglReshape(PuglView* view, int width, int height)
{
puglEnterContext(view);

if (view->reshapeFunc) {
view->reshapeFunc(view, width, height);
} else {
puglDefaultReshape(width, height);
}

puglLeaveContext(view, false);

view->width = width;
view->height = height;
}

static void
puglDisplay(PuglView* view)
{
puglEnterContext(view);

view->redisplay = false;
if (view->displayFunc) {
view->displayFunc(view);
}

puglLeaveContext(view, true);
}

PuglInternals* PuglInternals*
puglInitInternals() puglInitInternals()
{ {
@@ -42,48 +80,253 @@ puglInitInternals()
void void
puglEnterContext(PuglView* view) puglEnterContext(PuglView* view)
{ {
#ifdef PUGL_OPENGL
PuglInternals* impl = view->impl;

// FIXME without the first unlock we freeze
impl->view->UnlockGL();
impl->view->LockGL();
#endif
} }


void void
puglLeaveContext(PuglView* view, bool flush) puglLeaveContext(PuglView* view, bool flush)
{ {
#ifdef PUGL_OPENGL
PuglInternals* impl = view->impl;

if (flush)
impl->view->SwapBuffers(true);

impl->view->UnlockGL();
#endif
} }


class DView : public BViewType
{
public:
#ifdef PUGL_CAIRO
DView(PuglView* const v)
: BView(nullptr,
B_FULL_UPDATE_ON_RESIZE|B_WILL_DRAW|B_FRAME_EVENTS|B_NAVIGABLE|B_INPUT_METHOD_AWARE),
puglView(v) {}
#endif

#ifdef PUGL_OPENGL
DView(PuglView* const v)
: BGLView(BRect(512.0f),
"DPF-GLView",
0x0, // resize mode
B_FULL_UPDATE_ON_RESIZE|B_WILL_DRAW|B_FRAME_EVENTS|B_NAVIGABLE|B_INPUT_METHOD_AWARE,
BGL_RGB /*|BGL_DOUBLE|BGL_ALPHA|BGL_DEPTH|BGL_STENCIL*/),
puglView(v) {}
#endif

protected:
void Draw(BRect updateRect) override
{
d_stdout("%s %i", __func__, __LINE__);
puglDisplay(puglView);
d_stdout("%s %i", __func__, __LINE__);
#ifdef PUGL_OPENGL
BGLView::Draw(updateRect);
#endif
d_stdout("%s %i", __func__, __LINE__);
}

void MouseDown(BPoint where) override
{
if (puglView->mouseFunc) {
// puglView->event_timestamp_ms = GetMessageTime();
puglView->mouseFunc(puglView, 1, true, where.x, where.y);
}
}

void MouseUp(BPoint where) override
{
if (puglView->mouseFunc) {
// puglView->event_timestamp_ms = GetMessageTime();
puglView->mouseFunc(puglView, 1, false, where.x, where.y);
}
}

void MouseMoved(BPoint where, uint32, const BMessage*) override
{
if (puglView->motionFunc) {
// puglView->event_timestamp_ms = GetMessageTime();
puglView->motionFunc(puglView, where.x, where.y);
}
}

void KeyDown(const char* bytes, int32 numBytes) override
{
d_stdout("KeyDown %s %i", bytes, numBytes);
if (numBytes != 1)
return; // TODO
if (puglView->keyboardFunc) {
puglView->keyboardFunc(puglView, true, bytes[0]);
}
}

void KeyUp(const char* bytes, int32 numBytes) override
{
if (numBytes != 1)
return; // TODO
if (puglView->keyboardFunc) {
puglView->keyboardFunc(puglView, false, bytes[0]);
}
}

void FrameResized(float newWidth, float newHeight) override
{
d_stdout("%s %i", __func__, __LINE__);
const int width = static_cast<int>(newWidth);
const int height = static_cast<int>(newHeight);

puglReshape(puglView, width, height);
d_stdout("%s %i", __func__, __LINE__);
puglView->width = width;
puglView->height = height;
d_stdout("%s %i", __func__, __LINE__);
#ifdef PUGL_OPENGL
BGLView::FrameResized(newWidth, newHeight);
#endif
d_stdout("%s %i", __func__, __LINE__);
}

private:
PuglView* const puglView;
};

class DWindow : public BWindow class DWindow : public BWindow
{ {
public: public:
DWindow(PuglInternals* const i)
: BWindow(BRect(), "", B_TITLED_WINDOW, 0x0),
impl(i)
DWindow(PuglView* const v)
: BWindow(BRect(1.0f), "DPF-Window", B_TITLED_WINDOW, 0x0),
puglView(v),
needsQuit(true)
{
}
bool NeedsQuit() const
{
return needsQuit;
}

protected:
bool QuitRequested() override
{ {
d_stdout("%s %i", __func__, __LINE__);
if (puglView->closeFunc) {
puglView->closeFunc(puglView);
puglView->redisplay = false;
}
needsQuit = false;
d_stdout("%s %i", __func__, __LINE__);
return true;
} }


private: private:
PuglInternals* const impl;
PuglView* const puglView;
bool needsQuit;
}; };


int int
puglCreateWindow(PuglView* view, const char* title) puglCreateWindow(PuglView* view, const char* title)
{ {
PuglInternals* impl = view->impl; PuglInternals* impl = view->impl;

if (be_app == nullptr)
{
status_t status;
BApplication* const app = new BApplication("application/x-vnd.dpf-application", &status);

if (status != B_OK)
{
d_stdout("app status error %u", status);
delete app;
return 1;
}

impl->app = app;
}
if (view->parent == 0) {
impl->window = new DWindow(view);
impl->window->Lock();
}

impl->view = new DView(view);

if (view->parent != 0) {
BView* const pview = (BView*)view->parent;
pview->AddChild(impl->view);
impl->view->LockGL();
return 0;
}

if (title != nullptr) {
impl->window->SetTitle(title);
}
impl->window = new DWindow(impl);
impl->window->AddChild(impl->view);
puglEnterContext(view);
impl->window->Unlock();
return 0; return 0;
} }


void void
puglShowWindow(PuglView* view) puglShowWindow(PuglView* view)
{ {
PuglInternals* impl = view->impl;

if (impl->window != nullptr)
impl->window->Show();
else
impl->view->Show();
} }


void void
puglHideWindow(PuglView* view) puglHideWindow(PuglView* view)
{ {
PuglInternals* impl = view->impl;

if (impl->window != nullptr)
impl->window->Hide();
else
impl->view->Show();
} }


void void
puglDestroy(PuglView* view) puglDestroy(PuglView* view)
{ {
PuglInternals* impl = view->impl;

if (impl->window != nullptr)
{
// impl->window->Lock();
puglLeaveContext(view, false);
impl->window->RemoveChild(impl->view);
// impl->window->Unlock();

if (impl->window->NeedsQuit())
impl->window->Quit();
}

delete impl->view;
impl->view = nullptr;
impl->window = nullptr;

if (impl->app != nullptr && impl->app->CountWindows() == 0)
{
d_stdout("deleting app");
delete impl->app;
impl->app = nullptr;
} else
d_stdout("NOT deleting app");
} }


PuglStatus PuglStatus
@@ -96,12 +339,19 @@ void
puglPostRedisplay(PuglView* view) puglPostRedisplay(PuglView* view)
{ {
view->redisplay = true; view->redisplay = true;
view->impl->view->Invalidate();
} }


PuglNativeWindow PuglNativeWindow
puglGetNativeWindow(PuglView* view) puglGetNativeWindow(PuglView* view)
{ {
return NULL;
PuglInternals* impl = view->impl;

#ifdef PUGL_OPENGL
// return (PuglNativeWindow)impl->view->EmbeddedView();
#endif

return (PuglNativeWindow)impl->view;
} }


void* void*
@@ -113,11 +363,15 @@ puglGetContext(PuglView* view)
int int
puglUpdateGeometryConstraints(PuglView* view, int min_width, int min_height, bool aspect) puglUpdateGeometryConstraints(PuglView* view, int min_width, int min_height, bool aspect)
{ {
// TODO
return 1;
PuglInternals* impl = view->impl;

d_stdout("puglUpdateGeometryConstraints %i %i %i %i", min_width, min_height, view->width, view->height);
impl->window->SetSizeLimits(min_width,
view->user_resizable ? 4096 : min_width,
min_height,
view->user_resizable ? 4096 : min_height);
return 0;


(void)view;
(void)min_width;
(void)min_height;
// TODO
(void)aspect; (void)aspect;
} }

+ 0
- 2
dgl/src/pugl/pugl_win.cpp View File

@@ -392,8 +392,6 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
case WM_SIZE: case WM_SIZE:
GetClientRect(view->impl->hwnd, &rect); GetClientRect(view->impl->hwnd, &rect);
puglReshape(view, rect.right, rect.bottom); puglReshape(view, rect.right, rect.bottom);
view->width = rect.right;
view->height = rect.bottom;
break; break;
case WM_GETMINMAXINFO: case WM_GETMINMAXINFO:
mmi = (MINMAXINFO*)lParam; mmi = (MINMAXINFO*)lParam;


Loading…
Cancel
Save