2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
10 // This program 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
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "gnashconfig.h"
28 #include "Range2d.h" // for Intersection of inv bounds
29 #include "Renderer.h" // for setInvalidatedRegions
30 #include "RunResources.h"
37 SDLGui::SDLGui(unsigned long xid
, float scale
, bool loop
, RunResources
& r
)
38 : Gui(xid
, scale
, loop
, r
),
53 int button_state_old
= -1;
55 Uint32 movie_time
= 0;// SDL_GetTicks(); // what time it should be in the movie
60 if (_timeout
&& SDL_GetTicks() >= _timeout
)
65 while (SDL_PollEvent(&event
))
70 // SDL can generate MOUSEMOTION events even without mouse movement
71 if (event
.motion
.x
== x_old
&& event
.motion
.y
== y_old
) { break; }
72 x_old
= event
.motion
.x
;
73 y_old
= event
.motion
.y
;
74 notifyMouseMove(x_old
, y_old
);
77 case SDL_MOUSEBUTTONDOWN
:
78 case SDL_MOUSEBUTTONUP
:
80 if (event
.button
.state
== SDL_PRESSED
) {
81 // multiple events will be fired while the mouse is held down
82 // we are interested only in a change in the mouse state:
83 if (event
.button
.button
== button_state_old
) { break; }
84 notifyMouseClick(true);
85 button_state_old
= event
.button
.button
;
87 notifyMouseClick(false);
88 button_state_old
= -1;
94 if (event
.key
.keysym
.sym
== SDLK_ESCAPE
)
98 key_event(&event
.key
, true);
103 key_event(&event
.key
, false);
106 case SDL_VIDEORESIZE
:
110 case SDL_VIDEOEXPOSE
:
120 // Wait until real time catches up with movie time.
121 int delay
= movie_time
- SDL_GetTicks();
127 Gui::advance_movie(this);
128 movie_time
+= _interval
; // Time next frame should be displayed
135 SDLGui::setTimeout(unsigned int timeout
)
141 SDLGui::init(int argc
, char **argv
[])
147 char SDL_windowhack
[32];
148 snprintf (SDL_windowhack
, sizeof(SDL_windowhack
), "SDL_WINDOWID=%ld", _xid
);
149 putenv (SDL_windowhack
);
152 // Initialize the SDL subsystems we're using. Linux
153 // and Darwin use Pthreads for SDL threads, Win32
154 // doesn't. Otherwise the SDL event loop just polls.
155 if (SDL_Init(SDL_INIT_VIDEO
)) {
156 fprintf(stderr
, "Unable to init SDL: %s\n", SDL_GetError());
162 SDL_EnableKeyRepeat(250, 33);
164 _glue
.init(argc
, argv
);
166 _renderer
.reset(_glue
.createRenderHandler(32));
167 if ( ! _renderer
) return false;
174 SDLGui::createWindow(const char *title
, int width
, int height
,
175 int /*xPosition*/, int /*yPosition*/)
180 boost::uint32_t sdl_flags
= 0;
183 sdl_flags
|= SDL_INIT_NOPARACHUTE
;
187 sdl_flags
|= SDL_NOFRAME
;
190 _glue
.prepDrawingArea(_width
, _height
, sdl_flags
);
192 _runResources
.setRenderer(_renderer
);
194 SDL_WM_SetCaption( title
, title
);
200 SDLGui::disableCoreTrap()
205 /* public, overridden */
207 SDLGui::setInvalidatedRegions(const InvalidatedRanges
& ranges
)
209 _glue
.setInvalidatedRegions(ranges
);
213 SDLGui::renderBuffer()
219 SDLGui::setInterval(unsigned int interval
)
221 _interval
= interval
;
231 SDLGui::setupEvents()
237 SDLGui::sdl_to_gnash_key(SDL_KeyboardEvent
* key
)
239 gnash::key::code
c(gnash::key::INVALID
);
241 // TODO: take care of CAPS_LOCK and NUM_LOCK and SHIFT
242 // int mod = key->keysym.mod;
243 int code
= key
->keysym
.sym
;
245 if(code
>= 32 && code
<= 127) {
246 c
= (gnash::key::code
)(code
);
247 }else if(code
>= SDLK_KP0
&& code
<= SDLK_KP9
) {
248 c
= (gnash::key::code
)(code
- SDLK_KP0
+ gnash::key::KP_0
);
249 }else if(code
>= SDLK_F1
&& code
<= SDLK_F15
) {
250 c
= (gnash::key::code
)(code
- SDLK_F1
+ gnash::key::F1
);
254 case SDLK_UP
: c
= gnash::key::UP
; break;
255 case SDLK_DOWN
: c
= gnash::key::DOWN
; break;
256 case SDLK_RIGHT
: c
= gnash::key::RIGHT
; break;
257 case SDLK_LEFT
: c
= gnash::key::LEFT
; break;
258 case SDLK_INSERT
: c
= gnash::key::INSERT
; break;
259 case SDLK_HOME
: c
= gnash::key::HOME
; break;
260 case SDLK_END
: c
= gnash::key::END
; break;
261 case SDLK_PAGEUP
: c
= gnash::key::PGUP
; break;
262 case SDLK_PAGEDOWN
: c
= gnash::key::PGDN
; break;
264 case SDLK_LSHIFT
: c
= gnash::key::SHIFT
; break;
266 case SDLK_LCTRL
: c
= gnash::key::CONTROL
; break;
268 case SDLK_LALT
: c
= gnash::key::ALT
; break;
269 default: c
= gnash::key::INVALID
; break;
277 SDLGui::sdl_to_gnash_modifier(int state
)
279 int modifier
= gnash::key::GNASH_MOD_NONE
;
281 if (state
& KMOD_SHIFT
) {
282 modifier
= modifier
| gnash::key::GNASH_MOD_SHIFT
;
284 if (state
& KMOD_CTRL
) {
285 modifier
= modifier
| gnash::key::GNASH_MOD_CONTROL
;
287 if (state
& KMOD_ALT
) {
288 modifier
= modifier
| gnash::key::GNASH_MOD_ALT
;
294 void SDLGui::key_event(SDL_KeyboardEvent
* key
, bool down
)
295 // For forwarding SDL key events.
297 gnash::key::code c
= sdl_to_gnash_key(key
);
299 if (c
!= gnash::key::INVALID
)
301 int mod
= sdl_to_gnash_modifier(key
->keysym
.mod
);
303 notify_key_event(c
, mod
, down
);
308 SDLGui::resize_event()
310 log_debug("got resize_event ");
314 SDLGui::expose_event()
316 // TODO: implement and use setInvalidatedRegion instead?