change SDL 1.2 to SDL 2.0
[platform/upstream/SDL.git] / src / main / haiku / SDL_BApp.h
1 /*
2   Simple DirectMedia Layer
3   Copyright (C) 1997-2016 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, SDL_MOUSEWHEEL_NORMAL);
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