diff --git a/src/main/beos/SDL_BApp.h b/src/main/beos/SDL_BApp.h new file mode 100644 index 000000000..d42960117 --- /dev/null +++ b/src/main/beos/SDL_BApp.h @@ -0,0 +1,312 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2011 Sam Lantinga + + 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 + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SDL_config.h" +#include "SDL_video.h" + +/* Local includes */ +#include "../../events/SDL_events_c.h" + +#ifdef __cplusplus +} +#endif + + +#include + + +/* Forward declarations */ +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 +}; + + + +/* Create a descendant of BApplication */ +class SDL_BApp : public BApplication { +public: + SDL_BApp(const char* signature) : + BApplication(signature) { + } + /* 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_WINDOWEVENT_EXPOSED); + break; + + case BAPP_MAXIMIZE: + _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_MAXIMIZED); + break; + + case BAPP_MINIMIZE: + _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_MINIMIZED); + break; + + case BAPP_SHOW: + _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_SHOWN); + break; + + case BAPP_HIDE: + _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_HIDDEN); + break; + + case BAPP_MOUSE_FOCUS: + _HandleMouseFocus(message); + break; + + case BAPP_KEYBOARD_FOCUS: + _HandleKeyboardFocus(message); + break; + + case BAPP_WINDOW_CLOSE_REQUESTED: + _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_CLOSE); + break; + + case BAPP_WINDOW_MOVED: + _HandleWindowMoved(message); + break; + + case BAPP_WINDOW_RESIZED: + _HandleWindowResized(message); + break; + + case BAPP_SCREEN_CHANGED: + /* TODO: Handle screen resize or workspace change */ + break; + + default: + BApplication::MessageReceived(message); + break; + } + } + + /* Window creation/destruction methods */ + int32 GetID(SDL_Window *win) { + int32 i; + for(i = 0; i < window_map.size(); ++i) { + if( window_map[i] == NULL ) { + window_map[i] = win; + return i; + } + } + + /* Expand the vector if all slots are full */ + if( i == window_map.size() ) { + window_map.push_back(win); + return i; + } + } + + void ClearID(SDL_BWin *bwin); /* Defined in SDL_BeApp.cc */ + +private: + /* Event management */ + void _HandleBasicWindowEvent(BMessage *msg, int32 sdlEventType) { + SDL_Window *win; + int32 winID; + if( + !_GetWinID(msg, &winID) + ) { + return; + } + win = window_map[winID]; + SDL_SendWindowEvent(win, sdlEventType, 0, 0); + } + + void _HandleMouseMove(BMessage *msg) { + SDL_Window *win; + int32 winID; + int32 dx, dy; + if( + !_GetWinID(msg, &winID) || + msg->FindInt32("dx", &dx) != B_OK || /* x movement */ + msg->FindInt32("dy", &dy) != B_OK /* y movement */ + ) { + return; + } + win = window_map[winID]; + SDL_SendMouseMotion(win, 0, dx, dy); + } + + 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 = window_map[winID]; + SDL_SendMouseButton(win, 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 = window_map[winID]; + SDL_SendMouseWheel(win, xTicks, yTicks); + } + + 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; + } + SDL_SendKeyboardKey(state, (SDL_Scancode)scancode); + } + + 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 = window_map[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 = window_map[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 = window_map[winID]; + SDL_SendWindowEvent(win, SDL_WINDOWEVENT_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 = window_map[winID]; + SDL_SendWindowEvent(win, SDL_WINDOWEVENT_RESIZED, w, h); + } + + bool _GetWinID(BMessage *msg, int32 *winID) { + return msg->FindInt32("window-id", winID) == B_OK; + } + + /* Members */ + vector window_map; /* Keeps track of SDL_Windows by index-id */ +}; + +#endif diff --git a/src/main/beos/SDL_BeApp.cc b/src/main/beos/SDL_BeApp.cc index 2f68881e1..a31465e5e 100644 --- a/src/main/beos/SDL_BeApp.cc +++ b/src/main/beos/SDL_BeApp.cc @@ -27,11 +27,14 @@ #include #include +#include "SDL_BApp.h" /* SDL_BApp class definition */ #include "SDL_BeApp.h" #include "SDL_thread.h" #include "SDL_timer.h" #include "SDL_error.h" +#include "../../video/bwindow/SDL_BWin.h" + /* Flag to tell whether or not the Be application is active or not */ int SDL_BeAppActive = 0; static SDL_Thread *SDL_AppThread = NULL; @@ -41,7 +44,7 @@ StartBeApp(void *unused) { BApplication *App; - App = new BApplication("application/x-SDL-executable"); + App = new SDL_BApp("application/x-SDL-executable"); App->Run(); delete App; @@ -110,4 +113,15 @@ SDL_QuitBeApp(void) } } +/* SDL_BApp functions */ +void SDL_BApp::ClearID(SDL_BWin *bwin) { + window_map[bwin->GetID()] = NULL; + int32 i = window_map.size() - 1; + while(i >= 0 && window_map[i] == NULL) { + window_map.pop_back(); + --i; + } +} + /* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/video/bwindow/SDL_BView.h b/src/video/bwindow/SDL_BView.h index e5d29ef68..f522fe95e 100644 --- a/src/video/bwindow/SDL_BView.h +++ b/src/video/bwindow/SDL_BView.h @@ -24,11 +24,15 @@ #define _SDL_BView_h /* This is the event handling and graphics update portion of SDL_BWin */ +#ifdef __cplusplus +extern "C" { +#endif -extern "C" -{ #include "../../events/SDL_events_c.h" -}; + +#ifdef __cplusplus +} +#endif class SDL_BView:public BView { diff --git a/src/video/bwindow/SDL_BWin.h b/src/video/bwindow/SDL_BWin.h index 4688cc017..94042966b 100644 --- a/src/video/bwindow/SDL_BWin.h +++ b/src/video/bwindow/SDL_BWin.h @@ -22,7 +22,17 @@ #ifndef _SDL_BWin_h #define _SDL_BWin_h +#ifdef __cplusplus +extern "C" { +#endif + #include "SDL_config.h" +#include "SDL.h" +#include "SDL_syswm.h" + +#ifdef __cplusplus +} +#endif #include #include @@ -31,27 +41,30 @@ #if SDL_VIDEO_OPENGL #include #endif -#include - -//FIXME: Temporary fix until I can understand what the values used from here do -#include "SDL_compat.h" - -#include "../../main/beos/SDL_BeApp.h" #include "SDL_events.h" #include "SDL_BView.h" +#include "../../main/beos/SDL_BApp.h" -extern "C" -{ -#include "../../events/SDL_events_c.h" +enum WinCommands { + BWIN_MOVE_WINDOW, + BWIN_RESIZE_WINDOW, + BWIN_SHOW_WINDOW, + BWIN_HIDE_WINDOW, + BWIN_MAXIMIZE_WINDOW, + BWIN_MINIMIZE_WINDOW, + BWIN_RESTORE_WINDOW, /* TODO: IMPLEMENT THIS! */ + BWIN_SET_TITLE, + BWIN_FULLSCREEN }; + class SDL_BWin:public BDirectWindow { public: + /* Constructor/Destructor */ SDL_BWin(BRect bounds):BDirectWindow(bounds, "Untitled", B_TITLED_WINDOW, 0) { - InitKeyboard(); last_buttons = 0; the_view = NULL; @@ -60,8 +73,10 @@ class SDL_BWin:public BDirectWindow #endif SDL_View = NULL; Unlock(); - shown = false; + _shown = false; inhibit_resize = false; + mouse_focused = false; + prev_frame = NULL; } virtual ~ SDL_BWin() @@ -86,145 +101,9 @@ class SDL_BWin:public BDirectWindow delete SDL_View; } } - - virtual void InitKeyboard(void) - { - for (uint i = 0; i < SDL_TABLESIZE(keymap); ++i) - keymap[i] = SDLK_UNKNOWN; - - keymap[0x01] = SDLK_ESCAPE; - keymap[B_F1_KEY] = SDLK_F1; - keymap[B_F2_KEY] = SDLK_F2; - keymap[B_F3_KEY] = SDLK_F3; - keymap[B_F4_KEY] = SDLK_F4; - keymap[B_F5_KEY] = SDLK_F5; - keymap[B_F6_KEY] = SDLK_F6; - keymap[B_F7_KEY] = SDLK_F7; - keymap[B_F8_KEY] = SDLK_F8; - keymap[B_F9_KEY] = SDLK_F9; - keymap[B_F10_KEY] = SDLK_F10; - keymap[B_F11_KEY] = SDLK_F11; - keymap[B_F12_KEY] = SDLK_F12; - keymap[B_PRINT_KEY] = SDLK_PRINTSCREEN; - keymap[B_SCROLL_KEY] = SDLK_SCROLLLOCK; - keymap[B_PAUSE_KEY] = SDLK_PAUSE; - keymap[0x11] = SDLK_BACKQUOTE; - keymap[0x12] = SDLK_1; - keymap[0x13] = SDLK_2; - keymap[0x14] = SDLK_3; - keymap[0x15] = SDLK_4; - keymap[0x16] = SDLK_5; - keymap[0x17] = SDLK_6; - keymap[0x18] = SDLK_7; - keymap[0x19] = SDLK_8; - keymap[0x1a] = SDLK_9; - keymap[0x1b] = SDLK_0; - keymap[0x1c] = SDLK_MINUS; - keymap[0x1d] = SDLK_EQUALS; - keymap[0x1e] = SDLK_BACKSPACE; - keymap[0x1f] = SDLK_INSERT; - keymap[0x20] = SDLK_HOME; - keymap[0x21] = SDLK_PAGEUP; - keymap[0x22] = SDLK_NUMLOCKCLEAR; - keymap[0x23] = SDLK_KP_DIVIDE; - keymap[0x24] = SDLK_KP_MULTIPLY; - keymap[0x25] = SDLK_KP_MINUS; - keymap[0x26] = SDLK_TAB; - keymap[0x27] = SDLK_q; - keymap[0x28] = SDLK_w; - keymap[0x29] = SDLK_e; - keymap[0x2a] = SDLK_r; - keymap[0x2b] = SDLK_t; - keymap[0x2c] = SDLK_y; - keymap[0x2d] = SDLK_u; - keymap[0x2e] = SDLK_i; - keymap[0x2f] = SDLK_o; - keymap[0x30] = SDLK_p; - keymap[0x31] = SDLK_LEFTBRACKET; - keymap[0x32] = SDLK_RIGHTBRACKET; - keymap[0x33] = SDLK_BACKSLASH; - keymap[0x34] = SDLK_DELETE; - keymap[0x35] = SDLK_END; - keymap[0x36] = SDLK_PAGEDOWN; - keymap[0x37] = SDLK_KP_7; - keymap[0x38] = SDLK_KP_8; - keymap[0x39] = SDLK_KP_9; - keymap[0x3a] = SDLK_KP_PLUS; - keymap[0x3b] = SDLK_CAPSLOCK; - keymap[0x3c] = SDLK_a; - keymap[0x3d] = SDLK_s; - keymap[0x3e] = SDLK_d; - keymap[0x3f] = SDLK_f; - keymap[0x40] = SDLK_g; - keymap[0x41] = SDLK_h; - keymap[0x42] = SDLK_j; - keymap[0x43] = SDLK_k; - keymap[0x44] = SDLK_l; - keymap[0x45] = SDLK_SEMICOLON; - keymap[0x46] = SDLK_QUOTE; - keymap[0x47] = SDLK_RETURN; - keymap[0x48] = SDLK_KP_4; - keymap[0x49] = SDLK_KP_5; - keymap[0x4a] = SDLK_KP_6; - keymap[0x4b] = SDLK_LSHIFT; - keymap[0x4c] = SDLK_z; - keymap[0x4d] = SDLK_x; - keymap[0x4e] = SDLK_c; - keymap[0x4f] = SDLK_v; - keymap[0x50] = SDLK_b; - keymap[0x51] = SDLK_n; - keymap[0x52] = SDLK_m; - keymap[0x53] = SDLK_COMMA; - keymap[0x54] = SDLK_PERIOD; - keymap[0x55] = SDLK_SLASH; - keymap[0x56] = SDLK_RSHIFT; - keymap[0x57] = SDLK_UP; - keymap[0x58] = SDLK_KP_1; - keymap[0x59] = SDLK_KP_2; - keymap[0x5a] = SDLK_KP_3; - keymap[0x5b] = SDLK_KP_ENTER; - keymap[0x5c] = SDLK_LCTRL; - keymap[0x5d] = SDLK_LALT; - keymap[0x5e] = SDLK_SPACE; - keymap[0x5f] = SDLK_RALT; - keymap[0x60] = SDLK_RCTRL; - keymap[0x61] = SDLK_LEFT; - keymap[0x62] = SDLK_DOWN; - keymap[0x63] = SDLK_RIGHT; - keymap[0x64] = SDLK_KP_0; - keymap[0x65] = SDLK_KP_PERIOD; - keymap[0x66] = SDLK_LGUI; - keymap[0x67] = SDLK_RGUI; - keymap[0x68] = SDLK_MENU; - keymap[0x69] = SDLK_2; //SDLK_EURO; - keymap[0x6a] = SDLK_KP_EQUALS; - keymap[0x6b] = SDLK_POWER; - } - - /* Override the Show() method so we can tell when we've been shown */ - virtual void Show(void) - { - BWindow::Show(); - shown = true; - } - virtual bool Shown(void) - { - return (shown); - } - /* If called, the next resize event will not be forwarded to SDL. */ - virtual void InhibitResize(void) - { - inhibit_resize = true; - } - /* Handle resizing of the window */ - virtual void FrameResized(float width, float height) - { - if (inhibit_resize) - inhibit_resize = false; - else - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, - (int) width, (int) height); - } + + + /* Other construction */ virtual int CreateView(Uint32 flags, Uint32 gl_flags) { int retval; @@ -271,10 +150,218 @@ class SDL_BWin:public BDirectWindow Unlock(); return (retval); } - virtual void SetBitmap(BBitmap * bitmap) - { - SDL_View->SetBitmap(bitmap); + + /* * * * * 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; /* TODO: Check that +1 is needed */ + 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() { + BDirectWindow::Show(); + _shown = true; + + BMessage msg(BAPP_SHOW); + _PostWindowEvent(msg); + } + + virtual void Hide() { + /* FIXME: Multiple hides require multiple shows to undo. Should + this be altered to prevent this from happening? */ + 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: + where; + 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; + + case _UPDATE_: + case _UPDATE_IF_NEEDED_: /* Hopefully one doesn't call the other */ + _RepaintEvent(); + break; + + default: + /* move it after switch{} so it's always handled + that way we keep BeOS feautures 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_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; } + + /* Setter methods */ + void SetID(int32 id) { _id = id; } + + + + + + + + + + /* FIXME: Methods copied directly; do we need them? */ +#if 0 /* Disabled until its purpose is determined */ virtual void SetXYOffset(int x, int y) { #if SDL_VIDEO_OPENGL @@ -295,6 +382,7 @@ class SDL_BWin:public BDirectWindow #endif SDL_View->GetXYOffset(x, y); } +#endif virtual bool BeginDraw(void) { return (Lock()); @@ -321,291 +409,171 @@ class SDL_BWin:public BDirectWindow return (the_view); } - /* Hook functions -- overridden */ - virtual void Minimize(bool minimize) - { - /* This is only called when mimimized, not when restored */ - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MINIMIZED, 0, 0); - BWindow::Minimize(minimize); + + + + + + +private: + /* Event redirection */ + void _MouseMotionEvent(BPoint &where, int32 transit) { + if(transit == B_EXITED_VIEW) { + /* Change mouse focus */ + if(mouse_focused) { + _MouseFocusEvent(false); + } + } else { + static int x = 0, y = 0; + /* Change mouse focus */ + if (!mouse_focused) { + _MouseFocusEvent(true); + } +// GetXYOffset(x, y); //FIXME: What is this doing? (from SDL 1.2) + BMessage msg(BAPP_MOUSE_MOVED); + msg.AddInt32("dx", where.x - x); + msg.AddInt32("dy", where.y - y); + x = (int) where.x; + y = (int) where.y; + _PostWindowEvent(msg); + } } - virtual void WindowActivated(bool active) - { -// SDL_PrivateAppActive(active, SDL_APPINPUTFOCUS); - if( active ) { - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0); - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0); - } else { - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MINIMIZED, 0, 0); - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_HIDDEN, 0, 0); - } + + 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); } - virtual bool QuitRequested(void) - { - if (SDL_BeAppActive > 0) { - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_CLOSE, 0, 0); - /* We don't ever actually close the window here because - the application should respond to the quit request, - or ignore it as desired. - */ - return (false); - } - return (true); /* Close the app window */ + + 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; } - virtual void Quit() - { - if (!IsLocked()) - Lock(); - BDirectWindow::Quit(); + + 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 _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()); + } } - virtual int16 Translate2Unicode(const char *buf) - { - int32 state, srclen, dstlen; - unsigned char destbuf[2]; - Uint16 unicode = 0; - - if ((uchar) buf[0] > 127) { - state = 0; - srclen = SDL_strlen(buf); - dstlen = sizeof(destbuf); - convert_from_utf8(B_UNICODE_CONVERSION, buf, &srclen, - (char *) destbuf, &dstlen, &state); - unicode = destbuf[0]; - unicode <<= 8; - unicode |= destbuf[1]; - } else - unicode = buf[0]; - - /* For some reason function keys map to control characters */ -# define CTRL(X) ((X)-'@') - switch (unicode) { - case CTRL('A'): - case CTRL('B'): - case CTRL('C'): - case CTRL('D'): - case CTRL('E'): - case CTRL('K'): - case CTRL('L'): - case CTRL('P'): - if (!(SDL_GetModState() & KMOD_CTRL)) - unicode = 0; - break; - /* Keyboard input maps newline to carriage return */ - case '\n': - unicode = '\r'; - break; - default: - break; - } - - return unicode; + void _SetFullScreen(BMessage *msg) { + bool fullscreen; + if( + msg->FindBool("fullscreen", &fullscreen) != B_OK + ) { + return; + } + SetFullScreen(fullscreen); } - - virtual void DispatchMessage(BMessage * msg, BHandler * target) - { - switch (msg->what) { - case B_MOUSE_MOVED: - { - BPoint where; - int32 transit; - if (msg->FindPoint("where", &where) == B_OK - && msg->FindInt32("be:transit", &transit) == B_OK) { - if (transit == B_EXITED_VIEW) { - if (SDL_GetAppState() & SDL_APPMOUSEFOCUS) { -// SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_HIDDEN, 0, 0); - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MINIMIZED, 0, 0); - be_app->SetCursor(B_HAND_CURSOR); - } - } else { - int x, y; - if (!(SDL_GetAppState() & SDL_APPMOUSEFOCUS)) { -// SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0); - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0); - SDL_SetCursor(NULL); - } - GetXYOffset(x, y); - x = (int) where.x - x; - y = (int) where.y - y; - SDL_SendMouseMotion(window, 0, x, y); - } - } - break; - } - - case B_MOUSE_DOWN: - { - /* it looks like mouse down is send only for first clicked - button, each next is not send while last one is holded */ - int32 buttons; -// int sdl_buttons = 0; - if (msg->FindInt32("buttons", &buttons) == B_OK) { - /* Add any mouse button events */ - if (buttons & B_PRIMARY_MOUSE_BUTTON) { -// sdl_buttons |= SDL_BUTTON_LMASK; - SDL_SendMouseButton(window, SDL_PRESSED, SDL_BUTTON_LEFT); - } - if (buttons & B_SECONDARY_MOUSE_BUTTON) { -// sdl_buttons |= SDL_BUTTON_RMASK; - SDL_SendMouseButton(window, SDL_PRESSED, SDL_BUTTON_RIGHT); - } - if (buttons & B_TERTIARY_MOUSE_BUTTON) { -// sdl_buttons |= SDL_BUTTON_MMASK; - SDL_SendMouseButton(window, SDL_PRESSED, SDL_BUTTON_MIDDLE); - } - - last_buttons = buttons; - } - break; - } - - case B_MOUSE_UP: - { - /* mouse up doesn't give which button was released, - only state of buttons (after release, so it's always = 0), - which is not what we need ;] - So we need to store button in mouse down, and restore - in mouse up :( - mouse up is (similarly to mouse down) send only for - first button down (ie. it's no send if we click another button - without releasing previous one first) - but that's probably - because of how drivers are written?, not BeOS itself. */ - int32 buttons; -// int sdl_buttons = 0; - if (msg->FindInt32("buttons", &buttons) == B_OK) { - /* Add any mouse button events */ - if ((buttons ^ B_PRIMARY_MOUSE_BUTTON) & last_buttons) { -// sdl_buttons |= SDL_BUTTON_LMASK; - SDL_SendMouseButton(window, SDL_RELEASED, SDL_BUTTON_LEFT); - } - if ((buttons ^ B_SECONDARY_MOUSE_BUTTON) & last_buttons) { -// sdl_buttons |= SDL_BUTTON_RMASK; - SDL_SendMouseButton(window, SDL_RELEASED, SDL_BUTTON_RIGHT); - } - if ((buttons ^ B_TERTIARY_MOUSE_BUTTON) & last_buttons) { -// sdl_buttons |= SDL_BUTTON_MMASK; - SDL_SendMouseButton(window, SDL_RELEASED, SDL_BUTTON_MIDDLE); - } - - last_buttons = buttons; - } - break; - } - - case B_MOUSE_WHEEL_CHANGED: - { - float x, y; - x = y = 0; - if (msg->FindFloat("be:wheel_delta_x", &x) == B_OK - && msg->FindFloat("be:wheel_delta_y", &y) == B_OK) { - if (x < 0 || y < 0) { - SDL_SendMouseWheel(window, (int)x, (int)y); - } else if (x > 0 || y > 0) { - SDL_SendMouseWheel(window, (int)x, (int)y); - } - } - break; - } - - case B_KEY_DOWN: - case B_UNMAPPED_KEY_DOWN: /* modifier keys are unmapped */ - { - int32 key; - int32 modifiers; - int32 key_repeat; - /* Workaround for SDL message queue being filled too fast because of BeOS own key-repeat mechanism */ - if (msg->FindInt32("be:key_repeat", &key_repeat) == B_OK - && key_repeat > 0) - break; - - if (msg->FindInt32("key", &key) == B_OK - && msg->FindInt32("modifiers", &modifiers) == B_OK) { - SDL_Keysym keysym; - keysym.scancode = (SDL_Scancode)key; - if ((key > 0) && (key < 128)) { - keysym.sym = keymap[key]; - } else { - keysym.sym = SDLK_UNKNOWN; - } - /* FIX THIS? - it seems SDL_PrivateKeyboard() changes mod value - anyway, and doesn't care about what we setup here */ - keysym.mod = KMOD_NONE; - keysym.unicode = 0; -#if 0 /* FIXME: As far as I can make out, this isn't really used anymore? */ - if (SDL_TranslateUNICODE) { - const char *bytes; - if (msg->FindString("bytes", &bytes) == B_OK) { - /* FIX THIS? - this cares only about first "letter", - so if someone maps some key to print - "BeOS rulez!" only "B" will be used. */ - keysym.unicode = Translate2Unicode(bytes); - } - } -#endif - SDL_SendKeyboardKey(SDL_PRESSED, keysym.scancode); - } - break; - } - - case B_KEY_UP: - case B_UNMAPPED_KEY_UP: /* modifier keys are unmapped */ - { - int32 key; - int32 modifiers; - if (msg->FindInt32("key", &key) == B_OK - && msg->FindInt32("modifiers", &modifiers) == B_OK) { - SDL_Keysym keysym; - keysym.scancode = (SDL_Scancode)key; - if ((key > 0) && (key < 128)) { - keysym.sym = keymap[key]; - } else { - keysym.sym = SDLK_UNKNOWN; - } - keysym.mod = KMOD_NONE; /* FIX THIS? */ - keysym.unicode = 0; -#if 0 /* FIXME: As far as I can make out, this isn't really used anymore? */ - if (SDL_TranslateUNICODE) { - const char *bytes; - if (msg->FindString("bytes", &bytes) == B_OK) { - keysym.unicode = Translate2Unicode(bytes); - } - } -#endif - SDL_SendKeyboardKey(SDL_RELEASED, keysym.scancode); - } - break; - } - - default: - /* move it after switch{} so it's always handled - that way we keep BeOS feautures 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); - } - - private: + + /* Members */ #if SDL_VIDEO_OPENGL BGLView * SDL_GLView; #endif SDL_BView *SDL_View; BView *the_view; - - bool shown; - bool inhibit_resize; - - int32 last_buttons; - SDL_Keycode keymap[128]; - SDL_Window *window; + 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 */ }; -#endif /* _SDL_BWin_h */ -/* vi: set ts=4 sw=4 expandtab: */ +#endif diff --git a/src/video/bwindow/SDL_bclipboard.c b/src/video/bwindow/SDL_bclipboard.c new file mode 100644 index 000000000..4cc965899 --- /dev/null +++ b/src/video/bwindow/SDL_bclipboard.c @@ -0,0 +1,109 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2011 Sam Lantinga + + 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. +*/ + + +/* BWindow based framebuffer implementation */ +#include "SDL_config.h" + +#include +#include + +#include "SDL_BWin.h" +#include "SDL_timer.h" +#include "../SDL_sysvideo.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int BE_SetClipboardText(_THIS, const char *text) { +#if 0 + 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(); + } +#else +return -1; +#endif +} + +char *BE_GetClipboardText(_THIS) { +#if 0 + BMessage *clip = NULL; + const char *text; + ssize_t length; + if(be_clipboard->Lock()) { + if((clip = be_clipboard->Data())) { + /* Presumably the string of characters is ascii-format */ + clip->FindData("text/plain", B_MIME_TYPE, (void**)&text, &length); + } else { + be_clipboard->Unlock(); + return NULL; + } + be_clipboard->Unlock(); + } else { + return NULL; + } + + /* Copy the data and pass on to SDL */ + char *result = (char*)SDL_calloc(1, sizeof(char*)*length); + SDL_strlcpy(result, text, length); + + return result; +#else +return NULL; +#endif; +} + +SDL_bool BE_HasClipboardText(_THIS) { +#if 0 + BMessage *clip = NULL; + const char *text; + ssize_t length; + SDL_bool retval = SDL_FALSE; + + if(be_clipboard->Lock()) { + if((clip = be_clipboard->Data())) { + /* Presumably the string of characters is ascii-format */ + clip->FindData("text/plain", B_MIME_TYPE, (void**)&text, &length); + if( text ) retval = SDL_TRUE; + } + be_clipboard->Unlock(); + } + return retval; +#else +return SDL_FALSE; +#endif + +} + +#ifdef __cplusplus +} /* Extern C */ +#endif + diff --git a/src/video/bwindow/SDL_bclipboard.h b/src/video/bwindow/SDL_bclipboard.h new file mode 100644 index 000000000..bfb806cd0 --- /dev/null +++ b/src/video/bwindow/SDL_bclipboard.h @@ -0,0 +1,31 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2011 Sam Lantinga + + 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_config.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 diff --git a/src/video/bwindow/SDL_bmodes.c b/src/video/bwindow/SDL_bmodes.c new file mode 100644 index 000000000..2818718f5 --- /dev/null +++ b/src/video/bwindow/SDL_bmodes.c @@ -0,0 +1,78 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2011 Sam Lantinga + + 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_sysvideo.h" + +int BE_InitModes(_THIS) { +#if 0 + display_mode *modes; + uint32 i, nmodes; + int bpp; + + /* It is important that this be created after SDL_InitBeApp() */ + BScreen bscreen; + + /* Save the current display mode */ + bscreen.GetMode(&saved_mode); + _this->info.current_w = saved_mode.virtual_width; + _this->info.current_h = saved_mode.virtual_height; + + /* Get the video modes we can switch to in fullscreen mode */ + bscreen.GetModeList(&modes, &nmodes); + SDL_qsort(modes, nmodes, sizeof *modes, CompareModes); + for (i = 0; i < nmodes; ++i) { + bpp = ColorSpaceToBitsPerPixel(modes[i].space); + //if ( bpp != 0 ) { // There are bugs in changing colorspace + if (modes[i].space == saved_mode.space) { + BE_AddMode(_this, ((bpp + 7) / 8) - 1, + modes[i].virtual_width, modes[i].virtual_height); + } + } +#else +return -1; +#endif +} + +int BE_QuitModes(_THIS) { +#if 0 + int i, j; + for (i = 0; i < NUM_MODELISTS; ++i) { + if (SDL_modelist[i]) { + for (j = 0; SDL_modelist[i][j]; ++j) { + SDL_free(SDL_modelist[i][j]); + } + SDL_free(SDL_modelist[i]); + SDL_modelist[i] = NULL; + } + } + + /* Restore the original video mode */ + if (_this->screen) { + if ((_this->screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) { + BScreen bscreen; + bscreen.SetMode(&saved_mode); + } + _this->screen->pixels = NULL; + } +#else +return -1; +#endif +} diff --git a/src/video/bwindow/SDL_bmodes.h b/src/video/bwindow/SDL_bmodes.h new file mode 100644 index 000000000..e8208cf68 --- /dev/null +++ b/src/video/bwindow/SDL_bmodes.h @@ -0,0 +1,27 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2011 Sam Lantinga + + 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 + +extern int BE_InitModes(_THIS); +extern int BE_QuitModes(_THIS); +#endif diff --git a/src/video/bwindow/SDL_bopengl.c b/src/video/bwindow/SDL_bopengl.c new file mode 100644 index 000000000..4e8ae5225 --- /dev/null +++ b/src/video/bwindow/SDL_bopengl.c @@ -0,0 +1,195 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2011 Sam Lantinga + + 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_bopengl.h" +#include "../SDL_sysvideo.h" + + +/* Passing a NULL path means load pointers from the application */ +int BE_GL_LoadLibrary(_THIS, const char *path) +{ +#if 0 + if (path == NULL) { + if (_this->gl_config.dll_handle == NULL) { + image_info info; + int32 cookie = 0; + while (get_next_image_info(0, &cookie, &info) == B_OK) { + void *location = NULL; + if (get_image_symbol + ((image_id) cookie, "glBegin", + B_SYMBOL_TYPE_ANY, &location) == B_OK) { + _this->gl_config.dll_handle = (void *) cookie; + _this->gl_config.driver_loaded = 1; + SDL_strlcpy(_this->gl_config.driver_path, + "libGL.so", + SDL_arraysize(_this-> + gl_config.driver_path)); + } + } + } + } else { + /* + FIXME None of BeOS libGL.so implementations have exported functions + to load BGLView, which should be reloaded from new lib. + So for now just "load" linked libGL.so :( + */ + if (_this->gl_config.dll_handle == NULL) { + return BE_GL_LoadLibrary(_this, NULL); + } + + /* Unload old first */ + /*if (_this->gl_config.dll_handle != NULL) { */ + /* Do not try to unload application itself (if LoadLibrary was called before with NULL ;) */ + /* image_info info; + if (get_image_info((image_id)_this->gl_config.dll_handle, &info) == B_OK) { + if (info.type != B_APP_IMAGE) { + unload_add_on((image_id)_this->gl_config.dll_handle); + } + } + + } + + if ((_this->gl_config.dll_handle = (void*)load_add_on(path)) != (void*)B_ERROR) { + _this->gl_config.driver_loaded = 1; + SDL_strlcpy(_this->gl_config.driver_path, path, SDL_arraysize(_this->gl_config.driver_path)); + } */ + } + + if (_this->gl_config.dll_handle != NULL) { + return 0; + } else { + _this->gl_config.dll_handle = NULL; + _this->gl_config.driver_loaded = 0; + *_this->gl_config.driver_path = '\0'; + return -1; + } +#endif +} + +void *BE_GL_GetProcAddress(_THIS, const char *proc) +{ +#if 0 + 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; + } +#endif +} + + + + +int BE_GL_MakeCurrent(_THIS) +{ + /* FIXME: should we glview->unlock and then glview->lock()? */ + return 0; +} + + + + + + + + + + + + +#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; + } + + void BE_GL_SwapBuffers(_THIS) + { + SDL_Win->SwapBuffers(); + } +#endif diff --git a/src/video/bwindow/SDL_bopengl.h b/src/video/bwindow/SDL_bopengl.h new file mode 100644 index 000000000..de32975b7 --- /dev/null +++ b/src/video/bwindow/SDL_bopengl.h @@ -0,0 +1,27 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2011 Sam Lantinga + + 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 +extern int BE_GL_LoadLibrary(_THIS, const char *path); +extern void *BE_GL_GetProcAddress(_THIS, const char *proc); +extern int BE_GL_MakeCurrent(_THIS); +#endif diff --git a/src/video/bwindow/SDL_bvideo.c b/src/video/bwindow/SDL_bvideo.c new file mode 100644 index 000000000..3b4fea7f8 --- /dev/null +++ b/src/video/bwindow/SDL_bvideo.c @@ -0,0 +1,202 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2011 Sam Lantinga + + 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_bwindow.h" +#include "SDL_bclipboard.h" +#include "SDL_bvideo.h" +#include "SDL_bopengl.h" +#include "SDL_bmodes.h" + +#ifdef __cplusplus +extern "C" { +#endif +/* FIXME: Undefined functions */ +// #define BE_VideoInit NULL +// #define BE_VideoQuit NULL + #define BE_GetDisplayBounds NULL + #define BE_GetDisplayModes NULL + #define BE_SetDisplayMode NULL + #define BE_PumpEvents NULL + +#if SDL_VIDEO_OPENGL_WGL /* FIXME: Replace with BeOs's SDL OPENGL stuff */ +// #define BE_GL_LoadLibrary NULL +// #define BE_GL_GetProcAddress NULL + #define BE_GL_UnloadLibrary NULL + #define BE_GL_CreateContext NULL +// #define BE_GL_MakeCurrent NULL + #define BE_GL_SetSwapInterval NULL + #define BE_GL_GetSwapInterval NULL + #define BE_GL_SwapWindow NULL + #define BE_GL_DeleteContext NULL +#endif + #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)); + if (device) { + data = (struct SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); + } else { + data = NULL; + } + if (!data) { + SDL_OutOfMemory(); + if (device) { + SDL_free(device); + } + return NULL; + } + device->driverdata = data; + +/* TODO: Figure out what sort of 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->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; + +#if SDL_VIDEO_OPENGL_WGL /* FIXME: Replace with BeOs's SDL OPENGL stuff */ + 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; +#endif + 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; +} + +static void BE_DeleteDevice(SDL_VideoDevice * device) +{ + SDL_free(device->driverdata); + SDL_free(device); +} + +/* FIXME: This is the 1.2 function at the moment. Read through it and + o understand what it does. */ +int BE_VideoInit(_THIS) +{ + /* Initialize the Be Application for appserver interaction */ + if (SDL_InitBeApp() < 0) { + return -1; + } + + BE_InitModes(_this); + +#if SDL_VIDEO_OPENGL + /* testgl application doesn't load library, just tries to load symbols */ + /* is it correct? if so we have to load library here */ + BE_GL_LoadLibrary(_this, NULL); +#endif + + /* Fill in some window manager capabilities */ +// _this->info.wm_available = 1; + + /* We're done! */ + return (0); +} + +static int BE_Available(void) +{ + return (1); +} + +void BE_VideoQuit(_THIS) +{ + +#if 0 + SDL_Win->Quit(); + SDL_Win = NULL; +#endif +#if 0 + if (SDL_BlankCursor != NULL) { + BE_FreeWMCursor(_this, SDL_BlankCursor); + SDL_BlankCursor = NULL; + } +#endif + + BE_QuitModes(_this); + +#if SDL_VIDEO_OPENGL +// if (_this->gl_config.dll_handle != NULL) +// unload_add_on((image_id) _this->gl_config.dll_handle); +#endif + + SDL_QuitBeApp(); +} + +#ifdef __cplusplus +} +#endif diff --git a/src/video/bwindow/SDL_bvideo.h b/src/video/bwindow/SDL_bvideo.h new file mode 100644 index 000000000..c1c32a6bb --- /dev/null +++ b/src/video/bwindow/SDL_bvideo.h @@ -0,0 +1,44 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2011 Sam Lantinga + + 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/beos/SDL_BeApp.h" +#include "../SDL_sysvideo.h" + +typedef struct SDL_VideoData { + +} SDL_VideoData; + +extern void BE_VideoQuit(_THIS); +extern int BE_VideoInit(_THIS); +extern void BE_DeleteDevice(_THIS); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/video/bwindow/SDL_bwindow.c b/src/video/bwindow/SDL_bwindow.c new file mode 100644 index 000000000..1341093e6 --- /dev/null +++ b/src/video/bwindow/SDL_bwindow.c @@ -0,0 +1,203 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2011 Sam Lantinga + + 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_config.h" +#include "../SDL_sysvideo.h" + +#include "SDL_BWin.h" +#include + +/* Define a path to window's BWIN data */ +#ifdef __cplusplus +extern "C" { +#endif + +static inline SDL_BWin *_ToBeWin(SDL_Window *window) { + return ((SDL_BWin*)(window->driverdata)); +} + +static inline SDL_BApp *_GetBeApp() { + return ((SDL_BApp*)be_app); +} + +int _InitWindow(_THIS, SDL_Window *window) { + 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 + ); + + SDL_BWin *bwin = new(std::nothrow) SDL_BWin(bounds); + 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(); + + /* 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 BeOs/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_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 BeOs/Haiku supported */ +} + +int BE_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) { + /* FIXME: Not BeOs/Haiku supported */ +} + + +void BE_SetWindowGrab(_THIS, SDL_Window * window) { + /* 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? */ +} + + +extern int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window, + Uint32 * format, + void ** pixels, int *pitch) { + /* FIXME: Not BeOs/Haiku supported */ + return -1; +} + +extern int BE_UpdateWindowFramebuffer(_THIS, SDL_Window * window, + SDL_Rect * rects, int numrects) { + /* FIXME: Not BeOs/Haiku supported */ + return -1; +} + +extern void BE_DestroyWindowFramebuffer(_THIS, SDL_Window * window) { + /* FIXME: Not BeOs/Haiku supported */ +} + + +#ifdef __cplusplus +} +#endif + diff --git a/src/video/bwindow/SDL_bwindow.h b/src/video/bwindow/SDL_bwindow.h new file mode 100644 index 000000000..26f800b7f --- /dev/null +++ b/src/video/bwindow/SDL_bwindow.h @@ -0,0 +1,56 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2011 Sam Lantinga + + 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_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); +extern void BE_DestroyWindow(_THIS, SDL_Window * window); +extern SDL_bool BE_GetWindowWMInfo(_THIS, SDL_Window * window, + struct SDL_SysWMinfo *info); + +extern int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window, + Uint32 * format, + void ** pixels, int *pitch); +extern int BE_UpdateWindowFramebuffer(_THIS, SDL_Window * window, + SDL_Rect * rects, int numrects); +extern void BE_DestroyWindowFramebuffer(_THIS, SDL_Window * window); + +#endif +