src/video/haiku/SDL_BWin.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.
slouken@0
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@11811
     3
  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
slouken@0
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@0
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@0
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@0
    20
*/
slouken@0
    21
slouken@11382
    22
#ifndef SDL_BWin_h_
slouken@11382
    23
#define SDL_BWin_h_
slouken@0
    24
nathanheisey@5916
    25
#ifdef __cplusplus
nathanheisey@5916
    26
extern "C" {
nathanheisey@5916
    27
#endif
nathanheisey@5916
    28
icculus@8093
    29
#include "../../SDL_internal.h"
nathanheisey@5916
    30
#include "SDL.h"
nathanheisey@5916
    31
#include "SDL_syswm.h"
nathanheisey@5931
    32
#include "SDL_bframebuffer.h"
nathanheisey@5916
    33
nathanheisey@5916
    34
#ifdef __cplusplus
nathanheisey@5916
    35
}
nathanheisey@5916
    36
#endif
slouken@1367
    37
slouken@0
    38
#include <stdio.h>
slouken@0
    39
#include <AppKit.h>
slouken@0
    40
#include <InterfaceKit.h>
icculus@10983
    41
#include <game/DirectWindow.h>
slouken@1361
    42
#if SDL_VIDEO_OPENGL
icculus@10983
    43
#include <opengl/GLView.h>
slouken@0
    44
#endif
slouken@0
    45
#include "SDL_events.h"
icculus@7981
    46
#include "../../main/haiku/SDL_BApp.h"
slouken@0
    47
nathanheisey@5931
    48
nathanheisey@5916
    49
enum WinCommands {
slouken@7191
    50
    BWIN_MOVE_WINDOW,
slouken@7191
    51
    BWIN_RESIZE_WINDOW,
slouken@7191
    52
    BWIN_SHOW_WINDOW,
slouken@7191
    53
    BWIN_HIDE_WINDOW,
slouken@7191
    54
    BWIN_MAXIMIZE_WINDOW,
slouken@7191
    55
    BWIN_MINIMIZE_WINDOW,
slouken@7191
    56
    BWIN_RESTORE_WINDOW,
slouken@7191
    57
    BWIN_SET_TITLE,
slouken@7191
    58
    BWIN_SET_BORDERED,
icculus@10385
    59
    BWIN_SET_RESIZABLE,
slouken@7191
    60
    BWIN_FULLSCREEN
slouken@0
    61
};
slouken@0
    62
nathanheisey@5916
    63
slouken@1895
    64
class SDL_BWin:public BDirectWindow
slouken@0
    65
{
slouken@1895
    66
  public:
slouken@7191
    67
    /* Constructor/Destructor */
icculus@6421
    68
    SDL_BWin(BRect bounds, window_look look, uint32 flags)
icculus@6421
    69
        : BDirectWindow(bounds, "Untitled", look, B_NORMAL_WINDOW_FEEL, flags)
slouken@1895
    70
    {
nathanheisey@5925
    71
        _last_buttons = 0;
nathanheisey@5923
    72
slouken@1361
    73
#if SDL_VIDEO_OPENGL
nathanheisey@5925
    74
        _SDL_GLView = NULL;
philipp@11107
    75
        _gl_type = 0;
slouken@0
    76
#endif
nathanheisey@5916
    77
        _shown = false;
nathanheisey@5925
    78
        _inhibit_resize = false;
nathanheisey@5925
    79
        _mouse_focused = false;
nathanheisey@5925
    80
        _prev_frame = NULL;
nathanheisey@5925
    81
nathanheisey@5922
    82
        /* Handle framebuffer stuff */
nathanheisey@5925
    83
        _connected = _connection_disabled = false;
nathanheisey@5929
    84
        _buffer_created = _buffer_dirty = false;
nathanheisey@5930
    85
        _trash_window_buffer = false;
nathanheisey@5925
    86
        _buffer_locker = new BLocker();
nathanheisey@5933
    87
        _bitmap = NULL;
icculus@7984
    88
        _clips = NULL;
icculus@7984
    89
nathanheisey@5936
    90
#ifdef DRAWTHREAD
icculus@12082
    91
        _draw_thread_id = spawn_thread(HAIKU_DrawThread, "drawing_thread",
slouken@7191
    92
                            B_NORMAL_PRIORITY, (void*) this);
nathanheisey@5929
    93
        resume_thread(_draw_thread_id);
nathanheisey@5936
    94
#endif
slouken@1895
    95
    }
slouken@907
    96
slouken@1895
    97
    virtual ~ SDL_BWin()
slouken@1895
    98
    {
slouken@1895
    99
        Lock();
nathanheisey@5925
   100
        _connection_disabled = true;
nathanheisey@5929
   101
        int32 result;
slouken@7191
   102
slouken@1361
   103
#if SDL_VIDEO_OPENGL
nathanheisey@5925
   104
        if (_SDL_GLView) {
nathanheisey@5925
   105
            _SDL_GLView->UnlockGL();
slouken@7191
   106
            RemoveChild(_SDL_GLView);   /* Why was this outside the if
slouken@7191
   107
                                            statement before? */
slouken@1895
   108
        }
slouken@7191
   109
slouken@7191
   110
#endif
slouken@1895
   111
        Unlock();
slouken@1361
   112
#if SDL_VIDEO_OPENGL
nathanheisey@5925
   113
        if (_SDL_GLView) {
nathanheisey@5925
   114
            delete _SDL_GLView;
slouken@1895
   115
        }
slouken@0
   116
#endif
slouken@7191
   117
philipp@11118
   118
        delete _prev_frame;
philipp@11118
   119
nathanheisey@5922
   120
        /* Clean up framebuffer stuff */
nathanheisey@5925
   121
        _buffer_locker->Lock();
nathanheisey@5936
   122
#ifdef DRAWTHREAD
nathanheisey@5929
   123
        wait_for_thread(_draw_thread_id, &result);
nathanheisey@5936
   124
#endif
nathanheisey@5923
   125
        free(_clips);
nathanheisey@5925
   126
        delete _buffer_locker;
slouken@1895
   127
    }
slouken@7191
   128
nathanheisey@5923
   129
nathanheisey@5931
   130
    /* * * * * OpenGL functionality * * * * */
nathanheisey@5923
   131
#if SDL_VIDEO_OPENGL
nathanheisey@5931
   132
    virtual BGLView *CreateGLView(Uint32 gl_flags) {
slouken@1895
   133
        Lock();
nathanheisey@5931
   134
        if (_SDL_GLView == NULL) {
nathanheisey@5931
   135
            _SDL_GLView = new BGLView(Bounds(), "SDL GLView",
nathanheisey@5931
   136
                                     B_FOLLOW_ALL_SIDES,
nathanheisey@5931
   137
                                     (B_WILL_DRAW | B_FRAME_EVENTS),
nathanheisey@5931
   138
                                     gl_flags);
philipp@11107
   139
            _gl_type = gl_flags;
slouken@1895
   140
        }
nathanheisey@5931
   141
        AddChild(_SDL_GLView);
nathanheisey@5937
   142
        _SDL_GLView->EnableDirectMode(true);
slouken@7191
   143
        _SDL_GLView->LockGL();  /* "New" GLViews are created */
slouken@1895
   144
        Unlock();
nathanheisey@5931
   145
        return (_SDL_GLView);
slouken@1895
   146
    }
slouken@7191
   147
nathanheisey@5931
   148
    virtual void RemoveGLView() {
slouken@7191
   149
        Lock();
slouken@7191
   150
        if(_SDL_GLView) {
slouken@7191
   151
            _SDL_GLView->UnlockGL();
slouken@7191
   152
            RemoveChild(_SDL_GLView);
slouken@7191
   153
        }
slouken@7191
   154
        Unlock();
nathanheisey@5931
   155
    }
slouken@7191
   156
nathanheisey@5931
   157
    virtual void SwapBuffers(void) {
slouken@7191
   158
        _SDL_GLView->UnlockGL();
slouken@7191
   159
        _SDL_GLView->LockGL();
slouken@7191
   160
        _SDL_GLView->SwapBuffers();
slouken@7191
   161
    }
nathanheisey@5923
   162
#endif
slouken@7191
   163
nathanheisey@5921
   164
    /* * * * * Framebuffering* * * * */
nathanheisey@5921
   165
    virtual void DirectConnected(direct_buffer_info *info) {
slouken@7191
   166
        if(!_connected && _connection_disabled) {
slouken@7191
   167
            return;
slouken@7191
   168
        }
nathanheisey@5930
   169
slouken@7191
   170
        /* Determine if the pixel buffer is usable after this update */
slouken@7191
   171
        _trash_window_buffer =      _trash_window_buffer
slouken@7191
   172
                                || ((info->buffer_state & B_BUFFER_RESIZED)
slouken@7191
   173
                                || (info->buffer_state & B_BUFFER_RESET)
slouken@7191
   174
                                || (info->driver_state == B_MODE_CHANGED));
slouken@7191
   175
        LockBuffer();
nathanheisey@5930
   176
slouken@7191
   177
        switch(info->buffer_state & B_DIRECT_MODE_MASK) {
slouken@7191
   178
        case B_DIRECT_START:
slouken@7191
   179
            _connected = true;
nathanheisey@5922
   180
slouken@7191
   181
        case B_DIRECT_MODIFY:
slouken@7191
   182
            if(_clips) {
slouken@7191
   183
                free(_clips);
slouken@7191
   184
                _clips = NULL;
slouken@7191
   185
            }
nathanheisey@5922
   186
slouken@7191
   187
            _num_clips = info->clip_list_count;
slouken@7191
   188
            _clips = (clipping_rect *)malloc(_num_clips*sizeof(clipping_rect));
slouken@7191
   189
            if(_clips) {
slouken@7191
   190
                memcpy(_clips, info->clip_list,
slouken@7191
   191
                    _num_clips*sizeof(clipping_rect));
slouken@7191
   192
slouken@7191
   193
                _bits = (uint8*) info->bits;
slouken@7191
   194
                _row_bytes = info->bytes_per_row;
slouken@7191
   195
                _bounds = info->window_bounds;
slouken@7191
   196
                _bytes_per_px = info->bits_per_pixel / 8;
slouken@7191
   197
                _buffer_dirty = true;
slouken@7191
   198
            }
slouken@7191
   199
            break;
slouken@7191
   200
slouken@7191
   201
        case B_DIRECT_STOP:
slouken@7191
   202
            _connected = false;
slouken@7191
   203
            break;
slouken@7191
   204
        }
nathanheisey@5931
   205
#if SDL_VIDEO_OPENGL
slouken@7191
   206
        if(_SDL_GLView) {
slouken@7191
   207
            _SDL_GLView->DirectConnected(info);
slouken@7191
   208
        }
nathanheisey@5931
   209
#endif
slouken@7191
   210
slouken@7191
   211
slouken@7191
   212
        /* Call the base object directconnected */
slouken@7191
   213
        BDirectWindow::DirectConnected(info);
slouken@7191
   214
slouken@7191
   215
        UnlockBuffer();
slouken@7191
   216
nathanheisey@5921
   217
    }
slouken@7191
   218
slouken@7191
   219
slouken@7191
   220
slouken@7191
   221
nathanheisey@5916
   222
    /* * * * * Event sending * * * * */
nathanheisey@5916
   223
    /* Hook functions */
nathanheisey@5916
   224
    virtual void FrameMoved(BPoint origin) {
slouken@7191
   225
        /* Post a message to the BApp so that it can handle the window event */
slouken@7191
   226
        BMessage msg(BAPP_WINDOW_MOVED);
slouken@7191
   227
        msg.AddInt32("window-x", (int)origin.x);
slouken@7191
   228
        msg.AddInt32("window-y", (int)origin.y);
slouken@7191
   229
        _PostWindowEvent(msg);
nathanheisey@5939
   230
slouken@7191
   231
        /* Perform normal hook operations */
slouken@7191
   232
        BDirectWindow::FrameMoved(origin);
nathanheisey@5916
   233
    }
nathanheisey@5916
   234
slouken@7191
   235
    virtual void FrameResized(float width, float height) {
slouken@7191
   236
        /* Post a message to the BApp so that it can handle the window event */
slouken@7191
   237
        BMessage msg(BAPP_WINDOW_RESIZED);
nathanheisey@5925
   238
slouken@7191
   239
        msg.AddInt32("window-w", (int)width + 1);
slouken@7191
   240
        msg.AddInt32("window-h", (int)height + 1);
slouken@7191
   241
        _PostWindowEvent(msg);
slouken@7191
   242
slouken@7191
   243
        /* Perform normal hook operations */
slouken@7191
   244
        BDirectWindow::FrameResized(width, height);
nathanheisey@5916
   245
    }
slouken@7191
   246
slouken@7191
   247
    virtual bool QuitRequested() {
slouken@7191
   248
        BMessage msg(BAPP_WINDOW_CLOSE_REQUESTED);
slouken@7191
   249
        _PostWindowEvent(msg);
slouken@7191
   250
slouken@7191
   251
        /* We won't allow a quit unless asked by DestroyWindow() */
slouken@7191
   252
        return false;
slouken@7191
   253
    }
slouken@7191
   254
nathanheisey@5916
   255
    virtual void WindowActivated(bool active) {
slouken@7191
   256
        BMessage msg(BAPP_KEYBOARD_FOCUS);  /* Mouse focus sold separately */
icculus@11044
   257
        msg.AddBool("focusGained", active);
slouken@7191
   258
        _PostWindowEvent(msg);
nathanheisey@5916
   259
    }
slouken@7191
   260
nathanheisey@5916
   261
    virtual void Zoom(BPoint origin,
slouken@7191
   262
                float width,
slouken@7191
   263
                float height) {
slouken@7191
   264
        BMessage msg(BAPP_MAXIMIZE);    /* Closest thing to maximization Haiku has */
slouken@7191
   265
        _PostWindowEvent(msg);
nathanheisey@5916
   266
slouken@7191
   267
        /* Before the window zooms, record its size */
slouken@7191
   268
        if( !_prev_frame )
slouken@7191
   269
            _prev_frame = new BRect(Frame());
slouken@7191
   270
slouken@7191
   271
        /* Perform normal hook operations */
slouken@7191
   272
        BDirectWindow::Zoom(origin, width, height);
nathanheisey@5916
   273
    }
slouken@7191
   274
nathanheisey@5916
   275
    /* Member functions */
nathanheisey@5916
   276
    virtual void Show() {
slouken@7191
   277
        while(IsHidden()) {
slouken@7191
   278
            BDirectWindow::Show();
slouken@7191
   279
        }
slouken@7191
   280
        _shown = true;
nathanheisey@5925
   281
slouken@7191
   282
        BMessage msg(BAPP_SHOW);
slouken@7191
   283
        _PostWindowEvent(msg);
nathanheisey@5916
   284
    }
slouken@7191
   285
nathanheisey@5916
   286
    virtual void Hide() {
slouken@7191
   287
        BDirectWindow::Hide();
slouken@7191
   288
        _shown = false;
nathanheisey@5925
   289
slouken@7191
   290
        BMessage msg(BAPP_HIDE);
slouken@7191
   291
        _PostWindowEvent(msg);
nathanheisey@5916
   292
    }
nathanheisey@5916
   293
nathanheisey@5916
   294
    virtual void Minimize(bool minimize) {
slouken@7191
   295
        BDirectWindow::Minimize(minimize);
slouken@7191
   296
        int32 minState = (minimize ? BAPP_MINIMIZE : BAPP_RESTORE);
slouken@7191
   297
slouken@7191
   298
        BMessage msg(minState);
slouken@7191
   299
        _PostWindowEvent(msg);
nathanheisey@5916
   300
    }
slouken@7191
   301
slouken@7191
   302
nathanheisey@5916
   303
    /* BView message interruption */
nathanheisey@5916
   304
    virtual void DispatchMessage(BMessage * msg, BHandler * target)
slouken@1895
   305
    {
slouken@7191
   306
        BPoint where;   /* Used by mouse moved */
slouken@7191
   307
        int32 buttons;  /* Used for mouse button events */
slouken@7191
   308
        int32 key;      /* Used for key events */
slouken@7191
   309
nathanheisey@5916
   310
        switch (msg->what) {
nathanheisey@5916
   311
        case B_MOUSE_MOVED:
nathanheisey@5916
   312
            int32 transit;
nathanheisey@5916
   313
            if (msg->FindPoint("where", &where) == B_OK
nathanheisey@5916
   314
                && msg->FindInt32("be:transit", &transit) == B_OK) {
slouken@7191
   315
                _MouseMotionEvent(where, transit);
nathanheisey@5916
   316
            }
slouken@7191
   317
nathanheisey@5916
   318
            /* FIXME: Apparently a button press/release event might be dropped
nathanheisey@5916
   319
               if made before before a different button is released.  Does
nathanheisey@5916
   320
               B_MOUSE_MOVED have the data needed to check if a mouse button
nathanheisey@5916
   321
               state has changed? */
nathanheisey@5916
   322
            if (msg->FindInt32("buttons", &buttons) == B_OK) {
slouken@7191
   323
                _MouseButtonEvent(buttons);
nathanheisey@5916
   324
            }
nathanheisey@5916
   325
            break;
nathanheisey@5916
   326
nathanheisey@5916
   327
        case B_MOUSE_DOWN:
nathanheisey@5916
   328
        case B_MOUSE_UP:
nathanheisey@5916
   329
            /* _MouseButtonEvent() detects any and all buttons that may have
nathanheisey@5916
   330
               changed state, as well as that button's new state */
nathanheisey@5916
   331
            if (msg->FindInt32("buttons", &buttons) == B_OK) {
slouken@7191
   332
                _MouseButtonEvent(buttons);
nathanheisey@5916
   333
            }
nathanheisey@5916
   334
            break;
nathanheisey@5916
   335
nathanheisey@5916
   336
        case B_MOUSE_WHEEL_CHANGED:
slouken@7191
   337
            float x, y;
slouken@7191
   338
            if (msg->FindFloat("be:wheel_delta_x", &x) == B_OK
slouken@7191
   339
                && msg->FindFloat("be:wheel_delta_y", &y) == B_OK) {
slouken@7191
   340
                    _MouseWheelEvent((int)x, (int)y);
slouken@7191
   341
            }
slouken@7191
   342
            break;
nathanheisey@5916
   343
nathanheisey@5916
   344
        case B_KEY_DOWN:
slouken@10555
   345
            {
slouken@10555
   346
                int32 i = 0;
slouken@10555
   347
                int8 byte;
slouken@10555
   348
                int8 bytes[4] = { 0, 0, 0, 0 };
slouken@10555
   349
                while (i < 4 && msg->FindInt8("byte", i, &byte) == B_OK) {
slouken@10555
   350
                    bytes[i] = byte;
slouken@10555
   351
                    i++;
slouken@10555
   352
                }
slouken@10555
   353
                if (msg->FindInt32("key", &key) == B_OK) {
slouken@10555
   354
                    _KeyEvent((SDL_Scancode)key, &bytes[0], i, SDL_PRESSED);
slouken@10555
   355
                }
slouken@10555
   356
            }
slouken@10555
   357
            break;
slouken@10555
   358
            
nathanheisey@5916
   359
        case B_UNMAPPED_KEY_DOWN:      /* modifier keys are unmapped */
slouken@7191
   360
            if (msg->FindInt32("key", &key) == B_OK) {
slouken@10555
   361
                _KeyEvent((SDL_Scancode)key, NULL, 0, SDL_PRESSED);
slouken@7191
   362
            }
slouken@7191
   363
            break;
nathanheisey@5916
   364
nathanheisey@5916
   365
        case B_KEY_UP:
nathanheisey@5916
   366
        case B_UNMAPPED_KEY_UP:        /* modifier keys are unmapped */
slouken@7191
   367
            if (msg->FindInt32("key", &key) == B_OK) {
slouken@10555
   368
                _KeyEvent(key, NULL, 0, SDL_RELEASED);
nathanheisey@5916
   369
            }
nathanheisey@5916
   370
            break;
slouken@7191
   371
nathanheisey@5916
   372
        default:
nathanheisey@5916
   373
            /* move it after switch{} so it's always handled
icculus@7981
   374
               that way we keep Haiku features like:
nathanheisey@5916
   375
               - CTRL+Q to close window (and other shortcuts)
nathanheisey@5916
   376
               - PrintScreen to make screenshot into /boot/home
nathanheisey@5916
   377
               - etc.. */
gabomdq@7678
   378
            /* BDirectWindow::DispatchMessage(msg, target); */
nathanheisey@5916
   379
            break;
nathanheisey@5916
   380
        }
nathanheisey@5925
   381
nathanheisey@5916
   382
        BDirectWindow::DispatchMessage(msg, target);
slouken@1895
   383
    }
slouken@7191
   384
nathanheisey@5916
   385
    /* Handle command messages */
nathanheisey@5916
   386
    virtual void MessageReceived(BMessage* message) {
slouken@7191
   387
        switch (message->what) {
slouken@7191
   388
            /* Handle commands from SDL */
slouken@7191
   389
            case BWIN_SET_TITLE:
slouken@7191
   390
                _SetTitle(message);
slouken@7191
   391
                break;
slouken@7191
   392
            case BWIN_MOVE_WINDOW:
slouken@7191
   393
                _MoveTo(message);
slouken@7191
   394
                break;
slouken@7191
   395
            case BWIN_RESIZE_WINDOW:
slouken@7191
   396
                _ResizeTo(message);
slouken@7191
   397
                break;
slouken@7191
   398
            case BWIN_SET_BORDERED:
slouken@7191
   399
                _SetBordered(message);
slouken@7191
   400
                break;
icculus@10385
   401
            case BWIN_SET_RESIZABLE:
icculus@10385
   402
                _SetResizable(message);
icculus@10385
   403
                break;
slouken@7191
   404
            case BWIN_SHOW_WINDOW:
slouken@7191
   405
                Show();
slouken@7191
   406
                break;
slouken@7191
   407
            case BWIN_HIDE_WINDOW:
slouken@7191
   408
                Hide();
slouken@7191
   409
                break;
slouken@7191
   410
            case BWIN_MAXIMIZE_WINDOW:
slouken@7191
   411
                BWindow::Zoom();
slouken@7191
   412
                break;
slouken@7191
   413
            case BWIN_MINIMIZE_WINDOW:
slouken@7191
   414
                Minimize(true);
slouken@7191
   415
                break;
slouken@7191
   416
            case BWIN_RESTORE_WINDOW:
slouken@7191
   417
                _Restore();
slouken@7191
   418
                break;
slouken@7191
   419
            case BWIN_FULLSCREEN:
slouken@7191
   420
                _SetFullScreen(message);
slouken@7191
   421
                break;
slouken@7191
   422
            default:
slouken@7191
   423
                /* Perform normal message handling */
slouken@7191
   424
                BDirectWindow::MessageReceived(message);
slouken@7191
   425
                break;
slouken@7191
   426
        }
nathanheisey@5916
   427
nathanheisey@5916
   428
    }
nathanheisey@5916
   429
slouken@7191
   430
slouken@7191
   431
slouken@7191
   432
    /* Accessor methods */
slouken@7191
   433
    bool IsShown() { return _shown; }
slouken@7191
   434
    int32 GetID() { return _id; }
slouken@7191
   435
    uint32 GetRowBytes() { return _row_bytes; }
slouken@7191
   436
    int32 GetFbX() { return _bounds.left; }
slouken@7191
   437
    int32 GetFbY() { return _bounds.top; }
slouken@7191
   438
    bool ConnectionEnabled() { return !_connection_disabled; }
slouken@7191
   439
    bool Connected() { return _connected; }
slouken@7191
   440
    clipping_rect *GetClips() { return _clips; }
slouken@7191
   441
    int32 GetNumClips() { return _num_clips; }
slouken@7191
   442
    uint8* GetBufferPx() { return _bits; }
slouken@7191
   443
    int32 GetBytesPerPx() { return _bytes_per_px; }
slouken@7191
   444
    bool CanTrashWindowBuffer() { return _trash_window_buffer; }
slouken@7191
   445
    bool BufferExists() { return _buffer_created; }
slouken@7191
   446
    bool BufferIsDirty() { return _buffer_dirty; }
slouken@7191
   447
    BBitmap *GetBitmap() { return _bitmap; }
nathanheisey@5934
   448
#if SDL_VIDEO_OPENGL
slouken@7191
   449
    BGLView *GetGLView() { return _SDL_GLView; }
philipp@11107
   450
    Uint32 GetGLType() { return _gl_type; }
nathanheisey@5934
   451
#endif
slouken@7191
   452
slouken@7191
   453
    /* Setter methods */
slouken@7191
   454
    void SetID(int32 id) { _id = id; }
slouken@7191
   455
    void SetBufferExists(bool bufferExists) { _buffer_created = bufferExists; }
slouken@7191
   456
    void LockBuffer() { _buffer_locker->Lock(); }
slouken@7191
   457
    void UnlockBuffer() { _buffer_locker->Unlock(); }
slouken@7191
   458
    void SetBufferDirty(bool bufferDirty) { _buffer_dirty = bufferDirty; }
slouken@7191
   459
    void SetTrashBuffer(bool trash) { _trash_window_buffer = trash;     }
slouken@7191
   460
    void SetBitmap(BBitmap *bitmap) { _bitmap = bitmap; }
slouken@7191
   461
slouken@7191
   462
nathanheisey@5916
   463
private:
slouken@7191
   464
    /* Event redirection */
nathanheisey@5916
   465
    void _MouseMotionEvent(BPoint &where, int32 transit) {
slouken@7191
   466
        if(transit == B_EXITED_VIEW) {
slouken@7191
   467
            /* Change mouse focus */
slouken@7191
   468
            if(_mouse_focused) {
slouken@7191
   469
                _MouseFocusEvent(false);
slouken@7191
   470
            }
slouken@7191
   471
        } else {
slouken@7191
   472
            /* Change mouse focus */
slouken@7191
   473
            if (!_mouse_focused) {
slouken@7191
   474
                _MouseFocusEvent(true);
slouken@7191
   475
            }
slouken@7191
   476
            BMessage msg(BAPP_MOUSE_MOVED);
slouken@7191
   477
            msg.AddInt32("x", (int)where.x);
slouken@7191
   478
            msg.AddInt32("y", (int)where.y);
slouken@7191
   479
slouken@7191
   480
            _PostWindowEvent(msg);
slouken@7191
   481
        }
slouken@1895
   482
    }
slouken@7191
   483
nathanheisey@5916
   484
    void _MouseFocusEvent(bool focusGained) {
slouken@7191
   485
        _mouse_focused = focusGained;
slouken@7191
   486
        BMessage msg(BAPP_MOUSE_FOCUS);
slouken@7191
   487
        msg.AddBool("focusGained", focusGained);
slouken@7191
   488
        _PostWindowEvent(msg);
slouken@7191
   489
gabomdq@7678
   490
/* FIXME: Why were these here?
gabomdq@7663
   491
 if false: be_app->SetCursor(B_HAND_CURSOR);
gabomdq@7677
   492
 if true:  SDL_SetCursor(NULL); */
slouken@1895
   493
    }
slouken@7191
   494
nathanheisey@5916
   495
    void _MouseButtonEvent(int32 buttons) {
slouken@7191
   496
        int32 buttonStateChange = buttons ^ _last_buttons;
slouken@7191
   497
slouken@7191
   498
        /* Make sure at least one button has changed state */
slouken@7191
   499
        if( !(buttonStateChange) ) {
slouken@7191
   500
            return;
slouken@7191
   501
        }
slouken@7191
   502
slouken@7191
   503
        /* Add any mouse button events */
slouken@7191
   504
        if(buttonStateChange & B_PRIMARY_MOUSE_BUTTON) {
slouken@7191
   505
            _SendMouseButton(SDL_BUTTON_LEFT, buttons &
slouken@7191
   506
                B_PRIMARY_MOUSE_BUTTON);
slouken@7191
   507
        }
slouken@7191
   508
        if(buttonStateChange & B_SECONDARY_MOUSE_BUTTON) {
slouken@7191
   509
            _SendMouseButton(SDL_BUTTON_RIGHT, buttons &
slouken@7191
   510
                B_PRIMARY_MOUSE_BUTTON);
slouken@7191
   511
        }
slouken@7191
   512
        if(buttonStateChange & B_TERTIARY_MOUSE_BUTTON) {
slouken@7191
   513
            _SendMouseButton(SDL_BUTTON_MIDDLE, buttons &
slouken@7191
   514
                B_PRIMARY_MOUSE_BUTTON);
slouken@7191
   515
        }
slouken@7191
   516
slouken@7191
   517
        _last_buttons = buttons;
slouken@1895
   518
    }
slouken@7191
   519
nathanheisey@5916
   520
    void _SendMouseButton(int32 button, int32 state) {
slouken@7191
   521
        BMessage msg(BAPP_MOUSE_BUTTON);
slouken@7191
   522
        msg.AddInt32("button-id", button);
slouken@7191
   523
        msg.AddInt32("button-state", state);
slouken@7191
   524
        _PostWindowEvent(msg);
nathanheisey@5916
   525
    }
slouken@7191
   526
nathanheisey@5916
   527
    void _MouseWheelEvent(int32 x, int32 y) {
slouken@7191
   528
        /* Create a message to pass along to the BeApp thread */
slouken@7191
   529
        BMessage msg(BAPP_MOUSE_WHEEL);
slouken@7191
   530
        msg.AddInt32("xticks", x);
slouken@7191
   531
        msg.AddInt32("yticks", y);
slouken@7191
   532
        _PostWindowEvent(msg);
nathanheisey@5916
   533
    }
slouken@7191
   534
slouken@10555
   535
    void _KeyEvent(int32 keyCode, const int8 *keyUtf8, const ssize_t & len, int32 keyState) {
slouken@7191
   536
        /* Create a message to pass along to the BeApp thread */
slouken@7191
   537
        BMessage msg(BAPP_KEY);
slouken@7191
   538
        msg.AddInt32("key-state", keyState);
slouken@7191
   539
        msg.AddInt32("key-scancode", keyCode);
slouken@10555
   540
        if (keyUtf8 != NULL) {
slouken@10555
   541
        	msg.AddData("key-utf8", B_INT8_TYPE, (const void*)keyUtf8, len);
slouken@10555
   542
        }
slouken@7191
   543
        be_app->PostMessage(&msg);
nathanheisey@5916
   544
    }
slouken@7191
   545
nathanheisey@5916
   546
    void _RepaintEvent() {
slouken@7191
   547
        /* Force a repaint: Call the SDL exposed event */
slouken@7191
   548
        BMessage msg(BAPP_REPAINT);
slouken@7191
   549
        _PostWindowEvent(msg);
nathanheisey@5916
   550
    }
nathanheisey@5916
   551
    void _PostWindowEvent(BMessage &msg) {
slouken@7191
   552
        msg.AddInt32("window-id", _id);
slouken@7191
   553
        be_app->PostMessage(&msg);
nathanheisey@5916
   554
    }
slouken@7191
   555
slouken@7191
   556
    /* Command methods (functions called upon by SDL) */
nathanheisey@5916
   557
    void _SetTitle(BMessage *msg) {
slouken@7191
   558
        const char *title;
slouken@7191
   559
        if(
slouken@7191
   560
            msg->FindString("window-title", &title) != B_OK
slouken@7191
   561
        ) {
slouken@7191
   562
            return;
slouken@7191
   563
        }
slouken@7191
   564
        SetTitle(title);
nathanheisey@5916
   565
    }
slouken@7191
   566
nathanheisey@5916
   567
    void _MoveTo(BMessage *msg) {
slouken@7191
   568
        int32 x, y;
slouken@7191
   569
        if(
slouken@7191
   570
            msg->FindInt32("window-x", &x) != B_OK ||
slouken@7191
   571
            msg->FindInt32("window-y", &y) != B_OK
slouken@7191
   572
        ) {
slouken@7191
   573
            return;
slouken@7191
   574
        }
slouken@7191
   575
        MoveTo(x, y);
nathanheisey@5916
   576
    }
slouken@7191
   577
nathanheisey@5916
   578
    void _ResizeTo(BMessage *msg) {
slouken@7191
   579
        int32 w, h;
slouken@7191
   580
        if(
slouken@7191
   581
            msg->FindInt32("window-w", &w) != B_OK ||
slouken@7191
   582
            msg->FindInt32("window-h", &h) != B_OK
slouken@7191
   583
        ) {
slouken@7191
   584
            return;
slouken@7191
   585
        }
slouken@7191
   586
        ResizeTo(w, h);
nathanheisey@5916
   587
    }
icculus@6422
   588
icculus@6422
   589
    void _SetBordered(BMessage *msg) {
slouken@7191
   590
        bool bEnabled;
slouken@7191
   591
        if(msg->FindBool("window-border", &bEnabled) != B_OK) {
slouken@7191
   592
            return;
slouken@7191
   593
        }
philipp@11062
   594
        SetLook(bEnabled ? B_TITLED_WINDOW_LOOK : B_NO_BORDER_WINDOW_LOOK);
icculus@6422
   595
    }
icculus@6422
   596
icculus@10385
   597
    void _SetResizable(BMessage *msg) {
icculus@10385
   598
        bool bEnabled;
icculus@10385
   599
        if(msg->FindBool("window-resizable", &bEnabled) != B_OK) {
icculus@10385
   600
            return;
icculus@10385
   601
        }
icculus@10385
   602
        if (bEnabled) {
icculus@10388
   603
            SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_ZOOMABLE));
icculus@10385
   604
        } else {
icculus@10388
   605
            SetFlags(Flags() | (B_NOT_RESIZABLE | B_NOT_ZOOMABLE));
icculus@10385
   606
        }
icculus@10385
   607
    }
icculus@10385
   608
nathanheisey@5916
   609
    void _Restore() {
slouken@7191
   610
        if(IsMinimized()) {
slouken@7191
   611
            Minimize(false);
slouken@7191
   612
        } else if(IsHidden()) {
slouken@7191
   613
            Show();
slouken@7191
   614
        } else if(_prev_frame != NULL) {    /* Zoomed */
slouken@7191
   615
            MoveTo(_prev_frame->left, _prev_frame->top);
slouken@7191
   616
            ResizeTo(_prev_frame->Width(), _prev_frame->Height());
slouken@7191
   617
        }
slouken@1895
   618
    }
slouken@0
   619
nathanheisey@5916
   620
    void _SetFullScreen(BMessage *msg) {
slouken@7191
   621
        bool fullscreen;
slouken@7191
   622
        if(
slouken@7191
   623
            msg->FindBool("fullscreen", &fullscreen) != B_OK
slouken@7191
   624
        ) {
slouken@7191
   625
            return;
slouken@7191
   626
        }
slouken@7191
   627
        SetFullScreen(fullscreen);
slouken@1895
   628
    }
slouken@7191
   629
nathanheisey@5916
   630
    /* Members */
slouken@1361
   631
#if SDL_VIDEO_OPENGL
nathanheisey@5925
   632
    BGLView * _SDL_GLView;
philipp@11107
   633
    Uint32 _gl_type;
slouken@0
   634
#endif
slouken@7191
   635
nathanheisey@5925
   636
    int32 _last_buttons;
slouken@7191
   637
    int32 _id;  /* Window id used by SDL_BApp */
slouken@7191
   638
    bool  _mouse_focused;       /* Does this window have mouse focus? */
nathanheisey@5925
   639
    bool  _shown;
nathanheisey@5925
   640
    bool  _inhibit_resize;
slouken@7191
   641
slouken@7191
   642
    BRect *_prev_frame; /* Previous position and size of the window */
slouken@7191
   643
nathanheisey@5922
   644
    /* Framebuffer members */
slouken@7191
   645
    bool            _connected,
slouken@7191
   646
                    _connection_disabled,
slouken@7191
   647
                    _buffer_created,
slouken@7191
   648
                    _buffer_dirty,
slouken@7191
   649
                    _trash_window_buffer;
slouken@7191
   650
    uint8          *_bits;
slouken@7191
   651
    uint32          _row_bytes;
slouken@7191
   652
    clipping_rect   _bounds;
slouken@7191
   653
    BLocker        *_buffer_locker;
nathanheisey@5925
   654
    clipping_rect  *_clips;
slouken@7191
   655
    int32           _num_clips;
slouken@7191
   656
    int32           _bytes_per_px;
slouken@7191
   657
    thread_id       _draw_thread_id;
slouken@7191
   658
slouken@7191
   659
    BBitmap        *_bitmap;
slouken@0
   660
};
slouken@0
   661
nathanheisey@5939
   662
nathanheisey@5939
   663
/* FIXME:
nathanheisey@5939
   664
 * An explanation of framebuffer flags.
nathanheisey@5939
   665
 *
nathanheisey@5939
   666
 * _connected -           Original variable used to let the drawing thread know
nathanheisey@5939
   667
 *                         when changes are being made to the other framebuffer
nathanheisey@5939
   668
 *                         members.
nathanheisey@5939
   669
 * _connection_disabled - Used to signal to the drawing thread that the window
nathanheisey@5939
   670
 *                         is closing, and the thread should exit.
nathanheisey@5939
   671
 * _buffer_created -      True if the current buffer is valid
nathanheisey@5939
   672
 * _buffer_dirty -        True if the window should be redrawn.
nathanheisey@5939
   673
 * _trash_window_buffer - True if the window buffer needs to be trashed partway
nathanheisey@5939
   674
 *                         through a draw cycle.  Occurs when the previous
nathanheisey@5939
   675
 *                         buffer provided by DirectConnected() is invalidated.
nathanheisey@5939
   676
 */
slouken@11382
   677
#endif /* SDL_BWin_h_ */
slouken@10690
   678
slouken@10690
   679
/* vi: set ts=4 sw=4 expandtab: */