diff options
Diffstat (limited to 'contrib/SDL-3.2.8/src/video/haiku/SDL_bvideo.cc')
| -rw-r--r-- | contrib/SDL-3.2.8/src/video/haiku/SDL_bvideo.cc | 326 |
1 files changed, 326 insertions, 0 deletions
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 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include "SDL_internal.h" | ||
| 23 | #include "../../core/haiku/SDL_BApp.h" | ||
| 24 | |||
| 25 | #ifdef SDL_VIDEO_DRIVER_HAIKU | ||
| 26 | |||
| 27 | #include "SDL_BWin.h" | ||
| 28 | #include <Url.h> | ||
| 29 | |||
| 30 | #ifdef __cplusplus | ||
| 31 | extern "C" { | ||
| 32 | #endif | ||
| 33 | |||
| 34 | #include "SDL_bkeyboard.h" | ||
| 35 | #include "SDL_bwindow.h" | ||
| 36 | #include "SDL_bclipboard.h" | ||
| 37 | #include "SDL_bvideo.h" | ||
| 38 | #include "SDL_bopengl.h" | ||
| 39 | #include "SDL_bmodes.h" | ||
| 40 | #include "SDL_bframebuffer.h" | ||
| 41 | #include "SDL_bevents.h" | ||
| 42 | #include "SDL_bmessagebox.h" | ||
| 43 | #include "../../events/SDL_keyboard_c.h" | ||
| 44 | #include "../../events/SDL_mouse_c.h" | ||
| 45 | |||
| 46 | static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) { | ||
| 47 | return (SDL_BWin *)(window->internal); | ||
| 48 | } | ||
| 49 | |||
| 50 | static SDL_VideoDevice * HAIKU_CreateDevice(void) | ||
| 51 | { | ||
| 52 | SDL_VideoDevice *device; | ||
| 53 | |||
| 54 | // Initialize all variables that we clean on shutdown | ||
| 55 | device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); | ||
| 56 | |||
| 57 | device->internal = NULL; /* FIXME: Is this the cause of some of the | ||
| 58 | SDL_Quit() errors? */ | ||
| 59 | |||
| 60 | // TODO: Figure out if any initialization needs to go here | ||
| 61 | |||
| 62 | // Set the function pointers | ||
| 63 | device->VideoInit = HAIKU_VideoInit; | ||
| 64 | device->VideoQuit = HAIKU_VideoQuit; | ||
| 65 | device->GetDisplayBounds = HAIKU_GetDisplayBounds; | ||
| 66 | device->GetDisplayModes = HAIKU_GetDisplayModes; | ||
| 67 | device->SetDisplayMode = HAIKU_SetDisplayMode; | ||
| 68 | device->PumpEvents = HAIKU_PumpEvents; | ||
| 69 | |||
| 70 | device->CreateSDLWindow = HAIKU_CreateWindow; | ||
| 71 | device->SetWindowTitle = HAIKU_SetWindowTitle; | ||
| 72 | device->SetWindowPosition = HAIKU_SetWindowPosition; | ||
| 73 | device->SetWindowSize = HAIKU_SetWindowSize; | ||
| 74 | device->ShowWindow = HAIKU_ShowWindow; | ||
| 75 | device->HideWindow = HAIKU_HideWindow; | ||
| 76 | device->RaiseWindow = HAIKU_RaiseWindow; | ||
| 77 | device->MaximizeWindow = HAIKU_MaximizeWindow; | ||
| 78 | device->MinimizeWindow = HAIKU_MinimizeWindow; | ||
| 79 | device->RestoreWindow = HAIKU_RestoreWindow; | ||
| 80 | device->SetWindowBordered = HAIKU_SetWindowBordered; | ||
| 81 | device->SetWindowResizable = HAIKU_SetWindowResizable; | ||
| 82 | device->SetWindowFullscreen = HAIKU_SetWindowFullscreen; | ||
| 83 | device->SetWindowMouseGrab = HAIKU_SetWindowMouseGrab; | ||
| 84 | device->SetWindowMinimumSize = HAIKU_SetWindowMinimumSize; | ||
| 85 | device->SetWindowParent = HAIKU_SetWindowParent; | ||
| 86 | device->SetWindowModal = HAIKU_SetWindowModal; | ||
| 87 | device->DestroyWindow = HAIKU_DestroyWindow; | ||
| 88 | device->CreateWindowFramebuffer = HAIKU_CreateWindowFramebuffer; | ||
| 89 | device->UpdateWindowFramebuffer = HAIKU_UpdateWindowFramebuffer; | ||
| 90 | device->DestroyWindowFramebuffer = HAIKU_DestroyWindowFramebuffer; | ||
| 91 | |||
| 92 | #ifdef SDL_VIDEO_OPENGL | ||
| 93 | device->GL_LoadLibrary = HAIKU_GL_LoadLibrary; | ||
| 94 | device->GL_GetProcAddress = HAIKU_GL_GetProcAddress; | ||
| 95 | device->GL_UnloadLibrary = HAIKU_GL_UnloadLibrary; | ||
| 96 | device->GL_CreateContext = HAIKU_GL_CreateContext; | ||
| 97 | device->GL_MakeCurrent = HAIKU_GL_MakeCurrent; | ||
| 98 | device->GL_SetSwapInterval = HAIKU_GL_SetSwapInterval; | ||
| 99 | device->GL_GetSwapInterval = HAIKU_GL_GetSwapInterval; | ||
| 100 | device->GL_SwapWindow = HAIKU_GL_SwapWindow; | ||
| 101 | device->GL_DestroyContext = HAIKU_GL_DestroyContext; | ||
| 102 | #endif | ||
| 103 | |||
| 104 | device->SetClipboardText = HAIKU_SetClipboardText; | ||
| 105 | device->GetClipboardText = HAIKU_GetClipboardText; | ||
| 106 | device->HasClipboardText = HAIKU_HasClipboardText; | ||
| 107 | |||
| 108 | device->free = HAIKU_DeleteDevice; | ||
| 109 | |||
| 110 | return device; | ||
| 111 | } | ||
| 112 | |||
| 113 | VideoBootStrap HAIKU_bootstrap = { | ||
| 114 | "haiku", "Haiku graphics", | ||
| 115 | HAIKU_CreateDevice, | ||
| 116 | HAIKU_ShowMessageBox, | ||
| 117 | false | ||
| 118 | }; | ||
| 119 | |||
| 120 | void HAIKU_DeleteDevice(SDL_VideoDevice * device) | ||
| 121 | { | ||
| 122 | SDL_free(device->internal); | ||
| 123 | SDL_free(device); | ||
| 124 | } | ||
| 125 | |||
| 126 | struct SDL_CursorData | ||
| 127 | { | ||
| 128 | BCursor *cursor; | ||
| 129 | }; | ||
| 130 | |||
| 131 | static SDL_Cursor *HAIKU_CreateCursorAndData(BCursor *bcursor) | ||
| 132 | { | ||
| 133 | SDL_Cursor *cursor = (SDL_Cursor *)SDL_calloc(1, sizeof(*cursor)); | ||
| 134 | if (cursor) { | ||
| 135 | SDL_CursorData *data = (SDL_CursorData *)SDL_calloc(1, sizeof(*data)); | ||
| 136 | if (!data) { | ||
| 137 | SDL_free(cursor); | ||
| 138 | return NULL; | ||
| 139 | } | ||
| 140 | data->cursor = bcursor; | ||
| 141 | cursor->internal = data; | ||
| 142 | } | ||
| 143 | return cursor; | ||
| 144 | } | ||
| 145 | |||
| 146 | static SDL_Cursor * HAIKU_CreateSystemCursor(SDL_SystemCursor id) | ||
| 147 | { | ||
| 148 | BCursorID cursorId = B_CURSOR_ID_SYSTEM_DEFAULT; | ||
| 149 | |||
| 150 | switch(id) | ||
| 151 | { | ||
| 152 | #define CURSORCASE(sdlname, bname) case SDL_SYSTEM_CURSOR_##sdlname: cursorId = B_CURSOR_ID_##bname; break | ||
| 153 | CURSORCASE(DEFAULT, SYSTEM_DEFAULT); | ||
| 154 | CURSORCASE(TEXT, I_BEAM); | ||
| 155 | CURSORCASE(WAIT, PROGRESS); | ||
| 156 | CURSORCASE(CROSSHAIR, CROSS_HAIR); | ||
| 157 | CURSORCASE(PROGRESS, PROGRESS); | ||
| 158 | CURSORCASE(NWSE_RESIZE, RESIZE_NORTH_WEST_SOUTH_EAST); | ||
| 159 | CURSORCASE(NESW_RESIZE, RESIZE_NORTH_EAST_SOUTH_WEST); | ||
| 160 | CURSORCASE(EW_RESIZE, RESIZE_EAST_WEST); | ||
| 161 | CURSORCASE(NS_RESIZE, RESIZE_NORTH_SOUTH); | ||
| 162 | CURSORCASE(MOVE, MOVE); | ||
| 163 | CURSORCASE(NOT_ALLOWED, NOT_ALLOWED); | ||
| 164 | CURSORCASE(POINTER, FOLLOW_LINK); | ||
| 165 | CURSORCASE(NW_RESIZE, RESIZE_NORTH_WEST_SOUTH_EAST); | ||
| 166 | CURSORCASE(N_RESIZE, RESIZE_NORTH_SOUTH); | ||
| 167 | CURSORCASE(NE_RESIZE, RESIZE_NORTH_EAST_SOUTH_WEST); | ||
| 168 | CURSORCASE(E_RESIZE, RESIZE_EAST_WEST); | ||
| 169 | CURSORCASE(SE_RESIZE, RESIZE_NORTH_WEST_SOUTH_EAST); | ||
| 170 | CURSORCASE(S_RESIZE, RESIZE_NORTH_SOUTH); | ||
| 171 | CURSORCASE(SW_RESIZE, RESIZE_NORTH_EAST_SOUTH_WEST); | ||
| 172 | CURSORCASE(W_RESIZE, RESIZE_EAST_WEST); | ||
| 173 | #undef CURSORCASE | ||
| 174 | default: | ||
| 175 | SDL_assert(0); | ||
| 176 | return NULL; | ||
| 177 | } | ||
| 178 | |||
| 179 | return HAIKU_CreateCursorAndData(new BCursor(cursorId)); | ||
| 180 | } | ||
| 181 | |||
| 182 | static SDL_Cursor * HAIKU_CreateDefaultCursor() | ||
| 183 | { | ||
| 184 | SDL_SystemCursor id = SDL_GetDefaultSystemCursor(); | ||
| 185 | return HAIKU_CreateSystemCursor(id); | ||
| 186 | } | ||
| 187 | |||
| 188 | static void HAIKU_FreeCursor(SDL_Cursor * cursor) | ||
| 189 | { | ||
| 190 | SDL_CursorData *data = cursor->internal; | ||
| 191 | |||
| 192 | if (data) { | ||
| 193 | delete data->cursor; | ||
| 194 | } | ||
| 195 | SDL_free(data); | ||
| 196 | SDL_free(cursor); | ||
| 197 | } | ||
| 198 | |||
| 199 | static SDL_Cursor * HAIKU_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) | ||
| 200 | { | ||
| 201 | SDL_Surface *converted; | ||
| 202 | |||
| 203 | converted = SDL_ConvertSurface(surface, SDL_PIXELFORMAT_ARGB8888); | ||
| 204 | if (!converted) { | ||
| 205 | return NULL; | ||
| 206 | } | ||
| 207 | |||
| 208 | BBitmap *cursorBitmap = new BBitmap(BRect(0, 0, surface->w - 1, surface->h - 1), B_RGBA32); | ||
| 209 | cursorBitmap->SetBits(converted->pixels, converted->h * converted->pitch, 0, B_RGBA32); | ||
| 210 | SDL_DestroySurface(converted); | ||
| 211 | |||
| 212 | return HAIKU_CreateCursorAndData(new BCursor(cursorBitmap, BPoint(hot_x, hot_y))); | ||
| 213 | } | ||
| 214 | |||
| 215 | static bool HAIKU_ShowCursor(SDL_Cursor *cursor) | ||
| 216 | { | ||
| 217 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 218 | |||
| 219 | if (!mouse) { | ||
| 220 | return true; | ||
| 221 | } | ||
| 222 | |||
| 223 | if (cursor) { | ||
| 224 | BCursor *hCursor = cursor->internal->cursor; | ||
| 225 | be_app->SetCursor(hCursor); | ||
| 226 | } else { | ||
| 227 | BCursor *hCursor = new BCursor(B_CURSOR_ID_NO_CURSOR); | ||
| 228 | be_app->SetCursor(hCursor); | ||
| 229 | delete hCursor; | ||
| 230 | } | ||
| 231 | |||
| 232 | return true; | ||
| 233 | } | ||
| 234 | |||
| 235 | static bool HAIKU_SetRelativeMouseMode(bool enabled) | ||
| 236 | { | ||
| 237 | SDL_Window *window = SDL_GetMouseFocus(); | ||
| 238 | if (!window) { | ||
| 239 | return true; | ||
| 240 | } | ||
| 241 | |||
| 242 | SDL_BWin *bewin = _ToBeWin(window); | ||
| 243 | BGLView *_SDL_GLView = bewin->GetGLView(); | ||
| 244 | if (!_SDL_GLView) { | ||
| 245 | return false; | ||
| 246 | } | ||
| 247 | |||
| 248 | bewin->Lock(); | ||
| 249 | if (enabled) | ||
| 250 | _SDL_GLView->SetEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY); | ||
| 251 | else | ||
| 252 | _SDL_GLView->SetEventMask(0, 0); | ||
| 253 | bewin->Unlock(); | ||
| 254 | |||
| 255 | return true; | ||
| 256 | } | ||
| 257 | |||
| 258 | static void HAIKU_MouseInit(SDL_VideoDevice *_this) | ||
| 259 | { | ||
| 260 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 261 | if (!mouse) { | ||
| 262 | return; | ||
| 263 | } | ||
| 264 | mouse->CreateCursor = HAIKU_CreateCursor; | ||
| 265 | mouse->CreateSystemCursor = HAIKU_CreateSystemCursor; | ||
| 266 | mouse->ShowCursor = HAIKU_ShowCursor; | ||
| 267 | mouse->FreeCursor = HAIKU_FreeCursor; | ||
| 268 | mouse->SetRelativeMouseMode = HAIKU_SetRelativeMouseMode; | ||
| 269 | |||
| 270 | SDL_SetDefaultCursor(HAIKU_CreateDefaultCursor()); | ||
| 271 | } | ||
| 272 | |||
| 273 | bool HAIKU_VideoInit(SDL_VideoDevice *_this) | ||
| 274 | { | ||
| 275 | // Initialize the Be Application for appserver interaction | ||
| 276 | if (!SDL_InitBeApp()) { | ||
| 277 | return false; | ||
| 278 | } | ||
| 279 | |||
| 280 | // Initialize video modes | ||
| 281 | HAIKU_InitModes(_this); | ||
| 282 | |||
| 283 | // Init the keymap | ||
| 284 | HAIKU_InitOSKeymap(); | ||
| 285 | |||
| 286 | HAIKU_MouseInit(_this); | ||
| 287 | |||
| 288 | // Assume we have a mouse and keyboard | ||
| 289 | SDL_AddKeyboard(SDL_DEFAULT_KEYBOARD_ID, NULL, false); | ||
| 290 | SDL_AddMouse(SDL_DEFAULT_MOUSE_ID, NULL, false); | ||
| 291 | |||
| 292 | #ifdef SDL_VIDEO_OPENGL | ||
| 293 | // testgl application doesn't load library, just tries to load symbols | ||
| 294 | // is it correct? if so we have to load library here | ||
| 295 | HAIKU_GL_LoadLibrary(_this, NULL); | ||
| 296 | #endif | ||
| 297 | |||
| 298 | // We're done! | ||
| 299 | return true; | ||
| 300 | } | ||
| 301 | |||
| 302 | void HAIKU_VideoQuit(SDL_VideoDevice *_this) | ||
| 303 | { | ||
| 304 | |||
| 305 | HAIKU_QuitModes(_this); | ||
| 306 | |||
| 307 | SDL_QuitBeApp(); | ||
| 308 | } | ||
| 309 | |||
| 310 | // just sticking this function in here so it's in a C++ source file. | ||
| 311 | extern "C" | ||
| 312 | bool HAIKU_OpenURL(const char *url) | ||
| 313 | { | ||
| 314 | BUrl burl(url); | ||
| 315 | const status_t rc = burl.OpenWithPreferredApplication(false); | ||
| 316 | if (rc != B_NO_ERROR) { | ||
| 317 | return SDL_SetError("URL open failed (err=%d)", (int)rc); | ||
| 318 | } | ||
| 319 | return true; | ||
| 320 | } | ||
| 321 | |||
| 322 | #ifdef __cplusplus | ||
| 323 | } | ||
| 324 | #endif | ||
| 325 | |||
| 326 | #endif // SDL_VIDEO_DRIVER_HAIKU | ||
