2 Simple DirectMedia Layer
3 Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
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.
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:
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.
24 #include <InterfaceKit.h>
25 #include <OpenGLKit.h>
27 #include "../../video/haiku/SDL_bkeyboard.h"
34 #include "../../SDL_internal.h"
36 #include "SDL_video.h"
39 #include "../../events/SDL_events_c.h"
40 #include "../../video/haiku/SDL_bkeyboard.h"
41 #include "../../video/haiku/SDL_bframebuffer.h"
52 /* Forward declarations */
55 /* Message constants */
57 /* Intercepted by BWindow on its way to BView */
62 BAPP_REPAINT, /* from _UPDATE_ */
64 BAPP_MAXIMIZE, /* from B_ZOOM */
66 BAPP_RESTORE, /* TODO: IMPLEMENT! */
69 BAPP_MOUSE_FOCUS, /* caused by MOUSE_MOVE */
70 BAPP_KEYBOARD_FOCUS, /* from WINDOW_ACTIVATED */
71 BAPP_WINDOW_CLOSE_REQUESTED,
79 /* Create a descendant of BApplication */
80 class SDL_BApp : public BApplication {
82 SDL_BApp(const char* signature) :
83 BApplication(signature) {
84 _current_context = NULL;
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);
101 case BAPP_MOUSE_BUTTON:
102 _HandleMouseButton(message);
105 case BAPP_MOUSE_WHEEL:
106 _HandleMouseWheel(message);
114 _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_EXPOSED);
118 _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_MAXIMIZED);
122 _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_MINIMIZED);
126 _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_SHOWN);
130 _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_HIDDEN);
133 case BAPP_MOUSE_FOCUS:
134 _HandleMouseFocus(message);
137 case BAPP_KEYBOARD_FOCUS:
138 _HandleKeyboardFocus(message);
141 case BAPP_WINDOW_CLOSE_REQUESTED:
142 _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_CLOSE);
145 case BAPP_WINDOW_MOVED:
146 _HandleWindowMoved(message);
149 case BAPP_WINDOW_RESIZED:
150 _HandleWindowResized(message);
153 case BAPP_SCREEN_CHANGED:
154 /* TODO: Handle screen resize or workspace change */
158 BApplication::MessageReceived(message);
163 /* Window creation/destruction methods */
164 int32 GetID(SDL_Window *win) {
166 for(i = 0; i < _GetNumWindowSlots(); ++i) {
167 if( GetSDLWindow(i) == NULL ) {
168 _SetSDLWindow(win, i);
173 /* Expand the vector if all slots are full */
174 if( i == _GetNumWindowSlots() ) {
175 _PushBackWindow(win);
179 /* TODO: error handling */
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 */
188 SDL_Window *GetSDLWindow(int32 winID) {
189 return _window_map[winID];
192 void SetCurrentContext(BGLView *newContext) {
194 _current_context->UnlockGL();
195 _current_context = newContext;
196 _current_context->LockGL();
199 /* Event management */
200 void _HandleBasicWindowEvent(BMessage *msg, int32 sdlEventType) {
204 !_GetWinID(msg, &winID)
208 win = GetSDLWindow(winID);
209 SDL_SendWindowEvent(win, sdlEventType, 0, 0);
212 void _HandleMouseMove(BMessage *msg) {
217 !_GetWinID(msg, &winID) ||
218 msg->FindInt32("x", &x) != B_OK || /* x movement */
219 msg->FindInt32("y", &y) != B_OK /* y movement */
223 win = GetSDLWindow(winID);
224 SDL_SendMouseMotion(win, 0, 0, x, y);
226 /* Tell the application that the mouse passed over, redraw needed */
227 BE_UpdateWindowFramebuffer(NULL,win,NULL,-1);
230 void _HandleMouseButton(BMessage *msg) {
233 int32 button, state; /* left/middle/right, pressed/released */
235 !_GetWinID(msg, &winID) ||
236 msg->FindInt32("button-id", &button) != B_OK ||
237 msg->FindInt32("button-state", &state) != B_OK
241 win = GetSDLWindow(winID);
242 SDL_SendMouseButton(win, 0, state, button);
245 void _HandleMouseWheel(BMessage *msg) {
248 int32 xTicks, yTicks;
250 !_GetWinID(msg, &winID) ||
251 msg->FindInt32("xticks", &xTicks) != B_OK ||
252 msg->FindInt32("yticks", &yTicks) != B_OK
256 win = GetSDLWindow(winID);
257 SDL_SendMouseWheel(win, 0, xTicks, yTicks, SDL_MOUSEWHEEL_NORMAL);
260 void _HandleKey(BMessage *msg) {
261 int32 scancode, state; /* scancode, pressed/released */
263 msg->FindInt32("key-state", &state) != B_OK ||
264 msg->FindInt32("key-scancode", &scancode) != B_OK
269 /* Make sure this isn't a repeated event (key pressed and held) */
270 if(state == SDL_PRESSED && BE_GetKeyState(scancode) == SDL_PRESSED) {
273 BE_SetKeyState(scancode, state);
274 SDL_SendKeyboardKey(state, BE_GetScancodeFromBeKey(scancode));
277 void _HandleMouseFocus(BMessage *msg) {
280 bool bSetFocus; /* If false, lose focus */
282 !_GetWinID(msg, &winID) ||
283 msg->FindBool("focusGained", &bSetFocus) != B_OK
287 win = GetSDLWindow(winID);
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);
296 void _HandleKeyboardFocus(BMessage *msg) {
299 bool bSetFocus; /* If false, lose focus */
301 !_GetWinID(msg, &winID) ||
302 msg->FindBool("focusGained", &bSetFocus) != B_OK
306 win = GetSDLWindow(winID);
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);
315 void _HandleWindowMoved(BMessage *msg) {
319 /* Get the window id and new x/y position of the window */
321 !_GetWinID(msg, &winID) ||
322 msg->FindInt32("window-x", &xPos) != B_OK ||
323 msg->FindInt32("window-y", &yPos) != B_OK
327 win = GetSDLWindow(winID);
328 SDL_SendWindowEvent(win, SDL_WINDOWEVENT_MOVED, xPos, yPos);
331 void _HandleWindowResized(BMessage *msg) {
335 /* Get the window id ]and new x/y position of the window */
337 !_GetWinID(msg, &winID) ||
338 msg->FindInt32("window-w", &w) != B_OK ||
339 msg->FindInt32("window-h", &h) != B_OK
343 win = GetSDLWindow(winID);
344 SDL_SendWindowEvent(win, SDL_WINDOWEVENT_RESIZED, w, h);
347 bool _GetWinID(BMessage *msg, int32 *winID) {
348 return msg->FindInt32("window-id", winID) == B_OK;
353 /* Vector functions: Wraps vector stuff in case we need to change
355 void _SetSDLWindow(SDL_Window *win, int32 winID) {
356 _window_map[winID] = win;
359 int32 _GetNumWindowSlots() {
360 return _window_map.size();
364 void _PopBackWindow() {
365 _window_map.pop_back();
368 void _PushBackWindow(SDL_Window *win) {
369 _window_map.push_back(win);
374 std::vector<SDL_Window*> _window_map; /* Keeps track of SDL_Windows by index-id */
376 display_mode *_saved_mode;
377 BGLView *_current_context;