Gnash
0.8.10
|
00001 // 00002 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 00003 // 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 #include <boost/optional.hpp> 00082 00083 #include "dsodefs.h" // DSOEXPORT 00084 #include "MouseButtonState.h" // for composition 00085 #include "DragState.h" // for composition 00086 #include "GnashKey.h" // key::code 00087 #include "Movie.h" 00088 #include "GnashEnums.h" 00089 #include "MovieClip.h" 00090 #include "SimpleBuffer.h" // for LoadCallback 00091 #include "MovieLoader.h" 00092 #include "ExternalInterface.h" 00093 #include "GC.h" 00094 #include "VM.h" 00095 #include "HostInterface.h" 00096 #include "log.h" 00097 00098 #ifdef USE_SWFTREE 00099 # include "tree.hh" 00100 #endif 00101 00102 // GNASH_PARANOIA_LEVEL: 00103 // 0 : (not unimplemented) 00104 // 1 : quick assertions 00105 // 2 : add testInvariant 00106 // 00107 #ifndef GNASH_PARANOIA_LEVEL 00108 # define GNASH_PARANOIA_LEVEL 1 00109 #endif 00110 00111 // Forward declarations 00112 namespace gnash { 00113 class ExecutableCode; 00114 class URL; 00115 class Timer; 00116 class MovieClip; 00117 class VirtualClock; 00118 class IOChannel; 00119 class RunResources; 00120 class Button; 00121 class VM; 00122 } 00123 00124 namespace gnash { 00125 00126 struct DepthComparator 00127 { 00128 typedef MovieClip* LevelMovie; 00129 bool operator()(const LevelMovie& d1, const LevelMovie& d2) const { 00130 return d1->get_depth() < d2->get_depth(); 00131 } 00132 }; 00133 00135 // 00140 // 00143 // 00148 // 00150 class DSOEXPORT movie_root : public GcRoot, boost::noncopyable 00151 { 00152 public: 00153 00154 class LoadCallback { 00155 public: 00156 LoadCallback(boost::shared_ptr<IOChannel> s, as_object* o) 00157 : 00158 _stream(s), 00159 _obj(o) 00160 {} 00161 bool processLoad(); 00162 void setReachable() const; 00163 private: 00164 boost::shared_ptr<IOChannel> _stream; 00165 SimpleBuffer _buf; 00166 as_object* _obj; 00167 }; 00168 typedef std::list<LoadCallback> LoadCallbacks; 00169 00170 typedef std::bitset<key::KEYCOUNT> Keys; 00171 00173 // 00176 movie_root(VirtualClock& clock, const RunResources& runResources); 00177 00178 ~movie_root(); 00179 00181 // 00183 // 00189 Movie* init(movie_definition* def, 00190 const MovieClip::MovieVariables& variables); 00191 00193 // 00197 MovieClip* getLevel(unsigned int num) const; 00198 00200 // 00205 void setLevel(unsigned int num, Movie* movie); 00206 00208 // 00216 void replaceLevel(unsigned int num, Movie* external_movie); 00217 00219 // 00232 void swapLevels(MovieClip* sp, int depth); 00233 00235 // 00243 void dropLevel(int depth); 00244 00246 // 00249 // 00252 void setDimensions(size_t w, size_t h); 00253 00255 size_t getStageWidth() const; 00256 00258 size_t getStageHeight() const; 00259 00261 // 00270 DSOEXPORT bool mouseMoved(boost::int32_t x, boost::int32_t y); 00271 00273 // 00276 DSOEXPORT bool mouseClick(bool press); 00277 00279 // 00284 DSOEXPORT bool mouseWheel(int delta); 00285 00287 // 00291 DSOEXPORT bool keyEvent(key::code k, bool down); 00292 00294 // 00296 std::pair<boost::int32_t, boost::int32_t> mousePosition() const; 00297 00298 void setDragState(const DragState& st); 00299 00301 // 00303 Movie& getRootMovie() { 00304 return *_rootMovie; 00305 } 00306 00307 void stop_drag() { 00308 _dragState.reset(); 00309 } 00310 00312 // 00322 boost::uint32_t addIntervalTimer(std::auto_ptr<Timer> timer); 00323 00325 // 00329 // 00331 // 00334 // 00337 // 00340 void addLoadableObject(as_object* obj, std::auto_ptr<IOChannel> str); 00341 00342 void addAdvanceCallback(ActiveRelay* obj); 00343 00344 void removeAdvanceCallback(ActiveRelay* obj); 00345 00347 // 00349 bool clearIntervalTimer(boost::uint32_t x); 00350 00351 void set_background_color(const rgba& color); 00352 00353 void set_background_alpha(float alpha); 00354 00356 VM& getVM() { return _vm; } 00357 00360 // 00364 bool advance(); 00365 00369 // 00372 int timeToNextFrame() const; 00373 00375 // 00385 void advanceMovie(); 00386 00387 void display(); 00388 00390 size_t nextUnnamedInstance() { 00391 return ++_unnamedInstance; 00392 } 00393 00395 void registerButton(Button* listener); 00396 00398 void removeButton(Button* listener); 00399 00401 // 00407 DisplayObject* getFocus(); 00408 00410 // 00416 bool setFocus(DisplayObject* to); 00417 00418 DSOEXPORT void add_invalidated_bounds(InvalidatedRanges& ranges, 00419 bool force); 00420 00422 // 00429 DisplayObject* getActiveEntityUnderPointer() const; 00430 00432 // 00436 const DisplayObject* getEntityUnderPointer() const; 00437 00439 DisplayObject* getDraggingCharacter() const; 00440 00441 bool testInvariant() const; 00442 00444 enum DisplayState { 00445 DISPLAYSTATE_NORMAL, 00446 DISPLAYSTATE_FULLSCREEN 00447 }; 00448 00450 enum ScaleMode { 00451 SCALEMODE_SHOWALL, 00452 SCALEMODE_NOSCALE, 00453 SCALEMODE_EXACTFIT, 00454 SCALEMODE_NOBORDER 00455 }; 00456 00458 enum StageHorizontalAlign { 00459 STAGE_H_ALIGN_C, 00460 STAGE_H_ALIGN_L, 00461 STAGE_H_ALIGN_R 00462 }; 00463 00465 enum StageVerticalAlign { 00466 STAGE_V_ALIGN_C, 00467 STAGE_V_ALIGN_T, 00468 STAGE_V_ALIGN_B 00469 }; 00470 00472 enum AlignMode { 00473 STAGE_ALIGN_L, 00474 STAGE_ALIGN_T, 00475 STAGE_ALIGN_R, 00476 STAGE_ALIGN_B 00477 }; 00478 00480 enum AllowScriptAccessMode { 00481 SCRIPT_ACCESS_NEVER, 00482 SCRIPT_ACCESS_SAME_DOMAIN, 00483 SCRIPT_ACCESS_ALWAYS 00484 }; 00485 00487 void setQuality(Quality q); 00488 00490 Quality getQuality() const { return _quality; } 00491 00494 void setStageAlignment(short s); 00495 00498 void setAllowScriptAccess(AllowScriptAccessMode mode); 00499 00501 AllowScriptAccessMode getAllowScriptAccess(); 00502 00503 typedef std::pair<StageHorizontalAlign, StageVerticalAlign> StageAlign; 00504 00507 StageAlign getStageAlignment() const; 00508 00511 bool getShowMenuState() const; 00512 00515 void setShowMenuState(bool state); 00516 00518 void setStageScaleMode(ScaleMode sm); 00519 00521 ScaleMode getStageScaleMode() const { return _scaleMode; } 00522 00523 // The string representation of the current align mode. 00524 std::string getStageAlignMode() const; 00525 00527 DisplayState getStageDisplayState() const { return _displayState; } 00528 00529 // The string representation of the current align mode. 00530 void setStageDisplayState(const DisplayState ds); 00531 00533 enum ActionPriorityLevel { 00535 PRIORITY_INIT, 00537 PRIORITY_CONSTRUCT, 00539 PRIORITY_DOACTION, 00541 PRIORITY_SIZE 00542 }; 00543 00545 // 00549 typedef boost::array<boost::ptr_deque<ExecutableCode>, PRIORITY_SIZE> 00550 ActionQueue; 00551 00553 void pushAction(std::auto_ptr<ExecutableCode> code, size_t lvl); 00554 00556 void pushAction(const action_buffer& buf, DisplayObject* target); 00557 00559 // 00568 void markReachableResources() const; 00569 00573 // 00578 void addLiveChar(MovieClip* ch) 00579 { 00580 // Don't register the object in the list twice 00581 #if GNASH_PARANOIA_LEVEL > 1 00582 assert(std::find(_liveChars.begin(), _liveChars.end(), ch) == 00583 _liveChars.end()); 00584 #endif 00585 _liveChars.push_front(ch); 00586 } 00587 00589 void reset(); 00590 00592 // 00602 void disableScripts(); 00603 00605 bool scriptsDisabled() const { return _disableScripts; }; 00606 00609 // 00615 void flushHigherPriorityActionQueues(); 00616 00617 DisplayObject* findCharacterByTarget(const std::string& tgtstr) const; 00618 00620 // 00624 // 00636 void loadMovie(const std::string& url, const std::string& target, 00637 const std::string& data, MovieClip::VariablesMethod method, 00638 as_object* handler=0) 00639 { 00640 _movieLoader.loadMovie(url, target, data, method, handler); 00641 } 00642 00644 // 00648 // 00656 void getURL(const std::string& urlstr, const std::string& target, 00657 const std::string& data, MovieClip::VariablesMethod method); 00658 00659 00660 key::code lastKeyEvent() const { 00661 return _lastKeyEvent; 00662 } 00663 00664 const Keys& unreleasedKeys() const { 00665 return _unreleasedKeys; 00666 } 00667 00669 // 00673 void registerClass(const SWF::DefinitionTag* sprite, as_function* cls); 00674 00676 // 00680 as_function* getRegisteredClass(const SWF::DefinitionTag* sprite) const; 00681 00684 void setHostFD(int fd) { 00685 assert(fd >= 0); 00686 _hostfd = fd; 00687 } 00688 00691 void setControlFD(int fd) { 00692 _controlfd = fd; 00693 } 00694 00699 int getHostFD() const { 00700 return _hostfd; 00701 } 00702 00703 int getControlFD() const { 00704 return _controlfd; 00705 } 00706 00716 DSOEXPORT void registerFSCommandCallback(FsCallback* handler) { 00717 _fsCommandHandler = handler; 00718 } 00719 00721 DSOEXPORT void handleFsCommand(const std::string& cmd, 00722 const std::string& arg) const; 00723 00730 DSOEXPORT void registerEventCallback(HostInterface* handler) { 00731 _interfaceHandler = handler; 00732 } 00733 00735 // 00737 void callInterface(const HostInterface::Message& e) const; 00738 00740 // 00745 // 00748 template<typename T> T callInterface(const HostInterface::Message& e) const; 00749 00754 // 00765 void setScriptLimits(boost::uint16_t recursion, boost::uint16_t timeout); 00766 00769 boost::uint16_t getRecursionLimit() const { 00770 return _recursionLimit; 00771 } 00772 00775 boost::uint16_t getTimeoutLimit() const 00776 { 00777 return _timeoutLimit; 00778 } 00779 00780 #ifdef USE_SWFTREE 00781 typedef tree<std::pair<std::string, std::string> > InfoTree; 00782 void getMovieInfo(InfoTree& tr, InfoTree::iterator it); 00783 void getCharacterTree(InfoTree& tr, InfoTree::iterator it); 00784 #endif 00785 00786 const RunResources& runResources() const { return _runResources; } 00787 00789 void addExternalCallback(const std::string& name, as_object* callback); 00790 00791 bool processInvoke(ExternalInterface::invoke_t *); 00792 00793 std::string callExternalCallback(const std::string &name, 00794 const std::vector<as_value>& args); 00795 00796 std::string callExternalJavascript(const std::string &name, 00797 const std::vector<as_value>& args); 00798 00800 // 00805 void removeQueuedConstructor(MovieClip* target); 00806 00807 GC& gc() { 00808 return _gc; 00809 } 00810 00812 // 00815 bool queryInterface(const std::string& what) const; 00816 00818 // 00822 // 00828 void setStreamBlock(int id, int block); 00829 00831 // 00834 // 00836 void stopStream(int id); 00837 00838 private: 00839 00841 // 00863 void setRootMovie(Movie* movie); 00864 00866 bool notify_mouse_listeners(const event_id& event); 00867 00871 bool fire_mouse_event(); 00872 00874 void doMouseDrag(); 00875 00877 void executeAdvanceCallbacks(); 00878 00880 void executeTimers(); 00881 00883 void cleanupAndCollect(); 00884 00888 // 00900 InteractiveObject* getTopmostMouseEntity(boost::int32_t x, 00901 boost::int32_t y) const; 00902 00905 void cleanupDisplayList(); 00906 00908 void advanceLiveChars(); 00909 00913 void setInvalidated() { _invalidated = true; } 00914 00916 // 00919 void clearInvalidated() { _invalidated = false; } 00920 00922 // 00929 bool isInvalidated() { return _invalidated; } 00930 00932 // 00935 size_t minPopulatedPriorityQueue() const; 00936 00940 size_t processActionQueue(size_t lvl); 00941 00942 bool processingActions() const { 00943 return (_processingActionLevel < PRIORITY_SIZE); 00944 } 00945 00946 const DisplayObject* findDropTarget(boost::int32_t x, boost::int32_t y, 00947 DisplayObject* dragging) const; 00948 00949 void handleActionLimitHit(const std::string& ref); 00950 00951 typedef std::list<Button*> ButtonListeners; 00952 ButtonListeners _buttonListeners; 00953 00954 GC _gc; 00955 00956 const RunResources& _runResources; 00957 00960 VM _vm; 00961 00963 HostInterface* _interfaceHandler; 00964 00966 FsCallback* _fsCommandHandler; 00967 00969 // 00974 typedef std::list<MovieClip*> LiveChars; 00975 00977 LiveChars _liveChars; 00978 00979 ActionQueue _actionQueue; 00980 00982 void processActionQueue(); 00983 00985 size_t _stageWidth; 00986 size_t _stageHeight; 00987 00988 rgba m_background_color; 00989 bool m_background_color_set; 00990 00991 boost::int32_t _mouseX; 00992 boost::int32_t _mouseY; 00993 00994 MouseButtonState _mouseButtonState; 00995 00997 typedef std::set<ActiveRelay*> ObjectCallbacks; 00998 ObjectCallbacks _objectCallbacks; 00999 01000 LoadCallbacks _loadCallbacks; 01001 01002 typedef std::map<boost::uint32_t, boost::shared_ptr<Timer> > TimerMap; 01003 01004 TimerMap _intervalTimers; 01005 01006 size_t _lastTimerId; 01007 01009 Keys _unreleasedKeys; 01010 01011 key::code _lastKeyEvent; 01012 01014 DisplayObject* _currentFocus; 01015 01017 boost::optional<DragState> _dragState; 01018 01019 typedef std::map<int, MovieClip*> Levels; 01020 01022 // 01026 Levels _movies; 01027 01028 typedef std::map<const SWF::DefinitionTag*, as_function*> RegisteredClasses; 01029 RegisteredClasses _registeredClasses; 01030 01034 Movie* _rootMovie; 01035 01037 bool _invalidated; 01038 01041 bool _disableScripts; 01042 int _processingActionLevel; 01043 01045 // 01047 int _hostfd; 01048 int _controlfd; 01049 01051 // 01054 Quality _quality; 01055 01057 std::bitset<4u> _alignMode; 01058 01059 AllowScriptAccessMode _allowScriptAccess; 01060 01062 bool _showMenu; 01063 01065 ScaleMode _scaleMode; 01066 01068 DisplayState _displayState; 01069 01070 // Maximum number of recursions set in the ScriptLimits tag. 01071 boost::uint16_t _recursionLimit; 01072 01073 // Timeout in seconds for script execution, set in the ScriptLimits tag. 01074 boost::uint16_t _timeoutLimit; 01075 01076 // delay between movie advancement, in milliseconds 01077 size_t _movieAdvancementDelay; 01078 01079 // time of last movie advancement, in milliseconds 01080 size_t _lastMovieAdvancement; 01081 01083 size_t _unnamedInstance; 01084 01085 MovieLoader _movieLoader; 01086 01087 struct SoundStream { 01088 SoundStream(int i, int b) : id(i), block(b) {} 01089 int id; 01090 int block; 01091 }; 01092 01093 boost::optional<SoundStream> _timelineSound; 01094 }; 01095 01097 // 01105 bool isLevelTarget(int version, const std::string& name, unsigned int& levelno); 01106 01107 DSOEXPORT short stringToStageAlign(const std::string& s); 01108 01109 template<typename T> 01110 T 01111 movie_root::callInterface(const HostInterface::Message& e) const 01112 { 01113 if (!_interfaceHandler) { 01114 log_error("Hosting application registered no callback for " 01115 "messages, can't call %s(%s)"); 01116 return T(); 01117 } 01118 01119 try { 01120 return boost::any_cast<T>(_interfaceHandler->call(e)); 01121 } 01122 catch (const boost::bad_any_cast&) { 01123 log_error(_("Unexpected type from host interface when requesting " 01124 "%1%"), e); 01125 return T(); 01126 } 01127 } 01128 01129 } // namespace gnash 01130 01131 #endif // GNASH_MOVIE_ROOT_H 01132 01133 // Local Variables: 01134 // mode: C++ 01135 // indent-tabs-mode: nil 01136 // End: