cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

SDL_BApp.h (10305B)


      1/*
      2  Simple DirectMedia Layer
      3  Copyright (C) 1997-2014 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 <OpenGLKit.h>
     26
     27#include "../../video/haiku/SDL_bkeyboard.h"
     28
     29
     30#ifdef __cplusplus
     31extern "C" {
     32#endif
     33
     34#include "../../SDL_internal.h"
     35
     36#include "SDL_video.h"
     37
     38/* Local includes */
     39#include "../../events/SDL_events_c.h"
     40#include "../../video/haiku/SDL_bkeyboard.h"
     41#include "../../video/haiku/SDL_bframebuffer.h"
     42
     43#ifdef __cplusplus
     44}
     45#endif
     46
     47#include <vector>
     48
     49
     50
     51
     52/* Forward declarations */
     53class SDL_BWin;
     54
     55/* Message constants */
     56enum ToSDL {
     57    /* Intercepted by BWindow on its way to BView */
     58    BAPP_MOUSE_MOVED,
     59    BAPP_MOUSE_BUTTON,
     60    BAPP_MOUSE_WHEEL,
     61    BAPP_KEY,
     62    BAPP_REPAINT,           /* from _UPDATE_ */
     63    /* From BWindow */
     64    BAPP_MAXIMIZE,          /* from B_ZOOM */
     65    BAPP_MINIMIZE,
     66    BAPP_RESTORE,           /* TODO: IMPLEMENT! */
     67    BAPP_SHOW,
     68    BAPP_HIDE,
     69    BAPP_MOUSE_FOCUS,       /* caused by MOUSE_MOVE */
     70    BAPP_KEYBOARD_FOCUS,    /* from WINDOW_ACTIVATED */
     71    BAPP_WINDOW_CLOSE_REQUESTED,
     72    BAPP_WINDOW_MOVED,
     73    BAPP_WINDOW_RESIZED,
     74    BAPP_SCREEN_CHANGED
     75};
     76
     77
     78
     79/* Create a descendant of BApplication */
     80class SDL_BApp : public BApplication {
     81public:
     82    SDL_BApp(const char* signature) :
     83        BApplication(signature) {
     84        _current_context = NULL;
     85    }
     86
     87
     88    virtual ~SDL_BApp() {
     89    }
     90
     91
     92
     93        /* Event-handling functions */
     94    virtual void MessageReceived(BMessage* message) {
     95        /* Sort out SDL-related messages */
     96        switch ( message->what ) {
     97        case BAPP_MOUSE_MOVED:
     98            _HandleMouseMove(message);
     99            break;
    100
    101        case BAPP_MOUSE_BUTTON:
    102            _HandleMouseButton(message);
    103            break;
    104
    105        case BAPP_MOUSE_WHEEL:
    106            _HandleMouseWheel(message);
    107            break;
    108
    109        case BAPP_KEY:
    110            _HandleKey(message);
    111            break;
    112
    113        case BAPP_REPAINT:
    114            _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_EXPOSED);
    115            break;
    116
    117        case BAPP_MAXIMIZE:
    118            _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_MAXIMIZED);
    119            break;
    120
    121        case BAPP_MINIMIZE:
    122            _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_MINIMIZED);
    123            break;
    124
    125        case BAPP_SHOW:
    126            _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_SHOWN);
    127            break;
    128
    129        case BAPP_HIDE:
    130            _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_HIDDEN);
    131            break;
    132
    133        case BAPP_MOUSE_FOCUS:
    134            _HandleMouseFocus(message);
    135            break;
    136
    137        case BAPP_KEYBOARD_FOCUS:
    138            _HandleKeyboardFocus(message);
    139            break;
    140
    141        case BAPP_WINDOW_CLOSE_REQUESTED:
    142            _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_CLOSE);
    143            break;
    144
    145        case BAPP_WINDOW_MOVED:
    146            _HandleWindowMoved(message);
    147            break;
    148
    149        case BAPP_WINDOW_RESIZED:
    150            _HandleWindowResized(message);
    151            break;
    152
    153        case BAPP_SCREEN_CHANGED:
    154            /* TODO: Handle screen resize or workspace change */
    155            break;
    156
    157        default:
    158           BApplication::MessageReceived(message);
    159           break;
    160        }
    161    }
    162
    163    /* Window creation/destruction methods */
    164    int32 GetID(SDL_Window *win) {
    165        int32 i;
    166        for(i = 0; i < _GetNumWindowSlots(); ++i) {
    167            if( GetSDLWindow(i) == NULL ) {
    168                _SetSDLWindow(win, i);
    169                return i;
    170            }
    171        }
    172
    173        /* Expand the vector if all slots are full */
    174        if( i == _GetNumWindowSlots() ) {
    175            _PushBackWindow(win);
    176            return i;
    177        }
    178
    179        /* TODO: error handling */
    180        return 0;
    181    }
    182
    183    /* FIXME: Bad coding practice, but I can't include SDL_BWin.h here.  Is
    184       there another way to do this? */
    185    void ClearID(SDL_BWin *bwin); /* Defined in SDL_BeApp.cc */
    186
    187
    188    SDL_Window *GetSDLWindow(int32 winID) {
    189        return _window_map[winID];
    190    }
    191
    192    void SetCurrentContext(BGLView *newContext) {
    193        if(_current_context)
    194            _current_context->UnlockGL();
    195        _current_context = newContext;
    196        _current_context->LockGL();
    197    }
    198private:
    199    /* Event management */
    200    void _HandleBasicWindowEvent(BMessage *msg, int32 sdlEventType) {
    201        SDL_Window *win;
    202        int32 winID;
    203        if(
    204            !_GetWinID(msg, &winID)
    205        ) {
    206            return;
    207        }
    208        win = GetSDLWindow(winID);
    209        SDL_SendWindowEvent(win, sdlEventType, 0, 0);
    210    }
    211
    212    void _HandleMouseMove(BMessage *msg) {
    213        SDL_Window *win;
    214        int32 winID;
    215        int32 x = 0, y = 0;
    216        if(
    217            !_GetWinID(msg, &winID) ||
    218            msg->FindInt32("x", &x) != B_OK || /* x movement */
    219            msg->FindInt32("y", &y) != B_OK    /* y movement */
    220        ) {
    221            return;
    222        }
    223        win = GetSDLWindow(winID);
    224        SDL_SendMouseMotion(win, 0, 0, x, y);
    225
    226        /* Tell the application that the mouse passed over, redraw needed */
    227        BE_UpdateWindowFramebuffer(NULL,win,NULL,-1);
    228    }
    229
    230    void _HandleMouseButton(BMessage *msg) {
    231        SDL_Window *win;
    232        int32 winID;
    233        int32 button, state;    /* left/middle/right, pressed/released */
    234        if(
    235            !_GetWinID(msg, &winID) ||
    236            msg->FindInt32("button-id", &button) != B_OK ||
    237            msg->FindInt32("button-state", &state) != B_OK
    238        ) {
    239            return;
    240        }
    241        win = GetSDLWindow(winID);
    242        SDL_SendMouseButton(win, 0, state, button);
    243    }
    244
    245    void _HandleMouseWheel(BMessage *msg) {
    246        SDL_Window *win;
    247        int32 winID;
    248        int32 xTicks, yTicks;
    249        if(
    250            !_GetWinID(msg, &winID) ||
    251            msg->FindInt32("xticks", &xTicks) != B_OK ||
    252            msg->FindInt32("yticks", &yTicks) != B_OK
    253        ) {
    254            return;
    255        }
    256        win = GetSDLWindow(winID);
    257        SDL_SendMouseWheel(win, 0, xTicks, yTicks);
    258    }
    259
    260    void _HandleKey(BMessage *msg) {
    261        int32 scancode, state;  /* scancode, pressed/released */
    262        if(
    263            msg->FindInt32("key-state", &state) != B_OK ||
    264            msg->FindInt32("key-scancode", &scancode) != B_OK
    265        ) {
    266            return;
    267        }
    268
    269        /* Make sure this isn't a repeated event (key pressed and held) */
    270        if(state == SDL_PRESSED && BE_GetKeyState(scancode) == SDL_PRESSED) {
    271            return;
    272        }
    273        BE_SetKeyState(scancode, state);
    274        SDL_SendKeyboardKey(state, BE_GetScancodeFromBeKey(scancode));
    275    }
    276
    277    void _HandleMouseFocus(BMessage *msg) {
    278        SDL_Window *win;
    279        int32 winID;
    280        bool bSetFocus; /* If false, lose focus */
    281        if(
    282            !_GetWinID(msg, &winID) ||
    283            msg->FindBool("focusGained", &bSetFocus) != B_OK
    284        ) {
    285            return;
    286        }
    287        win = GetSDLWindow(winID);
    288        if(bSetFocus) {
    289            SDL_SetMouseFocus(win);
    290        } else if(SDL_GetMouseFocus() == win) {
    291            /* Only lose all focus if this window was the current focus */
    292            SDL_SetMouseFocus(NULL);
    293        }
    294    }
    295
    296    void _HandleKeyboardFocus(BMessage *msg) {
    297        SDL_Window *win;
    298        int32 winID;
    299        bool bSetFocus; /* If false, lose focus */
    300        if(
    301            !_GetWinID(msg, &winID) ||
    302            msg->FindBool("focusGained", &bSetFocus) != B_OK
    303        ) {
    304            return;
    305        }
    306        win = GetSDLWindow(winID);
    307        if(bSetFocus) {
    308            SDL_SetKeyboardFocus(win);
    309        } else if(SDL_GetKeyboardFocus() == win) {
    310            /* Only lose all focus if this window was the current focus */
    311            SDL_SetKeyboardFocus(NULL);
    312        }
    313    }
    314
    315    void _HandleWindowMoved(BMessage *msg) {
    316        SDL_Window *win;
    317        int32 winID;
    318        int32 xPos, yPos;
    319        /* Get the window id and new x/y position of the window */
    320        if(
    321            !_GetWinID(msg, &winID) ||
    322            msg->FindInt32("window-x", &xPos) != B_OK ||
    323            msg->FindInt32("window-y", &yPos) != B_OK
    324        ) {
    325            return;
    326        }
    327        win = GetSDLWindow(winID);
    328        SDL_SendWindowEvent(win, SDL_WINDOWEVENT_MOVED, xPos, yPos);
    329    }
    330
    331    void _HandleWindowResized(BMessage *msg) {
    332        SDL_Window *win;
    333        int32 winID;
    334        int32 w, h;
    335        /* Get the window id ]and new x/y position of the window */
    336        if(
    337            !_GetWinID(msg, &winID) ||
    338            msg->FindInt32("window-w", &w) != B_OK ||
    339            msg->FindInt32("window-h", &h) != B_OK
    340        ) {
    341            return;
    342        }
    343        win = GetSDLWindow(winID);
    344        SDL_SendWindowEvent(win, SDL_WINDOWEVENT_RESIZED, w, h);
    345    }
    346
    347    bool _GetWinID(BMessage *msg, int32 *winID) {
    348        return msg->FindInt32("window-id", winID) == B_OK;
    349    }
    350
    351
    352
    353    /* Vector functions: Wraps vector stuff in case we need to change
    354       implementation */
    355    void _SetSDLWindow(SDL_Window *win, int32 winID) {
    356        _window_map[winID] = win;
    357    }
    358
    359    int32 _GetNumWindowSlots() {
    360        return _window_map.size();
    361    }
    362
    363
    364    void _PopBackWindow() {
    365        _window_map.pop_back();
    366    }
    367
    368    void _PushBackWindow(SDL_Window *win) {
    369        _window_map.push_back(win);
    370    }
    371
    372
    373    /* Members */
    374    std::vector<SDL_Window*> _window_map; /* Keeps track of SDL_Windows by index-id */
    375
    376    display_mode *_saved_mode;
    377    BGLView      *_current_context;
    378};
    379
    380#endif