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

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

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

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

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

#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)
if (yesNo)
{
@@ -599,8 +634,11 @@ struct Window::PrivateData {

#if defined(DISTRHO_OS_HAIKU)
// TODO
// B_NO_BORDER
// B_TITLED_WINDOW_LOOK
// bWindow->SetFlags();
#elif defined(DISTRHO_OS_MAC)
const uint flags(yesNo ? (NSViewWidthSizable|NSViewHeightSizable) : 0x0);
const uint flags = yesNo ? (NSViewWidthSizable|NSViewHeightSizable) : 0x0;
[mView setAutoresizingMask:flags];
#elif defined(DISTRHO_OS_WINDOWS)
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");

#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)
[mView setFrame:NSMakeRect(0, 0, width, height)];

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

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

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

#if defined(DISTRHO_OS_HAIKU)
BWindow* bWindow;
BApplication* bApplication;
BView* bView;
BWindow* bWindow;
#elif defined(DISTRHO_OS_MAC)
bool fNeedsIdle;
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.
*/

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

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

#include "pugl_internal.h"

class DWindow;

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*
puglInitInternals()
{
@@ -42,48 +80,253 @@ puglInitInternals()
void
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
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
{
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:
PuglInternals* const impl;
PuglView* const puglView;
bool needsQuit;
};

int
puglCreateWindow(PuglView* view, const char* title)
{
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;
}

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

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

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

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

void
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
@@ -96,12 +339,19 @@ void
puglPostRedisplay(PuglView* view)
{
view->redisplay = true;
view->impl->view->Invalidate();
}

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

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

return (PuglNativeWindow)impl->view;
}

void*
@@ -113,11 +363,15 @@ puglGetContext(PuglView* view)
int
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;
}

+ 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:
GetClientRect(view->impl->hwnd, &rect);
puglReshape(view, rect.right, rect.bottom);
view->width = rect.right;
view->height = rect.bottom;
break;
case WM_GETMINMAXINFO:
mmi = (MINMAXINFO*)lParam;


Loading…
Cancel
Save