From 295b326839f336e2c46b2027d4701a6b75d9cdc6 Mon Sep 17 00:00:00 2001 From: Gerasim Troeglazov <3dEyes@gmail.com> Date: Sat, 12 Feb 2022 23:11:23 +1000 Subject: [PATCH] GLFW: add vulkan support * implement cursors * implement clipboard * implement file drop from Tracker --- media-libs/glfw/glfw-3.3.6.recipe | 2 +- media-libs/glfw/patches/glfw-3.3.6.patchset | 670 +++++++++++++++++++- 2 files changed, 655 insertions(+), 17 deletions(-) diff --git a/media-libs/glfw/glfw-3.3.6.recipe b/media-libs/glfw/glfw-3.3.6.recipe index ef6eb093a..9ffb1748b 100644 --- a/media-libs/glfw/glfw-3.3.6.recipe +++ b/media-libs/glfw/glfw-3.3.6.recipe @@ -7,7 +7,7 @@ COPYRIGHT="2002-2006 Marcus Geelnard 2006-2021 Camilla Löwy " LICENSE="Zlib" -REVISION="2" +REVISION="3" SOURCE_URI="https://github.com/glfw/glfw/archive/$portVersion.tar.gz" CHECKSUM_SHA256="ed07b90e334dcd39903e6288d90fa1ae0cf2d2119fec516cf743a0a404527c02" PATCHES="glfw-$portVersion.patchset" diff --git a/media-libs/glfw/patches/glfw-3.3.6.patchset b/media-libs/glfw/patches/glfw-3.3.6.patchset index ca2f3fb96..5d8427422 100644 --- a/media-libs/glfw/patches/glfw-3.3.6.patchset +++ b/media-libs/glfw/patches/glfw-3.3.6.patchset @@ -1,4 +1,4 @@ -From 88c7ff5c685df86ab96e0e238979bc20d1deb9c9 Mon Sep 17 00:00:00 2001 +From 6372d5127b28e5eea2b0234f86c710987adadb25 Mon Sep 17 00:00:00 2001 From: Gerasim Troeglazov <3dEyes@gmail.com> Date: Sun, 6 Feb 2022 20:26:48 +1000 Subject: Add Haiku support @@ -2343,7 +2343,7 @@ index 0000000..966b1f7 + return VK_ERROR_INITIALIZATION_FAILED; +} + -diff --git a/src/internal.h b/src/internal.h +ddiff --git a/src/internal.h b/src/internal.h index ad619b4..6a6c704 100644 --- a/src/internal.h +++ b/src/internal.h @@ -2395,20 +2395,658 @@ index 26b544b..ca2c227 100644 +#endif // GLFW_BUILD_HAIKU_MAPPINGS }; -diff --git a/src/osmesa_context.c b/src/osmesa_context.c -index f29f9cd..0458170 100644 ---- a/src/osmesa_context.c -+++ b/src/osmesa_context.c -@@ -92,6 +92,9 @@ static void destroyContextOSMesa(_GLFWwindow* window) - static void swapBuffersOSMesa(_GLFWwindow* window) - { - // No double buffering on OSMesa -+#ifdef __HAIKU__ -+ _glfwPlatformSwapBuffers(window); -+#endif - } - - static void swapIntervalOSMesa(int interval) +-- +2.30.2 + + +From e820d0945c82eca4de05b30d3edf679a42cf7388 Mon Sep 17 00:00:00 2001 +From: X512 +Date: Sat, 5 Feb 2022 13:57:28 +0900 +Subject: haiku: Vulkan window output + + +diff --git a/src/haiku_platform_view.cpp b/src/haiku_platform_view.cpp +index d490e75..6670abb 100644 +--- a/src/haiku_platform_view.cpp ++++ b/src/haiku_platform_view.cpp +@@ -24,19 +24,47 @@ + #include + + #include "haiku_platform_view.h" ++#include ++ ++HaikuPlatformView::ViewBitmapHook::ViewBitmapHook(HaikuPlatformView *view): ++ fView(view) ++{ ++} ++ ++void HaikuPlatformView::ViewBitmapHook::GetSize(uint32_t &width, uint32_t &height) ++{ ++ fView->LockLooper(); ++ width = (uint32_t)fView->Frame().Width() + 1; ++ height = (uint32_t)fView->Frame().Height() + 1; ++ fView->UnlockLooper(); ++} ++ ++BBitmap *HaikuPlatformView::ViewBitmapHook::SetBitmap(BBitmap *bmp) ++{ ++ fView->LockLooper(); ++ ++ BBitmap* oldBmp = fView->displayBitmap.Detach(); ++ fView->displayBitmap.SetTo(bmp); ++ fView->Invalidate(); ++ ++ fView->UnlockLooper(); ++ return oldBmp; ++} ++ + + HaikuPlatformView::HaikuPlatformView(BRect rect, int width, int height, _GLFWwindow* win) : + BView(rect, "HaikuPlatformView", B_FOLLOW_ALL, B_WILL_DRAW), + window(win), + bufferBitmap(NULL), ++ bitmapHook(this), + mouseMode(MOUSE_MODE_NORMAL) + { ++ SetViewColor(B_TRANSPARENT_COLOR); ++ SetLowColor(0, 0, 0); + } + + HaikuPlatformView::~HaikuPlatformView() + { +- if (bufferBitmap) +- delete bufferBitmap; + } + + void +@@ -89,7 +117,12 @@ void + HaikuPlatformView::Draw(BRect rect) + { + SetDrawingMode(B_OP_COPY); +- DrawBitmap(bufferBitmap, rect, rect); ++ BRegion region(rect); ++ if (displayBitmap.IsSet()) { ++ DrawBitmap(displayBitmap.Get(), B_ORIGIN); ++ region.Exclude(displayBitmap->Bounds()); ++ } ++ FillRegion(®ion, B_SOLID_LOW); + } + + void +@@ -104,31 +137,34 @@ HaikuPlatformView::SetMouseMode(int32 mode) + } + + void +-HaikuPlatformView::Repaint() ++HaikuPlatformView::Present() + { + if (LockLooperWithTimeout(10000) == B_OK) { +- SetDrawingMode(B_OP_COPY); +- DrawBitmap(bufferBitmap); +- UnlockLooper(); ++ if (bufferBitmap.IsSet()) { ++ delete bitmapHook.SetBitmap(bufferBitmap.Detach()); ++ } else { ++ bitmapHook.SetBitmap(renderBitmap); ++ } ++ UnlockLooper(); + } + } + + void + HaikuPlatformView::ResizeBitmap(int width, int height) +-{ ++{ + if (LockLooperWithTimeout(10000) == B_OK) + { +- if (bufferBitmap) ++ if (renderBitmap) + { + if (width == Width() && height == Height()) + { + UnlockLooper(); + return; + } +- delete bufferBitmap; + } + +- bufferBitmap = new BBitmap(BRect(0, 0, width - 1, height - 1), B_RGB32, true); ++ bufferBitmap.SetTo(new BBitmap(BRect(0, 0, width - 1, height - 1), B_RGB32)); ++ renderBitmap = bufferBitmap.Get(); + + UnlockLooper(); + } +diff --git a/src/haiku_platform_view.h b/src/haiku_platform_view.h +index fe4ff46..f95f5b7 100644 +--- a/src/haiku_platform_view.h ++++ b/src/haiku_platform_view.h +@@ -37,12 +37,37 @@ extern "C" { + #include + #include + #include ++#include + + #define MOUSE_MODE_NORMAL 0 + #define MOUSE_MODE_RELATIVE 1 + ++class BitmapHook { ++public: ++ virtual ~BitmapHook() {}; ++ virtual void GetSize(uint32_t &width, uint32_t &height) = 0; ++ virtual BBitmap *SetBitmap(BBitmap *bmp) = 0; ++}; ++ ++class VKLayerSurfaceBase { ++public: ++ virtual ~VKLayerSurfaceBase() {}; ++ virtual void SetBitmapHook(BitmapHook *hook) = 0; ++}; ++ + class HaikuPlatformView : public BView + { ++ private: ++ class ViewBitmapHook: public BitmapHook { ++ private: ++ HaikuPlatformView *fView; ++ public: ++ ViewBitmapHook(HaikuPlatformView *view); ++ virtual ~ViewBitmapHook() {}; ++ void GetSize(uint32_t &width, uint32_t &height) override; ++ BBitmap *SetBitmap(BBitmap *bmp) override; ++ }; ++ + public: + HaikuPlatformView(BRect rect, int width, int height, _GLFWwindow* win); + ~HaikuPlatformView(); +@@ -51,22 +76,29 @@ class HaikuPlatformView : public BView + virtual void Draw(BRect r); + virtual void AttachedToWindow(); + +- void Repaint(); ++ void Present(); + + void SetMouseMode(int32 mode); + +- char* GetBuffer() { return (char*)bufferBitmap->Bits(); } +- uint32 GetBufferSize() { return bufferBitmap->BitsLength(); } ++ char* GetBuffer() { return (char*)renderBitmap->Bits(); } ++ uint32 GetBufferSize() { return renderBitmap->BitsLength(); } + + void ResizeBitmap(int width, int height); + +- int Width() { return bufferBitmap->Bounds().IntegerWidth() + 1; } +- int Height() { return bufferBitmap->Bounds().IntegerHeight() + 1; } ++ int Width() { return renderBitmap->Bounds().IntegerWidth() + 1; } ++ int Height() { return renderBitmap->Bounds().IntegerHeight() + 1; } ++ ++ ViewBitmapHook* GetBitmapHook() { return &bitmapHook; } + + private: + _GLFWwindow* window; + +- BBitmap* bufferBitmap; ++ ViewBitmapHook bitmapHook; ++ ObjectDeleter ++ bufferBitmap; ++ BBitmap* renderBitmap; ++ ObjectDeleter ++ displayBitmap; + + int32 mouseMode; + }; +diff --git a/src/haiku_window.cpp b/src/haiku_window.cpp +index 966b1f7..6cf5e74 100644 +--- a/src/haiku_window.cpp ++++ b/src/haiku_window.cpp +@@ -549,12 +549,7 @@ void _glfwPlatformPollEvents(void) + window->haiku.width = width; + window->haiku.height = height; + +- _glfwInputFramebufferSize(window, width, height); + _glfwInputWindowSize(window, width, height); +- +- PLATFORM_VIEW(window)->ResizeBitmap(width, height); +- +- window->context.makeCurrent(window); + } + break; + } +@@ -689,13 +684,24 @@ int _glfwPlatformGetKeyScancode(int key) + + void _glfwPlatformGetRequiredInstanceExtensions(char** extensions) + { ++ if (!_glfw.vk.KHR_surface || !_glfw.vk.EXT_headless_surface) ++ return; ++ ++ extensions[0] = "VK_KHR_surface"; ++ extensions[1] = "VK_EXT_headless_surface"; + } + + void _glfwPlatformSwapBuffers(_GLFWwindow* window) + { + HaikuPlatformView *view = PLATFORM_VIEW(window); + glFinish(); +- view->Repaint(); ++ view->Present(); ++ ++ if (window->haiku.width != PLATFORM_VIEW(window)->Width() || window->haiku.height != PLATFORM_VIEW(window)->Height()) { ++ _glfwInputFramebufferSize(window, window->haiku.width, window->haiku.height); ++ PLATFORM_VIEW(window)->ResizeBitmap(window->haiku.width, window->haiku.height); ++ window->context.makeCurrent(window); ++ } + } + + int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, +@@ -705,11 +711,34 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, + return GLFW_FALSE; + } + ++#define VK_EXT_headless_surface 1 ++#define VK_EXT_HEADLESS_SURFACE_SPEC_VERSION 1 ++#define VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME "VK_EXT_headless_surface" ++typedef VkFlags VkHeadlessSurfaceCreateFlagsEXT; ++typedef struct VkHeadlessSurfaceCreateInfoEXT { ++ VkStructureType sType; ++ const void* pNext; ++ VkHeadlessSurfaceCreateFlagsEXT flags; ++} VkHeadlessSurfaceCreateInfoEXT; ++typedef VkResult (APIENTRY *PFN_vkCreateHeadlessSurfaceEXT)(VkInstance instance, const VkHeadlessSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); ++ + VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, + _GLFWwindow* window, + const VkAllocationCallbacks* allocator, + VkSurfaceKHR* surface) + { +- return VK_ERROR_INITIALIZATION_FAILED; ++ VkHeadlessSurfaceCreateInfoEXT surfaceCreateInfo = {}; ++ surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT; ++ PFN_vkCreateHeadlessSurfaceEXT fpCreateHeadlessSurfaceEXT = (PFN_vkCreateHeadlessSurfaceEXT)vkGetInstanceProcAddr(instance, "vkCreateHeadlessSurfaceEXT"); ++ if (!fpCreateHeadlessSurfaceEXT){ ++ printf("Could not fetch function pointer for the headless extension!"); ++ abort(); ++ } ++ VkResult res = fpCreateHeadlessSurfaceEXT(instance, &surfaceCreateInfo, nullptr, surface); ++ if (res != VK_SUCCESS) return res; ++ auto surfaceBase = (VKLayerSurfaceBase*)(*surface); ++ HaikuPlatformView *view = PLATFORM_VIEW(window); ++ surfaceBase->SetBitmapHook(view->GetBitmapHook()); ++ return res; + } + +diff --git a/src/internal.h b/src/internal.h +index 6a6c704..98815a8 100644 +--- a/src/internal.h ++++ b/src/internal.h +@@ -129,6 +129,7 @@ typedef enum VkStructureType + VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, + VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000, + VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000217000, ++ VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT = 1000256000, + VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF + } VkStructureType; + +@@ -556,6 +557,7 @@ struct _GLFWlibrary + PFN_vkGetInstanceProcAddr GetInstanceProcAddr; + #endif + GLFWbool KHR_surface; ++ GLFWbool EXT_headless_surface; + #if defined(_GLFW_WIN32) + GLFWbool KHR_win32_surface; + #elif defined(_GLFW_COCOA) +diff --git a/src/vulkan.c b/src/vulkan.c +index 22c54e4..e267e25 100644 +--- a/src/vulkan.c ++++ b/src/vulkan.c +@@ -126,6 +126,8 @@ GLFWbool _glfwInitVulkan(int mode) + { + if (strcmp(ep[i].extensionName, "VK_KHR_surface") == 0) + _glfw.vk.KHR_surface = GLFW_TRUE; ++ else if (strcmp(ep[i].extensionName, "VK_EXT_headless_surface") == 0) ++ _glfw.vk.EXT_headless_surface = GLFW_TRUE; + #if defined(_GLFW_WIN32) + else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0) + _glfw.vk.KHR_win32_surface = GLFW_TRUE; +-- +2.30.2 + + +From f64b80c363499fce85e4d590a72cd0e4e0b00518 Mon Sep 17 00:00:00 2001 +From: Gerasim Troeglazov <3dEyes@gmail.com> +Date: Mon, 7 Feb 2022 19:53:09 +1000 +Subject: Update framebuffer size on window resize + + +diff --git a/src/haiku_window.cpp b/src/haiku_window.cpp +index 6cf5e74..f7d2752 100644 +--- a/src/haiku_window.cpp ++++ b/src/haiku_window.cpp +@@ -548,7 +548,8 @@ void _glfwPlatformPollEvents(void) + { + window->haiku.width = width; + window->haiku.height = height; +- ++ if (window->context.makeCurrent != NULL) ++ _glfwInputFramebufferSize(window, width, height); + _glfwInputWindowSize(window, width, height); + } + break; +-- +2.30.2 + + +From 284b95d1d6ac5e0f8b47c08f76132c4c14f27ebe Mon Sep 17 00:00:00 2001 +From: Gerasim Troeglazov <3dEyes@gmail.com> +Date: Sat, 12 Feb 2022 22:44:09 +1000 +Subject: Missing initial NULL value for renderBitmap + + +diff --git a/src/haiku_platform_view.cpp b/src/haiku_platform_view.cpp +index 6670abb..2c7e127 100644 +--- a/src/haiku_platform_view.cpp ++++ b/src/haiku_platform_view.cpp +@@ -56,6 +56,7 @@ HaikuPlatformView::HaikuPlatformView(BRect rect, int width, int height, _GLFWwin + BView(rect, "HaikuPlatformView", B_FOLLOW_ALL, B_WILL_DRAW), + window(win), + bufferBitmap(NULL), ++ renderBitmap(NULL), + bitmapHook(this), + mouseMode(MOUSE_MODE_NORMAL) + { +-- +2.30.2 + + +From b3ee435c9f7132dff1bcfc10d4313a37fa9a5728 Mon Sep 17 00:00:00 2001 +From: Gerasim Troeglazov <3dEyes@gmail.com> +Date: Sat, 12 Feb 2022 22:51:37 +1000 +Subject: Add cursors, clipboard and files drop support + + +diff --git a/src/haiku_platform.h b/src/haiku_platform.h +index bfa0553..4d62ce6 100644 +--- a/src/haiku_platform.h ++++ b/src/haiku_platform.h +@@ -23,17 +23,16 @@ + + #include + +-#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowHaiku haiku ++#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowHaiku haiku ++#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryHaiku haiku ++#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorHaiku haiku + + #define _GLFW_PLATFORM_CONTEXT_STATE struct { int dummyContext; } + #define _GLFW_PLATFORM_MONITOR_STATE struct { int dummyMonitor; } +-#define _GLFW_PLATFORM_CURSOR_STATE struct { int dummyCursor; } + #define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE struct { int dummyLibraryContext; } + #define _GLFW_EGL_CONTEXT_STATE struct { int dummyEGLContext; } + #define _GLFW_EGL_LIBRARY_CONTEXT_STATE struct { int dummyEGLLibraryContext; } + +-#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryHaiku haiku +- + #include "haiku_context.h" + #include "posix_time.h" + #include "posix_thread.h" +@@ -54,6 +53,12 @@ typedef struct _GLFWwindowHaiku + int mouseGrab; + } _GLFWwindowHaiku; + ++// Haiku-specific per-cursor data ++// ++typedef struct _GLFWcursorHaiku ++{ ++ void* handle; ++} _GLFWcursorHaiku; + + // Haiku-specific global data + // +diff --git a/src/haiku_platform_window.cpp b/src/haiku_platform_window.cpp +index af75685..a4f233e 100644 +--- a/src/haiku_platform_window.cpp ++++ b/src/haiku_platform_window.cpp +@@ -52,20 +52,44 @@ HaikuPlatformWindow::~HaikuPlatformWindow() + void + HaikuPlatformWindow::MessageReceived(BMessage *message) + { ++ if (message->WasDropped()) ++ { ++ BMessage *msg = new BMessage(*message); ++ msg->what = kDropFile; ++ msg->AddPointer("window", (void*)window); ++ msg->AddPoint("drop_point", ConvertFromScreen(message->DropPoint())); ++ PLATFORM_QUEUE->AddMessage(msg); ++ return; ++ } + switch (message->what) + { + case kShowCursor: ++ { + fView->SetViewCursor(cursorStd); + break; ++ } + case kHideCursor: ++ { + fView->SetViewCursor(cursorEmpty); + break; ++ } ++ case kSetCursor: ++ { ++ BCursor *cursor = (BCursor*)(message->GetPointer("cursor")); ++ if (cursor) ++ fView->SetViewCursor(cursor); ++ break; ++ } + case kMouseModeNormal: ++ { + fView->SetMouseMode(MOUSE_MODE_NORMAL); + break; ++ } + case kMouseModeRelative: ++ { + fView->SetMouseMode(MOUSE_MODE_RELATIVE); + break; ++ } + case B_UNMAPPED_KEY_UP: + case B_KEY_UP: + case B_UNMAPPED_KEY_DOWN: +diff --git a/src/haiku_platform_window.h b/src/haiku_platform_window.h +index b2e5461..d9732e8 100644 +--- a/src/haiku_platform_window.h ++++ b/src/haiku_platform_window.h +@@ -29,13 +29,16 @@ + #include + #include + #include ++#include + #include + #include + + const uint32 kShowCursor = 'mSHO'; + const uint32 kHideCursor = 'mHID'; ++const uint32 kSetCursor = 'mCUR'; + const uint32 kMouseModeNormal = 'mNOR'; + const uint32 kMouseModeRelative = 'mREL'; ++const uint32 kDropFile = 'mDRP'; + + #include "haiku_platform_view.h" + +diff --git a/src/haiku_window.cpp b/src/haiku_window.cpp +index f7d2752..2e03cef 100644 +--- a/src/haiku_window.cpp ++++ b/src/haiku_window.cpp +@@ -36,6 +36,8 @@ extern "C" { + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -421,6 +423,37 @@ void _glfwPlatformPollEvents(void) + _GLFWwindow* window = (_GLFWwindow*)(message->GetPointer("window")); + switch(message->what) + { ++ case kDropFile: ++ { ++ BPoint dropPoint = message->FindPoint("drop_point"); ++ _glfwInputCursorPos(window, dropPoint.x, dropPoint.y); ++ ++ int32 count; ++ uint32 type; ++ message->GetInfo("refs", &type, &count); ++ ++ if (count > 0) ++ { ++ char** paths = (char**)calloc(count, sizeof(char*)); ++ entry_ref aRef; ++ for (int i = 0; i < count; i++) ++ { ++ message->FindRef("refs", i, &aRef); ++ BEntry entry(&aRef); ++ BPath path; ++ entry.GetPath(&path); ++ paths[i] = strdup(path.Path()); ++ } ++ ++ _glfwInputDrop(window, count, (const char**) paths); ++ ++ for (int i = 0; i < count; i++) ++ free(paths[i]); ++ free(paths); ++ } ++ ++ break; ++ } + case B_MOUSE_DOWN: + { + int32 mod = modifiers(); +@@ -648,29 +681,124 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor, + const GLFWimage* image, + int xhot, int yhot) + { ++ BBitmap *bitmap = new BBitmap(BRect(0, 0, image->width -1, image->height - 1), B_RGBA32); ++ if (bitmap->InitCheck() != B_OK) ++ return GLFW_FALSE; ++ ++ unsigned char* source = (unsigned char*) image->pixels; ++ uint32* target = (uint32*)bitmap->Bits(); ++ ++ for (int i = 0; i < image->width * image->height; i++, target++, source += 4) ++ { ++ unsigned int alpha = source[3]; ++ ++ *target = (alpha << 24) | ++ ((unsigned char) ((source[0] * alpha) / 255) << 16) | ++ ((unsigned char) ((source[1] * alpha) / 255) << 8) | ++ ((unsigned char) ((source[2] * alpha) / 255) << 0); ++ } ++ ++ cursor->haiku.handle = new BCursor(bitmap, BPoint(xhot, yhot)); ++ ++ if (!cursor->haiku.handle) ++ { ++ _glfwInputError(GLFW_PLATFORM_ERROR, "Haiku: Failed to create cursor"); ++ return GLFW_FALSE; ++ } ++ + return GLFW_TRUE; + } + + int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) + { ++ BCursorID id = B_CURSOR_ID_SYSTEM_DEFAULT; ++ ++ switch (shape) ++ { ++ case GLFW_IBEAM_CURSOR: ++ id = B_CURSOR_ID_I_BEAM; ++ break; ++ case GLFW_CROSSHAIR_CURSOR: ++ id = B_CURSOR_ID_CROSS_HAIR; ++ break; ++ case GLFW_HAND_CURSOR: ++ id = B_CURSOR_ID_FOLLOW_LINK; ++ break; ++ case GLFW_HRESIZE_CURSOR: ++ id = B_CURSOR_ID_RESIZE_EAST_WEST; ++ break; ++ case GLFW_VRESIZE_CURSOR: ++ id = B_CURSOR_ID_RESIZE_NORTH_SOUTH; ++ break; ++ default: ++ id = B_CURSOR_ID_SYSTEM_DEFAULT; ++ break; ++ } ++ ++ cursor->haiku.handle = new BCursor(id); ++ ++ if (!cursor->haiku.handle) ++ { ++ _glfwInputError(GLFW_PLATFORM_ERROR, "Haiku: Failed to create standard cursor"); ++ return GLFW_FALSE; ++ } ++ + return GLFW_TRUE; + } + + void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) + { ++ if (cursor->haiku.handle) ++ delete static_cast(cursor->haiku.handle); + } + + void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) + { ++ if (!cursor) ++ { ++ BMessage message(kShowCursor); ++ PLATFORM_WINDOW(window)->PostMessage(&message); ++ return; ++ } ++ ++ if (window->cursorMode == GLFW_CURSOR_NORMAL) ++ { ++ if (cursor->haiku.handle) ++ { ++ BMessage message(kSetCursor); ++ message.AddPointer("cursor", cursor->haiku.handle); ++ PLATFORM_WINDOW(window)->PostMessage(&message); ++ } ++ } + } + + void _glfwPlatformSetClipboardString(const char* string) + { ++ BMessage *clip = NULL; ++ if(be_clipboard->Lock()) ++ { ++ be_clipboard->Clear(); ++ if((clip = be_clipboard->Data())) ++ { ++ clip->AddData("text/plain", B_MIME_TYPE, string, strlen(string)); ++ be_clipboard->Commit(); ++ } ++ be_clipboard->Unlock(); ++ } + } + + const char* _glfwPlatformGetClipboardString(void) + { +- return NULL; ++ BMessage *clip = NULL; ++ const char *text = NULL; ++ ssize_t length; ++ if(be_clipboard->Lock()) ++ { ++ if((clip = be_clipboard->Data())) ++ clip->FindData("text/plain", B_MIME_TYPE, (const void**)&text, &length); ++ be_clipboard->Unlock(); ++ } ++ return text; + } + + const char* _glfwPlatformGetScancodeName(int scancode) -- 2.30.2