Gnash  0.8.11dev
movie_root.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 // 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
18 
19 
62 
63 
64 #ifndef GNASH_MOVIE_ROOT_H
65 #define GNASH_MOVIE_ROOT_H
66 
67 #ifdef HAVE_CONFIG_H
68 #include "gnashconfig.h" //USE_SWFTREE
69 #endif
70 
71 #include <map>
72 #include <string>
73 #include <vector>
74 #include <list>
75 #include <set>
76 #include <bitset>
77 #include <boost/array.hpp>
78 #include <boost/ptr_container/ptr_deque.hpp>
79 #include <boost/noncopyable.hpp>
80 #include <boost/any.hpp>
81 #include <boost/optional.hpp>
82 
83 #include "dsodefs.h" // DSOEXPORT
84 #include "DragState.h"
85 #include "MouseButtonState.h" // for composition
86 #include "GnashKey.h" // key::code
87 #include "GnashEnums.h"
88 #include "MovieClip.h"
89 #include "SimpleBuffer.h" // for LoadCallback
90 #include "MovieLoader.h"
91 #include "ExternalInterface.h"
92 #include "GC.h"
93 #include "VM.h"
94 #include "HostInterface.h"
95 #include "log.h"
96 
97 #ifdef USE_SWFTREE
98 # include "tree.hh"
99 #endif
100 
101 // GNASH_PARANOIA_LEVEL:
102 // 0 : (not unimplemented)
103 // 1 : quick assertions
104 // 2 : add testInvariant
105 //
106 #ifndef GNASH_PARANOIA_LEVEL
107 # define GNASH_PARANOIA_LEVEL 1
108 #endif
109 
110 // Forward declarations
111 namespace gnash {
112  class ExecutableCode;
113  class URL;
114  class Timer;
115  class MovieClip;
116  class VirtualClock;
117  class IOChannel;
118  class RunResources;
119  class Button;
120  class VM;
121  class Movie;
122 }
123 
124 namespace gnash {
125 
127 {
129  bool operator()(const LevelMovie& d1, const LevelMovie& d2) const {
130  return d1->get_depth() < d2->get_depth();
131  }
132 };
133 
135 //
140 //
143 //
148 //
150 class DSOEXPORT movie_root : public GcRoot, boost::noncopyable
151 {
152 public:
153 
154  class LoadCallback {
155  public:
156  LoadCallback(boost::shared_ptr<IOChannel> s, as_object* o)
157  :
158  _stream(s),
159  _obj(o)
160  {}
161  bool processLoad();
162  void setReachable() const;
163  private:
164  boost::shared_ptr<IOChannel> _stream;
166  as_object* _obj;
167  };
168  typedef std::list<LoadCallback> LoadCallbacks;
169 
170  typedef std::bitset<key::KEYCOUNT> Keys;
171 
173  //
176  movie_root(VirtualClock& clock, const RunResources& runResources);
177 
178  ~movie_root();
179 
181  //
183  //
189  Movie* init(movie_definition* def,
190  const MovieClip::MovieVariables& variables);
191 
193  //
197  MovieClip* getLevel(unsigned int num) const;
198 
200  //
205  void setLevel(unsigned int num, Movie* movie);
206 
208  //
216  void replaceLevel(unsigned int num, Movie* external_movie);
217 
219  //
232  void swapLevels(MovieClip* sp, int depth);
233 
235  //
243  void dropLevel(int depth);
244 
246  //
249  //
252  void setDimensions(size_t w, size_t h);
253 
255  size_t getStageWidth() const;
256 
258  size_t getStageHeight() const;
259 
261  //
270  DSOEXPORT bool mouseMoved(boost::int32_t x, boost::int32_t y);
271 
273  //
276  DSOEXPORT bool mouseClick(bool press);
277 
279  //
284  DSOEXPORT bool mouseWheel(int delta);
285 
287  //
291  DSOEXPORT bool keyEvent(key::code k, bool down);
292 
294  //
296  std::pair<boost::int32_t, boost::int32_t> mousePosition() const;
297 
298  void setDragState(const DragState& st);
299 
301  //
304  return *_rootMovie;
305  }
306 
307  void stop_drag() {
308  _dragState.reset();
309  }
310 
312  //
322  boost::uint32_t addIntervalTimer(std::auto_ptr<Timer> timer);
323 
325  //
329  //
331  //
334  //
337  //
340  void addLoadableObject(as_object* obj, std::auto_ptr<IOChannel> str);
341 
342  void addAdvanceCallback(ActiveRelay* obj);
343 
344  void removeAdvanceCallback(ActiveRelay* obj);
345 
347  //
349  bool clearIntervalTimer(boost::uint32_t x);
350 
351  void set_background_color(const rgba& color);
352 
353  void set_background_alpha(float alpha);
354 
356  VM& getVM() { return _vm; }
357 
360  //
364  bool advance();
365 
369  //
372  int timeToNextFrame() const;
373 
375  //
385  void advanceMovie();
386 
387  void display();
388 
391  return ++_unnamedInstance;
392  }
393 
395  void registerButton(Button* listener);
396 
398  void removeButton(Button* listener);
399 
401  //
407  DisplayObject* getFocus();
408 
410  //
416  bool setFocus(DisplayObject* to);
417 
418  DSOEXPORT void add_invalidated_bounds(InvalidatedRanges& ranges,
419  bool force);
420 
422  //
429  DisplayObject* getActiveEntityUnderPointer() const;
430 
432  //
436  const DisplayObject* getEntityUnderPointer() const;
437 
439  DisplayObject* getDraggingCharacter() const;
440 
441  bool testInvariant() const;
442 
446  DISPLAYSTATE_FULLSCREEN
447  };
448 
450  enum ScaleMode {
454  SCALEMODE_NOBORDER
455  };
456 
461  STAGE_H_ALIGN_R
462  };
463 
468  STAGE_V_ALIGN_B
469  };
470 
472  enum AlignMode {
476  STAGE_ALIGN_B
477  };
478 
483  SCRIPT_ACCESS_ALWAYS
484  };
485 
487  void setQuality(Quality q);
488 
490  Quality getQuality() const { return _quality; }
491 
494  void setStageAlignment(short s);
495 
498  void setAllowScriptAccess(AllowScriptAccessMode mode);
499 
501  AllowScriptAccessMode getAllowScriptAccess();
502 
503  typedef std::pair<StageHorizontalAlign, StageVerticalAlign> StageAlign;
504 
507  StageAlign getStageAlignment() const;
508 
511  bool getShowMenuState() const;
512 
515  void setShowMenuState(bool state);
516 
518  void setStageScaleMode(ScaleMode sm);
519 
521  ScaleMode getStageScaleMode() const { return _scaleMode; }
522 
523  // The string representation of the current align mode.
524  std::string getStageAlignMode() const;
525 
527  DisplayState getStageDisplayState() const { return _displayState; }
528 
529  // The string representation of the current align mode.
530  void setStageDisplayState(const DisplayState ds);
531 
541  PRIORITY_SIZE
542  };
543 
545  //
549  typedef boost::array<boost::ptr_deque<ExecutableCode>, PRIORITY_SIZE>
551 
553  void pushAction(std::auto_ptr<ExecutableCode> code, size_t lvl);
554 
556  void pushAction(const action_buffer& buf, DisplayObject* target);
557 
559  //
568  void markReachableResources() const;
569 
573  //
578  void addLiveChar(MovieClip* ch)
579  {
580  // Don't register the object in the list twice
581 #if GNASH_PARANOIA_LEVEL > 1
582  assert(std::find(_liveChars.begin(), _liveChars.end(), ch) ==
583  _liveChars.end());
584 #endif
585  _liveChars.push_front(ch);
586  }
587 
589  void reset();
590 
592  //
602  void disableScripts();
603 
605  bool scriptsDisabled() const { return _disableScripts; };
606 
609  //
615  void flushHigherPriorityActionQueues();
616 
617  DisplayObject* findCharacterByTarget(const std::string& tgtstr) const;
618 
620  //
624  //
636  void loadMovie(const std::string& url, const std::string& target,
637  const std::string& data, MovieClip::VariablesMethod method,
638  as_object* handler=0)
639  {
640  _movieLoader.loadMovie(url, target, data, method, handler);
641  }
642 
644  //
648  //
656  void getURL(const std::string& urlstr, const std::string& target,
657  const std::string& data, MovieClip::VariablesMethod method);
658 
659 
661  return _lastKeyEvent;
662  }
663 
664  const Keys& unreleasedKeys() const {
665  return _unreleasedKeys;
666  }
667 
669  //
673  void registerClass(const SWF::DefinitionTag* sprite, as_function* cls);
674 
676  //
680  as_function* getRegisteredClass(const SWF::DefinitionTag* sprite) const;
681 
684  void setHostFD(int fd) {
685  assert(fd >= 0);
686  _hostfd = fd;
687  }
688 
691  void setControlFD(int fd) {
692  _controlfd = fd;
693  }
694 
699  int getHostFD() const {
700  return _hostfd;
701  }
702 
703  int getControlFD() const {
704  return _controlfd;
705  }
706 
717  _fsCommandHandler = handler;
718  }
719 
721  DSOEXPORT void handleFsCommand(const std::string& cmd,
722  const std::string& arg) const;
723 
731  _interfaceHandler = handler;
732  }
733 
735  //
737  void callInterface(const HostInterface::Message& e) const;
738 
740  //
745  //
748  template<typename T> T callInterface(const HostInterface::Message& e) const;
749 
754  //
765  void setScriptLimits(boost::uint16_t recursion, boost::uint16_t timeout);
766 
769  boost::uint16_t getRecursionLimit() const {
770  return _recursionLimit;
771  }
772 
775  boost::uint16_t getTimeoutLimit() const
776  {
777  return _timeoutLimit;
778  }
779 
780 #ifdef USE_SWFTREE
781  typedef tree<std::pair<std::string, std::string> > InfoTree;
782  void getMovieInfo(InfoTree& tr, InfoTree::iterator it);
783  void getCharacterTree(InfoTree& tr, InfoTree::iterator it);
784 #endif
785 
786  const RunResources& runResources() const { return _runResources; }
787 
789  void addExternalCallback(const std::string& name, as_object* callback);
790 
791  bool processInvoke(ExternalInterface::invoke_t *);
792 
793  std::string callExternalCallback(const std::string &name,
794  const std::vector<as_value>& args);
795 
796  std::string callExternalJavascript(const std::string &name,
797  const std::vector<as_value>& args);
798 
800  //
805  void removeQueuedConstructor(MovieClip* target);
806 
807  GC& gc() {
808  return _gc;
809  }
810 
812  //
815  bool queryInterface(const std::string& what) const;
816 
818  //
822  //
828  void setStreamBlock(int id, int block);
829 
831  //
834  //
836  void stopStream(int id);
837 
838 private:
839 
841  //
863  void setRootMovie(Movie* movie);
864 
866  bool notify_mouse_listeners(const event_id& event);
867 
871  bool fire_mouse_event();
872 
874  void doMouseDrag();
875 
877  void executeAdvanceCallbacks();
878 
880  void executeTimers();
881 
883  void cleanupAndCollect();
884 
888  //
900  InteractiveObject* getTopmostMouseEntity(boost::int32_t x,
901  boost::int32_t y) const;
902 
905  void cleanupDisplayList();
906 
908  void advanceLiveChars();
909 
913  void setInvalidated() { _invalidated = true; }
914 
916  //
919  void clearInvalidated() { _invalidated = false; }
920 
922  //
929  bool isInvalidated() { return _invalidated; }
930 
932  //
935  size_t minPopulatedPriorityQueue() const;
936 
940  size_t processActionQueue(size_t lvl);
941 
942  bool processingActions() const {
943  return (_processingActionLevel < PRIORITY_SIZE);
944  }
945 
946  const DisplayObject* findDropTarget(boost::int32_t x, boost::int32_t y,
947  DisplayObject* dragging) const;
948 
949  void handleActionLimitHit(const std::string& ref);
950 
951  typedef std::list<Button*> ButtonListeners;
952  ButtonListeners _buttonListeners;
953 
954  GC _gc;
955 
956  const RunResources& _runResources;
957 
960  VM _vm;
961 
963  HostInterface* _interfaceHandler;
964 
966  FsCallback* _fsCommandHandler;
967 
969  //
974  typedef std::list<MovieClip*> LiveChars;
975 
977  LiveChars _liveChars;
978 
979  ActionQueue _actionQueue;
980 
982  void processActionQueue();
983 
985  size_t _stageWidth;
986  size_t _stageHeight;
987 
988  rgba m_background_color;
989  bool m_background_color_set;
990 
991  boost::int32_t _mouseX;
992  boost::int32_t _mouseY;
993 
994  MouseButtonState _mouseButtonState;
995 
997  typedef std::set<ActiveRelay*> ObjectCallbacks;
998  ObjectCallbacks _objectCallbacks;
999 
1000  LoadCallbacks _loadCallbacks;
1001 
1002  typedef std::map<boost::uint32_t, boost::shared_ptr<Timer> > TimerMap;
1003 
1004  TimerMap _intervalTimers;
1005 
1006  size_t _lastTimerId;
1007 
1009  Keys _unreleasedKeys;
1010 
1011  key::code _lastKeyEvent;
1012 
1014  DisplayObject* _currentFocus;
1015 
1017  boost::optional<DragState> _dragState;
1018 
1019  typedef std::map<int, MovieClip*> Levels;
1020 
1022  //
1026  Levels _movies;
1027 
1028  typedef std::map<const SWF::DefinitionTag*, as_function*> RegisteredClasses;
1029  RegisteredClasses _registeredClasses;
1030 
1034  Movie* _rootMovie;
1035 
1037  bool _invalidated;
1038 
1041  bool _disableScripts;
1042  int _processingActionLevel;
1043 
1045  //
1047  int _hostfd;
1048  int _controlfd;
1049 
1051  //
1054  Quality _quality;
1055 
1057  std::bitset<4u> _alignMode;
1058 
1059  AllowScriptAccessMode _allowScriptAccess;
1060 
1062  bool _showMenu;
1063 
1065  ScaleMode _scaleMode;
1066 
1068  DisplayState _displayState;
1069 
1070  // Maximum number of recursions set in the ScriptLimits tag.
1071  boost::uint16_t _recursionLimit;
1072 
1073  // Timeout in seconds for script execution, set in the ScriptLimits tag.
1074  boost::uint16_t _timeoutLimit;
1075 
1076  // delay between movie advancement, in milliseconds
1077  size_t _movieAdvancementDelay;
1078 
1079  // time of last movie advancement, in milliseconds
1080  size_t _lastMovieAdvancement;
1081 
1083  size_t _unnamedInstance;
1084 
1085  MovieLoader _movieLoader;
1086 
1087  struct SoundStream {
1088  SoundStream(int i, int b) : id(i), block(b) {}
1089  int id;
1090  int block;
1091  };
1092 
1093  boost::optional<SoundStream> _timelineSound;
1094 };
1095 
1097 //
1105 bool isLevelTarget(int version, const std::string& name, unsigned int& levelno);
1106 
1107 DSOEXPORT short stringToStageAlign(const std::string& s);
1108 
1109 template<typename T>
1110 T
1112 {
1113  if (!_interfaceHandler) {
1114  log_error("Hosting application registered no callback for "
1115  "messages, can't call %s(%s)");
1116  return T();
1117  }
1118 
1119  try {
1120  return boost::any_cast<T>(_interfaceHandler->call(e));
1121  }
1122  catch (const boost::bad_any_cast&) {
1123  log_error(_("Unexpected type from host interface when requesting "
1124  "%1%"), e);
1125  return T();
1126  }
1127 }
1128 
1129 } // namespace gnash
1130 
1131 #endif // GNASH_MOVIE_ROOT_H
1132 
1133 // Local Variables:
1134 // mode: C++
1135 // indent-tabs-mode: nil
1136 // End: