sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

SDL_BApp.h (11581B)


      1 /*
      2   Simple DirectMedia Layer
      3   Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
      4 
      5   This software is provided 'as-is', without any express or implied
      6   warranty.  In no event will the authors be held liable for any damages
      7   arising from the use of this software.
      8 
      9   Permission is granted to anyone to use this software for any purpose,
     10   including commercial applications, and to alter it and redistribute it
     11   freely, subject to the following restrictions:
     12 
     13   1. The origin of this software must not be misrepresented; you must not
     14      claim that you wrote the original software. If you use this software
     15      in a product, an acknowledgment in the product documentation would be
     16      appreciated but is not required.
     17   2. Altered source versions must be plainly marked as such, and must not be
     18      misrepresented as being the original software.
     19   3. This notice may not be removed or altered from any source distribution.
     20 */
     21 #ifndef SDL_BAPP_H
     22 #define SDL_BAPP_H
     23 
     24 #include <InterfaceKit.h>
     25 #include <LocaleRoster.h>
     26 #if SDL_VIDEO_OPENGL
     27 #include <OpenGLKit.h>
     28 #endif
     29 
     30 #include "../../video/haiku/SDL_bkeyboard.h"
     31 
     32 
     33 #ifdef __cplusplus
     34 extern "C" {
     35 #endif
     36 
     37 #include "../../SDL_internal.h"
     38 
     39 #include "SDL_video.h"
     40 
     41 /* Local includes */
     42 #include "../../events/SDL_events_c.h"
     43 #include "../../video/haiku/SDL_bframebuffer.h"
     44 
     45 #ifdef __cplusplus
     46 }
     47 #endif
     48 
     49 #include <vector>
     50 
     51 
     52 
     53 
     54 /* Forward declarations */
     55 class SDL_BWin;
     56 
     57 /* Message constants */
     58 enum ToSDL {
     59     /* Intercepted by BWindow on its way to BView */
     60     BAPP_MOUSE_MOVED,
     61     BAPP_MOUSE_BUTTON,
     62     BAPP_MOUSE_WHEEL,
     63     BAPP_KEY,
     64     BAPP_REPAINT,           /* from _UPDATE_ */
     65     /* From BWindow */
     66     BAPP_MAXIMIZE,          /* from B_ZOOM */
     67     BAPP_MINIMIZE,
     68     BAPP_RESTORE,           /* TODO: IMPLEMENT! */
     69     BAPP_SHOW,
     70     BAPP_HIDE,
     71     BAPP_MOUSE_FOCUS,       /* caused by MOUSE_MOVE */
     72     BAPP_KEYBOARD_FOCUS,    /* from WINDOW_ACTIVATED */
     73     BAPP_WINDOW_CLOSE_REQUESTED,
     74     BAPP_WINDOW_MOVED,
     75     BAPP_WINDOW_RESIZED,
     76     BAPP_SCREEN_CHANGED
     77 };
     78 
     79 
     80 
     81 /* Create a descendant of BApplication */
     82 class SDL_BApp : public BApplication {
     83 public:
     84     SDL_BApp(const char* signature) :
     85         BApplication(signature) {
     86 #if SDL_VIDEO_OPENGL
     87         _current_context = NULL;
     88 #endif
     89     }
     90 
     91 
     92     virtual ~SDL_BApp() {
     93     }
     94 
     95 
     96 
     97         /* Event-handling functions */
     98     virtual void MessageReceived(BMessage* message) {
     99         /* Sort out SDL-related messages */
    100         switch ( message->what ) {
    101         case BAPP_MOUSE_MOVED:
    102             _HandleMouseMove(message);
    103             break;
    104 
    105         case BAPP_MOUSE_BUTTON:
    106             _HandleMouseButton(message);
    107             break;
    108 
    109         case BAPP_MOUSE_WHEEL:
    110             _HandleMouseWheel(message);
    111             break;
    112 
    113         case BAPP_KEY:
    114             _HandleKey(message);
    115             break;
    116 
    117         case BAPP_REPAINT:
    118             _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_EXPOSED);
    119             break;
    120 
    121         case BAPP_MAXIMIZE:
    122             _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_MAXIMIZED);
    123             break;
    124 
    125         case BAPP_MINIMIZE:
    126             _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_MINIMIZED);
    127             break;
    128 
    129         case BAPP_SHOW:
    130             _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_SHOWN);
    131             break;
    132 
    133         case BAPP_HIDE:
    134             _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_HIDDEN);
    135             break;
    136 
    137         case BAPP_MOUSE_FOCUS:
    138             _HandleMouseFocus(message);
    139             break;
    140 
    141         case BAPP_KEYBOARD_FOCUS:
    142             _HandleKeyboardFocus(message);
    143             break;
    144 
    145         case BAPP_WINDOW_CLOSE_REQUESTED:
    146             _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_CLOSE);
    147             break;
    148 
    149         case BAPP_WINDOW_MOVED:
    150             _HandleWindowMoved(message);
    151             break;
    152 
    153         case BAPP_WINDOW_RESIZED:
    154             _HandleWindowResized(message);
    155             break;
    156 
    157         case B_LOCALE_CHANGED:
    158             SDL_SendLocaleChangedEvent();
    159             break;
    160 
    161         case BAPP_SCREEN_CHANGED:
    162             /* TODO: Handle screen resize or workspace change */
    163             break;
    164 
    165         default:
    166            BApplication::MessageReceived(message);
    167            break;
    168         }
    169     }
    170 
    171     /* Window creation/destruction methods */
    172     int32 GetID(SDL_Window *win) {
    173         int32 i;
    174         for(i = 0; i < _GetNumWindowSlots(); ++i) {
    175             if( GetSDLWindow(i) == NULL ) {
    176                 _SetSDLWindow(win, i);
    177                 return i;
    178             }
    179         }
    180 
    181         /* Expand the vector if all slots are full */
    182         if( i == _GetNumWindowSlots() ) {
    183             _PushBackWindow(win);
    184             return i;
    185         }
    186 
    187         /* TODO: error handling */
    188         return 0;
    189     }
    190 
    191     /* FIXME: Bad coding practice, but I can't include SDL_BWin.h here.  Is
    192        there another way to do this? */
    193     void ClearID(SDL_BWin *bwin); /* Defined in SDL_BeApp.cc */
    194 
    195 
    196     SDL_Window *GetSDLWindow(int32 winID) {
    197         return _window_map[winID];
    198     }
    199 
    200 #if SDL_VIDEO_OPENGL
    201     void SetCurrentContext(BGLView *newContext) {
    202         if(_current_context)
    203             _current_context->UnlockGL();
    204         _current_context = newContext;
    205         if (_current_context)
    206             _current_context->LockGL();
    207     }
    208 #endif
    209 
    210 private:
    211     /* Event management */
    212     void _HandleBasicWindowEvent(BMessage *msg, int32 sdlEventType) {
    213         SDL_Window *win;
    214         int32 winID;
    215         if(
    216             !_GetWinID(msg, &winID)
    217         ) {
    218             return;
    219         }
    220         win = GetSDLWindow(winID);
    221         SDL_SendWindowEvent(win, sdlEventType, 0, 0);
    222     }
    223 
    224     void _HandleMouseMove(BMessage *msg) {
    225         SDL_Window *win;
    226         int32 winID;
    227         int32 x = 0, y = 0;
    228         if(
    229             !_GetWinID(msg, &winID) ||
    230             msg->FindInt32("x", &x) != B_OK || /* x movement */
    231             msg->FindInt32("y", &y) != B_OK    /* y movement */
    232         ) {
    233             return;
    234         }
    235         win = GetSDLWindow(winID);
    236 
    237 		// Simple relative mode support for mouse.
    238 		if (SDL_GetMouse()->relative_mode) {
    239 			int winWidth, winHeight, winPosX, winPosY;
    240 			SDL_GetWindowSize(win, &winWidth, &winHeight);
    241 			SDL_GetWindowPosition(win, &winPosX, &winPosY);
    242 			int dx = x - (winWidth / 2);
    243 			int dy = y - (winHeight / 2);
    244 			SDL_SendMouseMotion(win, 0, SDL_GetMouse()->relative_mode, dx, dy);
    245 			set_mouse_position((winPosX + winWidth / 2), (winPosY + winHeight / 2));
    246 			if (!be_app->IsCursorHidden())
    247 				be_app->HideCursor();
    248 		} else {
    249 			SDL_SendMouseMotion(win, 0, 0, x, y);
    250 			if (SDL_ShowCursor(-1) && be_app->IsCursorHidden())
    251 				be_app->ShowCursor();
    252 		}
    253 
    254         /* Tell the application that the mouse passed over, redraw needed */
    255         HAIKU_UpdateWindowFramebuffer(NULL,win,NULL,-1);
    256     }
    257 
    258     void _HandleMouseButton(BMessage *msg) {
    259         SDL_Window *win;
    260         int32 winID;
    261         int32 button, state;    /* left/middle/right, pressed/released */
    262         if(
    263             !_GetWinID(msg, &winID) ||
    264             msg->FindInt32("button-id", &button) != B_OK ||
    265             msg->FindInt32("button-state", &state) != B_OK
    266         ) {
    267             return;
    268         }
    269         win = GetSDLWindow(winID);
    270         SDL_SendMouseButton(win, 0, state, button);
    271     }
    272 
    273     void _HandleMouseWheel(BMessage *msg) {
    274         SDL_Window *win;
    275         int32 winID;
    276         int32 xTicks, yTicks;
    277         if(
    278             !_GetWinID(msg, &winID) ||
    279             msg->FindInt32("xticks", &xTicks) != B_OK ||
    280             msg->FindInt32("yticks", &yTicks) != B_OK
    281         ) {
    282             return;
    283         }
    284         win = GetSDLWindow(winID);
    285         SDL_SendMouseWheel(win, 0, xTicks, -yTicks, SDL_MOUSEWHEEL_NORMAL);
    286     }
    287 
    288     void _HandleKey(BMessage *msg) {
    289         int32 scancode, state;  /* scancode, pressed/released */
    290         if(
    291             msg->FindInt32("key-state", &state) != B_OK ||
    292             msg->FindInt32("key-scancode", &scancode) != B_OK
    293         ) {
    294             return;
    295         }
    296 
    297         /* Make sure this isn't a repeated event (key pressed and held) */
    298         if(state == SDL_PRESSED && HAIKU_GetKeyState(scancode) == SDL_PRESSED) {
    299             return;
    300         }
    301         HAIKU_SetKeyState(scancode, state);
    302         SDL_SendKeyboardKey(state, HAIKU_GetScancodeFromBeKey(scancode));
    303         
    304         if (state == SDL_PRESSED && SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
    305             const int8 *keyUtf8;
    306             ssize_t count;
    307             if (msg->FindData("key-utf8", B_INT8_TYPE, (const void**)&keyUtf8, &count) == B_OK) {
    308                 char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
    309                 SDL_zeroa(text);
    310                 SDL_memcpy(text, keyUtf8, count);
    311                 SDL_SendKeyboardText(text);
    312             }
    313         }
    314     }
    315 
    316     void _HandleMouseFocus(BMessage *msg) {
    317         SDL_Window *win;
    318         int32 winID;
    319         bool bSetFocus; /* If false, lose focus */
    320         if(
    321             !_GetWinID(msg, &winID) ||
    322             msg->FindBool("focusGained", &bSetFocus) != B_OK
    323         ) {
    324             return;
    325         }
    326         win = GetSDLWindow(winID);
    327         if(bSetFocus) {
    328             SDL_SetMouseFocus(win);
    329         } else if(SDL_GetMouseFocus() == win) {
    330             /* Only lose all focus if this window was the current focus */
    331             SDL_SetMouseFocus(NULL);
    332         }
    333     }
    334 
    335     void _HandleKeyboardFocus(BMessage *msg) {
    336         SDL_Window *win;
    337         int32 winID;
    338         bool bSetFocus; /* If false, lose focus */
    339         if(
    340             !_GetWinID(msg, &winID) ||
    341             msg->FindBool("focusGained", &bSetFocus) != B_OK
    342         ) {
    343             return;
    344         }
    345         win = GetSDLWindow(winID);
    346         if(bSetFocus) {
    347             SDL_SetKeyboardFocus(win);
    348         } else if(SDL_GetKeyboardFocus() == win) {
    349             /* Only lose all focus if this window was the current focus */
    350             SDL_SetKeyboardFocus(NULL);
    351         }
    352     }
    353 
    354     void _HandleWindowMoved(BMessage *msg) {
    355         SDL_Window *win;
    356         int32 winID;
    357         int32 xPos, yPos;
    358         /* Get the window id and new x/y position of the window */
    359         if(
    360             !_GetWinID(msg, &winID) ||
    361             msg->FindInt32("window-x", &xPos) != B_OK ||
    362             msg->FindInt32("window-y", &yPos) != B_OK
    363         ) {
    364             return;
    365         }
    366         win = GetSDLWindow(winID);
    367         SDL_SendWindowEvent(win, SDL_WINDOWEVENT_MOVED, xPos, yPos);
    368     }
    369 
    370     void _HandleWindowResized(BMessage *msg) {
    371         SDL_Window *win;
    372         int32 winID;
    373         int32 w, h;
    374         /* Get the window id ]and new x/y position of the window */
    375         if(
    376             !_GetWinID(msg, &winID) ||
    377             msg->FindInt32("window-w", &w) != B_OK ||
    378             msg->FindInt32("window-h", &h) != B_OK
    379         ) {
    380             return;
    381         }
    382         win = GetSDLWindow(winID);
    383         SDL_SendWindowEvent(win, SDL_WINDOWEVENT_RESIZED, w, h);
    384     }
    385 
    386     bool _GetWinID(BMessage *msg, int32 *winID) {
    387         return msg->FindInt32("window-id", winID) == B_OK;
    388     }
    389 
    390 
    391 
    392     /* Vector functions: Wraps vector stuff in case we need to change
    393        implementation */
    394     void _SetSDLWindow(SDL_Window *win, int32 winID) {
    395         _window_map[winID] = win;
    396     }
    397 
    398     int32 _GetNumWindowSlots() {
    399         return _window_map.size();
    400     }
    401 
    402 
    403     void _PopBackWindow() {
    404         _window_map.pop_back();
    405     }
    406 
    407     void _PushBackWindow(SDL_Window *win) {
    408         _window_map.push_back(win);
    409     }
    410 
    411 
    412     /* Members */
    413     std::vector<SDL_Window*> _window_map; /* Keeps track of SDL_Windows by index-id */
    414 
    415 #if SDL_VIDEO_OPENGL
    416     BGLView      *_current_context;
    417 #endif
    418 };
    419 
    420 #endif