Browse Source

Add stubs for Haiku, does not work yet

Signed-off-by: falkTX <falktx@falktx.com>
pull/401/head
falkTX 2 years ago
parent
commit
95e66eba1b
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
8 changed files with 515 additions and 60 deletions
  1. +12
    -7
      Makefile.base.mk
  2. +342
    -21
      dgl/src/pugl-extra/haiku.cpp
  3. +12
    -22
      dgl/src/pugl-extra/haiku.h
  4. +87
    -0
      dgl/src/pugl-extra/haiku_gl.cpp
  5. +24
    -0
      dgl/src/pugl-extra/haiku_stub.cpp
  6. +1
    -1
      dgl/src/pugl-extra/wasm_gl.c
  7. +32
    -8
      dgl/src/pugl.cpp
  8. +5
    -1
      dgl/src/pugl.hpp

+ 12
- 7
Makefile.base.mk View File

@@ -272,7 +272,10 @@ BASE_OPTS = -O2 -ffast-math -fdata-sections -ffunction-sections
endif

ifeq ($(DEBUG),true)
BASE_FLAGS += -DDEBUG -O0 -g -fsanitize=address
BASE_FLAGS += -DDEBUG -O0 -g
ifneq ($(HAIKU),true)
BASE_FLAGS += -fsanitize=address
endif
LINK_OPTS =
ifeq ($(WASM),true)
LINK_OPTS += -sASSERTIONS=1
@@ -347,9 +350,11 @@ endif
# ---------------------------------------------------------------------------------------------------------------------
# Check for required libraries

HAVE_CAIRO = $(shell $(PKG_CONFIG) --exists cairo && echo true)
ifneq ($(HAIKU),true)
HAVE_CAIRO = $(shell $(PKG_CONFIG) --exists cairo && echo true)
endif

ifeq ($(MACOS_OR_WASM_OR_WINDOWS),true)
ifeq ($(HAIKU_OR_MACOS_OR_WASM_OR_WINDOWS),true)
HAVE_OPENGL = true
else
HAVE_OPENGL = $(shell $(PKG_CONFIG) --exists gl && echo true)
@@ -454,8 +459,8 @@ ifeq ($(HAVE_OPENGL),true)
DGL_FLAGS += -DHAVE_OPENGL

ifeq ($(HAIKU),true)
OPENGL_FLAGS = $(shell $(PKG_CONFIG) --cflags gl)
OPENGL_LIBS = $(shell $(PKG_CONFIG) --libs gl)
OPENGL_FLAGS =
OPENGL_LIBS = -lGL
else ifeq ($(MACOS),true)
OPENGL_FLAGS = -DGL_SILENCE_DEPRECATION=1 -Wno-deprecated-declarations
OPENGL_LIBS = -framework OpenGL
@@ -481,7 +486,7 @@ endif
# ---------------------------------------------------------------------------------------------------------------------
# Set Stub specific stuff

ifeq ($(MACOS_OR_WASM_OR_WINDOWS),true)
ifeq ($(HAIKU_OR_MACOS_OR_WASM_OR_WINDOWS),true)
HAVE_STUB = true
else
HAVE_STUB = $(HAVE_X11)
@@ -540,7 +545,7 @@ endif
# ---------------------------------------------------------------------------------------------------------------------
# Backwards-compatible HAVE_DGL

ifeq ($(MACOS_OR_WASM_OR_WINDOWS),true)
ifeq ($(HAIKU_OR_MACOS_OR_WASM_OR_WINDOWS),true)
HAVE_DGL = true
else ifeq ($(HAVE_OPENGL),true)
HAVE_DGL = $(HAVE_X11)


+ 342
- 21
dgl/src/pugl-extra/haiku.cpp View File

@@ -1,28 +1,348 @@
/*
Copyright 2012-2019 David Robillard <http://drobilla.net>
Copyright 2019-2020 Filipe Coelho <falktx@falktx.com>

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

/**
@file mac.cpp HaikuOS implementation.
*/
// Copyright 2012-2022 David Robillard <d@drobilla.net>
// Copyright 2021-2022 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: ISC

#include "haiku.h"

#include "pugl/detail/implementation.h"
#include "../pugl-upstream/src/internal.h"

class PuglHaikuView : public BView
{
PuglView* const view;

public:
PuglHaikuView(PuglView* const v)
: BView(NULL, B_FULL_UPDATE_ON_RESIZE|B_FRAME_EVENTS|B_NAVIGABLE|B_INPUT_METHOD_AWARE),
view(v) {}

protected:
void GetPreferredSize(float* width, float* height) override
{
d_stdout("%s %i", __func__, __LINE__);
if (width != nullptr)
*width = view->frame.width;
if (height != nullptr)
*height = view->frame.height;
d_stdout("%s %i", __func__, __LINE__);
}
};

class PuglHaikuWindow : public BWindow
{
PuglView* const view;

public:
PuglHaikuWindow(PuglView* const v)
: BWindow(BRect(1.0f), "DPF-Window", B_TITLED_WINDOW, 0x0),
view(v) {}

// 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;
// }
};

BApplication* s_app = NULL;

PuglWorldInternals*
puglInitWorldInternals(const PuglWorldType type, const PuglWorldFlags flags)
{
if (!s_app) {
status_t status;
s_app = new BApplication("application/x-vnd.pugl-application", &status);
if (status != B_OK) {
delete s_app;
return NULL;
}
}

PuglWorldInternals* impl =
(PuglWorldInternals*)calloc(1, sizeof(PuglWorldInternals));

impl->app = s_app;
return impl;
}

void*
puglGetNativeWorld(PuglWorld* const world)
{
return world->impl->app;
}

PuglInternals*
puglInitViewInternals(PuglWorld* const world)
{
PuglInternals* impl = (PuglInternals*)calloc(1, sizeof(PuglInternals));

return impl;
}

PuglStatus
puglRealize(PuglView* const view)
{
PuglInternals* const impl = view->impl;
PuglStatus st = PUGL_SUCCESS;

// Ensure that we're unrealized and that a reasonable backend has been set
if (impl->view) {
return PUGL_FAILURE;
}
if (!view->backend || !view->backend->configure) {
return PUGL_BAD_BACKEND;
}

// Set the size to the default if it has not already been set
if (view->frame.width <= 0.0 || view->frame.height <= 0.0) {
const PuglViewSize defaultSize = view->sizeHints[PUGL_DEFAULT_SIZE];
if (!defaultSize.width || !defaultSize.height) {
return PUGL_BAD_CONFIGURATION;
}

view->frame.width = defaultSize.width;
view->frame.height = defaultSize.height;
}

// Center top-level windows if a position has not been set
if (!view->parent && !view->frame.x && !view->frame.y) {
// TODO
}

if (!view->parent) {
impl->window = new PuglHaikuWindow(view);
impl->window->Lock();
}

impl->view = new PuglHaikuView(view);

if (view->parent) {
BView* const pview = (BView*)view->parent;
pview->AddChild(impl->view);
} else {
impl->window->AddChild(impl->view);
}

// Configure and create the backend
if ((st = view->backend->configure(view)) || (st = view->backend->create(view))) {
view->backend->destroy(view);
return st;
}

if (view->title) {
puglSetWindowTitle(view, view->title);
}

if (view->transientParent) {
puglSetTransientParent(view, view->transientParent);
}

puglDispatchSimpleEvent(view, PUGL_CREATE);

if (impl->window) {
impl->window->Unlock();
}

return PUGL_SUCCESS;
}

PuglStatus
puglShow(PuglView* const view)
{
PuglInternals* const impl = view->impl;
if (impl->window) {
impl->window->Show();
} else {
impl->view->Show();
}
return PUGL_SUCCESS;
}

PuglStatus
puglHide(PuglView* const view)
{
PuglInternals* const impl = view->impl;
if (impl->window) {
impl->window->Hide();
} else {
impl->view->Hide();
}
return PUGL_SUCCESS;
}

void
puglFreeViewInternals(PuglView* const view)
{
if (view && view->impl) {
PuglInternals* const impl = view->impl;
if (view->backend) {
view->backend->destroy(view);
}
if (impl->view) {
if (impl->window) {
impl->window->RemoveChild(impl->view);
}
delete impl->view;
delete impl->window;
}
free(impl);
}
}

void
puglFreeWorldInternals(PuglWorld* const world)
{
// if (world->impl->app != nullptr && world->impl->app->CountWindows() == 0) {
// delete world->impl->app;
// s_app = NULL;
// }
free(world->impl);
}

PuglStatus
puglGrabFocus(PuglView*)
{
return PUGL_UNSUPPORTED;
}

double
puglGetScaleFactor(const PuglView* const view)
{
return 1.0;
}

double
puglGetTime(const PuglWorld* const world)
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return ((double)ts.tv_sec + (double)ts.tv_nsec / 1000000000.0) -
world->startTime;
}

PuglStatus
puglUpdate(PuglWorld* const world, const double timeout)
{
return PUGL_UNSUPPORTED;
}

PuglStatus
puglPostRedisplay(PuglView* const view)
{
return PUGL_UNSUPPORTED;
}

PuglStatus
puglPostRedisplayRect(PuglView* const view, const PuglRect rect)
{
return PUGL_UNSUPPORTED;
}

PuglNativeView
puglGetNativeView(PuglView* const view)
{
return 0;
}

PuglStatus
puglSetWindowTitle(PuglView* const view, const char* const title)
{
puglSetString(&view->title, title);
return PUGL_UNSUPPORTED;
}

PuglStatus
puglSetSizeHint(PuglView* const view,
const PuglSizeHint hint,
const PuglSpan width,
const PuglSpan height)
{
view->sizeHints[hint].width = width;
view->sizeHints[hint].height = height;
return PUGL_SUCCESS;
}

PuglStatus
puglStartTimer(PuglView* const view, const uintptr_t id, const double timeout)
{
return PUGL_UNSUPPORTED;
}

PuglStatus
puglStopTimer(PuglView* const view, const uintptr_t id)
{
return PUGL_UNSUPPORTED;
}

PuglStatus
puglPaste(PuglView* const view)
{
return PUGL_UNSUPPORTED;
}

PuglStatus
puglAcceptOffer(PuglView* const view,
const PuglDataOfferEvent* const offer,
const uint32_t typeIndex)
{
return PUGL_UNSUPPORTED;
}

uint32_t
puglGetNumClipboardTypes(const PuglView* const view)
{
return 0u;
}

const char*
puglGetClipboardType(const PuglView* const view, const uint32_t typeIndex)
{
return NULL;
}

const void*
puglGetClipboard(PuglView* const view,
const uint32_t typeIndex,
size_t* const len)
{
return NULL;
}

PuglStatus
puglSetClipboard(PuglView* const view,
const char* const type,
const void* const data,
const size_t len)
{
return PUGL_FAILURE;
}

PuglStatus
puglSetCursor(PuglView* const view, const PuglCursor cursor)
{
return PUGL_FAILURE;
}

PuglStatus
puglSetTransientParent(PuglView* const view, const PuglNativeView parent)
{
return PUGL_FAILURE;
}

PuglStatus
puglSetPosition(PuglView* const view, const int x, const int y)
{
return PUGL_FAILURE;
}

#if 0
PuglStatus
puglGrabFocus(PuglView* view)
{
@@ -79,3 +399,4 @@ void setVisible(const bool yesNo)
bView->Hide();
}
}
#endif

+ 12
- 22
dgl/src/pugl-extra/haiku.h View File

@@ -1,35 +1,25 @@
/*
Copyright 2012-2019 David Robillard <http://drobilla.net>
Copyright 2019-2020 Filipe Coelho <falktx@falktx.com>
// Copyright 2012-2022 David Robillard <d@drobilla.net>
// Copyright 2021-2022 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: ISC

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
#ifndef PUGL_SRC_HAIKU_H
#define PUGL_SRC_HAIKU_H

THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

/**
@file haiku.h Shared definitions for HaikuOS implementation.
*/
#include "../pugl-upstream/src/types.h"

#include "pugl/pugl.h"

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

struct PuglWorldInternalsImpl {
BApplication* app;
BApplication* app;
};

struct PuglInternalsImpl {
BViewType* view;
BWindow* window;
PuglSurface* surface;
BView* view;
BWindow* window;
};

#endif // PUGL_SRC_HAIKU_H

+ 87
- 0
dgl/src/pugl-extra/haiku_gl.cpp View File

@@ -0,0 +1,87 @@
// Copyright 2012-2022 David Robillard <d@drobilla.net>
// Copyright 2021-2022 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: ISC

#include "../pugl-upstream/src/stub.h"
#include "haiku.h"

#include "pugl/pugl.h"

#include <stdio.h>
#include <stdlib.h>

#include <GL/gl.h>
#include <opengl/GLView.h>

typedef struct {
BGLView* view;
} PuglHaikuGlSurface;

static PuglStatus
puglHaikuGlConfigure(PuglView* view)
{
PuglInternals* const impl = view->impl;

PuglHaikuGlSurface* const surface =
(PuglHaikuGlSurface*)calloc(1, sizeof(PuglHaikuGlSurface));
impl->surface = surface;

return PUGL_SUCCESS;
}

PUGL_WARN_UNUSED_RESULT
static PuglStatus
puglHaikuGlEnter(PuglView* const view, const PuglExposeEvent* PUGL_UNUSED(expose))
{
PuglHaikuGlSurface* const surface = (PuglHaikuGlSurface*)view->impl->surface;
if (!surface || !surface->view) {
return PUGL_FAILURE;
}

surface->view->LockGL();
return PUGL_SUCCESS;
}

PUGL_WARN_UNUSED_RESULT
static PuglStatus
puglHaikuGlLeave(PuglView* const view, const PuglExposeEvent* const expose)
{
PuglHaikuGlSurface* const surface = (PuglHaikuGlSurface*)view->impl->surface;
if (!surface || !surface->view) {
return PUGL_FAILURE;
}

if (expose)
surface->view->SwapBuffers();

surface->view->UnlockGL();
return PUGL_SUCCESS;
}

static PuglStatus
puglHaikuGlCreate(PuglView* view)
{
return PUGL_SUCCESS;
}

static void
puglHaikuGlDestroy(PuglView* view)
{
PuglHaikuGlSurface* surface = (PuglHaikuGlSurface*)view->impl->surface;
if (surface) {
free(surface);
view->impl->surface = NULL;
}
}

const PuglBackend*
puglGlBackend(void)
{
static const PuglBackend backend = {puglHaikuGlConfigure,
puglHaikuGlCreate,
puglHaikuGlDestroy,
puglHaikuGlEnter,
puglHaikuGlLeave,
puglStubGetContext};
return &backend;
}

+ 24
- 0
dgl/src/pugl-extra/haiku_stub.cpp View File

@@ -0,0 +1,24 @@
// Copyright 2012-2022 David Robillard <d@drobilla.net>
// Copyright 2021-2022 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: ISC

#include "pugl/stub.h"

#include "../pugl-upstream/src/stub.h"

#include "pugl/pugl.h"

const PuglBackend*
puglStubBackend(void)
{
static const PuglBackend backend = {
puglStubConfigure,
puglStubCreate,
puglStubDestroy,
puglStubEnter,
puglStubLeave,
puglStubGetContext,
};

return &backend;
}

+ 1
- 1
dgl/src/pugl-extra/wasm_gl.c View File

@@ -41,7 +41,7 @@ puglWasmGlGetAttrib(const EGLDisplay display,
static PuglStatus
puglWasmGlConfigure(PuglView* view)
{
PuglInternals* const impl = view->impl;
PuglInternals* const impl = view->impl;

const EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);



+ 32
- 8
dgl/src/pugl.cpp View File

@@ -37,7 +37,14 @@
#include <cstring>
#include <ctime>

#if defined(DISTRHO_OS_MAC)
#if defined(DISTRHO_OS_HAIKU)
# include <Application.h>
# include <Window.h>
# ifdef DGL_OPENGL
# include <GL/gl.h>
# include <opengl/GLView.h>
# endif
#elif defined(DISTRHO_OS_MAC)
# import <Cocoa/Cocoa.h>
# include <dlfcn.h>
# include <mach/mach_time.h>
@@ -119,7 +126,13 @@ START_NAMESPACE_DGL

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

#if defined(DISTRHO_OS_MAC)
#if defined(DISTRHO_OS_HAIKU)
# include "pugl-extra/haiku.cpp"
# include "pugl-extra/haiku_stub.cpp"
# ifdef DGL_OPENGL
# include "pugl-extra/haiku_gl.cpp"
# endif
#elif defined(DISTRHO_OS_MAC)
# ifndef DISTRHO_MACOS_NAMESPACE_MACRO
# define DISTRHO_MACOS_NAMESPACE_MACRO_HELPER(NS, SEP, INTERFACE) NS ## SEP ## INTERFACE
# define DISTRHO_MACOS_NAMESPACE_MACRO(NS, INTERFACE) DISTRHO_MACOS_NAMESPACE_MACRO_HELPER(NS, _, INTERFACE)
@@ -237,7 +250,8 @@ void puglSetMatchingBackendForCurrentBuild(PuglView* const view)

void puglRaiseWindow(PuglView* const view)
{
#if defined(DISTRHO_OS_MAC)
#if defined(DISTRHO_OS_HAIKU)
#elif defined(DISTRHO_OS_MAC)
if (NSWindow* const window = view->impl->window ? view->impl->window
: [view->impl->wrapperView window])
[window orderFrontRegardless];
@@ -257,7 +271,10 @@ void puglRaiseWindow(PuglView* const view)
double puglGetScaleFactorFromParent(const PuglView* const view)
{
const PuglNativeView parent = view->parent ? view->parent : view->transientParent ? view->transientParent : 0;
#if defined(DISTRHO_OS_MAC)
#if defined(DISTRHO_OS_HAIKU)
// TODO
return 1.0;
#elif defined(DISTRHO_OS_MAC)
// some of these can return 0 as backingScaleFactor, pick the most relevant valid one
const NSWindow* possibleWindows[] = {
parent != 0 ? [(NSView*)parent window] : nullptr,
@@ -296,7 +313,8 @@ PuglStatus puglSetGeometryConstraints(PuglView* const view, const uint width, co
view->sizeHints[PUGL_FIXED_ASPECT].height = height;
}

#if defined(DISTRHO_OS_MAC)
#if defined(DISTRHO_OS_HAIKU)
#elif defined(DISTRHO_OS_MAC)
if (view->impl->window)
{
PuglStatus status;
@@ -328,7 +346,8 @@ void puglSetResizable(PuglView* const view, const bool resizable)
{
puglSetViewHint(view, PUGL_RESIZABLE, resizable ? PUGL_TRUE : PUGL_FALSE);

#if defined(DISTRHO_OS_MAC)
#if defined(DISTRHO_OS_HAIKU)
#elif defined(DISTRHO_OS_MAC)
if (PuglWindow* const window = view->impl->window)
{
const uint style = (NSClosableWindowMask | NSTitledWindowMask | NSMiniaturizableWindowMask)
@@ -361,7 +380,8 @@ PuglStatus puglSetSizeAndDefault(PuglView* view, uint width, uint height)
view->sizeHints[PUGL_DEFAULT_SIZE].width = view->frame.width = static_cast<PuglSpan>(width);
view->sizeHints[PUGL_DEFAULT_SIZE].height = view->frame.height = static_cast<PuglSpan>(height);

#if defined(DISTRHO_OS_MAC)
#if defined(DISTRHO_OS_HAIKU)
#elif defined(DISTRHO_OS_MAC)
// mostly matches upstream pugl, simplified
PuglInternals* const impl = view->impl;

@@ -456,7 +476,11 @@ void puglFallbackOnResize(PuglView* const view)

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

#if defined(DISTRHO_OS_MAC)
#if defined(DISTRHO_OS_HAIKU)

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

#elif defined(DISTRHO_OS_MAC)

// --------------------------------------------------------------------------------------------------------------------
// macOS specific, add another view's window as child


+ 5
- 1
dgl/src/pugl.hpp View File

@@ -73,7 +73,11 @@ void puglOnDisplayPrepare(PuglView* view);
// DGL specific, build-specific fallback resize
void puglFallbackOnResize(PuglView* view);

#if defined(DISTRHO_OS_MAC)
#if defined(DISTRHO_OS_HAIKU)

// nothing here yet

#elif defined(DISTRHO_OS_MAC)

// macOS specific, add another view's window as child
PuglStatus puglMacOSAddChildWindow(PuglView* view, PuglView* child);


Loading…
Cancel
Save