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