summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/video/haiku
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/SDL-3.2.8/src/video/haiku')
-rw-r--r--contrib/SDL-3.2.8/src/video/haiku/SDL_BWin.h755
-rw-r--r--contrib/SDL-3.2.8/src/video/haiku/SDL_bclipboard.cc93
-rw-r--r--contrib/SDL-3.2.8/src/video/haiku/SDL_bclipboard.h31
-rw-r--r--contrib/SDL-3.2.8/src/video/haiku/SDL_bevents.cc39
-rw-r--r--contrib/SDL-3.2.8/src/video/haiku/SDL_bevents.h37
-rw-r--r--contrib/SDL-3.2.8/src/video/haiku/SDL_bframebuffer.cc128
-rw-r--r--contrib/SDL-3.2.8/src/video/haiku/SDL_bframebuffer.h45
-rw-r--r--contrib/SDL-3.2.8/src/video/haiku/SDL_bkeyboard.cc168
-rw-r--r--contrib/SDL-3.2.8/src/video/haiku/SDL_bkeyboard.h38
-rw-r--r--contrib/SDL-3.2.8/src/video/haiku/SDL_bmessagebox.cc383
-rw-r--r--contrib/SDL-3.2.8/src/video/haiku/SDL_bmessagebox.h42
-rw-r--r--contrib/SDL-3.2.8/src/video/haiku/SDL_bmodes.cc307
-rw-r--r--contrib/SDL-3.2.8/src/video/haiku/SDL_bmodes.h43
-rw-r--r--contrib/SDL-3.2.8/src/video/haiku/SDL_bopengl.cc205
-rw-r--r--contrib/SDL-3.2.8/src/video/haiku/SDL_bopengl.h52
-rw-r--r--contrib/SDL-3.2.8/src/video/haiku/SDL_bvideo.cc326
-rw-r--r--contrib/SDL-3.2.8/src/video/haiku/SDL_bvideo.h40
-rw-r--r--contrib/SDL-3.2.8/src/video/haiku/SDL_bwindow.cc224
-rw-r--r--contrib/SDL-3.2.8/src/video/haiku/SDL_bwindow.h46
19 files changed, 3002 insertions, 0 deletions
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 @@
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#ifndef SDL_BWin_h_
23#define SDL_BWin_h_
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29#include "SDL_internal.h"
30#include "SDL_bframebuffer.h"
31
32#ifdef __cplusplus
33}
34#endif
35
36#include <stdio.h>
37#include <AppKit.h>
38#include <Cursor.h>
39#include <InterfaceKit.h>
40#ifdef SDL_VIDEO_OPENGL
41#include <opengl/GLView.h>
42#endif
43#include "../../core/haiku/SDL_BApp.h"
44
45enum WinCommands
46{
47 BWIN_MOVE_WINDOW,
48 BWIN_RESIZE_WINDOW,
49 BWIN_SHOW_WINDOW,
50 BWIN_HIDE_WINDOW,
51 BWIN_MAXIMIZE_WINDOW,
52 BWIN_MINIMIZE_WINDOW,
53 BWIN_RESTORE_WINDOW,
54 BWIN_SET_TITLE,
55 BWIN_SET_BORDERED,
56 BWIN_SET_RESIZABLE,
57 BWIN_FULLSCREEN,
58 BWIN_UPDATE_FRAMEBUFFER,
59 BWIN_MINIMUM_SIZE_WINDOW
60};
61
62// non-OpenGL framebuffer view
63class SDL_BView : public BView
64{
65 public:
66 SDL_BView(BRect frame, const char *name, uint32 resizingMode)
67 : BView(frame, name, resizingMode, B_WILL_DRAW),
68 fBitmap(NULL)
69 {
70 }
71
72 void Draw(BRect dirty)
73 {
74 if (fBitmap != NULL)
75 DrawBitmap(fBitmap, B_ORIGIN);
76 }
77
78 void SetBitmap(BBitmap *bitmap)
79 {
80 fBitmap = bitmap;
81 }
82
83 private:
84 BBitmap *fBitmap;
85};
86
87class SDL_BWin : public BWindow
88{
89 public:
90 // Constructor/Destructor
91 SDL_BWin(BRect bounds, window_look look, uint32 flags)
92 : BWindow(bounds, "Untitled", look, B_NORMAL_WINDOW_FEEL, flags)
93 {
94 _last_buttons = 0;
95
96 _cur_view = NULL;
97 _SDL_View = NULL;
98
99#ifdef SDL_VIDEO_OPENGL
100 _SDL_GLView = NULL;
101 _gl_type = 0;
102#endif
103 _shown = false;
104 _inhibit_resize = false;
105 _mouse_focused = false;
106 _prev_frame = NULL;
107 _fullscreen = NULL;
108
109 // Handle framebuffer stuff
110 _buffer_locker = new BLocker();
111 _bitmap = NULL;
112 }
113
114 virtual ~SDL_BWin()
115 {
116 Lock();
117
118 if (_SDL_View != NULL && _SDL_View != _cur_view) {
119 delete _SDL_View;
120 _SDL_View = NULL;
121 }
122
123#ifdef SDL_VIDEO_OPENGL
124 if (_SDL_GLView) {
125 if (SDL_Looper->GetCurrentContext() == _SDL_GLView)
126 SDL_Looper->SetCurrentContext(NULL);
127 if (_SDL_GLView == _cur_view)
128 RemoveChild(_SDL_GLView);
129 _SDL_GLView = NULL;
130 // _SDL_GLView deleted by HAIKU_GL_DestroyContext
131 }
132
133#endif
134 Unlock();
135
136 delete _prev_frame;
137
138 // Clean up framebuffer stuff
139 _buffer_locker->Lock();
140 delete _buffer_locker;
141 }
142
143 void SetCurrentView(BView *view)
144 {
145 if (_cur_view != view) {
146 if (_cur_view != NULL)
147 RemoveChild(_cur_view);
148 _cur_view = view;
149 if (_cur_view != NULL)
150 AddChild(_cur_view);
151 }
152 }
153
154 void UpdateCurrentView()
155 {
156#ifdef SDL_VIDEO_OPENGL
157 if (_SDL_GLView != NULL) {
158 SetCurrentView(_SDL_GLView);
159 } else
160#endif
161 if (_SDL_View != NULL) {
162 SetCurrentView(_SDL_View);
163 } else {
164 SetCurrentView(NULL);
165 }
166 }
167
168 SDL_BView *CreateView()
169 {
170 Lock();
171 if (_SDL_View == NULL) {
172 _SDL_View = new SDL_BView(Bounds(), "SDL View", B_FOLLOW_ALL_SIDES);
173 UpdateCurrentView();
174 }
175 Unlock();
176 return _SDL_View;
177 }
178
179 void RemoveView()
180 {
181 Lock();
182 if (_SDL_View != NULL) {
183 SDL_BView *oldView = _SDL_View;
184 _SDL_View = NULL;
185 UpdateCurrentView();
186 delete oldView;
187 }
188 Unlock();
189 }
190
191 /* * * * * OpenGL functionality * * * * */
192#ifdef SDL_VIDEO_OPENGL
193 BGLView *CreateGLView(Uint32 gl_flags)
194 {
195 Lock();
196 if (_SDL_GLView == NULL) {
197 _SDL_GLView = new BGLView(Bounds(), "SDL GLView",
198 B_FOLLOW_ALL_SIDES,
199 (B_WILL_DRAW | B_FRAME_EVENTS),
200 gl_flags);
201 _gl_type = gl_flags;
202 UpdateCurrentView();
203 }
204 Unlock();
205 return _SDL_GLView;
206 }
207
208 void RemoveGLView()
209 {
210 Lock();
211 if (_SDL_GLView != NULL) {
212 if (SDL_Looper->GetCurrentContext() == _SDL_GLView)
213 SDL_Looper->SetCurrentContext(NULL);
214 _SDL_GLView = NULL;
215 UpdateCurrentView();
216 // _SDL_GLView deleted by HAIKU_GL_DestroyContext
217 }
218 Unlock();
219 }
220
221 void SwapBuffers(void)
222 {
223 _SDL_GLView->SwapBuffers();
224 }
225#endif
226
227 /* * * * * Event sending * * * * */
228 // Hook functions
229 virtual void FrameMoved(BPoint origin)
230 {
231 // Post a message to the BApp so that it can handle the window event
232 BMessage msg(BAPP_WINDOW_MOVED);
233 msg.AddInt32("window-x", (int)origin.x);
234 msg.AddInt32("window-y", (int)origin.y);
235 _PostWindowEvent(msg);
236
237 // Perform normal hook operations
238 BWindow::FrameMoved(origin);
239 }
240
241 void FrameResized(float width, float height)
242 {
243 // Post a message to the BApp so that it can handle the window event
244 BMessage msg(BAPP_WINDOW_RESIZED);
245
246 msg.AddInt32("window-w", (int)width + 1);
247 msg.AddInt32("window-h", (int)height + 1);
248 _PostWindowEvent(msg);
249
250 // Perform normal hook operations
251 BWindow::FrameResized(width, height);
252 }
253
254 bool QuitRequested()
255 {
256 BMessage msg(BAPP_WINDOW_CLOSE_REQUESTED);
257 _PostWindowEvent(msg);
258
259 // We won't allow a quit unless asked by DestroyWindow()
260 return false;
261 }
262
263 void WindowActivated(bool active)
264 {
265 BMessage msg(BAPP_KEYBOARD_FOCUS); // Mouse focus sold separately
266 msg.AddBool("focusGained", active);
267 _PostWindowEvent(msg);
268 }
269
270 void Zoom(BPoint origin,
271 float width,
272 float height)
273 {
274 BMessage msg(BAPP_MAXIMIZE); // Closest thing to maximization Haiku has
275 _PostWindowEvent(msg);
276
277 // Before the window zooms, record its size
278 if (!_prev_frame)
279 _prev_frame = new BRect(Frame());
280
281 // Perform normal hook operations
282 BWindow::Zoom(origin, width, height);
283 }
284
285 // Member functions
286 void Show()
287 {
288 while (IsHidden()) {
289 BWindow::Show();
290 }
291 _shown = true;
292
293 BMessage msg(BAPP_SHOW);
294 _PostWindowEvent(msg);
295 }
296
297 void Hide()
298 {
299 BWindow::Hide();
300 _shown = false;
301
302 BMessage msg(BAPP_HIDE);
303 _PostWindowEvent(msg);
304 }
305
306 void Minimize(bool minimize)
307 {
308 BWindow::Minimize(minimize);
309 int32 minState = (minimize ? BAPP_MINIMIZE : BAPP_RESTORE);
310
311 BMessage msg(minState);
312 _PostWindowEvent(msg);
313 }
314
315 void ScreenChanged(BRect screenFrame, color_space depth)
316 {
317 if (_fullscreen) {
318 MoveTo(screenFrame.left, screenFrame.top);
319 ResizeTo(screenFrame.Width(), screenFrame.Height());
320 }
321 }
322
323 // BView message interruption
324 void DispatchMessage(BMessage *msg, BHandler *target)
325 {
326 BPoint where; // Used by mouse moved
327 int32 buttons; // Used for mouse button events
328 int32 key; // Used for key events
329
330 switch (msg->what) {
331 case B_MOUSE_MOVED:
332 int32 transit;
333 if (msg->FindPoint("where", &where) == B_OK && msg->FindInt32("be:transit", &transit) == B_OK) {
334 _MouseMotionEvent(where, transit);
335 }
336 break;
337
338 case B_MOUSE_DOWN:
339 if (msg->FindInt32("buttons", &buttons) == B_OK) {
340 _MouseButtonEvent(buttons, true);
341 }
342 break;
343
344 case B_MOUSE_UP:
345 if (msg->FindInt32("buttons", &buttons) == B_OK) {
346 _MouseButtonEvent(buttons, false);
347 }
348 break;
349
350 case B_MOUSE_WHEEL_CHANGED:
351 float x, y;
352 if (msg->FindFloat("be:wheel_delta_x", &x) == B_OK && msg->FindFloat("be:wheel_delta_y", &y) == B_OK) {
353 _MouseWheelEvent((int)x, (int)y);
354 }
355 break;
356
357 case B_KEY_DOWN:
358 {
359 int32 i = 0;
360 int8 byte;
361 int8 bytes[4] = { 0, 0, 0, 0 };
362 while (i < 4 && msg->FindInt8("byte", i, &byte) == B_OK) {
363 bytes[i] = byte;
364 i++;
365 }
366 if (msg->FindInt32("key", &key) == B_OK) {
367 _KeyEvent((SDL_Scancode)key, &bytes[0], i, true);
368 }
369 } break;
370
371 case B_UNMAPPED_KEY_DOWN: // modifier keys are unmapped
372 if (msg->FindInt32("key", &key) == B_OK) {
373 _KeyEvent((SDL_Scancode)key, NULL, 0, true);
374 }
375 break;
376
377 case B_KEY_UP:
378 case B_UNMAPPED_KEY_UP: // modifier keys are unmapped
379 if (msg->FindInt32("key", &key) == B_OK) {
380 _KeyEvent(key, NULL, 0, false);
381 }
382 break;
383
384 default:
385 /* move it after switch{} so it's always handled
386 that way we keep Haiku features like:
387 - CTRL+Q to close window (and other shortcuts)
388 - PrintScreen to make screenshot into /boot/home
389 - etc.. */
390 // BWindow::DispatchMessage(msg, target);
391 break;
392 }
393
394 BWindow::DispatchMessage(msg, target);
395 }
396
397 // Handle command messages
398 void MessageReceived(BMessage *message)
399 {
400 switch (message->what) {
401 // Handle commands from SDL
402 case BWIN_SET_TITLE:
403 _SetTitle(message);
404 break;
405 case BWIN_MOVE_WINDOW:
406 _MoveTo(message);
407 break;
408 case BWIN_RESIZE_WINDOW:
409 _ResizeTo(message);
410 break;
411 case BWIN_SET_BORDERED:
412 {
413 bool bEnabled;
414 if (message->FindBool("window-border", &bEnabled) == B_OK)
415 _SetBordered(bEnabled);
416 break;
417 }
418 case BWIN_SET_RESIZABLE:
419 {
420 bool bEnabled;
421 if (message->FindBool("window-resizable", &bEnabled) == B_OK)
422 _SetResizable(bEnabled);
423 break;
424 }
425 case BWIN_SHOW_WINDOW:
426 Show();
427 break;
428 case BWIN_HIDE_WINDOW:
429 Hide();
430 break;
431 case BWIN_MAXIMIZE_WINDOW:
432 BWindow::Zoom();
433 break;
434 case BWIN_MINIMIZE_WINDOW:
435 Minimize(true);
436 break;
437 case BWIN_RESTORE_WINDOW:
438 _Restore();
439 break;
440 case BWIN_FULLSCREEN:
441 {
442 bool fullscreen;
443 if (message->FindBool("fullscreen", &fullscreen) == B_OK)
444 _SetFullScreen(fullscreen);
445 break;
446 }
447 case BWIN_MINIMUM_SIZE_WINDOW:
448 _SetMinimumSize(message);
449 break;
450 case BWIN_UPDATE_FRAMEBUFFER:
451 {
452 BMessage *pendingMessage;
453 while ((pendingMessage = MessageQueue()->FindMessage(BWIN_UPDATE_FRAMEBUFFER, 0))) {
454 MessageQueue()->RemoveMessage(pendingMessage);
455 delete pendingMessage;
456 }
457 if (_bitmap != NULL) {
458#ifdef SDL_VIDEO_OPENGL
459 if (_SDL_GLView != NULL && _cur_view == _SDL_GLView) {
460 _SDL_GLView->CopyPixelsIn(_bitmap, B_ORIGIN);
461 } else
462#endif
463 if (_SDL_View != NULL && _cur_view == _SDL_View) {
464 _SDL_View->Draw(Bounds());
465 }
466 }
467 break;
468 }
469 default:
470 // Perform normal message handling
471 BWindow::MessageReceived(message);
472 break;
473 }
474 }
475
476 // Accessor methods
477 bool IsShown() { return _shown; }
478 int32 GetID() { return _id; }
479 BBitmap *GetBitmap() { return _bitmap; }
480 BView *GetCurView() { return _cur_view; }
481 SDL_BView *GetView() { return _SDL_View; }
482#ifdef SDL_VIDEO_OPENGL
483 BGLView *GetGLView()
484 {
485 return _SDL_GLView;
486 }
487 Uint32 GetGLType() { return _gl_type; }
488#endif
489
490 // Setter methods
491 void SetID(int32 id) { _id = id; }
492 void LockBuffer() { _buffer_locker->Lock(); }
493 void UnlockBuffer() { _buffer_locker->Unlock(); }
494 void SetBitmap(BBitmap *bitmap)
495 {
496 _bitmap = bitmap;
497 if (_SDL_View != NULL)
498 _SDL_View->SetBitmap(bitmap);
499 }
500
501 private:
502 // Event redirection
503 void _MouseMotionEvent(BPoint &where, int32 transit)
504 {
505 if (transit == B_EXITED_VIEW) {
506 // Change mouse focus
507 if (_mouse_focused) {
508 _MouseFocusEvent(false);
509 }
510 } else {
511 // Change mouse focus
512 if (!_mouse_focused) {
513 _MouseFocusEvent(true);
514 }
515 BMessage msg(BAPP_MOUSE_MOVED);
516 msg.AddInt32("x", (int)where.x);
517 msg.AddInt32("y", (int)where.y);
518
519 _PostWindowEvent(msg);
520 }
521 }
522
523 void _MouseFocusEvent(bool focusGained)
524 {
525 _mouse_focused = focusGained;
526 BMessage msg(BAPP_MOUSE_FOCUS);
527 msg.AddBool("focusGained", focusGained);
528 _PostWindowEvent(msg);
529
530 /* FIXME: Why were these here?
531 if false: be_app->SetCursor(B_HAND_CURSOR);
532 if true: SDL_SetCursor(NULL); */
533 }
534
535 void _MouseButtonEvent(int32 buttons, bool down)
536 {
537 int32 buttonStateChange = buttons ^ _last_buttons;
538
539 if (buttonStateChange & B_PRIMARY_MOUSE_BUTTON) {
540 _SendMouseButton(SDL_BUTTON_LEFT, down);
541 }
542 if (buttonStateChange & B_SECONDARY_MOUSE_BUTTON) {
543 _SendMouseButton(SDL_BUTTON_RIGHT, down);
544 }
545 if (buttonStateChange & B_TERTIARY_MOUSE_BUTTON) {
546 _SendMouseButton(SDL_BUTTON_MIDDLE, down);
547 }
548
549 _last_buttons = buttons;
550 }
551
552 void _SendMouseButton(int32 button, bool down)
553 {
554 BMessage msg(BAPP_MOUSE_BUTTON);
555 msg.AddInt32("button-id", button);
556 msg.AddBool("button-down", down);
557 _PostWindowEvent(msg);
558 }
559
560 void _MouseWheelEvent(int32 x, int32 y)
561 {
562 // Create a message to pass along to the BeApp thread
563 BMessage msg(BAPP_MOUSE_WHEEL);
564 msg.AddInt32("xticks", x);
565 msg.AddInt32("yticks", y);
566 _PostWindowEvent(msg);
567 }
568
569 void _KeyEvent(int32 keyCode, const int8 *keyUtf8, const ssize_t &len, bool down)
570 {
571 // Create a message to pass along to the BeApp thread
572 BMessage msg(BAPP_KEY);
573 msg.AddInt32("key-scancode", keyCode);
574 if (keyUtf8 != NULL) {
575 msg.AddData("key-utf8", B_INT8_TYPE, (const void *)keyUtf8, len);
576 }
577 msg.AddBool("key-down", down);
578 SDL_Looper->PostMessage(&msg);
579 }
580
581 void _RepaintEvent()
582 {
583 // Force a repaint: Call the SDL exposed event
584 BMessage msg(BAPP_REPAINT);
585 _PostWindowEvent(msg);
586 }
587 void _PostWindowEvent(BMessage &msg)
588 {
589 msg.AddInt32("window-id", _id);
590 SDL_Looper->PostMessage(&msg);
591 }
592
593 // Command methods (functions called upon by SDL)
594 void _SetTitle(BMessage *msg)
595 {
596 const char *title;
597 if (
598 msg->FindString("window-title", &title) != B_OK) {
599 return;
600 }
601 SetTitle(title);
602 }
603
604 void _MoveTo(BMessage *msg)
605 {
606 int32 x, y;
607 if (
608 msg->FindInt32("window-x", &x) != B_OK ||
609 msg->FindInt32("window-y", &y) != B_OK) {
610 return;
611 }
612 if (_fullscreen)
613 _non_fullscreen_frame.OffsetTo(x, y);
614 else
615 MoveTo(x, y);
616 }
617
618 void _ResizeTo(BMessage *msg)
619 {
620 int32 w, h;
621 if (
622 msg->FindInt32("window-w", &w) != B_OK ||
623 msg->FindInt32("window-h", &h) != B_OK) {
624 return;
625 }
626 if (_fullscreen) {
627 _non_fullscreen_frame.right = _non_fullscreen_frame.left + w;
628 _non_fullscreen_frame.bottom = _non_fullscreen_frame.top + h;
629 } else
630 ResizeTo(w, h);
631 }
632
633 void _SetBordered(bool bEnabled)
634 {
635 if (_fullscreen)
636 _bordered = bEnabled;
637 else
638 SetLook(bEnabled ? B_TITLED_WINDOW_LOOK : B_NO_BORDER_WINDOW_LOOK);
639 }
640
641 void _SetResizable(bool bEnabled)
642 {
643 if (_fullscreen)
644 _resizable = bEnabled;
645 else {
646 if (bEnabled) {
647 SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_ZOOMABLE));
648 } else {
649 SetFlags(Flags() | (B_NOT_RESIZABLE | B_NOT_ZOOMABLE));
650 }
651 }
652 }
653
654 void _SetMinimumSize(BMessage *msg)
655 {
656 float maxHeight;
657 float maxWidth;
658 float _;
659 int32 minHeight;
660 int32 minWidth;
661
662 // This is a bit convoluted, we only want to set the minimum not the maximum
663 // But there is no direct call to do that, so store the maximum size beforehand
664 GetSizeLimits(&_, &maxWidth, &_, &maxHeight);
665 if (msg->FindInt32("window-w", &minWidth) != B_OK)
666 return;
667 if (msg->FindInt32("window-h", &minHeight) != B_OK)
668 return;
669 SetSizeLimits((float)minWidth, maxWidth, (float)minHeight, maxHeight);
670 UpdateSizeLimits();
671 }
672
673 void _Restore()
674 {
675 if (IsMinimized()) {
676 Minimize(false);
677 } else if (IsHidden()) {
678 Show();
679 } else if (_fullscreen) {
680
681 } else if (_prev_frame != NULL) { // Zoomed
682 MoveTo(_prev_frame->left, _prev_frame->top);
683 ResizeTo(_prev_frame->Width(), _prev_frame->Height());
684 }
685 }
686
687 void _SetFullScreen(bool fullscreen)
688 {
689 if (fullscreen != _fullscreen) {
690 if (fullscreen) {
691 BScreen screen(this);
692 BRect screenFrame = screen.Frame();
693 printf("screen frame: ");
694 screenFrame.PrintToStream();
695 printf("\n");
696 _bordered = Look() != B_NO_BORDER_WINDOW_LOOK;
697 _resizable = !(Flags() & B_NOT_RESIZABLE);
698 _non_fullscreen_frame = Frame();
699 _SetBordered(false);
700 _SetResizable(false);
701 MoveTo(screenFrame.left, screenFrame.top);
702 ResizeTo(screenFrame.Width(), screenFrame.Height());
703 _fullscreen = fullscreen;
704 } else {
705 _fullscreen = fullscreen;
706 MoveTo(_non_fullscreen_frame.left, _non_fullscreen_frame.top);
707 ResizeTo(_non_fullscreen_frame.Width(), _non_fullscreen_frame.Height());
708 _SetBordered(_bordered);
709 _SetResizable(_resizable);
710 }
711 }
712 }
713
714 // Members
715
716 BView *_cur_view;
717 SDL_BView *_SDL_View;
718#ifdef SDL_VIDEO_OPENGL
719 BGLView *_SDL_GLView;
720 Uint32 _gl_type;
721#endif
722
723 int32 _last_buttons;
724 int32 _id; // Window id used by SDL_BApp
725 bool _mouse_focused; // Does this window have mouse focus?
726 bool _shown;
727 bool _inhibit_resize;
728
729 BRect *_prev_frame; // Previous position and size of the window
730 bool _fullscreen;
731 // valid only if fullscreen
732 BRect _non_fullscreen_frame;
733 bool _bordered;
734 bool _resizable;
735
736 // Framebuffer members
737 BLocker *_buffer_locker;
738 BBitmap *_bitmap;
739};
740
741/* FIXME:
742 * An explanation of framebuffer flags.
743 *
744 * _connected - Original variable used to let the drawing thread know
745 * when changes are being made to the other framebuffer
746 * members.
747 * _connection_disabled - Used to signal to the drawing thread that the window
748 * is closing, and the thread should exit.
749 * _buffer_created - True if the current buffer is valid
750 * _buffer_dirty - True if the window should be redrawn.
751 * _trash_window_buffer - True if the window buffer needs to be trashed partway
752 * through a draw cycle. Occurs when the previous
753 * buffer provided by DirectConnected() is invalidated.
754 */
755#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 @@
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#include "SDL_internal.h"
22
23#ifdef SDL_VIDEO_DRIVER_HAIKU
24
25// BWindow based clipboard implementation
26
27#include <unistd.h>
28#include <TypeConstants.h>
29
30#include "SDL_BWin.h"
31#include "../SDL_sysvideo.h"
32
33#ifdef __cplusplus
34extern "C" {
35#endif
36
37bool HAIKU_SetClipboardText(SDL_VideoDevice *_this, const char *text)
38{
39 BMessage *clip = NULL;
40 if (be_clipboard->Lock()) {
41 be_clipboard->Clear();
42 if ((clip = be_clipboard->Data())) {
43 // Presumably the string of characters is ascii-format
44 ssize_t asciiLength = 0;
45 for (; text[asciiLength] != 0; ++asciiLength) {}
46 clip->AddData("text/plain", B_MIME_TYPE, text, asciiLength);
47 be_clipboard->Commit();
48 }
49 be_clipboard->Unlock();
50 }
51 return true;
52}
53
54char *HAIKU_GetClipboardText(SDL_VideoDevice *_this) {
55 BMessage *clip = NULL;
56 const char *text = NULL;
57 ssize_t length;
58 char *result;
59 if (be_clipboard->Lock()) {
60 if ((clip = be_clipboard->Data())) {
61 // Presumably the string of characters is ascii-format
62 clip->FindData("text/plain", B_MIME_TYPE, (const void**)&text,
63 &length);
64 }
65 be_clipboard->Unlock();
66 }
67
68 if (!text) {
69 result = SDL_strdup("");
70 } else {
71 // Copy the data and pass on to SDL
72 result = (char *)SDL_malloc((length + 1) * sizeof(char));
73 SDL_strlcpy(result, text, length + 1);
74 }
75
76 return result;
77}
78
79bool HAIKU_HasClipboardText(SDL_VideoDevice *_this) {
80 bool result = false;
81 char *text = HAIKU_GetClipboardText(_this);
82 if (text) {
83 result = (text[0] != '\0');
84 SDL_free(text);
85 }
86 return result;
87}
88
89#ifdef __cplusplus
90}
91#endif
92
93#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 @@
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
24#ifndef SDL_BCLIPBOARD_H
25#define SDL_BCLIPBOARD_H
26
27extern bool HAIKU_SetClipboardText(SDL_VideoDevice *_this, const char *text);
28extern char *HAIKU_GetClipboardText(SDL_VideoDevice *_this);
29extern bool HAIKU_HasClipboardText(SDL_VideoDevice *_this);
30
31#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 @@
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#include "SDL_internal.h"
22
23#ifdef SDL_VIDEO_DRIVER_HAIKU
24
25#include "SDL_bevents.h"
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31void HAIKU_PumpEvents(SDL_VideoDevice *_this) {
32 // Since the event thread is its own thread, this isn't really necessary
33}
34
35#ifdef __cplusplus
36}
37#endif
38
39#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 @@
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#ifndef SDL_BEVENTS_H
23#define SDL_BEVENTS_H
24
25#include "../SDL_sysvideo.h"
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31extern void HAIKU_PumpEvents(SDL_VideoDevice *_this);
32
33#ifdef __cplusplus
34}
35#endif
36
37#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 @@
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#include "SDL_internal.h"
22
23#ifdef SDL_VIDEO_DRIVER_HAIKU
24
25#include "SDL_bframebuffer.h"
26
27#include <AppKit.h>
28#include <InterfaceKit.h>
29#include "SDL_bmodes.h"
30#include "SDL_BWin.h"
31
32#include "../../core/haiku/SDL_BApp.h"
33
34#ifdef __cplusplus
35extern "C" {
36#endif
37
38static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window)
39{
40 return (SDL_BWin *)(window->internal);
41}
42
43static SDL_INLINE SDL_BLooper *_GetBeLooper()
44{
45 return SDL_Looper;
46}
47
48bool HAIKU_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window * window, SDL_PixelFormat * format, void ** pixels, int *pitch)
49{
50 SDL_BWin *bwin = _ToBeWin(window);
51 BScreen bscreen;
52 if (!bscreen.IsValid()) {
53 return false;
54 }
55
56 // Make sure we have exclusive access to frame buffer data
57 bwin->LockBuffer();
58
59 bwin->CreateView();
60
61 // format
62 display_mode bmode;
63 bscreen.GetMode(&bmode);
64 *format = HAIKU_ColorSpaceToSDLPxFormat(bmode.space);
65
66 // Create the new bitmap object
67 BBitmap *bitmap = bwin->GetBitmap();
68
69 if (bitmap) {
70 delete bitmap;
71 }
72 bitmap = new BBitmap(bwin->Bounds(), (color_space)bmode.space,
73 false, // Views not accepted
74 true); // Contiguous memory required
75
76 if (bitmap->InitCheck() != B_OK) {
77 delete bitmap;
78 return SDL_SetError("Could not initialize back buffer!");
79 }
80
81
82 bwin->SetBitmap(bitmap);
83
84 // Set the pixel pointer
85 *pixels = bitmap->Bits();
86
87 // pitch = width of window, in bytes
88 *pitch = bitmap->BytesPerRow();
89
90 bwin->UnlockBuffer();
91 return true;
92}
93
94
95
96bool HAIKU_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window * window,
97 const SDL_Rect * rects, int numrects) {
98 if (!window) {
99 return true;
100 }
101
102 SDL_BWin *bwin = _ToBeWin(window);
103
104 bwin->PostMessage(BWIN_UPDATE_FRAMEBUFFER);
105
106 return true;
107}
108
109void HAIKU_DestroyWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window * window) {
110 SDL_BWin *bwin = _ToBeWin(window);
111
112 bwin->LockBuffer();
113
114 // Free and clear the window buffer
115 BBitmap *bitmap = bwin->GetBitmap();
116 delete bitmap;
117 bwin->SetBitmap(NULL);
118
119 bwin->RemoveView();
120
121 bwin->UnlockBuffer();
122}
123
124#ifdef __cplusplus
125}
126#endif
127
128#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 @@
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#ifndef SDL_BFRAMEBUFFER_H
23#define SDL_BFRAMEBUFFER_H
24#include <SupportDefs.h>
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29#define DRAWTHREAD
30
31#include "../SDL_sysvideo.h"
32
33extern bool HAIKU_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window,
34 SDL_PixelFormat *format,
35 void **pixels, int *pitch);
36extern bool HAIKU_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window,
37 const SDL_Rect *rects, int numrects);
38extern void HAIKU_DestroyWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window);
39extern int32 HAIKU_DrawThread(void *data);
40
41#ifdef __cplusplus
42}
43#endif
44
45#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 @@
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#include "SDL_internal.h"
22
23#ifdef SDL_VIDEO_DRIVER_HAIKU
24
25#include <SupportDefs.h>
26#include <support/UTF8.h>
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32
33#include "SDL_bkeyboard.h"
34
35
36#define KEYMAP_SIZE 128
37
38
39static SDL_Scancode keymap[KEYMAP_SIZE];
40
41void HAIKU_InitOSKeymap(void)
42{
43 for ( uint i = 0; i < SDL_arraysize(keymap); ++i ) {
44 keymap[i] = SDL_SCANCODE_UNKNOWN;
45 }
46
47 keymap[0x01] = SDL_SCANCODE_ESCAPE;
48 keymap[B_F1_KEY] = SDL_SCANCODE_F1;
49 keymap[B_F2_KEY] = SDL_SCANCODE_F2;
50 keymap[B_F3_KEY] = SDL_SCANCODE_F3;
51 keymap[B_F4_KEY] = SDL_SCANCODE_F4;
52 keymap[B_F5_KEY] = SDL_SCANCODE_F5;
53 keymap[B_F6_KEY] = SDL_SCANCODE_F6;
54 keymap[B_F7_KEY] = SDL_SCANCODE_F7;
55 keymap[B_F8_KEY] = SDL_SCANCODE_F8;
56 keymap[B_F9_KEY] = SDL_SCANCODE_F9;
57 keymap[B_F10_KEY] = SDL_SCANCODE_F10;
58 keymap[B_F11_KEY] = SDL_SCANCODE_F11;
59 keymap[B_F12_KEY] = SDL_SCANCODE_F12;
60 keymap[B_PRINT_KEY] = SDL_SCANCODE_PRINTSCREEN;
61 keymap[B_SCROLL_KEY]= SDL_SCANCODE_SCROLLLOCK;
62 keymap[B_PAUSE_KEY] = SDL_SCANCODE_PAUSE;
63 keymap[0x11] = SDL_SCANCODE_GRAVE;
64 keymap[0x12] = SDL_SCANCODE_1;
65 keymap[0x13] = SDL_SCANCODE_2;
66 keymap[0x14] = SDL_SCANCODE_3;
67 keymap[0x15] = SDL_SCANCODE_4;
68 keymap[0x16] = SDL_SCANCODE_5;
69 keymap[0x17] = SDL_SCANCODE_6;
70 keymap[0x18] = SDL_SCANCODE_7;
71 keymap[0x19] = SDL_SCANCODE_8;
72 keymap[0x1a] = SDL_SCANCODE_9;
73 keymap[0x1b] = SDL_SCANCODE_0;
74 keymap[0x1c] = SDL_SCANCODE_MINUS;
75 keymap[0x1d] = SDL_SCANCODE_EQUALS;
76 keymap[0x1e] = SDL_SCANCODE_BACKSPACE;
77 keymap[0x1f] = SDL_SCANCODE_INSERT;
78 keymap[0x20] = SDL_SCANCODE_HOME;
79 keymap[0x21] = SDL_SCANCODE_PAGEUP;
80 keymap[0x22] = SDL_SCANCODE_NUMLOCKCLEAR;
81 keymap[0x23] = SDL_SCANCODE_KP_DIVIDE;
82 keymap[0x24] = SDL_SCANCODE_KP_MULTIPLY;
83 keymap[0x25] = SDL_SCANCODE_KP_MINUS;
84 keymap[0x26] = SDL_SCANCODE_TAB;
85 keymap[0x27] = SDL_SCANCODE_Q;
86 keymap[0x28] = SDL_SCANCODE_W;
87 keymap[0x29] = SDL_SCANCODE_E;
88 keymap[0x2a] = SDL_SCANCODE_R;
89 keymap[0x2b] = SDL_SCANCODE_T;
90 keymap[0x2c] = SDL_SCANCODE_Y;
91 keymap[0x2d] = SDL_SCANCODE_U;
92 keymap[0x2e] = SDL_SCANCODE_I;
93 keymap[0x2f] = SDL_SCANCODE_O;
94 keymap[0x30] = SDL_SCANCODE_P;
95 keymap[0x31] = SDL_SCANCODE_LEFTBRACKET;
96 keymap[0x32] = SDL_SCANCODE_RIGHTBRACKET;
97 keymap[0x33] = SDL_SCANCODE_BACKSLASH;
98 keymap[0x34] = SDL_SCANCODE_DELETE;
99 keymap[0x35] = SDL_SCANCODE_END;
100 keymap[0x36] = SDL_SCANCODE_PAGEDOWN;
101 keymap[0x37] = SDL_SCANCODE_KP_7;
102 keymap[0x38] = SDL_SCANCODE_KP_8;
103 keymap[0x39] = SDL_SCANCODE_KP_9;
104 keymap[0x3a] = SDL_SCANCODE_KP_PLUS;
105 keymap[0x3b] = SDL_SCANCODE_CAPSLOCK;
106 keymap[0x3c] = SDL_SCANCODE_A;
107 keymap[0x3d] = SDL_SCANCODE_S;
108 keymap[0x3e] = SDL_SCANCODE_D;
109 keymap[0x3f] = SDL_SCANCODE_F;
110 keymap[0x40] = SDL_SCANCODE_G;
111 keymap[0x41] = SDL_SCANCODE_H;
112 keymap[0x42] = SDL_SCANCODE_J;
113 keymap[0x43] = SDL_SCANCODE_K;
114 keymap[0x44] = SDL_SCANCODE_L;
115 keymap[0x45] = SDL_SCANCODE_SEMICOLON;
116 keymap[0x46] = SDL_SCANCODE_APOSTROPHE;
117 keymap[0x47] = SDL_SCANCODE_RETURN;
118 keymap[0x48] = SDL_SCANCODE_KP_4;
119 keymap[0x49] = SDL_SCANCODE_KP_5;
120 keymap[0x4a] = SDL_SCANCODE_KP_6;
121 keymap[0x4b] = SDL_SCANCODE_LSHIFT;
122 keymap[0x4c] = SDL_SCANCODE_Z;
123 keymap[0x4d] = SDL_SCANCODE_X;
124 keymap[0x4e] = SDL_SCANCODE_C;
125 keymap[0x4f] = SDL_SCANCODE_V;
126 keymap[0x50] = SDL_SCANCODE_B;
127 keymap[0x51] = SDL_SCANCODE_N;
128 keymap[0x52] = SDL_SCANCODE_M;
129 keymap[0x53] = SDL_SCANCODE_COMMA;
130 keymap[0x54] = SDL_SCANCODE_PERIOD;
131 keymap[0x55] = SDL_SCANCODE_SLASH;
132 keymap[0x56] = SDL_SCANCODE_RSHIFT;
133 keymap[0x57] = SDL_SCANCODE_UP;
134 keymap[0x58] = SDL_SCANCODE_KP_1;
135 keymap[0x59] = SDL_SCANCODE_KP_2;
136 keymap[0x5a] = SDL_SCANCODE_KP_3;
137 keymap[0x5b] = SDL_SCANCODE_KP_ENTER;
138 keymap[0x5c] = SDL_SCANCODE_LCTRL;
139 keymap[0x5d] = SDL_SCANCODE_LALT;
140 keymap[0x5e] = SDL_SCANCODE_SPACE;
141 keymap[0x5f] = SDL_SCANCODE_RALT;
142 keymap[0x60] = SDL_SCANCODE_RCTRL;
143 keymap[0x61] = SDL_SCANCODE_LEFT;
144 keymap[0x62] = SDL_SCANCODE_DOWN;
145 keymap[0x63] = SDL_SCANCODE_RIGHT;
146 keymap[0x64] = SDL_SCANCODE_KP_0;
147 keymap[0x65] = SDL_SCANCODE_KP_PERIOD;
148 keymap[0x66] = SDL_SCANCODE_LGUI;
149 keymap[0x67] = SDL_SCANCODE_RGUI;
150 keymap[0x68] = SDL_SCANCODE_MENU;
151 keymap[0x69] = SDL_SCANCODE_2; // SDLK_EURO
152 keymap[0x6a] = SDL_SCANCODE_KP_EQUALS;
153 keymap[0x6b] = SDL_SCANCODE_POWER;
154}
155
156SDL_Scancode HAIKU_GetScancodeFromBeKey(int32 bkey) {
157 if (bkey > 0 && bkey < (int32)SDL_arraysize(keymap)) {
158 return keymap[bkey];
159 } else {
160 return SDL_SCANCODE_UNKNOWN;
161 }
162}
163
164#ifdef __cplusplus
165}
166#endif
167
168#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 @@
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#ifndef SDL_BKEYBOARD_H
23#define SDL_BKEYBOARD_H
24
25#include <SupportDefs.h>
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31extern void HAIKU_InitOSKeymap(void);
32extern SDL_Scancode HAIKU_GetScancodeFromBeKey(int32 bkey);
33
34#ifdef __cplusplus
35}
36#endif
37
38#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 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4 Copyright (C) 2018-2019 EXL <exlmotodev@gmail.com>
5
6 This software is provided 'as-is', without any express or implied
7 warranty. In no event will the authors be held liable for any damages
8 arising from the use of this software.
9
10 Permission is granted to anyone to use this software for any purpose,
11 including commercial applications, and to alter it and redistribute it
12 freely, subject to the following restrictions:
13
14 1. The origin of this software must not be misrepresented; you must not
15 claim that you wrote the original software. If you use this software
16 in a product, an acknowledgment in the product documentation would be
17 appreciated but is not required.
18 2. Altered source versions must be plainly marked as such, and must not be
19 misrepresented as being the original software.
20 3. This notice may not be removed or altered from any source distribution.
21*/
22
23#include "SDL_internal.h"
24
25#ifdef SDL_VIDEO_DRIVER_HAIKU
26
27
28// For application signature.
29#include "../../core/haiku/SDL_BeApp.h"
30
31#include <Alert.h>
32#include <Application.h>
33#include <Button.h>
34#include <Font.h>
35#include <Layout.h>
36#include <String.h>
37#include <TextView.h>
38#include <View.h>
39#include <Window.h>
40
41#include <InterfaceDefs.h>
42#include <SupportDefs.h>
43#include <GraphicsDefs.h>
44
45#include <new>
46#include <vector>
47#include <algorithm>
48#include <memory>
49
50enum
51{
52 G_CLOSE_BUTTON_ID = -1,
53 G_DEFAULT_BUTTON_ID = 0,
54 G_MAX_STRING_LENGTH_BYTES = 120
55};
56
57class HAIKU_SDL_MessageBox : public BAlert
58{
59 float fComputedMessageBoxWidth;
60
61 BTextView *fMessageBoxTextView;
62
63 int fCloseButton;
64 int fDefaultButton;
65
66 bool fCustomColorScheme;
67 bool fThereIsLongLine;
68 rgb_color fTextColor;
69
70 const char *fTitle;
71 const char *HAIKU_SDL_DefTitle;
72 const char *HAIKU_SDL_DefMessage;
73 const char *HAIKU_SDL_DefButton;
74
75 std::vector<const SDL_MessageBoxButtonData *> fButtons;
76
77 static bool
78 SortButtonsPredicate(const SDL_MessageBoxButtonData *aButtonLeft,
79 const SDL_MessageBoxButtonData *aButtonRight)
80 {
81 return aButtonLeft->buttonID < aButtonRight->buttonID;
82 }
83
84 alert_type
85 ConvertMessageBoxType(const SDL_MessageBoxFlags aWindowType) const
86 {
87 switch (aWindowType)
88 {
89 default:
90 case SDL_MESSAGEBOX_WARNING:
91 {
92 return B_WARNING_ALERT;
93 }
94 case SDL_MESSAGEBOX_ERROR:
95 {
96 return B_STOP_ALERT;
97 }
98 case SDL_MESSAGEBOX_INFORMATION:
99 {
100 return B_INFO_ALERT;
101 }
102 }
103 }
104
105 rgb_color
106 ConvertColorType(const SDL_MessageBoxColor *aColor) const
107 {
108 rgb_color color = { aColor->r, aColor->g, aColor->b, color.alpha = 255 };
109 return color;
110 }
111
112 int32
113 GetLeftPanelWidth(void) const
114 {
115 // See file "haiku/src/kits/interface/Alert.cpp" for this magic numbers.
116 // IconStripeWidth = 30 * Scale
117 // IconSize = 32 * Scale
118 // Scale = max_c(1, ((int32)be_plain_font->Size() + 15) / 16)
119 // RealWidth = (IconStripeWidth * Scale) + (IconSize * Scale)
120
121 int32 scale = max_c(1, ((int32)be_plain_font->Size() + 15) / 16);
122 return (30 * scale) + (32 * scale);
123 }
124
125 void
126 UpdateTextViewWidth(void)
127 {
128 fComputedMessageBoxWidth = fMessageBoxTextView->PreferredSize().Width() + GetLeftPanelWidth();
129 }
130
131 void
132 ParseSdlMessageBoxData(const SDL_MessageBoxData *aMessageBoxData)
133 {
134 if (aMessageBoxData == NULL) {
135 SetTitle(HAIKU_SDL_DefTitle);
136 SetMessageText(HAIKU_SDL_DefMessage);
137 AddButton(HAIKU_SDL_DefButton);
138 return;
139 }
140
141 if (aMessageBoxData->numbuttons <= 0) {
142 AddButton(HAIKU_SDL_DefButton);
143 } else {
144 AddSdlButtons(aMessageBoxData->buttons, aMessageBoxData->numbuttons);
145 }
146
147 if (aMessageBoxData->colorScheme != NULL) {
148 fCustomColorScheme = true;
149 ApplyAndParseColorScheme(aMessageBoxData->colorScheme);
150 }
151
152 (aMessageBoxData->title[0]) ?
153 SetTitle(aMessageBoxData->title) : SetTitle(HAIKU_SDL_DefTitle);
154 (aMessageBoxData->message[0]) ?
155 SetMessageText(aMessageBoxData->message) : SetMessageText(HAIKU_SDL_DefMessage);
156
157 SetType(ConvertMessageBoxType(aMessageBoxData->flags));
158 }
159
160 void
161 ApplyAndParseColorScheme(const SDL_MessageBoxColorScheme *aColorScheme)
162 {
163 SetBackgroundColor(&aColorScheme->colors[SDL_MESSAGEBOX_COLOR_BACKGROUND]);
164 fTextColor = ConvertColorType(&aColorScheme->colors[SDL_MESSAGEBOX_COLOR_TEXT]);
165 SetButtonColors(&aColorScheme->colors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER],
166 &aColorScheme->colors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND],
167 &aColorScheme->colors[SDL_MESSAGEBOX_COLOR_TEXT],
168 &aColorScheme->colors[SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED]);
169 }
170
171 void
172 SetButtonColors(const SDL_MessageBoxColor *aBorderColor,
173 const SDL_MessageBoxColor *aBackgroundColor,
174 const SDL_MessageBoxColor *aTextColor,
175 const SDL_MessageBoxColor *aSelectedColor)
176 {
177 if (fCustomColorScheme) {
178 int32 countButtons = CountButtons();
179 for (int i = 0; i < countButtons; ++i) {
180 ButtonAt(i)->SetViewColor(ConvertColorType(aBorderColor));
181 ButtonAt(i)->SetLowColor(ConvertColorType(aBackgroundColor));
182
183 // This doesn't work. See this why:
184 // https://github.com/haiku/haiku/commit/de9c53f8f5008c7b3b0af75d944a628e17f6dffe
185 // Let it remain.
186 ButtonAt(i)->SetHighColor(ConvertColorType(aTextColor));
187 }
188 }
189 // TODO: Not Implemented.
190 // Is it even necessary?!
191 (void)aSelectedColor;
192 }
193
194 void
195 SetBackgroundColor(const SDL_MessageBoxColor *aColor)
196 {
197 rgb_color background = ConvertColorType(aColor);
198
199 GetLayout()->View()->SetViewColor(background);
200 // See file "haiku/src/kits/interface/Alert.cpp", the "TAlertView" is the internal name of the left panel.
201 FindView("TAlertView")->SetViewColor(background);
202 fMessageBoxTextView->SetViewColor(background);
203 }
204
205 bool
206 CheckLongLines(const char *aMessage)
207 {
208 int final = 0;
209
210 // This UTF-8 friendly.
211 BString message = aMessage;
212 int32 length = message.CountChars();
213
214 for (int i = 0, c = 0; i < length; ++i) {
215 c++;
216 if (*(message.CharAt(i)) == '\n') {
217 c = 0;
218 }
219 if (c > final) {
220 final = c;
221 }
222 }
223
224 return (final > G_MAX_STRING_LENGTH_BYTES);
225 }
226
227 void
228 SetMessageText(const char *aMessage)
229 {
230 fThereIsLongLine = CheckLongLines(aMessage);
231 if (fThereIsLongLine) {
232 fMessageBoxTextView->SetWordWrap(true);
233 }
234
235 rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR);
236 if (fCustomColorScheme) {
237 textColor = fTextColor;
238 }
239
240 /*
241 if (fNoTitledWindow) {
242 fMessageBoxTextView->SetFontAndColor(be_bold_font);
243 fMessageBoxTextView->Insert(fTitle);
244 fMessageBoxTextView->Insert("\n\n");
245 fMessageBoxTextView->SetFontAndColor(be_plain_font);
246 }
247 */
248
249 fMessageBoxTextView->SetFontAndColor(be_plain_font, B_FONT_ALL, &textColor);
250 fMessageBoxTextView->Insert(aMessage);
251
252 // Be sure to call update width method.
253 UpdateTextViewWidth();
254 }
255
256 void
257 AddSdlButtons(const SDL_MessageBoxButtonData *aButtons, int aNumButtons)
258 {
259 for (int i = 0; i < aNumButtons; ++i) {
260 fButtons.push_back(&aButtons[i]);
261 }
262
263 std::sort(fButtons.begin(), fButtons.end(), &HAIKU_SDL_MessageBox::SortButtonsPredicate);
264
265 size_t countButtons = fButtons.size();
266 for (size_t i = 0; i < countButtons; ++i) {
267 if (fButtons[i]->flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) {
268 fCloseButton = static_cast<int>(i);
269 }
270 if (fButtons[i]->flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
271 fDefaultButton = static_cast<int>(i);
272 }
273 AddButton(fButtons[i]->text);
274 }
275
276 SetDefaultButton(ButtonAt(fDefaultButton));
277 }
278
279public:
280 explicit
281 HAIKU_SDL_MessageBox(const SDL_MessageBoxData *aMessageBoxData)
282 : BAlert(NULL, NULL, NULL, NULL, NULL, B_WIDTH_FROM_LABEL, B_WARNING_ALERT),
283 fComputedMessageBoxWidth(0.0f),
284 fCloseButton(G_CLOSE_BUTTON_ID), fDefaultButton(G_DEFAULT_BUTTON_ID),
285 fCustomColorScheme(false), fThereIsLongLine(false),
286 HAIKU_SDL_DefTitle("SDL MessageBox"),
287 HAIKU_SDL_DefMessage("Some information has been lost."),
288 HAIKU_SDL_DefButton("OK")
289 {
290 // MessageBox settings.
291 // We need a title to display it.
292 SetLook(B_TITLED_WINDOW_LOOK);
293 SetFlags(Flags() | B_CLOSE_ON_ESCAPE);
294
295 // MessageBox TextView settings.
296 fMessageBoxTextView = TextView();
297 fMessageBoxTextView->SetWordWrap(false);
298 fMessageBoxTextView->SetStylable(true);
299
300 ParseSdlMessageBoxData(aMessageBoxData);
301 }
302
303 int
304 GetCloseButtonId(void) const
305 {
306 return fCloseButton;
307 }
308
309 virtual
310 ~HAIKU_SDL_MessageBox(void)
311 {
312 fButtons.clear();
313 }
314
315protected:
316 virtual void
317 FrameResized(float aNewWidth, float aNewHeight)
318 {
319 if (fComputedMessageBoxWidth > aNewWidth) {
320 ResizeTo(fComputedMessageBoxWidth, aNewHeight);
321 } else {
322 BAlert::FrameResized(aNewWidth, aNewHeight);
323 }
324 }
325
326 virtual void
327 SetTitle(const char* aTitle)
328 {
329 fTitle = aTitle;
330 BAlert::SetTitle(aTitle);
331 }
332};
333
334#ifdef __cplusplus
335extern "C" {
336#endif
337
338bool HAIKU_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
339{
340 // Initialize button by closed or error value first.
341 *buttonID = G_CLOSE_BUTTON_ID;
342
343 // We need to check "be_app" pointer to "NULL". The "messageboxdata->window" pointer isn't appropriate here
344 // because it is possible to create a MessageBox from another thread. This fixes the following errors:
345 // "You need a valid BApplication object before interacting with the app_server."
346 // "2 BApplication objects were created. Only one is allowed."
347 std::unique_ptr<BApplication> application;
348 if (!be_app) {
349 application = std::unique_ptr<BApplication>(new(std::nothrow) BApplication(SDL_signature));
350 if (!application) {
351 return SDL_SetError("Cannot create the BApplication object. Lack of memory?");
352 }
353 }
354
355 HAIKU_SDL_MessageBox *SDL_MessageBox = new(std::nothrow) HAIKU_SDL_MessageBox(messageboxdata);
356 if (!SDL_MessageBox) {
357 return SDL_SetError("Cannot create the HAIKU_SDL_MessageBox (BAlert inheritor) object. Lack of memory?");
358 }
359 const int closeButton = SDL_MessageBox->GetCloseButtonId();
360 int pushedButton = SDL_MessageBox->Go();
361
362 // The close button is equivalent to pressing Escape.
363 if (closeButton != G_CLOSE_BUTTON_ID && pushedButton == G_CLOSE_BUTTON_ID) {
364 pushedButton = closeButton;
365 }
366
367 // It's deleted by itself after the "Go()" method was executed.
368 /*
369 if (messageBox != NULL) {
370 delete messageBox;
371 }
372 */
373 // Initialize button by real pushed value then.
374 *buttonID = pushedButton;
375
376 return true;
377}
378
379#ifdef __cplusplus
380}
381#endif
382
383#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 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4 Copyright (C) 2018-2019 EXL <exlmotodev@gmail.com>
5
6 This software is provided 'as-is', without any express or implied
7 warranty. In no event will the authors be held liable for any damages
8 arising from the use of this software.
9
10 Permission is granted to anyone to use this software for any purpose,
11 including commercial applications, and to alter it and redistribute it
12 freely, subject to the following restrictions:
13
14 1. The origin of this software must not be misrepresented; you must not
15 claim that you wrote the original software. If you use this software
16 in a product, an acknowledgment in the product documentation would be
17 appreciated but is not required.
18 2. Altered source versions must be plainly marked as such, and must not be
19 misrepresented as being the original software.
20 3. This notice may not be removed or altered from any source distribution.
21*/
22
23#ifndef SDL_BMESSAGEBOX_H
24#define SDL_BMESSAGEBOX_H
25
26#include "SDL_internal.h"
27
28#ifdef SDL_VIDEO_DRIVER_HAIKU
29
30#ifdef __cplusplus
31extern "C" {
32#endif
33
34extern bool HAIKU_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID);
35
36#ifdef __cplusplus
37}
38#endif
39
40#endif // SDL_VIDEO_DRIVER_HAIKU
41
42#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 @@
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#include "SDL_internal.h"
22
23#ifdef SDL_VIDEO_DRIVER_HAIKU
24
25#include <AppKit.h>
26#include <InterfaceKit.h>
27#include "SDL_bmodes.h"
28#include "SDL_BWin.h"
29
30#ifdef SDL_VIDEO_OPENGL
31#include "SDL_bopengl.h"
32#endif
33
34#include "../../core/haiku/SDL_BApp.h"
35
36#ifdef __cplusplus
37extern "C" {
38#endif
39
40
41#define WRAP_BMODE 1 // FIXME: Some debate as to whether this is necessary
42
43#if WRAP_BMODE
44/* This wrapper is here so that the internal can be freed without freeing
45 the display_mode structure */
46struct SDL_DisplayModeData {
47 display_mode *bmode;
48};
49#endif
50
51static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window)
52{
53 return (SDL_BWin *)(window->internal);
54}
55
56static SDL_INLINE SDL_BLooper *_GetBeLooper()
57{
58 return SDL_Looper;
59}
60
61static SDL_INLINE display_mode * _ExtractBMode(SDL_DisplayMode *mode)
62{
63#if WRAP_BMODE
64 return mode->internal->bmode;
65#else
66 return (display_mode *)mode->internal;
67#endif
68}
69
70// Copied from haiku/trunk/src/preferences/screen/ScreenMode.cpp
71static void get_refresh_rate(display_mode &mode, int *numerator, int *denominator)
72{
73 *numerator = (mode.timing.pixel_clock * 1000);
74 *denominator = (mode.timing.h_total * mode.timing.v_total);
75}
76
77
78#if 0
79/* TODO:
80 * This is a useful debugging tool. Uncomment and insert into code as needed.
81 */
82void _SpoutModeData(display_mode *bmode)
83{
84 printf("BMode:\n");
85 printf("\tw,h = (%i,%i)\n", bmode->virtual_width, bmode->virtual_height);
86 printf("\th,v = (%i,%i)\n", bmode->h_display_start,
87 bmode->v_display_start);
88 if (bmode->flags) {
89 printf("\tFlags:\n");
90 if (bmode->flags & B_SCROLL) {
91 printf("\t\tB_SCROLL\n");
92 }
93 if (bmode->flags & B_8_BIT_DAC) {
94 printf("\t\tB_8_BIT_DAC\n");
95 }
96 if (bmode->flags & B_HARDWARE_CURSOR) {
97 printf("\t\tB_HARDWARE_CURSOR\n");
98 }
99 if (bmode->flags & B_PARALLEL_ACCESS) {
100 printf("\t\tB_PARALLEL_ACCESS\n");
101 }
102 if (bmode->flags & B_DPMS) {
103 printf("\t\tB_DPMS\n");
104 }
105 if (bmode->flags & B_IO_FB_NA) {
106 printf("\t\tB_IO_FB_NA\n");
107 }
108 }
109 printf("\tTiming:\n");
110 printf("\t\tpx clock: %i\n", bmode->timing.pixel_clock);
111 printf("\t\th - display: %i sync start: %i sync end: %i total: %i\n",
112 bmode->timing.h_display, bmode->timing.h_sync_start,
113 bmode->timing.h_sync_end, bmode->timing.h_total);
114 printf("\t\tv - display: %i sync start: %i sync end: %i total: %i\n",
115 bmode->timing.v_display, bmode->timing.v_sync_start,
116 bmode->timing.v_sync_end, bmode->timing.v_total);
117 if (bmode->timing.flags) {
118 printf("\t\tFlags:\n");
119 if (bmode->timing.flags & B_BLANK_PEDESTAL) {
120 printf("\t\t\tB_BLANK_PEDESTAL\n");
121 }
122 if (bmode->timing.flags & B_TIMING_INTERLACED) {
123 printf("\t\t\tB_TIMING_INTERLACED\n");
124 }
125 if (bmode->timing.flags & B_POSITIVE_HSYNC) {
126 printf("\t\t\tB_POSITIVE_HSYNC\n");
127 }
128 if (bmode->timing.flags & B_POSITIVE_VSYNC) {
129 printf("\t\t\tB_POSITIVE_VSYNC\n");
130 }
131 if (bmode->timing.flags & B_SYNC_ON_GREEN) {
132 printf("\t\t\tB_SYNC_ON_GREEN\n");
133 }
134 }
135}
136#endif
137
138
139
140SDL_PixelFormat HAIKU_ColorSpaceToSDLPxFormat(uint32 colorspace)
141{
142 switch (colorspace) {
143 case B_CMAP8:
144 return SDL_PIXELFORMAT_INDEX8;
145 break;
146 case B_RGB15:
147 case B_RGBA15:
148 case B_RGB15_BIG:
149 case B_RGBA15_BIG:
150 return SDL_PIXELFORMAT_XRGB1555;
151 break;
152 case B_RGB16:
153 case B_RGB16_BIG:
154 return SDL_PIXELFORMAT_RGB565;
155 break;
156 case B_RGB24:
157 case B_RGB24_BIG:
158 return SDL_PIXELFORMAT_BGR24;
159 break;
160 case B_RGB32:
161 case B_RGBA32:
162 case B_RGB32_BIG:
163 case B_RGBA32_BIG:
164 return SDL_PIXELFORMAT_XRGB8888;
165 break;
166 }
167
168 // May never get here, but safer and needed to shut up compiler
169 SDL_SetError("Invalid color space");
170 return SDL_PIXELFORMAT_UNKNOWN;
171}
172
173static void _BDisplayModeToSdlDisplayMode(display_mode *bmode, SDL_DisplayMode *mode)
174{
175 SDL_zerop(mode);
176 mode->w = bmode->virtual_width;
177 mode->h = bmode->virtual_height;
178 get_refresh_rate(*bmode, &mode->refresh_rate_numerator, &mode->refresh_rate_denominator);
179
180#if WRAP_BMODE
181 SDL_DisplayModeData *data = (SDL_DisplayModeData*)SDL_calloc(1, sizeof(SDL_DisplayModeData));
182 data->bmode = bmode;
183
184 mode->internal = data;
185#else
186 mode->internal = bmode;
187#endif
188
189 // Set the format
190 mode->format = HAIKU_ColorSpaceToSDLPxFormat(bmode->space);
191}
192
193// Later, there may be more than one monitor available
194static void _AddDisplay(BScreen *screen)
195{
196 SDL_DisplayMode mode;
197 display_mode bmode;
198 screen->GetMode(&bmode);
199
200 _BDisplayModeToSdlDisplayMode(&bmode, &mode);
201
202 SDL_AddBasicVideoDisplay(&mode);
203}
204
205/*
206 * Functions called by SDL
207 */
208
209bool HAIKU_InitModes(SDL_VideoDevice *_this)
210{
211 BScreen screen;
212
213 /* TODO: When Haiku supports multiple display screens, call
214 _AddDisplayScreen() for each of them. */
215 _AddDisplay(&screen);
216 return true;
217}
218
219void HAIKU_QuitModes(SDL_VideoDevice *_this)
220{
221 return;
222}
223
224
225bool HAIKU_GetDisplayBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect)
226{
227 BScreen bscreen;
228 BRect rc = bscreen.Frame();
229 rect->x = (int)rc.left;
230 rect->y = (int)rc.top;
231 rect->w = (int)rc.Width() + 1;
232 rect->h = (int)rc.Height() + 1;
233 return true;
234}
235
236bool HAIKU_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display)
237{
238 // Get the current screen
239 BScreen bscreen;
240
241 // Iterate through all of the modes
242 SDL_DisplayMode mode;
243 display_mode this_bmode;
244 display_mode *bmodes;
245 uint32 count, i;
246
247 // Get graphics-hardware supported modes
248 bscreen.GetModeList(&bmodes, &count);
249 bscreen.GetMode(&this_bmode);
250
251 for (i = 0; i < count; ++i) {
252 // FIXME: Apparently there are errors with colorspace changes
253 if (bmodes[i].space == this_bmode.space) {
254 _BDisplayModeToSdlDisplayMode(&bmodes[i], &mode);
255 SDL_AddFullscreenDisplayMode(display, &mode);
256 }
257 }
258 free(bmodes); // This should NOT be SDL_free()
259 return true;
260}
261
262
263bool HAIKU_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
264{
265 // Get the current screen
266 BScreen bscreen;
267 if (!bscreen.IsValid()) {
268 printf(__FILE__": %d - ERROR: BAD SCREEN\n", __LINE__);
269 }
270
271 // Set the mode using the driver data
272 display_mode *bmode = _ExtractBMode(mode);
273
274
275 // FIXME: Is the first option always going to be the right one?
276 uint32 c = 0, i;
277 display_mode *bmode_list;
278 bscreen.GetModeList(&bmode_list, &c);
279 for (i = 0; i < c; ++i) {
280 if ( bmode_list[i].space == bmode->space &&
281 bmode_list[i].virtual_width == bmode->virtual_width &&
282 bmode_list[i].virtual_height == bmode->virtual_height ) {
283 bmode = &bmode_list[i];
284 break;
285 }
286 }
287
288 if (bscreen.SetMode(bmode) != B_OK) {
289 return SDL_SetError("Bad video mode");
290 }
291
292 free(bmode_list); // This should NOT be SDL_free()
293
294#ifdef SDL_VIDEO_OPENGL
295 /* FIXME: Is there some way to reboot the OpenGL context? This doesn't
296 help */
297// HAIKU_GL_RebootContexts(_this);
298#endif
299
300 return true;
301}
302
303#ifdef __cplusplus
304}
305#endif
306
307#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 @@
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#ifndef SDL_BMODES_H
23#define SDL_BMODES_H
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29#include "../SDL_sysvideo.h"
30
31extern SDL_PixelFormat HAIKU_ColorSpaceToSDLPxFormat(uint32 colorspace);
32
33extern bool HAIKU_InitModes(SDL_VideoDevice *_this);
34extern void HAIKU_QuitModes(SDL_VideoDevice *_this);
35extern bool HAIKU_GetDisplayBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect);
36extern bool HAIKU_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display);
37extern bool HAIKU_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode);
38
39#ifdef __cplusplus
40}
41#endif
42
43#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 @@
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#include "SDL_internal.h"
22
23#if defined(SDL_VIDEO_DRIVER_HAIKU) && defined(SDL_VIDEO_OPENGL)
24
25#include "SDL_bopengl.h"
26
27#include <unistd.h>
28#include <KernelKit.h>
29#include <OpenGLKit.h>
30#include "SDL_BWin.h"
31#include "../../core/haiku/SDL_BApp.h"
32
33#ifdef __cplusplus
34extern "C" {
35#endif
36
37
38static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window)
39{
40 return (SDL_BWin *)(window->internal);
41}
42
43static SDL_INLINE SDL_BLooper *_GetBeLooper()
44{
45 return SDL_Looper;
46}
47
48// Passing a NULL path means load pointers from the application
49bool HAIKU_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path)
50{
51// FIXME: Is this working correctly?
52 image_info info;
53 int32 cookie = 0;
54 while (get_next_image_info(0, &cookie, &info) == B_OK) {
55 void *location = NULL;
56 if ( get_image_symbol(info.id, "glBegin", B_SYMBOL_TYPE_ANY,
57 &location) == B_OK) {
58
59 _this->gl_config.dll_handle = (SDL_SharedObject *) (addr_t) info.id;
60 _this->gl_config.driver_loaded = 1;
61 SDL_strlcpy(_this->gl_config.driver_path, "libGL.so",
62 SDL_arraysize(_this->gl_config.driver_path));
63 }
64 }
65 return true;
66}
67
68SDL_FunctionPointer HAIKU_GL_GetProcAddress(SDL_VideoDevice *_this, const char *proc)
69{
70 if (_this->gl_config.dll_handle) {
71 void *location = NULL;
72 status_t err;
73 if ((err =
74 get_image_symbol((image_id) (addr_t) _this->gl_config.dll_handle,
75 proc, B_SYMBOL_TYPE_ANY,
76 &location)) == B_OK) {
77 return (SDL_FunctionPointer)location;
78 } else {
79 SDL_SetError("Couldn't find OpenGL symbol");
80 return NULL;
81 }
82 } else {
83 SDL_SetError("OpenGL library not loaded");
84 return NULL;
85 }
86}
87
88
89bool HAIKU_GL_SwapWindow(SDL_VideoDevice *_this, SDL_Window * window)
90{
91 _ToBeWin(window)->SwapBuffers();
92 return true;
93}
94
95bool HAIKU_GL_MakeCurrent(SDL_VideoDevice *_this, SDL_Window * window, SDL_GLContext context)
96{
97 BGLView* glView = (BGLView*)context;
98 // printf("HAIKU_GL_MakeCurrent(%llx), win = %llx, thread = %d\n", (uint64)context, (uint64)window, find_thread(NULL));
99 if (glView) {
100 if ((glView->Window() == NULL) || (!window) || (_ToBeWin(window)->GetGLView() != glView)) {
101 return SDL_SetError("MakeCurrent failed");
102 }
103 }
104 _GetBeLooper()->SetCurrentContext(glView);
105 return true;
106}
107
108
109SDL_GLContext HAIKU_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window * window)
110{
111 /* FIXME: Not sure what flags should be included here; may want to have
112 most of them */
113 SDL_BWin *bwin = _ToBeWin(window);
114 // printf("HAIKU_GL_CreateContext, win = %llx, thread = %d\n", (uint64)window, find_thread(NULL));
115 if (bwin->GetGLView() != NULL) {
116 SDL_SetError("Context already creaded");
117 return NULL;
118 }
119 Uint32 gl_flags = BGL_RGB;
120 if (_this->gl_config.alpha_size) {
121 gl_flags |= BGL_ALPHA;
122 }
123 if (_this->gl_config.depth_size) {
124 gl_flags |= BGL_DEPTH;
125 }
126 if (_this->gl_config.stencil_size) {
127 gl_flags |= BGL_STENCIL;
128 }
129 if (_this->gl_config.double_buffer) {
130 gl_flags |= BGL_DOUBLE;
131 } else {
132 gl_flags |= BGL_SINGLE;
133 }
134 if (_this->gl_config.accum_red_size ||
135 _this->gl_config.accum_green_size ||
136 _this->gl_config.accum_blue_size ||
137 _this->gl_config.accum_alpha_size) {
138 gl_flags |= BGL_ACCUM;
139 }
140#if __GNUC__ > 3
141 if (_this->gl_config.share_with_current_context) {
142 gl_flags |= BGL_SHARE_CONTEXT;
143 }
144#endif
145 bwin->CreateGLView(gl_flags);
146 _GetBeLooper()->SetCurrentContext(bwin->GetGLView());
147 return (SDL_GLContext)(bwin->GetGLView());
148}
149
150bool HAIKU_GL_DestroyContext(SDL_VideoDevice *_this, SDL_GLContext context)
151{
152 // printf("HAIKU_GL_DestroyContext(%llx), thread = %d\n", (uint64)context, find_thread(NULL));
153 BGLView* glView = (BGLView*)context;
154 SDL_BWin *bwin = (SDL_BWin*)glView->Window();
155 if (!bwin) {
156 delete glView;
157 } else {
158 bwin->RemoveGLView();
159 }
160 return true;
161}
162
163
164bool HAIKU_GL_SetSwapInterval(SDL_VideoDevice *_this, int interval)
165{
166 // TODO: Implement this, if necessary?
167 return SDL_Unsupported();
168}
169
170bool HAIKU_GL_GetSwapInterval(SDL_VideoDevice *_this, int *interval)
171{
172 return SDL_Unsupported();
173}
174
175
176void HAIKU_GL_UnloadLibrary(SDL_VideoDevice *_this)
177{
178 // TODO: Implement this, if necessary?
179}
180
181
182/* FIXME: This function is meant to clear the OpenGL context when the video
183 mode changes (see SDL_bmodes.cc), but it doesn't seem to help, and is not
184 currently in use. */
185void HAIKU_GL_RebootContexts(SDL_VideoDevice *_this)
186{
187 SDL_Window *window = _this->windows;
188 while (window) {
189 SDL_BWin *bwin = _ToBeWin(window);
190 if (bwin->GetGLView()) {
191 bwin->LockLooper();
192 bwin->RemoveGLView();
193 bwin->CreateGLView(bwin->GetGLType());
194 bwin->UnlockLooper();
195 }
196 window = window->next;
197 }
198}
199
200
201#ifdef __cplusplus
202}
203#endif
204
205#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 @@
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#ifndef SDL_BOPENGL_H
23#define SDL_BOPENGL_H
24
25#if defined(SDL_VIDEO_DRIVER_HAIKU) && defined(SDL_VIDEO_OPENGL)
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31#include "../SDL_sysvideo.h"
32
33extern bool HAIKU_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path); // FIXME
34extern SDL_FunctionPointer HAIKU_GL_GetProcAddress(SDL_VideoDevice *_this, const char *proc); // FIXME
35extern void HAIKU_GL_UnloadLibrary(SDL_VideoDevice *_this); // TODO
36extern bool HAIKU_GL_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window,
37 SDL_GLContext context);
38extern bool HAIKU_GL_SetSwapInterval(SDL_VideoDevice *_this, int interval); // TODO
39extern bool HAIKU_GL_GetSwapInterval(SDL_VideoDevice *_this, int *interval); // TODO
40extern bool HAIKU_GL_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window);
41extern SDL_GLContext HAIKU_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window);
42extern bool HAIKU_GL_DestroyContext(SDL_VideoDevice *_this, SDL_GLContext context);
43
44extern void HAIKU_GL_RebootContexts(SDL_VideoDevice *_this);
45
46#ifdef __cplusplus
47}
48#endif
49
50#endif // SDL_VIDEO_DRIVER_HAIKU && SDL_VIDEO_OPENGL
51
52#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 @@
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
31extern "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
46static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
47 return (SDL_BWin *)(window->internal);
48}
49
50static 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
113VideoBootStrap HAIKU_bootstrap = {
114 "haiku", "Haiku graphics",
115 HAIKU_CreateDevice,
116 HAIKU_ShowMessageBox,
117 false
118};
119
120void HAIKU_DeleteDevice(SDL_VideoDevice * device)
121{
122 SDL_free(device->internal);
123 SDL_free(device);
124}
125
126struct SDL_CursorData
127{
128 BCursor *cursor;
129};
130
131static 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
146static 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
182static SDL_Cursor * HAIKU_CreateDefaultCursor()
183{
184 SDL_SystemCursor id = SDL_GetDefaultSystemCursor();
185 return HAIKU_CreateSystemCursor(id);
186}
187
188static 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
199static 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
215static 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
235static 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
258static 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
273bool 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
302void 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.
311extern "C"
312bool 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
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 @@
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#ifndef BVIDEO_H
23#define BVIDEO_H
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29#include "../../core/haiku/SDL_BeApp.h"
30#include "../SDL_sysvideo.h"
31
32extern void HAIKU_VideoQuit(SDL_VideoDevice *_this);
33extern bool HAIKU_VideoInit(SDL_VideoDevice *_this);
34extern void HAIKU_DeleteDevice(SDL_VideoDevice *_this);
35
36#ifdef __cplusplus
37}
38#endif
39
40#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 @@
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#include "SDL_internal.h"
22
23#ifdef SDL_VIDEO_DRIVER_HAIKU
24#include "../SDL_sysvideo.h"
25
26#include "SDL_BWin.h"
27#include <new>
28
29// Define a path to window's BWIN data
30#ifdef __cplusplus
31extern "C" {
32#endif
33
34static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window)
35{
36 return (SDL_BWin *)(window->internal);
37}
38
39static SDL_INLINE SDL_BLooper *_GetBeLooper()
40{
41 return SDL_Looper;
42}
43
44static bool _InitWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props)
45{
46 uint32 flags = 0;
47 window_look look = B_TITLED_WINDOW_LOOK;
48
49 BRect bounds(
50 window->x,
51 window->y,
52 window->x + window->w - 1, //BeWindows have an off-by-one px w/h thing
53 window->y + window->h - 1
54 );
55
56 if (window->flags & SDL_WINDOW_FULLSCREEN) {
57 // TODO: Add support for this flag
58 printf(__FILE__": %d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",__LINE__);
59 }
60 if (window->flags & SDL_WINDOW_OPENGL) {
61 // TODO: Add support for this flag
62 }
63 if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
64 flags |= B_NOT_RESIZABLE | B_NOT_ZOOMABLE;
65 }
66 if (window->flags & SDL_WINDOW_BORDERLESS) {
67 look = B_NO_BORDER_WINDOW_LOOK;
68 }
69
70 SDL_BWin *bwin = new(std::nothrow) SDL_BWin(bounds, look, flags);
71 if (!bwin) {
72 return false;
73 }
74
75 window->internal = (SDL_WindowData *)bwin;
76 int32 winID = _GetBeLooper()->GetID(window);
77 bwin->SetID(winID);
78
79 return true;
80}
81
82bool HAIKU_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props)
83{
84 if (!_InitWindow(_this, window, create_props)) {
85 return false;
86 }
87
88 // Start window loop
89 _ToBeWin(window)->Show();
90 return true;
91}
92
93void HAIKU_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window * window)
94{
95 BMessage msg(BWIN_SET_TITLE);
96 msg.AddString("window-title", window->title);
97 _ToBeWin(window)->PostMessage(&msg);
98}
99
100bool HAIKU_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window * window)
101{
102 BMessage msg(BWIN_MOVE_WINDOW);
103 msg.AddInt32("window-x", window->pending.x);
104 msg.AddInt32("window-y", window->pending.y);
105 _ToBeWin(window)->PostMessage(&msg);
106 return true;
107}
108
109void HAIKU_SetWindowSize(SDL_VideoDevice *_this, SDL_Window * window)
110{
111 BMessage msg(BWIN_RESIZE_WINDOW);
112 msg.AddInt32("window-w", window->pending.w - 1);
113 msg.AddInt32("window-h", window->pending.h - 1);
114 _ToBeWin(window)->PostMessage(&msg);
115}
116
117void HAIKU_SetWindowBordered(SDL_VideoDevice *_this, SDL_Window * window, bool bordered)
118{
119 BMessage msg(BWIN_SET_BORDERED);
120 msg.AddBool("window-border", bordered != false);
121 _ToBeWin(window)->PostMessage(&msg);
122}
123
124void HAIKU_SetWindowResizable(SDL_VideoDevice *_this, SDL_Window * window, bool resizable)
125{
126 BMessage msg(BWIN_SET_RESIZABLE);
127 msg.AddBool("window-resizable", resizable != false);
128 _ToBeWin(window)->PostMessage(&msg);
129}
130
131void HAIKU_ShowWindow(SDL_VideoDevice *_this, SDL_Window * window)
132{
133 BMessage msg(BWIN_SHOW_WINDOW);
134 _ToBeWin(window)->PostMessage(&msg);
135}
136
137void HAIKU_HideWindow(SDL_VideoDevice *_this, SDL_Window * window)
138{
139 BMessage msg(BWIN_HIDE_WINDOW);
140 _ToBeWin(window)->PostMessage(&msg);
141}
142
143void HAIKU_RaiseWindow(SDL_VideoDevice *_this, SDL_Window * window)
144{
145 BMessage msg(BWIN_SHOW_WINDOW); // Activate this window and move to front
146 _ToBeWin(window)->PostMessage(&msg);
147}
148
149void HAIKU_MaximizeWindow(SDL_VideoDevice *_this, SDL_Window * window)
150{
151 BMessage msg(BWIN_MAXIMIZE_WINDOW);
152 _ToBeWin(window)->PostMessage(&msg);
153}
154
155void HAIKU_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window * window)
156{
157 BMessage msg(BWIN_MINIMIZE_WINDOW);
158 _ToBeWin(window)->PostMessage(&msg);
159}
160
161void HAIKU_RestoreWindow(SDL_VideoDevice *_this, SDL_Window * window)
162{
163 BMessage msg(BWIN_RESTORE_WINDOW);
164 _ToBeWin(window)->PostMessage(&msg);
165}
166
167SDL_FullscreenResult HAIKU_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay * display, SDL_FullscreenOp fullscreen)
168{
169 // Haiku tracks all video display information
170 BMessage msg(BWIN_FULLSCREEN);
171 msg.AddBool("fullscreen", !!fullscreen);
172 _ToBeWin(window)->PostMessage(&msg);
173 return SDL_FULLSCREEN_SUCCEEDED;
174}
175
176
177void HAIKU_SetWindowMinimumSize(SDL_VideoDevice *_this, SDL_Window * window)
178{
179 BMessage msg(BWIN_MINIMUM_SIZE_WINDOW);
180 msg.AddInt32("window-w", window->w -1);
181 msg.AddInt32("window-h", window->h -1);
182 _ToBeWin(window)->PostMessage(&msg);
183}
184
185bool HAIKU_SetWindowMouseGrab(SDL_VideoDevice *_this, SDL_Window * window, bool grabbed)
186{
187 // TODO: Implement this!
188 return SDL_Unsupported();
189}
190
191bool HAIKU_SetWindowParent(SDL_VideoDevice *_this, SDL_Window * window, SDL_Window *parent)
192{
193 return true;
194}
195
196bool HAIKU_SetWindowModal(SDL_VideoDevice *_this, SDL_Window *window, bool modal)
197{
198 if (modal) {
199 _ToBeWin(window)->SetLook(B_MODAL_WINDOW_LOOK);
200 _ToBeWin(window)->SetFeel(B_MODAL_SUBSET_WINDOW_FEEL);
201 _ToBeWin(window)->AddToSubset(_ToBeWin(window->parent));
202 } else {
203 window_look look = (window->flags & SDL_WINDOW_BORDERLESS) ? B_NO_BORDER_WINDOW_LOOK : B_TITLED_WINDOW_LOOK;
204 _ToBeWin(window)->RemoveFromSubset(_ToBeWin(window->parent));
205 _ToBeWin(window)->SetLook(look);
206 _ToBeWin(window)->SetFeel(B_NORMAL_WINDOW_FEEL);
207 }
208
209 return true;
210}
211
212void HAIKU_DestroyWindow(SDL_VideoDevice *_this, SDL_Window * window)
213{
214 _ToBeWin(window)->LockLooper(); // This MUST be locked
215 _GetBeLooper()->ClearID(_ToBeWin(window));
216 _ToBeWin(window)->Quit();
217 window->internal = NULL;
218}
219
220#ifdef __cplusplus
221}
222#endif
223
224#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 @@
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#ifndef SDL_BWINDOW_H
23#define SDL_BWINDOW_H
24
25#include "../SDL_sysvideo.h"
26
27extern bool HAIKU_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props);
28extern void HAIKU_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window);
29extern bool HAIKU_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window);
30extern void HAIKU_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window);
31extern void HAIKU_SetWindowMinimumSize(SDL_VideoDevice *_this, SDL_Window *window);
32extern void HAIKU_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window);
33extern void HAIKU_HideWindow(SDL_VideoDevice *_this, SDL_Window *window);
34extern void HAIKU_RaiseWindow(SDL_VideoDevice *_this, SDL_Window *window);
35extern void HAIKU_MaximizeWindow(SDL_VideoDevice *_this, SDL_Window *window);
36extern void HAIKU_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window);
37extern void HAIKU_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window);
38extern void HAIKU_SetWindowBordered(SDL_VideoDevice *_this, SDL_Window *window, bool bordered);
39extern void HAIKU_SetWindowResizable(SDL_VideoDevice *_this, SDL_Window *window, bool resizable);
40extern SDL_FullscreenResult HAIKU_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_FullscreenOp fullscreen);
41extern bool HAIKU_SetWindowMouseGrab(SDL_VideoDevice *_this, SDL_Window *window, bool grabbed);
42extern bool HAIKU_SetWindowParent(SDL_VideoDevice *_this, SDL_Window *window, SDL_Window *parent);
43extern bool HAIKU_SetWindowModal(SDL_VideoDevice *_this, SDL_Window *window, bool modal);
44extern void HAIKU_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window);
45
46#endif