Fixed crash if initialization of EGL failed but was tried again later.

The internal function SDL_EGL_LoadLibrary() did not delete and remove a mostly
uninitialized data structure if loading the library first failed. A later try to
use EGL then skipped initialization and assumed it was previously successful
because the data structure now already existed. This led to at least one crash
in the internal function SDL_EGL_ChooseConfig() because a NULL pointer was
dereferenced to make a call to eglBindAPI().
This commit is contained in:
Philipp Wiesemann
2015-06-21 17:33:46 +02:00
commit 0e45984fa0
1596 changed files with 468120 additions and 0 deletions

638
src/video/haiku/SDL_BWin.h Normal file
View File

@@ -0,0 +1,638 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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.h"
#include "SDL_syswm.h"
#include "SDL_bframebuffer.h"
#ifdef __cplusplus
}
#endif
#include <stdio.h>
#include <AppKit.h>
#include <InterfaceKit.h>
#include <be/game/DirectWindow.h>
#if SDL_VIDEO_OPENGL
#include <be/opengl/GLView.h>
#endif
#include "SDL_events.h"
#include "../../main/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_FULLSCREEN
};
class SDL_BWin:public BDirectWindow
{
public:
/* Constructor/Destructor */
SDL_BWin(BRect bounds, window_look look, uint32 flags)
: BDirectWindow(bounds, "Untitled", look, B_NORMAL_WINDOW_FEEL, flags)
{
_last_buttons = 0;
#if SDL_VIDEO_OPENGL
_SDL_GLView = NULL;
#endif
_shown = false;
_inhibit_resize = false;
_mouse_focused = false;
_prev_frame = NULL;
/* Handle framebuffer stuff */
_connected = _connection_disabled = false;
_buffer_created = _buffer_dirty = false;
_trash_window_buffer = false;
_buffer_locker = new BLocker();
_bitmap = NULL;
_clips = NULL;
#ifdef DRAWTHREAD
_draw_thread_id = spawn_thread(BE_DrawThread, "drawing_thread",
B_NORMAL_PRIORITY, (void*) this);
resume_thread(_draw_thread_id);
#endif
}
virtual ~ SDL_BWin()
{
Lock();
_connection_disabled = true;
int32 result;
#if SDL_VIDEO_OPENGL
if (_SDL_GLView) {
_SDL_GLView->UnlockGL();
RemoveChild(_SDL_GLView); /* Why was this outside the if
statement before? */
}
#endif
Unlock();
#if SDL_VIDEO_OPENGL
if (_SDL_GLView) {
delete _SDL_GLView;
}
#endif
/* Clean up framebuffer stuff */
_buffer_locker->Lock();
#ifdef DRAWTHREAD
wait_for_thread(_draw_thread_id, &result);
#endif
free(_clips);
delete _buffer_locker;
}
/* * * * * OpenGL functionality * * * * */
#if SDL_VIDEO_OPENGL
virtual 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);
}
AddChild(_SDL_GLView);
_SDL_GLView->EnableDirectMode(true);
_SDL_GLView->LockGL(); /* "New" GLViews are created */
Unlock();
return (_SDL_GLView);
}
virtual void RemoveGLView() {
Lock();
if(_SDL_GLView) {
_SDL_GLView->UnlockGL();
RemoveChild(_SDL_GLView);
}
Unlock();
}
virtual void SwapBuffers(void) {
_SDL_GLView->UnlockGL();
_SDL_GLView->LockGL();
_SDL_GLView->SwapBuffers();
}
#endif
/* * * * * Framebuffering* * * * */
virtual void DirectConnected(direct_buffer_info *info) {
if(!_connected && _connection_disabled) {
return;
}
/* Determine if the pixel buffer is usable after this update */
_trash_window_buffer = _trash_window_buffer
|| ((info->buffer_state & B_BUFFER_RESIZED)
|| (info->buffer_state & B_BUFFER_RESET)
|| (info->driver_state == B_MODE_CHANGED));
LockBuffer();
switch(info->buffer_state & B_DIRECT_MODE_MASK) {
case B_DIRECT_START:
_connected = true;
case B_DIRECT_MODIFY:
if(_clips) {
free(_clips);
_clips = NULL;
}
_num_clips = info->clip_list_count;
_clips = (clipping_rect *)malloc(_num_clips*sizeof(clipping_rect));
if(_clips) {
memcpy(_clips, info->clip_list,
_num_clips*sizeof(clipping_rect));
_bits = (uint8*) info->bits;
_row_bytes = info->bytes_per_row;
_bounds = info->window_bounds;
_bytes_per_px = info->bits_per_pixel / 8;
_buffer_dirty = true;
}
break;
case B_DIRECT_STOP:
_connected = false;
break;
}
#if SDL_VIDEO_OPENGL
if(_SDL_GLView) {
_SDL_GLView->DirectConnected(info);
}
#endif
/* Call the base object directconnected */
BDirectWindow::DirectConnected(info);
UnlockBuffer();
}
/* * * * * 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 */
BDirectWindow::FrameMoved(origin);
}
virtual 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 */
BDirectWindow::FrameResized(width, height);
}
virtual bool QuitRequested() {
BMessage msg(BAPP_WINDOW_CLOSE_REQUESTED);
_PostWindowEvent(msg);
/* We won't allow a quit unless asked by DestroyWindow() */
return false;
}
virtual void WindowActivated(bool active) {
BMessage msg(BAPP_KEYBOARD_FOCUS); /* Mouse focus sold separately */
_PostWindowEvent(msg);
}
virtual 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 */
BDirectWindow::Zoom(origin, width, height);
}
/* Member functions */
virtual void Show() {
while(IsHidden()) {
BDirectWindow::Show();
}
_shown = true;
BMessage msg(BAPP_SHOW);
_PostWindowEvent(msg);
}
virtual void Hide() {
BDirectWindow::Hide();
_shown = false;
BMessage msg(BAPP_HIDE);
_PostWindowEvent(msg);
}
virtual void Minimize(bool minimize) {
BDirectWindow::Minimize(minimize);
int32 minState = (minimize ? BAPP_MINIMIZE : BAPP_RESTORE);
BMessage msg(minState);
_PostWindowEvent(msg);
}
/* BView message interruption */
virtual 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);
}
/* 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? */
if (msg->FindInt32("buttons", &buttons) == B_OK) {
_MouseButtonEvent(buttons);
}
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);
}
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:
case B_UNMAPPED_KEY_DOWN: /* modifier keys are unmapped */
if (msg->FindInt32("key", &key) == B_OK) {
_KeyEvent((SDL_Scancode)key, 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, 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.. */
/* BDirectWindow::DispatchMessage(msg, target); */
break;
}
BDirectWindow::DispatchMessage(msg, target);
}
/* Handle command messages */
virtual 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:
_SetBordered(message);
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:
_SetFullScreen(message);
break;
default:
/* Perform normal message handling */
BDirectWindow::MessageReceived(message);
break;
}
}
/* Accessor methods */
bool IsShown() { return _shown; }
int32 GetID() { return _id; }
uint32 GetRowBytes() { return _row_bytes; }
int32 GetFbX() { return _bounds.left; }
int32 GetFbY() { return _bounds.top; }
bool ConnectionEnabled() { return !_connection_disabled; }
bool Connected() { return _connected; }
clipping_rect *GetClips() { return _clips; }
int32 GetNumClips() { return _num_clips; }
uint8* GetBufferPx() { return _bits; }
int32 GetBytesPerPx() { return _bytes_per_px; }
bool CanTrashWindowBuffer() { return _trash_window_buffer; }
bool BufferExists() { return _buffer_created; }
bool BufferIsDirty() { return _buffer_dirty; }
BBitmap *GetBitmap() { return _bitmap; }
#if SDL_VIDEO_OPENGL
BGLView *GetGLView() { return _SDL_GLView; }
#endif
/* Setter methods */
void SetID(int32 id) { _id = id; }
void SetBufferExists(bool bufferExists) { _buffer_created = bufferExists; }
void LockBuffer() { _buffer_locker->Lock(); }
void UnlockBuffer() { _buffer_locker->Unlock(); }
void SetBufferDirty(bool bufferDirty) { _buffer_dirty = bufferDirty; }
void SetTrashBuffer(bool trash) { _trash_window_buffer = trash; }
void SetBitmap(BBitmap *bitmap) { _bitmap = 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) {
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);
}
if(buttonStateChange & B_SECONDARY_MOUSE_BUTTON) {
_SendMouseButton(SDL_BUTTON_RIGHT, buttons &
B_PRIMARY_MOUSE_BUTTON);
}
if(buttonStateChange & B_TERTIARY_MOUSE_BUTTON) {
_SendMouseButton(SDL_BUTTON_MIDDLE, buttons &
B_PRIMARY_MOUSE_BUTTON);
}
_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, 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);
be_app->PostMessage(&msg);
/* Apparently SDL only uses the scancode */
}
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);
be_app->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;
}
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;
}
ResizeTo(w, h);
}
void _SetBordered(BMessage *msg) {
bool bEnabled;
if(msg->FindBool("window-border", &bEnabled) != B_OK) {
return;
}
SetLook(bEnabled ? B_BORDERED_WINDOW_LOOK : B_NO_BORDER_WINDOW_LOOK);
}
void _Restore() {
if(IsMinimized()) {
Minimize(false);
} else if(IsHidden()) {
Show();
} else if(_prev_frame != NULL) { /* Zoomed */
MoveTo(_prev_frame->left, _prev_frame->top);
ResizeTo(_prev_frame->Width(), _prev_frame->Height());
}
}
void _SetFullScreen(BMessage *msg) {
bool fullscreen;
if(
msg->FindBool("fullscreen", &fullscreen) != B_OK
) {
return;
}
SetFullScreen(fullscreen);
}
/* Members */
#if SDL_VIDEO_OPENGL
BGLView * _SDL_GLView;
#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 */
/* Framebuffer members */
bool _connected,
_connection_disabled,
_buffer_created,
_buffer_dirty,
_trash_window_buffer;
uint8 *_bits;
uint32 _row_bytes;
clipping_rect _bounds;
BLocker *_buffer_locker;
clipping_rect *_clips;
int32 _num_clips;
int32 _bytes_per_px;
thread_id _draw_thread_id;
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

View File

@@ -0,0 +1,95 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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 SDL_VIDEO_DRIVER_HAIKU
/* BWindow based framebuffer implementation */
#include <unistd.h>
#include <TypeConstants.h>
#include "SDL_BWin.h"
#include "SDL_timer.h"
#include "../SDL_sysvideo.h"
#ifdef __cplusplus
extern "C" {
#endif
int BE_SetClipboardText(_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 *BE_GetClipboardText(_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);
} else {
be_clipboard->Unlock();
}
be_clipboard->Unlock();
}
if (!text) {
result = SDL_strdup("");
} else {
/* Copy the data and pass on to SDL */
result = (char*)SDL_calloc(1, sizeof(char*)*length);
SDL_strlcpy(result, text, length);
}
return result;
}
SDL_bool BE_HasClipboardText(_THIS) {
SDL_bool result = SDL_FALSE;
char *text = BE_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-2015 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 BE_SetClipboardText(_THIS, const char *text);
extern char *BE_GetClipboardText(_THIS);
extern SDL_bool BE_HasClipboardText(_THIS);
#endif

View File

@@ -0,0 +1,39 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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 SDL_VIDEO_DRIVER_HAIKU
#include "SDL_bevents.h"
#ifdef __cplusplus
extern "C" {
#endif
void BE_PumpEvents(_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-2015 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 BE_PumpEvents(_THIS);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,254 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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 SDL_VIDEO_DRIVER_HAIKU
#include "SDL_bframebuffer.h"
#include <AppKit.h>
#include <InterfaceKit.h>
#include "SDL_bmodes.h"
#include "SDL_BWin.h"
#include "../../main/haiku/SDL_BApp.h"
#ifdef __cplusplus
extern "C" {
#endif
int32 BE_UpdateOnce(SDL_Window *window);
static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
return ((SDL_BWin*)(window->driverdata));
}
static SDL_INLINE SDL_BApp *_GetBeApp() {
return ((SDL_BApp*)be_app);
}
int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window,
Uint32 * format,
void ** pixels, int *pitch) {
SDL_BWin *bwin = _ToBeWin(window);
BScreen bscreen;
if(!bscreen.IsValid()) {
return -1;
}
while(!bwin->Connected()) { snooze(100); }
/* Make sure we have exclusive access to frame buffer data */
bwin->LockBuffer();
/* format */
display_mode bmode;
bscreen.GetMode(&bmode);
int32 bpp = BE_ColorSpaceToBitsPerPixel(bmode.space);
*format = BE_BPPToSDLPxFormat(bpp);
/* 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) {
return SDL_SetError("Could not initialize back buffer!\n");
}
bwin->SetBitmap(bitmap);
/* Set the pixel pointer */
*pixels = bitmap->Bits();
/* pitch = width of window, in bytes */
*pitch = bitmap->BytesPerRow();
bwin->SetBufferExists(true);
bwin->SetTrashBuffer(false);
bwin->UnlockBuffer();
return 0;
}
int BE_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
const SDL_Rect * rects, int numrects) {
if(!window)
return 0;
SDL_BWin *bwin = _ToBeWin(window);
#ifdef DRAWTHREAD
bwin->LockBuffer();
bwin->SetBufferDirty(true);
bwin->UnlockBuffer();
#else
bwin->SetBufferDirty(true);
BE_UpdateOnce(window);
#endif
return 0;
}
int32 BE_DrawThread(void *data) {
SDL_BWin *bwin = (SDL_BWin*)data;
BScreen bscreen;
if(!bscreen.IsValid()) {
return -1;
}
while(bwin->ConnectionEnabled()) {
if( bwin->Connected() && bwin->BufferExists() && bwin->BufferIsDirty() ) {
bwin->LockBuffer();
BBitmap *bitmap = NULL;
bitmap = bwin->GetBitmap();
int32 windowPitch = bitmap->BytesPerRow();
int32 bufferPitch = bwin->GetRowBytes();
uint8 *windowpx;
uint8 *bufferpx;
int32 BPP = bwin->GetBytesPerPx();
int32 windowSub = bwin->GetFbX() * BPP +
bwin->GetFbY() * windowPitch;
clipping_rect *clips = bwin->GetClips();
int32 numClips = bwin->GetNumClips();
int i, y;
/* Blit each clipping rectangle */
bscreen.WaitForRetrace();
for(i = 0; i < numClips; ++i) {
clipping_rect rc = clips[i];
/* Get addresses of the start of each clipping rectangle */
int32 width = clips[i].right - clips[i].left + 1;
int32 height = clips[i].bottom - clips[i].top + 1;
bufferpx = bwin->GetBufferPx() +
clips[i].top * bufferPitch + clips[i].left * BPP;
windowpx = (uint8*)bitmap->Bits() +
clips[i].top * windowPitch + clips[i].left * BPP -
windowSub;
/* Copy each row of pixels from the window buffer into the frame
buffer */
for(y = 0; y < height; ++y)
{
if(bwin->CanTrashWindowBuffer()) {
goto escape; /* Break out before the buffer is killed */
}
memcpy(bufferpx, windowpx, width * BPP);
bufferpx += bufferPitch;
windowpx += windowPitch;
}
}
bwin->SetBufferDirty(false);
escape:
bwin->UnlockBuffer();
} else {
snooze(16000);
}
}
return B_OK;
}
void BE_DestroyWindowFramebuffer(_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->SetBufferExists(false);
bwin->UnlockBuffer();
}
/*
* TODO:
* This was written to test if certain errors were caused by threading issues.
* The specific issues have since become rare enough that they may have been
* solved, but I doubt it- they were pretty sporadic before now.
*/
int32 BE_UpdateOnce(SDL_Window *window) {
SDL_BWin *bwin = _ToBeWin(window);
BScreen bscreen;
if(!bscreen.IsValid()) {
return -1;
}
if(bwin->ConnectionEnabled() && bwin->Connected()) {
bwin->LockBuffer();
int32 windowPitch = window->surface->pitch;
int32 bufferPitch = bwin->GetRowBytes();
uint8 *windowpx;
uint8 *bufferpx;
int32 BPP = bwin->GetBytesPerPx();
uint8 *windowBaseAddress = (uint8*)window->surface->pixels;
int32 windowSub = bwin->GetFbX() * BPP +
bwin->GetFbY() * windowPitch;
clipping_rect *clips = bwin->GetClips();
int32 numClips = bwin->GetNumClips();
int i, y;
/* Blit each clipping rectangle */
bscreen.WaitForRetrace();
for(i = 0; i < numClips; ++i) {
clipping_rect rc = clips[i];
/* Get addresses of the start of each clipping rectangle */
int32 width = clips[i].right - clips[i].left + 1;
int32 height = clips[i].bottom - clips[i].top + 1;
bufferpx = bwin->GetBufferPx() +
clips[i].top * bufferPitch + clips[i].left * BPP;
windowpx = windowBaseAddress +
clips[i].top * windowPitch + clips[i].left * BPP - windowSub;
/* Copy each row of pixels from the window buffer into the frame
buffer */
for(y = 0; y < height; ++y)
{
memcpy(bufferpx, windowpx, width * BPP);
bufferpx += bufferPitch;
windowpx += windowPitch;
}
}
bwin->UnlockBuffer();
}
return 0;
}
#ifdef __cplusplus
}
#endif
#endif /* SDL_VIDEO_DRIVER_HAIKU */

View File

@@ -0,0 +1,45 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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 BE_CreateWindowFramebuffer(_THIS, SDL_Window * window,
Uint32 * format,
void ** pixels, int *pitch);
extern int BE_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
const SDL_Rect * rects, int numrects);
extern void BE_DestroyWindowFramebuffer(_THIS, SDL_Window * window);
extern int32 BE_DrawThread(void *data);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,188 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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 SDL_VIDEO_DRIVER_HAIKU
#include <SupportDefs.h>
#include <support/UTF8.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "SDL_events.h"
#include "SDL_keycode.h"
#include "SDL_bkeyboard.h"
#define KEYMAP_SIZE 128
static SDL_Scancode keymap[KEYMAP_SIZE];
static int8 keystate[KEYMAP_SIZE];
void BE_InitOSKeymap() {
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 BE_GetScancodeFromBeKey(int32 bkey) {
if(bkey > 0 && bkey < (int32)SDL_TABLESIZE(keymap)) {
return keymap[bkey];
} else {
return SDL_SCANCODE_UNKNOWN;
}
}
int8 BE_GetKeyState(int32 bkey) {
if(bkey > 0 && bkey < KEYMAP_SIZE) {
return keystate[bkey];
} else {
return SDL_RELEASED;
}
}
void BE_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,42 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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
#include "../../../include/SDL_keyboard.h"
extern void BE_InitOSKeymap();
extern SDL_Scancode BE_GetScancodeFromBeKey(int32 bkey);
extern int8 BE_GetKeyState(int32 bkey);
extern void BE_SetKeyState(int32 bkey, int8 state);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,331 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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 SDL_VIDEO_DRIVER_HAIKU
#include <AppKit.h>
#include <InterfaceKit.h>
#include "SDL_bmodes.h"
#include "SDL_BWin.h"
#if SDL_VIDEO_OPENGL
#include "SDL_bopengl.h"
#endif
#include "../../main/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 */
typedef 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_BApp *_GetBeApp() {
return ((SDL_BApp*)be_app);
}
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 BE_ColorSpaceToBitsPerPixel(uint32 colorspace)
{
int bitsperpixel;
bitsperpixel = 0;
switch (colorspace) {
case B_CMAP8:
bitsperpixel = 8;
break;
case B_RGB15:
case B_RGBA15:
case B_RGB15_BIG:
case B_RGBA15_BIG:
bitsperpixel = 15;
break;
case B_RGB16:
case B_RGB16_BIG:
bitsperpixel = 16;
break;
case B_RGB32:
case B_RGBA32:
case B_RGB32_BIG:
case B_RGBA32_BIG:
bitsperpixel = 32;
break;
default:
break;
}
return(bitsperpixel);
}
int32 BE_BPPToSDLPxFormat(int32 bpp) {
/* Translation taken from SDL_windowsmodes.c */
switch (bpp) {
case 32:
return SDL_PIXELFORMAT_RGB888;
break;
case 24: /* May not be supported by Haiku */
return SDL_PIXELFORMAT_RGB24;
break;
case 16:
return SDL_PIXELFORMAT_RGB565;
break;
case 15:
return SDL_PIXELFORMAT_RGB555;
break;
case 8:
return SDL_PIXELFORMAT_INDEX8;
break;
case 4: /* May not be supported by Haiku */
return SDL_PIXELFORMAT_INDEX4LSB;
break;
}
/* May never get here, but safer and needed to shut up compiler */
SDL_SetError("Invalid bpp value");
return 0;
}
static void _BDisplayModeToSdlDisplayMode(display_mode *bmode,
SDL_DisplayMode *mode) {
mode->w = bmode->virtual_width;
mode->h = bmode->virtual_height;
mode->refresh_rate = (int)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 */
int32 bpp = BE_ColorSpaceToBitsPerPixel(bmode->space);
mode->format = BE_BPPToSDLPxFormat(bpp);
}
/* Later, there may be more than one monitor available */
static void _AddDisplay(BScreen *screen) {
SDL_VideoDisplay display;
SDL_DisplayMode *mode = (SDL_DisplayMode*)SDL_calloc(1,
sizeof(SDL_DisplayMode));
display_mode *bmode = (display_mode*)SDL_calloc(1, sizeof(display_mode));
screen->GetMode(bmode);
_BDisplayModeToSdlDisplayMode(bmode, mode);
SDL_zero(display);
display.desktop_mode = *mode;
display.current_mode = *mode;
SDL_AddVideoDisplay(&display);
}
/*
* Functions called by SDL
*/
int BE_InitModes(_THIS) {
BScreen screen;
/* TODO: When Haiku supports multiple display screens, call
_AddDisplayScreen() for each of them. */
_AddDisplay(&screen);
return 0;
}
int BE_QuitModes(_THIS) {
/* FIXME: Nothing really needs to be done here at the moment? */
return 0;
}
int BE_GetDisplayBounds(_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;
}
void BE_GetDisplayModes(_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_AddDisplayMode(display, &mode);
}
}
free(bmodes);
}
int BE_SetDisplayMode(_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\n");
}
free(bmode_list);
#if SDL_VIDEO_OPENGL
/* FIXME: Is there some way to reboot the OpenGL context? This doesn't
help */
// BE_GL_RebootContexts(_this);
#endif
return 0;
}
#ifdef __cplusplus
}
#endif
#endif /* SDL_VIDEO_DRIVER_HAIKU */

View File

@@ -0,0 +1,46 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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 BE_ColorSpaceToBitsPerPixel(uint32 colorspace);
extern int32 BE_BPPToSDLPxFormat(int32 bpp);
extern int BE_InitModes(_THIS);
extern int BE_QuitModes(_THIS);
extern int BE_GetDisplayBounds(_THIS, SDL_VideoDisplay *display,
SDL_Rect *rect);
extern void BE_GetDisplayModes(_THIS, SDL_VideoDisplay *display);
extern int BE_SetDisplayMode(_THIS, SDL_VideoDisplay *display,
SDL_DisplayMode *mode);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,219 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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 SDL_VIDEO_DRIVER_HAIKU
#include "SDL_bopengl.h"
#include <unistd.h>
#include <KernelKit.h>
#include <OpenGLKit.h>
#include "SDL_BWin.h"
#include "../../main/haiku/SDL_BApp.h"
#ifdef __cplusplus
extern "C" {
#endif
#define BGL_FLAGS BGL_RGB | BGL_DOUBLE
static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
return ((SDL_BWin*)(window->driverdata));
}
static SDL_INLINE SDL_BApp *_GetBeApp() {
return ((SDL_BApp*)be_app);
}
/* Passing a NULL path means load pointers from the application */
int BE_GL_LoadLibrary(_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 *) 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;
}
void *BE_GL_GetProcAddress(_THIS, const char *proc)
{
if (_this->gl_config.dll_handle != NULL) {
void *location = NULL;
status_t err;
if ((err =
get_image_symbol((image_id) _this->gl_config.dll_handle,
proc, B_SYMBOL_TYPE_ANY,
&location)) == B_OK) {
return location;
} else {
SDL_SetError("Couldn't find OpenGL symbol");
return NULL;
}
} else {
SDL_SetError("OpenGL library not loaded");
return NULL;
}
}
void BE_GL_SwapWindow(_THIS, SDL_Window * window) {
_ToBeWin(window)->SwapBuffers();
}
int BE_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) {
_GetBeApp()->SetCurrentContext(((SDL_BWin*)context)->GetGLView());
return 0;
}
SDL_GLContext BE_GL_CreateContext(_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);
bwin->CreateGLView(BGL_FLAGS);
return (SDL_GLContext)(bwin);
}
void BE_GL_DeleteContext(_THIS, SDL_GLContext context) {
/* Currently, automatically unlocks the view */
((SDL_BWin*)context)->RemoveGLView();
}
int BE_GL_SetSwapInterval(_THIS, int interval) {
/* TODO: Implement this, if necessary? */
return 0;
}
int BE_GL_GetSwapInterval(_THIS) {
/* TODO: Implement this, if necessary? */
return 0;
}
void BE_GL_UnloadLibrary(_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 BE_GL_RebootContexts(_THIS) {
SDL_Window *window = _this->windows;
while(window) {
SDL_BWin *bwin = _ToBeWin(window);
if(bwin->GetGLView()) {
bwin->LockLooper();
bwin->RemoveGLView();
bwin->CreateGLView(BGL_FLAGS);
bwin->UnlockLooper();
}
window = window->next;
}
}
#if 0 /* Functions from 1.2 that do not appear to be used in 1.3 */
int BE_GL_GetAttribute(_THIS, SDL_GLattr attrib, int *value)
{
/*
FIXME? Right now BE_GL_GetAttribute shouldn't be called between glBegin() and glEnd() - it doesn't use "cached" values
*/
switch (attrib) {
case SDL_GL_RED_SIZE:
glGetIntegerv(GL_RED_BITS, (GLint *) value);
break;
case SDL_GL_GREEN_SIZE:
glGetIntegerv(GL_GREEN_BITS, (GLint *) value);
break;
case SDL_GL_BLUE_SIZE:
glGetIntegerv(GL_BLUE_BITS, (GLint *) value);
break;
case SDL_GL_ALPHA_SIZE:
glGetIntegerv(GL_ALPHA_BITS, (GLint *) value);
break;
case SDL_GL_DOUBLEBUFFER:
glGetBooleanv(GL_DOUBLEBUFFER, (GLboolean *) value);
break;
case SDL_GL_BUFFER_SIZE:
int v;
glGetIntegerv(GL_RED_BITS, (GLint *) & v);
*value = v;
glGetIntegerv(GL_GREEN_BITS, (GLint *) & v);
*value += v;
glGetIntegerv(GL_BLUE_BITS, (GLint *) & v);
*value += v;
glGetIntegerv(GL_ALPHA_BITS, (GLint *) & v);
*value += v;
break;
case SDL_GL_DEPTH_SIZE:
glGetIntegerv(GL_DEPTH_BITS, (GLint *) value); /* Mesa creates 16 only? r5 always 32 */
break;
case SDL_GL_STENCIL_SIZE:
glGetIntegerv(GL_STENCIL_BITS, (GLint *) value);
break;
case SDL_GL_ACCUM_RED_SIZE:
glGetIntegerv(GL_ACCUM_RED_BITS, (GLint *) value);
break;
case SDL_GL_ACCUM_GREEN_SIZE:
glGetIntegerv(GL_ACCUM_GREEN_BITS, (GLint *) value);
break;
case SDL_GL_ACCUM_BLUE_SIZE:
glGetIntegerv(GL_ACCUM_BLUE_BITS, (GLint *) value);
break;
case SDL_GL_ACCUM_ALPHA_SIZE:
glGetIntegerv(GL_ACCUM_ALPHA_BITS, (GLint *) value);
break;
case SDL_GL_STEREO:
case SDL_GL_MULTISAMPLEBUFFERS:
case SDL_GL_MULTISAMPLESAMPLES:
default:
*value = 0;
return (-1);
}
return 0;
}
#endif
#ifdef __cplusplus
}
#endif
#endif /* SDL_VIDEO_DRIVER_HAIKU */

View File

@@ -0,0 +1,49 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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
#ifdef __cplusplus
extern "C" {
#endif
#include "../SDL_sysvideo.h"
extern int BE_GL_LoadLibrary(_THIS, const char *path); /* FIXME */
extern void *BE_GL_GetProcAddress(_THIS, const char *proc); /* FIXME */
extern void BE_GL_UnloadLibrary(_THIS); /* TODO */
extern int BE_GL_MakeCurrent(_THIS, SDL_Window * window,
SDL_GLContext context);
extern int BE_GL_SetSwapInterval(_THIS, int interval); /* TODO */
extern int BE_GL_GetSwapInterval(_THIS); /* TODO */
extern void BE_GL_SwapWindow(_THIS, SDL_Window * window);
extern SDL_GLContext BE_GL_CreateContext(_THIS, SDL_Window * window);
extern void BE_GL_DeleteContext(_THIS, SDL_GLContext context);
extern void BE_GL_RebootContexts(_THIS);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,174 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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 SDL_VIDEO_DRIVER_HAIKU
#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"
/* FIXME: Undefined functions */
// #define BE_PumpEvents NULL
#define BE_StartTextInput NULL
#define BE_StopTextInput NULL
#define BE_SetTextInputRect NULL
// #define BE_DeleteDevice NULL
/* End undefined functions */
static SDL_VideoDevice *
BE_CreateDevice(int devindex)
{
SDL_VideoDevice *device;
/*SDL_VideoData *data;*/
/* 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 = BE_VideoInit;
device->VideoQuit = BE_VideoQuit;
device->GetDisplayBounds = BE_GetDisplayBounds;
device->GetDisplayModes = BE_GetDisplayModes;
device->SetDisplayMode = BE_SetDisplayMode;
device->PumpEvents = BE_PumpEvents;
device->CreateWindow = BE_CreateWindow;
device->CreateWindowFrom = BE_CreateWindowFrom;
device->SetWindowTitle = BE_SetWindowTitle;
device->SetWindowIcon = BE_SetWindowIcon;
device->SetWindowPosition = BE_SetWindowPosition;
device->SetWindowSize = BE_SetWindowSize;
device->ShowWindow = BE_ShowWindow;
device->HideWindow = BE_HideWindow;
device->RaiseWindow = BE_RaiseWindow;
device->MaximizeWindow = BE_MaximizeWindow;
device->MinimizeWindow = BE_MinimizeWindow;
device->RestoreWindow = BE_RestoreWindow;
device->SetWindowBordered = BE_SetWindowBordered;
device->SetWindowFullscreen = BE_SetWindowFullscreen;
device->SetWindowGammaRamp = BE_SetWindowGammaRamp;
device->GetWindowGammaRamp = BE_GetWindowGammaRamp;
device->SetWindowGrab = BE_SetWindowGrab;
device->DestroyWindow = BE_DestroyWindow;
device->GetWindowWMInfo = BE_GetWindowWMInfo;
device->CreateWindowFramebuffer = BE_CreateWindowFramebuffer;
device->UpdateWindowFramebuffer = BE_UpdateWindowFramebuffer;
device->DestroyWindowFramebuffer = BE_DestroyWindowFramebuffer;
device->shape_driver.CreateShaper = NULL;
device->shape_driver.SetWindowShape = NULL;
device->shape_driver.ResizeWindowShape = NULL;
device->GL_LoadLibrary = BE_GL_LoadLibrary;
device->GL_GetProcAddress = BE_GL_GetProcAddress;
device->GL_UnloadLibrary = BE_GL_UnloadLibrary;
device->GL_CreateContext = BE_GL_CreateContext;
device->GL_MakeCurrent = BE_GL_MakeCurrent;
device->GL_SetSwapInterval = BE_GL_SetSwapInterval;
device->GL_GetSwapInterval = BE_GL_GetSwapInterval;
device->GL_SwapWindow = BE_GL_SwapWindow;
device->GL_DeleteContext = BE_GL_DeleteContext;
device->StartTextInput = BE_StartTextInput;
device->StopTextInput = BE_StopTextInput;
device->SetTextInputRect = BE_SetTextInputRect;
device->SetClipboardText = BE_SetClipboardText;
device->GetClipboardText = BE_GetClipboardText;
device->HasClipboardText = BE_HasClipboardText;
device->free = BE_DeleteDevice;
return device;
}
VideoBootStrap HAIKU_bootstrap = {
"haiku", "Haiku graphics",
BE_Available, BE_CreateDevice
};
void BE_DeleteDevice(SDL_VideoDevice * device)
{
SDL_free(device->driverdata);
SDL_free(device);
}
int BE_VideoInit(_THIS)
{
/* Initialize the Be Application for appserver interaction */
if (SDL_InitBeApp() < 0) {
return -1;
}
/* Initialize video modes */
BE_InitModes(_this);
/* Init the keymap */
BE_InitOSKeymap();
#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 */
BE_GL_LoadLibrary(_this, NULL);
#endif
/* We're done! */
return (0);
}
int BE_Available(void)
{
return (1);
}
void BE_VideoQuit(_THIS)
{
BE_QuitModes(_this);
SDL_QuitBeApp();
}
#ifdef __cplusplus
}
#endif
#endif /* SDL_VIDEO_DRIVER_HAIKU */

View File

@@ -0,0 +1,42 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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 "../../main/haiku/SDL_BeApp.h"
#include "../SDL_sysvideo.h"
extern void BE_VideoQuit(_THIS);
extern int BE_VideoInit(_THIS);
extern void BE_DeleteDevice(_THIS);
extern int BE_Available(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,223 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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 SDL_VIDEO_DRIVER_HAIKU
#include "../SDL_sysvideo.h"
#include "SDL_BWin.h"
#include <new>
/* 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_BApp *_GetBeApp() {
return ((SDL_BApp*)be_app);
}
static int _InitWindow(_THIS, SDL_Window *window) {
uint32 flags = 0;
window_look look = B_BORDERED_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 ENOMEM;
window->driverdata = bwin;
int32 winID = _GetBeApp()->GetID(window);
bwin->SetID(winID);
return 0;
}
int BE_CreateWindow(_THIS, SDL_Window *window) {
if(_InitWindow(_this, window) == ENOMEM)
return ENOMEM;
/* Start window loop */
_ToBeWin(window)->Show();
return 0;
}
int BE_CreateWindowFrom(_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) == ENOMEM)
return ENOMEM;
/* 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 BE_SetWindowTitle(_THIS, SDL_Window * window) {
BMessage msg(BWIN_SET_TITLE);
msg.AddString("window-title", window->title);
_ToBeWin(window)->PostMessage(&msg);
}
void BE_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) {
/* FIXME: Icons not supported by Haiku */
}
void BE_SetWindowPosition(_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 BE_SetWindowSize(_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 BE_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) {
BMessage msg(BWIN_SET_BORDERED);
msg.AddBool("window-border", bordered != SDL_FALSE);
_ToBeWin(window)->PostMessage(&msg);
}
void BE_ShowWindow(_THIS, SDL_Window * window) {
BMessage msg(BWIN_SHOW_WINDOW);
_ToBeWin(window)->PostMessage(&msg);
}
void BE_HideWindow(_THIS, SDL_Window * window) {
BMessage msg(BWIN_HIDE_WINDOW);
_ToBeWin(window)->PostMessage(&msg);
}
void BE_RaiseWindow(_THIS, SDL_Window * window) {
BMessage msg(BWIN_SHOW_WINDOW); /* Activate this window and move to front */
_ToBeWin(window)->PostMessage(&msg);
}
void BE_MaximizeWindow(_THIS, SDL_Window * window) {
BMessage msg(BWIN_MAXIMIZE_WINDOW);
_ToBeWin(window)->PostMessage(&msg);
}
void BE_MinimizeWindow(_THIS, SDL_Window * window) {
BMessage msg(BWIN_MINIMIZE_WINDOW);
_ToBeWin(window)->PostMessage(&msg);
}
void BE_RestoreWindow(_THIS, SDL_Window * window) {
BMessage msg(BWIN_RESTORE_WINDOW);
_ToBeWin(window)->PostMessage(&msg);
}
void BE_SetWindowFullscreen(_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);
}
int BE_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) {
/* FIXME: Not Haiku supported */
return -1;
}
int BE_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) {
/* FIXME: Not Haiku supported */
return -1;
}
void BE_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) {
/* TODO: Implement this! */
}
void BE_DestroyWindow(_THIS, SDL_Window * window) {
_ToBeWin(window)->LockLooper(); /* This MUST be locked */
_GetBeApp()->ClearID(_ToBeWin(window));
_ToBeWin(window)->Quit();
window->driverdata = NULL;
}
SDL_bool BE_GetWindowWMInfo(_THIS, SDL_Window * window,
struct SDL_SysWMinfo *info) {
/* FIXME: What is the point of this? What information should be included? */
return SDL_FALSE;
}
#ifdef __cplusplus
}
#endif
#endif /* SDL_VIDEO_DRIVER_HAIKU */

View File

@@ -0,0 +1,53 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 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 BE_CreateWindow(_THIS, SDL_Window *window);
extern int BE_CreateWindowFrom(_THIS, SDL_Window * window, const void *data);
extern void BE_SetWindowTitle(_THIS, SDL_Window * window);
extern void BE_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
extern void BE_SetWindowPosition(_THIS, SDL_Window * window);
extern void BE_SetWindowSize(_THIS, SDL_Window * window);
extern void BE_ShowWindow(_THIS, SDL_Window * window);
extern void BE_HideWindow(_THIS, SDL_Window * window);
extern void BE_RaiseWindow(_THIS, SDL_Window * window);
extern void BE_MaximizeWindow(_THIS, SDL_Window * window);
extern void BE_MinimizeWindow(_THIS, SDL_Window * window);
extern void BE_RestoreWindow(_THIS, SDL_Window * window);
extern void BE_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered);
extern void BE_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
extern int BE_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp);
extern int BE_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp);
extern void BE_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
extern void BE_DestroyWindow(_THIS, SDL_Window * window);
extern SDL_bool BE_GetWindowWMInfo(_THIS, SDL_Window * window,
struct SDL_SysWMinfo *info);
#endif