src/main/haiku/SDL_BApp.h
author Philipp Wiesemann <philipp.wiesemann@arcor.de>
Wed, 29 Oct 2014 20:20:47 +0100
changeset 9201 21d9f9babb30
parent 8149 681eb46b8ac4
child 9257 6f41196c2d6b
permissions -rw-r--r--
Fixed bug 2647 - Memory leak in SDL_AddHintCallback function - SDL_hints.c

Nitz

Variable entry going out of scope leaks the storage it points to, at:

/* Need to add a hint entry for this watcher */
hint = (SDL_Hint *)SDL_malloc(sizeof(*hint));
if (!hint) {
return;
}

Patch is attached.
     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
    31 extern "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 */
    53 class SDL_BWin;
    54 
    55 /* Message constants */
    56 enum 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 */
    80 class SDL_BApp : public BApplication {
    81 public:
    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     }
   198 private:
   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