big merge from master, fix rpm creation, drop fetching swfdec
[gnash.git] / gui / gui.h
bloba2beb827263db30636b5ab29523a3b7b3bd58d4e
1 //
2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
3 // 2011 Free Software Foundation, Inc
4 //
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.
9 //
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.
14 //
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
19 #ifndef GNASH_GUI_H
20 #define GNASH_GUI_H
22 #ifdef HAVE_CONFIG_H
23 #include "gnashconfig.h"
24 #endif
26 #include <boost/intrusive_ptr.hpp>
27 #include <boost/scoped_ptr.hpp>
28 #include <boost/function.hpp>
29 #include <string>
30 #include <map>
31 #include <utility>
33 #include "SWFRect.h" // for composition
34 #include "snappingrange.h" // for InvalidatedRanges
35 #include "ScreenShotter.h"
36 #include "GnashKey.h"
37 #include "Renderer.h"
38 #include "VirtualClock.h"
39 #include "SystemClock.h"
40 #include "GnashEnums.h"
41 #include "movie_root.h"
43 #ifdef USE_SWFTREE
44 #include "tree.hh" // for tree
45 #endif
47 // Define this to enable fps debugging without touching
48 // gnashconfig.h
49 //#define GNASH_FPS_DEBUG
51 /// Define this to disable region updates debugging altogether. If undefined,
52 /// debugging will be a runtime option. The flag and flag-setting functions
53 /// will not be disabled (too ugly).
54 ///
55 /// This should go in gnashconfig.h
56 ///
57 /// This has the side effect that all frames will be re-rendered completely
58 /// but in contrast to FORCE_REDRAW it won't re-render when no motion
59 /// has been detected in the movie (for example when the movie is stopped).
60 ///
61 //#define DISABLE_REGION_UPDATES_DEBUGGING 1
64 /// Define this to support keyboard-based pointer movements
65 #define ENABLE_KEYBOARD_MOUSE_MOVEMENTS 1
67 // Forward declarations
68 namespace gnash {
69 class SWFRect;
70 class ScreenShotter;
71 class RunResources;
72 class movie_root;
73 class movie_definition;
76 namespace gnash {
78 /// Enumerates mouse cursor types.
79 enum gnash_cursor_type {
80 CURSOR_HAND,
81 CURSOR_NORMAL,
82 CURSOR_INPUT
85 /// Parent class from which all GUI implementations will depend.
86 class Gui {
88 public:
90 virtual ~Gui();
92 /** \brief
93 * Initialise the gui and the associated renderer.
95 * @param argc The commandline argument count.
96 * @param argv The commandline arguments.
97 * @return True on success; false on failure.
99 virtual bool init(int argc, char **argv[]) = 0;
101 /// Set main loop delay in milliseconds.
102 virtual void setInterval(unsigned int interval) {
103 _interval = interval;
106 /// Instructs the Gui to monitor a file descriptor.
108 /// @param fd The file descriptor to monitor
109 /// @param callback The callback to fire
110 void setFDCallback(int fd, boost::function<void ()> callback);
112 /// Calls the callback function registered for a file descriptor.
114 /// @param fd The file descriptor for which the registered callback should
115 /// be fired.
116 void callCallback(int fd);
118 /// Return the clock provided by this Gui.
120 /// The Gui clock will be paused when the gui is put
121 /// in pause mode and resumed when gui playback is resumed.
123 virtual VirtualClock& getClock() { return _virtualClock; }
125 /// Set the time in milliseconds after which the programme should exit.
126 virtual void setTimeout(unsigned int timeout) = 0;
128 void setScreenShotter(std::auto_ptr<ScreenShotter> ss);
130 /** \brief
131 * Create and display our window.
133 * @param title The window title.
134 * @param width The desired window width in pixels.
135 * @param height The desired window height in pixels.
136 * @param xPosition The desired window X position from the top left corner.
137 * @param yPosition The desired window Y position from the top left corner.
139 virtual bool createWindow(const char* title, int width, int height,
140 int xPosition = 0, int yPosition = 0) = 0;
142 virtual void resizeWindow(int width, int height);
144 /// Start main rendering loop.
145 virtual bool run() = 0;
147 /// Always called on exit.
149 /// Handles any common functions, then calls virtual quitUI().
150 void quit();
152 /// Render the current buffer.
153 /// For OpenGL, this means that the front and back buffers are swapped.
154 virtual void renderBuffer() = 0;
156 /// Gives the GUI a *hint* which region of the stage should be redrawn.
158 /// There is *no* restriction what the GUI might do with these coordinates.
159 /// Normally the GUI forwards the information to the renderer so that
160 /// it avoids rendering regions that did not change anyway. The GUI can
161 /// also alter the bounds before passing them to the renderer and it's
162 /// absolutely legal for the GUI to simply ignore the call.
164 /// Coordinates are in TWIPS!
166 /// Note this information is given to the GUI and not directly to the
167 /// renderer because both of them need to support this feature for
168 /// correct results. It is up to the GUI to forward this information to
169 /// the renderer.
171 // does not need to be implemented (optional feature),
172 // but still needs to be available.
174 virtual void setInvalidatedRegion(const SWFRect& bounds);
175 virtual void setInvalidatedRegions(const InvalidatedRanges& ranges);
177 // Called right before rendering anything (after setInvalidatedRegion).
178 // Used by GTK-AGG.
179 virtual void beforeRendering() { /* nop */ };
181 // Should return TRUE when the GUI/Renderer combination supports multiple
182 // invalidated bounds regions.
183 virtual bool want_multiple_regions() { return false; }
185 /// Asks the GUI handler if the next frame should be redrawn completely.
187 /// For example, when the contents of the player window have been destroyed,
188 /// then want_redraw() should return true so that setInvalidatedRegion() is
189 /// called with the coordinates of the complete screen.
190 virtual bool want_redraw();
192 /// Sets the current mouse cursor for the Gui window.
193 virtual void setCursor(gnash_cursor_type newcursor);
195 virtual void setClipboard(const std::string& copy);
197 // Information for System.capabilities to be reimplemented in
198 // each gui.
199 virtual double getPixelAspectRatio() const { return 0; }
201 virtual std::pair<int, int> screenResolution() const {
202 return std::make_pair(0, 0);
205 virtual double getScreenDPI() const { return 0; }
207 /// Get the screen color type.
209 /// The choice is between "color" and something designating
210 /// monochrome (not sure what). If this isn't implemented in the
211 /// gui we return "color".
212 virtual std::string getScreenColor() const {
213 return "color";
216 /// @return Whether or not the movie should be looped indefinitely.
217 bool loops() const { return _loop; }
219 /// @return Whether the movie is running fullscreen or not.
220 bool isFullscreen() const { return _fullscreen; }
222 /// Mouse notification callback to be called when the mouse is moved.
224 /// @param x The mouse coordinate X component in user/window
225 /// coordinate space (pixels).
226 /// @param y The mouse coordinate Y component in user/window
227 /// coordinate space (pixels).
228 void notifyMouseMove(int x, int y);
230 /// Mouse notification callback to be called when the mouse is clicked.
232 /// @param mouse_pressed Determines whether the mouse button is being
233 /// pressed (true) or being released (false)
234 void notifyMouseClick(bool mouse_pressed);
236 /// Send a mouse wheel event to the stage.
238 /// @param delta A number expressing the extent of the wheel scroll.
239 void notifyMouseWheel(int delta);
241 /// Key event notification to be called when a key is pressed or depressed
243 /// @param k The key code.
244 /// @param modifier
245 /// Modifier key identifiers from gnash::key::modifier ORed together
246 /// @param pressed
247 /// Determines whether the key is being pressed (true)
248 /// or being released (false)
250 void notify_key_event(gnash::key::code k, int modifier, bool pressed);
252 /// Resize the client area view and the window accordingly.
254 /// @param width The desired width in pixels.
255 /// @param height The desired height in pixels.
256 void resize_view(int width, int height);
258 /// Update stage SWFMatrix accordingly to window size and flash Stage
259 /// configuration (scaleMode, alignment)
261 /// This method should be called from the core lib when Stage configuration
262 /// change or is called by resize_view.
264 void updateStageMatrix();
266 /// \brief
267 /// Give movie an heart-beat.
269 /// This is to take place after the
270 /// interval specified in the call to setInterval().
272 /// Wheter or not this beat advanced the movie to the next frame
273 /// depends on elapsed time since last advancement.
275 /// @return true if this beat resulted in actual frame advancement.
277 bool advanceMovie(bool doDisplay = true);
279 /// Convenience static wrapper around advanceMovie for callbacks happiness.
281 /// NOTE: this function always return TRUE, for historical reasons.
282 /// TODO: bring code up-to-date to drop this legacy return code..
283 ///
284 static bool advance_movie(Gui* gui) {
285 gui->advanceMovie();
286 return true;
289 /// Force immediate redraw
291 void refreshView();
293 /// Attempt to run in a fullscreen window both for plugin and
294 /// standalone player.
296 /// Use isFullscreen() to see if gnash thinks
297 /// it's running in fullscreen or not. The switch to fullscreen may
298 /// fail if, for instance, the window manager refuses to allow it, but
299 /// the flag will be set anyway.
300 virtual void setFullscreen();
302 /// Return from fullscreen to normal mode.
304 virtual void unsetFullscreen();
306 /// Hide the menu bar when using standalone player
308 virtual void hideMenu();
310 /// Sets whether the gui should show the system mouse pointer
312 /// @param show true if the mouse should be shown.
313 /// @return true if the state changed.
314 virtual bool showMouse(bool show);
316 /// Sets whether the menus should be shown (for fscommand)
318 /// @param show true if the menu bar should be shown.
319 virtual void showMenu(bool show);
321 /// Sets whether scaling should be allowed (for fscommand)
323 /// @param allow true if stage scaling should be allowed
324 virtual void allowScale(bool allow);
326 // Toggle between fullscreen and normal mode
327 void toggleFullscreen();
329 /// Put the application in "stop" mode
331 /// When in stop mode the application won't be advanced.
333 void stop();
335 /// Put the application in "play" mode
337 /// When in play mode the application will be advanced as usual.
339 void play();
341 /// Toggle between "stop" and "play" mode
343 /// See stop() and play()
345 void pause();
347 /// Start the movie
349 /// This function will create an instance of the registered top-level
350 /// movie definition, set variables into it and place it to the stage.
352 void start();
354 /// See stop(), play() and pause()
355 bool isStopped() const { return _stopped; }
357 /// Whether gnash is is running as a plugin
358 bool isPlugin() const { return ((_xid)); }
360 /// Take a screenshot now!
361 void takeScreenShot();
363 /// Set the maximum number of frame advances before Gnash exits.
364 void setMaxAdvances(unsigned long ul) { if (ul) _maxAdvances = ul; }
366 void showUpdatedRegions(bool x) { _showUpdatedRegions = x; }
367 bool showUpdatedRegions() const { return _showUpdatedRegions; }
369 /// Instruct the core to restart the movie and
370 /// set state to play(). This does not change pause
371 /// state.
372 void restart();
374 /// Set rendering quality, if not locked by RC file..
375 void setQuality(Quality q);
377 /// Get current rendering quality
378 Quality getQuality() const;
380 /// Toggle sound state between muted and unmuted. If
381 /// there is no active sound handler this does nothing.
382 void toggleSound();
384 #ifdef GNASH_FPS_DEBUG
385 /// Set the interval between FPS debugging prints
387 /// See fpsCounterTick()
389 void setFpsTimerInterval(float interval)
391 assert(interval >= 0.0);
392 fps_timer_interval = interval;
394 #endif // def GNASH_FPS_DEBUG
397 #ifdef USE_SWFTREE
398 /// Return a tree containing information about the movie playing.
399 std::auto_ptr<movie_root::InfoTree> getMovieInfo() const;
400 #endif
402 typedef std::map<std::string, std::string> VariableMap;
404 /// Add variables to set into instances of the top-level movie definition
405 void addFlashVars(VariableMap& vars);
407 /// Set the definition of top-level movie
408 void setMovieDefinition(movie_definition* md);
410 /// Set the stage to advance/display
411 void setStage(movie_root* stage);
413 /// Set the name of a file to dump audio to
414 void setAudioDump(const std::string& fname) {
415 _audioDump = fname;
418 /// The root movie, or "Stage"
419 movie_root* getStage() { return _stage; };
421 /// Handle error message from the core
423 /// @param msg The error message recieved
425 virtual void error(const std::string& /*msg*/) {}
427 /// Prompt user with a question she can answer with yes/no
429 /// @param question
430 /// The question to ask user
432 /// @return
433 /// true for YES, false for NO
435 /// The default implementation always returns true.
437 virtual bool yesno(const std::string& question);
439 /// Width of a window pixel, in stage pseudopixel units.
440 float getXScale() const { return _xscale; };
442 /// Height of a window pixel, in stage pseudopixel units.
443 float getYScale() const { return _yscale; };
445 protected:
447 /// Default constructor. Initialises members to safe defaults.
448 Gui(RunResources& r);
450 /** \brief
451 * Expanded constructor for more control over member values.
453 * @param xid The X11 Window ID to attach to. If this is argument is zero,
454 * a new window is created.
456 * @param scale The scale used to resize the window size, which has been
457 * established by extracting information from the SWF file.
459 * @param loop Defines whether or not the movie should be played once or
460 * looped indefinitely.
462 * @param depth Colour depth to be used in the client area of our window.
464 Gui(unsigned long xid, float scale, bool loop, RunResources& r);
466 /// End main rendering loop calling GUI-specific exit functions.
468 /// Do not call this directly. Call quit() instead.
470 /// The default implementation calls exit(EXIT_SUCCESS), which isn't nice.
471 /// Please implement the proper main loop quitter in the subclasses.
472 virtual void quitUI() {
473 std::exit(EXIT_SUCCESS);
476 /// Watch a file descriptor.
478 /// An implementing Gui should monitor the file descriptor in its main
479 /// loop. When the file descriptor is triggered, the implementation should
480 /// call callCallback().
482 /// @param fd The file descriptor to be watched
483 virtual bool watchFD(int /* fd */)
485 log_unimpl("This GUI does not implement FD watching.");
486 return false;
490 /// Determines if playback should restart after the movie ends.
491 bool _loop;
493 /// The X Window ID to attach to. If zero, we create a new window.
494 unsigned long _xid;
496 // This would be 0,0,_width,_height, so maybe
497 // we should not duplicate the info with those
498 // explicit values too..
499 geometry::Range2d<int> _validbounds;
501 /// Desired window width.
502 int _width;
504 /// Desired window height.
505 int _height;
507 /// Per-run resources
508 RunResources& _runResources;
510 /// Main loop interval: the time between successive advance_movie calls.
511 unsigned int _interval;
513 /// The handler which is called to update the client area of our window.
514 boost::shared_ptr<Renderer> _renderer;
516 /// Signals that the next frame must be re-rendered completely because the
517 /// window size did change.
518 bool _redraw_flag;
520 // True if Gnash is running in fullscreen
521 bool _fullscreen;
523 // True if mouse pointer is showing
524 bool _mouseShown;
526 // Maximum number of advances before exit; 0 for no limit.
527 unsigned long _maxAdvances;
529 /// Counter to keep track of frame advances
530 unsigned long _advances;
532 /// Name of a file to dump audio to
533 std::string _audioDump;
535 /// Called by Gui::stop(). This can be used by GUIs to implement pause
536 /// widgets (so that resuming a stopped animation is more user-friendly)
537 virtual void stopHook() {}
539 /// Called by Gui::play().
540 virtual void playHook() {}
542 /// Determines whether the Gui is visible (not obscured).
543 virtual bool visible() { return true; }
544 private:
546 struct Display;
548 std::map<int /* fd */, boost::function<void ()> > _fd_callbacks;
550 /// Width of a window pixel, in stage pseudopixel units.
551 float _xscale;
553 /// Height of a window pixel, in stage pseudopixel units.
554 float _yscale;
556 /// Window pixel X offset of stage origin
557 boost::int32_t _xoffset;
559 /// Window pixel Y offset of stage origin
560 boost::int32_t _yoffset;
562 bool display(movie_root* m);
564 #ifdef GNASH_FPS_DEBUG
565 unsigned int fps_counter;
567 float fps_rate_min, fps_rate_max;
569 // Number of calls to fpsCounterTick, which is also
570 // the number of calls to movie_advance()
571 unsigned int fps_counter_total;
573 boost::uint64_t fps_timer, fps_start_timer;
575 /// The time, in seconds, between prints (which also resets the fps counter).
577 /// interval must be >= 0
579 float fps_timer_interval;
581 /// Number of frames rendering of which was dropped
582 unsigned int frames_dropped;
584 /// \brief
585 /// Should be called on every frame advance (including inter-frames caused
586 /// by mouse events).
588 /// Based on fps-timer_interval. See setFpsTimerInterval.
590 void fpsCounterTick();
592 #endif // def GNASH_FPS_DEBUG
594 VariableMap _flashVars;
596 boost::intrusive_ptr<movie_definition> _movieDef;
598 /// The root movie, or "Stage"
599 movie_root* _stage;
601 /// True if the application has been put into "stop" mode
602 bool _stopped;
604 /// True if the application didn't start yet
605 bool _started;
607 /// If true, updated regions (invalidated ranges) are visibly outlined.
608 bool _showUpdatedRegions;
610 SystemClock _systemClock;
611 InterruptableVirtualClock _virtualClock;
613 /// Checked on each advance for screenshot activity if it exists.
614 boost::scoped_ptr<ScreenShotter> _screenShotter;
616 #ifdef ENABLE_KEYBOARD_MOUSE_MOVEMENTS
617 int _xpointer;
618 int _ypointer;
619 bool _keyboardMouseMovements;
620 int _keyboardMouseMovementsStep;
621 #endif // ENABLE_KEYBOARD_MOUSE_MOVEMENTS
624 /// Named constructors
625 std::auto_ptr<Gui> createGTKGui(unsigned long xid, float scale, bool loop, RunResources& r);
626 std::auto_ptr<Gui> createKDEGui(unsigned long xid, float scale, bool loop, RunResources& r);
627 std::auto_ptr<Gui> createKDE4Gui(unsigned long xid, float scale, bool loop, RunResources& r);
628 std::auto_ptr<Gui> createSDLGui(unsigned long xid, float scale, bool loop, RunResources& r);
629 std::auto_ptr<Gui> createFLTKGui(unsigned long xid, float scale, bool loop, RunResources& r);
630 std::auto_ptr<Gui> createFBGui(unsigned long xid, float scale, bool loop, RunResources& r);
631 std::auto_ptr<Gui> createAQUAGui(unsigned long xid, float scale, bool loop, RunResources& r);
632 std::auto_ptr<Gui> createRISCOSGui(unsigned long xid, float scale, bool loop, RunResources& r);
633 std::auto_ptr<Gui> createAOS4Gui(unsigned long xid, float scale, bool loop, RunResources& r);
634 std::auto_ptr<Gui> createHaikuGui(unsigned long xid, float scale, bool loop, RunResources& r);
635 std::auto_ptr<Gui> createDumpGui(unsigned long xid, float scale, bool loop, RunResources& r);
638 } // end of gnash namespace
640 // end of _GUI_H_
641 #endif
643 // Local Variables:
644 // mode: C++
645 // indent-tabs-mode: nil
646 // End: