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_BWin.h | 755 +++++++++++++++++++++ .../SDL-3.2.8/src/video/haiku/SDL_bclipboard.cc | 93 +++ contrib/SDL-3.2.8/src/video/haiku/SDL_bclipboard.h | 31 + contrib/SDL-3.2.8/src/video/haiku/SDL_bevents.cc | 39 ++ contrib/SDL-3.2.8/src/video/haiku/SDL_bevents.h | 37 + .../SDL-3.2.8/src/video/haiku/SDL_bframebuffer.cc | 128 ++++ .../SDL-3.2.8/src/video/haiku/SDL_bframebuffer.h | 45 ++ contrib/SDL-3.2.8/src/video/haiku/SDL_bkeyboard.cc | 168 +++++ contrib/SDL-3.2.8/src/video/haiku/SDL_bkeyboard.h | 38 ++ .../SDL-3.2.8/src/video/haiku/SDL_bmessagebox.cc | 383 +++++++++++ .../SDL-3.2.8/src/video/haiku/SDL_bmessagebox.h | 42 ++ contrib/SDL-3.2.8/src/video/haiku/SDL_bmodes.cc | 307 +++++++++ contrib/SDL-3.2.8/src/video/haiku/SDL_bmodes.h | 43 ++ contrib/SDL-3.2.8/src/video/haiku/SDL_bopengl.cc | 205 ++++++ contrib/SDL-3.2.8/src/video/haiku/SDL_bopengl.h | 52 ++ contrib/SDL-3.2.8/src/video/haiku/SDL_bvideo.cc | 326 +++++++++ contrib/SDL-3.2.8/src/video/haiku/SDL_bvideo.h | 40 ++ contrib/SDL-3.2.8/src/video/haiku/SDL_bwindow.cc | 224 ++++++ contrib/SDL-3.2.8/src/video/haiku/SDL_bwindow.h | 46 ++ 19 files changed, 3002 insertions(+) create mode 100644 contrib/SDL-3.2.8/src/video/haiku/SDL_BWin.h create mode 100644 contrib/SDL-3.2.8/src/video/haiku/SDL_bclipboard.cc create mode 100644 contrib/SDL-3.2.8/src/video/haiku/SDL_bclipboard.h create mode 100644 contrib/SDL-3.2.8/src/video/haiku/SDL_bevents.cc create mode 100644 contrib/SDL-3.2.8/src/video/haiku/SDL_bevents.h create mode 100644 contrib/SDL-3.2.8/src/video/haiku/SDL_bframebuffer.cc create mode 100644 contrib/SDL-3.2.8/src/video/haiku/SDL_bframebuffer.h create mode 100644 contrib/SDL-3.2.8/src/video/haiku/SDL_bkeyboard.cc create mode 100644 contrib/SDL-3.2.8/src/video/haiku/SDL_bkeyboard.h create mode 100644 contrib/SDL-3.2.8/src/video/haiku/SDL_bmessagebox.cc create mode 100644 contrib/SDL-3.2.8/src/video/haiku/SDL_bmessagebox.h create mode 100644 contrib/SDL-3.2.8/src/video/haiku/SDL_bmodes.cc create mode 100644 contrib/SDL-3.2.8/src/video/haiku/SDL_bmodes.h create mode 100644 contrib/SDL-3.2.8/src/video/haiku/SDL_bopengl.cc create mode 100644 contrib/SDL-3.2.8/src/video/haiku/SDL_bopengl.h create mode 100644 contrib/SDL-3.2.8/src/video/haiku/SDL_bvideo.cc create mode 100644 contrib/SDL-3.2.8/src/video/haiku/SDL_bvideo.h create mode 100644 contrib/SDL-3.2.8/src/video/haiku/SDL_bwindow.cc create mode 100644 contrib/SDL-3.2.8/src/video/haiku/SDL_bwindow.h (limited to 'contrib/SDL-3.2.8/src/video/haiku') diff --git a/contrib/SDL-3.2.8/src/video/haiku/SDL_BWin.h b/contrib/SDL-3.2.8/src/video/haiku/SDL_BWin.h new file mode 100644 index 0000000..add3aaf --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/haiku/SDL_BWin.h @@ -0,0 +1,755 @@ +/* + 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. +*/ + +#ifndef SDL_BWin_h_ +#define SDL_BWin_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SDL_internal.h" +#include "SDL_bframebuffer.h" + +#ifdef __cplusplus +} +#endif + +#include +#include +#include +#include +#ifdef SDL_VIDEO_OPENGL +#include +#endif +#include "../../core/haiku/SDL_BApp.h" + +enum WinCommands +{ + BWIN_MOVE_WINDOW, + BWIN_RESIZE_WINDOW, + BWIN_SHOW_WINDOW, + BWIN_HIDE_WINDOW, + BWIN_MAXIMIZE_WINDOW, + BWIN_MINIMIZE_WINDOW, + BWIN_RESTORE_WINDOW, + BWIN_SET_TITLE, + BWIN_SET_BORDERED, + BWIN_SET_RESIZABLE, + BWIN_FULLSCREEN, + BWIN_UPDATE_FRAMEBUFFER, + BWIN_MINIMUM_SIZE_WINDOW +}; + +// non-OpenGL framebuffer view +class SDL_BView : public BView +{ + public: + SDL_BView(BRect frame, const char *name, uint32 resizingMode) + : BView(frame, name, resizingMode, B_WILL_DRAW), + fBitmap(NULL) + { + } + + void Draw(BRect dirty) + { + if (fBitmap != NULL) + DrawBitmap(fBitmap, B_ORIGIN); + } + + void SetBitmap(BBitmap *bitmap) + { + fBitmap = bitmap; + } + + private: + BBitmap *fBitmap; +}; + +class SDL_BWin : public BWindow +{ + public: + // Constructor/Destructor + SDL_BWin(BRect bounds, window_look look, uint32 flags) + : BWindow(bounds, "Untitled", look, B_NORMAL_WINDOW_FEEL, flags) + { + _last_buttons = 0; + + _cur_view = NULL; + _SDL_View = NULL; + +#ifdef SDL_VIDEO_OPENGL + _SDL_GLView = NULL; + _gl_type = 0; +#endif + _shown = false; + _inhibit_resize = false; + _mouse_focused = false; + _prev_frame = NULL; + _fullscreen = NULL; + + // Handle framebuffer stuff + _buffer_locker = new BLocker(); + _bitmap = NULL; + } + + virtual ~SDL_BWin() + { + Lock(); + + if (_SDL_View != NULL && _SDL_View != _cur_view) { + delete _SDL_View; + _SDL_View = NULL; + } + +#ifdef SDL_VIDEO_OPENGL + if (_SDL_GLView) { + if (SDL_Looper->GetCurrentContext() == _SDL_GLView) + SDL_Looper->SetCurrentContext(NULL); + if (_SDL_GLView == _cur_view) + RemoveChild(_SDL_GLView); + _SDL_GLView = NULL; + // _SDL_GLView deleted by HAIKU_GL_DestroyContext + } + +#endif + Unlock(); + + delete _prev_frame; + + // Clean up framebuffer stuff + _buffer_locker->Lock(); + delete _buffer_locker; + } + + void SetCurrentView(BView *view) + { + if (_cur_view != view) { + if (_cur_view != NULL) + RemoveChild(_cur_view); + _cur_view = view; + if (_cur_view != NULL) + AddChild(_cur_view); + } + } + + void UpdateCurrentView() + { +#ifdef SDL_VIDEO_OPENGL + if (_SDL_GLView != NULL) { + SetCurrentView(_SDL_GLView); + } else +#endif + if (_SDL_View != NULL) { + SetCurrentView(_SDL_View); + } else { + SetCurrentView(NULL); + } + } + + SDL_BView *CreateView() + { + Lock(); + if (_SDL_View == NULL) { + _SDL_View = new SDL_BView(Bounds(), "SDL View", B_FOLLOW_ALL_SIDES); + UpdateCurrentView(); + } + Unlock(); + return _SDL_View; + } + + void RemoveView() + { + Lock(); + if (_SDL_View != NULL) { + SDL_BView *oldView = _SDL_View; + _SDL_View = NULL; + UpdateCurrentView(); + delete oldView; + } + Unlock(); + } + + /* * * * * OpenGL functionality * * * * */ +#ifdef SDL_VIDEO_OPENGL + BGLView *CreateGLView(Uint32 gl_flags) + { + Lock(); + if (_SDL_GLView == NULL) { + _SDL_GLView = new BGLView(Bounds(), "SDL GLView", + B_FOLLOW_ALL_SIDES, + (B_WILL_DRAW | B_FRAME_EVENTS), + gl_flags); + _gl_type = gl_flags; + UpdateCurrentView(); + } + Unlock(); + return _SDL_GLView; + } + + void RemoveGLView() + { + Lock(); + if (_SDL_GLView != NULL) { + if (SDL_Looper->GetCurrentContext() == _SDL_GLView) + SDL_Looper->SetCurrentContext(NULL); + _SDL_GLView = NULL; + UpdateCurrentView(); + // _SDL_GLView deleted by HAIKU_GL_DestroyContext + } + Unlock(); + } + + void SwapBuffers(void) + { + _SDL_GLView->SwapBuffers(); + } +#endif + + /* * * * * Event sending * * * * */ + // Hook functions + virtual void FrameMoved(BPoint origin) + { + // Post a message to the BApp so that it can handle the window event + BMessage msg(BAPP_WINDOW_MOVED); + msg.AddInt32("window-x", (int)origin.x); + msg.AddInt32("window-y", (int)origin.y); + _PostWindowEvent(msg); + + // Perform normal hook operations + BWindow::FrameMoved(origin); + } + + void FrameResized(float width, float height) + { + // Post a message to the BApp so that it can handle the window event + BMessage msg(BAPP_WINDOW_RESIZED); + + msg.AddInt32("window-w", (int)width + 1); + msg.AddInt32("window-h", (int)height + 1); + _PostWindowEvent(msg); + + // Perform normal hook operations + BWindow::FrameResized(width, height); + } + + bool QuitRequested() + { + BMessage msg(BAPP_WINDOW_CLOSE_REQUESTED); + _PostWindowEvent(msg); + + // We won't allow a quit unless asked by DestroyWindow() + return false; + } + + void WindowActivated(bool active) + { + BMessage msg(BAPP_KEYBOARD_FOCUS); // Mouse focus sold separately + msg.AddBool("focusGained", active); + _PostWindowEvent(msg); + } + + void Zoom(BPoint origin, + float width, + float height) + { + BMessage msg(BAPP_MAXIMIZE); // Closest thing to maximization Haiku has + _PostWindowEvent(msg); + + // Before the window zooms, record its size + if (!_prev_frame) + _prev_frame = new BRect(Frame()); + + // Perform normal hook operations + BWindow::Zoom(origin, width, height); + } + + // Member functions + void Show() + { + while (IsHidden()) { + BWindow::Show(); + } + _shown = true; + + BMessage msg(BAPP_SHOW); + _PostWindowEvent(msg); + } + + void Hide() + { + BWindow::Hide(); + _shown = false; + + BMessage msg(BAPP_HIDE); + _PostWindowEvent(msg); + } + + void Minimize(bool minimize) + { + BWindow::Minimize(minimize); + int32 minState = (minimize ? BAPP_MINIMIZE : BAPP_RESTORE); + + BMessage msg(minState); + _PostWindowEvent(msg); + } + + void ScreenChanged(BRect screenFrame, color_space depth) + { + if (_fullscreen) { + MoveTo(screenFrame.left, screenFrame.top); + ResizeTo(screenFrame.Width(), screenFrame.Height()); + } + } + + // BView message interruption + void DispatchMessage(BMessage *msg, BHandler *target) + { + BPoint where; // Used by mouse moved + int32 buttons; // Used for mouse button events + int32 key; // Used for key events + + switch (msg->what) { + case B_MOUSE_MOVED: + int32 transit; + if (msg->FindPoint("where", &where) == B_OK && msg->FindInt32("be:transit", &transit) == B_OK) { + _MouseMotionEvent(where, transit); + } + break; + + case B_MOUSE_DOWN: + if (msg->FindInt32("buttons", &buttons) == B_OK) { + _MouseButtonEvent(buttons, true); + } + break; + + case B_MOUSE_UP: + if (msg->FindInt32("buttons", &buttons) == B_OK) { + _MouseButtonEvent(buttons, false); + } + break; + + case B_MOUSE_WHEEL_CHANGED: + float x, y; + if (msg->FindFloat("be:wheel_delta_x", &x) == B_OK && msg->FindFloat("be:wheel_delta_y", &y) == B_OK) { + _MouseWheelEvent((int)x, (int)y); + } + break; + + case B_KEY_DOWN: + { + int32 i = 0; + int8 byte; + int8 bytes[4] = { 0, 0, 0, 0 }; + while (i < 4 && msg->FindInt8("byte", i, &byte) == B_OK) { + bytes[i] = byte; + i++; + } + if (msg->FindInt32("key", &key) == B_OK) { + _KeyEvent((SDL_Scancode)key, &bytes[0], i, true); + } + } break; + + case B_UNMAPPED_KEY_DOWN: // modifier keys are unmapped + if (msg->FindInt32("key", &key) == B_OK) { + _KeyEvent((SDL_Scancode)key, NULL, 0, true); + } + break; + + case B_KEY_UP: + case B_UNMAPPED_KEY_UP: // modifier keys are unmapped + if (msg->FindInt32("key", &key) == B_OK) { + _KeyEvent(key, NULL, 0, false); + } + break; + + default: + /* move it after switch{} so it's always handled + that way we keep Haiku features like: + - CTRL+Q to close window (and other shortcuts) + - PrintScreen to make screenshot into /boot/home + - etc.. */ + // BWindow::DispatchMessage(msg, target); + break; + } + + BWindow::DispatchMessage(msg, target); + } + + // Handle command messages + void MessageReceived(BMessage *message) + { + switch (message->what) { + // Handle commands from SDL + case BWIN_SET_TITLE: + _SetTitle(message); + break; + case BWIN_MOVE_WINDOW: + _MoveTo(message); + break; + case BWIN_RESIZE_WINDOW: + _ResizeTo(message); + break; + case BWIN_SET_BORDERED: + { + bool bEnabled; + if (message->FindBool("window-border", &bEnabled) == B_OK) + _SetBordered(bEnabled); + break; + } + case BWIN_SET_RESIZABLE: + { + bool bEnabled; + if (message->FindBool("window-resizable", &bEnabled) == B_OK) + _SetResizable(bEnabled); + break; + } + case BWIN_SHOW_WINDOW: + Show(); + break; + case BWIN_HIDE_WINDOW: + Hide(); + break; + case BWIN_MAXIMIZE_WINDOW: + BWindow::Zoom(); + break; + case BWIN_MINIMIZE_WINDOW: + Minimize(true); + break; + case BWIN_RESTORE_WINDOW: + _Restore(); + break; + case BWIN_FULLSCREEN: + { + bool fullscreen; + if (message->FindBool("fullscreen", &fullscreen) == B_OK) + _SetFullScreen(fullscreen); + break; + } + case BWIN_MINIMUM_SIZE_WINDOW: + _SetMinimumSize(message); + break; + case BWIN_UPDATE_FRAMEBUFFER: + { + BMessage *pendingMessage; + while ((pendingMessage = MessageQueue()->FindMessage(BWIN_UPDATE_FRAMEBUFFER, 0))) { + MessageQueue()->RemoveMessage(pendingMessage); + delete pendingMessage; + } + if (_bitmap != NULL) { +#ifdef SDL_VIDEO_OPENGL + if (_SDL_GLView != NULL && _cur_view == _SDL_GLView) { + _SDL_GLView->CopyPixelsIn(_bitmap, B_ORIGIN); + } else +#endif + if (_SDL_View != NULL && _cur_view == _SDL_View) { + _SDL_View->Draw(Bounds()); + } + } + break; + } + default: + // Perform normal message handling + BWindow::MessageReceived(message); + break; + } + } + + // Accessor methods + bool IsShown() { return _shown; } + int32 GetID() { return _id; } + BBitmap *GetBitmap() { return _bitmap; } + BView *GetCurView() { return _cur_view; } + SDL_BView *GetView() { return _SDL_View; } +#ifdef SDL_VIDEO_OPENGL + BGLView *GetGLView() + { + return _SDL_GLView; + } + Uint32 GetGLType() { return _gl_type; } +#endif + + // Setter methods + void SetID(int32 id) { _id = id; } + void LockBuffer() { _buffer_locker->Lock(); } + void UnlockBuffer() { _buffer_locker->Unlock(); } + void SetBitmap(BBitmap *bitmap) + { + _bitmap = bitmap; + if (_SDL_View != NULL) + _SDL_View->SetBitmap(bitmap); + } + + private: + // Event redirection + void _MouseMotionEvent(BPoint &where, int32 transit) + { + if (transit == B_EXITED_VIEW) { + // Change mouse focus + if (_mouse_focused) { + _MouseFocusEvent(false); + } + } else { + // Change mouse focus + if (!_mouse_focused) { + _MouseFocusEvent(true); + } + BMessage msg(BAPP_MOUSE_MOVED); + msg.AddInt32("x", (int)where.x); + msg.AddInt32("y", (int)where.y); + + _PostWindowEvent(msg); + } + } + + void _MouseFocusEvent(bool focusGained) + { + _mouse_focused = focusGained; + BMessage msg(BAPP_MOUSE_FOCUS); + msg.AddBool("focusGained", focusGained); + _PostWindowEvent(msg); + + /* FIXME: Why were these here? + if false: be_app->SetCursor(B_HAND_CURSOR); + if true: SDL_SetCursor(NULL); */ + } + + void _MouseButtonEvent(int32 buttons, bool down) + { + int32 buttonStateChange = buttons ^ _last_buttons; + + if (buttonStateChange & B_PRIMARY_MOUSE_BUTTON) { + _SendMouseButton(SDL_BUTTON_LEFT, down); + } + if (buttonStateChange & B_SECONDARY_MOUSE_BUTTON) { + _SendMouseButton(SDL_BUTTON_RIGHT, down); + } + if (buttonStateChange & B_TERTIARY_MOUSE_BUTTON) { + _SendMouseButton(SDL_BUTTON_MIDDLE, down); + } + + _last_buttons = buttons; + } + + void _SendMouseButton(int32 button, bool down) + { + BMessage msg(BAPP_MOUSE_BUTTON); + msg.AddInt32("button-id", button); + msg.AddBool("button-down", down); + _PostWindowEvent(msg); + } + + void _MouseWheelEvent(int32 x, int32 y) + { + // Create a message to pass along to the BeApp thread + BMessage msg(BAPP_MOUSE_WHEEL); + msg.AddInt32("xticks", x); + msg.AddInt32("yticks", y); + _PostWindowEvent(msg); + } + + void _KeyEvent(int32 keyCode, const int8 *keyUtf8, const ssize_t &len, bool down) + { + // Create a message to pass along to the BeApp thread + BMessage msg(BAPP_KEY); + msg.AddInt32("key-scancode", keyCode); + if (keyUtf8 != NULL) { + msg.AddData("key-utf8", B_INT8_TYPE, (const void *)keyUtf8, len); + } + msg.AddBool("key-down", down); + SDL_Looper->PostMessage(&msg); + } + + void _RepaintEvent() + { + // Force a repaint: Call the SDL exposed event + BMessage msg(BAPP_REPAINT); + _PostWindowEvent(msg); + } + void _PostWindowEvent(BMessage &msg) + { + msg.AddInt32("window-id", _id); + SDL_Looper->PostMessage(&msg); + } + + // Command methods (functions called upon by SDL) + void _SetTitle(BMessage *msg) + { + const char *title; + if ( + msg->FindString("window-title", &title) != B_OK) { + return; + } + SetTitle(title); + } + + void _MoveTo(BMessage *msg) + { + int32 x, y; + if ( + msg->FindInt32("window-x", &x) != B_OK || + msg->FindInt32("window-y", &y) != B_OK) { + return; + } + if (_fullscreen) + _non_fullscreen_frame.OffsetTo(x, y); + else + MoveTo(x, y); + } + + void _ResizeTo(BMessage *msg) + { + int32 w, h; + if ( + msg->FindInt32("window-w", &w) != B_OK || + msg->FindInt32("window-h", &h) != B_OK) { + return; + } + if (_fullscreen) { + _non_fullscreen_frame.right = _non_fullscreen_frame.left + w; + _non_fullscreen_frame.bottom = _non_fullscreen_frame.top + h; + } else + ResizeTo(w, h); + } + + void _SetBordered(bool bEnabled) + { + if (_fullscreen) + _bordered = bEnabled; + else + SetLook(bEnabled ? B_TITLED_WINDOW_LOOK : B_NO_BORDER_WINDOW_LOOK); + } + + void _SetResizable(bool bEnabled) + { + if (_fullscreen) + _resizable = bEnabled; + else { + if (bEnabled) { + SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_ZOOMABLE)); + } else { + SetFlags(Flags() | (B_NOT_RESIZABLE | B_NOT_ZOOMABLE)); + } + } + } + + void _SetMinimumSize(BMessage *msg) + { + float maxHeight; + float maxWidth; + float _; + int32 minHeight; + int32 minWidth; + + // This is a bit convoluted, we only want to set the minimum not the maximum + // But there is no direct call to do that, so store the maximum size beforehand + GetSizeLimits(&_, &maxWidth, &_, &maxHeight); + if (msg->FindInt32("window-w", &minWidth) != B_OK) + return; + if (msg->FindInt32("window-h", &minHeight) != B_OK) + return; + SetSizeLimits((float)minWidth, maxWidth, (float)minHeight, maxHeight); + UpdateSizeLimits(); + } + + void _Restore() + { + if (IsMinimized()) { + Minimize(false); + } else if (IsHidden()) { + Show(); + } else if (_fullscreen) { + + } else if (_prev_frame != NULL) { // Zoomed + MoveTo(_prev_frame->left, _prev_frame->top); + ResizeTo(_prev_frame->Width(), _prev_frame->Height()); + } + } + + void _SetFullScreen(bool fullscreen) + { + if (fullscreen != _fullscreen) { + if (fullscreen) { + BScreen screen(this); + BRect screenFrame = screen.Frame(); + printf("screen frame: "); + screenFrame.PrintToStream(); + printf("\n"); + _bordered = Look() != B_NO_BORDER_WINDOW_LOOK; + _resizable = !(Flags() & B_NOT_RESIZABLE); + _non_fullscreen_frame = Frame(); + _SetBordered(false); + _SetResizable(false); + MoveTo(screenFrame.left, screenFrame.top); + ResizeTo(screenFrame.Width(), screenFrame.Height()); + _fullscreen = fullscreen; + } else { + _fullscreen = fullscreen; + MoveTo(_non_fullscreen_frame.left, _non_fullscreen_frame.top); + ResizeTo(_non_fullscreen_frame.Width(), _non_fullscreen_frame.Height()); + _SetBordered(_bordered); + _SetResizable(_resizable); + } + } + } + + // Members + + BView *_cur_view; + SDL_BView *_SDL_View; +#ifdef SDL_VIDEO_OPENGL + BGLView *_SDL_GLView; + Uint32 _gl_type; +#endif + + int32 _last_buttons; + int32 _id; // Window id used by SDL_BApp + bool _mouse_focused; // Does this window have mouse focus? + bool _shown; + bool _inhibit_resize; + + BRect *_prev_frame; // Previous position and size of the window + bool _fullscreen; + // valid only if fullscreen + BRect _non_fullscreen_frame; + bool _bordered; + bool _resizable; + + // Framebuffer members + BLocker *_buffer_locker; + BBitmap *_bitmap; +}; + +/* FIXME: + * An explanation of framebuffer flags. + * + * _connected - Original variable used to let the drawing thread know + * when changes are being made to the other framebuffer + * members. + * _connection_disabled - Used to signal to the drawing thread that the window + * is closing, and the thread should exit. + * _buffer_created - True if the current buffer is valid + * _buffer_dirty - True if the window should be redrawn. + * _trash_window_buffer - True if the window buffer needs to be trashed partway + * through a draw cycle. Occurs when the previous + * buffer provided by DirectConnected() is invalidated. + */ +#endif // SDL_BWin_h_ diff --git a/contrib/SDL-3.2.8/src/video/haiku/SDL_bclipboard.cc b/contrib/SDL-3.2.8/src/video/haiku/SDL_bclipboard.cc new file mode 100644 index 0000000..ff2bc6b --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/haiku/SDL_bclipboard.cc @@ -0,0 +1,93 @@ +/* + 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" + +#ifdef SDL_VIDEO_DRIVER_HAIKU + +// BWindow based clipboard implementation + +#include +#include + +#include "SDL_BWin.h" +#include "../SDL_sysvideo.h" + +#ifdef __cplusplus +extern "C" { +#endif + +bool HAIKU_SetClipboardText(SDL_VideoDevice *_this, const char *text) +{ + BMessage *clip = NULL; + if (be_clipboard->Lock()) { + be_clipboard->Clear(); + if ((clip = be_clipboard->Data())) { + // Presumably the string of characters is ascii-format + ssize_t asciiLength = 0; + for (; text[asciiLength] != 0; ++asciiLength) {} + clip->AddData("text/plain", B_MIME_TYPE, text, asciiLength); + be_clipboard->Commit(); + } + be_clipboard->Unlock(); + } + return true; +} + +char *HAIKU_GetClipboardText(SDL_VideoDevice *_this) { + BMessage *clip = NULL; + const char *text = NULL; + ssize_t length; + char *result; + if (be_clipboard->Lock()) { + if ((clip = be_clipboard->Data())) { + // Presumably the string of characters is ascii-format + clip->FindData("text/plain", B_MIME_TYPE, (const void**)&text, + &length); + } + be_clipboard->Unlock(); + } + + if (!text) { + result = SDL_strdup(""); + } else { + // Copy the data and pass on to SDL + result = (char *)SDL_malloc((length + 1) * sizeof(char)); + SDL_strlcpy(result, text, length + 1); + } + + return result; +} + +bool HAIKU_HasClipboardText(SDL_VideoDevice *_this) { + bool result = false; + char *text = HAIKU_GetClipboardText(_this); + if (text) { + result = (text[0] != '\0'); + SDL_free(text); + } + return result; +} + +#ifdef __cplusplus +} +#endif + +#endif // SDL_VIDEO_DRIVER_HAIKU diff --git a/contrib/SDL-3.2.8/src/video/haiku/SDL_bclipboard.h b/contrib/SDL-3.2.8/src/video/haiku/SDL_bclipboard.h new file mode 100644 index 0000000..72965ba --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/haiku/SDL_bclipboard.h @@ -0,0 +1,31 @@ +/* + 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" + +#ifndef SDL_BCLIPBOARD_H +#define SDL_BCLIPBOARD_H + +extern bool HAIKU_SetClipboardText(SDL_VideoDevice *_this, const char *text); +extern char *HAIKU_GetClipboardText(SDL_VideoDevice *_this); +extern bool HAIKU_HasClipboardText(SDL_VideoDevice *_this); + +#endif diff --git a/contrib/SDL-3.2.8/src/video/haiku/SDL_bevents.cc b/contrib/SDL-3.2.8/src/video/haiku/SDL_bevents.cc new file mode 100644 index 0000000..ee23b20 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/haiku/SDL_bevents.cc @@ -0,0 +1,39 @@ +/* + 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" + +#ifdef SDL_VIDEO_DRIVER_HAIKU + +#include "SDL_bevents.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void HAIKU_PumpEvents(SDL_VideoDevice *_this) { + // Since the event thread is its own thread, this isn't really necessary +} + +#ifdef __cplusplus +} +#endif + +#endif // SDL_VIDEO_DRIVER_HAIKU diff --git a/contrib/SDL-3.2.8/src/video/haiku/SDL_bevents.h b/contrib/SDL-3.2.8/src/video/haiku/SDL_bevents.h new file mode 100644 index 0000000..de2c909 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/haiku/SDL_bevents.h @@ -0,0 +1,37 @@ +/* + 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. +*/ + +#ifndef SDL_BEVENTS_H +#define SDL_BEVENTS_H + +#include "../SDL_sysvideo.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void HAIKU_PumpEvents(SDL_VideoDevice *_this); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/contrib/SDL-3.2.8/src/video/haiku/SDL_bframebuffer.cc b/contrib/SDL-3.2.8/src/video/haiku/SDL_bframebuffer.cc new file mode 100644 index 0000000..d152255 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/haiku/SDL_bframebuffer.cc @@ -0,0 +1,128 @@ +/* + 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" + +#ifdef SDL_VIDEO_DRIVER_HAIKU + +#include "SDL_bframebuffer.h" + +#include +#include +#include "SDL_bmodes.h" +#include "SDL_BWin.h" + +#include "../../core/haiku/SDL_BApp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) +{ + return (SDL_BWin *)(window->internal); +} + +static SDL_INLINE SDL_BLooper *_GetBeLooper() +{ + return SDL_Looper; +} + +bool HAIKU_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window * window, SDL_PixelFormat * format, void ** pixels, int *pitch) +{ + SDL_BWin *bwin = _ToBeWin(window); + BScreen bscreen; + if (!bscreen.IsValid()) { + return false; + } + + // Make sure we have exclusive access to frame buffer data + bwin->LockBuffer(); + + bwin->CreateView(); + + // format + display_mode bmode; + bscreen.GetMode(&bmode); + *format = HAIKU_ColorSpaceToSDLPxFormat(bmode.space); + + // Create the new bitmap object + BBitmap *bitmap = bwin->GetBitmap(); + + if (bitmap) { + delete bitmap; + } + bitmap = new BBitmap(bwin->Bounds(), (color_space)bmode.space, + false, // Views not accepted + true); // Contiguous memory required + + if (bitmap->InitCheck() != B_OK) { + delete bitmap; + return SDL_SetError("Could not initialize back buffer!"); + } + + + bwin->SetBitmap(bitmap); + + // Set the pixel pointer + *pixels = bitmap->Bits(); + + // pitch = width of window, in bytes + *pitch = bitmap->BytesPerRow(); + + bwin->UnlockBuffer(); + return true; +} + + + +bool HAIKU_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window * window, + const SDL_Rect * rects, int numrects) { + if (!window) { + return true; + } + + SDL_BWin *bwin = _ToBeWin(window); + + bwin->PostMessage(BWIN_UPDATE_FRAMEBUFFER); + + return true; +} + +void HAIKU_DestroyWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window * window) { + SDL_BWin *bwin = _ToBeWin(window); + + bwin->LockBuffer(); + + // Free and clear the window buffer + BBitmap *bitmap = bwin->GetBitmap(); + delete bitmap; + bwin->SetBitmap(NULL); + + bwin->RemoveView(); + + bwin->UnlockBuffer(); +} + +#ifdef __cplusplus +} +#endif + +#endif // SDL_VIDEO_DRIVER_HAIKU diff --git a/contrib/SDL-3.2.8/src/video/haiku/SDL_bframebuffer.h b/contrib/SDL-3.2.8/src/video/haiku/SDL_bframebuffer.h new file mode 100644 index 0000000..c782001 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/haiku/SDL_bframebuffer.h @@ -0,0 +1,45 @@ +/* + 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. +*/ + +#ifndef SDL_BFRAMEBUFFER_H +#define SDL_BFRAMEBUFFER_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +#define DRAWTHREAD + +#include "../SDL_sysvideo.h" + +extern bool HAIKU_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, + SDL_PixelFormat *format, + void **pixels, int *pitch); +extern bool HAIKU_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, + const SDL_Rect *rects, int numrects); +extern void HAIKU_DestroyWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window); +extern int32 HAIKU_DrawThread(void *data); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/contrib/SDL-3.2.8/src/video/haiku/SDL_bkeyboard.cc b/contrib/SDL-3.2.8/src/video/haiku/SDL_bkeyboard.cc new file mode 100644 index 0000000..c4f364e --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/haiku/SDL_bkeyboard.cc @@ -0,0 +1,168 @@ +/* + 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" + +#ifdef SDL_VIDEO_DRIVER_HAIKU + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "SDL_bkeyboard.h" + + +#define KEYMAP_SIZE 128 + + +static SDL_Scancode keymap[KEYMAP_SIZE]; + +void HAIKU_InitOSKeymap(void) +{ + for ( uint i = 0; i < SDL_arraysize(keymap); ++i ) { + keymap[i] = SDL_SCANCODE_UNKNOWN; + } + + keymap[0x01] = SDL_SCANCODE_ESCAPE; + keymap[B_F1_KEY] = SDL_SCANCODE_F1; + keymap[B_F2_KEY] = SDL_SCANCODE_F2; + keymap[B_F3_KEY] = SDL_SCANCODE_F3; + keymap[B_F4_KEY] = SDL_SCANCODE_F4; + keymap[B_F5_KEY] = SDL_SCANCODE_F5; + keymap[B_F6_KEY] = SDL_SCANCODE_F6; + keymap[B_F7_KEY] = SDL_SCANCODE_F7; + keymap[B_F8_KEY] = SDL_SCANCODE_F8; + keymap[B_F9_KEY] = SDL_SCANCODE_F9; + keymap[B_F10_KEY] = SDL_SCANCODE_F10; + keymap[B_F11_KEY] = SDL_SCANCODE_F11; + keymap[B_F12_KEY] = SDL_SCANCODE_F12; + keymap[B_PRINT_KEY] = SDL_SCANCODE_PRINTSCREEN; + keymap[B_SCROLL_KEY]= SDL_SCANCODE_SCROLLLOCK; + keymap[B_PAUSE_KEY] = SDL_SCANCODE_PAUSE; + keymap[0x11] = SDL_SCANCODE_GRAVE; + keymap[0x12] = SDL_SCANCODE_1; + keymap[0x13] = SDL_SCANCODE_2; + keymap[0x14] = SDL_SCANCODE_3; + keymap[0x15] = SDL_SCANCODE_4; + keymap[0x16] = SDL_SCANCODE_5; + keymap[0x17] = SDL_SCANCODE_6; + keymap[0x18] = SDL_SCANCODE_7; + keymap[0x19] = SDL_SCANCODE_8; + keymap[0x1a] = SDL_SCANCODE_9; + keymap[0x1b] = SDL_SCANCODE_0; + keymap[0x1c] = SDL_SCANCODE_MINUS; + keymap[0x1d] = SDL_SCANCODE_EQUALS; + keymap[0x1e] = SDL_SCANCODE_BACKSPACE; + keymap[0x1f] = SDL_SCANCODE_INSERT; + keymap[0x20] = SDL_SCANCODE_HOME; + keymap[0x21] = SDL_SCANCODE_PAGEUP; + keymap[0x22] = SDL_SCANCODE_NUMLOCKCLEAR; + keymap[0x23] = SDL_SCANCODE_KP_DIVIDE; + keymap[0x24] = SDL_SCANCODE_KP_MULTIPLY; + keymap[0x25] = SDL_SCANCODE_KP_MINUS; + keymap[0x26] = SDL_SCANCODE_TAB; + keymap[0x27] = SDL_SCANCODE_Q; + keymap[0x28] = SDL_SCANCODE_W; + keymap[0x29] = SDL_SCANCODE_E; + keymap[0x2a] = SDL_SCANCODE_R; + keymap[0x2b] = SDL_SCANCODE_T; + keymap[0x2c] = SDL_SCANCODE_Y; + keymap[0x2d] = SDL_SCANCODE_U; + keymap[0x2e] = SDL_SCANCODE_I; + keymap[0x2f] = SDL_SCANCODE_O; + keymap[0x30] = SDL_SCANCODE_P; + keymap[0x31] = SDL_SCANCODE_LEFTBRACKET; + keymap[0x32] = SDL_SCANCODE_RIGHTBRACKET; + keymap[0x33] = SDL_SCANCODE_BACKSLASH; + keymap[0x34] = SDL_SCANCODE_DELETE; + keymap[0x35] = SDL_SCANCODE_END; + keymap[0x36] = SDL_SCANCODE_PAGEDOWN; + keymap[0x37] = SDL_SCANCODE_KP_7; + keymap[0x38] = SDL_SCANCODE_KP_8; + keymap[0x39] = SDL_SCANCODE_KP_9; + keymap[0x3a] = SDL_SCANCODE_KP_PLUS; + keymap[0x3b] = SDL_SCANCODE_CAPSLOCK; + keymap[0x3c] = SDL_SCANCODE_A; + keymap[0x3d] = SDL_SCANCODE_S; + keymap[0x3e] = SDL_SCANCODE_D; + keymap[0x3f] = SDL_SCANCODE_F; + keymap[0x40] = SDL_SCANCODE_G; + keymap[0x41] = SDL_SCANCODE_H; + keymap[0x42] = SDL_SCANCODE_J; + keymap[0x43] = SDL_SCANCODE_K; + keymap[0x44] = SDL_SCANCODE_L; + keymap[0x45] = SDL_SCANCODE_SEMICOLON; + keymap[0x46] = SDL_SCANCODE_APOSTROPHE; + keymap[0x47] = SDL_SCANCODE_RETURN; + keymap[0x48] = SDL_SCANCODE_KP_4; + keymap[0x49] = SDL_SCANCODE_KP_5; + keymap[0x4a] = SDL_SCANCODE_KP_6; + keymap[0x4b] = SDL_SCANCODE_LSHIFT; + keymap[0x4c] = SDL_SCANCODE_Z; + keymap[0x4d] = SDL_SCANCODE_X; + keymap[0x4e] = SDL_SCANCODE_C; + keymap[0x4f] = SDL_SCANCODE_V; + keymap[0x50] = SDL_SCANCODE_B; + keymap[0x51] = SDL_SCANCODE_N; + keymap[0x52] = SDL_SCANCODE_M; + keymap[0x53] = SDL_SCANCODE_COMMA; + keymap[0x54] = SDL_SCANCODE_PERIOD; + keymap[0x55] = SDL_SCANCODE_SLASH; + keymap[0x56] = SDL_SCANCODE_RSHIFT; + keymap[0x57] = SDL_SCANCODE_UP; + keymap[0x58] = SDL_SCANCODE_KP_1; + keymap[0x59] = SDL_SCANCODE_KP_2; + keymap[0x5a] = SDL_SCANCODE_KP_3; + keymap[0x5b] = SDL_SCANCODE_KP_ENTER; + keymap[0x5c] = SDL_SCANCODE_LCTRL; + keymap[0x5d] = SDL_SCANCODE_LALT; + keymap[0x5e] = SDL_SCANCODE_SPACE; + keymap[0x5f] = SDL_SCANCODE_RALT; + keymap[0x60] = SDL_SCANCODE_RCTRL; + keymap[0x61] = SDL_SCANCODE_LEFT; + keymap[0x62] = SDL_SCANCODE_DOWN; + keymap[0x63] = SDL_SCANCODE_RIGHT; + keymap[0x64] = SDL_SCANCODE_KP_0; + keymap[0x65] = SDL_SCANCODE_KP_PERIOD; + keymap[0x66] = SDL_SCANCODE_LGUI; + keymap[0x67] = SDL_SCANCODE_RGUI; + keymap[0x68] = SDL_SCANCODE_MENU; + keymap[0x69] = SDL_SCANCODE_2; // SDLK_EURO + keymap[0x6a] = SDL_SCANCODE_KP_EQUALS; + keymap[0x6b] = SDL_SCANCODE_POWER; +} + +SDL_Scancode HAIKU_GetScancodeFromBeKey(int32 bkey) { + if (bkey > 0 && bkey < (int32)SDL_arraysize(keymap)) { + return keymap[bkey]; + } else { + return SDL_SCANCODE_UNKNOWN; + } +} + +#ifdef __cplusplus +} +#endif + +#endif // SDL_VIDEO_DRIVER_HAIKU diff --git a/contrib/SDL-3.2.8/src/video/haiku/SDL_bkeyboard.h b/contrib/SDL-3.2.8/src/video/haiku/SDL_bkeyboard.h new file mode 100644 index 0000000..57fd77a --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/haiku/SDL_bkeyboard.h @@ -0,0 +1,38 @@ +/* + 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. +*/ + +#ifndef SDL_BKEYBOARD_H +#define SDL_BKEYBOARD_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern void HAIKU_InitOSKeymap(void); +extern SDL_Scancode HAIKU_GetScancodeFromBeKey(int32 bkey); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/contrib/SDL-3.2.8/src/video/haiku/SDL_bmessagebox.cc b/contrib/SDL-3.2.8/src/video/haiku/SDL_bmessagebox.cc new file mode 100644 index 0000000..75bef70 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/haiku/SDL_bmessagebox.cc @@ -0,0 +1,383 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 2018-2019 EXL + + 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" + +#ifdef SDL_VIDEO_DRIVER_HAIKU + + +// For application signature. +#include "../../core/haiku/SDL_BeApp.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +enum +{ + G_CLOSE_BUTTON_ID = -1, + G_DEFAULT_BUTTON_ID = 0, + G_MAX_STRING_LENGTH_BYTES = 120 +}; + +class HAIKU_SDL_MessageBox : public BAlert +{ + float fComputedMessageBoxWidth; + + BTextView *fMessageBoxTextView; + + int fCloseButton; + int fDefaultButton; + + bool fCustomColorScheme; + bool fThereIsLongLine; + rgb_color fTextColor; + + const char *fTitle; + const char *HAIKU_SDL_DefTitle; + const char *HAIKU_SDL_DefMessage; + const char *HAIKU_SDL_DefButton; + + std::vector fButtons; + + static bool + SortButtonsPredicate(const SDL_MessageBoxButtonData *aButtonLeft, + const SDL_MessageBoxButtonData *aButtonRight) + { + return aButtonLeft->buttonID < aButtonRight->buttonID; + } + + alert_type + ConvertMessageBoxType(const SDL_MessageBoxFlags aWindowType) const + { + switch (aWindowType) + { + default: + case SDL_MESSAGEBOX_WARNING: + { + return B_WARNING_ALERT; + } + case SDL_MESSAGEBOX_ERROR: + { + return B_STOP_ALERT; + } + case SDL_MESSAGEBOX_INFORMATION: + { + return B_INFO_ALERT; + } + } + } + + rgb_color + ConvertColorType(const SDL_MessageBoxColor *aColor) const + { + rgb_color color = { aColor->r, aColor->g, aColor->b, color.alpha = 255 }; + return color; + } + + int32 + GetLeftPanelWidth(void) const + { + // See file "haiku/src/kits/interface/Alert.cpp" for this magic numbers. + // IconStripeWidth = 30 * Scale + // IconSize = 32 * Scale + // Scale = max_c(1, ((int32)be_plain_font->Size() + 15) / 16) + // RealWidth = (IconStripeWidth * Scale) + (IconSize * Scale) + + int32 scale = max_c(1, ((int32)be_plain_font->Size() + 15) / 16); + return (30 * scale) + (32 * scale); + } + + void + UpdateTextViewWidth(void) + { + fComputedMessageBoxWidth = fMessageBoxTextView->PreferredSize().Width() + GetLeftPanelWidth(); + } + + void + ParseSdlMessageBoxData(const SDL_MessageBoxData *aMessageBoxData) + { + if (aMessageBoxData == NULL) { + SetTitle(HAIKU_SDL_DefTitle); + SetMessageText(HAIKU_SDL_DefMessage); + AddButton(HAIKU_SDL_DefButton); + return; + } + + if (aMessageBoxData->numbuttons <= 0) { + AddButton(HAIKU_SDL_DefButton); + } else { + AddSdlButtons(aMessageBoxData->buttons, aMessageBoxData->numbuttons); + } + + if (aMessageBoxData->colorScheme != NULL) { + fCustomColorScheme = true; + ApplyAndParseColorScheme(aMessageBoxData->colorScheme); + } + + (aMessageBoxData->title[0]) ? + SetTitle(aMessageBoxData->title) : SetTitle(HAIKU_SDL_DefTitle); + (aMessageBoxData->message[0]) ? + SetMessageText(aMessageBoxData->message) : SetMessageText(HAIKU_SDL_DefMessage); + + SetType(ConvertMessageBoxType(aMessageBoxData->flags)); + } + + void + ApplyAndParseColorScheme(const SDL_MessageBoxColorScheme *aColorScheme) + { + SetBackgroundColor(&aColorScheme->colors[SDL_MESSAGEBOX_COLOR_BACKGROUND]); + fTextColor = ConvertColorType(&aColorScheme->colors[SDL_MESSAGEBOX_COLOR_TEXT]); + SetButtonColors(&aColorScheme->colors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER], + &aColorScheme->colors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND], + &aColorScheme->colors[SDL_MESSAGEBOX_COLOR_TEXT], + &aColorScheme->colors[SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED]); + } + + void + SetButtonColors(const SDL_MessageBoxColor *aBorderColor, + const SDL_MessageBoxColor *aBackgroundColor, + const SDL_MessageBoxColor *aTextColor, + const SDL_MessageBoxColor *aSelectedColor) + { + if (fCustomColorScheme) { + int32 countButtons = CountButtons(); + for (int i = 0; i < countButtons; ++i) { + ButtonAt(i)->SetViewColor(ConvertColorType(aBorderColor)); + ButtonAt(i)->SetLowColor(ConvertColorType(aBackgroundColor)); + + // This doesn't work. See this why: + // https://github.com/haiku/haiku/commit/de9c53f8f5008c7b3b0af75d944a628e17f6dffe + // Let it remain. + ButtonAt(i)->SetHighColor(ConvertColorType(aTextColor)); + } + } + // TODO: Not Implemented. + // Is it even necessary?! + (void)aSelectedColor; + } + + void + SetBackgroundColor(const SDL_MessageBoxColor *aColor) + { + rgb_color background = ConvertColorType(aColor); + + GetLayout()->View()->SetViewColor(background); + // See file "haiku/src/kits/interface/Alert.cpp", the "TAlertView" is the internal name of the left panel. + FindView("TAlertView")->SetViewColor(background); + fMessageBoxTextView->SetViewColor(background); + } + + bool + CheckLongLines(const char *aMessage) + { + int final = 0; + + // This UTF-8 friendly. + BString message = aMessage; + int32 length = message.CountChars(); + + for (int i = 0, c = 0; i < length; ++i) { + c++; + if (*(message.CharAt(i)) == '\n') { + c = 0; + } + if (c > final) { + final = c; + } + } + + return (final > G_MAX_STRING_LENGTH_BYTES); + } + + void + SetMessageText(const char *aMessage) + { + fThereIsLongLine = CheckLongLines(aMessage); + if (fThereIsLongLine) { + fMessageBoxTextView->SetWordWrap(true); + } + + rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR); + if (fCustomColorScheme) { + textColor = fTextColor; + } + + /* + if (fNoTitledWindow) { + fMessageBoxTextView->SetFontAndColor(be_bold_font); + fMessageBoxTextView->Insert(fTitle); + fMessageBoxTextView->Insert("\n\n"); + fMessageBoxTextView->SetFontAndColor(be_plain_font); + } + */ + + fMessageBoxTextView->SetFontAndColor(be_plain_font, B_FONT_ALL, &textColor); + fMessageBoxTextView->Insert(aMessage); + + // Be sure to call update width method. + UpdateTextViewWidth(); + } + + void + AddSdlButtons(const SDL_MessageBoxButtonData *aButtons, int aNumButtons) + { + for (int i = 0; i < aNumButtons; ++i) { + fButtons.push_back(&aButtons[i]); + } + + std::sort(fButtons.begin(), fButtons.end(), &HAIKU_SDL_MessageBox::SortButtonsPredicate); + + size_t countButtons = fButtons.size(); + for (size_t i = 0; i < countButtons; ++i) { + if (fButtons[i]->flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) { + fCloseButton = static_cast(i); + } + if (fButtons[i]->flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) { + fDefaultButton = static_cast(i); + } + AddButton(fButtons[i]->text); + } + + SetDefaultButton(ButtonAt(fDefaultButton)); + } + +public: + explicit + HAIKU_SDL_MessageBox(const SDL_MessageBoxData *aMessageBoxData) + : BAlert(NULL, NULL, NULL, NULL, NULL, B_WIDTH_FROM_LABEL, B_WARNING_ALERT), + fComputedMessageBoxWidth(0.0f), + fCloseButton(G_CLOSE_BUTTON_ID), fDefaultButton(G_DEFAULT_BUTTON_ID), + fCustomColorScheme(false), fThereIsLongLine(false), + HAIKU_SDL_DefTitle("SDL MessageBox"), + HAIKU_SDL_DefMessage("Some information has been lost."), + HAIKU_SDL_DefButton("OK") + { + // MessageBox settings. + // We need a title to display it. + SetLook(B_TITLED_WINDOW_LOOK); + SetFlags(Flags() | B_CLOSE_ON_ESCAPE); + + // MessageBox TextView settings. + fMessageBoxTextView = TextView(); + fMessageBoxTextView->SetWordWrap(false); + fMessageBoxTextView->SetStylable(true); + + ParseSdlMessageBoxData(aMessageBoxData); + } + + int + GetCloseButtonId(void) const + { + return fCloseButton; + } + + virtual + ~HAIKU_SDL_MessageBox(void) + { + fButtons.clear(); + } + +protected: + virtual void + FrameResized(float aNewWidth, float aNewHeight) + { + if (fComputedMessageBoxWidth > aNewWidth) { + ResizeTo(fComputedMessageBoxWidth, aNewHeight); + } else { + BAlert::FrameResized(aNewWidth, aNewHeight); + } + } + + virtual void + SetTitle(const char* aTitle) + { + fTitle = aTitle; + BAlert::SetTitle(aTitle); + } +}; + +#ifdef __cplusplus +extern "C" { +#endif + +bool HAIKU_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID) +{ + // Initialize button by closed or error value first. + *buttonID = G_CLOSE_BUTTON_ID; + + // We need to check "be_app" pointer to "NULL". The "messageboxdata->window" pointer isn't appropriate here + // because it is possible to create a MessageBox from another thread. This fixes the following errors: + // "You need a valid BApplication object before interacting with the app_server." + // "2 BApplication objects were created. Only one is allowed." + std::unique_ptr application; + if (!be_app) { + application = std::unique_ptr(new(std::nothrow) BApplication(SDL_signature)); + if (!application) { + return SDL_SetError("Cannot create the BApplication object. Lack of memory?"); + } + } + + HAIKU_SDL_MessageBox *SDL_MessageBox = new(std::nothrow) HAIKU_SDL_MessageBox(messageboxdata); + if (!SDL_MessageBox) { + return SDL_SetError("Cannot create the HAIKU_SDL_MessageBox (BAlert inheritor) object. Lack of memory?"); + } + const int closeButton = SDL_MessageBox->GetCloseButtonId(); + int pushedButton = SDL_MessageBox->Go(); + + // The close button is equivalent to pressing Escape. + if (closeButton != G_CLOSE_BUTTON_ID && pushedButton == G_CLOSE_BUTTON_ID) { + pushedButton = closeButton; + } + + // It's deleted by itself after the "Go()" method was executed. + /* + if (messageBox != NULL) { + delete messageBox; + } + */ + // Initialize button by real pushed value then. + *buttonID = pushedButton; + + return true; +} + +#ifdef __cplusplus +} +#endif + +#endif // SDL_VIDEO_DRIVER_HAIKU diff --git a/contrib/SDL-3.2.8/src/video/haiku/SDL_bmessagebox.h b/contrib/SDL-3.2.8/src/video/haiku/SDL_bmessagebox.h new file mode 100644 index 0000000..e2800af --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/haiku/SDL_bmessagebox.h @@ -0,0 +1,42 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 2018-2019 EXL + + 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. +*/ + +#ifndef SDL_BMESSAGEBOX_H +#define SDL_BMESSAGEBOX_H + +#include "SDL_internal.h" + +#ifdef SDL_VIDEO_DRIVER_HAIKU + +#ifdef __cplusplus +extern "C" { +#endif + +extern bool HAIKU_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID); + +#ifdef __cplusplus +} +#endif + +#endif // SDL_VIDEO_DRIVER_HAIKU + +#endif diff --git a/contrib/SDL-3.2.8/src/video/haiku/SDL_bmodes.cc b/contrib/SDL-3.2.8/src/video/haiku/SDL_bmodes.cc new file mode 100644 index 0000000..32c8b6d --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/haiku/SDL_bmodes.cc @@ -0,0 +1,307 @@ +/* + 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" + +#ifdef SDL_VIDEO_DRIVER_HAIKU + +#include +#include +#include "SDL_bmodes.h" +#include "SDL_BWin.h" + +#ifdef SDL_VIDEO_OPENGL +#include "SDL_bopengl.h" +#endif + +#include "../../core/haiku/SDL_BApp.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define WRAP_BMODE 1 // FIXME: Some debate as to whether this is necessary + +#if WRAP_BMODE +/* This wrapper is here so that the internal can be freed without freeing + the display_mode structure */ +struct SDL_DisplayModeData { + display_mode *bmode; +}; +#endif + +static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) +{ + return (SDL_BWin *)(window->internal); +} + +static SDL_INLINE SDL_BLooper *_GetBeLooper() +{ + return SDL_Looper; +} + +static SDL_INLINE display_mode * _ExtractBMode(SDL_DisplayMode *mode) +{ +#if WRAP_BMODE + return mode->internal->bmode; +#else + return (display_mode *)mode->internal; +#endif +} + +// Copied from haiku/trunk/src/preferences/screen/ScreenMode.cpp +static void get_refresh_rate(display_mode &mode, int *numerator, int *denominator) +{ + *numerator = (mode.timing.pixel_clock * 1000); + *denominator = (mode.timing.h_total * mode.timing.v_total); +} + + +#if 0 +/* TODO: + * This is a useful debugging tool. Uncomment and insert into code as needed. + */ +void _SpoutModeData(display_mode *bmode) +{ + printf("BMode:\n"); + printf("\tw,h = (%i,%i)\n", bmode->virtual_width, bmode->virtual_height); + printf("\th,v = (%i,%i)\n", bmode->h_display_start, + bmode->v_display_start); + if (bmode->flags) { + printf("\tFlags:\n"); + if (bmode->flags & B_SCROLL) { + printf("\t\tB_SCROLL\n"); + } + if (bmode->flags & B_8_BIT_DAC) { + printf("\t\tB_8_BIT_DAC\n"); + } + if (bmode->flags & B_HARDWARE_CURSOR) { + printf("\t\tB_HARDWARE_CURSOR\n"); + } + if (bmode->flags & B_PARALLEL_ACCESS) { + printf("\t\tB_PARALLEL_ACCESS\n"); + } + if (bmode->flags & B_DPMS) { + printf("\t\tB_DPMS\n"); + } + if (bmode->flags & B_IO_FB_NA) { + printf("\t\tB_IO_FB_NA\n"); + } + } + printf("\tTiming:\n"); + printf("\t\tpx clock: %i\n", bmode->timing.pixel_clock); + printf("\t\th - display: %i sync start: %i sync end: %i total: %i\n", + bmode->timing.h_display, bmode->timing.h_sync_start, + bmode->timing.h_sync_end, bmode->timing.h_total); + printf("\t\tv - display: %i sync start: %i sync end: %i total: %i\n", + bmode->timing.v_display, bmode->timing.v_sync_start, + bmode->timing.v_sync_end, bmode->timing.v_total); + if (bmode->timing.flags) { + printf("\t\tFlags:\n"); + if (bmode->timing.flags & B_BLANK_PEDESTAL) { + printf("\t\t\tB_BLANK_PEDESTAL\n"); + } + if (bmode->timing.flags & B_TIMING_INTERLACED) { + printf("\t\t\tB_TIMING_INTERLACED\n"); + } + if (bmode->timing.flags & B_POSITIVE_HSYNC) { + printf("\t\t\tB_POSITIVE_HSYNC\n"); + } + if (bmode->timing.flags & B_POSITIVE_VSYNC) { + printf("\t\t\tB_POSITIVE_VSYNC\n"); + } + if (bmode->timing.flags & B_SYNC_ON_GREEN) { + printf("\t\t\tB_SYNC_ON_GREEN\n"); + } + } +} +#endif + + + +SDL_PixelFormat HAIKU_ColorSpaceToSDLPxFormat(uint32 colorspace) +{ + switch (colorspace) { + case B_CMAP8: + return SDL_PIXELFORMAT_INDEX8; + break; + case B_RGB15: + case B_RGBA15: + case B_RGB15_BIG: + case B_RGBA15_BIG: + return SDL_PIXELFORMAT_XRGB1555; + break; + case B_RGB16: + case B_RGB16_BIG: + return SDL_PIXELFORMAT_RGB565; + break; + case B_RGB24: + case B_RGB24_BIG: + return SDL_PIXELFORMAT_BGR24; + break; + case B_RGB32: + case B_RGBA32: + case B_RGB32_BIG: + case B_RGBA32_BIG: + return SDL_PIXELFORMAT_XRGB8888; + break; + } + + // May never get here, but safer and needed to shut up compiler + SDL_SetError("Invalid color space"); + return SDL_PIXELFORMAT_UNKNOWN; +} + +static void _BDisplayModeToSdlDisplayMode(display_mode *bmode, SDL_DisplayMode *mode) +{ + SDL_zerop(mode); + mode->w = bmode->virtual_width; + mode->h = bmode->virtual_height; + get_refresh_rate(*bmode, &mode->refresh_rate_numerator, &mode->refresh_rate_denominator); + +#if WRAP_BMODE + SDL_DisplayModeData *data = (SDL_DisplayModeData*)SDL_calloc(1, sizeof(SDL_DisplayModeData)); + data->bmode = bmode; + + mode->internal = data; +#else + mode->internal = bmode; +#endif + + // Set the format + mode->format = HAIKU_ColorSpaceToSDLPxFormat(bmode->space); +} + +// Later, there may be more than one monitor available +static void _AddDisplay(BScreen *screen) +{ + SDL_DisplayMode mode; + display_mode bmode; + screen->GetMode(&bmode); + + _BDisplayModeToSdlDisplayMode(&bmode, &mode); + + SDL_AddBasicVideoDisplay(&mode); +} + +/* + * Functions called by SDL + */ + +bool HAIKU_InitModes(SDL_VideoDevice *_this) +{ + BScreen screen; + + /* TODO: When Haiku supports multiple display screens, call + _AddDisplayScreen() for each of them. */ + _AddDisplay(&screen); + return true; +} + +void HAIKU_QuitModes(SDL_VideoDevice *_this) +{ + return; +} + + +bool HAIKU_GetDisplayBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect) +{ + BScreen bscreen; + BRect rc = bscreen.Frame(); + rect->x = (int)rc.left; + rect->y = (int)rc.top; + rect->w = (int)rc.Width() + 1; + rect->h = (int)rc.Height() + 1; + return true; +} + +bool HAIKU_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display) +{ + // Get the current screen + BScreen bscreen; + + // Iterate through all of the modes + SDL_DisplayMode mode; + display_mode this_bmode; + display_mode *bmodes; + uint32 count, i; + + // Get graphics-hardware supported modes + bscreen.GetModeList(&bmodes, &count); + bscreen.GetMode(&this_bmode); + + for (i = 0; i < count; ++i) { + // FIXME: Apparently there are errors with colorspace changes + if (bmodes[i].space == this_bmode.space) { + _BDisplayModeToSdlDisplayMode(&bmodes[i], &mode); + SDL_AddFullscreenDisplayMode(display, &mode); + } + } + free(bmodes); // This should NOT be SDL_free() + return true; +} + + +bool HAIKU_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode) +{ + // Get the current screen + BScreen bscreen; + if (!bscreen.IsValid()) { + printf(__FILE__": %d - ERROR: BAD SCREEN\n", __LINE__); + } + + // Set the mode using the driver data + display_mode *bmode = _ExtractBMode(mode); + + + // FIXME: Is the first option always going to be the right one? + uint32 c = 0, i; + display_mode *bmode_list; + bscreen.GetModeList(&bmode_list, &c); + for (i = 0; i < c; ++i) { + if ( bmode_list[i].space == bmode->space && + bmode_list[i].virtual_width == bmode->virtual_width && + bmode_list[i].virtual_height == bmode->virtual_height ) { + bmode = &bmode_list[i]; + break; + } + } + + if (bscreen.SetMode(bmode) != B_OK) { + return SDL_SetError("Bad video mode"); + } + + free(bmode_list); // This should NOT be SDL_free() + +#ifdef SDL_VIDEO_OPENGL + /* FIXME: Is there some way to reboot the OpenGL context? This doesn't + help */ +// HAIKU_GL_RebootContexts(_this); +#endif + + return true; +} + +#ifdef __cplusplus +} +#endif + +#endif // SDL_VIDEO_DRIVER_HAIKU diff --git a/contrib/SDL-3.2.8/src/video/haiku/SDL_bmodes.h b/contrib/SDL-3.2.8/src/video/haiku/SDL_bmodes.h new file mode 100644 index 0000000..2fd0bc2 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/haiku/SDL_bmodes.h @@ -0,0 +1,43 @@ +/* + 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. +*/ + +#ifndef SDL_BMODES_H +#define SDL_BMODES_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../SDL_sysvideo.h" + +extern SDL_PixelFormat HAIKU_ColorSpaceToSDLPxFormat(uint32 colorspace); + +extern bool HAIKU_InitModes(SDL_VideoDevice *_this); +extern void HAIKU_QuitModes(SDL_VideoDevice *_this); +extern bool HAIKU_GetDisplayBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect); +extern bool HAIKU_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display); +extern bool HAIKU_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/contrib/SDL-3.2.8/src/video/haiku/SDL_bopengl.cc b/contrib/SDL-3.2.8/src/video/haiku/SDL_bopengl.cc new file mode 100644 index 0000000..469b7f6 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/haiku/SDL_bopengl.cc @@ -0,0 +1,205 @@ +/* + 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" + +#if defined(SDL_VIDEO_DRIVER_HAIKU) && defined(SDL_VIDEO_OPENGL) + +#include "SDL_bopengl.h" + +#include +#include +#include +#include "SDL_BWin.h" +#include "../../core/haiku/SDL_BApp.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) +{ + return (SDL_BWin *)(window->internal); +} + +static SDL_INLINE SDL_BLooper *_GetBeLooper() +{ + return SDL_Looper; +} + +// Passing a NULL path means load pointers from the application +bool HAIKU_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path) +{ +// FIXME: Is this working correctly? + image_info info; + int32 cookie = 0; + while (get_next_image_info(0, &cookie, &info) == B_OK) { + void *location = NULL; + if ( get_image_symbol(info.id, "glBegin", B_SYMBOL_TYPE_ANY, + &location) == B_OK) { + + _this->gl_config.dll_handle = (SDL_SharedObject *) (addr_t) info.id; + _this->gl_config.driver_loaded = 1; + SDL_strlcpy(_this->gl_config.driver_path, "libGL.so", + SDL_arraysize(_this->gl_config.driver_path)); + } + } + return true; +} + +SDL_FunctionPointer HAIKU_GL_GetProcAddress(SDL_VideoDevice *_this, const char *proc) +{ + if (_this->gl_config.dll_handle) { + void *location = NULL; + status_t err; + if ((err = + get_image_symbol((image_id) (addr_t) _this->gl_config.dll_handle, + proc, B_SYMBOL_TYPE_ANY, + &location)) == B_OK) { + return (SDL_FunctionPointer)location; + } else { + SDL_SetError("Couldn't find OpenGL symbol"); + return NULL; + } + } else { + SDL_SetError("OpenGL library not loaded"); + return NULL; + } +} + + +bool HAIKU_GL_SwapWindow(SDL_VideoDevice *_this, SDL_Window * window) +{ + _ToBeWin(window)->SwapBuffers(); + return true; +} + +bool HAIKU_GL_MakeCurrent(SDL_VideoDevice *_this, SDL_Window * window, SDL_GLContext context) +{ + BGLView* glView = (BGLView*)context; + // printf("HAIKU_GL_MakeCurrent(%llx), win = %llx, thread = %d\n", (uint64)context, (uint64)window, find_thread(NULL)); + if (glView) { + if ((glView->Window() == NULL) || (!window) || (_ToBeWin(window)->GetGLView() != glView)) { + return SDL_SetError("MakeCurrent failed"); + } + } + _GetBeLooper()->SetCurrentContext(glView); + return true; +} + + +SDL_GLContext HAIKU_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window * window) +{ + /* FIXME: Not sure what flags should be included here; may want to have + most of them */ + SDL_BWin *bwin = _ToBeWin(window); + // printf("HAIKU_GL_CreateContext, win = %llx, thread = %d\n", (uint64)window, find_thread(NULL)); + if (bwin->GetGLView() != NULL) { + SDL_SetError("Context already creaded"); + return NULL; + } + Uint32 gl_flags = BGL_RGB; + if (_this->gl_config.alpha_size) { + gl_flags |= BGL_ALPHA; + } + if (_this->gl_config.depth_size) { + gl_flags |= BGL_DEPTH; + } + if (_this->gl_config.stencil_size) { + gl_flags |= BGL_STENCIL; + } + if (_this->gl_config.double_buffer) { + gl_flags |= BGL_DOUBLE; + } else { + gl_flags |= BGL_SINGLE; + } + if (_this->gl_config.accum_red_size || + _this->gl_config.accum_green_size || + _this->gl_config.accum_blue_size || + _this->gl_config.accum_alpha_size) { + gl_flags |= BGL_ACCUM; + } +#if __GNUC__ > 3 + if (_this->gl_config.share_with_current_context) { + gl_flags |= BGL_SHARE_CONTEXT; + } +#endif + bwin->CreateGLView(gl_flags); + _GetBeLooper()->SetCurrentContext(bwin->GetGLView()); + return (SDL_GLContext)(bwin->GetGLView()); +} + +bool HAIKU_GL_DestroyContext(SDL_VideoDevice *_this, SDL_GLContext context) +{ + // printf("HAIKU_GL_DestroyContext(%llx), thread = %d\n", (uint64)context, find_thread(NULL)); + BGLView* glView = (BGLView*)context; + SDL_BWin *bwin = (SDL_BWin*)glView->Window(); + if (!bwin) { + delete glView; + } else { + bwin->RemoveGLView(); + } + return true; +} + + +bool HAIKU_GL_SetSwapInterval(SDL_VideoDevice *_this, int interval) +{ + // TODO: Implement this, if necessary? + return SDL_Unsupported(); +} + +bool HAIKU_GL_GetSwapInterval(SDL_VideoDevice *_this, int *interval) +{ + return SDL_Unsupported(); +} + + +void HAIKU_GL_UnloadLibrary(SDL_VideoDevice *_this) +{ + // TODO: Implement this, if necessary? +} + + +/* FIXME: This function is meant to clear the OpenGL context when the video + mode changes (see SDL_bmodes.cc), but it doesn't seem to help, and is not + currently in use. */ +void HAIKU_GL_RebootContexts(SDL_VideoDevice *_this) +{ + SDL_Window *window = _this->windows; + while (window) { + SDL_BWin *bwin = _ToBeWin(window); + if (bwin->GetGLView()) { + bwin->LockLooper(); + bwin->RemoveGLView(); + bwin->CreateGLView(bwin->GetGLType()); + bwin->UnlockLooper(); + } + window = window->next; + } +} + + +#ifdef __cplusplus +} +#endif + +#endif // SDL_VIDEO_DRIVER_HAIKU && SDL_VIDEO_OPENGL diff --git a/contrib/SDL-3.2.8/src/video/haiku/SDL_bopengl.h b/contrib/SDL-3.2.8/src/video/haiku/SDL_bopengl.h new file mode 100644 index 0000000..e0522a8 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/haiku/SDL_bopengl.h @@ -0,0 +1,52 @@ +/* + 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. +*/ + +#ifndef SDL_BOPENGL_H +#define SDL_BOPENGL_H + +#if defined(SDL_VIDEO_DRIVER_HAIKU) && defined(SDL_VIDEO_OPENGL) + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../SDL_sysvideo.h" + +extern bool HAIKU_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path); // FIXME +extern SDL_FunctionPointer HAIKU_GL_GetProcAddress(SDL_VideoDevice *_this, const char *proc); // FIXME +extern void HAIKU_GL_UnloadLibrary(SDL_VideoDevice *_this); // TODO +extern bool HAIKU_GL_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, + SDL_GLContext context); +extern bool HAIKU_GL_SetSwapInterval(SDL_VideoDevice *_this, int interval); // TODO +extern bool HAIKU_GL_GetSwapInterval(SDL_VideoDevice *_this, int *interval); // TODO +extern bool HAIKU_GL_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window); +extern SDL_GLContext HAIKU_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window); +extern bool HAIKU_GL_DestroyContext(SDL_VideoDevice *_this, SDL_GLContext context); + +extern void HAIKU_GL_RebootContexts(SDL_VideoDevice *_this); + +#ifdef __cplusplus +} +#endif + +#endif // SDL_VIDEO_DRIVER_HAIKU && SDL_VIDEO_OPENGL + +#endif 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 diff --git a/contrib/SDL-3.2.8/src/video/haiku/SDL_bvideo.h b/contrib/SDL-3.2.8/src/video/haiku/SDL_bvideo.h new file mode 100644 index 0000000..f107d80 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/haiku/SDL_bvideo.h @@ -0,0 +1,40 @@ +/* + 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. +*/ + +#ifndef BVIDEO_H +#define BVIDEO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../core/haiku/SDL_BeApp.h" +#include "../SDL_sysvideo.h" + +extern void HAIKU_VideoQuit(SDL_VideoDevice *_this); +extern bool HAIKU_VideoInit(SDL_VideoDevice *_this); +extern void HAIKU_DeleteDevice(SDL_VideoDevice *_this); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/contrib/SDL-3.2.8/src/video/haiku/SDL_bwindow.cc b/contrib/SDL-3.2.8/src/video/haiku/SDL_bwindow.cc new file mode 100644 index 0000000..47a28d3 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/haiku/SDL_bwindow.cc @@ -0,0 +1,224 @@ +/* + 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" + +#ifdef SDL_VIDEO_DRIVER_HAIKU +#include "../SDL_sysvideo.h" + +#include "SDL_BWin.h" +#include + +// Define a path to window's BWIN data +#ifdef __cplusplus +extern "C" { +#endif + +static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) +{ + return (SDL_BWin *)(window->internal); +} + +static SDL_INLINE SDL_BLooper *_GetBeLooper() +{ + return SDL_Looper; +} + +static bool _InitWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props) +{ + uint32 flags = 0; + window_look look = B_TITLED_WINDOW_LOOK; + + BRect bounds( + window->x, + window->y, + window->x + window->w - 1, //BeWindows have an off-by-one px w/h thing + window->y + window->h - 1 + ); + + if (window->flags & SDL_WINDOW_FULLSCREEN) { + // TODO: Add support for this flag + printf(__FILE__": %d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",__LINE__); + } + if (window->flags & SDL_WINDOW_OPENGL) { + // TODO: Add support for this flag + } + if (!(window->flags & SDL_WINDOW_RESIZABLE)) { + flags |= B_NOT_RESIZABLE | B_NOT_ZOOMABLE; + } + if (window->flags & SDL_WINDOW_BORDERLESS) { + look = B_NO_BORDER_WINDOW_LOOK; + } + + SDL_BWin *bwin = new(std::nothrow) SDL_BWin(bounds, look, flags); + if (!bwin) { + return false; + } + + window->internal = (SDL_WindowData *)bwin; + int32 winID = _GetBeLooper()->GetID(window); + bwin->SetID(winID); + + return true; +} + +bool HAIKU_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props) +{ + if (!_InitWindow(_this, window, create_props)) { + return false; + } + + // Start window loop + _ToBeWin(window)->Show(); + return true; +} + +void HAIKU_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window * window) +{ + BMessage msg(BWIN_SET_TITLE); + msg.AddString("window-title", window->title); + _ToBeWin(window)->PostMessage(&msg); +} + +bool HAIKU_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window * window) +{ + BMessage msg(BWIN_MOVE_WINDOW); + msg.AddInt32("window-x", window->pending.x); + msg.AddInt32("window-y", window->pending.y); + _ToBeWin(window)->PostMessage(&msg); + return true; +} + +void HAIKU_SetWindowSize(SDL_VideoDevice *_this, SDL_Window * window) +{ + BMessage msg(BWIN_RESIZE_WINDOW); + msg.AddInt32("window-w", window->pending.w - 1); + msg.AddInt32("window-h", window->pending.h - 1); + _ToBeWin(window)->PostMessage(&msg); +} + +void HAIKU_SetWindowBordered(SDL_VideoDevice *_this, SDL_Window * window, bool bordered) +{ + BMessage msg(BWIN_SET_BORDERED); + msg.AddBool("window-border", bordered != false); + _ToBeWin(window)->PostMessage(&msg); +} + +void HAIKU_SetWindowResizable(SDL_VideoDevice *_this, SDL_Window * window, bool resizable) +{ + BMessage msg(BWIN_SET_RESIZABLE); + msg.AddBool("window-resizable", resizable != false); + _ToBeWin(window)->PostMessage(&msg); +} + +void HAIKU_ShowWindow(SDL_VideoDevice *_this, SDL_Window * window) +{ + BMessage msg(BWIN_SHOW_WINDOW); + _ToBeWin(window)->PostMessage(&msg); +} + +void HAIKU_HideWindow(SDL_VideoDevice *_this, SDL_Window * window) +{ + BMessage msg(BWIN_HIDE_WINDOW); + _ToBeWin(window)->PostMessage(&msg); +} + +void HAIKU_RaiseWindow(SDL_VideoDevice *_this, SDL_Window * window) +{ + BMessage msg(BWIN_SHOW_WINDOW); // Activate this window and move to front + _ToBeWin(window)->PostMessage(&msg); +} + +void HAIKU_MaximizeWindow(SDL_VideoDevice *_this, SDL_Window * window) +{ + BMessage msg(BWIN_MAXIMIZE_WINDOW); + _ToBeWin(window)->PostMessage(&msg); +} + +void HAIKU_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window * window) +{ + BMessage msg(BWIN_MINIMIZE_WINDOW); + _ToBeWin(window)->PostMessage(&msg); +} + +void HAIKU_RestoreWindow(SDL_VideoDevice *_this, SDL_Window * window) +{ + BMessage msg(BWIN_RESTORE_WINDOW); + _ToBeWin(window)->PostMessage(&msg); +} + +SDL_FullscreenResult HAIKU_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay * display, SDL_FullscreenOp fullscreen) +{ + // Haiku tracks all video display information + BMessage msg(BWIN_FULLSCREEN); + msg.AddBool("fullscreen", !!fullscreen); + _ToBeWin(window)->PostMessage(&msg); + return SDL_FULLSCREEN_SUCCEEDED; +} + + +void HAIKU_SetWindowMinimumSize(SDL_VideoDevice *_this, SDL_Window * window) +{ + BMessage msg(BWIN_MINIMUM_SIZE_WINDOW); + msg.AddInt32("window-w", window->w -1); + msg.AddInt32("window-h", window->h -1); + _ToBeWin(window)->PostMessage(&msg); +} + +bool HAIKU_SetWindowMouseGrab(SDL_VideoDevice *_this, SDL_Window * window, bool grabbed) +{ + // TODO: Implement this! + return SDL_Unsupported(); +} + +bool HAIKU_SetWindowParent(SDL_VideoDevice *_this, SDL_Window * window, SDL_Window *parent) +{ + return true; +} + +bool HAIKU_SetWindowModal(SDL_VideoDevice *_this, SDL_Window *window, bool modal) +{ + if (modal) { + _ToBeWin(window)->SetLook(B_MODAL_WINDOW_LOOK); + _ToBeWin(window)->SetFeel(B_MODAL_SUBSET_WINDOW_FEEL); + _ToBeWin(window)->AddToSubset(_ToBeWin(window->parent)); + } else { + window_look look = (window->flags & SDL_WINDOW_BORDERLESS) ? B_NO_BORDER_WINDOW_LOOK : B_TITLED_WINDOW_LOOK; + _ToBeWin(window)->RemoveFromSubset(_ToBeWin(window->parent)); + _ToBeWin(window)->SetLook(look); + _ToBeWin(window)->SetFeel(B_NORMAL_WINDOW_FEEL); + } + + return true; +} + +void HAIKU_DestroyWindow(SDL_VideoDevice *_this, SDL_Window * window) +{ + _ToBeWin(window)->LockLooper(); // This MUST be locked + _GetBeLooper()->ClearID(_ToBeWin(window)); + _ToBeWin(window)->Quit(); + window->internal = NULL; +} + +#ifdef __cplusplus +} +#endif + +#endif // SDL_VIDEO_DRIVER_HAIKU diff --git a/contrib/SDL-3.2.8/src/video/haiku/SDL_bwindow.h b/contrib/SDL-3.2.8/src/video/haiku/SDL_bwindow.h new file mode 100644 index 0000000..0f0da85 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/haiku/SDL_bwindow.h @@ -0,0 +1,46 @@ +/* + 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. +*/ + +#ifndef SDL_BWINDOW_H +#define SDL_BWINDOW_H + +#include "../SDL_sysvideo.h" + +extern bool HAIKU_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props); +extern void HAIKU_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window); +extern bool HAIKU_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window); +extern void HAIKU_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window); +extern void HAIKU_SetWindowMinimumSize(SDL_VideoDevice *_this, SDL_Window *window); +extern void HAIKU_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window); +extern void HAIKU_HideWindow(SDL_VideoDevice *_this, SDL_Window *window); +extern void HAIKU_RaiseWindow(SDL_VideoDevice *_this, SDL_Window *window); +extern void HAIKU_MaximizeWindow(SDL_VideoDevice *_this, SDL_Window *window); +extern void HAIKU_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window); +extern void HAIKU_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window); +extern void HAIKU_SetWindowBordered(SDL_VideoDevice *_this, SDL_Window *window, bool bordered); +extern void HAIKU_SetWindowResizable(SDL_VideoDevice *_this, SDL_Window *window, bool resizable); +extern SDL_FullscreenResult HAIKU_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_FullscreenOp fullscreen); +extern bool HAIKU_SetWindowMouseGrab(SDL_VideoDevice *_this, SDL_Window *window, bool grabbed); +extern bool HAIKU_SetWindowParent(SDL_VideoDevice *_this, SDL_Window *window, SDL_Window *parent); +extern bool HAIKU_SetWindowModal(SDL_VideoDevice *_this, SDL_Window *window, bool modal); +extern void HAIKU_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window); + +#endif -- cgit v1.2.3