e14743d1 |
1 | /* |
2 | SDL - Simple DirectMedia Layer |
3 | Copyright (C) 1997-2009 Sam Lantinga |
4 | |
5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2.1 of the License, or (at your option) any later version. |
9 | |
10 | This library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Lesser General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with this library; if not, write to the Free Software |
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
18 | |
19 | Sam Lantinga |
20 | slouken@libsdl.org |
21 | */ |
22 | |
23 | #ifndef _SDL_BWin_h |
24 | #define _SDL_BWin_h |
25 | |
26 | #include "SDL_config.h" |
27 | |
28 | #include <stdio.h> |
29 | #include <AppKit.h> |
30 | #include <InterfaceKit.h> |
31 | #include <be/game/DirectWindow.h> |
32 | #if SDL_VIDEO_OPENGL |
33 | #include <be/opengl/GLView.h> |
34 | #endif |
35 | #include <support/UTF8.h> |
36 | |
37 | #include "../../main/beos/SDL_BeApp.h" |
38 | #include "SDL_events.h" |
39 | #include "SDL_BView.h" |
40 | |
41 | extern "C" { |
42 | #include "../../events/SDL_events_c.h" |
43 | |
44 | extern int mouse_relative; |
45 | }; |
46 | |
47 | class SDL_BWin : public BDirectWindow |
48 | { |
49 | public: |
50 | SDL_BWin(BRect bounds) : |
51 | BDirectWindow(bounds, "Untitled", B_TITLED_WINDOW, 0) { |
52 | last_buttons = 0; |
53 | the_view = NULL; |
54 | #if SDL_VIDEO_OPENGL |
55 | SDL_GLView = NULL; |
56 | #endif |
57 | SDL_View = NULL; |
58 | Unlock(); |
59 | shown = false; |
60 | inhibit_resize = false; |
61 | } |
62 | |
63 | virtual ~SDL_BWin() { |
64 | Lock(); |
65 | if ( the_view ) { |
66 | #if SDL_VIDEO_OPENGL |
67 | if ( the_view == SDL_GLView ) { |
68 | SDL_GLView->UnlockGL(); |
69 | } |
70 | #endif |
71 | RemoveChild(the_view); |
72 | the_view = NULL; |
73 | } |
74 | Unlock(); |
75 | #if SDL_VIDEO_OPENGL |
76 | if ( SDL_GLView ) { |
77 | delete SDL_GLView; |
78 | } |
79 | #endif |
80 | if ( SDL_View ) { |
81 | delete SDL_View; |
82 | } |
83 | } |
84 | |
85 | |
86 | /* Override the Show() method so we can tell when we've been shown */ |
87 | virtual void Show(void) { |
88 | BWindow::Show(); |
89 | shown = true; |
90 | } |
91 | virtual bool Shown(void) { |
92 | return (shown); |
93 | } |
94 | /* If called, the next resize event will not be forwarded to SDL. */ |
95 | virtual void InhibitResize(void) { |
96 | inhibit_resize=true; |
97 | } |
98 | /* Handle resizing of the window */ |
99 | virtual void FrameResized(float width, float height) { |
100 | if(inhibit_resize) |
101 | inhibit_resize = false; |
102 | else |
103 | SDL_PrivateResize((int)width, (int)height); |
104 | } |
105 | virtual int CreateView(Uint32 flags, Uint32 gl_flags) { |
106 | int retval; |
107 | |
108 | retval = 0; |
109 | Lock(); |
110 | if ( flags & SDL_OPENGL ) { |
111 | #if SDL_VIDEO_OPENGL |
112 | if ( SDL_GLView == NULL ) { |
113 | SDL_GLView = new BGLView(Bounds(), "SDL GLView", |
114 | B_FOLLOW_ALL_SIDES, (B_WILL_DRAW|B_FRAME_EVENTS), |
115 | gl_flags); |
116 | SDL_GLView->EnableDirectMode(true); |
117 | } |
118 | if ( the_view != SDL_GLView ) { |
119 | if ( the_view ) { |
120 | RemoveChild(the_view); |
121 | } |
122 | AddChild(SDL_GLView); |
123 | SDL_GLView->LockGL(); |
124 | the_view = SDL_GLView; |
125 | } |
126 | #else |
127 | SDL_SetError("OpenGL support not enabled"); |
128 | retval = -1; |
129 | #endif |
130 | } else { |
131 | if ( SDL_View == NULL ) { |
132 | SDL_View = new SDL_BView(Bounds()); |
133 | } |
134 | if ( the_view != SDL_View ) { |
135 | if ( the_view ) { |
136 | #if SDL_VIDEO_OPENGL |
137 | if ( the_view == SDL_GLView ) { |
138 | SDL_GLView->UnlockGL(); |
139 | } |
140 | #endif |
141 | RemoveChild(the_view); |
142 | } |
143 | AddChild(SDL_View); |
144 | the_view = SDL_View; |
145 | } |
146 | } |
147 | Unlock(); |
148 | return(retval); |
149 | } |
150 | virtual void SetBitmap(BBitmap *bitmap) { |
151 | SDL_View->SetBitmap(bitmap); |
152 | } |
153 | virtual void SetXYOffset(int x, int y) { |
154 | #if SDL_VIDEO_OPENGL |
155 | if ( the_view == SDL_GLView ) { |
156 | return; |
157 | } |
158 | #endif |
159 | SDL_View->SetXYOffset(x, y); |
160 | } |
161 | virtual void GetXYOffset(int &x, int &y) { |
162 | #if SDL_VIDEO_OPENGL |
163 | if ( the_view == SDL_GLView ) { |
164 | x = 0; |
165 | y = 0; |
166 | return; |
167 | } |
168 | #endif |
169 | SDL_View->GetXYOffset(x, y); |
170 | } |
171 | virtual void GetXYOffset(float &x, float &y) { |
172 | #if SDL_VIDEO_OPENGL |
173 | if ( the_view == SDL_GLView ) { |
174 | x = 0.0f; |
175 | y = 0.0f; |
176 | return; |
177 | } |
178 | #endif |
179 | SDL_View->GetXYOffset(x, y); |
180 | } |
181 | virtual bool BeginDraw(void) { |
182 | return(Lock()); |
183 | } |
184 | virtual void DrawAsync(BRect updateRect) { |
185 | SDL_View->DrawAsync(updateRect); |
186 | } |
187 | virtual void EndDraw(void) { |
188 | SDL_View->Sync(); |
189 | Unlock(); |
190 | } |
191 | #if SDL_VIDEO_OPENGL |
192 | virtual void SwapBuffers(void) { |
193 | SDL_GLView->UnlockGL(); |
194 | SDL_GLView->LockGL(); |
195 | SDL_GLView->SwapBuffers(); |
196 | } |
197 | #endif |
198 | virtual BView *View(void) { |
199 | return(the_view); |
200 | } |
201 | |
202 | /* Hook functions -- overridden */ |
203 | virtual void Minimize(bool minimize) { |
204 | /* This is only called when mimimized, not when restored */ |
205 | //SDL_PrivateAppActive(minimize, SDL_APPACTIVE); |
206 | BWindow::Minimize(minimize); |
207 | } |
208 | virtual void WindowActivated(bool active) { |
209 | SDL_PrivateAppActive(active, SDL_APPINPUTFOCUS); |
210 | } |
211 | virtual bool QuitRequested(void) { |
212 | if ( SDL_BeAppActive > 0 ) { |
213 | SDL_PrivateQuit(); |
214 | /* We don't ever actually close the window here because |
215 | the application should respond to the quit request, |
216 | or ignore it as desired. |
217 | */ |
218 | return(false); |
219 | } |
220 | return(true); /* Close the app window */ |
221 | } |
222 | virtual void Quit() { |
223 | if (!IsLocked()) |
224 | Lock(); |
225 | BDirectWindow::Quit(); |
226 | } |
227 | |
228 | virtual int16 Translate2Unicode(const char *buf) { |
229 | int32 state, srclen, dstlen; |
230 | unsigned char destbuf[2]; |
231 | Uint16 unicode = 0; |
232 | |
233 | if ((uchar)buf[0] > 127) { |
234 | state = 0; |
235 | srclen = SDL_strlen(buf); |
236 | dstlen = sizeof(destbuf); |
237 | convert_from_utf8(B_UNICODE_CONVERSION, buf, &srclen, (char *)destbuf, &dstlen, &state); |
238 | unicode = destbuf[0]; |
239 | unicode <<= 8; |
240 | unicode |= destbuf[1]; |
241 | } else |
242 | unicode = buf[0]; |
243 | |
244 | /* For some reason function keys map to control characters */ |
245 | # define CTRL(X) ((X)-'@') |
246 | switch (unicode) { |
247 | case CTRL('A'): |
248 | case CTRL('B'): |
249 | case CTRL('C'): |
250 | case CTRL('D'): |
251 | case CTRL('E'): |
252 | case CTRL('K'): |
253 | case CTRL('L'): |
254 | case CTRL('P'): |
255 | if ( ! (SDL_GetModState() & KMOD_CTRL) ) |
256 | unicode = 0; |
257 | break; |
258 | /* Keyboard input maps newline to carriage return */ |
259 | case '\n': |
260 | unicode = '\r'; |
261 | break; |
262 | default: |
263 | break; |
264 | } |
265 | |
266 | return unicode; |
267 | } |
268 | |
269 | virtual void DispatchMessage(BMessage *msg, BHandler *target); |
270 | |
271 | virtual void DirectConnected(direct_buffer_info *info); |
272 | |
273 | private: |
274 | #if SDL_VIDEO_OPENGL |
275 | BGLView *SDL_GLView; |
276 | #endif |
277 | SDL_BView *SDL_View; |
278 | BView *the_view; |
279 | bool shown; |
280 | bool inhibit_resize; |
281 | int32 last_buttons; |
282 | }; |
283 | |
284 | #endif /* _SDL_BWin_h */ |