src/main/haiku/SDL_BApp.h
author Ryan C. Gordon <icculus@icculus.org>
Tue, 07 Aug 2018 18:07:11 -0400
changeset 12082 09999a0e8f9a
parent 11811 5d94cb6b24d3
child 12201 8bdc4d340419
permissions -rw-r--r--
haiku: Rename internal functions from BE_* to HAIKU_*

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