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