Merge commit 'dec0d4ec4153bf9fc2b78ae6c2df45b6ea8dde7a' as 'external/sdl/SDL'

This commit is contained in:
2023-07-25 22:27:55 +02:00
1663 changed files with 627495 additions and 0 deletions

View File

@@ -0,0 +1,425 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
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_BAPP_H
#define SDL_BAPP_H
#include <Path.h>
#include <InterfaceKit.h>
#include <LocaleRoster.h>
#ifdef SDL_VIDEO_OPENGL
#include <OpenGLKit.h>
#endif
#include "../../video/haiku/SDL_bkeyboard.h"
#ifdef __cplusplus
extern "C" {
#endif
#include "SDL_internal.h"
/* Local includes */
#include "../../events/SDL_events_c.h"
#include "../../video/haiku/SDL_bframebuffer.h"
#ifdef __cplusplus
}
#endif
#include <vector>
/* Forward declarations */
class SDL_BLooper;
class SDL_BWin;
/* Message constants */
enum ToSDL
{
/* Intercepted by BWindow on its way to BView */
BAPP_MOUSE_MOVED,
BAPP_MOUSE_BUTTON,
BAPP_MOUSE_WHEEL,
BAPP_KEY,
BAPP_REPAINT, /* from _UPDATE_ */
/* From BWindow */
BAPP_MAXIMIZE, /* from B_ZOOM */
BAPP_MINIMIZE,
BAPP_RESTORE, /* TODO: IMPLEMENT! */
BAPP_SHOW,
BAPP_HIDE,
BAPP_MOUSE_FOCUS, /* caused by MOUSE_MOVE */
BAPP_KEYBOARD_FOCUS, /* from WINDOW_ACTIVATED */
BAPP_WINDOW_CLOSE_REQUESTED,
BAPP_WINDOW_MOVED,
BAPP_WINDOW_RESIZED,
BAPP_SCREEN_CHANGED
};
extern "C" SDL_BLooper *SDL_Looper;
/* Create a descendant of BLooper */
class SDL_BLooper : public BLooper
{
public:
SDL_BLooper(const char* name) : BLooper(name)
{
#ifdef SDL_VIDEO_OPENGL
_current_context = NULL;
#endif
}
virtual ~SDL_BLooper()
{
}
/* Event-handling functions */
virtual void MessageReceived(BMessage *message)
{
/* Sort out SDL-related messages */
switch (message->what) {
case BAPP_MOUSE_MOVED:
_HandleMouseMove(message);
break;
case BAPP_MOUSE_BUTTON:
_HandleMouseButton(message);
break;
case BAPP_MOUSE_WHEEL:
_HandleMouseWheel(message);
break;
case BAPP_KEY:
_HandleKey(message);
break;
case BAPP_REPAINT:
_HandleBasicWindowEvent(message, SDL_EVENT_WINDOW_EXPOSED);
break;
case BAPP_MAXIMIZE:
_HandleBasicWindowEvent(message, SDL_EVENT_WINDOW_MAXIMIZED);
break;
case BAPP_MINIMIZE:
_HandleBasicWindowEvent(message, SDL_EVENT_WINDOW_MINIMIZED);
break;
case BAPP_SHOW:
_HandleBasicWindowEvent(message, SDL_EVENT_WINDOW_SHOWN);
break;
case BAPP_HIDE:
_HandleBasicWindowEvent(message, SDL_EVENT_WINDOW_HIDDEN);
break;
case BAPP_MOUSE_FOCUS:
_HandleMouseFocus(message);
break;
case BAPP_KEYBOARD_FOCUS:
_HandleKeyboardFocus(message);
break;
case BAPP_WINDOW_CLOSE_REQUESTED:
_HandleBasicWindowEvent(message, SDL_EVENT_WINDOW_CLOSE_REQUESTED);
break;
case BAPP_WINDOW_MOVED:
_HandleWindowMoved(message);
break;
case BAPP_WINDOW_RESIZED:
_HandleWindowResized(message);
break;
case B_LOCALE_CHANGED:
SDL_SendLocaleChangedEvent();
break;
case BAPP_SCREEN_CHANGED:
/* TODO: Handle screen resize or workspace change */
break;
default:
BLooper::MessageReceived(message);
break;
}
}
/* Window creation/destruction methods */
int32 GetID(SDL_Window *win)
{
int32 i;
for (i = 0; i < _GetNumWindowSlots(); ++i) {
if (GetSDLWindow(i) == NULL) {
_SetSDLWindow(win, i);
return i;
}
}
/* Expand the vector if all slots are full */
if (i == _GetNumWindowSlots()) {
_PushBackWindow(win);
return i;
}
/* TODO: error handling */
return 0;
}
/* FIXME: Bad coding practice, but I can't include SDL_BWin.h here. Is
there another way to do this? */
void ClearID(SDL_BWin *bwin); /* Defined in SDL_BeApp.cc */
SDL_Window *GetSDLWindow(int32 winID)
{
return _window_map[winID];
}
#ifdef SDL_VIDEO_OPENGL
BGLView *GetCurrentContext()
{
return _current_context;
}
void SetCurrentContext(BGLView *newContext)
{
if (_current_context)
_current_context->UnlockGL();
_current_context = newContext;
if (_current_context)
_current_context->LockGL();
}
#endif
private:
/* Event management */
void _HandleBasicWindowEvent(BMessage *msg, SDL_EventType sdlEventType)
{
SDL_Window *win;
int32 winID;
if (
!_GetWinID(msg, &winID)) {
return;
}
win = GetSDLWindow(winID);
SDL_SendWindowEvent(win, sdlEventType, 0, 0);
}
void _HandleMouseMove(BMessage *msg)
{
SDL_Window *win;
int32 winID;
int32 x = 0, y = 0;
if (
!_GetWinID(msg, &winID) ||
msg->FindInt32("x", &x) != B_OK || /* x movement */
msg->FindInt32("y", &y) != B_OK /* y movement */
) {
return;
}
win = GetSDLWindow(winID);
// Simple relative mode support for mouse.
if (SDL_GetMouse()->relative_mode) {
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(0, win, 0, SDL_GetMouse()->relative_mode, (float)dx, (float)dy);
set_mouse_position((winPosX + winWidth / 2), (winPosY + winHeight / 2));
if (!be_app->IsCursorHidden())
be_app->HideCursor();
} else {
SDL_SendMouseMotion(0, win, 0, 0, (float)x, (float)y);
if (SDL_CursorVisible() && be_app->IsCursorHidden())
be_app->ShowCursor();
}
}
void _HandleMouseButton(BMessage *msg)
{
SDL_Window *win;
int32 winID;
int32 button, state; /* left/middle/right, pressed/released */
if (
!_GetWinID(msg, &winID) ||
msg->FindInt32("button-id", &button) != B_OK ||
msg->FindInt32("button-state", &state) != B_OK) {
return;
}
win = GetSDLWindow(winID);
SDL_SendMouseButton(0, win, 0, state, button);
}
void _HandleMouseWheel(BMessage *msg)
{
SDL_Window *win;
int32 winID;
int32 xTicks, yTicks;
if (
!_GetWinID(msg, &winID) ||
msg->FindInt32("xticks", &xTicks) != B_OK ||
msg->FindInt32("yticks", &yTicks) != B_OK) {
return;
}
win = GetSDLWindow(winID);
SDL_SendMouseWheel(0, win, 0, xTicks, -yTicks, SDL_MOUSEWHEEL_NORMAL);
}
void _HandleKey(BMessage *msg)
{
int32 scancode, state; /* scancode, pressed/released */
if (
msg->FindInt32("key-state", &state) != B_OK ||
msg->FindInt32("key-scancode", &scancode) != B_OK) {
return;
}
/* Make sure this isn't a repeated event (key pressed and held) */
if (state == SDL_PRESSED && HAIKU_GetKeyState(scancode) == SDL_PRESSED) {
return;
}
HAIKU_SetKeyState(scancode, state);
SDL_SendKeyboardKey(0, state, HAIKU_GetScancodeFromBeKey(scancode));
if (state == SDL_PRESSED && SDL_EventEnabled(SDL_EVENT_TEXT_INPUT)) {
const int8 *keyUtf8;
ssize_t count;
if (msg->FindData("key-utf8", B_INT8_TYPE, (const void **)&keyUtf8, &count) == B_OK) {
char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
SDL_zeroa(text);
SDL_memcpy(text, keyUtf8, count);
SDL_SendKeyboardText(text);
}
}
}
void _HandleMouseFocus(BMessage *msg)
{
SDL_Window *win;
int32 winID;
bool bSetFocus; /* If false, lose focus */
if (
!_GetWinID(msg, &winID) ||
msg->FindBool("focusGained", &bSetFocus) != B_OK) {
return;
}
win = GetSDLWindow(winID);
if (bSetFocus) {
SDL_SetMouseFocus(win);
} else if (SDL_GetMouseFocus() == win) {
/* Only lose all focus if this window was the current focus */
SDL_SetMouseFocus(NULL);
}
}
void _HandleKeyboardFocus(BMessage *msg)
{
SDL_Window *win;
int32 winID;
bool bSetFocus; /* If false, lose focus */
if (
!_GetWinID(msg, &winID) ||
msg->FindBool("focusGained", &bSetFocus) != B_OK) {
return;
}
win = GetSDLWindow(winID);
if (bSetFocus) {
SDL_SetKeyboardFocus(win);
} else if (SDL_GetKeyboardFocus() == win) {
/* Only lose all focus if this window was the current focus */
SDL_SetKeyboardFocus(NULL);
}
}
void _HandleWindowMoved(BMessage *msg)
{
SDL_Window *win;
int32 winID;
int32 xPos, yPos;
/* Get the window id and new x/y position of the window */
if (
!_GetWinID(msg, &winID) ||
msg->FindInt32("window-x", &xPos) != B_OK ||
msg->FindInt32("window-y", &yPos) != B_OK) {
return;
}
win = GetSDLWindow(winID);
SDL_SendWindowEvent(win, SDL_EVENT_WINDOW_MOVED, xPos, yPos);
}
void _HandleWindowResized(BMessage *msg)
{
SDL_Window *win;
int32 winID;
int32 w, h;
/* Get the window id ]and new x/y position of the window */
if (
!_GetWinID(msg, &winID) ||
msg->FindInt32("window-w", &w) != B_OK ||
msg->FindInt32("window-h", &h) != B_OK) {
return;
}
win = GetSDLWindow(winID);
SDL_SendWindowEvent(win, SDL_EVENT_WINDOW_RESIZED, w, h);
}
bool _GetWinID(BMessage *msg, int32 *winID)
{
return msg->FindInt32("window-id", winID) == B_OK;
}
/* Vector functions: Wraps vector stuff in case we need to change
implementation */
void _SetSDLWindow(SDL_Window *win, int32 winID)
{
_window_map[winID] = win;
}
int32 _GetNumWindowSlots()
{
return _window_map.size();
}
void _PopBackWindow()
{
_window_map.pop_back();
}
void _PushBackWindow(SDL_Window *win)
{
_window_map.push_back(win);
}
/* Members */
std::vector<SDL_Window *> _window_map; /* Keeps track of SDL_Windows by index-id */
#ifdef SDL_VIDEO_OPENGL
BGLView *_current_context;
#endif
};
#endif

View File

@@ -0,0 +1,751 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_BWin_h_
#define SDL_BWin_h_
#ifdef __cplusplus
extern "C" {
#endif
#include "SDL_internal.h"
#include "SDL_bframebuffer.h"
#include <SDL3/SDL_syswm.h>
#ifdef __cplusplus
}
#endif
#include <stdio.h>
#include <AppKit.h>
#include <Cursor.h>
#include <InterfaceKit.h>
#ifdef SDL_VIDEO_OPENGL
#include <opengl/GLView.h>
#endif
#include "../../core/haiku/SDL_BApp.h"
enum WinCommands
{
BWIN_MOVE_WINDOW,
BWIN_RESIZE_WINDOW,
BWIN_SHOW_WINDOW,
BWIN_HIDE_WINDOW,
BWIN_MAXIMIZE_WINDOW,
BWIN_MINIMIZE_WINDOW,
BWIN_RESTORE_WINDOW,
BWIN_SET_TITLE,
BWIN_SET_BORDERED,
BWIN_SET_RESIZABLE,
BWIN_FULLSCREEN,
BWIN_UPDATE_FRAMEBUFFER,
BWIN_MINIMUM_SIZE_WINDOW
};
// non-OpenGL framebuffer view
class SDL_BView : public BView
{
public:
SDL_BView(BRect frame, const char *name, uint32 resizingMode)
: BView(frame, name, resizingMode, B_WILL_DRAW),
fBitmap(NULL)
{
}
void Draw(BRect dirty)
{
if (fBitmap != NULL)
DrawBitmap(fBitmap, B_ORIGIN);
}
void SetBitmap(BBitmap *bitmap)
{
fBitmap = bitmap;
}
private:
BBitmap *fBitmap;
};
class SDL_BWin : public BWindow
{
public:
/* Constructor/Destructor */
SDL_BWin(BRect bounds, window_look look, uint32 flags)
: BWindow(bounds, "Untitled", look, B_NORMAL_WINDOW_FEEL, flags)
{
_last_buttons = 0;
_cur_view = NULL;
_SDL_View = NULL;
#ifdef SDL_VIDEO_OPENGL
_SDL_GLView = NULL;
_gl_type = 0;
#endif
_shown = false;
_inhibit_resize = false;
_mouse_focused = false;
_prev_frame = NULL;
_fullscreen = NULL;
/* Handle framebuffer stuff */
_buffer_locker = new BLocker();
_bitmap = NULL;
}
virtual ~SDL_BWin()
{
Lock();
if (_SDL_View != NULL && _SDL_View != _cur_view) {
delete _SDL_View;
_SDL_View = NULL;
}
#ifdef SDL_VIDEO_OPENGL
if (_SDL_GLView) {
if (SDL_Looper->GetCurrentContext() == _SDL_GLView)
SDL_Looper->SetCurrentContext(NULL);
if (_SDL_GLView == _cur_view)
RemoveChild(_SDL_GLView);
_SDL_GLView = NULL;
// _SDL_GLView deleted by HAIKU_GL_DeleteContext
}
#endif
Unlock();
delete _prev_frame;
/* Clean up framebuffer stuff */
_buffer_locker->Lock();
delete _buffer_locker;
}
void SetCurrentView(BView *view)
{
if (_cur_view != view) {
if (_cur_view != NULL)
RemoveChild(_cur_view);
_cur_view = view;
if (_cur_view != NULL)
AddChild(_cur_view);
}
}
void UpdateCurrentView()
{
if (_SDL_GLView != NULL) {
SetCurrentView(_SDL_GLView);
} else if (_SDL_View != NULL) {
SetCurrentView(_SDL_View);
} else {
SetCurrentView(NULL);
}
}
SDL_BView *CreateView()
{
Lock();
if (_SDL_View == NULL) {
_SDL_View = new SDL_BView(Bounds(), "SDL View", B_FOLLOW_ALL_SIDES);
UpdateCurrentView();
}
Unlock();
return _SDL_View;
}
void RemoveView()
{
Lock();
if (_SDL_View != NULL) {
SDL_BView *oldView = _SDL_View;
_SDL_View = NULL;
UpdateCurrentView();
delete oldView;
}
Unlock();
}
/* * * * * OpenGL functionality * * * * */
#ifdef SDL_VIDEO_OPENGL
BGLView *CreateGLView(Uint32 gl_flags)
{
Lock();
if (_SDL_GLView == NULL) {
_SDL_GLView = new BGLView(Bounds(), "SDL GLView",
B_FOLLOW_ALL_SIDES,
(B_WILL_DRAW | B_FRAME_EVENTS),
gl_flags);
_gl_type = gl_flags;
UpdateCurrentView();
}
Unlock();
return _SDL_GLView;
}
void RemoveGLView()
{
Lock();
if (_SDL_GLView != NULL) {
if (SDL_Looper->GetCurrentContext() == _SDL_GLView)
SDL_Looper->SetCurrentContext(NULL);
_SDL_GLView = NULL;
UpdateCurrentView();
// _SDL_GLView deleted by HAIKU_GL_DeleteContext
}
Unlock();
}
void SwapBuffers(void)
{
_SDL_GLView->SwapBuffers();
}
#endif
/* * * * * Event sending * * * * */
/* Hook functions */
virtual void FrameMoved(BPoint origin)
{
/* Post a message to the BApp so that it can handle the window event */
BMessage msg(BAPP_WINDOW_MOVED);
msg.AddInt32("window-x", (int)origin.x);
msg.AddInt32("window-y", (int)origin.y);
_PostWindowEvent(msg);
/* Perform normal hook operations */
BWindow::FrameMoved(origin);
}
void FrameResized(float width, float height)
{
/* Post a message to the BApp so that it can handle the window event */
BMessage msg(BAPP_WINDOW_RESIZED);
msg.AddInt32("window-w", (int)width + 1);
msg.AddInt32("window-h", (int)height + 1);
_PostWindowEvent(msg);
/* Perform normal hook operations */
BWindow::FrameResized(width, height);
}
bool QuitRequested()
{
BMessage msg(BAPP_WINDOW_CLOSE_REQUESTED);
_PostWindowEvent(msg);
/* We won't allow a quit unless asked by DestroyWindow() */
return false;
}
void WindowActivated(bool active)
{
BMessage msg(BAPP_KEYBOARD_FOCUS); /* Mouse focus sold separately */
msg.AddBool("focusGained", active);
_PostWindowEvent(msg);
}
void Zoom(BPoint origin,
float width,
float height)
{
BMessage msg(BAPP_MAXIMIZE); /* Closest thing to maximization Haiku has */
_PostWindowEvent(msg);
/* Before the window zooms, record its size */
if (!_prev_frame)
_prev_frame = new BRect(Frame());
/* Perform normal hook operations */
BWindow::Zoom(origin, width, height);
}
/* Member functions */
void Show()
{
while (IsHidden()) {
BWindow::Show();
}
_shown = true;
BMessage msg(BAPP_SHOW);
_PostWindowEvent(msg);
}
void Hide()
{
BWindow::Hide();
_shown = false;
BMessage msg(BAPP_HIDE);
_PostWindowEvent(msg);
}
void Minimize(bool minimize)
{
BWindow::Minimize(minimize);
int32 minState = (minimize ? BAPP_MINIMIZE : BAPP_RESTORE);
BMessage msg(minState);
_PostWindowEvent(msg);
}
void ScreenChanged(BRect screenFrame, color_space depth)
{
if (_fullscreen) {
MoveTo(screenFrame.left, screenFrame.top);
ResizeTo(screenFrame.Width(), screenFrame.Height());
}
}
/* BView message interruption */
void DispatchMessage(BMessage *msg, BHandler *target)
{
BPoint where; /* Used by mouse moved */
int32 buttons; /* Used for mouse button events */
int32 key; /* Used for key events */
switch (msg->what) {
case B_MOUSE_MOVED:
int32 transit;
if (msg->FindPoint("where", &where) == B_OK && msg->FindInt32("be:transit", &transit) == B_OK) {
_MouseMotionEvent(where, transit);
}
break;
case B_MOUSE_DOWN:
if (msg->FindInt32("buttons", &buttons) == B_OK) {
_MouseButtonEvent(buttons, SDL_PRESSED);
}
break;
case B_MOUSE_UP:
if (msg->FindInt32("buttons", &buttons) == B_OK) {
_MouseButtonEvent(buttons, SDL_RELEASED);
}
break;
case B_MOUSE_WHEEL_CHANGED:
float x, y;
if (msg->FindFloat("be:wheel_delta_x", &x) == B_OK && msg->FindFloat("be:wheel_delta_y", &y) == B_OK) {
_MouseWheelEvent((int)x, (int)y);
}
break;
case B_KEY_DOWN:
{
int32 i = 0;
int8 byte;
int8 bytes[4] = { 0, 0, 0, 0 };
while (i < 4 && msg->FindInt8("byte", i, &byte) == B_OK) {
bytes[i] = byte;
i++;
}
if (msg->FindInt32("key", &key) == B_OK) {
_KeyEvent((SDL_Scancode)key, &bytes[0], i, SDL_PRESSED);
}
} break;
case B_UNMAPPED_KEY_DOWN: /* modifier keys are unmapped */
if (msg->FindInt32("key", &key) == B_OK) {
_KeyEvent((SDL_Scancode)key, NULL, 0, SDL_PRESSED);
}
break;
case B_KEY_UP:
case B_UNMAPPED_KEY_UP: /* modifier keys are unmapped */
if (msg->FindInt32("key", &key) == B_OK) {
_KeyEvent(key, NULL, 0, SDL_RELEASED);
}
break;
default:
/* move it after switch{} so it's always handled
that way we keep Haiku features like:
- CTRL+Q to close window (and other shortcuts)
- PrintScreen to make screenshot into /boot/home
- etc.. */
/* BWindow::DispatchMessage(msg, target); */
break;
}
BWindow::DispatchMessage(msg, target);
}
/* Handle command messages */
void MessageReceived(BMessage *message)
{
switch (message->what) {
/* Handle commands from SDL */
case BWIN_SET_TITLE:
_SetTitle(message);
break;
case BWIN_MOVE_WINDOW:
_MoveTo(message);
break;
case BWIN_RESIZE_WINDOW:
_ResizeTo(message);
break;
case BWIN_SET_BORDERED:
{
bool bEnabled;
if (message->FindBool("window-border", &bEnabled) == B_OK)
_SetBordered(bEnabled);
break;
}
case BWIN_SET_RESIZABLE:
{
bool bEnabled;
if (message->FindBool("window-resizable", &bEnabled) == B_OK)
_SetResizable(bEnabled);
break;
}
case BWIN_SHOW_WINDOW:
Show();
break;
case BWIN_HIDE_WINDOW:
Hide();
break;
case BWIN_MAXIMIZE_WINDOW:
BWindow::Zoom();
break;
case BWIN_MINIMIZE_WINDOW:
Minimize(true);
break;
case BWIN_RESTORE_WINDOW:
_Restore();
break;
case BWIN_FULLSCREEN:
{
bool fullscreen;
if (message->FindBool("fullscreen", &fullscreen) == B_OK)
_SetFullScreen(fullscreen);
break;
}
case BWIN_MINIMUM_SIZE_WINDOW:
_SetMinimumSize(message);
break;
case BWIN_UPDATE_FRAMEBUFFER:
{
BMessage *pendingMessage;
while ((pendingMessage = MessageQueue()->FindMessage(BWIN_UPDATE_FRAMEBUFFER, 0))) {
MessageQueue()->RemoveMessage(pendingMessage);
delete pendingMessage;
}
if (_bitmap != NULL) {
if (_SDL_View != NULL && _cur_view == _SDL_View)
_SDL_View->Draw(Bounds());
else if (_SDL_GLView != NULL && _cur_view == _SDL_GLView) {
_SDL_GLView->CopyPixelsIn(_bitmap, B_ORIGIN);
}
}
break;
}
default:
/* Perform normal message handling */
BWindow::MessageReceived(message);
break;
}
}
/* Accessor methods */
bool IsShown() { return _shown; }
int32 GetID() { return _id; }
BBitmap *GetBitmap() { return _bitmap; }
BView *GetCurView() { return _cur_view; }
SDL_BView *GetView() { return _SDL_View; }
#ifdef SDL_VIDEO_OPENGL
BGLView *GetGLView()
{
return _SDL_GLView;
}
Uint32 GetGLType() { return _gl_type; }
#endif
/* Setter methods */
void SetID(int32 id) { _id = id; }
void LockBuffer() { _buffer_locker->Lock(); }
void UnlockBuffer() { _buffer_locker->Unlock(); }
void SetBitmap(BBitmap *bitmap)
{
_bitmap = bitmap;
if (_SDL_View != NULL)
_SDL_View->SetBitmap(bitmap);
}
private:
/* Event redirection */
void _MouseMotionEvent(BPoint &where, int32 transit)
{
if (transit == B_EXITED_VIEW) {
/* Change mouse focus */
if (_mouse_focused) {
_MouseFocusEvent(false);
}
} else {
/* Change mouse focus */
if (!_mouse_focused) {
_MouseFocusEvent(true);
}
BMessage msg(BAPP_MOUSE_MOVED);
msg.AddInt32("x", (int)where.x);
msg.AddInt32("y", (int)where.y);
_PostWindowEvent(msg);
}
}
void _MouseFocusEvent(bool focusGained)
{
_mouse_focused = focusGained;
BMessage msg(BAPP_MOUSE_FOCUS);
msg.AddBool("focusGained", focusGained);
_PostWindowEvent(msg);
/* FIXME: Why were these here?
if false: be_app->SetCursor(B_HAND_CURSOR);
if true: SDL_SetCursor(NULL); */
}
void _MouseButtonEvent(int32 buttons, Uint8 state)
{
int32 buttonStateChange = buttons ^ _last_buttons;
if (buttonStateChange & B_PRIMARY_MOUSE_BUTTON) {
_SendMouseButton(SDL_BUTTON_LEFT, state);
}
if (buttonStateChange & B_SECONDARY_MOUSE_BUTTON) {
_SendMouseButton(SDL_BUTTON_RIGHT, state);
}
if (buttonStateChange & B_TERTIARY_MOUSE_BUTTON) {
_SendMouseButton(SDL_BUTTON_MIDDLE, state);
}
_last_buttons = buttons;
}
void _SendMouseButton(int32 button, int32 state)
{
BMessage msg(BAPP_MOUSE_BUTTON);
msg.AddInt32("button-id", button);
msg.AddInt32("button-state", state);
_PostWindowEvent(msg);
}
void _MouseWheelEvent(int32 x, int32 y)
{
/* Create a message to pass along to the BeApp thread */
BMessage msg(BAPP_MOUSE_WHEEL);
msg.AddInt32("xticks", x);
msg.AddInt32("yticks", y);
_PostWindowEvent(msg);
}
void _KeyEvent(int32 keyCode, const int8 *keyUtf8, const ssize_t &len, int32 keyState)
{
/* Create a message to pass along to the BeApp thread */
BMessage msg(BAPP_KEY);
msg.AddInt32("key-state", keyState);
msg.AddInt32("key-scancode", keyCode);
if (keyUtf8 != NULL) {
msg.AddData("key-utf8", B_INT8_TYPE, (const void *)keyUtf8, len);
}
SDL_Looper->PostMessage(&msg);
}
void _RepaintEvent()
{
/* Force a repaint: Call the SDL exposed event */
BMessage msg(BAPP_REPAINT);
_PostWindowEvent(msg);
}
void _PostWindowEvent(BMessage &msg)
{
msg.AddInt32("window-id", _id);
SDL_Looper->PostMessage(&msg);
}
/* Command methods (functions called upon by SDL) */
void _SetTitle(BMessage *msg)
{
const char *title;
if (
msg->FindString("window-title", &title) != B_OK) {
return;
}
SetTitle(title);
}
void _MoveTo(BMessage *msg)
{
int32 x, y;
if (
msg->FindInt32("window-x", &x) != B_OK ||
msg->FindInt32("window-y", &y) != B_OK) {
return;
}
if (_fullscreen)
_non_fullscreen_frame.OffsetTo(x, y);
else
MoveTo(x, y);
}
void _ResizeTo(BMessage *msg)
{
int32 w, h;
if (
msg->FindInt32("window-w", &w) != B_OK ||
msg->FindInt32("window-h", &h) != B_OK) {
return;
}
if (_fullscreen) {
_non_fullscreen_frame.right = _non_fullscreen_frame.left + w;
_non_fullscreen_frame.bottom = _non_fullscreen_frame.top + h;
} else
ResizeTo(w, h);
}
void _SetBordered(bool bEnabled)
{
if (_fullscreen)
_bordered = bEnabled;
else
SetLook(bEnabled ? B_TITLED_WINDOW_LOOK : B_NO_BORDER_WINDOW_LOOK);
}
void _SetResizable(bool bEnabled)
{
if (_fullscreen)
_resizable = bEnabled;
else {
if (bEnabled) {
SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_ZOOMABLE));
} else {
SetFlags(Flags() | (B_NOT_RESIZABLE | B_NOT_ZOOMABLE));
}
}
}
void _SetMinimumSize(BMessage *msg)
{
float maxHeight;
float maxWidth;
float _;
int32 minHeight;
int32 minWidth;
// This is a bit convoluted, we only want to set the minimum not the maximum
// But there is no direct call to do that, so store the maximum size beforehand
GetSizeLimits(&_, &maxWidth, &_, &maxHeight);
if (msg->FindInt32("window-w", &minWidth) != B_OK)
return;
if (msg->FindInt32("window-h", &minHeight) != B_OK)
return;
SetSizeLimits((float)minWidth, maxWidth, (float)minHeight, maxHeight);
UpdateSizeLimits();
}
void _Restore()
{
if (IsMinimized()) {
Minimize(false);
} else if (IsHidden()) {
Show();
} else if (_fullscreen) {
} else if (_prev_frame != NULL) { /* Zoomed */
MoveTo(_prev_frame->left, _prev_frame->top);
ResizeTo(_prev_frame->Width(), _prev_frame->Height());
}
}
void _SetFullScreen(bool fullscreen)
{
if (fullscreen != _fullscreen) {
if (fullscreen) {
BScreen screen(this);
BRect screenFrame = screen.Frame();
printf("screen frame: ");
screenFrame.PrintToStream();
printf("\n");
_bordered = Look() != B_NO_BORDER_WINDOW_LOOK;
_resizable = !(Flags() & B_NOT_RESIZABLE);
_non_fullscreen_frame = Frame();
_SetBordered(false);
_SetResizable(false);
MoveTo(screenFrame.left, screenFrame.top);
ResizeTo(screenFrame.Width(), screenFrame.Height());
_fullscreen = fullscreen;
} else {
_fullscreen = fullscreen;
MoveTo(_non_fullscreen_frame.left, _non_fullscreen_frame.top);
ResizeTo(_non_fullscreen_frame.Width(), _non_fullscreen_frame.Height());
_SetBordered(_bordered);
_SetResizable(_resizable);
}
}
}
/* Members */
BView *_cur_view;
SDL_BView *_SDL_View;
#ifdef SDL_VIDEO_OPENGL
BGLView *_SDL_GLView;
Uint32 _gl_type;
#endif
int32 _last_buttons;
int32 _id; /* Window id used by SDL_BApp */
bool _mouse_focused; /* Does this window have mouse focus? */
bool _shown;
bool _inhibit_resize;
BRect *_prev_frame; /* Previous position and size of the window */
bool _fullscreen;
// valid only if fullscreen
BRect _non_fullscreen_frame;
bool _bordered;
bool _resizable;
/* Framebuffer members */
BLocker *_buffer_locker;
BBitmap *_bitmap;
};
/* FIXME:
* An explanation of framebuffer flags.
*
* _connected - Original variable used to let the drawing thread know
* when changes are being made to the other framebuffer
* members.
* _connection_disabled - Used to signal to the drawing thread that the window
* is closing, and the thread should exit.
* _buffer_created - True if the current buffer is valid
* _buffer_dirty - True if the window should be redrawn.
* _trash_window_buffer - True if the window buffer needs to be trashed partway
* through a draw cycle. Occurs when the previous
* buffer provided by DirectConnected() is invalidated.
*/
#endif /* SDL_BWin_h_ */

View File

@@ -0,0 +1,92 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_HAIKU
/* BWindow based clipboard implementation */
#include <unistd.h>
#include <TypeConstants.h>
#include "SDL_BWin.h"
#include "../SDL_sysvideo.h"
#ifdef __cplusplus
extern "C" {
#endif
int HAIKU_SetClipboardText(SDL_VideoDevice *_this, const char *text) {
BMessage *clip = NULL;
if (be_clipboard->Lock()) {
be_clipboard->Clear();
if ((clip = be_clipboard->Data())) {
/* Presumably the string of characters is ascii-format */
ssize_t asciiLength = 0;
for (; text[asciiLength] != 0; ++asciiLength) {}
clip->AddData("text/plain", B_MIME_TYPE, text, asciiLength);
be_clipboard->Commit();
}
be_clipboard->Unlock();
}
return 0;
}
char *HAIKU_GetClipboardText(SDL_VideoDevice *_this) {
BMessage *clip = NULL;
const char *text = NULL;
ssize_t length;
char *result;
if (be_clipboard->Lock()) {
if ((clip = be_clipboard->Data())) {
/* Presumably the string of characters is ascii-format */
clip->FindData("text/plain", B_MIME_TYPE, (const void**)&text,
&length);
}
be_clipboard->Unlock();
}
if (text == NULL) {
result = SDL_strdup("");
} else {
/* Copy the data and pass on to SDL */
result = (char *)SDL_malloc((length + 1) * sizeof(char));
SDL_strlcpy(result, text, length + 1);
}
return result;
}
SDL_bool HAIKU_HasClipboardText(SDL_VideoDevice *_this) {
SDL_bool result = SDL_FALSE;
char *text = HAIKU_GetClipboardText(_this);
if (text) {
result = text[0] != '\0' ? SDL_TRUE : SDL_FALSE;
SDL_free(text);
}
return result;
}
#ifdef __cplusplus
}
#endif
#endif /* SDL_VIDEO_DRIVER_HAIKU */

View File

@@ -0,0 +1,31 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifndef SDL_BCLIPBOARD_H
#define SDL_BCLIPBOARD_H
extern int HAIKU_SetClipboardText(SDL_VideoDevice *_this, const char *text);
extern char *HAIKU_GetClipboardText(SDL_VideoDevice *_this);
extern SDL_bool HAIKU_HasClipboardText(SDL_VideoDevice *_this);
#endif

View File

@@ -0,0 +1,39 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_HAIKU
#include "SDL_bevents.h"
#ifdef __cplusplus
extern "C" {
#endif
void HAIKU_PumpEvents(SDL_VideoDevice *_this) {
/* Since the event thread is its own thread, this isn't really necessary */
}
#ifdef __cplusplus
}
#endif
#endif /* SDL_VIDEO_DRIVER_HAIKU */

View File

@@ -0,0 +1,37 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_BEVENTS_H
#define SDL_BEVENTS_H
#include "../SDL_sysvideo.h"
#ifdef __cplusplus
extern "C" {
#endif
extern void HAIKU_PumpEvents(SDL_VideoDevice *_this);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,127 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_HAIKU
#include "SDL_bframebuffer.h"
#include <AppKit.h>
#include <InterfaceKit.h>
#include "SDL_bmodes.h"
#include "SDL_BWin.h"
#include "../../core/haiku/SDL_BApp.h"
#ifdef __cplusplus
extern "C" {
#endif
static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
return (SDL_BWin *)(window->driverdata);
}
static SDL_INLINE SDL_BLooper *_GetBeLooper() {
return SDL_Looper;
}
int HAIKU_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window * window,
Uint32 * format,
void ** pixels, int *pitch) {
SDL_BWin *bwin = _ToBeWin(window);
BScreen bscreen;
if (!bscreen.IsValid()) {
return -1;
}
/* Make sure we have exclusive access to frame buffer data */
bwin->LockBuffer();
bwin->CreateView();
/* format */
display_mode bmode;
bscreen.GetMode(&bmode);
*format = HAIKU_ColorSpaceToSDLPxFormat(bmode.space);
/* Create the new bitmap object */
BBitmap *bitmap = bwin->GetBitmap();
if (bitmap) {
delete bitmap;
}
bitmap = new BBitmap(bwin->Bounds(), (color_space)bmode.space,
false, /* Views not accepted */
true); /* Contiguous memory required */
if (bitmap->InitCheck() != B_OK) {
delete bitmap;
return SDL_SetError("Could not initialize back buffer!");
}
bwin->SetBitmap(bitmap);
/* Set the pixel pointer */
*pixels = bitmap->Bits();
/* pitch = width of window, in bytes */
*pitch = bitmap->BytesPerRow();
bwin->UnlockBuffer();
return 0;
}
int HAIKU_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window * window,
const SDL_Rect * rects, int numrects) {
if (window == NULL) {
return 0;
}
SDL_BWin *bwin = _ToBeWin(window);
bwin->PostMessage(BWIN_UPDATE_FRAMEBUFFER);
return 0;
}
void HAIKU_DestroyWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window * window) {
SDL_BWin *bwin = _ToBeWin(window);
bwin->LockBuffer();
/* Free and clear the window buffer */
BBitmap *bitmap = bwin->GetBitmap();
delete bitmap;
bwin->SetBitmap(NULL);
bwin->RemoveView();
bwin->UnlockBuffer();
}
#ifdef __cplusplus
}
#endif
#endif /* SDL_VIDEO_DRIVER_HAIKU */

View File

@@ -0,0 +1,45 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_BFRAMEBUFFER_H
#define SDL_BFRAMEBUFFER_H
#include <SupportDefs.h>
#ifdef __cplusplus
extern "C" {
#endif
#define DRAWTHREAD
#include "../SDL_sysvideo.h"
extern int HAIKU_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window,
Uint32 *format,
void **pixels, int *pitch);
extern int HAIKU_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window,
const SDL_Rect *rects, int numrects);
extern void HAIKU_DestroyWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window);
extern int32 HAIKU_DrawThread(void *data);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,186 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_HAIKU
#include <SupportDefs.h>
#include <support/UTF8.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "SDL_bkeyboard.h"
#define KEYMAP_SIZE 128
static SDL_Scancode keymap[KEYMAP_SIZE];
static int8 keystate[KEYMAP_SIZE];
void HAIKU_InitOSKeymap(void) {
for ( uint i = 0; i < SDL_TABLESIZE(keymap); ++i ) {
keymap[i] = SDL_SCANCODE_UNKNOWN;
}
for ( uint i = 0; i < KEYMAP_SIZE; ++i ) {
keystate[i] = SDL_RELEASED;
}
keymap[0x01] = SDL_GetScancodeFromKey(SDLK_ESCAPE);
keymap[B_F1_KEY] = SDL_GetScancodeFromKey(SDLK_F1);
keymap[B_F2_KEY] = SDL_GetScancodeFromKey(SDLK_F2);
keymap[B_F3_KEY] = SDL_GetScancodeFromKey(SDLK_F3);
keymap[B_F4_KEY] = SDL_GetScancodeFromKey(SDLK_F4);
keymap[B_F5_KEY] = SDL_GetScancodeFromKey(SDLK_F5);
keymap[B_F6_KEY] = SDL_GetScancodeFromKey(SDLK_F6);
keymap[B_F7_KEY] = SDL_GetScancodeFromKey(SDLK_F7);
keymap[B_F8_KEY] = SDL_GetScancodeFromKey(SDLK_F8);
keymap[B_F9_KEY] = SDL_GetScancodeFromKey(SDLK_F9);
keymap[B_F10_KEY] = SDL_GetScancodeFromKey(SDLK_F10);
keymap[B_F11_KEY] = SDL_GetScancodeFromKey(SDLK_F11);
keymap[B_F12_KEY] = SDL_GetScancodeFromKey(SDLK_F12);
keymap[B_PRINT_KEY] = SDL_GetScancodeFromKey(SDLK_PRINTSCREEN);
keymap[B_SCROLL_KEY] = SDL_GetScancodeFromKey(SDLK_SCROLLLOCK);
keymap[B_PAUSE_KEY] = SDL_GetScancodeFromKey(SDLK_PAUSE);
keymap[0x11] = SDL_GetScancodeFromKey(SDLK_BACKQUOTE);
keymap[0x12] = SDL_GetScancodeFromKey(SDLK_1);
keymap[0x13] = SDL_GetScancodeFromKey(SDLK_2);
keymap[0x14] = SDL_GetScancodeFromKey(SDLK_3);
keymap[0x15] = SDL_GetScancodeFromKey(SDLK_4);
keymap[0x16] = SDL_GetScancodeFromKey(SDLK_5);
keymap[0x17] = SDL_GetScancodeFromKey(SDLK_6);
keymap[0x18] = SDL_GetScancodeFromKey(SDLK_7);
keymap[0x19] = SDL_GetScancodeFromKey(SDLK_8);
keymap[0x1a] = SDL_GetScancodeFromKey(SDLK_9);
keymap[0x1b] = SDL_GetScancodeFromKey(SDLK_0);
keymap[0x1c] = SDL_GetScancodeFromKey(SDLK_MINUS);
keymap[0x1d] = SDL_GetScancodeFromKey(SDLK_EQUALS);
keymap[0x1e] = SDL_GetScancodeFromKey(SDLK_BACKSPACE);
keymap[0x1f] = SDL_GetScancodeFromKey(SDLK_INSERT);
keymap[0x20] = SDL_GetScancodeFromKey(SDLK_HOME);
keymap[0x21] = SDL_GetScancodeFromKey(SDLK_PAGEUP);
keymap[0x22] = SDL_GetScancodeFromKey(SDLK_NUMLOCKCLEAR);
keymap[0x23] = SDL_GetScancodeFromKey(SDLK_KP_DIVIDE);
keymap[0x24] = SDL_GetScancodeFromKey(SDLK_KP_MULTIPLY);
keymap[0x25] = SDL_GetScancodeFromKey(SDLK_KP_MINUS);
keymap[0x26] = SDL_GetScancodeFromKey(SDLK_TAB);
keymap[0x27] = SDL_GetScancodeFromKey(SDLK_q);
keymap[0x28] = SDL_GetScancodeFromKey(SDLK_w);
keymap[0x29] = SDL_GetScancodeFromKey(SDLK_e);
keymap[0x2a] = SDL_GetScancodeFromKey(SDLK_r);
keymap[0x2b] = SDL_GetScancodeFromKey(SDLK_t);
keymap[0x2c] = SDL_GetScancodeFromKey(SDLK_y);
keymap[0x2d] = SDL_GetScancodeFromKey(SDLK_u);
keymap[0x2e] = SDL_GetScancodeFromKey(SDLK_i);
keymap[0x2f] = SDL_GetScancodeFromKey(SDLK_o);
keymap[0x30] = SDL_GetScancodeFromKey(SDLK_p);
keymap[0x31] = SDL_GetScancodeFromKey(SDLK_LEFTBRACKET);
keymap[0x32] = SDL_GetScancodeFromKey(SDLK_RIGHTBRACKET);
keymap[0x33] = SDL_GetScancodeFromKey(SDLK_BACKSLASH);
keymap[0x34] = SDL_GetScancodeFromKey(SDLK_DELETE);
keymap[0x35] = SDL_GetScancodeFromKey(SDLK_END);
keymap[0x36] = SDL_GetScancodeFromKey(SDLK_PAGEDOWN);
keymap[0x37] = SDL_GetScancodeFromKey(SDLK_KP_7);
keymap[0x38] = SDL_GetScancodeFromKey(SDLK_KP_8);
keymap[0x39] = SDL_GetScancodeFromKey(SDLK_KP_9);
keymap[0x3a] = SDL_GetScancodeFromKey(SDLK_KP_PLUS);
keymap[0x3b] = SDL_GetScancodeFromKey(SDLK_CAPSLOCK);
keymap[0x3c] = SDL_GetScancodeFromKey(SDLK_a);
keymap[0x3d] = SDL_GetScancodeFromKey(SDLK_s);
keymap[0x3e] = SDL_GetScancodeFromKey(SDLK_d);
keymap[0x3f] = SDL_GetScancodeFromKey(SDLK_f);
keymap[0x40] = SDL_GetScancodeFromKey(SDLK_g);
keymap[0x41] = SDL_GetScancodeFromKey(SDLK_h);
keymap[0x42] = SDL_GetScancodeFromKey(SDLK_j);
keymap[0x43] = SDL_GetScancodeFromKey(SDLK_k);
keymap[0x44] = SDL_GetScancodeFromKey(SDLK_l);
keymap[0x45] = SDL_GetScancodeFromKey(SDLK_SEMICOLON);
keymap[0x46] = SDL_GetScancodeFromKey(SDLK_QUOTE);
keymap[0x47] = SDL_GetScancodeFromKey(SDLK_RETURN);
keymap[0x48] = SDL_GetScancodeFromKey(SDLK_KP_4);
keymap[0x49] = SDL_GetScancodeFromKey(SDLK_KP_5);
keymap[0x4a] = SDL_GetScancodeFromKey(SDLK_KP_6);
keymap[0x4b] = SDL_GetScancodeFromKey(SDLK_LSHIFT);
keymap[0x4c] = SDL_GetScancodeFromKey(SDLK_z);
keymap[0x4d] = SDL_GetScancodeFromKey(SDLK_x);
keymap[0x4e] = SDL_GetScancodeFromKey(SDLK_c);
keymap[0x4f] = SDL_GetScancodeFromKey(SDLK_v);
keymap[0x50] = SDL_GetScancodeFromKey(SDLK_b);
keymap[0x51] = SDL_GetScancodeFromKey(SDLK_n);
keymap[0x52] = SDL_GetScancodeFromKey(SDLK_m);
keymap[0x53] = SDL_GetScancodeFromKey(SDLK_COMMA);
keymap[0x54] = SDL_GetScancodeFromKey(SDLK_PERIOD);
keymap[0x55] = SDL_GetScancodeFromKey(SDLK_SLASH);
keymap[0x56] = SDL_GetScancodeFromKey(SDLK_RSHIFT);
keymap[0x57] = SDL_GetScancodeFromKey(SDLK_UP);
keymap[0x58] = SDL_GetScancodeFromKey(SDLK_KP_1);
keymap[0x59] = SDL_GetScancodeFromKey(SDLK_KP_2);
keymap[0x5a] = SDL_GetScancodeFromKey(SDLK_KP_3);
keymap[0x5b] = SDL_GetScancodeFromKey(SDLK_KP_ENTER);
keymap[0x5c] = SDL_GetScancodeFromKey(SDLK_LCTRL);
keymap[0x5d] = SDL_GetScancodeFromKey(SDLK_LALT);
keymap[0x5e] = SDL_GetScancodeFromKey(SDLK_SPACE);
keymap[0x5f] = SDL_GetScancodeFromKey(SDLK_RALT);
keymap[0x60] = SDL_GetScancodeFromKey(SDLK_RCTRL);
keymap[0x61] = SDL_GetScancodeFromKey(SDLK_LEFT);
keymap[0x62] = SDL_GetScancodeFromKey(SDLK_DOWN);
keymap[0x63] = SDL_GetScancodeFromKey(SDLK_RIGHT);
keymap[0x64] = SDL_GetScancodeFromKey(SDLK_KP_0);
keymap[0x65] = SDL_GetScancodeFromKey(SDLK_KP_PERIOD);
keymap[0x66] = SDL_GetScancodeFromKey(SDLK_LGUI);
keymap[0x67] = SDL_GetScancodeFromKey(SDLK_RGUI);
keymap[0x68] = SDL_GetScancodeFromKey(SDLK_MENU);
keymap[0x69] = SDL_GetScancodeFromKey(SDLK_2); /* SDLK_EURO */
keymap[0x6a] = SDL_GetScancodeFromKey(SDLK_KP_EQUALS);
keymap[0x6b] = SDL_GetScancodeFromKey(SDLK_POWER);
}
SDL_Scancode HAIKU_GetScancodeFromBeKey(int32 bkey) {
if (bkey > 0 && bkey < (int32)SDL_TABLESIZE(keymap)) {
return keymap[bkey];
} else {
return SDL_SCANCODE_UNKNOWN;
}
}
int8 HAIKU_GetKeyState(int32 bkey) {
if (bkey > 0 && bkey < KEYMAP_SIZE) {
return keystate[bkey];
} else {
return SDL_RELEASED;
}
}
void HAIKU_SetKeyState(int32 bkey, int8 state) {
if (bkey > 0 && bkey < KEYMAP_SIZE) {
keystate[bkey] = state;
}
}
#ifdef __cplusplus
}
#endif
#endif /* SDL_VIDEO_DRIVER_HAIKU */

View File

@@ -0,0 +1,40 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_BKEYBOARD_H
#define SDL_BKEYBOARD_H
#include <SupportDefs.h>
#ifdef __cplusplus
extern "C" {
#endif
extern void HAIKU_InitOSKeymap(void);
extern SDL_Scancode HAIKU_GetScancodeFromBeKey(int32 bkey);
extern int8 HAIKU_GetKeyState(int32 bkey);
extern void HAIKU_SetKeyState(int32 bkey, int8 state);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,394 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 2018-2019 EXL <exlmotodev@gmail.com>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_HAIKU
/* For application signature. */
#include "../../core/haiku/SDL_BeApp.h"
#include <Alert.h>
#include <Application.h>
#include <Button.h>
#include <Font.h>
#include <Layout.h>
#include <String.h>
#include <TextView.h>
#include <View.h>
#include <Window.h>
#include <InterfaceDefs.h>
#include <SupportDefs.h>
#include <GraphicsDefs.h>
#include <new>
#include <vector>
#include <algorithm>
#include <memory>
enum
{
G_CLOSE_BUTTON_ID = -1,
G_DEFAULT_BUTTON_ID = 0,
G_MAX_STRING_LENGTH_BYTES = 120
};
class HAIKU_SDL_MessageBox : public BAlert
{
float fComputedMessageBoxWidth;
BTextView *fMessageBoxTextView;
int fCloseButton;
int fDefaultButton;
bool fCustomColorScheme;
bool fThereIsLongLine;
rgb_color fTextColor;
const char *fTitle;
const char *HAIKU_SDL_DefTitle;
const char *HAIKU_SDL_DefMessage;
const char *HAIKU_SDL_DefButton;
std::vector<const SDL_MessageBoxButtonData *> fButtons;
static bool
SortButtonsPredicate(const SDL_MessageBoxButtonData *aButtonLeft,
const SDL_MessageBoxButtonData *aButtonRight)
{
return aButtonLeft->buttonid < aButtonRight->buttonid;
}
alert_type
ConvertMessageBoxType(const SDL_MessageBoxFlags aWindowType) const
{
switch (aWindowType)
{
default:
case SDL_MESSAGEBOX_WARNING:
{
return B_WARNING_ALERT;
}
case SDL_MESSAGEBOX_ERROR:
{
return B_STOP_ALERT;
}
case SDL_MESSAGEBOX_INFORMATION:
{
return B_INFO_ALERT;
}
}
}
rgb_color
ConvertColorType(const SDL_MessageBoxColor *aColor) const
{
rgb_color color = { aColor->r, aColor->g, aColor->b, color.alpha = 255 };
return color;
}
int32
GetLeftPanelWidth(void) const
{
// See file "haiku/src/kits/interface/Alert.cpp" for this magic numbers.
// IconStripeWidth = 30 * Scale
// IconSize = 32 * Scale
// Scale = max_c(1, ((int32)be_plain_font->Size() + 15) / 16)
// RealWidth = (IconStripeWidth * Scale) + (IconSize * Scale)
int32 scale = max_c(1, ((int32)be_plain_font->Size() + 15) / 16);
return (30 * scale) + (32 * scale);
}
void
UpdateTextViewWidth(void)
{
fComputedMessageBoxWidth = fMessageBoxTextView->PreferredSize().Width() + GetLeftPanelWidth();
}
void
ParseSdlMessageBoxData(const SDL_MessageBoxData *aMessageBoxData)
{
if (aMessageBoxData == NULL) {
SetTitle(HAIKU_SDL_DefTitle);
SetMessageText(HAIKU_SDL_DefMessage);
AddButton(HAIKU_SDL_DefButton);
return;
}
if (aMessageBoxData->numbuttons <= 0) {
AddButton(HAIKU_SDL_DefButton);
} else {
AddSdlButtons(aMessageBoxData->buttons, aMessageBoxData->numbuttons);
}
if (aMessageBoxData->colorScheme != NULL) {
fCustomColorScheme = true;
ApplyAndParseColorScheme(aMessageBoxData->colorScheme);
}
(aMessageBoxData->title[0]) ?
SetTitle(aMessageBoxData->title) : SetTitle(HAIKU_SDL_DefTitle);
(aMessageBoxData->message[0]) ?
SetMessageText(aMessageBoxData->message) : SetMessageText(HAIKU_SDL_DefMessage);
SetType(ConvertMessageBoxType(static_cast<SDL_MessageBoxFlags>(aMessageBoxData->flags)));
}
void
ApplyAndParseColorScheme(const SDL_MessageBoxColorScheme *aColorScheme)
{
SetBackgroundColor(&aColorScheme->colors[SDL_MESSAGEBOX_COLOR_BACKGROUND]);
fTextColor = ConvertColorType(&aColorScheme->colors[SDL_MESSAGEBOX_COLOR_TEXT]);
SetButtonColors(&aColorScheme->colors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER],
&aColorScheme->colors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND],
&aColorScheme->colors[SDL_MESSAGEBOX_COLOR_TEXT],
&aColorScheme->colors[SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED]);
}
void
SetButtonColors(const SDL_MessageBoxColor *aBorderColor,
const SDL_MessageBoxColor *aBackgroundColor,
const SDL_MessageBoxColor *aTextColor,
const SDL_MessageBoxColor *aSelectedColor)
{
if (fCustomColorScheme) {
int32 countButtons = CountButtons();
for (int i = 0; i < countButtons; ++i) {
ButtonAt(i)->SetViewColor(ConvertColorType(aBorderColor));
ButtonAt(i)->SetLowColor(ConvertColorType(aBackgroundColor));
// This doesn't work. See this why:
// https://github.com/haiku/haiku/commit/de9c53f8f5008c7b3b0af75d944a628e17f6dffe
// Let it remain.
ButtonAt(i)->SetHighColor(ConvertColorType(aTextColor));
}
}
// TODO: Not Implemented.
// Is it even necessary?!
(void)aSelectedColor;
}
void
SetBackgroundColor(const SDL_MessageBoxColor *aColor)
{
rgb_color background = ConvertColorType(aColor);
GetLayout()->View()->SetViewColor(background);
// See file "haiku/src/kits/interface/Alert.cpp", the "TAlertView" is the internal name of the left panel.
FindView("TAlertView")->SetViewColor(background);
fMessageBoxTextView->SetViewColor(background);
}
bool
CheckLongLines(const char *aMessage)
{
int final = 0;
// This UTF-8 friendly.
BString message = aMessage;
int32 length = message.CountChars();
for (int i = 0, c = 0; i < length; ++i) {
c++;
if (*(message.CharAt(i)) == '\n') {
c = 0;
}
if (c > final) {
final = c;
}
}
return (final > G_MAX_STRING_LENGTH_BYTES);
}
void
SetMessageText(const char *aMessage)
{
fThereIsLongLine = CheckLongLines(aMessage);
if (fThereIsLongLine) {
fMessageBoxTextView->SetWordWrap(true);
}
rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR);
if (fCustomColorScheme) {
textColor = fTextColor;
}
/*
if (fNoTitledWindow) {
fMessageBoxTextView->SetFontAndColor(be_bold_font);
fMessageBoxTextView->Insert(fTitle);
fMessageBoxTextView->Insert("\n\n");
fMessageBoxTextView->SetFontAndColor(be_plain_font);
}
*/
fMessageBoxTextView->SetFontAndColor(be_plain_font, B_FONT_ALL, &textColor);
fMessageBoxTextView->Insert(aMessage);
// Be sure to call update width method.
UpdateTextViewWidth();
}
void
AddSdlButtons(const SDL_MessageBoxButtonData *aButtons, int aNumButtons)
{
for (int i = 0; i < aNumButtons; ++i) {
fButtons.push_back(&aButtons[i]);
}
std::sort(fButtons.begin(), fButtons.end(), &HAIKU_SDL_MessageBox::SortButtonsPredicate);
size_t countButtons = fButtons.size();
for (size_t i = 0; i < countButtons; ++i) {
switch (fButtons[i]->flags)
{
case SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT:
{
fCloseButton = static_cast<int>(i);
break;
}
case SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT:
{
fDefaultButton = static_cast<int>(i);
break;
}
default:
{
break;
}
}
AddButton(fButtons[i]->text);
}
SetDefaultButton(ButtonAt(fDefaultButton));
}
public:
explicit
HAIKU_SDL_MessageBox(const SDL_MessageBoxData *aMessageBoxData)
: BAlert(NULL, NULL, NULL, NULL, NULL, B_WIDTH_FROM_LABEL, B_WARNING_ALERT),
fComputedMessageBoxWidth(0.0f),
fCloseButton(G_CLOSE_BUTTON_ID), fDefaultButton(G_DEFAULT_BUTTON_ID),
fCustomColorScheme(false), fThereIsLongLine(false),
HAIKU_SDL_DefTitle("SDL MessageBox"),
HAIKU_SDL_DefMessage("Some information has been lost."),
HAIKU_SDL_DefButton("OK")
{
// MessageBox settings.
// We need a title to display it.
SetLook(B_TITLED_WINDOW_LOOK);
SetFlags(Flags() | B_CLOSE_ON_ESCAPE);
// MessageBox TextView settings.
fMessageBoxTextView = TextView();
fMessageBoxTextView->SetWordWrap(false);
fMessageBoxTextView->SetStylable(true);
ParseSdlMessageBoxData(aMessageBoxData);
}
int
GetCloseButtonId(void) const
{
return fCloseButton;
}
virtual
~HAIKU_SDL_MessageBox(void)
{
fButtons.clear();
}
protected:
virtual void
FrameResized(float aNewWidth, float aNewHeight)
{
if (fComputedMessageBoxWidth > aNewWidth) {
ResizeTo(fComputedMessageBoxWidth, aNewHeight);
} else {
BAlert::FrameResized(aNewWidth, aNewHeight);
}
}
virtual void
SetTitle(const char* aTitle)
{
fTitle = aTitle;
BAlert::SetTitle(aTitle);
}
};
#ifdef __cplusplus
extern "C" {
#endif
int HAIKU_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
{
// Initialize button by closed or error value first.
*buttonid = G_CLOSE_BUTTON_ID;
// We need to check "be_app" pointer to "NULL". The "messageboxdata->window" pointer isn't appropriate here
// because it is possible to create a MessageBox from another thread. This fixes the following errors:
// "You need a valid BApplication object before interacting with the app_server."
// "2 BApplication objects were created. Only one is allowed."
std::unique_ptr<BApplication> application;
if (be_app == NULL) {
application = std::unique_ptr<BApplication>(new(std::nothrow) BApplication(SDL_signature));
if (application == NULL) {
return SDL_SetError("Cannot create the BApplication object. Lack of memory?");
}
}
HAIKU_SDL_MessageBox *SDL_MessageBox = new(std::nothrow) HAIKU_SDL_MessageBox(messageboxdata);
if (SDL_MessageBox == NULL) {
return SDL_SetError("Cannot create the HAIKU_SDL_MessageBox (BAlert inheritor) object. Lack of memory?");
}
const int closeButton = SDL_MessageBox->GetCloseButtonId();
int pushedButton = SDL_MessageBox->Go();
// The close button is equivalent to pressing Escape.
if (closeButton != G_CLOSE_BUTTON_ID && pushedButton == G_CLOSE_BUTTON_ID) {
pushedButton = closeButton;
}
// It's deleted by itself after the "Go()" method was executed.
/*
if (messageBox != NULL) {
delete messageBox;
}
*/
// Initialize button by real pushed value then.
*buttonid = pushedButton;
return 0;
}
#ifdef __cplusplus
}
#endif
#endif /* SDL_VIDEO_DRIVER_HAIKU */

View File

@@ -0,0 +1,43 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 2018-2019 EXL <exlmotodev@gmail.com>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_BMESSAGEBOX_H
#define SDL_BMESSAGEBOX_H
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_HAIKU
#ifdef __cplusplus
extern "C" {
#endif
extern int
HAIKU_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
#ifdef __cplusplus
}
#endif
#endif /* SDL_VIDEO_DRIVER_HAIKU */
#endif

View File

@@ -0,0 +1,298 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_HAIKU
#include <AppKit.h>
#include <InterfaceKit.h>
#include "SDL_bmodes.h"
#include "SDL_BWin.h"
#ifdef SDL_VIDEO_OPENGL
#include "SDL_bopengl.h"
#endif
#include "../../core/haiku/SDL_BApp.h"
#ifdef __cplusplus
extern "C" {
#endif
#define WRAP_BMODE 1 /* FIXME: Some debate as to whether this is necessary */
#if WRAP_BMODE
/* This wrapper is here so that the driverdata can be freed without freeing
the display_mode structure */
struct SDL_DisplayModeData {
display_mode *bmode;
};
#endif
static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
return (SDL_BWin *)(window->driverdata);
}
static SDL_INLINE SDL_BLooper *_GetBeLooper() {
return SDL_Looper;
}
static SDL_INLINE display_mode * _ExtractBMode(SDL_DisplayMode *mode) {
#if WRAP_BMODE
return ((SDL_DisplayModeData *)mode->driverdata)->bmode;
#else
return (display_mode *)(mode->driverdata);
#endif
}
/* Copied from haiku/trunk/src/preferences/screen/ScreenMode.cpp */
static float get_refresh_rate(display_mode &mode) {
return float(mode.timing.pixel_clock * 1000)
/ float(mode.timing.h_total * mode.timing.v_total);
}
#if 0
/* TODO:
* This is a useful debugging tool. Uncomment and insert into code as needed.
*/
void _SpoutModeData(display_mode *bmode) {
printf("BMode:\n");
printf("\tw,h = (%i,%i)\n", bmode->virtual_width, bmode->virtual_height);
printf("\th,v = (%i,%i)\n", bmode->h_display_start,
bmode->v_display_start);
if (bmode->flags) {
printf("\tFlags:\n");
if (bmode->flags & B_SCROLL) {
printf("\t\tB_SCROLL\n");
}
if (bmode->flags & B_8_BIT_DAC) {
printf("\t\tB_8_BIT_DAC\n");
}
if (bmode->flags & B_HARDWARE_CURSOR) {
printf("\t\tB_HARDWARE_CURSOR\n");
}
if (bmode->flags & B_PARALLEL_ACCESS) {
printf("\t\tB_PARALLEL_ACCESS\n");
}
if (bmode->flags & B_DPMS) {
printf("\t\tB_DPMS\n");
}
if (bmode->flags & B_IO_FB_NA) {
printf("\t\tB_IO_FB_NA\n");
}
}
printf("\tTiming:\n");
printf("\t\tpx clock: %i\n", bmode->timing.pixel_clock);
printf("\t\th - display: %i sync start: %i sync end: %i total: %i\n",
bmode->timing.h_display, bmode->timing.h_sync_start,
bmode->timing.h_sync_end, bmode->timing.h_total);
printf("\t\tv - display: %i sync start: %i sync end: %i total: %i\n",
bmode->timing.v_display, bmode->timing.v_sync_start,
bmode->timing.v_sync_end, bmode->timing.v_total);
if (bmode->timing.flags) {
printf("\t\tFlags:\n");
if (bmode->timing.flags & B_BLANK_PEDESTAL) {
printf("\t\t\tB_BLANK_PEDESTAL\n");
}
if (bmode->timing.flags & B_TIMING_INTERLACED) {
printf("\t\t\tB_TIMING_INTERLACED\n");
}
if (bmode->timing.flags & B_POSITIVE_HSYNC) {
printf("\t\t\tB_POSITIVE_HSYNC\n");
}
if (bmode->timing.flags & B_POSITIVE_VSYNC) {
printf("\t\t\tB_POSITIVE_VSYNC\n");
}
if (bmode->timing.flags & B_SYNC_ON_GREEN) {
printf("\t\t\tB_SYNC_ON_GREEN\n");
}
}
}
#endif
int32 HAIKU_ColorSpaceToSDLPxFormat(uint32 colorspace)
{
switch (colorspace) {
case B_CMAP8:
return SDL_PIXELFORMAT_INDEX8;
break;
case B_RGB15:
case B_RGBA15:
case B_RGB15_BIG:
case B_RGBA15_BIG:
return SDL_PIXELFORMAT_RGB555;
break;
case B_RGB16:
case B_RGB16_BIG:
return SDL_PIXELFORMAT_RGB565;
break;
case B_RGB24:
case B_RGB24_BIG:
return SDL_PIXELFORMAT_BGR24;
break;
case B_RGB32:
case B_RGBA32:
case B_RGB32_BIG:
case B_RGBA32_BIG:
return SDL_PIXELFORMAT_XRGB8888;
break;
}
/* May never get here, but safer and needed to shut up compiler */
SDL_SetError("Invalid color space");
return 0;
}
static void _BDisplayModeToSdlDisplayMode(display_mode *bmode, SDL_DisplayMode *mode) {
SDL_zerop(mode);
mode->w = bmode->virtual_width;
mode->h = bmode->virtual_height;
mode->refresh_rate = get_refresh_rate(*bmode);
#if WRAP_BMODE
SDL_DisplayModeData *data = (SDL_DisplayModeData*)SDL_calloc(1,
sizeof(SDL_DisplayModeData));
data->bmode = bmode;
mode->driverdata = data;
#else
mode->driverdata = bmode;
#endif
/* Set the format */
mode->format = HAIKU_ColorSpaceToSDLPxFormat(bmode->space);
}
/* Later, there may be more than one monitor available */
static void _AddDisplay(BScreen *screen) {
SDL_DisplayMode mode;
display_mode bmode;
screen->GetMode(&bmode);
_BDisplayModeToSdlDisplayMode(&bmode, &mode);
SDL_AddBasicVideoDisplay(&mode);
}
/*
* Functions called by SDL
*/
int HAIKU_InitModes(SDL_VideoDevice *_this) {
BScreen screen;
/* TODO: When Haiku supports multiple display screens, call
_AddDisplayScreen() for each of them. */
_AddDisplay(&screen);
return 0;
}
int HAIKU_QuitModes(SDL_VideoDevice *_this) {
/* FIXME: Nothing really needs to be done here at the moment? */
return 0;
}
int HAIKU_GetDisplayBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect) {
BScreen bscreen;
BRect rc = bscreen.Frame();
rect->x = (int)rc.left;
rect->y = (int)rc.top;
rect->w = (int)rc.Width() + 1;
rect->h = (int)rc.Height() + 1;
return 0;
}
int HAIKU_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display) {
/* Get the current screen */
BScreen bscreen;
/* Iterate through all of the modes */
SDL_DisplayMode mode;
display_mode this_bmode;
display_mode *bmodes;
uint32 count, i;
/* Get graphics-hardware supported modes */
bscreen.GetModeList(&bmodes, &count);
bscreen.GetMode(&this_bmode);
for (i = 0; i < count; ++i) {
// FIXME: Apparently there are errors with colorspace changes
if (bmodes[i].space == this_bmode.space) {
_BDisplayModeToSdlDisplayMode(&bmodes[i], &mode);
SDL_AddFullscreenDisplayMode(display, &mode);
}
}
free(bmodes); /* This should not be SDL_free() */
return 0;
}
int HAIKU_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode) {
/* Get the current screen */
BScreen bscreen;
if (!bscreen.IsValid()) {
printf(__FILE__": %d - ERROR: BAD SCREEN\n", __LINE__);
}
/* Set the mode using the driver data */
display_mode *bmode = _ExtractBMode(mode);
/* FIXME: Is the first option always going to be the right one? */
uint32 c = 0, i;
display_mode *bmode_list;
bscreen.GetModeList(&bmode_list, &c);
for (i = 0; i < c; ++i) {
if ( bmode_list[i].space == bmode->space &&
bmode_list[i].virtual_width == bmode->virtual_width &&
bmode_list[i].virtual_height == bmode->virtual_height ) {
bmode = &bmode_list[i];
break;
}
}
if (bscreen.SetMode(bmode) != B_OK) {
return SDL_SetError("Bad video mode");
}
free(bmode_list); /* This should not be SDL_free() */
#ifdef SDL_VIDEO_OPENGL
/* FIXME: Is there some way to reboot the OpenGL context? This doesn't
help */
// HAIKU_GL_RebootContexts(_this);
#endif
return 0;
}
#ifdef __cplusplus
}
#endif
#endif /* SDL_VIDEO_DRIVER_HAIKU */

View File

@@ -0,0 +1,45 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_BMODES_H
#define SDL_BMODES_H
#ifdef __cplusplus
extern "C" {
#endif
#include "../SDL_sysvideo.h"
extern int32 HAIKU_ColorSpaceToSDLPxFormat(uint32 colorspace);
extern int HAIKU_InitModes(SDL_VideoDevice *_this);
extern int HAIKU_QuitModes(SDL_VideoDevice *_this);
extern int HAIKU_GetDisplayBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display,
SDL_Rect *rect);
extern int HAIKU_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display);
extern int HAIKU_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display,
SDL_DisplayMode *mode);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,195 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if defined(SDL_VIDEO_DRIVER_HAIKU) && defined(SDL_VIDEO_OPENGL)
#include "SDL_bopengl.h"
#include <unistd.h>
#include <KernelKit.h>
#include <OpenGLKit.h>
#include "SDL_BWin.h"
#include "../../core/haiku/SDL_BApp.h"
#ifdef __cplusplus
extern "C" {
#endif
static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
return (SDL_BWin *)(window->driverdata);
}
static SDL_INLINE SDL_BLooper *_GetBeLooper() {
return SDL_Looper;
}
/* Passing a NULL path means load pointers from the application */
int HAIKU_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path)
{
/* FIXME: Is this working correctly? */
image_info info;
int32 cookie = 0;
while (get_next_image_info(0, &cookie, &info) == B_OK) {
void *location = NULL;
if ( get_image_symbol(info.id, "glBegin", B_SYMBOL_TYPE_ANY,
&location) == B_OK) {
_this->gl_config.dll_handle = (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));
}
}
return 0;
}
SDL_FunctionPointer HAIKU_GL_GetProcAddress(SDL_VideoDevice *_this, const char *proc)
{
if (_this->gl_config.dll_handle != NULL) {
void *location = NULL;
status_t err;
if ((err =
get_image_symbol((image_id) (addr_t) _this->gl_config.dll_handle,
proc, B_SYMBOL_TYPE_ANY,
&location)) == B_OK) {
return (SDL_FunctionPointer)location;
} else {
SDL_SetError("Couldn't find OpenGL symbol");
return NULL;
}
} else {
SDL_SetError("OpenGL library not loaded");
return NULL;
}
}
int HAIKU_GL_SwapWindow(SDL_VideoDevice *_this, SDL_Window * window) {
_ToBeWin(window)->SwapBuffers();
return 0;
}
int HAIKU_GL_MakeCurrent(SDL_VideoDevice *_this, SDL_Window * window, SDL_GLContext context) {
BGLView* glView = (BGLView*)context;
// printf("HAIKU_GL_MakeCurrent(%llx), win = %llx, thread = %d\n", (uint64)context, (uint64)window, find_thread(NULL));
if (glView != NULL) {
if ((glView->Window() == NULL) || (window == NULL) || (_ToBeWin(window)->GetGLView() != glView)) {
return SDL_SetError("MakeCurrent failed");
}
}
_GetBeLooper()->SetCurrentContext(glView);
return 0;
}
SDL_GLContext HAIKU_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window * window) {
/* FIXME: Not sure what flags should be included here; may want to have
most of them */
SDL_BWin *bwin = _ToBeWin(window);
// printf("HAIKU_GL_CreateContext, win = %llx, thread = %d\n", (uint64)window, find_thread(NULL));
if (bwin->GetGLView() != NULL) {
SDL_SetError("Context already creaded");
return NULL;
}
Uint32 gl_flags = BGL_RGB;
if (_this->gl_config.alpha_size) {
gl_flags |= BGL_ALPHA;
}
if (_this->gl_config.depth_size) {
gl_flags |= BGL_DEPTH;
}
if (_this->gl_config.stencil_size) {
gl_flags |= BGL_STENCIL;
}
if (_this->gl_config.double_buffer) {
gl_flags |= BGL_DOUBLE;
} else {
gl_flags |= BGL_SINGLE;
}
if (_this->gl_config.accum_red_size ||
_this->gl_config.accum_green_size ||
_this->gl_config.accum_blue_size ||
_this->gl_config.accum_alpha_size) {
gl_flags |= BGL_ACCUM;
}
#if __GNUC__ > 3
if (_this->gl_config.share_with_current_context) {
gl_flags |= BGL_SHARE_CONTEXT;
}
#endif
bwin->CreateGLView(gl_flags);
_GetBeLooper()->SetCurrentContext(bwin->GetGLView());
return (SDL_GLContext)(bwin->GetGLView());
}
int HAIKU_GL_DeleteContext(SDL_VideoDevice *_this, SDL_GLContext context) {
// printf("HAIKU_GL_DeleteContext(%llx), thread = %d\n", (uint64)context, find_thread(NULL));
BGLView* glView = (BGLView*)context;
SDL_BWin *bwin = (SDL_BWin*)glView->Window();
if (bwin == NULL) {
delete glView;
} else {
bwin->RemoveGLView();
}
return 0;
}
int HAIKU_GL_SetSwapInterval(SDL_VideoDevice *_this, int interval) {
/* TODO: Implement this, if necessary? */
return SDL_Unsupported();
}
int HAIKU_GL_GetSwapInterval(SDL_VideoDevice *_this, int *interval) {
return SDL_Unsupported();
}
void HAIKU_GL_UnloadLibrary(SDL_VideoDevice *_this) {
/* TODO: Implement this, if necessary? */
}
/* FIXME: This function is meant to clear the OpenGL context when the video
mode changes (see SDL_bmodes.cc), but it doesn't seem to help, and is not
currently in use. */
void HAIKU_GL_RebootContexts(SDL_VideoDevice *_this) {
SDL_Window *window = _this->windows;
while (window) {
SDL_BWin *bwin = _ToBeWin(window);
if (bwin->GetGLView()) {
bwin->LockLooper();
bwin->RemoveGLView();
bwin->CreateGLView(bwin->GetGLType());
bwin->UnlockLooper();
}
window = window->next;
}
}
#ifdef __cplusplus
}
#endif
#endif /* SDL_VIDEO_DRIVER_HAIKU && SDL_VIDEO_OPENGL */

View File

@@ -0,0 +1,52 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_BOPENGL_H
#define SDL_BOPENGL_H
#if defined(SDL_VIDEO_DRIVER_HAIKU) && defined(SDL_VIDEO_OPENGL)
#ifdef __cplusplus
extern "C" {
#endif
#include "../SDL_sysvideo.h"
extern int HAIKU_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path); /* FIXME */
extern SDL_FunctionPointer HAIKU_GL_GetProcAddress(SDL_VideoDevice *_this, const char *proc); /* FIXME */
extern void HAIKU_GL_UnloadLibrary(SDL_VideoDevice *_this); /* TODO */
extern int HAIKU_GL_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window,
SDL_GLContext context);
extern int HAIKU_GL_SetSwapInterval(SDL_VideoDevice *_this, int interval); /* TODO */
extern int HAIKU_GL_GetSwapInterval(SDL_VideoDevice *_this, int *interval); /* TODO */
extern int HAIKU_GL_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern SDL_GLContext HAIKU_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window);
extern int HAIKU_GL_DeleteContext(SDL_VideoDevice *_this, SDL_GLContext context);
extern void HAIKU_GL_RebootContexts(SDL_VideoDevice *_this);
#ifdef __cplusplus
}
#endif
#endif /* SDL_VIDEO_DRIVER_HAIKU && SDL_VIDEO_OPENGL */
#endif

View File

@@ -0,0 +1,307 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#include "../../core/haiku/SDL_BApp.h"
#ifdef SDL_VIDEO_DRIVER_HAIKU
#include "SDL_BWin.h"
#include <Url.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "SDL_bkeyboard.h"
#include "SDL_bwindow.h"
#include "SDL_bclipboard.h"
#include "SDL_bvideo.h"
#include "SDL_bopengl.h"
#include "SDL_bmodes.h"
#include "SDL_bframebuffer.h"
#include "SDL_bevents.h"
static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
return (SDL_BWin *)(window->driverdata);
}
/* FIXME: Undefined functions */
// #define HAIKU_PumpEvents NULL
#define HAIKU_StartTextInput NULL
#define HAIKU_StopTextInput NULL
#define HAIKU_SetTextInputRect NULL
// #define HAIKU_DeleteDevice NULL
/* End undefined functions */
static SDL_VideoDevice * HAIKU_CreateDevice(void)
{
SDL_VideoDevice *device;
/* Initialize all variables that we clean on shutdown */
device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
device->driverdata = NULL; /* FIXME: Is this the cause of some of the
SDL_Quit() errors? */
/* TODO: Figure out if any initialization needs to go here */
/* Set the function pointers */
device->VideoInit = HAIKU_VideoInit;
device->VideoQuit = HAIKU_VideoQuit;
device->GetDisplayBounds = HAIKU_GetDisplayBounds;
device->GetDisplayModes = HAIKU_GetDisplayModes;
device->SetDisplayMode = HAIKU_SetDisplayMode;
device->PumpEvents = HAIKU_PumpEvents;
device->CreateSDLWindow = HAIKU_CreateWindow;
device->CreateSDLWindowFrom = HAIKU_CreateWindowFrom;
device->SetWindowTitle = HAIKU_SetWindowTitle;
device->SetWindowPosition = HAIKU_SetWindowPosition;
device->SetWindowSize = HAIKU_SetWindowSize;
device->ShowWindow = HAIKU_ShowWindow;
device->HideWindow = HAIKU_HideWindow;
device->RaiseWindow = HAIKU_RaiseWindow;
device->MaximizeWindow = HAIKU_MaximizeWindow;
device->MinimizeWindow = HAIKU_MinimizeWindow;
device->RestoreWindow = HAIKU_RestoreWindow;
device->SetWindowBordered = HAIKU_SetWindowBordered;
device->SetWindowResizable = HAIKU_SetWindowResizable;
device->SetWindowFullscreen = HAIKU_SetWindowFullscreen;
device->SetWindowMouseGrab = HAIKU_SetWindowMouseGrab;
device->SetWindowMinimumSize = HAIKU_SetWindowMinimumSize;
device->DestroyWindow = HAIKU_DestroyWindow;
device->GetWindowWMInfo = HAIKU_GetWindowWMInfo;
device->CreateWindowFramebuffer = HAIKU_CreateWindowFramebuffer;
device->UpdateWindowFramebuffer = HAIKU_UpdateWindowFramebuffer;
device->DestroyWindowFramebuffer = HAIKU_DestroyWindowFramebuffer;
#ifdef SDL_VIDEO_OPENGL
device->GL_LoadLibrary = HAIKU_GL_LoadLibrary;
device->GL_GetProcAddress = HAIKU_GL_GetProcAddress;
device->GL_UnloadLibrary = HAIKU_GL_UnloadLibrary;
device->GL_CreateContext = HAIKU_GL_CreateContext;
device->GL_MakeCurrent = HAIKU_GL_MakeCurrent;
device->GL_SetSwapInterval = HAIKU_GL_SetSwapInterval;
device->GL_GetSwapInterval = HAIKU_GL_GetSwapInterval;
device->GL_SwapWindow = HAIKU_GL_SwapWindow;
device->GL_DeleteContext = HAIKU_GL_DeleteContext;
#endif
device->StartTextInput = HAIKU_StartTextInput;
device->StopTextInput = HAIKU_StopTextInput;
device->SetTextInputRect = HAIKU_SetTextInputRect;
device->SetClipboardText = HAIKU_SetClipboardText;
device->GetClipboardText = HAIKU_GetClipboardText;
device->HasClipboardText = HAIKU_HasClipboardText;
device->free = HAIKU_DeleteDevice;
return device;
}
VideoBootStrap HAIKU_bootstrap = {
"haiku", "Haiku graphics",
HAIKU_CreateDevice
};
void HAIKU_DeleteDevice(SDL_VideoDevice * device)
{
SDL_free(device->driverdata);
SDL_free(device);
}
static SDL_Cursor * HAIKU_CreateSystemCursor(SDL_SystemCursor id)
{
SDL_Cursor *cursor;
BCursorID cursorId = B_CURSOR_ID_SYSTEM_DEFAULT;
switch(id)
{
default:
SDL_assert(0);
return NULL;
case SDL_SYSTEM_CURSOR_ARROW: cursorId = B_CURSOR_ID_SYSTEM_DEFAULT; break;
case SDL_SYSTEM_CURSOR_IBEAM: cursorId = B_CURSOR_ID_I_BEAM; break;
case SDL_SYSTEM_CURSOR_WAIT: cursorId = B_CURSOR_ID_PROGRESS; break;
case SDL_SYSTEM_CURSOR_CROSSHAIR: cursorId = B_CURSOR_ID_CROSS_HAIR; break;
case SDL_SYSTEM_CURSOR_WAITARROW: cursorId = B_CURSOR_ID_PROGRESS; break;
case SDL_SYSTEM_CURSOR_SIZENWSE: cursorId = B_CURSOR_ID_RESIZE_NORTH_WEST_SOUTH_EAST; break;
case SDL_SYSTEM_CURSOR_SIZENESW: cursorId = B_CURSOR_ID_RESIZE_NORTH_EAST_SOUTH_WEST; break;
case SDL_SYSTEM_CURSOR_SIZEWE: cursorId = B_CURSOR_ID_RESIZE_EAST_WEST; break;
case SDL_SYSTEM_CURSOR_SIZENS: cursorId = B_CURSOR_ID_RESIZE_NORTH_SOUTH; break;
case SDL_SYSTEM_CURSOR_SIZEALL: cursorId = B_CURSOR_ID_MOVE; break;
case SDL_SYSTEM_CURSOR_NO: cursorId = B_CURSOR_ID_NOT_ALLOWED; break;
case SDL_SYSTEM_CURSOR_HAND: cursorId = B_CURSOR_ID_FOLLOW_LINK; break;
}
cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor));
if (cursor) {
cursor->driverdata = (void *)new BCursor(cursorId);
} else {
SDL_OutOfMemory();
}
return cursor;
}
static SDL_Cursor * HAIKU_CreateDefaultCursor()
{
return HAIKU_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
}
static void HAIKU_FreeCursor(SDL_Cursor * cursor)
{
if (cursor->driverdata) {
delete (BCursor*) cursor->driverdata;
}
SDL_free(cursor);
}
static SDL_Cursor * HAIKU_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
{
SDL_Cursor *cursor;
SDL_Surface *converted;
converted = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ARGB8888);
if (converted == NULL) {
return NULL;
}
BBitmap *cursorBitmap = new BBitmap(BRect(0, 0, surface->w - 1, surface->h - 1), B_RGBA32);
cursorBitmap->SetBits(converted->pixels, converted->h * converted->pitch, 0, B_RGBA32);
SDL_DestroySurface(converted);
cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor));
if (cursor) {
cursor->driverdata = (void *)new BCursor(cursorBitmap, BPoint(hot_x, hot_y));
} else {
return NULL;
}
return cursor;
}
static int HAIKU_ShowCursor(SDL_Cursor *cursor)
{
SDL_Mouse *mouse = SDL_GetMouse();
if (mouse == NULL) {
return 0;
}
if (cursor) {
BCursor *hCursor = (BCursor*)cursor->driverdata;
be_app->SetCursor(hCursor);
} else {
BCursor *hCursor = new BCursor(B_CURSOR_ID_NO_CURSOR);
be_app->SetCursor(hCursor);
delete hCursor;
}
return 0;
}
static int HAIKU_SetRelativeMouseMode(SDL_bool enabled)
{
SDL_Window *window = SDL_GetMouseFocus();
if (window == NULL) {
return 0;
}
SDL_BWin *bewin = _ToBeWin(window);
BGLView *_SDL_GLView = bewin->GetGLView();
bewin->Lock();
if (enabled)
_SDL_GLView->SetEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY);
else
_SDL_GLView->SetEventMask(0, 0);
bewin->Unlock();
return 0;
}
static void HAIKU_MouseInit(SDL_VideoDevice *_this)
{
SDL_Mouse *mouse = SDL_GetMouse();
if (mouse == NULL) {
return;
}
mouse->CreateCursor = HAIKU_CreateCursor;
mouse->CreateSystemCursor = HAIKU_CreateSystemCursor;
mouse->ShowCursor = HAIKU_ShowCursor;
mouse->FreeCursor = HAIKU_FreeCursor;
mouse->SetRelativeMouseMode = HAIKU_SetRelativeMouseMode;
SDL_SetDefaultCursor(HAIKU_CreateDefaultCursor());
}
int HAIKU_VideoInit(SDL_VideoDevice *_this)
{
/* Initialize the Be Application for appserver interaction */
if (SDL_InitBeApp() < 0) {
return -1;
}
/* Initialize video modes */
HAIKU_InitModes(_this);
/* Init the keymap */
HAIKU_InitOSKeymap();
HAIKU_MouseInit(_this);
#ifdef SDL_VIDEO_OPENGL
/* testgl application doesn't load library, just tries to load symbols */
/* is it correct? if so we have to load library here */
HAIKU_GL_LoadLibrary(_this, NULL);
#endif
/* We're done! */
return 0;
}
void HAIKU_VideoQuit(SDL_VideoDevice *_this)
{
HAIKU_QuitModes(_this);
SDL_QuitBeApp();
}
// just sticking this function in here so it's in a C++ source file.
extern "C" { int HAIKU_OpenURL(const char *url); }
int HAIKU_OpenURL(const char *url)
{
BUrl burl(url);
const status_t rc = burl.OpenWithPreferredApplication(false);
return (rc == B_NO_ERROR) ? 0 : SDL_SetError("URL open failed (err=%d)", (int)rc);
}
#ifdef __cplusplus
}
#endif
#endif /* SDL_VIDEO_DRIVER_HAIKU */

View File

@@ -0,0 +1,40 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BVIDEO_H
#define BVIDEO_H
#ifdef __cplusplus
extern "C" {
#endif
#include "../../core/haiku/SDL_BeApp.h"
#include "../SDL_sysvideo.h"
extern void HAIKU_VideoQuit(SDL_VideoDevice *_this);
extern int HAIKU_VideoInit(SDL_VideoDevice *_this);
extern void HAIKU_DeleteDevice(SDL_VideoDevice *_this);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,225 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_HAIKU
#include "../SDL_sysvideo.h"
#include "SDL_BWin.h"
#include <new>
#include <SDL3/SDL_syswm.h>
/* Define a path to window's BWIN data */
#ifdef __cplusplus
extern "C" {
#endif
static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
return (SDL_BWin *)(window->driverdata);
}
static SDL_INLINE SDL_BLooper *_GetBeLooper() {
return SDL_Looper;
}
static int _InitWindow(SDL_VideoDevice *_this, SDL_Window *window) {
uint32 flags = 0;
window_look look = B_TITLED_WINDOW_LOOK;
BRect bounds(
window->x,
window->y,
window->x + window->w - 1, //BeWindows have an off-by-one px w/h thing
window->y + window->h - 1
);
if (window->flags & SDL_WINDOW_FULLSCREEN) {
/* TODO: Add support for this flag */
printf(__FILE__": %d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",__LINE__);
}
if (window->flags & SDL_WINDOW_OPENGL) {
/* TODO: Add support for this flag */
}
if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
flags |= B_NOT_RESIZABLE | B_NOT_ZOOMABLE;
}
if (window->flags & SDL_WINDOW_BORDERLESS) {
look = B_NO_BORDER_WINDOW_LOOK;
}
SDL_BWin *bwin = new(std::nothrow) SDL_BWin(bounds, look, flags);
if (bwin == NULL) {
return -1;
}
window->driverdata = (SDL_WindowData *)bwin;
int32 winID = _GetBeLooper()->GetID(window);
bwin->SetID(winID);
return 0;
}
int HAIKU_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window) {
if (_InitWindow(_this, window) < 0) {
return -1;
}
/* Start window loop */
_ToBeWin(window)->Show();
return 0;
}
int HAIKU_CreateWindowFrom(SDL_VideoDevice *_this, SDL_Window * window, const void *data) {
SDL_BWin *otherBWin = (SDL_BWin*)data;
if (!otherBWin->LockLooper()) {
return -1;
}
/* Create the new window and initialize its members */
window->x = (int)otherBWin->Frame().left;
window->y = (int)otherBWin->Frame().top;
window->w = (int)otherBWin->Frame().Width();
window->h = (int)otherBWin->Frame().Height();
/* Set SDL flags */
if (!(otherBWin->Flags() & B_NOT_RESIZABLE)) {
window->flags |= SDL_WINDOW_RESIZABLE;
}
/* If we are out of memory, return the error code */
if (_InitWindow(_this, window) < 0) {
return -1;
}
/* TODO: Add any other SDL-supported window attributes here */
_ToBeWin(window)->SetTitle(otherBWin->Title());
/* Start window loop and unlock the other window */
_ToBeWin(window)->Show();
otherBWin->UnlockLooper();
return 0;
}
void HAIKU_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window * window) {
BMessage msg(BWIN_SET_TITLE);
msg.AddString("window-title", window->title);
_ToBeWin(window)->PostMessage(&msg);
}
void HAIKU_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window * window) {
BMessage msg(BWIN_MOVE_WINDOW);
msg.AddInt32("window-x", window->x);
msg.AddInt32("window-y", window->y);
_ToBeWin(window)->PostMessage(&msg);
}
void HAIKU_SetWindowSize(SDL_VideoDevice *_this, SDL_Window * window) {
BMessage msg(BWIN_RESIZE_WINDOW);
msg.AddInt32("window-w", window->w - 1);
msg.AddInt32("window-h", window->h - 1);
_ToBeWin(window)->PostMessage(&msg);
}
void HAIKU_SetWindowBordered(SDL_VideoDevice *_this, SDL_Window * window, SDL_bool bordered) {
BMessage msg(BWIN_SET_BORDERED);
msg.AddBool("window-border", bordered != SDL_FALSE);
_ToBeWin(window)->PostMessage(&msg);
}
void HAIKU_SetWindowResizable(SDL_VideoDevice *_this, SDL_Window * window, SDL_bool resizable) {
BMessage msg(BWIN_SET_RESIZABLE);
msg.AddBool("window-resizable", resizable != SDL_FALSE);
_ToBeWin(window)->PostMessage(&msg);
}
void HAIKU_ShowWindow(SDL_VideoDevice *_this, SDL_Window * window) {
BMessage msg(BWIN_SHOW_WINDOW);
_ToBeWin(window)->PostMessage(&msg);
}
void HAIKU_HideWindow(SDL_VideoDevice *_this, SDL_Window * window) {
BMessage msg(BWIN_HIDE_WINDOW);
_ToBeWin(window)->PostMessage(&msg);
}
void HAIKU_RaiseWindow(SDL_VideoDevice *_this, SDL_Window * window) {
BMessage msg(BWIN_SHOW_WINDOW); /* Activate this window and move to front */
_ToBeWin(window)->PostMessage(&msg);
}
void HAIKU_MaximizeWindow(SDL_VideoDevice *_this, SDL_Window * window) {
BMessage msg(BWIN_MAXIMIZE_WINDOW);
_ToBeWin(window)->PostMessage(&msg);
}
void HAIKU_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window * window) {
BMessage msg(BWIN_MINIMIZE_WINDOW);
_ToBeWin(window)->PostMessage(&msg);
}
void HAIKU_RestoreWindow(SDL_VideoDevice *_this, SDL_Window * window) {
BMessage msg(BWIN_RESTORE_WINDOW);
_ToBeWin(window)->PostMessage(&msg);
}
void HAIKU_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window * window,
SDL_VideoDisplay * display, SDL_bool fullscreen) {
/* Haiku tracks all video display information */
BMessage msg(BWIN_FULLSCREEN);
msg.AddBool("fullscreen", fullscreen);
_ToBeWin(window)->PostMessage(&msg);
}
void HAIKU_SetWindowMinimumSize(SDL_VideoDevice *_this, SDL_Window * window) {
BMessage msg(BWIN_MINIMUM_SIZE_WINDOW);
msg.AddInt32("window-w", window->w -1);
msg.AddInt32("window-h", window->h -1);
_ToBeWin(window)->PostMessage(&msg);
}
void HAIKU_SetWindowMouseGrab(SDL_VideoDevice *_this, SDL_Window * window, SDL_bool grabbed) {
/* TODO: Implement this! */
}
void HAIKU_DestroyWindow(SDL_VideoDevice *_this, SDL_Window * window) {
_ToBeWin(window)->LockLooper(); /* This MUST be locked */
_GetBeLooper()->ClearID(_ToBeWin(window));
_ToBeWin(window)->Quit();
window->driverdata = NULL;
}
int HAIKU_GetWindowWMInfo(SDL_VideoDevice *_this, SDL_Window *window, struct SDL_SysWMinfo *info)
{
info->subsystem = SDL_SYSWM_HAIKU;
return 0;
}
#ifdef __cplusplus
}
#endif
#endif /* SDL_VIDEO_DRIVER_HAIKU */

View File

@@ -0,0 +1,46 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_BWINDOW_H
#define SDL_BWINDOW_H
#include "../SDL_sysvideo.h"
extern int HAIKU_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern int HAIKU_CreateWindowFrom(SDL_VideoDevice *_this, SDL_Window *window, const void *data);
extern void HAIKU_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window);
extern int HAIKU_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window);
extern void HAIKU_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window);
extern void HAIKU_SetWindowMinimumSize(SDL_VideoDevice *_this, SDL_Window *window);
extern void HAIKU_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void HAIKU_HideWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void HAIKU_RaiseWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void HAIKU_MaximizeWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void HAIKU_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void HAIKU_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void HAIKU_SetWindowBordered(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool bordered);
extern void HAIKU_SetWindowResizable(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool resizable);
extern void HAIKU_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
extern void HAIKU_SetWindowMouseGrab(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool grabbed);
extern void HAIKU_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern int HAIKU_GetWindowWMInfo(SDL_VideoDevice *_this, SDL_Window *window, struct SDL_SysWMinfo *info);
#endif