Gnash 0.8.10dev
|
00001 // 00002 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 00003 // 2011 Free Software Foundation, Inc 00004 // 00005 // This program is free software; you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation; either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with this program; if not, write to the Free Software 00017 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 00019 00062 00063 00064 #ifndef GNASH_MOVIE_ROOT_H 00065 #define GNASH_MOVIE_ROOT_H 00066 00067 #ifdef HAVE_CONFIG_H 00068 #include "gnashconfig.h" //USE_SWFTREE 00069 #endif 00070 00071 #include <map> 00072 #include <string> 00073 #include <vector> 00074 #include <list> 00075 #include <set> 00076 #include <bitset> 00077 #include <boost/array.hpp> 00078 #include <boost/ptr_container/ptr_deque.hpp> 00079 #include <boost/noncopyable.hpp> 00080 #include <boost/any.hpp> 00081 00082 #include "dsodefs.h" // DSOEXPORT 00083 #include "MouseButtonState.h" // for composition 00084 #include "DragState.h" // for composition 00085 #include "GnashKey.h" // key::code 00086 #include "Movie.h" 00087 #include "GnashEnums.h" 00088 #include "MovieClip.h" 00089 #include "SimpleBuffer.h" // for LoadCallback 00090 #include "MovieLoader.h" 00091 #include "ExternalInterface.h" 00092 #include "GC.h" 00093 #include "VM.h" 00094 #include "HostInterface.h" 00095 #include "log.h" 00096 00097 #ifdef USE_SWFTREE 00098 # include "tree.hh" 00099 #endif 00100 00101 // GNASH_PARANOIA_LEVEL: 00102 // 0 : (not unimplemented) 00103 // 1 : quick assertions 00104 // 2 : add testInvariant 00105 // 00106 #ifndef GNASH_PARANOIA_LEVEL 00107 # define GNASH_PARANOIA_LEVEL 1 00108 #endif 00109 00110 // Forward declarations 00111 namespace gnash { 00112 class ExecutableCode; 00113 class URL; 00114 class Timer; 00115 class MovieClip; 00116 class VirtualClock; 00117 class IOChannel; 00118 class RunResources; 00119 class Button; 00120 class VM; 00121 } 00122 00123 namespace gnash { 00124 00125 struct DepthComparator 00126 { 00127 typedef MovieClip* LevelMovie; 00128 bool operator()(const LevelMovie& d1, const LevelMovie& d2) const { 00129 return d1->get_depth() < d2->get_depth(); 00130 } 00131 }; 00132 00134 // 00139 // 00142 // 00147 // 00149 class DSOEXPORT movie_root : public GcRoot, boost::noncopyable 00150 { 00151 public: 00152 00154 typedef std::list<Button*> Listeners; 00155 00156 class LoadCallback { 00157 public: 00158 LoadCallback(boost::shared_ptr<IOChannel> s, as_object* o) 00159 : 00160 _stream(s), 00161 _obj(o) 00162 {} 00163 bool processLoad(); 00164 void setReachable() const; 00165 private: 00166 boost::shared_ptr<IOChannel> _stream; 00167 SimpleBuffer _buf; 00168 as_object* _obj; 00169 }; 00170 typedef std::list<LoadCallback> LoadCallbacks; 00171 00172 typedef std::bitset<key::KEYCOUNT> Keys; 00173 00175 // 00178 movie_root(VirtualClock& clock, const RunResources& runResources); 00179 00180 ~movie_root(); 00181 00183 // 00185 // 00191 Movie* init(movie_definition* def, 00192 const MovieClip::MovieVariables& variables); 00193 00195 // 00199 MovieClip* getLevel(unsigned int num) const; 00200 00202 // 00207 void setLevel(unsigned int num, Movie* movie); 00208 00210 // 00218 void replaceLevel(unsigned int num, Movie* external_movie); 00219 00221 // 00234 void swapLevels(MovieClip* sp, int depth); 00235 00237 // 00245 void dropLevel(int depth); 00246 00248 // 00251 // 00254 void setDimensions(size_t w, size_t h); 00255 00257 size_t getStageWidth() const; 00258 00260 size_t getStageHeight() const; 00261 00263 // 00272 DSOEXPORT bool mouseMoved(boost::int32_t x, boost::int32_t y); 00273 00275 // 00278 DSOEXPORT bool mouseClick(bool press); 00279 00281 // 00286 DSOEXPORT bool mouseWheel(int delta); 00287 00289 // 00293 DSOEXPORT bool keyEvent(key::code k, bool down); 00294 00296 // 00298 std::pair<boost::int32_t, boost::int32_t> mousePosition() const; 00299 00300 void setDragState(const DragState& st); 00301 00303 // 00305 Movie& getRootMovie() { 00306 return *_rootMovie; 00307 } 00308 00309 void stop_drag() { 00310 _dragState.reset(); 00311 } 00312 00314 // 00324 boost::uint32_t addIntervalTimer(std::auto_ptr<Timer> timer); 00325 00327 // 00331 // 00333 // 00336 // 00339 // 00342 void addLoadableObject(as_object* obj, std::auto_ptr<IOChannel> str); 00343 00344 void addAdvanceCallback(ActiveRelay* obj); 00345 00346 void removeAdvanceCallback(ActiveRelay* obj); 00347 00349 // 00351 bool clearIntervalTimer(boost::uint32_t x); 00352 00353 void set_background_color(const rgba& color); 00354 00355 void set_background_alpha(float alpha); 00356 00358 VM& getVM() { return _vm; } 00359 00362 // 00366 bool advance(); 00367 00371 // 00374 int timeToNextFrame() const; 00375 00377 // 00387 void advanceMovie(); 00388 00389 void display(); 00390 00392 size_t nextUnnamedInstance() { 00393 return ++_unnamedInstance; 00394 } 00395 00397 void add_key_listener(Button* listener); 00398 00400 void remove_key_listener(Button* listener); 00401 00403 // 00409 DisplayObject* getFocus(); 00410 00412 // 00418 bool setFocus(DisplayObject* to); 00419 00420 DSOEXPORT void add_invalidated_bounds(InvalidatedRanges& ranges, 00421 bool force); 00422 00424 // 00431 DisplayObject* getActiveEntityUnderPointer() const; 00432 00434 // 00438 const DisplayObject* getEntityUnderPointer() const; 00439 00441 DisplayObject* getDraggingCharacter() const; 00442 00443 bool testInvariant() const; 00444 00446 enum DisplayState { 00447 DISPLAYSTATE_NORMAL, 00448 DISPLAYSTATE_FULLSCREEN 00449 }; 00450 00452 enum ScaleMode { 00453 SCALEMODE_SHOWALL, 00454 SCALEMODE_NOSCALE, 00455 SCALEMODE_EXACTFIT, 00456 SCALEMODE_NOBORDER 00457 }; 00458 00460 enum StageHorizontalAlign { 00461 STAGE_H_ALIGN_C, 00462 STAGE_H_ALIGN_L, 00463 STAGE_H_ALIGN_R 00464 }; 00465 00467 enum StageVerticalAlign { 00468 STAGE_V_ALIGN_C, 00469 STAGE_V_ALIGN_T, 00470 STAGE_V_ALIGN_B 00471 }; 00472 00474 enum AlignMode { 00475 STAGE_ALIGN_L, 00476 STAGE_ALIGN_T, 00477 STAGE_ALIGN_R, 00478 STAGE_ALIGN_B 00479 }; 00480 00482 enum AllowScriptAccessMode { 00483 SCRIPT_ACCESS_NEVER, 00484 SCRIPT_ACCESS_SAME_DOMAIN, 00485 SCRIPT_ACCESS_ALWAYS 00486 }; 00487 00489 void setQuality(Quality q); 00490 00492 Quality getQuality() const { return _quality; } 00493 00496 void setStageAlignment(short s); 00497 00500 void setAllowScriptAccess(AllowScriptAccessMode mode); 00501 00503 AllowScriptAccessMode getAllowScriptAccess(); 00504 00505 typedef std::pair<StageHorizontalAlign, StageVerticalAlign> StageAlign; 00506 00509 StageAlign getStageAlignment() const; 00510 00513 bool getShowMenuState() const; 00514 00517 void setShowMenuState(bool state); 00518 00520 void setStageScaleMode(ScaleMode sm); 00521 00523 ScaleMode getStageScaleMode() const { return _scaleMode; } 00524 00525 // The string representation of the current align mode. 00526 std::string getStageAlignMode() const; 00527 00529 DisplayState getStageDisplayState() const { return _displayState; } 00530 00531 // The string representation of the current align mode. 00532 void setStageDisplayState(const DisplayState ds); 00533 00535 enum ActionPriorityLevel { 00537 PRIORITY_INIT, 00539 PRIORITY_CONSTRUCT, 00541 PRIORITY_DOACTION, 00543 PRIORITY_SIZE 00544 }; 00545 00547 // 00551 typedef boost::array<boost::ptr_deque<ExecutableCode>, PRIORITY_SIZE> 00552 ActionQueue; 00553 00555 void pushAction(std::auto_ptr<ExecutableCode> code, size_t lvl); 00556 00558 void pushAction(const action_buffer& buf, DisplayObject* target); 00559 00561 // 00572 void markReachableResources() const; 00573 00577 // 00582 void addLiveChar(MovieClip* ch) 00583 { 00584 // Don't register the object in the list twice 00585 #if GNASH_PARANOIA_LEVEL > 1 00586 assert(std::find(_liveChars.begin(), _liveChars.end(), ch) == 00587 _liveChars.end()); 00588 #endif 00589 _liveChars.push_front(ch); 00590 } 00591 00593 void reset(); 00594 00596 // 00606 void disableScripts(); 00607 00609 bool scriptsDisabled() const { return _disableScripts; }; 00610 00613 // 00619 void flushHigherPriorityActionQueues(); 00620 00621 DisplayObject* findCharacterByTarget(const std::string& tgtstr) const; 00622 00624 // 00628 // 00640 void loadMovie(const std::string& url, const std::string& target, 00641 const std::string& data, MovieClip::VariablesMethod method, 00642 as_object* handler=0) 00643 { 00644 _movieLoader.loadMovie(url, target, data, method, handler); 00645 } 00646 00648 // 00652 // 00660 void getURL(const std::string& urlstr, const std::string& target, 00661 const std::string& data, MovieClip::VariablesMethod method); 00662 00663 00664 key::code lastKeyEvent() const { 00665 return _lastKeyEvent; 00666 } 00667 00668 const Keys& unreleasedKeys() const { 00669 return _unreleasedKeys; 00670 } 00671 00674 void setHostFD(int fd) { 00675 assert(fd >= 0); 00676 _hostfd = fd; 00677 } 00678 00681 void setControlFD(int fd) { 00682 _controlfd = fd; 00683 } 00684 00689 int getHostFD() const { 00690 return _hostfd; 00691 } 00692 00693 int getControlFD() const { 00694 return _controlfd; 00695 } 00696 00706 DSOEXPORT void registerFSCommandCallback(FsCallback* handler) { 00707 _fsCommandHandler = handler; 00708 } 00709 00711 DSOEXPORT void handleFsCommand(const std::string& cmd, 00712 const std::string& arg) const; 00713 00720 DSOEXPORT void registerEventCallback(HostInterface* handler) { 00721 _interfaceHandler = handler; 00722 } 00723 00725 // 00727 void callInterface(const HostInterface::Message& e) const; 00728 00730 // 00735 // 00738 template<typename T> T callInterface(const HostInterface::Message& e) const; 00739 00744 // 00755 void setScriptLimits(boost::uint16_t recursion, boost::uint16_t timeout); 00756 00759 boost::uint16_t getRecursionLimit() const { 00760 return _recursionLimit; 00761 } 00762 00765 boost::uint16_t getTimeoutLimit() const 00766 { 00767 return _timeoutLimit; 00768 } 00769 00770 #ifdef USE_SWFTREE 00771 typedef tree<std::pair<std::string, std::string> > InfoTree; 00772 void getMovieInfo(InfoTree& tr, InfoTree::iterator it); 00773 void getCharacterTree(InfoTree& tr, InfoTree::iterator it); 00774 #endif 00775 00776 const RunResources& runResources() const { return _runResources; } 00777 00779 void addExternalCallback(const std::string& name, as_object* callback); 00780 00781 bool processInvoke(ExternalInterface::invoke_t *); 00782 00783 std::string callExternalCallback(const std::string &name, 00784 const std::vector<as_value>& args); 00785 00786 std::string callExternalJavascript(const std::string &name, 00787 const std::vector<as_value>& args); 00788 00790 // 00795 void removeQueuedConstructor(DisplayObject* target); 00796 00797 GC& gc() { 00798 return _gc; 00799 } 00800 00801 bool abortOnScriptTimeout(const std::string& when) const; 00802 00803 private: 00804 00806 // 00828 void setRootMovie(Movie* movie); 00829 00831 bool notify_mouse_listeners(const event_id& event); 00832 00836 bool fire_mouse_event(); 00837 00839 void doMouseDrag(); 00840 00842 void executeAdvanceCallbacks(); 00843 00845 void executeTimers(); 00846 00848 void cleanupAndCollect(); 00849 00853 // 00865 InteractiveObject* getTopmostMouseEntity(boost::int32_t x, 00866 boost::int32_t y) const; 00867 00870 void cleanupDisplayList(); 00871 00873 void advanceLiveChars(); 00874 00878 void setInvalidated() { _invalidated = true; } 00879 00881 // 00884 void clearInvalidated() { _invalidated = false; } 00885 00887 // 00894 bool isInvalidated() { return _invalidated; } 00895 00897 // 00900 size_t minPopulatedPriorityQueue() const; 00901 00905 size_t processActionQueue(size_t lvl); 00906 00907 bool processingActions() const { 00908 return (_processingActionLevel < PRIORITY_SIZE); 00909 } 00910 00911 const DisplayObject* findDropTarget(boost::int32_t x, boost::int32_t y, 00912 DisplayObject* dragging) const; 00913 00914 void handleActionLimitHit(const std::string& ref); 00915 00917 // 00922 // 00924 Listeners _keyListeners; 00925 00926 GC _gc; 00927 00928 const RunResources& _runResources; 00929 00932 VM _vm; 00933 00935 HostInterface* _interfaceHandler; 00936 00938 FsCallback* _fsCommandHandler; 00939 00941 // 00946 typedef std::list<MovieClip*> LiveChars; 00947 00949 LiveChars _liveChars; 00950 00951 ActionQueue _actionQueue; 00952 00954 void processActionQueue(); 00955 00957 size_t _stageWidth; 00958 size_t _stageHeight; 00959 00960 rgba m_background_color; 00961 bool m_background_color_set; 00962 00963 boost::int32_t _mouseX; 00964 boost::int32_t _mouseY; 00965 00966 MouseButtonState _mouseButtonState; 00967 00969 typedef std::set<ActiveRelay*> ObjectCallbacks; 00970 ObjectCallbacks _objectCallbacks; 00971 00972 LoadCallbacks _loadCallbacks; 00973 00974 typedef std::map<boost::uint32_t, boost::shared_ptr<Timer> > TimerMap; 00975 00976 TimerMap _intervalTimers; 00977 00978 size_t _lastTimerId; 00979 00981 Keys _unreleasedKeys; 00982 00983 key::code _lastKeyEvent; 00984 00986 DisplayObject* _currentFocus; 00987 00989 DragState _dragState; 00990 00991 typedef std::map<int, MovieClip*> Levels; 00992 00994 // 00998 Levels _movies; 00999 01003 Movie* _rootMovie; 01004 01006 bool _invalidated; 01007 01010 bool _disableScripts; 01011 int _processingActionLevel; 01012 01014 // 01016 int _hostfd; 01017 int _controlfd; 01018 01020 // 01023 Quality _quality; 01024 01026 std::bitset<4u> _alignMode; 01027 01028 AllowScriptAccessMode _allowScriptAccess; 01029 01031 bool _showMenu; 01032 01034 ScaleMode _scaleMode; 01035 01037 DisplayState _displayState; 01038 01039 // Maximum number of recursions set in the ScriptLimits tag. 01040 boost::uint16_t _recursionLimit; 01041 01042 // Timeout in seconds for script execution, set in the ScriptLimits tag. 01043 boost::uint16_t _timeoutLimit; 01044 01045 // delay between movie advancement, in milliseconds 01046 size_t _movieAdvancementDelay; 01047 01048 // time of last movie advancement, in milliseconds 01049 size_t _lastMovieAdvancement; 01050 01052 size_t _unnamedInstance; 01053 01054 MovieLoader _movieLoader; 01055 }; 01056 01058 // 01066 bool isLevelTarget(int version, const std::string& name, unsigned int& levelno); 01067 01068 DSOEXPORT short stringToStageAlign(const std::string& s); 01069 01070 template<typename T> 01071 T 01072 movie_root::callInterface(const HostInterface::Message& e) const 01073 { 01074 if (!_interfaceHandler) { 01075 log_error("Hosting application registered no callback for " 01076 "messages, can't call %s(%s)"); 01077 return T(); 01078 } 01079 01080 try { 01081 return boost::any_cast<T>(_interfaceHandler->call(e)); 01082 } 01083 catch (const boost::bad_any_cast&) { 01084 log_error(_("Unexpected type from host interface when requesting " 01085 "%1%"), e); 01086 return T(); 01087 } 01088 } 01089 01090 01091 } // namespace gnash 01092 01093 #endif // GNASH_MOVIE_ROOT_H 01094 01095 // Local Variables: 01096 // mode: C++ 01097 // indent-tabs-mode: nil 01098 // End: