From 9145a1f1a70d80f9cbbf1f905bb4a86696de1e9a Mon Sep 17 00:00:00 2001 From: Jerome Duval Date: Fri, 29 Aug 2014 15:24:11 +0000 Subject: haiku patch diff --git a/src/video/haiku/SDL_bopengl.cc b/src/video/haiku/SDL_bopengl.cc index e599062..3b145a3 100644 --- a/src/video/haiku/SDL_bopengl.cc +++ b/src/video/haiku/SDL_bopengl.cc @@ -54,7 +54,7 @@ int HAIKU_GL_LoadLibrary(_THIS, const char *path) if( get_image_symbol(info.id, "glBegin", B_SYMBOL_TYPE_ANY, &location) == B_OK) { - _this->gl_config.dll_handle = (void *) (size_t) info.id; + _this->gl_config.dll_handle = (void *) (addr_t) info.id; _this->gl_config.driver_loaded = 1; SDL_strlcpy(_this->gl_config.driver_path, "libGL.so", SDL_arraysize(_this->gl_config.driver_path)); @@ -69,7 +69,7 @@ void *HAIKU_GL_GetProcAddress(_THIS, const char *proc) void *location = NULL; status_t err; if ((err = - get_image_symbol((image_id) (size_t) _this->gl_config.dll_handle, + get_image_symbol((image_id) (addr_t) _this->gl_config.dll_handle, proc, B_SYMBOL_TYPE_ANY, &location)) == B_OK) { return location; -- 2.19.1 From 313046cb8e582cd1485589302f7f469766592aca Mon Sep 17 00:00:00 2001 From: Jerome Duval Date: Thu, 25 Feb 2016 20:23:41 +0000 Subject: remove nacl, missing templates on Haiku diff --git a/configure.in b/configure.in index ae866ff..57afa1f 100644 --- a/configure.in +++ b/configure.in @@ -1551,33 +1551,6 @@ AC_HELP_STRING([--enable-mir-shared], [dynamically load Mir support [[default=ma fi } -dnl Check for Native Client stuff -CheckNativeClient() -{ - AC_TRY_COMPILE([ - #if !defined(__native_client__) - #error "NO NACL" - #endif - ],[ - ],[ - AC_DEFINE(SDL_VIDEO_DRIVER_NACL, 1, [ ]) - AC_DEFINE(SDL_AUDIO_DRIVER_NACL, 1, [ ]) - AC_DEFINE(HAVE_POW, 1, [ ]) - AC_DEFINE(HAVE_OPENGLES2, 1, [ ]) - AC_DEFINE(SDL_VIDEO_OPENGL_ES2, 1, [ ]) - AC_DEFINE(SDL_VIDEO_RENDER_OGL_ES2, 1, [ ]) - - SDL_LIBS="-lppapi_simple -lppapi_gles2 $SDL_LIBS" - - SDLMAIN_SOURCES="$srcdir/src/main/nacl/*.c" - SOURCES="$SOURCES $srcdir/src/audio/nacl/*.c" - SUMMARY_audio="${SUMMARY_audio} nacl" - SOURCES="$SOURCES $srcdir/src/video/nacl/*.c" - SUMMARY_video="${SUMMARY_video} nacl opengles2" - ]) -} - - CheckRPI() { AC_ARG_ENABLE(video-rpi, -- 2.19.1 From 69d3ffdec32e5fd06126102298d0bdc3c82912f9 Mon Sep 17 00:00:00 2001 From: Jerome Duval Date: Sat, 30 Sep 2017 13:36:12 +0200 Subject: fix AC_DEFINE diff --git a/configure.in b/configure.in index 57afa1f..4c87ce0 100644 --- a/configure.in +++ b/configure.in @@ -1854,7 +1854,7 @@ int event_type = XI_TouchBegin; XITouchClassInfo *t; ],[ have_xinput2_multitouch=yes - AC_DEFINE([SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH], 1, []) + AC_DEFINE([SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH], [], [Description]) SUMMARY_video_x11="${SUMMARY_video_x11} xinput2_multitouch" ]) AC_MSG_RESULT($have_xinput2_multitouch) -- 2.19.1 From 5a8b19e6e594ce29fd579c4554a32f4628ffb7b7 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Fri, 2 Feb 2018 09:40:46 +0100 Subject: Fix secondary arch build. Rather than trying to guess the name of libstdc++, run libtool in C++ mode so it figures this out by itself. The previous way of detecting libstdc++ would not allow for building a secondary architecture package. diff --git a/Makefile.in b/Makefile.in index 4eb6e63..85162c6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -144,13 +144,13 @@ update-revision: .PHONY: all update-revision install install-bin install-hdrs install-lib install-data uninstall uninstall-bin uninstall-hdrs uninstall-lib uninstall-data clean distclean dist $(OBJECTS:.lo=.d) $(objects)/$(TARGET): $(GEN_HEADERS) $(GEN_OBJECTS) $(OBJECTS) $(VERSION_OBJECTS) - $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ $(OBJECTS) $(GEN_OBJECTS) $(VERSION_OBJECTS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LT_LDFLAGS) + $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=CXX --mode=link $(CXX) -o $@ $(OBJECTS) $(GEN_OBJECTS) $(VERSION_OBJECTS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LT_LDFLAGS) $(objects)/$(SDLMAIN_TARGET): $(SDLMAIN_OBJECTS) - $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=CC --mode=link $(CC) -static -o $@ $(SDLMAIN_OBJECTS) -rpath $(libdir) + $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=CXX --mode=link $(CXX) -static -o $@ $(SDLMAIN_OBJECTS) -rpath $(libdir) $(objects)/$(SDLTEST_TARGET): $(SDLTEST_OBJECTS) - $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=CC --mode=link $(CC) -static -o $@ $(SDLTEST_OBJECTS) -rpath $(libdir) + $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=CXX --mode=link $(CXX) -static -o $@ $(SDLTEST_OBJECTS) -rpath $(libdir) install: all install-bin install-hdrs install-lib install-data install-bin: diff --git a/configure.in b/configure.in index 4c87ce0..7dd7cd8 100644 --- a/configure.in +++ b/configure.in @@ -3733,9 +3733,6 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau # The Haiku platform requires special setup. SOURCES="$srcdir/src/main/haiku/*.cc $SOURCES" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lroot -lbe -lmedia -lgame -ldevice -ltextencoding" - # Haiku's x86 spins use libstdc++.r4.so (for binary compat?), but - # other spins, like x86-64, use a more standard "libstdc++.so.*" - AC_CHECK_FILE("/boot/system/lib/libstdc++.r4.so", EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lstdc++.r4", EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lstdc++") ;; arm*-apple-darwin*|*-ios-*) ARCH=ios -- 2.19.1 From b56132ee7db02db18db43eeedc53892cdc89583e Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Fri, 2 Feb 2018 10:40:00 +0100 Subject: Fix crash when opening window - _num_clips was not set in constructor, so a NULL _clips could be mistakenly dereferenced. - As _clips is accessible outside the class, it is not a good idea to free/reallocate it. Try to limit this by reallocating only when it needs to grow. diff --git a/src/video/haiku/SDL_BWin.h b/src/video/haiku/SDL_BWin.h index b22f74b..7cb2de9 100644 --- a/src/video/haiku/SDL_BWin.h +++ b/src/video/haiku/SDL_BWin.h @@ -86,6 +86,7 @@ class SDL_BWin:public BDirectWindow _buffer_locker = new BLocker(); _bitmap = NULL; _clips = NULL; + _num_clips = 0; #ifdef DRAWTHREAD _draw_thread_id = spawn_thread(HAIKU_DrawThread, "drawing_thread", @@ -179,13 +180,17 @@ class SDL_BWin:public BDirectWindow _connected = true; case B_DIRECT_MODIFY: - if(_clips) { - free(_clips); - _clips = NULL; + if (info->clip_list_count > _num_clips) + { + if(_clips) { + free(_clips); + _clips = NULL; + } } _num_clips = info->clip_list_count; - _clips = (clipping_rect *)malloc(_num_clips*sizeof(clipping_rect)); + if (_clips == NULL) + _clips = (clipping_rect *)malloc(_num_clips*sizeof(clipping_rect)); if(_clips) { memcpy(_clips, info->clip_list, _num_clips*sizeof(clipping_rect)); @@ -652,7 +657,7 @@ private: clipping_rect _bounds; BLocker *_buffer_locker; clipping_rect *_clips; - int32 _num_clips; + uint32 _num_clips; int32 _bytes_per_px; thread_id _draw_thread_id; -- 2.19.1 From e1745294f598df356ba81e4a4471367a7425876a Mon Sep 17 00:00:00 2001 From: Gerasim Troeglazov <3dEyes@gmail.com> Date: Sat, 15 Sep 2018 23:16:25 +1000 Subject: Add simple relative mode for mouse diff --git a/src/main/haiku/SDL_BApp.h b/src/main/haiku/SDL_BApp.h index 7adbd00..786a57e 100644 --- a/src/main/haiku/SDL_BApp.h +++ b/src/main/haiku/SDL_BApp.h @@ -230,6 +230,21 @@ private: win = GetSDLWindow(winID); SDL_SendMouseMotion(win, 0, 0, x, y); + // Simple relative mode support for mouse. + if ((SDL_GetMouse()->relative_mode || + (win->flags & SDL_WINDOW_INPUT_GRABBED)) && + (win->flags & SDL_WINDOW_INPUT_FOCUS)) { + int winWidth, winHeight, winPosX, winPosY; + SDL_GetWindowSize(win, &winWidth, &winHeight); + SDL_GetWindowPosition(win, &winPosX, &winPosY); + set_mouse_position((winPosX + winWidth / 2), (winPosY + winHeight / 2)); + if (!be_app->IsCursorHidden()) + be_app->HideCursor(); + } else { + if (be_app->IsCursorHidden()) + be_app->ShowCursor(); + } + /* Tell the application that the mouse passed over, redraw needed */ HAIKU_UpdateWindowFramebuffer(NULL,win,NULL,-1); } -- 2.19.1 From 9e78031698012e2ef19a1a935972f8048b6297de Mon Sep 17 00:00:00 2001 From: Gerasim Troeglazov <3dEyes@gmail.com> Date: Tue, 18 Sep 2018 20:47:07 +1000 Subject: Add support for relative mouse mode diff --git a/src/main/haiku/SDL_BApp.h b/src/main/haiku/SDL_BApp.h index 786a57e..07f33f6 100644 --- a/src/main/haiku/SDL_BApp.h +++ b/src/main/haiku/SDL_BApp.h @@ -228,7 +228,6 @@ private: return; } win = GetSDLWindow(winID); - SDL_SendMouseMotion(win, 0, 0, x, y); // Simple relative mode support for mouse. if ((SDL_GetMouse()->relative_mode || @@ -237,10 +236,14 @@ private: int winWidth, winHeight, winPosX, winPosY; SDL_GetWindowSize(win, &winWidth, &winHeight); SDL_GetWindowPosition(win, &winPosX, &winPosY); + int dx = x - (winWidth / 2); + int dy = y - (winHeight / 2); + SDL_SendMouseMotion(win, 0, SDL_GetMouse()->relative_mode, dx, dy); set_mouse_position((winPosX + winWidth / 2), (winPosY + winHeight / 2)); if (!be_app->IsCursorHidden()) be_app->HideCursor(); } else { + SDL_SendMouseMotion(win, 0, 0, x, y); if (be_app->IsCursorHidden()) be_app->ShowCursor(); } diff --git a/src/video/haiku/SDL_BWin.h b/src/video/haiku/SDL_BWin.h index 7cb2de9..fa945a5 100644 --- a/src/video/haiku/SDL_BWin.h +++ b/src/video/haiku/SDL_BWin.h @@ -319,22 +319,17 @@ class SDL_BWin:public BDirectWindow && msg->FindInt32("be:transit", &transit) == B_OK) { _MouseMotionEvent(where, transit); } + break; - /* FIXME: Apparently a button press/release event might be dropped - if made before before a different button is released. Does - B_MOUSE_MOVED have the data needed to check if a mouse button - state has changed? */ + case B_MOUSE_DOWN: if (msg->FindInt32("buttons", &buttons) == B_OK) { - _MouseButtonEvent(buttons); + _MouseButtonEvent(buttons, SDL_PRESSED); } break; - case B_MOUSE_DOWN: case B_MOUSE_UP: - /* _MouseButtonEvent() detects any and all buttons that may have - changed state, as well as that button's new state */ if (msg->FindInt32("buttons", &buttons) == B_OK) { - _MouseButtonEvent(buttons); + _MouseButtonEvent(buttons, SDL_RELEASED); } break; @@ -497,26 +492,17 @@ private: if true: SDL_SetCursor(NULL); */ } - void _MouseButtonEvent(int32 buttons) { + void _MouseButtonEvent(int32 buttons, Uint8 state) { int32 buttonStateChange = buttons ^ _last_buttons; - /* Make sure at least one button has changed state */ - if( !(buttonStateChange) ) { - return; - } - - /* Add any mouse button events */ if(buttonStateChange & B_PRIMARY_MOUSE_BUTTON) { - _SendMouseButton(SDL_BUTTON_LEFT, buttons & - B_PRIMARY_MOUSE_BUTTON); + _SendMouseButton(SDL_BUTTON_LEFT, state); } if(buttonStateChange & B_SECONDARY_MOUSE_BUTTON) { - _SendMouseButton(SDL_BUTTON_RIGHT, buttons & - B_PRIMARY_MOUSE_BUTTON); + _SendMouseButton(SDL_BUTTON_RIGHT, state); } if(buttonStateChange & B_TERTIARY_MOUSE_BUTTON) { - _SendMouseButton(SDL_BUTTON_MIDDLE, buttons & - B_PRIMARY_MOUSE_BUTTON); + _SendMouseButton(SDL_BUTTON_MIDDLE, state); } _last_buttons = buttons; -- 2.19.1 From 022d289781c1a582ff6a732ce521b741aba62a42 Mon Sep 17 00:00:00 2001 From: Peter Kosyh Date: Sat, 6 Oct 2018 12:48:15 +0300 Subject: haiku: mouse->ShowMouse method added diff --git a/src/main/haiku/SDL_BApp.h b/src/main/haiku/SDL_BApp.h index 07f33f6..f86ba9a 100644 --- a/src/main/haiku/SDL_BApp.h +++ b/src/main/haiku/SDL_BApp.h @@ -244,7 +244,7 @@ private: be_app->HideCursor(); } else { SDL_SendMouseMotion(win, 0, 0, x, y); - if (be_app->IsCursorHidden()) + if (SDL_ShowCursor(-1) && be_app->IsCursorHidden()) be_app->ShowCursor(); } diff --git a/src/video/haiku/SDL_bvideo.cc b/src/video/haiku/SDL_bvideo.cc index e7b4b6e..747f7d4 100644 --- a/src/video/haiku/SDL_bvideo.cc +++ b/src/video/haiku/SDL_bvideo.cc @@ -19,6 +19,7 @@ 3. This notice may not be removed or altered from any source distribution. */ #include "../../SDL_internal.h" +#include "../../main/haiku/SDL_BApp.h" #if SDL_VIDEO_DRIVER_HAIKU @@ -132,6 +133,33 @@ void HAIKU_DeleteDevice(SDL_VideoDevice * device) SDL_free(device); } +static int HAIKU_ShowCursor(SDL_Cursor *cur) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + int show; + if (!mouse) + return 0; + show = (cur || !mouse->focus); + if (show) { + if (be_app->IsCursorHidden()) + be_app->ShowCursor(); + } else { + if (!be_app->IsCursorHidden()) + be_app->HideCursor(); + } + return 0; +} + +static void HAIKU_MouseInit(_THIS) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + if (!mouse) + return; + mouse->ShowCursor = HAIKU_ShowCursor; + mouse->cur_cursor = (SDL_Cursor*)0x1; + mouse->def_cursor = (SDL_Cursor*)0x2; +} + int HAIKU_VideoInit(_THIS) { /* Initialize the Be Application for appserver interaction */ @@ -145,6 +173,8 @@ int HAIKU_VideoInit(_THIS) /* Init the keymap */ HAIKU_InitOSKeymap(); + HAIKU_MouseInit(_this); + #if SDL_VIDEO_OPENGL /* testgl application doesn't load library, just tries to load symbols */ /* is it correct? if so we have to load library here */ -- 2.19.1 From b4513263389947c11b17f264a241803e3c5a4a6e Mon Sep 17 00:00:00 2001 From: Peter Kosyh Date: Sat, 6 Oct 2018 13:50:30 +0300 Subject: mouse_relative fix diff --git a/src/main/haiku/SDL_BApp.h b/src/main/haiku/SDL_BApp.h index f86ba9a..1e7a8b5 100644 --- a/src/main/haiku/SDL_BApp.h +++ b/src/main/haiku/SDL_BApp.h @@ -230,9 +230,7 @@ private: win = GetSDLWindow(winID); // Simple relative mode support for mouse. - if ((SDL_GetMouse()->relative_mode || - (win->flags & SDL_WINDOW_INPUT_GRABBED)) && - (win->flags & SDL_WINDOW_INPUT_FOCUS)) { + if (SDL_GetMouse()->relative_mode) { int winWidth, winHeight, winPosX, winPosY; SDL_GetWindowSize(win, &winWidth, &winHeight); SDL_GetWindowPosition(win, &winPosX, &winPosY); -- 2.19.1 From 72367442fc2d13b6727cadf8d0a7d221a55c49d0 Mon Sep 17 00:00:00 2001 From: Peter Kosyh Date: Sat, 6 Oct 2018 14:28:41 +0300 Subject: mouse wheel y invert diff --git a/src/main/haiku/SDL_BApp.h b/src/main/haiku/SDL_BApp.h index 1e7a8b5..3fe4bb0 100644 --- a/src/main/haiku/SDL_BApp.h +++ b/src/main/haiku/SDL_BApp.h @@ -277,7 +277,7 @@ private: return; } win = GetSDLWindow(winID); - SDL_SendMouseWheel(win, 0, xTicks, yTicks, SDL_MOUSEWHEEL_NORMAL); + SDL_SendMouseWheel(win, 0, xTicks, -yTicks, SDL_MOUSEWHEEL_NORMAL); } void _HandleKey(BMessage *msg) { -- 2.19.1 From faefae6437eaa7e9bae17a117d7453126fa1e136 Mon Sep 17 00:00:00 2001 From: Gerasim Troeglazov <3dEyes@gmail.com> Date: Mon, 5 Nov 2018 23:25:54 +1000 Subject: Disable pointer history diff --git a/src/video/haiku/SDL_BWin.h b/src/video/haiku/SDL_BWin.h index fa945a5..9bcfa66 100644 --- a/src/video/haiku/SDL_BWin.h +++ b/src/video/haiku/SDL_BWin.h @@ -140,6 +140,7 @@ class SDL_BWin:public BDirectWindow _gl_type = gl_flags; } AddChild(_SDL_GLView); + _SDL_GLView->SetEventMask(B_POINTER_EVENTS | B_KEYBOARD_EVENTS, B_NO_POINTER_HISTORY); _SDL_GLView->EnableDirectMode(true); _SDL_GLView->LockGL(); /* "New" GLViews are created */ Unlock(); -- 2.19.1 From 3c12c62dbeea984063c2ecb3153dcef3977d1855 Mon Sep 17 00:00:00 2001 From: EXL Date: Wed, 5 Dec 2018 07:02:11 +0000 Subject: Implement message box for Haiku Add implementation for functions: SDL_ShowSimpleMessageBox() SDL_ShowMessageBox() Add simple customization support also. Fix build for x86_gcc2. diff --git a/include/SDL_syswm.h b/include/SDL_syswm.h index f1c4021..384753c 100644 --- a/include/SDL_syswm.h +++ b/include/SDL_syswm.h @@ -126,7 +126,8 @@ typedef enum SDL_SYSWM_WINRT, SDL_SYSWM_ANDROID, SDL_SYSWM_VIVANTE, - SDL_SYSWM_OS2 + SDL_SYSWM_OS2, + SDL_SYSWM_HAIKU } SDL_SYSWM_TYPE; /** diff --git a/src/main/haiku/SDL_BeApp.cc b/src/main/haiku/SDL_BeApp.cc index cbd2129..5c06744 100644 --- a/src/main/haiku/SDL_BeApp.cc +++ b/src/main/haiku/SDL_BeApp.cc @@ -48,13 +48,14 @@ extern "C" { static int SDL_BeAppActive = 0; static SDL_Thread *SDL_AppThread = NULL; +/* Default application signature */ +const char *signature = "application/x-SDL-executable"; + static int StartBeApp(void *unused) { BApplication *App; - // default application signature - const char *signature = "application/x-SDL-executable"; // dig resources for correct signature image_info info; int32 cookie = 0; diff --git a/src/main/haiku/SDL_BeApp.h b/src/main/haiku/SDL_BeApp.h index 83a2beb..7d5e569 100644 --- a/src/main/haiku/SDL_BeApp.h +++ b/src/main/haiku/SDL_BeApp.h @@ -31,6 +31,9 @@ extern int SDL_InitBeApp(void); /* Quit the Be Application, if there's nothing left to do */ extern void SDL_QuitBeApp(void); +/* Be Application Signature*/ +extern const char *signature; + /* vi: set ts=4 sw=4 expandtab: */ #ifdef __cplusplus diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 336fdaa..290cfef 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -3818,9 +3818,12 @@ SDL_IsScreenKeyboardShown(SDL_Window *window) #if SDL_VIDEO_DRIVER_X11 #include "x11/SDL_x11messagebox.h" #endif +#if SDL_VIDEO_DRIVER_HAIKU +#include "haiku/SDL_bmessagebox.h" +#endif -#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT || SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT || SDL_VIDEO_DRIVER_X11 +#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT || SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT || SDL_VIDEO_DRIVER_X11 || SDL_VIDEO_DRIVER_HAIKU static SDL_bool SDL_MessageboxValidForDriver(const SDL_MessageBoxData *messageboxdata, SDL_SYSWM_TYPE drivertype) { SDL_SysWMinfo info; @@ -3912,6 +3915,13 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) X11_ShowMessageBox(messageboxdata, buttonid) == 0) { retval = 0; } +#endif +#if SDL_VIDEO_DRIVER_HAIKU + if (retval == -1 && + SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_HAIKU) && + BE_ShowMessageBox(messageboxdata, buttonid) == 0) { + retval = 0; + } #endif if (retval == -1) { SDL_SetError("No message system available"); diff --git a/src/video/haiku/SDL_bmessagebox.cc b/src/video/haiku/SDL_bmessagebox.cc new file mode 100644 index 0000000..9b9fe14 --- /dev/null +++ b/src/video/haiku/SDL_bmessagebox.cc @@ -0,0 +1,425 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga + Copyright (C) 2018 EXL + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_HAIKU + +#include "SDL_messagebox.h" + +/* For application signature. */ +#include "../../main/haiku/SDL_BeApp.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +enum +{ + G_CLOSE_BUTTON_ID = -1, + G_DEFAULT_BUTTON_ID = 0, + G_MAX_STRING_LENGTH_BYTES = 120 +}; + +class BE_SDL_MessageBox : public BAlert +{ + float fComputedMessageBoxWidth; + + BTextView *fMessageBoxTextView; + + int fCloseButton; + int fDefaultButton; + + bool fCustomColorScheme; + bool fThereIsLongLine; + rgb_color fTextColor; + + const char *fTitle; + const char *BE_SDL_DefTitle; + const char *BE_SDL_DefMessage; + const char *BE_SDL_DefButton; + + std::vector fButtons; + + static bool + SortButtonsPredicate(const SDL_MessageBoxButtonData *aButtonLeft, + const SDL_MessageBoxButtonData *aButtonRight) + { + return aButtonLeft->buttonid < aButtonRight->buttonid; + } + + alert_type + ConvertMessageBoxType(const SDL_MessageBoxFlags aWindowType) const + { + switch (aWindowType) + { + default: + case SDL_MESSAGEBOX_WARNING: + { + return B_WARNING_ALERT; + } + case SDL_MESSAGEBOX_ERROR: + { + return B_STOP_ALERT; + } + case SDL_MESSAGEBOX_INFORMATION: + { + return B_INFO_ALERT; + } + } + } + + rgb_color + ConvertColorType(const SDL_MessageBoxColor *aColor) const + { + rgb_color color = { aColor->r, aColor->g, aColor->b, color.alpha = 255 }; + return color; + } + + int32 + GetLeftPanelWidth(void) const + { + // See file "haiku/src/kits/interface/Alert.cpp" for this magic numbers. + // IconStripeWidth = 30 * Scale + // IconSize = 32 * Scale + // Scale = max_c(1, ((int32)be_plain_font->Size() + 15) / 16) + // RealWidth = (IconStripeWidth * Scale) + (IconSize * Scale) + + int32 scale = max_c(1, ((int32)be_plain_font->Size() + 15) / 16); + return (30 * scale) + (32 * scale); + } + + void + UpdateTextViewWidth(void) + { + fComputedMessageBoxWidth = fMessageBoxTextView->PreferredSize().Width() + GetLeftPanelWidth(); + } + + void + ParseSdlMessageBoxData(const SDL_MessageBoxData *aMessageBoxData) + { + if (aMessageBoxData == NULL) + { + SetTitle(BE_SDL_DefTitle); + SetMessageText(BE_SDL_DefMessage); + AddButton(BE_SDL_DefButton); + return; + } + + if (aMessageBoxData->numbuttons <= 0) + { + AddButton(BE_SDL_DefButton); + } + else + { + AddSdlButtons(aMessageBoxData->buttons, aMessageBoxData->numbuttons); + } + + if (aMessageBoxData->colorScheme != NULL) + { + fCustomColorScheme = true; + ApplyAndParseColorScheme(aMessageBoxData->colorScheme); + } + + (aMessageBoxData->title != NULL) ? + SetTitle(aMessageBoxData->title) : SetTitle(BE_SDL_DefTitle); + (aMessageBoxData->message != NULL) ? + SetMessageText(aMessageBoxData->message) : SetMessageText(BE_SDL_DefMessage); + + SetType(ConvertMessageBoxType(static_cast(aMessageBoxData->flags))); + } + + void + ApplyAndParseColorScheme(const SDL_MessageBoxColorScheme *aColorScheme) + { + SetBackgroundColor(&aColorScheme->colors[SDL_MESSAGEBOX_COLOR_BACKGROUND]); + fTextColor = ConvertColorType(&aColorScheme->colors[SDL_MESSAGEBOX_COLOR_TEXT]); + SetButtonColors(&aColorScheme->colors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER], + &aColorScheme->colors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND], + &aColorScheme->colors[SDL_MESSAGEBOX_COLOR_TEXT], + &aColorScheme->colors[SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED]); + } + + void + SetButtonColors(const SDL_MessageBoxColor *aBorderColor, + const SDL_MessageBoxColor *aBackgroundColor, + const SDL_MessageBoxColor *aTextColor, + const SDL_MessageBoxColor *aSelectedColor) + { + if (fCustomColorScheme) + { + int32 countButtons = CountButtons(); + for (int i = 0; i < countButtons; ++i) + { + ButtonAt(i)->SetViewColor(ConvertColorType(aBorderColor)); + ButtonAt(i)->SetLowColor(ConvertColorType(aBackgroundColor)); + + // This doesn't work. See this why: + // https://github.com/haiku/haiku/commit/de9c53f8f5008c7b3b0af75d944a628e17f6dffe + // Let it remain. + ButtonAt(i)->SetHighColor(ConvertColorType(aTextColor)); + } + } + // TODO: Not Implemented. + // Is it even necessary?! + (void)aSelectedColor; + } + + void + SetBackgroundColor(const SDL_MessageBoxColor *aColor) + { + rgb_color background = ConvertColorType(aColor); + + GetLayout()->View()->SetViewColor(background); + // See file "haiku/src/kits/interface/Alert.cpp", the "TAlertView" is the internal name of the left panel. + FindView("TAlertView")->SetViewColor(background); + fMessageBoxTextView->SetViewColor(background); + } + + bool + CheckLongLines(const char *aMessage) + { + int final = 0; + + // This UTF-8 friendly. + BString message = aMessage; + int32 length = message.CountChars(); + + for (int i = 0, c = 0; i < length; ++i) + { + c++; + if (*(message.CharAt(i)) == '\n') + { + c = 0; + } + if (c > final) + { + final = c; + } + } + + return (final > G_MAX_STRING_LENGTH_BYTES); + } + + void + SetMessageText(const char *aMessage) + { + fThereIsLongLine = CheckLongLines(aMessage); + if (fThereIsLongLine) + { + fMessageBoxTextView->SetWordWrap(true); + } + + rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR); + if (fCustomColorScheme) + { + textColor = fTextColor; + } + + /* + if (fNoTitledWindow) + { + fMessageBoxTextView->SetFontAndColor(be_bold_font); + fMessageBoxTextView->Insert(fTitle); + fMessageBoxTextView->Insert("\n\n"); + fMessageBoxTextView->SetFontAndColor(be_plain_font); + } + */ + + fMessageBoxTextView->SetFontAndColor(be_plain_font, B_FONT_ALL, &textColor); + fMessageBoxTextView->Insert(aMessage); + + // Be sure to call update width method. + UpdateTextViewWidth(); + } + + void + AddSdlButtons(const SDL_MessageBoxButtonData *aButtons, int aNumButtons) + { + for (int i = 0; i < aNumButtons; ++i) + { + fButtons.push_back(&aButtons[i]); + } + + std::sort(fButtons.begin(), fButtons.end(), &BE_SDL_MessageBox::SortButtonsPredicate); + + size_t countButtons = fButtons.size(); + for (size_t i = 0; i < countButtons; ++i) + { + switch (fButtons[i]->flags) + { + case SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT: + { + fCloseButton = static_cast(i); + break; + } + case SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT: + { + fDefaultButton = static_cast(i); + break; + } + default: + { + break; + } + } + AddButton(fButtons[i]->text); + } + + SetDefaultButton(ButtonAt(fDefaultButton)); + } + +public: + explicit + BE_SDL_MessageBox(const SDL_MessageBoxData *aMessageBoxData) + : BAlert(NULL, NULL, NULL, NULL, NULL, B_WIDTH_FROM_LABEL, B_WARNING_ALERT), + fComputedMessageBoxWidth(0.0f), + fCloseButton(G_CLOSE_BUTTON_ID), fDefaultButton(G_DEFAULT_BUTTON_ID), + fCustomColorScheme(false), fThereIsLongLine(false), + BE_SDL_DefTitle("SDL2 MessageBox"), + BE_SDL_DefMessage("Some information has been lost."), + BE_SDL_DefButton("OK") + { + // MessageBox settings. + // We need a title to display it. + SetLook(B_TITLED_WINDOW_LOOK); + SetFlags(Flags() | B_CLOSE_ON_ESCAPE); + + // MessageBox TextView settings. + fMessageBoxTextView = TextView(); + fMessageBoxTextView->SetWordWrap(false); + fMessageBoxTextView->SetStylable(true); + + ParseSdlMessageBoxData(aMessageBoxData); + } + + int + GetCloseButtonId(void) const + { + return fCloseButton; + } + + virtual + ~BE_SDL_MessageBox(void) + { + fButtons.clear(); + } + +protected: + virtual void + FrameResized(float aNewWidth, float aNewHeight) + { + if (fComputedMessageBoxWidth > aNewWidth) + { + ResizeTo(fComputedMessageBoxWidth, aNewHeight); + } + else + { + BAlert::FrameResized(aNewWidth, aNewHeight); + } + } + + virtual void + SetTitle(const char* aTitle) + { + fTitle = aTitle; + BAlert::SetTitle(aTitle); + } +}; + +#ifdef __cplusplus +extern "C" { +#endif + +int +BE_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +{ + // Initialize button by closed or error value first. + *buttonid = G_CLOSE_BUTTON_ID; + + // We need to check "be_app" pointer to "NULL". The "messageboxdata->window" pointer isn't appropriate here + // because it is possible to create a MessageBox from another thread. This fixes the following errors: + // "You need a valid BApplication object before interacting with the app_server." + // "2 BApplication objects were created. Only one is allowed." + BApplication *application = NULL; + if (be_app == NULL) + { + application = new(std::nothrow) BApplication(signature); + if (application == NULL) + { + return SDL_SetError("Cannot create the BApplication object. Lack of memory?"); + } + } + + BE_SDL_MessageBox *SDL_MessageBox = new(std::nothrow) BE_SDL_MessageBox(messageboxdata); + if (SDL_MessageBox == NULL) + { + return SDL_SetError("Cannot create the BE_SDL_MessageBox (BAlert inheritor) object. Lack of memory?"); + } + const int closeButton = SDL_MessageBox->GetCloseButtonId(); + int pushedButton = SDL_MessageBox->Go(); + + // The close button is equivalent to pressing Escape. + if (closeButton != G_CLOSE_BUTTON_ID && pushedButton == G_CLOSE_BUTTON_ID) + { + pushedButton = closeButton; + } + + // It's deleted by itself after the "Go()" method was executed. + /* + if (messageBox != NULL) + { + delete messageBox; + } + */ + if (application != NULL) + { + delete application; + } + + // Initialize button by real pushed value then. + *buttonid = pushedButton; + + return 0; +} + +#ifdef __cplusplus +} +#endif + +#endif /* SDL_VIDEO_DRIVER_HAIKU */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/haiku/SDL_bmessagebox.h b/src/video/haiku/SDL_bmessagebox.h new file mode 100644 index 0000000..4f35cda --- /dev/null +++ b/src/video/haiku/SDL_bmessagebox.h @@ -0,0 +1,45 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2018 Sam Lantinga + Copyright (C) 2018 EXL + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_BMESSAGEBOX_H +#define SDL_BMESSAGEBOX_H + +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_HAIKU + +#ifdef __cplusplus +extern "C" { +#endif + +extern int +BE_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); + +#ifdef __cplusplus +} +#endif + +#endif /* SDL_VIDEO_DRIVER_HAIKU */ + +#endif + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/haiku/SDL_bwindow.cc b/src/video/haiku/SDL_bwindow.cc index 142a3fa..462608b 100644 --- a/src/video/haiku/SDL_bwindow.cc +++ b/src/video/haiku/SDL_bwindow.cc @@ -26,6 +26,8 @@ #include "SDL_BWin.h" #include +#include "SDL_syswm.h" + /* Define a path to window's BWIN data */ #ifdef __cplusplus extern "C" { @@ -217,7 +219,15 @@ void HAIKU_DestroyWindow(_THIS, SDL_Window * window) { SDL_bool HAIKU_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) { /* FIXME: What is the point of this? What information should be included? */ - return SDL_FALSE; + if (info->version.major == SDL_MAJOR_VERSION && + info->version.minor == SDL_MINOR_VERSION) { + info->subsystem = SDL_SYSWM_HAIKU; + return SDL_TRUE; + } else { + SDL_SetError("Application not compiled with SDL %d.%d", + SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + return SDL_FALSE; + } } -- 2.19.1