diff options
author | Franklin Wei <git@fwei.tk> | 2017-01-21 15:18:31 -0500 |
---|---|---|
committer | Franklin Wei <git@fwei.tk> | 2017-12-23 21:01:26 -0500 |
commit | a855d6202536ff28e5aae4f22a0f31d8f5b325d0 (patch) | |
tree | 8c75f224dd64ed360505afa8843d016b0d75000b /apps/plugins/sdl/src/video/bwindow | |
parent | 01c6dcf6c7b9bb1ad2fa0450f99bacc5f3d3e04b (diff) | |
download | rockbox-a855d6202536ff28e5aae4f22a0f31d8f5b325d0.tar.gz rockbox-a855d6202536ff28e5aae4f22a0f31d8f5b325d0.zip |
Port of Duke Nukem 3D
This ports Fabien Sanglard's Chocolate Duke to run on a version of SDL
for Rockbox.
Change-Id: I8f2c4c78af19de10c1633ed7bb7a997b43256dd9
Diffstat (limited to 'apps/plugins/sdl/src/video/bwindow')
-rw-r--r-- | apps/plugins/sdl/src/video/bwindow/SDL_BView.h | 116 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/bwindow/SDL_BWin.h | 290 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/bwindow/SDL_lowvideo.h | 58 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/bwindow/SDL_sysevents.cc | 415 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/bwindow/SDL_sysevents_c.h | 31 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/bwindow/SDL_sysmouse.cc | 153 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/bwindow/SDL_sysmouse_c.h | 33 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/bwindow/SDL_sysvideo.cc | 841 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/bwindow/SDL_syswm.cc | 92 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/bwindow/SDL_syswm_c.h | 32 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/bwindow/SDL_sysyuv.cc | 314 | ||||
-rw-r--r-- | apps/plugins/sdl/src/video/bwindow/SDL_sysyuv.h | 73 |
12 files changed, 2448 insertions, 0 deletions
diff --git a/apps/plugins/sdl/src/video/bwindow/SDL_BView.h b/apps/plugins/sdl/src/video/bwindow/SDL_BView.h new file mode 100644 index 0000000000..bfa2c89588 --- /dev/null +++ b/apps/plugins/sdl/src/video/bwindow/SDL_BView.h | |||
@@ -0,0 +1,116 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _SDL_BView_h | ||
25 | #define _SDL_BView_h | ||
26 | |||
27 | /* This is the event handling and graphics update portion of SDL_BWin */ | ||
28 | |||
29 | extern "C" { | ||
30 | #include "../../events/SDL_events_c.h" | ||
31 | }; | ||
32 | |||
33 | class SDL_BView : public BView | ||
34 | { | ||
35 | public: | ||
36 | SDL_BView(BRect frame) : | ||
37 | BView(frame, "SDL View", B_FOLLOW_ALL_SIDES, | ||
38 | (B_WILL_DRAW|B_FRAME_EVENTS)) { | ||
39 | image = NULL; | ||
40 | xoff = yoff = 0; | ||
41 | SetViewColor(0,0,0,0); | ||
42 | SetHighColor(0,0,0,0); | ||
43 | } | ||
44 | virtual ~SDL_BView() { | ||
45 | SetBitmap(NULL); | ||
46 | } | ||
47 | /* Set drawing offsets for fullscreen mode */ | ||
48 | virtual void SetXYOffset(int x, int y) { | ||
49 | xoff = x; | ||
50 | yoff = y; | ||
51 | } | ||
52 | virtual void GetXYOffset(int &x, int &y) { | ||
53 | x = xoff; | ||
54 | y = yoff; | ||
55 | } | ||
56 | virtual void GetXYOffset(float &x, float &y) { | ||
57 | x = (float)xoff; | ||
58 | y = (float)yoff; | ||
59 | } | ||
60 | /* The view changed size. If it means we're in fullscreen, we | ||
61 | * draw a nice black box in the entire view to get black borders. | ||
62 | */ | ||
63 | virtual void FrameResized(float width, float height) { | ||
64 | BRect bounds; | ||
65 | bounds.top = bounds.left = 0; | ||
66 | bounds.right = width; | ||
67 | bounds.bottom = height; | ||
68 | /* Fill the entire view with black */ | ||
69 | FillRect(bounds, B_SOLID_HIGH); | ||
70 | /* And if there's an image, redraw it. */ | ||
71 | if( image ) { | ||
72 | bounds = image->Bounds(); | ||
73 | Draw(bounds); | ||
74 | } | ||
75 | } | ||
76 | |||
77 | /* Drawing portion of this complete breakfast. :) */ | ||
78 | virtual void SetBitmap(BBitmap *bitmap) { | ||
79 | if ( image ) { | ||
80 | delete image; | ||
81 | } | ||
82 | image = bitmap; | ||
83 | } | ||
84 | virtual void Draw(BRect updateRect) { | ||
85 | if ( image ) { | ||
86 | if(xoff || yoff) { | ||
87 | BRect dest; | ||
88 | dest.top = updateRect.top + yoff; | ||
89 | dest.left = updateRect.left + xoff; | ||
90 | dest.bottom = updateRect.bottom + yoff; | ||
91 | dest.right = updateRect.right + xoff; | ||
92 | DrawBitmap(image, updateRect, dest); | ||
93 | } else { | ||
94 | DrawBitmap(image, updateRect, updateRect); | ||
95 | } | ||
96 | } | ||
97 | } | ||
98 | virtual void DrawAsync(BRect updateRect) { | ||
99 | if(xoff || yoff) { | ||
100 | BRect dest; | ||
101 | dest.top = updateRect.top + yoff; | ||
102 | dest.left = updateRect.left + xoff; | ||
103 | dest.bottom = updateRect.bottom + yoff; | ||
104 | dest.right = updateRect.right + xoff;; | ||
105 | DrawBitmapAsync(image, updateRect, dest); | ||
106 | } else { | ||
107 | DrawBitmapAsync(image, updateRect, updateRect); | ||
108 | } | ||
109 | } | ||
110 | |||
111 | private: | ||
112 | BBitmap *image; | ||
113 | int xoff, yoff; | ||
114 | }; | ||
115 | |||
116 | #endif /* _SDL_BView_h */ | ||
diff --git a/apps/plugins/sdl/src/video/bwindow/SDL_BWin.h b/apps/plugins/sdl/src/video/bwindow/SDL_BWin.h new file mode 100644 index 0000000000..f2b19a29e2 --- /dev/null +++ b/apps/plugins/sdl/src/video/bwindow/SDL_BWin.h | |||
@@ -0,0 +1,290 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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 "SDL_opengl.h" | ||
34 | #include <be/opengl/GLView.h> | ||
35 | #endif | ||
36 | #include <support/UTF8.h> | ||
37 | |||
38 | #include "../../main/beos/SDL_BeApp.h" | ||
39 | #include "SDL_events.h" | ||
40 | #include "SDL_BView.h" | ||
41 | |||
42 | extern "C" { | ||
43 | #include "../../events/SDL_events_c.h" | ||
44 | |||
45 | extern int mouse_relative; | ||
46 | }; | ||
47 | |||
48 | class SDL_BWin : public BDirectWindow | ||
49 | { | ||
50 | public: | ||
51 | SDL_BWin(BRect bounds) : | ||
52 | BDirectWindow(bounds, "Untitled", B_TITLED_WINDOW, 0) { | ||
53 | last_buttons = 0; | ||
54 | the_view = NULL; | ||
55 | #if SDL_VIDEO_OPENGL | ||
56 | SDL_GLView = NULL; | ||
57 | #endif | ||
58 | SDL_View = NULL; | ||
59 | Unlock(); | ||
60 | shown = false; | ||
61 | inhibit_resize = false; | ||
62 | } | ||
63 | |||
64 | virtual ~SDL_BWin() { | ||
65 | Lock(); | ||
66 | if ( the_view ) { | ||
67 | #if SDL_VIDEO_OPENGL | ||
68 | if ( the_view == SDL_GLView ) { | ||
69 | SDL_GLView->UnlockGL(); | ||
70 | } | ||
71 | #endif | ||
72 | RemoveChild(the_view); | ||
73 | the_view = NULL; | ||
74 | } | ||
75 | Unlock(); | ||
76 | #if SDL_VIDEO_OPENGL | ||
77 | if ( SDL_GLView ) { | ||
78 | delete SDL_GLView; | ||
79 | } | ||
80 | #endif | ||
81 | if ( SDL_View ) { | ||
82 | delete SDL_View; | ||
83 | } | ||
84 | } | ||
85 | |||
86 | |||
87 | /* Override the Show() method so we can tell when we've been shown */ | ||
88 | virtual void Show(void) { | ||
89 | BWindow::Show(); | ||
90 | shown = true; | ||
91 | } | ||
92 | virtual bool Shown(void) { | ||
93 | return (shown); | ||
94 | } | ||
95 | /* If called, the next resize event will not be forwarded to SDL. */ | ||
96 | virtual void InhibitResize(void) { | ||
97 | inhibit_resize=true; | ||
98 | } | ||
99 | /* Handle resizing of the window */ | ||
100 | virtual void FrameResized(float width, float height) { | ||
101 | if(inhibit_resize) | ||
102 | inhibit_resize = false; | ||
103 | else | ||
104 | SDL_PrivateResize((int)width, (int)height); | ||
105 | } | ||
106 | virtual int CreateView(Uint32 flags, Uint32 gl_flags) { | ||
107 | int retval; | ||
108 | |||
109 | retval = 0; | ||
110 | Lock(); | ||
111 | if ( flags & SDL_OPENGL ) { | ||
112 | #if SDL_VIDEO_OPENGL | ||
113 | if ( SDL_GLView == NULL ) { | ||
114 | SDL_GLView = new BGLView(Bounds(), "SDL GLView", | ||
115 | B_FOLLOW_ALL_SIDES, (B_WILL_DRAW|B_FRAME_EVENTS), | ||
116 | gl_flags|BGL_DOUBLE); | ||
117 | SDL_GLView->EnableDirectMode(true); | ||
118 | } | ||
119 | if ( the_view != SDL_GLView ) { | ||
120 | if ( the_view ) { | ||
121 | RemoveChild(the_view); | ||
122 | } | ||
123 | AddChild(SDL_GLView); | ||
124 | SDL_GLView->LockGL(); | ||
125 | the_view = SDL_GLView; | ||
126 | } | ||
127 | #else | ||
128 | SDL_SetError("OpenGL support not enabled"); | ||
129 | retval = -1; | ||
130 | #endif | ||
131 | } else { | ||
132 | if ( SDL_View == NULL ) { | ||
133 | SDL_View = new SDL_BView(Bounds()); | ||
134 | } | ||
135 | if ( the_view != SDL_View ) { | ||
136 | if ( the_view ) { | ||
137 | RemoveChild(the_view); | ||
138 | } | ||
139 | AddChild(SDL_View); | ||
140 | the_view = SDL_View; | ||
141 | } | ||
142 | } | ||
143 | #if SDL_VIDEO_OPENGL | ||
144 | if ( the_view == SDL_GLView ) { | ||
145 | SDL_GLView->UnlockGL(); | ||
146 | } | ||
147 | #endif | ||
148 | Unlock(); | ||
149 | return(retval); | ||
150 | } | ||
151 | virtual void SetBitmap(BBitmap *bitmap) { | ||
152 | SDL_View->SetBitmap(bitmap); | ||
153 | } | ||
154 | virtual void SetXYOffset(int x, int y) { | ||
155 | #if SDL_VIDEO_OPENGL | ||
156 | if ( the_view == SDL_GLView ) { | ||
157 | return; | ||
158 | } | ||
159 | #endif | ||
160 | SDL_View->SetXYOffset(x, y); | ||
161 | } | ||
162 | virtual void GetXYOffset(int &x, int &y) { | ||
163 | #if SDL_VIDEO_OPENGL | ||
164 | if ( the_view == SDL_GLView ) { | ||
165 | x = 0; | ||
166 | y = 0; | ||
167 | return; | ||
168 | } | ||
169 | #endif | ||
170 | SDL_View->GetXYOffset(x, y); | ||
171 | } | ||
172 | virtual void GetXYOffset(float &x, float &y) { | ||
173 | #if SDL_VIDEO_OPENGL | ||
174 | if ( the_view == SDL_GLView ) { | ||
175 | x = 0.0f; | ||
176 | y = 0.0f; | ||
177 | return; | ||
178 | } | ||
179 | #endif | ||
180 | SDL_View->GetXYOffset(x, y); | ||
181 | } | ||
182 | virtual bool BeginDraw(void) { | ||
183 | return(Lock()); | ||
184 | } | ||
185 | virtual void DrawAsync(BRect updateRect) { | ||
186 | SDL_View->DrawAsync(updateRect); | ||
187 | } | ||
188 | virtual void EndDraw(void) { | ||
189 | SDL_View->Sync(); | ||
190 | Unlock(); | ||
191 | } | ||
192 | #if SDL_VIDEO_OPENGL | ||
193 | virtual void SwapBuffers(void) { | ||
194 | SDL_GLView->UnlockGL(); | ||
195 | SDL_GLView->SwapBuffers(); | ||
196 | SDL_GLView->LockGL(); | ||
197 | } | ||
198 | #endif | ||
199 | virtual BView *View(void) { | ||
200 | return(the_view); | ||
201 | } | ||
202 | |||
203 | /* Hook functions -- overridden */ | ||
204 | virtual void Minimize(bool minimize) { | ||
205 | /* This is only called when mimimized, not when restored */ | ||
206 | //SDL_PrivateAppActive(minimize, SDL_APPACTIVE); | ||
207 | BWindow::Minimize(minimize); | ||
208 | } | ||
209 | virtual void WindowActivated(bool active) { | ||
210 | SDL_PrivateAppActive(active, SDL_APPINPUTFOCUS); | ||
211 | } | ||
212 | virtual bool QuitRequested(void) { | ||
213 | if ( SDL_BeAppActive > 0 ) { | ||
214 | SDL_PrivateQuit(); | ||
215 | /* We don't ever actually close the window here because | ||
216 | the application should respond to the quit request, | ||
217 | or ignore it as desired. | ||
218 | */ | ||
219 | #if SDL_VIDEO_OPENGL | ||
220 | if ( SDL_GLView != NULL ) { | ||
221 | SDL_GLView->EnableDirectMode(false); | ||
222 | } | ||
223 | #endif | ||
224 | return(false); | ||
225 | } | ||
226 | return(true); /* Close the app window */ | ||
227 | } | ||
228 | virtual void Quit() { | ||
229 | if (!IsLocked()) | ||
230 | Lock(); | ||
231 | BDirectWindow::Quit(); | ||
232 | } | ||
233 | |||
234 | virtual int16 Translate2Unicode(const char *buf) { | ||
235 | int32 state, srclen, dstlen; | ||
236 | unsigned char destbuf[2]; | ||
237 | Uint16 unicode = 0; | ||
238 | |||
239 | if ((uchar)buf[0] > 127) { | ||
240 | state = 0; | ||
241 | srclen = SDL_strlen(buf); | ||
242 | dstlen = sizeof(destbuf); | ||
243 | convert_from_utf8(B_UNICODE_CONVERSION, buf, &srclen, (char *)destbuf, &dstlen, &state); | ||
244 | unicode = destbuf[0]; | ||
245 | unicode <<= 8; | ||
246 | unicode |= destbuf[1]; | ||
247 | } else | ||
248 | unicode = buf[0]; | ||
249 | |||
250 | /* For some reason function keys map to control characters */ | ||
251 | # define CTRL(X) ((X)-'@') | ||
252 | switch (unicode) { | ||
253 | case CTRL('A'): | ||
254 | case CTRL('B'): | ||
255 | case CTRL('C'): | ||
256 | case CTRL('D'): | ||
257 | case CTRL('E'): | ||
258 | case CTRL('K'): | ||
259 | case CTRL('L'): | ||
260 | case CTRL('P'): | ||
261 | if ( ! (SDL_GetModState() & KMOD_CTRL) ) | ||
262 | unicode = 0; | ||
263 | break; | ||
264 | /* Keyboard input maps newline to carriage return */ | ||
265 | case '\n': | ||
266 | unicode = '\r'; | ||
267 | break; | ||
268 | default: | ||
269 | break; | ||
270 | } | ||
271 | |||
272 | return unicode; | ||
273 | } | ||
274 | |||
275 | virtual void DispatchMessage(BMessage *msg, BHandler *target); | ||
276 | |||
277 | virtual void DirectConnected(direct_buffer_info *info); | ||
278 | |||
279 | private: | ||
280 | #if SDL_VIDEO_OPENGL | ||
281 | BGLView *SDL_GLView; | ||
282 | #endif | ||
283 | SDL_BView *SDL_View; | ||
284 | BView *the_view; | ||
285 | bool shown; | ||
286 | bool inhibit_resize; | ||
287 | int32 last_buttons; | ||
288 | }; | ||
289 | |||
290 | #endif /* _SDL_BWin_h */ | ||
diff --git a/apps/plugins/sdl/src/video/bwindow/SDL_lowvideo.h b/apps/plugins/sdl/src/video/bwindow/SDL_lowvideo.h new file mode 100644 index 0000000000..0513b2db26 --- /dev/null +++ b/apps/plugins/sdl/src/video/bwindow/SDL_lowvideo.h | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _SDL_lowvideo_h | ||
25 | #define _SDL_lowvideo_h | ||
26 | |||
27 | #include "SDL_BWin.h" | ||
28 | #include "SDL_mouse.h" | ||
29 | #include "../SDL_sysvideo.h" | ||
30 | |||
31 | /* Hidden "this" pointer for the video functions */ | ||
32 | #define _THIS SDL_VideoDevice *_this | ||
33 | |||
34 | /* Private display data */ | ||
35 | struct SDL_PrivateVideoData { | ||
36 | /* The main window */ | ||
37 | SDL_BWin *SDL_Win; | ||
38 | |||
39 | /* The fullscreen mode list */ | ||
40 | display_mode saved_mode; | ||
41 | #define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */ | ||
42 | int SDL_nummodes[NUM_MODELISTS]; | ||
43 | SDL_Rect **SDL_modelist[NUM_MODELISTS]; | ||
44 | |||
45 | /* A completely clear cursor */ | ||
46 | WMcursor *BlankCursor; | ||
47 | |||
48 | SDL_Overlay *overlay; | ||
49 | }; | ||
50 | /* Old variable names */ | ||
51 | #define SDL_Win (_this->hidden->SDL_Win) | ||
52 | #define saved_mode (_this->hidden->saved_mode) | ||
53 | #define SDL_nummodes (_this->hidden->SDL_nummodes) | ||
54 | #define SDL_modelist (_this->hidden->SDL_modelist) | ||
55 | #define SDL_BlankCursor (_this->hidden->BlankCursor) | ||
56 | #define current_overlay (_this->hidden->overlay) | ||
57 | |||
58 | #endif /* _SDL_lowvideo_h */ | ||
diff --git a/apps/plugins/sdl/src/video/bwindow/SDL_sysevents.cc b/apps/plugins/sdl/src/video/bwindow/SDL_sysevents.cc new file mode 100644 index 0000000000..9e127506de --- /dev/null +++ b/apps/plugins/sdl/src/video/bwindow/SDL_sysevents.cc | |||
@@ -0,0 +1,415 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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 | #include "SDL_config.h" | ||
23 | |||
24 | #include <support/UTF8.h> | ||
25 | #include <stdio.h> | ||
26 | #include <string.h> | ||
27 | #include "SDL_error.h" | ||
28 | #include "SDL_events.h" | ||
29 | #include "SDL_BWin.h" | ||
30 | #include "SDL_lowvideo.h" | ||
31 | |||
32 | static SDLKey keymap[128]; | ||
33 | int mouse_relative = 0; | ||
34 | extern "C" { | ||
35 | |||
36 | #include "../../events/SDL_sysevents.h" | ||
37 | #include "../../events/SDL_events_c.h" | ||
38 | #include "SDL_sysevents_c.h" | ||
39 | #include "../SDL_cursor_c.h" | ||
40 | |||
41 | void BE_PumpEvents(_THIS) | ||
42 | { | ||
43 | } | ||
44 | |||
45 | void BE_InitOSKeymap(_THIS) | ||
46 | { | ||
47 | for ( uint i=0; i<SDL_TABLESIZE(keymap); ++i ) | ||
48 | keymap[i] = SDLK_UNKNOWN; | ||
49 | |||
50 | keymap[0x01] = SDLK_ESCAPE; | ||
51 | keymap[B_F1_KEY] = SDLK_F1; | ||
52 | keymap[B_F2_KEY] = SDLK_F2; | ||
53 | keymap[B_F3_KEY] = SDLK_F3; | ||
54 | keymap[B_F4_KEY] = SDLK_F4; | ||
55 | keymap[B_F5_KEY] = SDLK_F5; | ||
56 | keymap[B_F6_KEY] = SDLK_F6; | ||
57 | keymap[B_F7_KEY] = SDLK_F7; | ||
58 | keymap[B_F8_KEY] = SDLK_F8; | ||
59 | keymap[B_F9_KEY] = SDLK_F9; | ||
60 | keymap[B_F10_KEY] = SDLK_F10; | ||
61 | keymap[B_F11_KEY] = SDLK_F11; | ||
62 | keymap[B_F12_KEY] = SDLK_F12; | ||
63 | keymap[B_PRINT_KEY] = SDLK_PRINT; | ||
64 | keymap[B_SCROLL_KEY] = SDLK_SCROLLOCK; | ||
65 | keymap[B_PAUSE_KEY] = SDLK_PAUSE; | ||
66 | keymap[0x11] = SDLK_BACKQUOTE; | ||
67 | keymap[0x12] = SDLK_1; | ||
68 | keymap[0x13] = SDLK_2; | ||
69 | keymap[0x14] = SDLK_3; | ||
70 | keymap[0x15] = SDLK_4; | ||
71 | keymap[0x16] = SDLK_5; | ||
72 | keymap[0x17] = SDLK_6; | ||
73 | keymap[0x18] = SDLK_7; | ||
74 | keymap[0x19] = SDLK_8; | ||
75 | keymap[0x1a] = SDLK_9; | ||
76 | keymap[0x1b] = SDLK_0; | ||
77 | keymap[0x1c] = SDLK_MINUS; | ||
78 | keymap[0x1d] = SDLK_EQUALS; | ||
79 | keymap[0x1e] = SDLK_BACKSPACE; | ||
80 | keymap[0x1f] = SDLK_INSERT; | ||
81 | keymap[0x20] = SDLK_HOME; | ||
82 | keymap[0x21] = SDLK_PAGEUP; | ||
83 | keymap[0x22] = SDLK_NUMLOCK; | ||
84 | keymap[0x23] = SDLK_KP_DIVIDE; | ||
85 | keymap[0x24] = SDLK_KP_MULTIPLY; | ||
86 | keymap[0x25] = SDLK_KP_MINUS; | ||
87 | keymap[0x26] = SDLK_TAB; | ||
88 | keymap[0x27] = SDLK_q; | ||
89 | keymap[0x28] = SDLK_w; | ||
90 | keymap[0x29] = SDLK_e; | ||
91 | keymap[0x2a] = SDLK_r; | ||
92 | keymap[0x2b] = SDLK_t; | ||
93 | keymap[0x2c] = SDLK_y; | ||
94 | keymap[0x2d] = SDLK_u; | ||
95 | keymap[0x2e] = SDLK_i; | ||
96 | keymap[0x2f] = SDLK_o; | ||
97 | keymap[0x30] = SDLK_p; | ||
98 | keymap[0x31] = SDLK_LEFTBRACKET; | ||
99 | keymap[0x32] = SDLK_RIGHTBRACKET; | ||
100 | keymap[0x33] = SDLK_BACKSLASH; | ||
101 | keymap[0x34] = SDLK_DELETE; | ||
102 | keymap[0x35] = SDLK_END; | ||
103 | keymap[0x36] = SDLK_PAGEDOWN; | ||
104 | keymap[0x37] = SDLK_KP7; | ||
105 | keymap[0x38] = SDLK_KP8; | ||
106 | keymap[0x39] = SDLK_KP9; | ||
107 | keymap[0x3a] = SDLK_KP_PLUS; | ||
108 | keymap[0x3b] = SDLK_CAPSLOCK; | ||
109 | keymap[0x3c] = SDLK_a; | ||
110 | keymap[0x3d] = SDLK_s; | ||
111 | keymap[0x3e] = SDLK_d; | ||
112 | keymap[0x3f] = SDLK_f; | ||
113 | keymap[0x40] = SDLK_g; | ||
114 | keymap[0x41] = SDLK_h; | ||
115 | keymap[0x42] = SDLK_j; | ||
116 | keymap[0x43] = SDLK_k; | ||
117 | keymap[0x44] = SDLK_l; | ||
118 | keymap[0x45] = SDLK_SEMICOLON; | ||
119 | keymap[0x46] = SDLK_QUOTE; | ||
120 | keymap[0x47] = SDLK_RETURN; | ||
121 | keymap[0x48] = SDLK_KP4; | ||
122 | keymap[0x49] = SDLK_KP5; | ||
123 | keymap[0x4a] = SDLK_KP6; | ||
124 | keymap[0x4b] = SDLK_LSHIFT; | ||
125 | keymap[0x4c] = SDLK_z; | ||
126 | keymap[0x4d] = SDLK_x; | ||
127 | keymap[0x4e] = SDLK_c; | ||
128 | keymap[0x4f] = SDLK_v; | ||
129 | keymap[0x50] = SDLK_b; | ||
130 | keymap[0x51] = SDLK_n; | ||
131 | keymap[0x52] = SDLK_m; | ||
132 | keymap[0x53] = SDLK_COMMA; | ||
133 | keymap[0x54] = SDLK_PERIOD; | ||
134 | keymap[0x55] = SDLK_SLASH; | ||
135 | keymap[0x56] = SDLK_RSHIFT; | ||
136 | keymap[0x57] = SDLK_UP; | ||
137 | keymap[0x58] = SDLK_KP1; | ||
138 | keymap[0x59] = SDLK_KP2; | ||
139 | keymap[0x5a] = SDLK_KP3; | ||
140 | keymap[0x5b] = SDLK_KP_ENTER; | ||
141 | keymap[0x5c] = SDLK_LCTRL; | ||
142 | keymap[0x5d] = SDLK_LALT; | ||
143 | keymap[0x5e] = SDLK_SPACE; | ||
144 | keymap[0x5f] = SDLK_RALT; | ||
145 | keymap[0x60] = SDLK_RCTRL; | ||
146 | keymap[0x61] = SDLK_LEFT; | ||
147 | keymap[0x62] = SDLK_DOWN; | ||
148 | keymap[0x63] = SDLK_RIGHT; | ||
149 | keymap[0x64] = SDLK_KP0; | ||
150 | keymap[0x65] = SDLK_KP_PERIOD; | ||
151 | keymap[0x66] = SDLK_LMETA; | ||
152 | keymap[0x67] = SDLK_RMETA; | ||
153 | keymap[0x68] = SDLK_MENU; | ||
154 | keymap[0x69] = SDLK_EURO; | ||
155 | keymap[0x6a] = SDLK_KP_EQUALS; | ||
156 | keymap[0x6b] = SDLK_POWER; | ||
157 | } | ||
158 | |||
159 | }; /* Extern C */ | ||
160 | |||
161 | void SDL_BWin::DispatchMessage(BMessage *msg, BHandler *target) | ||
162 | { | ||
163 | switch (msg->what) { | ||
164 | case B_MOUSE_MOVED: | ||
165 | { | ||
166 | SDL_VideoDevice *view = current_video; | ||
167 | BPoint where; | ||
168 | int32 transit; | ||
169 | if (msg->FindPoint("where", &where) == B_OK && msg->FindInt32("be:transit", &transit) == B_OK) { | ||
170 | int x, y; | ||
171 | |||
172 | GetXYOffset(x, y); | ||
173 | x = (int)where.x - x; | ||
174 | y = (int)where.y - y; | ||
175 | |||
176 | //BeSman: I need another method for cursor catching !!! | ||
177 | if (view->input_grab != SDL_GRAB_OFF) | ||
178 | { | ||
179 | bool clipped = false; | ||
180 | if ( x < 0 ) { | ||
181 | x = 0; | ||
182 | clipped = true; | ||
183 | } else if ( x >= SDL_VideoSurface->w ) { | ||
184 | x = (SDL_VideoSurface->w-1); | ||
185 | clipped = true; | ||
186 | } | ||
187 | if ( y < 0 ) { | ||
188 | y = 0; | ||
189 | clipped = true; | ||
190 | } else if ( y >= SDL_VideoSurface->h ) { | ||
191 | y = (SDL_VideoSurface->h-1); | ||
192 | clipped = true; | ||
193 | } | ||
194 | if ( clipped ) { | ||
195 | BPoint edge; | ||
196 | GetXYOffset(edge.x, edge.y); | ||
197 | edge.x += x; | ||
198 | edge.y += y; | ||
199 | ConvertToScreen(&edge); | ||
200 | set_mouse_position((int)edge.x, (int)edge.y); | ||
201 | } | ||
202 | transit = B_INSIDE_VIEW; | ||
203 | } | ||
204 | if (transit == B_EXITED_VIEW) { | ||
205 | if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) { | ||
206 | SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); | ||
207 | #if SDL_VIDEO_OPENGL | ||
208 | // for some reason, SDL_EraseCursor fails for OpenGL | ||
209 | if (this->the_view != this->SDL_GLView) | ||
210 | #endif | ||
211 | SDL_EraseCursor(SDL_VideoSurface); | ||
212 | be_app->SetCursor(B_HAND_CURSOR); | ||
213 | } | ||
214 | } else { | ||
215 | if ( !(SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) { | ||
216 | SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); | ||
217 | #if SDL_VIDEO_OPENGL | ||
218 | // for some reason, SDL_EraseCursor fails for OpenGL | ||
219 | if (this->the_view != this->SDL_GLView) | ||
220 | #endif | ||
221 | SDL_EraseCursor(SDL_VideoSurface); | ||
222 | SDL_SetCursor(NULL); | ||
223 | } | ||
224 | |||
225 | if ( mouse_relative ) { | ||
226 | int half_w = (SDL_VideoSurface->w/2); | ||
227 | int half_h = (SDL_VideoSurface->h/2); | ||
228 | x -= half_w; | ||
229 | y -= half_h; | ||
230 | if ( x || y ) { | ||
231 | BPoint center; | ||
232 | GetXYOffset(center.x, center.y); | ||
233 | center.x += half_w; | ||
234 | center.y += half_h; | ||
235 | ConvertToScreen(¢er); | ||
236 | set_mouse_position((int)center.x, (int)center.y); | ||
237 | SDL_PrivateMouseMotion(0, 1, x, y); | ||
238 | } | ||
239 | } else { | ||
240 | SDL_PrivateMouseMotion(0, 0, x, y); | ||
241 | } | ||
242 | } | ||
243 | } | ||
244 | break; | ||
245 | } | ||
246 | |||
247 | case B_MOUSE_DOWN: | ||
248 | { | ||
249 | /* it looks like mouse down is send only for first clicked | ||
250 | button, each next is not send while last one is holded */ | ||
251 | int32 buttons; | ||
252 | int sdl_buttons = 0; | ||
253 | if (msg->FindInt32("buttons", &buttons) == B_OK) { | ||
254 | /* Add any mouse button events */ | ||
255 | if (buttons & B_PRIMARY_MOUSE_BUTTON) { | ||
256 | sdl_buttons |= SDL_BUTTON_LEFT; | ||
257 | } | ||
258 | if (buttons & B_SECONDARY_MOUSE_BUTTON) { | ||
259 | sdl_buttons |= SDL_BUTTON_RIGHT; | ||
260 | } | ||
261 | if (buttons & B_TERTIARY_MOUSE_BUTTON) { | ||
262 | sdl_buttons |= SDL_BUTTON_MIDDLE; | ||
263 | } | ||
264 | SDL_PrivateMouseButton(SDL_PRESSED, sdl_buttons, 0, 0); | ||
265 | |||
266 | last_buttons = buttons; | ||
267 | } | ||
268 | break; | ||
269 | } | ||
270 | |||
271 | case B_MOUSE_UP: | ||
272 | { | ||
273 | /* mouse up doesn't give which button was released, | ||
274 | only state of buttons (after release, so it's always = 0), | ||
275 | which is not what we need ;] | ||
276 | So we need to store button in mouse down, and restore | ||
277 | in mouse up :( | ||
278 | mouse up is (similarly to mouse down) send only for | ||
279 | first button down (ie. it's no send if we click another button | ||
280 | without releasing previous one first) - but that's probably | ||
281 | because of how drivers are written?, not BeOS itself. */ | ||
282 | int32 buttons; | ||
283 | int sdl_buttons = 0; | ||
284 | if (msg->FindInt32("buttons", &buttons) == B_OK) { | ||
285 | /* Add any mouse button events */ | ||
286 | if ((buttons ^ B_PRIMARY_MOUSE_BUTTON) & last_buttons) { | ||
287 | sdl_buttons |= SDL_BUTTON_LEFT; | ||
288 | } | ||
289 | if ((buttons ^ B_SECONDARY_MOUSE_BUTTON) & last_buttons) { | ||
290 | sdl_buttons |= SDL_BUTTON_RIGHT; | ||
291 | } | ||
292 | if ((buttons ^ B_TERTIARY_MOUSE_BUTTON) & last_buttons) { | ||
293 | sdl_buttons |= SDL_BUTTON_MIDDLE; | ||
294 | } | ||
295 | SDL_PrivateMouseButton(SDL_RELEASED, sdl_buttons, 0, 0); | ||
296 | |||
297 | last_buttons = buttons; | ||
298 | } | ||
299 | break; | ||
300 | } | ||
301 | |||
302 | case B_MOUSE_WHEEL_CHANGED: | ||
303 | { | ||
304 | float x, y; | ||
305 | x = y = 0; | ||
306 | if (msg->FindFloat("be:wheel_delta_x", &x) == B_OK && msg->FindFloat("be:wheel_delta_y", &y) == B_OK) { | ||
307 | if (x < 0 || y < 0) { | ||
308 | SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELDOWN, 0, 0); | ||
309 | SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELDOWN, 0, 0); | ||
310 | } else if (x > 0 || y > 0) { | ||
311 | SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELUP, 0, 0); | ||
312 | SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELUP, 0, 0); | ||
313 | } | ||
314 | } | ||
315 | break; | ||
316 | } | ||
317 | |||
318 | case B_KEY_DOWN: | ||
319 | case B_UNMAPPED_KEY_DOWN: /* modifier keys are unmapped */ | ||
320 | { | ||
321 | int32 key; | ||
322 | int32 modifiers; | ||
323 | int32 key_repeat; | ||
324 | /* Workaround for SDL message queue being filled too fast because of BeOS own key-repeat mechanism */ | ||
325 | if (msg->FindInt32("be:key_repeat", &key_repeat) == B_OK && key_repeat > 0) | ||
326 | break; | ||
327 | |||
328 | if (msg->FindInt32("key", &key) == B_OK && msg->FindInt32("modifiers", &modifiers) == B_OK) { | ||
329 | SDL_keysym keysym; | ||
330 | keysym.scancode = key; | ||
331 | if (key < 128) { | ||
332 | keysym.sym = keymap[key]; | ||
333 | } else { | ||
334 | keysym.sym = SDLK_UNKNOWN; | ||
335 | } | ||
336 | /* FIX THIS? | ||
337 | it seems SDL_PrivateKeyboard() changes mod value | ||
338 | anyway, and doesn't care about what we setup here */ | ||
339 | keysym.mod = KMOD_NONE; | ||
340 | keysym.unicode = 0; | ||
341 | if (SDL_TranslateUNICODE) { | ||
342 | const char *bytes; | ||
343 | if (msg->FindString("bytes", &bytes) == B_OK) { | ||
344 | /* FIX THIS? | ||
345 | this cares only about first "letter", | ||
346 | so if someone maps some key to print | ||
347 | "BeOS rulez!" only "B" will be used. */ | ||
348 | keysym.unicode = Translate2Unicode(bytes); | ||
349 | } | ||
350 | } | ||
351 | SDL_PrivateKeyboard(SDL_PRESSED, &keysym); | ||
352 | } | ||
353 | break; | ||
354 | } | ||
355 | |||
356 | case B_KEY_UP: | ||
357 | case B_UNMAPPED_KEY_UP: /* modifier keys are unmapped */ | ||
358 | { | ||
359 | int32 key; | ||
360 | int32 modifiers; | ||
361 | if (msg->FindInt32("key", &key) == B_OK && msg->FindInt32("modifiers", &modifiers) == B_OK) { | ||
362 | SDL_keysym keysym; | ||
363 | keysym.scancode = key; | ||
364 | if (key < 128) { | ||
365 | keysym.sym = keymap[key]; | ||
366 | } else { | ||
367 | keysym.sym = SDLK_UNKNOWN; | ||
368 | } | ||
369 | keysym.mod = KMOD_NONE; /* FIX THIS? */ | ||
370 | keysym.unicode = 0; | ||
371 | if (SDL_TranslateUNICODE) { | ||
372 | const char *bytes; | ||
373 | if (msg->FindString("bytes", &bytes) == B_OK) { | ||
374 | keysym.unicode = Translate2Unicode(bytes); | ||
375 | } | ||
376 | } | ||
377 | SDL_PrivateKeyboard(SDL_RELEASED, &keysym); | ||
378 | } | ||
379 | break; | ||
380 | } | ||
381 | |||
382 | default: | ||
383 | /* move it after switch{} so it's always handled | ||
384 | that way we keep BeOS feautures like: | ||
385 | - CTRL+Q to close window (and other shortcuts) | ||
386 | - PrintScreen to make screenshot into /boot/home | ||
387 | - etc.. */ | ||
388 | //BDirectWindow::DispatchMessage(msg, target); | ||
389 | break; | ||
390 | } | ||
391 | BDirectWindow::DispatchMessage(msg, target); | ||
392 | } | ||
393 | |||
394 | void SDL_BWin::DirectConnected(direct_buffer_info *info) { | ||
395 | switch (info->buffer_state & B_DIRECT_MODE_MASK) { | ||
396 | case B_DIRECT_START: | ||
397 | case B_DIRECT_MODIFY: | ||
398 | { | ||
399 | int32 width = info->window_bounds.right - | ||
400 | info->window_bounds.left; | ||
401 | int32 height = info->window_bounds.bottom - | ||
402 | info->window_bounds.top; | ||
403 | SDL_PrivateResize(width, height); | ||
404 | break; | ||
405 | } | ||
406 | default: | ||
407 | break; | ||
408 | } | ||
409 | #if SDL_VIDEO_OPENGL | ||
410 | // If it is a BGLView, it is apparently required to | ||
411 | // call DirectConnected() on it as well | ||
412 | if (this->the_view == this->SDL_GLView) | ||
413 | this->SDL_GLView->DirectConnected(info); | ||
414 | #endif | ||
415 | } | ||
diff --git a/apps/plugins/sdl/src/video/bwindow/SDL_sysevents_c.h b/apps/plugins/sdl/src/video/bwindow/SDL_sysevents_c.h new file mode 100644 index 0000000000..70c55358c9 --- /dev/null +++ b/apps/plugins/sdl/src/video/bwindow/SDL_sysevents_c.h | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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 | #include "SDL_config.h" | ||
23 | |||
24 | #include "SDL_lowvideo.h" | ||
25 | |||
26 | /* Variables and functions exported by SDL_sysevents.c to other parts | ||
27 | of the native video subsystem (SDL_sysvideo.c) | ||
28 | */ | ||
29 | |||
30 | extern void BE_InitOSKeymap(_THIS); | ||
31 | extern void BE_PumpEvents(_THIS); | ||
diff --git a/apps/plugins/sdl/src/video/bwindow/SDL_sysmouse.cc b/apps/plugins/sdl/src/video/bwindow/SDL_sysmouse.cc new file mode 100644 index 0000000000..9a557d6286 --- /dev/null +++ b/apps/plugins/sdl/src/video/bwindow/SDL_sysmouse.cc | |||
@@ -0,0 +1,153 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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 | #include "SDL_config.h" | ||
23 | |||
24 | #include <AppKit.h> | ||
25 | #include <GameKit.h> | ||
26 | |||
27 | #include "SDL_BWin.h" | ||
28 | |||
29 | extern "C" { | ||
30 | #include "../SDL_cursor_c.h" | ||
31 | #include "SDL_sysmouse_c.h" | ||
32 | |||
33 | /* Convert bits to padded bytes */ | ||
34 | #define PADDED_BITS(bits) ((bits+7)/8) | ||
35 | |||
36 | /* The implementation dependent data for the window manager cursor */ | ||
37 | struct WMcursor { | ||
38 | char *bits; | ||
39 | }; | ||
40 | |||
41 | /* Can this be done in the BeOS? */ | ||
42 | WMcursor *BE_CreateWMCursor(_THIS, | ||
43 | Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y) | ||
44 | { | ||
45 | WMcursor *cursor; | ||
46 | int allowed_x; | ||
47 | int allowed_y; | ||
48 | int run, pad, i; | ||
49 | char *cptr; | ||
50 | |||
51 | allowed_x = 16; /* BeOS limitation */ | ||
52 | allowed_y = 16; /* BeOS limitation */ | ||
53 | if ( (w > allowed_x) || (h > allowed_y) ) { | ||
54 | SDL_SetError("Only cursors of dimension (%dx%d) are allowed", | ||
55 | allowed_x, allowed_y); | ||
56 | return(NULL); | ||
57 | } | ||
58 | |||
59 | /* Allocate the cursor */ | ||
60 | cursor = (WMcursor *)SDL_malloc(sizeof(WMcursor)); | ||
61 | if ( cursor == NULL ) { | ||
62 | SDL_OutOfMemory(); | ||
63 | return(NULL); | ||
64 | } | ||
65 | cursor->bits = (char *)SDL_malloc(4+2*((allowed_x/8)*allowed_y)); | ||
66 | if ( cursor->bits == NULL ) { | ||
67 | SDL_free(cursor); | ||
68 | SDL_OutOfMemory(); | ||
69 | return(NULL); | ||
70 | } | ||
71 | cursor->bits[0] = allowed_y; /* Size of the cursor */ | ||
72 | cursor->bits[1] = 1; /* Bit depth of cursor */ | ||
73 | cursor->bits[2] = hot_y; | ||
74 | cursor->bits[3] = hot_x; | ||
75 | cptr = &cursor->bits[4]; | ||
76 | |||
77 | /* Pad out to the normal cursor size */ | ||
78 | run = PADDED_BITS(w); | ||
79 | pad = PADDED_BITS(allowed_x)-run; | ||
80 | for ( i=0; i<h; ++i ) { | ||
81 | SDL_memcpy(cptr, data, run); | ||
82 | SDL_memset(cptr+run, 0, pad); | ||
83 | data += run; | ||
84 | cptr += (run+pad); | ||
85 | } | ||
86 | for ( ; i<allowed_y; ++i ) { | ||
87 | SDL_memset(cptr, 0, run+pad); | ||
88 | cptr += (run+pad); | ||
89 | } | ||
90 | for ( i=0; i<h; ++i ) { | ||
91 | /* FIXME: The mask should be OR'd with the data to turn | ||
92 | inverted color pixels black, since inverted color pixels | ||
93 | aren't supported under BeOS. | ||
94 | */ | ||
95 | SDL_memcpy(cptr, mask, run); | ||
96 | SDL_memset(cptr+run, 0, pad); | ||
97 | mask += run; | ||
98 | cptr += (run+pad); | ||
99 | } | ||
100 | for ( ; i<allowed_y; ++i ) { | ||
101 | SDL_memset(cptr, 0, run+pad); | ||
102 | cptr += (run+pad); | ||
103 | } | ||
104 | return(cursor); | ||
105 | } | ||
106 | |||
107 | int BE_ShowWMCursor(_THIS, WMcursor *cursor) | ||
108 | { | ||
109 | if ( be_app->Lock() ) { | ||
110 | if ( cursor == NULL ) { | ||
111 | if ( SDL_BlankCursor != NULL ) { | ||
112 | be_app->SetCursor(SDL_BlankCursor->bits); | ||
113 | } | ||
114 | } else { | ||
115 | be_app->SetCursor(cursor->bits); | ||
116 | } | ||
117 | be_app->Unlock(); | ||
118 | } | ||
119 | return(1); | ||
120 | } | ||
121 | |||
122 | void BE_FreeWMCursor(_THIS, WMcursor *cursor) | ||
123 | { | ||
124 | SDL_free(cursor->bits); | ||
125 | SDL_free(cursor); | ||
126 | } | ||
127 | |||
128 | /* Implementation by Christian Bauer <cbauer@student.physik.uni-mainz.de> */ | ||
129 | void BE_WarpWMCursor(_THIS, Uint16 x, Uint16 y) | ||
130 | { | ||
131 | BPoint pt; | ||
132 | SDL_Win->GetXYOffset(pt.x, pt.y); | ||
133 | pt.x += x; | ||
134 | pt.y += y; | ||
135 | SDL_Win->Lock(); | ||
136 | SDL_Win->ConvertToScreen(&pt); | ||
137 | SDL_Win->Unlock(); | ||
138 | set_mouse_position((int32)pt.x, (int32)pt.y); | ||
139 | } | ||
140 | |||
141 | /* Check to see if we need to enter or leave mouse relative mode */ | ||
142 | void BE_CheckMouseMode(_THIS) | ||
143 | { | ||
144 | /* If the mouse is hidden and input is grabbed, we use relative mode */ | ||
145 | if ( !(SDL_cursorstate & CURSOR_VISIBLE) && | ||
146 | (_this->input_grab != SDL_GRAB_OFF) ) { | ||
147 | mouse_relative = 1; | ||
148 | } else { | ||
149 | mouse_relative = 0; | ||
150 | } | ||
151 | } | ||
152 | |||
153 | }; /* Extern C */ | ||
diff --git a/apps/plugins/sdl/src/video/bwindow/SDL_sysmouse_c.h b/apps/plugins/sdl/src/video/bwindow/SDL_sysmouse_c.h new file mode 100644 index 0000000000..70b3b2a5f9 --- /dev/null +++ b/apps/plugins/sdl/src/video/bwindow/SDL_sysmouse_c.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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 | #include "SDL_config.h" | ||
23 | |||
24 | #include "SDL_lowvideo.h" | ||
25 | |||
26 | /* Functions to be exported */ | ||
27 | extern void BE_FreeWMCursor(_THIS, WMcursor *cursor); | ||
28 | extern WMcursor *BE_CreateWMCursor(_THIS, | ||
29 | Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y); | ||
30 | extern int BE_ShowWMCursor(_THIS, WMcursor *cursor); | ||
31 | extern void BE_WarpWMCursor(_THIS, Uint16 x, Uint16 y); | ||
32 | extern void BE_CheckMouseMode(_THIS); | ||
33 | |||
diff --git a/apps/plugins/sdl/src/video/bwindow/SDL_sysvideo.cc b/apps/plugins/sdl/src/video/bwindow/SDL_sysvideo.cc new file mode 100644 index 0000000000..c32b661d24 --- /dev/null +++ b/apps/plugins/sdl/src/video/bwindow/SDL_sysvideo.cc | |||
@@ -0,0 +1,841 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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 | #include "SDL_config.h" | ||
23 | |||
24 | /* BWindow based framebuffer implementation */ | ||
25 | |||
26 | #include <unistd.h> | ||
27 | |||
28 | #include "SDL_BWin.h" | ||
29 | #include "SDL_timer.h" | ||
30 | |||
31 | extern "C" { | ||
32 | |||
33 | #include "../SDL_sysvideo.h" | ||
34 | #include "../../events/SDL_events_c.h" | ||
35 | #include "SDL_sysevents_c.h" | ||
36 | #include "SDL_sysmouse_c.h" | ||
37 | #include "SDL_syswm_c.h" | ||
38 | #include "SDL_lowvideo.h" | ||
39 | #include "../SDL_yuvfuncs.h" | ||
40 | #include "SDL_sysyuv.h" | ||
41 | #include "../blank_cursor.h" | ||
42 | |||
43 | #define BEOS_HIDDEN_SIZE 32 /* starting hidden window size */ | ||
44 | |||
45 | /* Initialization/Query functions */ | ||
46 | static int BE_VideoInit(_THIS, SDL_PixelFormat *vformat); | ||
47 | static SDL_Rect **BE_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); | ||
48 | static SDL_Surface *BE_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | ||
49 | static void BE_UpdateMouse(_THIS); | ||
50 | static int BE_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); | ||
51 | static void BE_VideoQuit(_THIS); | ||
52 | |||
53 | /* Hardware surface functions */ | ||
54 | static int BE_AllocHWSurface(_THIS, SDL_Surface *surface); | ||
55 | static int BE_LockHWSurface(_THIS, SDL_Surface *surface); | ||
56 | static void BE_UnlockHWSurface(_THIS, SDL_Surface *surface); | ||
57 | static void BE_FreeHWSurface(_THIS, SDL_Surface *surface); | ||
58 | |||
59 | static int BE_ToggleFullScreen(_THIS, int fullscreen); | ||
60 | |||
61 | /* OpenGL functions */ | ||
62 | #if SDL_VIDEO_OPENGL | ||
63 | static int BE_GL_LoadLibrary(_THIS, const char *path); | ||
64 | static void* BE_GL_GetProcAddress(_THIS, const char *proc); | ||
65 | static int BE_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value); | ||
66 | static int BE_GL_MakeCurrent(_THIS); | ||
67 | static void BE_GL_SwapBuffers(_THIS); | ||
68 | #endif | ||
69 | |||
70 | /* FB driver bootstrap functions */ | ||
71 | |||
72 | static int BE_Available(void) | ||
73 | { | ||
74 | return(1); | ||
75 | } | ||
76 | |||
77 | static void BE_DeleteDevice(SDL_VideoDevice *device) | ||
78 | { | ||
79 | SDL_free(device->hidden); | ||
80 | SDL_free(device); | ||
81 | } | ||
82 | |||
83 | static SDL_VideoDevice *BE_CreateDevice(int devindex) | ||
84 | { | ||
85 | SDL_VideoDevice *device; | ||
86 | |||
87 | /* Initialize all variables that we clean on shutdown */ | ||
88 | device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); | ||
89 | if ( device ) { | ||
90 | SDL_memset(device, 0, (sizeof *device)); | ||
91 | device->hidden = (struct SDL_PrivateVideoData *) | ||
92 | SDL_malloc((sizeof *device->hidden)); | ||
93 | } | ||
94 | if ( (device == NULL) || (device->hidden == NULL) ) { | ||
95 | SDL_OutOfMemory(); | ||
96 | if ( device ) { | ||
97 | SDL_free(device); | ||
98 | } | ||
99 | return(0); | ||
100 | } | ||
101 | SDL_memset(device->hidden, 0, (sizeof *device->hidden)); | ||
102 | |||
103 | /* Set the function pointers */ | ||
104 | /* Initialization/Query functions */ | ||
105 | device->VideoInit = BE_VideoInit; | ||
106 | device->ListModes = BE_ListModes; | ||
107 | device->SetVideoMode = BE_SetVideoMode; | ||
108 | device->ToggleFullScreen = BE_ToggleFullScreen; | ||
109 | device->UpdateMouse = BE_UpdateMouse; | ||
110 | device->CreateYUVOverlay = BE_CreateYUVOverlay; | ||
111 | device->SetColors = BE_SetColors; | ||
112 | device->UpdateRects = NULL; | ||
113 | device->VideoQuit = BE_VideoQuit; | ||
114 | /* Hardware acceleration functions */ | ||
115 | device->AllocHWSurface = BE_AllocHWSurface; | ||
116 | device->CheckHWBlit = NULL; | ||
117 | device->FillHWRect = NULL; | ||
118 | device->SetHWColorKey = NULL; | ||
119 | device->SetHWAlpha = NULL; | ||
120 | device->LockHWSurface = BE_LockHWSurface; | ||
121 | device->UnlockHWSurface = BE_UnlockHWSurface; | ||
122 | device->FlipHWSurface = NULL; | ||
123 | device->FreeHWSurface = BE_FreeHWSurface; | ||
124 | /* Gamma support */ | ||
125 | #if SDL_VIDEO_OPENGL | ||
126 | /* OpenGL support */ | ||
127 | device->GL_LoadLibrary = BE_GL_LoadLibrary; | ||
128 | device->GL_GetProcAddress = BE_GL_GetProcAddress; | ||
129 | device->GL_GetAttribute = BE_GL_GetAttribute; | ||
130 | device->GL_MakeCurrent = BE_GL_MakeCurrent; | ||
131 | device->GL_SwapBuffers = BE_GL_SwapBuffers; | ||
132 | #endif | ||
133 | /* Window manager functions */ | ||
134 | device->SetCaption = BE_SetWMCaption; | ||
135 | device->SetIcon = NULL; | ||
136 | device->IconifyWindow = BE_IconifyWindow; | ||
137 | device->GrabInput = BE_GrabInput; | ||
138 | device->GetWMInfo = BE_GetWMInfo; | ||
139 | /* Cursor manager functions */ | ||
140 | device->FreeWMCursor = BE_FreeWMCursor; | ||
141 | device->CreateWMCursor = BE_CreateWMCursor; | ||
142 | device->ShowWMCursor = BE_ShowWMCursor; | ||
143 | device->WarpWMCursor = BE_WarpWMCursor; | ||
144 | device->MoveWMCursor = NULL; | ||
145 | device->CheckMouseMode = BE_CheckMouseMode; | ||
146 | /* Event manager functions */ | ||
147 | device->InitOSKeymap = BE_InitOSKeymap; | ||
148 | device->PumpEvents = BE_PumpEvents; | ||
149 | |||
150 | device->free = BE_DeleteDevice; | ||
151 | |||
152 | /* Set the driver flags */ | ||
153 | device->handles_any_size = 1; | ||
154 | |||
155 | return device; | ||
156 | } | ||
157 | |||
158 | VideoBootStrap BWINDOW_bootstrap = { | ||
159 | "bwindow", "BDirectWindow graphics", | ||
160 | BE_Available, BE_CreateDevice | ||
161 | }; | ||
162 | |||
163 | static inline int ColorSpaceToBitsPerPixel(uint32 colorspace) | ||
164 | { | ||
165 | int bitsperpixel; | ||
166 | |||
167 | bitsperpixel = 0; | ||
168 | switch (colorspace) { | ||
169 | case B_CMAP8: | ||
170 | bitsperpixel = 8; | ||
171 | break; | ||
172 | case B_RGB15: | ||
173 | case B_RGBA15: | ||
174 | case B_RGB15_BIG: | ||
175 | case B_RGBA15_BIG: | ||
176 | bitsperpixel = 15; | ||
177 | break; | ||
178 | case B_RGB16: | ||
179 | case B_RGB16_BIG: | ||
180 | bitsperpixel = 16; | ||
181 | break; | ||
182 | case B_RGB32: | ||
183 | case B_RGBA32: | ||
184 | case B_RGB32_BIG: | ||
185 | case B_RGBA32_BIG: | ||
186 | bitsperpixel = 32; | ||
187 | break; | ||
188 | default: | ||
189 | break; | ||
190 | } | ||
191 | return(bitsperpixel); | ||
192 | } | ||
193 | |||
194 | /* Function to sort the display_list in bscreen */ | ||
195 | static int CompareModes(const void *A, const void *B) | ||
196 | { | ||
197 | const display_mode *a = (display_mode *)A; | ||
198 | const display_mode *b = (display_mode *)B; | ||
199 | |||
200 | if ( a->space == b->space ) { | ||
201 | return((b->virtual_width*b->virtual_height)- | ||
202 | (a->virtual_width*a->virtual_height)); | ||
203 | } else { | ||
204 | return(ColorSpaceToBitsPerPixel(b->space)- | ||
205 | ColorSpaceToBitsPerPixel(a->space)); | ||
206 | } | ||
207 | } | ||
208 | |||
209 | /* Yes, this isn't the fastest it could be, but it works nicely */ | ||
210 | static int BE_AddMode(_THIS, int index, unsigned int w, unsigned int h) | ||
211 | { | ||
212 | SDL_Rect *mode; | ||
213 | int i; | ||
214 | int next_mode; | ||
215 | |||
216 | /* Check to see if we already have this mode */ | ||
217 | if ( SDL_nummodes[index] > 0 ) { | ||
218 | for ( i=SDL_nummodes[index]-1; i >= 0; --i ) { | ||
219 | mode = SDL_modelist[index][i]; | ||
220 | if ( (mode->w == w) && (mode->h == h) ) { | ||
221 | #ifdef BWINDOW_DEBUG | ||
222 | fprintf(stderr, "We already have mode %dx%d at %d bytes per pixel\n", w, h, index+1); | ||
223 | #endif | ||
224 | return(0); | ||
225 | } | ||
226 | } | ||
227 | } | ||
228 | |||
229 | /* Set up the new video mode rectangle */ | ||
230 | mode = (SDL_Rect *)SDL_malloc(sizeof *mode); | ||
231 | if ( mode == NULL ) { | ||
232 | SDL_OutOfMemory(); | ||
233 | return(-1); | ||
234 | } | ||
235 | mode->x = 0; | ||
236 | mode->y = 0; | ||
237 | mode->w = w; | ||
238 | mode->h = h; | ||
239 | #ifdef BWINDOW_DEBUG | ||
240 | fprintf(stderr, "Adding mode %dx%d at %d bytes per pixel\n", w, h, index+1); | ||
241 | #endif | ||
242 | |||
243 | /* Allocate the new list of modes, and fill in the new mode */ | ||
244 | next_mode = SDL_nummodes[index]; | ||
245 | SDL_modelist[index] = (SDL_Rect **) | ||
246 | SDL_realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *)); | ||
247 | if ( SDL_modelist[index] == NULL ) { | ||
248 | SDL_OutOfMemory(); | ||
249 | SDL_nummodes[index] = 0; | ||
250 | SDL_free(mode); | ||
251 | return(-1); | ||
252 | } | ||
253 | SDL_modelist[index][next_mode] = mode; | ||
254 | SDL_modelist[index][next_mode+1] = NULL; | ||
255 | SDL_nummodes[index]++; | ||
256 | |||
257 | return(0); | ||
258 | } | ||
259 | |||
260 | int BE_VideoInit(_THIS, SDL_PixelFormat *vformat) | ||
261 | { | ||
262 | display_mode *modes; | ||
263 | uint32 i, nmodes; | ||
264 | int bpp; | ||
265 | BRect bounds; | ||
266 | |||
267 | /* Initialize the Be Application for appserver interaction */ | ||
268 | if ( SDL_InitBeApp() < 0 ) { | ||
269 | return(-1); | ||
270 | } | ||
271 | |||
272 | /* It is important that this be created after SDL_InitBeApp() */ | ||
273 | BScreen bscreen; | ||
274 | |||
275 | /* Save the current display mode */ | ||
276 | bscreen.GetMode(&saved_mode); | ||
277 | _this->info.current_w = saved_mode.virtual_width; | ||
278 | _this->info.current_h = saved_mode.virtual_height; | ||
279 | |||
280 | /* Determine the screen depth */ | ||
281 | vformat->BitsPerPixel = ColorSpaceToBitsPerPixel(bscreen.ColorSpace()); | ||
282 | if ( vformat->BitsPerPixel == 0 ) { | ||
283 | SDL_SetError("Unknown BScreen colorspace: 0x%x", | ||
284 | bscreen.ColorSpace()); | ||
285 | return(-1); | ||
286 | } | ||
287 | |||
288 | /* Get the video modes we can switch to in fullscreen mode */ | ||
289 | bscreen.GetModeList(&modes, &nmodes); | ||
290 | SDL_qsort(modes, nmodes, sizeof *modes, CompareModes); | ||
291 | for ( i=0; i<nmodes; ++i ) { | ||
292 | bpp = ColorSpaceToBitsPerPixel(modes[i].space); | ||
293 | //if ( bpp != 0 ) { // There are bugs in changing colorspace | ||
294 | if ( modes[i].space == saved_mode.space ) { | ||
295 | BE_AddMode(_this, ((bpp+7)/8)-1, | ||
296 | modes[i].virtual_width, | ||
297 | modes[i].virtual_height); | ||
298 | } | ||
299 | } | ||
300 | |||
301 | /* Create the window and view */ | ||
302 | bounds.top = 0; bounds.left = 0; | ||
303 | bounds.right = BEOS_HIDDEN_SIZE; | ||
304 | bounds.bottom = BEOS_HIDDEN_SIZE; | ||
305 | SDL_Win = new SDL_BWin(bounds); | ||
306 | |||
307 | #if SDL_VIDEO_OPENGL | ||
308 | /* testgl application doesn't load library, just tries to load symbols */ | ||
309 | /* is it correct? if so we have to load library here */ | ||
310 | BE_GL_LoadLibrary(_this, NULL); | ||
311 | #endif | ||
312 | |||
313 | /* Create the clear cursor */ | ||
314 | SDL_BlankCursor = BE_CreateWMCursor(_this, blank_cdata, blank_cmask, | ||
315 | BLANK_CWIDTH, BLANK_CHEIGHT, BLANK_CHOTX, BLANK_CHOTY); | ||
316 | |||
317 | /* Fill in some window manager capabilities */ | ||
318 | _this->info.wm_available = 1; | ||
319 | |||
320 | /* We're done! */ | ||
321 | return(0); | ||
322 | } | ||
323 | |||
324 | /* We support any dimension at our bit-depth */ | ||
325 | SDL_Rect **BE_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) | ||
326 | { | ||
327 | SDL_Rect **modes; | ||
328 | |||
329 | modes = ((SDL_Rect **)0); | ||
330 | if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) { | ||
331 | modes = SDL_modelist[((format->BitsPerPixel+7)/8)-1]; | ||
332 | } else { | ||
333 | if ( format->BitsPerPixel == | ||
334 | _this->screen->format->BitsPerPixel ) { | ||
335 | modes = ((SDL_Rect **)-1); | ||
336 | } | ||
337 | } | ||
338 | return(modes); | ||
339 | } | ||
340 | |||
341 | /* Various screen update functions available */ | ||
342 | static void BE_NormalUpdate(_THIS, int numrects, SDL_Rect *rects); | ||
343 | |||
344 | |||
345 | /* Find the closest display mode for fullscreen */ | ||
346 | static bool BE_FindClosestFSMode(_THIS, int width, int height, int bpp, | ||
347 | display_mode *mode) | ||
348 | { | ||
349 | BScreen bscreen; | ||
350 | uint32 i, nmodes; | ||
351 | SDL_Rect **modes; | ||
352 | display_mode *dmodes; | ||
353 | display_mode current; | ||
354 | float current_refresh; | ||
355 | bscreen.GetMode(¤t); | ||
356 | current_refresh = (1000 * current.timing.pixel_clock) / | ||
357 | (current.timing.h_total * current.timing.v_total); | ||
358 | |||
359 | modes = SDL_modelist[((bpp+7)/8)-1]; | ||
360 | |||
361 | // find end of list (lowest-resolution mode; modes are ordered | ||
362 | // highest-to-lowest). | ||
363 | i = 0; while(modes[i]) i++; | ||
364 | if (!i) return false; // what? no modes at all? | ||
365 | |||
366 | // find first mode with resolution >= requested in both dimensions | ||
367 | for (--i; i >= 0; --i) | ||
368 | { | ||
369 | if (modes[i]->w >= width && modes[i]->h >= height) | ||
370 | break; | ||
371 | } | ||
372 | |||
373 | // unable to find any mode with that high a resolution! | ||
374 | if (i < 0) | ||
375 | return false; | ||
376 | |||
377 | width = modes[i]->w; | ||
378 | height = modes[i]->h; | ||
379 | |||
380 | bscreen.GetModeList(&dmodes, &nmodes); | ||
381 | for ( i = 0; i < nmodes; ++i ) { | ||
382 | if ( (bpp == ColorSpaceToBitsPerPixel(dmodes[i].space)) && | ||
383 | (width == dmodes[i].virtual_width) && | ||
384 | (height == dmodes[i].virtual_height) ) { | ||
385 | break; | ||
386 | } | ||
387 | } | ||
388 | if ( i != nmodes ) { | ||
389 | *mode = dmodes[i]; | ||
390 | if ((mode->virtual_width <= current.virtual_width) && | ||
391 | (mode->virtual_height <= current.virtual_height)) { | ||
392 | float new_refresh = (1000 * mode->timing.pixel_clock) / | ||
393 | (mode->timing.h_total * mode->timing.v_total); | ||
394 | if (new_refresh < current_refresh) { | ||
395 | mode->timing.pixel_clock = (uint32)((mode->timing.h_total * mode->timing.v_total) | ||
396 | * current_refresh / 1000); | ||
397 | } | ||
398 | } | ||
399 | return true; | ||
400 | } else { | ||
401 | return false; | ||
402 | } | ||
403 | } | ||
404 | |||
405 | static int BE_SetFullScreen(_THIS, SDL_Surface *screen, int fullscreen) | ||
406 | { | ||
407 | // printf("SetFullScreen(%d)\n", fullscreen); | ||
408 | BScreen bscreen; | ||
409 | |||
410 | // SetFullSscreen() does not work as expected if called in a window | ||
411 | // that was never shown. This is probably a bug in the Haiku Game Kit that needs | ||
412 | // to be investigated. | ||
413 | if (SDL_Win->Lock()) { | ||
414 | // Show our window. | ||
415 | SDL_Win->Show(); | ||
416 | } | ||
417 | |||
418 | if (SDL_Win->IsLocked()) { | ||
419 | // Unlock the window if it was locked. This is needed as only the | ||
420 | // first call to Show() unlocks the looper. All other calls to it | ||
421 | // will not. | ||
422 | SDL_Win->Unlock(); | ||
423 | } | ||
424 | |||
425 | int width = screen->w; | ||
426 | int height = screen->h; | ||
427 | |||
428 | if (fullscreen) { | ||
429 | // Set resolution to the closest available one that matches the | ||
430 | // current SDL resolution. | ||
431 | display_mode mode; | ||
432 | bscreen.GetMode(&mode); | ||
433 | |||
434 | int bpp = screen->format->BitsPerPixel; | ||
435 | if (bpp != ColorSpaceToBitsPerPixel(mode.space) || | ||
436 | width != mode.virtual_width || height != mode.virtual_height) { | ||
437 | if(BE_FindClosestFSMode(_this, width, height, bpp, &mode)) { | ||
438 | bscreen.SetMode(&mode); | ||
439 | } else { | ||
440 | // printf("Could not set new mode.\n"); | ||
441 | return(0); | ||
442 | } | ||
443 | } | ||
444 | } else { | ||
445 | // Reset to the previous known resolution as we are now in window | ||
446 | // mode. | ||
447 | bscreen.SetMode(&saved_mode); | ||
448 | } | ||
449 | |||
450 | // Effectivelly set/reset full screen mode. If we are already in | ||
451 | // full screen mode, we reset back to windowed mode first so the | ||
452 | // window can resize when going fullscreen. | ||
453 | // if (fullscreen) | ||
454 | // printf("Going fullscreen\n"); | ||
455 | // else | ||
456 | // printf("Going windowed\n"); | ||
457 | SDL_Win->SetFullScreen(fullscreen); | ||
458 | |||
459 | // Calculate offsets for centering the window (in window mode) and for | ||
460 | // dentering the bitmap (in full screen mode). | ||
461 | BRect bounds = bscreen.Frame(); | ||
462 | bounds.PrintToStream(); | ||
463 | int32 cx = (bounds.IntegerWidth() - width)/2; | ||
464 | int32 cy = (bounds.IntegerHeight() - height)/2; | ||
465 | |||
466 | // printf ("cx = %d, cy = %d\n", cx, cy); | ||
467 | if (!SDL_Win->IsFullScreen()) { | ||
468 | // printf("Doing not fullscreen stuff.\n"); | ||
469 | // We are not in full screen mode, so we want to change the window | ||
470 | // size to match the resolution in SDL. | ||
471 | SDL_Win->ResizeTo(width, height); | ||
472 | |||
473 | // And also center the window and reset the drawing offset. | ||
474 | SDL_Win->MoveTo(cx, cy); | ||
475 | SDL_Win->SetXYOffset(0, 0); | ||
476 | } else { | ||
477 | // printf("Doing fullscreen stuff."); | ||
478 | // Center the bitmap whenever we are in full screen mode. | ||
479 | SDL_Win->SetXYOffset(cx, cy); | ||
480 | } | ||
481 | |||
482 | // Set relevant internal SDL screen flags. | ||
483 | if (SDL_Win->IsFullScreen()) { | ||
484 | screen->flags |= SDL_FULLSCREEN; | ||
485 | } else { | ||
486 | screen->flags &= ~SDL_FULLSCREEN; | ||
487 | } | ||
488 | |||
489 | return(1); | ||
490 | } | ||
491 | |||
492 | static int BE_ToggleFullScreen(_THIS, int fullscreen) | ||
493 | { | ||
494 | return BE_SetFullScreen(_this, _this->screen, fullscreen); | ||
495 | } | ||
496 | |||
497 | /* FIXME: check return values and cleanup here */ | ||
498 | SDL_Surface *BE_SetVideoMode(_THIS, SDL_Surface *current, | ||
499 | int width, int height, int bpp, Uint32 flags) | ||
500 | { | ||
501 | BScreen bscreen; | ||
502 | BBitmap *bbitmap; | ||
503 | BRect bounds; | ||
504 | Uint32 gl_flags = 0; | ||
505 | |||
506 | /* Only RGB works on r5 currently */ | ||
507 | gl_flags = BGL_RGB; | ||
508 | if (_this->gl_config.double_buffer) | ||
509 | gl_flags |= BGL_DOUBLE; | ||
510 | else | ||
511 | gl_flags |= BGL_SINGLE; | ||
512 | if (_this->gl_config.alpha_size > 0 || bpp == 32) | ||
513 | gl_flags |= BGL_ALPHA; | ||
514 | if (_this->gl_config.depth_size > 0) | ||
515 | gl_flags |= BGL_DEPTH; | ||
516 | if (_this->gl_config.stencil_size > 0) | ||
517 | gl_flags |= BGL_STENCIL; | ||
518 | if (_this->gl_config.accum_red_size > 0 | ||
519 | || _this->gl_config.accum_green_size > 0 | ||
520 | || _this->gl_config.accum_blue_size > 0 | ||
521 | || _this->gl_config.accum_alpha_size > 0) | ||
522 | gl_flags |= BGL_ACCUM; | ||
523 | |||
524 | /* Create the view for this window, using found flags */ | ||
525 | if ( SDL_Win->CreateView(flags, gl_flags) < 0 ) { | ||
526 | return(NULL); | ||
527 | } | ||
528 | |||
529 | current->flags = 0; /* Clear flags */ | ||
530 | current->w = width; | ||
531 | current->h = height; | ||
532 | SDL_Win->SetType(B_TITLED_WINDOW); | ||
533 | if ( flags & SDL_NOFRAME ) { | ||
534 | current->flags |= SDL_NOFRAME; | ||
535 | SDL_Win->SetLook(B_NO_BORDER_WINDOW_LOOK); | ||
536 | } else { | ||
537 | if ( (flags & SDL_RESIZABLE) && !(flags & SDL_OPENGL) ) { | ||
538 | current->flags |= SDL_RESIZABLE; | ||
539 | /* We don't want opaque resizing (TM). :-) */ | ||
540 | SDL_Win->SetFlags(B_OUTLINE_RESIZE); | ||
541 | } else { | ||
542 | SDL_Win->SetFlags(B_NOT_RESIZABLE|B_NOT_ZOOMABLE); | ||
543 | } | ||
544 | } | ||
545 | |||
546 | if ( flags & SDL_OPENGL ) { | ||
547 | current->flags |= SDL_OPENGL; | ||
548 | current->pitch = 0; | ||
549 | current->pixels = NULL; | ||
550 | _this->UpdateRects = NULL; | ||
551 | } else { | ||
552 | /* Create the BBitmap framebuffer */ | ||
553 | bounds.top = 0; bounds.left = 0; | ||
554 | bounds.right = width-1; | ||
555 | bounds.bottom = height-1; | ||
556 | bbitmap = new BBitmap(bounds, bscreen.ColorSpace()); | ||
557 | if ( ! bbitmap->IsValid() ) { | ||
558 | SDL_SetError("Couldn't create screen bitmap"); | ||
559 | delete bbitmap; | ||
560 | return(NULL); | ||
561 | } | ||
562 | current->pitch = bbitmap->BytesPerRow(); | ||
563 | current->pixels = (void *)bbitmap->Bits(); | ||
564 | SDL_Win->SetBitmap(bbitmap); | ||
565 | _this->UpdateRects = BE_NormalUpdate; | ||
566 | } | ||
567 | |||
568 | /* Set the correct fullscreen mode */ | ||
569 | BE_SetFullScreen(_this, current, flags & SDL_FULLSCREEN ? 1 : 0); | ||
570 | |||
571 | /* We're done */ | ||
572 | return(current); | ||
573 | } | ||
574 | |||
575 | /* Update the current mouse state and position */ | ||
576 | void BE_UpdateMouse(_THIS) | ||
577 | { | ||
578 | BPoint point; | ||
579 | uint32 buttons; | ||
580 | |||
581 | if ( SDL_Win->Lock() ) { | ||
582 | /* Get new input state, if still active */ | ||
583 | if ( SDL_Win->IsActive() ) { | ||
584 | (SDL_Win->View())->GetMouse(&point, &buttons, true); | ||
585 | } else { | ||
586 | point.x = -1; | ||
587 | point.y = -1; | ||
588 | } | ||
589 | SDL_Win->Unlock(); | ||
590 | |||
591 | if ( (point.x >= 0) && (point.x < SDL_VideoSurface->w) && | ||
592 | (point.y >= 0) && (point.y < SDL_VideoSurface->h) ) { | ||
593 | SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); | ||
594 | SDL_PrivateMouseMotion(0, 0, | ||
595 | (Sint16)point.x, (Sint16)point.y); | ||
596 | } else { | ||
597 | SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); | ||
598 | } | ||
599 | } | ||
600 | } | ||
601 | |||
602 | /* We don't actually allow hardware surfaces other than the main one */ | ||
603 | static int BE_AllocHWSurface(_THIS, SDL_Surface *surface) | ||
604 | { | ||
605 | return(-1); | ||
606 | } | ||
607 | static void BE_FreeHWSurface(_THIS, SDL_Surface *surface) | ||
608 | { | ||
609 | return; | ||
610 | } | ||
611 | static int BE_LockHWSurface(_THIS, SDL_Surface *surface) | ||
612 | { | ||
613 | return(0); | ||
614 | } | ||
615 | static void BE_UnlockHWSurface(_THIS, SDL_Surface *surface) | ||
616 | { | ||
617 | return; | ||
618 | } | ||
619 | |||
620 | static void BE_NormalUpdate(_THIS, int numrects, SDL_Rect *rects) | ||
621 | { | ||
622 | if ( SDL_Win->BeginDraw() ) { | ||
623 | int i; | ||
624 | |||
625 | for ( i=0; i<numrects; ++i ) { | ||
626 | BRect rect; | ||
627 | |||
628 | rect.top = rects[i].y; | ||
629 | rect.left = rects[i].x; | ||
630 | rect.bottom = rect.top+rects[i].h-1; | ||
631 | rect.right = rect.left+rects[i].w-1; | ||
632 | SDL_Win->DrawAsync(rect); | ||
633 | } | ||
634 | SDL_Win->EndDraw(); | ||
635 | } | ||
636 | } | ||
637 | |||
638 | #if SDL_VIDEO_OPENGL | ||
639 | /* Passing a NULL path means load pointers from the application */ | ||
640 | int BE_GL_LoadLibrary(_THIS, const char *path) | ||
641 | { | ||
642 | if (path == NULL) { | ||
643 | if (_this->gl_config.dll_handle == NULL) { | ||
644 | image_info info; | ||
645 | int32 cookie = 0; | ||
646 | while (get_next_image_info(0,&cookie,&info) == B_OK) { | ||
647 | void *location = NULL; | ||
648 | #ifdef __HAIKU__ | ||
649 | if (get_image_symbol(info.id,"glBegin",B_SYMBOL_TYPE_ANY,&location) == B_OK) { // This is how it actually works in Haiku | ||
650 | #else | ||
651 | if (get_image_symbol((image_id)cookie,"glBegin",B_SYMBOL_TYPE_ANY,&location) == B_OK) { // I don't know if that *did* work in BeOS | ||
652 | #endif | ||
653 | _this->gl_config.dll_handle = (void*)info.id; | ||
654 | _this->gl_config.driver_loaded = 1; | ||
655 | SDL_strlcpy(_this->gl_config.driver_path, "libGL.so", SDL_arraysize(_this->gl_config.driver_path)); | ||
656 | } | ||
657 | } | ||
658 | } | ||
659 | } else { | ||
660 | /* | ||
661 | FIXME None of BeOS libGL.so implementations have exported functions | ||
662 | to load BGLView, which should be reloaded from new lib. | ||
663 | So for now just "load" linked libGL.so :( | ||
664 | */ | ||
665 | if (_this->gl_config.dll_handle == NULL) { | ||
666 | return BE_GL_LoadLibrary(_this, NULL); | ||
667 | } | ||
668 | |||
669 | /* Unload old first */ | ||
670 | /*if (_this->gl_config.dll_handle != NULL) {*/ | ||
671 | /* Do not try to unload application itself (if LoadLibrary was called before with NULL ;) */ | ||
672 | /* image_info info; | ||
673 | if (get_image_info((image_id)_this->gl_config.dll_handle, &info) == B_OK) { | ||
674 | if (info.type != B_APP_IMAGE) { | ||
675 | unload_add_on((image_id)_this->gl_config.dll_handle); | ||
676 | } | ||
677 | } | ||
678 | |||
679 | } | ||
680 | |||
681 | if ((_this->gl_config.dll_handle = (void*)load_add_on(path)) != (void*)B_ERROR) { | ||
682 | _this->gl_config.driver_loaded = 1; | ||
683 | SDL_strlcpy(_this->gl_config.driver_path, path, SDL_arraysize(_this->gl_config.driver_path)); | ||
684 | }*/ | ||
685 | } | ||
686 | |||
687 | if (_this->gl_config.dll_handle != NULL) { | ||
688 | return 0; | ||
689 | } else { | ||
690 | _this->gl_config.dll_handle = NULL; | ||
691 | _this->gl_config.driver_loaded = 0; | ||
692 | *_this->gl_config.driver_path = '\0'; | ||
693 | return -1; | ||
694 | } | ||
695 | } | ||
696 | |||
697 | void* BE_GL_GetProcAddress(_THIS, const char *proc) | ||
698 | { | ||
699 | if (_this->gl_config.dll_handle != NULL) { | ||
700 | void *location = NULL; | ||
701 | status_t err; | ||
702 | if ((err = get_image_symbol((image_id)_this->gl_config.dll_handle, proc, B_SYMBOL_TYPE_ANY, &location)) == B_OK) { | ||
703 | return location; | ||
704 | } else { | ||
705 | SDL_SetError("Couldn't find OpenGL symbol"); | ||
706 | return NULL; | ||
707 | } | ||
708 | } else { | ||
709 | SDL_SetError("OpenGL library not loaded"); | ||
710 | return NULL; | ||
711 | } | ||
712 | } | ||
713 | |||
714 | int BE_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value) | ||
715 | { | ||
716 | /* | ||
717 | FIXME? Right now BE_GL_GetAttribute shouldn't be called between glBegin() and glEnd() - it doesn't use "cached" values | ||
718 | */ | ||
719 | switch (attrib) | ||
720 | { | ||
721 | case SDL_GL_RED_SIZE: | ||
722 | glGetIntegerv(GL_RED_BITS, (GLint*)value); | ||
723 | break; | ||
724 | case SDL_GL_GREEN_SIZE: | ||
725 | glGetIntegerv(GL_GREEN_BITS, (GLint*)value); | ||
726 | break; | ||
727 | case SDL_GL_BLUE_SIZE: | ||
728 | glGetIntegerv(GL_BLUE_BITS, (GLint*)value); | ||
729 | break; | ||
730 | case SDL_GL_ALPHA_SIZE: | ||
731 | glGetIntegerv(GL_ALPHA_BITS, (GLint*)value); | ||
732 | break; | ||
733 | case SDL_GL_DOUBLEBUFFER: | ||
734 | glGetBooleanv(GL_DOUBLEBUFFER, (GLboolean*)value); | ||
735 | break; | ||
736 | case SDL_GL_BUFFER_SIZE: | ||
737 | int v; | ||
738 | glGetIntegerv(GL_RED_BITS, (GLint*)&v); | ||
739 | *value = v; | ||
740 | glGetIntegerv(GL_GREEN_BITS, (GLint*)&v); | ||
741 | *value += v; | ||
742 | glGetIntegerv(GL_BLUE_BITS, (GLint*)&v); | ||
743 | *value += v; | ||
744 | glGetIntegerv(GL_ALPHA_BITS, (GLint*)&v); | ||
745 | *value += v; | ||
746 | break; | ||
747 | case SDL_GL_DEPTH_SIZE: | ||
748 | glGetIntegerv(GL_DEPTH_BITS, (GLint*)value); /* Mesa creates 16 only? r5 always 32 */ | ||
749 | break; | ||
750 | case SDL_GL_STENCIL_SIZE: | ||
751 | glGetIntegerv(GL_STENCIL_BITS, (GLint*)value); | ||
752 | break; | ||
753 | case SDL_GL_ACCUM_RED_SIZE: | ||
754 | glGetIntegerv(GL_ACCUM_RED_BITS, (GLint*)value); | ||
755 | break; | ||
756 | case SDL_GL_ACCUM_GREEN_SIZE: | ||
757 | glGetIntegerv(GL_ACCUM_GREEN_BITS, (GLint*)value); | ||
758 | break; | ||
759 | case SDL_GL_ACCUM_BLUE_SIZE: | ||
760 | glGetIntegerv(GL_ACCUM_BLUE_BITS, (GLint*)value); | ||
761 | break; | ||
762 | case SDL_GL_ACCUM_ALPHA_SIZE: | ||
763 | glGetIntegerv(GL_ACCUM_ALPHA_BITS, (GLint*)value); | ||
764 | break; | ||
765 | case SDL_GL_STEREO: | ||
766 | case SDL_GL_MULTISAMPLEBUFFERS: | ||
767 | case SDL_GL_MULTISAMPLESAMPLES: | ||
768 | default: | ||
769 | *value=0; | ||
770 | return(-1); | ||
771 | } | ||
772 | return 0; | ||
773 | } | ||
774 | |||
775 | int BE_GL_MakeCurrent(_THIS) | ||
776 | { | ||
777 | /* FIXME: should we glview->unlock and then glview->lock()? */ | ||
778 | return 0; | ||
779 | } | ||
780 | |||
781 | void BE_GL_SwapBuffers(_THIS) | ||
782 | { | ||
783 | SDL_Win->SwapBuffers(); | ||
784 | } | ||
785 | #endif | ||
786 | |||
787 | /* Is the system palette settable? */ | ||
788 | int BE_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) | ||
789 | { | ||
790 | int i; | ||
791 | SDL_Palette *palette; | ||
792 | const color_map *cmap = BScreen().ColorMap(); | ||
793 | |||
794 | /* Get the screen colormap */ | ||
795 | palette = _this->screen->format->palette; | ||
796 | for ( i=0; i<256; ++i ) { | ||
797 | palette->colors[i].r = cmap->color_list[i].red; | ||
798 | palette->colors[i].g = cmap->color_list[i].green; | ||
799 | palette->colors[i].b = cmap->color_list[i].blue; | ||
800 | } | ||
801 | return(0); | ||
802 | } | ||
803 | |||
804 | void BE_VideoQuit(_THIS) | ||
805 | { | ||
806 | int i, j; | ||
807 | |||
808 | SDL_Win->Quit(); | ||
809 | SDL_Win = NULL; | ||
810 | |||
811 | if ( SDL_BlankCursor != NULL ) { | ||
812 | BE_FreeWMCursor(_this, SDL_BlankCursor); | ||
813 | SDL_BlankCursor = NULL; | ||
814 | } | ||
815 | for ( i=0; i<NUM_MODELISTS; ++i ) { | ||
816 | if ( SDL_modelist[i] ) { | ||
817 | for ( j=0; SDL_modelist[i][j]; ++j ) { | ||
818 | SDL_free(SDL_modelist[i][j]); | ||
819 | } | ||
820 | SDL_free(SDL_modelist[i]); | ||
821 | SDL_modelist[i] = NULL; | ||
822 | } | ||
823 | } | ||
824 | /* Restore the original video mode */ | ||
825 | if ( _this->screen ) { | ||
826 | if ( (_this->screen->flags&SDL_FULLSCREEN) == SDL_FULLSCREEN ) { | ||
827 | BScreen bscreen; | ||
828 | bscreen.SetMode(&saved_mode); | ||
829 | } | ||
830 | _this->screen->pixels = NULL; | ||
831 | } | ||
832 | |||
833 | #if SDL_VIDEO_OPENGL | ||
834 | if (_this->gl_config.dll_handle != NULL) | ||
835 | unload_add_on((image_id)_this->gl_config.dll_handle); | ||
836 | #endif | ||
837 | |||
838 | SDL_QuitBeApp(); | ||
839 | } | ||
840 | |||
841 | }; /* Extern C */ | ||
diff --git a/apps/plugins/sdl/src/video/bwindow/SDL_syswm.cc b/apps/plugins/sdl/src/video/bwindow/SDL_syswm.cc new file mode 100644 index 0000000000..df801005d4 --- /dev/null +++ b/apps/plugins/sdl/src/video/bwindow/SDL_syswm.cc | |||
@@ -0,0 +1,92 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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 | #include "SDL_config.h" | ||
23 | |||
24 | #include "SDL_BWin.h" | ||
25 | |||
26 | extern "C" { | ||
27 | #include "SDL_syswm_c.h" | ||
28 | #include "SDL_error.h" | ||
29 | #include "../SDL_cursor_c.h" | ||
30 | |||
31 | void BE_SetWMCaption(_THIS, const char *title, const char *icon) | ||
32 | { | ||
33 | SDL_Win->SetTitle(title); | ||
34 | } | ||
35 | |||
36 | int BE_IconifyWindow(_THIS) | ||
37 | { | ||
38 | SDL_Win->Minimize(true); | ||
39 | return 1; | ||
40 | } | ||
41 | |||
42 | SDL_GrabMode BE_GrabInput(_THIS, SDL_GrabMode mode) | ||
43 | { | ||
44 | if ( mode == SDL_GRAB_OFF ) { | ||
45 | // be_app->ShowCursor(); | ||
46 | if ( !(SDL_cursorstate & CURSOR_VISIBLE) ) { | ||
47 | /* BeSman: Jan 2, 2006 | ||
48 | must be leaving relative mode, move mouse from | ||
49 | center of window to where it belongs ... */ | ||
50 | BPoint pt; | ||
51 | int x, y; | ||
52 | SDL_GetMouseState(&x,&y); | ||
53 | pt.x = x; | ||
54 | pt.y = y; | ||
55 | SDL_Win->Lock(); | ||
56 | SDL_Win->ConvertToScreen(&pt); | ||
57 | SDL_Win->Unlock(); | ||
58 | set_mouse_position((int)pt.x, (int)pt.y); | ||
59 | } | ||
60 | } else { | ||
61 | // be_app->HideCursor(); | ||
62 | if ( !(SDL_cursorstate & CURSOR_VISIBLE) ) { | ||
63 | /* BeSman: Jan 2, 2006 | ||
64 | must be entering relative mode, get ready by | ||
65 | moving mouse to center of window ... */ | ||
66 | BPoint pt; | ||
67 | pt.x = (SDL_VideoSurface->w/2); | ||
68 | pt.y = (SDL_VideoSurface->h/2); | ||
69 | SDL_Win->Lock(); | ||
70 | SDL_Win->ConvertToScreen(&pt); | ||
71 | SDL_Win->Unlock(); | ||
72 | set_mouse_position((int)pt.x, (int)pt.y); | ||
73 | } | ||
74 | } | ||
75 | return(mode); | ||
76 | } | ||
77 | |||
78 | int BE_GetWMInfo(_THIS, SDL_SysWMinfo *info) | ||
79 | { | ||
80 | if (info->version.major <= SDL_MAJOR_VERSION) | ||
81 | { | ||
82 | return 1; | ||
83 | } | ||
84 | else | ||
85 | { | ||
86 | SDL_SetError("Application not compiled with SDL %d.%d\n", | ||
87 | SDL_MAJOR_VERSION, SDL_MINOR_VERSION); | ||
88 | return -1; | ||
89 | } | ||
90 | } | ||
91 | |||
92 | }; /* Extern C */ | ||
diff --git a/apps/plugins/sdl/src/video/bwindow/SDL_syswm_c.h b/apps/plugins/sdl/src/video/bwindow/SDL_syswm_c.h new file mode 100644 index 0000000000..c1285c8ec2 --- /dev/null +++ b/apps/plugins/sdl/src/video/bwindow/SDL_syswm_c.h | |||
@@ -0,0 +1,32 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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 | #include "SDL_config.h" | ||
23 | |||
24 | #include "SDL_syswm.h" | ||
25 | #include "SDL_lowvideo.h" | ||
26 | |||
27 | |||
28 | /* Functions to be exported */ | ||
29 | extern void BE_SetWMCaption(_THIS, const char *title, const char *icon); | ||
30 | extern int BE_IconifyWindow(_THIS); | ||
31 | extern int BE_GetWMInfo(_THIS, SDL_SysWMinfo *info); | ||
32 | extern SDL_GrabMode BE_GrabInput(_THIS, SDL_GrabMode mode); | ||
diff --git a/apps/plugins/sdl/src/video/bwindow/SDL_sysyuv.cc b/apps/plugins/sdl/src/video/bwindow/SDL_sysyuv.cc new file mode 100644 index 0000000000..7c71b006e4 --- /dev/null +++ b/apps/plugins/sdl/src/video/bwindow/SDL_sysyuv.cc | |||
@@ -0,0 +1,314 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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 | #include "SDL_config.h" | ||
23 | |||
24 | /* This is the BeOS version of SDL YUV video overlays */ | ||
25 | |||
26 | #include "SDL_video.h" | ||
27 | #include "SDL_sysyuv.h" | ||
28 | #include "../SDL_yuvfuncs.h" | ||
29 | |||
30 | extern "C" { | ||
31 | |||
32 | /* The functions used to manipulate software video overlays */ | ||
33 | static struct private_yuvhwfuncs be_yuvfuncs = | ||
34 | { | ||
35 | BE_LockYUVOverlay, | ||
36 | BE_UnlockYUVOverlay, | ||
37 | BE_DisplayYUVOverlay, | ||
38 | BE_FreeYUVOverlay | ||
39 | }; | ||
40 | |||
41 | BBitmap * BE_GetOverlayBitmap(BRect bounds, color_space cs) { | ||
42 | BBitmap *bbitmap; | ||
43 | bbitmap = new BBitmap(bounds,B_BITMAP_WILL_OVERLAY,cs); | ||
44 | if (!bbitmap || bbitmap->InitCheck() != B_OK) { | ||
45 | delete bbitmap; | ||
46 | return 0; | ||
47 | } | ||
48 | overlay_restrictions r; | ||
49 | bbitmap->GetOverlayRestrictions(&r); | ||
50 | uint32 width = bounds.IntegerWidth() + 1; | ||
51 | uint32 height = bounds.IntegerHeight() + 1; | ||
52 | uint32 width_padding = 0; | ||
53 | uint32 height_padding = 0; | ||
54 | if ((r.source.horizontal_alignment != 0) || | ||
55 | (r.source.vertical_alignment != 0)) { | ||
56 | delete bbitmap; | ||
57 | return 0; | ||
58 | } | ||
59 | if (r.source.width_alignment != 0) { | ||
60 | uint32 aligned_width = r.source.width_alignment + 1; | ||
61 | if (width % aligned_width > 0) { | ||
62 | width_padding = aligned_width - width % aligned_width; | ||
63 | } | ||
64 | } | ||
65 | if (r.source.height_alignment != 0) { | ||
66 | uint32 aligned_height = r.source.height_alignment + 1; | ||
67 | if (height % aligned_height > 0) { | ||
68 | fprintf(stderr,"GetOverlayBitmap failed height alignment\n"); | ||
69 | fprintf(stderr,"- height = %lu, aligned_height = %lu\n",height,aligned_height); | ||
70 | delete bbitmap; | ||
71 | return 0; | ||
72 | } | ||
73 | } | ||
74 | if ((r.source.min_width > width) || | ||
75 | (r.source.min_height > height) || | ||
76 | (r.source.max_width < width) || | ||
77 | (r.source.max_height < height)) { | ||
78 | fprintf(stderr,"GetOverlayBitmap failed bounds tests\n"); | ||
79 | delete bbitmap; | ||
80 | return 0; | ||
81 | } | ||
82 | if ((width_padding != 0) || (height_padding != 0)) { | ||
83 | delete bbitmap; | ||
84 | bounds.Set(bounds.left,bounds.top,bounds.right+width_padding,bounds.bottom+height_padding); | ||
85 | bbitmap = new BBitmap(bounds,B_BITMAP_WILL_OVERLAY,cs); | ||
86 | if (!bbitmap || bbitmap->InitCheck() != B_OK) { | ||
87 | fprintf(stderr,"GetOverlayBitmap failed late\n"); | ||
88 | delete bbitmap; | ||
89 | return 0; | ||
90 | } | ||
91 | } | ||
92 | return bbitmap; | ||
93 | } | ||
94 | |||
95 | // See <GraphicsDefs.h> [btw: Cb=U, Cr=V] | ||
96 | // See also http://www.fourcc.org/indexyuv.htm | ||
97 | color_space convert_color_space(Uint32 format) { | ||
98 | switch (format) { | ||
99 | case SDL_YV12_OVERLAY: | ||
100 | return B_YUV9; | ||
101 | case SDL_IYUV_OVERLAY: | ||
102 | return B_YUV12; | ||
103 | case SDL_YUY2_OVERLAY: | ||
104 | return B_YCbCr422; | ||
105 | case SDL_UYVY_OVERLAY: | ||
106 | return B_YUV422; | ||
107 | case SDL_YVYU_OVERLAY: // not supported on beos? | ||
108 | return B_NO_COLOR_SPACE; | ||
109 | default: | ||
110 | return B_NO_COLOR_SPACE; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | // See SDL_video.h | ||
115 | int count_planes(Uint32 format) { | ||
116 | switch (format) { | ||
117 | case SDL_YV12_OVERLAY: | ||
118 | case SDL_IYUV_OVERLAY: | ||
119 | return 3; | ||
120 | case SDL_YUY2_OVERLAY: | ||
121 | case SDL_UYVY_OVERLAY: | ||
122 | case SDL_YVYU_OVERLAY: | ||
123 | return 1; | ||
124 | default: | ||
125 | return 0; | ||
126 | } | ||
127 | } | ||
128 | |||
129 | SDL_Overlay *BE_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) { | ||
130 | SDL_Overlay* overlay; | ||
131 | struct private_yuvhwdata* hwdata; | ||
132 | BBitmap *bbitmap; | ||
133 | int planes; | ||
134 | BRect bounds; | ||
135 | color_space cs; | ||
136 | |||
137 | /* find the appropriate BeOS colorspace descriptor */ | ||
138 | cs = convert_color_space(format); | ||
139 | if (cs == B_NO_COLOR_SPACE) | ||
140 | { | ||
141 | return NULL; | ||
142 | } | ||
143 | |||
144 | /* count planes */ | ||
145 | planes = count_planes(format); | ||
146 | if (planes == 0) | ||
147 | { | ||
148 | return NULL; | ||
149 | } | ||
150 | /* TODO: figure out planar modes, if anyone cares */ | ||
151 | if (planes == 3) | ||
152 | { | ||
153 | return NULL; | ||
154 | } | ||
155 | |||
156 | /* Create the overlay structure */ | ||
157 | overlay = (SDL_Overlay*)SDL_calloc(1, sizeof(SDL_Overlay)); | ||
158 | |||
159 | if (overlay == NULL) | ||
160 | { | ||
161 | SDL_OutOfMemory(); | ||
162 | return NULL; | ||
163 | } | ||
164 | |||
165 | /* Fill in the basic members */ | ||
166 | overlay->format = format; | ||
167 | overlay->w = width; | ||
168 | overlay->h = height; | ||
169 | overlay->hwdata = NULL; | ||
170 | |||
171 | /* Set up the YUV surface function structure */ | ||
172 | overlay->hwfuncs = &be_yuvfuncs; | ||
173 | |||
174 | /* Create the pixel data and lookup tables */ | ||
175 | hwdata = (struct private_yuvhwdata*)SDL_calloc(1, sizeof(struct private_yuvhwdata)); | ||
176 | |||
177 | if (hwdata == NULL) | ||
178 | { | ||
179 | SDL_OutOfMemory(); | ||
180 | SDL_FreeYUVOverlay(overlay); | ||
181 | return NULL; | ||
182 | } | ||
183 | |||
184 | overlay->hwdata = hwdata; | ||
185 | overlay->hwdata->display = display; | ||
186 | overlay->hwdata->bview = NULL; | ||
187 | overlay->hwdata->bbitmap = NULL; | ||
188 | overlay->hwdata->locked = 0; | ||
189 | |||
190 | /* Create the BBitmap framebuffer */ | ||
191 | bounds.top = 0; bounds.left = 0; | ||
192 | bounds.right = width-1; | ||
193 | bounds.bottom = height-1; | ||
194 | |||
195 | BView * bview = new BView(bounds,"overlay",B_FOLLOW_NONE,B_WILL_DRAW); | ||
196 | if (!bview) { | ||
197 | SDL_OutOfMemory(); | ||
198 | SDL_FreeYUVOverlay(overlay); | ||
199 | return NULL; | ||
200 | } | ||
201 | overlay->hwdata->bview = bview; | ||
202 | overlay->hwdata->first_display = true; | ||
203 | bview->Hide(); | ||
204 | |||
205 | bbitmap = BE_GetOverlayBitmap(bounds,cs); | ||
206 | if (!bbitmap) { | ||
207 | overlay->hwdata->bbitmap = NULL; | ||
208 | SDL_FreeYUVOverlay(overlay); | ||
209 | return NULL; | ||
210 | } | ||
211 | overlay->hwdata->bbitmap = bbitmap; | ||
212 | |||
213 | overlay->planes = planes; | ||
214 | overlay->pitches = (Uint16*)SDL_calloc(overlay->planes, sizeof(Uint16)); | ||
215 | overlay->pixels = (Uint8**)SDL_calloc(overlay->planes, sizeof(Uint8*)); | ||
216 | if (!overlay->pitches || !overlay->pixels) | ||
217 | { | ||
218 | SDL_OutOfMemory(); | ||
219 | SDL_FreeYUVOverlay(overlay); | ||
220 | return(NULL); | ||
221 | } | ||
222 | |||
223 | overlay->pitches[0] = bbitmap->BytesPerRow(); | ||
224 | overlay->pixels[0] = (Uint8 *)bbitmap->Bits(); | ||
225 | overlay->hw_overlay = 1; | ||
226 | |||
227 | if (SDL_Win->LockWithTimeout(1000000) != B_OK) { | ||
228 | SDL_FreeYUVOverlay(overlay); | ||
229 | return(NULL); | ||
230 | } | ||
231 | BView * view = SDL_Win->View(); | ||
232 | view->AddChild(bview); | ||
233 | rgb_color key; | ||
234 | bview->SetViewOverlay(bbitmap,bounds,bview->Bounds(),&key,B_FOLLOW_ALL, | ||
235 | B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL); | ||
236 | bview->SetViewColor(key); | ||
237 | bview->Flush(); | ||
238 | SDL_Win->Unlock(); | ||
239 | |||
240 | current_overlay=overlay; | ||
241 | |||
242 | return overlay; | ||
243 | } | ||
244 | |||
245 | int BE_LockYUVOverlay(_THIS, SDL_Overlay* overlay) | ||
246 | { | ||
247 | if (overlay == NULL) | ||
248 | { | ||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | overlay->hwdata->locked = 1; | ||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | void BE_UnlockYUVOverlay(_THIS, SDL_Overlay* overlay) | ||
257 | { | ||
258 | if (overlay == NULL) | ||
259 | { | ||
260 | return; | ||
261 | } | ||
262 | |||
263 | overlay->hwdata->locked = 0; | ||
264 | } | ||
265 | |||
266 | int BE_DisplayYUVOverlay(_THIS, SDL_Overlay* overlay, SDL_Rect* src, SDL_Rect *dst) | ||
267 | { | ||
268 | if ((overlay == NULL) || (overlay->hwdata==NULL) | ||
269 | || (overlay->hwdata->bview==NULL) || (SDL_Win->View() == NULL)) | ||
270 | { | ||
271 | return -1; | ||
272 | } | ||
273 | if (SDL_Win->LockWithTimeout(50000) != B_OK) { | ||
274 | return 0; | ||
275 | } | ||
276 | BView * bview = overlay->hwdata->bview; | ||
277 | if (SDL_Win->IsFullScreen()) { | ||
278 | int left,top; | ||
279 | SDL_Win->GetXYOffset(left,top); | ||
280 | bview->MoveTo(left+dst->x,top+dst->y); | ||
281 | } else { | ||
282 | bview->MoveTo(dst->x,dst->y); | ||
283 | } | ||
284 | bview->ResizeTo(dst->w,dst->h); | ||
285 | bview->Flush(); | ||
286 | if (overlay->hwdata->first_display) { | ||
287 | bview->Show(); | ||
288 | overlay->hwdata->first_display = false; | ||
289 | } | ||
290 | SDL_Win->Unlock(); | ||
291 | |||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | void BE_FreeYUVOverlay(_THIS, SDL_Overlay *overlay) | ||
296 | { | ||
297 | if (overlay == NULL) | ||
298 | { | ||
299 | return; | ||
300 | } | ||
301 | |||
302 | if (overlay->hwdata == NULL) | ||
303 | { | ||
304 | return; | ||
305 | } | ||
306 | |||
307 | current_overlay=NULL; | ||
308 | |||
309 | delete overlay->hwdata->bbitmap; | ||
310 | |||
311 | SDL_free(overlay->hwdata); | ||
312 | } | ||
313 | |||
314 | }; // extern "C" | ||
diff --git a/apps/plugins/sdl/src/video/bwindow/SDL_sysyuv.h b/apps/plugins/sdl/src/video/bwindow/SDL_sysyuv.h new file mode 100644 index 0000000000..fb5961c9d8 --- /dev/null +++ b/apps/plugins/sdl/src/video/bwindow/SDL_sysyuv.h | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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 | #include "SDL_config.h" | ||
23 | |||
24 | |||
25 | #ifndef __SDL_SYS_YUV_H__ | ||
26 | #define __SDL_SYS_YUV_H__ | ||
27 | |||
28 | /* This is the BeOS implementation of YUV video overlays */ | ||
29 | |||
30 | #include "SDL_video.h" | ||
31 | #include "SDL_lowvideo.h" | ||
32 | |||
33 | extern "C" { | ||
34 | |||
35 | struct private_yuvhwdata | ||
36 | { | ||
37 | /* FRAMEDATA* CurrentFrameData; | ||
38 | FRAMEDATA* FrameData0; | ||
39 | FRAMEDATA* FrameData1; | ||
40 | PgScalerProps_t props; | ||
41 | PgScalerCaps_t caps; | ||
42 | PgVideoChannel_t* channel; | ||
43 | PhArea_t CurrentViewPort; | ||
44 | PhPoint_t CurrentWindowPos; | ||
45 | long format; | ||
46 | int scaler_on; | ||
47 | int current; | ||
48 | long YStride; | ||
49 | long VStride; | ||
50 | long UStride; | ||
51 | int ischromakey; | ||
52 | long chromakey; | ||
53 | int forcedredraw; | ||
54 | unsigned long State; | ||
55 | long flags; | ||
56 | */ | ||
57 | SDL_Surface *display; | ||
58 | BView *bview; | ||
59 | bool first_display; | ||
60 | BBitmap *bbitmap; | ||
61 | int locked; | ||
62 | }; | ||
63 | |||
64 | extern BBitmap * BE_GetOverlayBitmap(BRect bounds, color_space cs); | ||
65 | extern SDL_Overlay* BE_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface* display); | ||
66 | extern int BE_LockYUVOverlay(_THIS, SDL_Overlay* overlay); | ||
67 | extern void BE_UnlockYUVOverlay(_THIS, SDL_Overlay* overlay); | ||
68 | extern int BE_DisplayYUVOverlay(_THIS, SDL_Overlay* overlay, SDL_Rect* src, SDL_Rect* dst); | ||
69 | extern void BE_FreeYUVOverlay(_THIS, SDL_Overlay* overlay); | ||
70 | |||
71 | }; | ||
72 | |||
73 | #endif /* __SDL_PH_YUV_H__ */ | ||