From 5a079a2d114f96d4847d1ee305d5b7c16eeec50e Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Sat, 27 Dec 2025 12:03:39 -0800 Subject: Initial commit --- contrib/SDL-3.2.8/src/video/haiku/SDL_bvideo.cc | 326 ++++++++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 contrib/SDL-3.2.8/src/video/haiku/SDL_bvideo.cc (limited to 'contrib/SDL-3.2.8/src/video/haiku/SDL_bvideo.cc') diff --git a/contrib/SDL-3.2.8/src/video/haiku/SDL_bvideo.cc b/contrib/SDL-3.2.8/src/video/haiku/SDL_bvideo.cc new file mode 100644 index 0000000..d7f9e7c --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/haiku/SDL_bvideo.cc @@ -0,0 +1,326 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_internal.h" +#include "../../core/haiku/SDL_BApp.h" + +#ifdef SDL_VIDEO_DRIVER_HAIKU + +#include "SDL_BWin.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SDL_bkeyboard.h" +#include "SDL_bwindow.h" +#include "SDL_bclipboard.h" +#include "SDL_bvideo.h" +#include "SDL_bopengl.h" +#include "SDL_bmodes.h" +#include "SDL_bframebuffer.h" +#include "SDL_bevents.h" +#include "SDL_bmessagebox.h" +#include "../../events/SDL_keyboard_c.h" +#include "../../events/SDL_mouse_c.h" + +static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) { + return (SDL_BWin *)(window->internal); +} + +static SDL_VideoDevice * HAIKU_CreateDevice(void) +{ + SDL_VideoDevice *device; + + // Initialize all variables that we clean on shutdown + device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); + + device->internal = NULL; /* FIXME: Is this the cause of some of the + SDL_Quit() errors? */ + +// TODO: Figure out if any initialization needs to go here + + // Set the function pointers + device->VideoInit = HAIKU_VideoInit; + device->VideoQuit = HAIKU_VideoQuit; + device->GetDisplayBounds = HAIKU_GetDisplayBounds; + device->GetDisplayModes = HAIKU_GetDisplayModes; + device->SetDisplayMode = HAIKU_SetDisplayMode; + device->PumpEvents = HAIKU_PumpEvents; + + device->CreateSDLWindow = HAIKU_CreateWindow; + device->SetWindowTitle = HAIKU_SetWindowTitle; + device->SetWindowPosition = HAIKU_SetWindowPosition; + device->SetWindowSize = HAIKU_SetWindowSize; + device->ShowWindow = HAIKU_ShowWindow; + device->HideWindow = HAIKU_HideWindow; + device->RaiseWindow = HAIKU_RaiseWindow; + device->MaximizeWindow = HAIKU_MaximizeWindow; + device->MinimizeWindow = HAIKU_MinimizeWindow; + device->RestoreWindow = HAIKU_RestoreWindow; + device->SetWindowBordered = HAIKU_SetWindowBordered; + device->SetWindowResizable = HAIKU_SetWindowResizable; + device->SetWindowFullscreen = HAIKU_SetWindowFullscreen; + device->SetWindowMouseGrab = HAIKU_SetWindowMouseGrab; + device->SetWindowMinimumSize = HAIKU_SetWindowMinimumSize; + device->SetWindowParent = HAIKU_SetWindowParent; + device->SetWindowModal = HAIKU_SetWindowModal; + device->DestroyWindow = HAIKU_DestroyWindow; + device->CreateWindowFramebuffer = HAIKU_CreateWindowFramebuffer; + device->UpdateWindowFramebuffer = HAIKU_UpdateWindowFramebuffer; + device->DestroyWindowFramebuffer = HAIKU_DestroyWindowFramebuffer; + +#ifdef SDL_VIDEO_OPENGL + device->GL_LoadLibrary = HAIKU_GL_LoadLibrary; + device->GL_GetProcAddress = HAIKU_GL_GetProcAddress; + device->GL_UnloadLibrary = HAIKU_GL_UnloadLibrary; + device->GL_CreateContext = HAIKU_GL_CreateContext; + device->GL_MakeCurrent = HAIKU_GL_MakeCurrent; + device->GL_SetSwapInterval = HAIKU_GL_SetSwapInterval; + device->GL_GetSwapInterval = HAIKU_GL_GetSwapInterval; + device->GL_SwapWindow = HAIKU_GL_SwapWindow; + device->GL_DestroyContext = HAIKU_GL_DestroyContext; +#endif + + device->SetClipboardText = HAIKU_SetClipboardText; + device->GetClipboardText = HAIKU_GetClipboardText; + device->HasClipboardText = HAIKU_HasClipboardText; + + device->free = HAIKU_DeleteDevice; + + return device; +} + +VideoBootStrap HAIKU_bootstrap = { + "haiku", "Haiku graphics", + HAIKU_CreateDevice, + HAIKU_ShowMessageBox, + false +}; + +void HAIKU_DeleteDevice(SDL_VideoDevice * device) +{ + SDL_free(device->internal); + SDL_free(device); +} + +struct SDL_CursorData +{ + BCursor *cursor; +}; + +static SDL_Cursor *HAIKU_CreateCursorAndData(BCursor *bcursor) +{ + SDL_Cursor *cursor = (SDL_Cursor *)SDL_calloc(1, sizeof(*cursor)); + if (cursor) { + SDL_CursorData *data = (SDL_CursorData *)SDL_calloc(1, sizeof(*data)); + if (!data) { + SDL_free(cursor); + return NULL; + } + data->cursor = bcursor; + cursor->internal = data; + } + return cursor; +} + +static SDL_Cursor * HAIKU_CreateSystemCursor(SDL_SystemCursor id) +{ + BCursorID cursorId = B_CURSOR_ID_SYSTEM_DEFAULT; + + switch(id) + { + #define CURSORCASE(sdlname, bname) case SDL_SYSTEM_CURSOR_##sdlname: cursorId = B_CURSOR_ID_##bname; break + CURSORCASE(DEFAULT, SYSTEM_DEFAULT); + CURSORCASE(TEXT, I_BEAM); + CURSORCASE(WAIT, PROGRESS); + CURSORCASE(CROSSHAIR, CROSS_HAIR); + CURSORCASE(PROGRESS, PROGRESS); + CURSORCASE(NWSE_RESIZE, RESIZE_NORTH_WEST_SOUTH_EAST); + CURSORCASE(NESW_RESIZE, RESIZE_NORTH_EAST_SOUTH_WEST); + CURSORCASE(EW_RESIZE, RESIZE_EAST_WEST); + CURSORCASE(NS_RESIZE, RESIZE_NORTH_SOUTH); + CURSORCASE(MOVE, MOVE); + CURSORCASE(NOT_ALLOWED, NOT_ALLOWED); + CURSORCASE(POINTER, FOLLOW_LINK); + CURSORCASE(NW_RESIZE, RESIZE_NORTH_WEST_SOUTH_EAST); + CURSORCASE(N_RESIZE, RESIZE_NORTH_SOUTH); + CURSORCASE(NE_RESIZE, RESIZE_NORTH_EAST_SOUTH_WEST); + CURSORCASE(E_RESIZE, RESIZE_EAST_WEST); + CURSORCASE(SE_RESIZE, RESIZE_NORTH_WEST_SOUTH_EAST); + CURSORCASE(S_RESIZE, RESIZE_NORTH_SOUTH); + CURSORCASE(SW_RESIZE, RESIZE_NORTH_EAST_SOUTH_WEST); + CURSORCASE(W_RESIZE, RESIZE_EAST_WEST); + #undef CURSORCASE + default: + SDL_assert(0); + return NULL; + } + + return HAIKU_CreateCursorAndData(new BCursor(cursorId)); +} + +static SDL_Cursor * HAIKU_CreateDefaultCursor() +{ + SDL_SystemCursor id = SDL_GetDefaultSystemCursor(); + return HAIKU_CreateSystemCursor(id); +} + +static void HAIKU_FreeCursor(SDL_Cursor * cursor) +{ + SDL_CursorData *data = cursor->internal; + + if (data) { + delete data->cursor; + } + SDL_free(data); + SDL_free(cursor); +} + +static SDL_Cursor * HAIKU_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) +{ + SDL_Surface *converted; + + converted = SDL_ConvertSurface(surface, SDL_PIXELFORMAT_ARGB8888); + if (!converted) { + return NULL; + } + + BBitmap *cursorBitmap = new BBitmap(BRect(0, 0, surface->w - 1, surface->h - 1), B_RGBA32); + cursorBitmap->SetBits(converted->pixels, converted->h * converted->pitch, 0, B_RGBA32); + SDL_DestroySurface(converted); + + return HAIKU_CreateCursorAndData(new BCursor(cursorBitmap, BPoint(hot_x, hot_y))); +} + +static bool HAIKU_ShowCursor(SDL_Cursor *cursor) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + + if (!mouse) { + return true; + } + + if (cursor) { + BCursor *hCursor = cursor->internal->cursor; + be_app->SetCursor(hCursor); + } else { + BCursor *hCursor = new BCursor(B_CURSOR_ID_NO_CURSOR); + be_app->SetCursor(hCursor); + delete hCursor; + } + + return true; +} + +static bool HAIKU_SetRelativeMouseMode(bool enabled) +{ + SDL_Window *window = SDL_GetMouseFocus(); + if (!window) { + return true; + } + + SDL_BWin *bewin = _ToBeWin(window); + BGLView *_SDL_GLView = bewin->GetGLView(); + if (!_SDL_GLView) { + return false; + } + + bewin->Lock(); + if (enabled) + _SDL_GLView->SetEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY); + else + _SDL_GLView->SetEventMask(0, 0); + bewin->Unlock(); + + return true; +} + +static void HAIKU_MouseInit(SDL_VideoDevice *_this) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + if (!mouse) { + return; + } + mouse->CreateCursor = HAIKU_CreateCursor; + mouse->CreateSystemCursor = HAIKU_CreateSystemCursor; + mouse->ShowCursor = HAIKU_ShowCursor; + mouse->FreeCursor = HAIKU_FreeCursor; + mouse->SetRelativeMouseMode = HAIKU_SetRelativeMouseMode; + + SDL_SetDefaultCursor(HAIKU_CreateDefaultCursor()); +} + +bool HAIKU_VideoInit(SDL_VideoDevice *_this) +{ + // Initialize the Be Application for appserver interaction + if (!SDL_InitBeApp()) { + return false; + } + + // Initialize video modes + HAIKU_InitModes(_this); + + // Init the keymap + HAIKU_InitOSKeymap(); + + HAIKU_MouseInit(_this); + + // Assume we have a mouse and keyboard + SDL_AddKeyboard(SDL_DEFAULT_KEYBOARD_ID, NULL, false); + SDL_AddMouse(SDL_DEFAULT_MOUSE_ID, NULL, false); + +#ifdef SDL_VIDEO_OPENGL + // testgl application doesn't load library, just tries to load symbols + // is it correct? if so we have to load library here + HAIKU_GL_LoadLibrary(_this, NULL); +#endif + + // We're done! + return true; +} + +void HAIKU_VideoQuit(SDL_VideoDevice *_this) +{ + + HAIKU_QuitModes(_this); + + SDL_QuitBeApp(); +} + +// just sticking this function in here so it's in a C++ source file. +extern "C" +bool HAIKU_OpenURL(const char *url) +{ + BUrl burl(url); + const status_t rc = burl.OpenWithPreferredApplication(false); + if (rc != B_NO_ERROR) { + return SDL_SetError("URL open failed (err=%d)", (int)rc); + } + return true; +} + +#ifdef __cplusplus +} +#endif + +#endif // SDL_VIDEO_DRIVER_HAIKU -- cgit v1.2.3