Gnash 0.8.9
|
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 "smart_ptr.h" 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 00155 typedef std::list<Button*> Listeners; 00156 00157 class LoadCallback { 00158 public: 00159 LoadCallback(boost::shared_ptr<IOChannel> s, as_object* o) 00160 : 00161 _stream(s), 00162 _obj(o) 00163 {} 00164 bool processLoad(); 00165 void setReachable() const; 00166 private: 00167 boost::shared_ptr<IOChannel> _stream; 00168 SimpleBuffer _buf; 00169 as_object* _obj; 00170 }; 00171 typedef std::list<LoadCallback> LoadCallbacks; 00172 00173 typedef std::bitset<key::KEYCOUNT> Keys; 00174 00176 // 00180 movie_root(const movie_definition& def, VirtualClock& clock, 00181 const RunResources& runResources); 00182 00183 ~movie_root(); 00184 00186 // 00188 // 00194 Movie* init(movie_definition* def, 00195 const MovieClip::MovieVariables& variables); 00196 00198 // 00202 MovieClip* getLevel(unsigned int num) const; 00203 00205 // 00210 void setLevel(unsigned int num, Movie* movie); 00211 00213 // 00221 void replaceLevel(unsigned int num, Movie* external_movie); 00222 00224 // 00237 void swapLevels(MovieClip* sp, int depth); 00238 00240 // 00248 void dropLevel(int depth); 00249 00251 // 00254 // 00257 void setDimensions(size_t w, size_t h); 00258 00260 size_t getStageWidth() const; 00261 00263 size_t getStageHeight() const; 00264 00266 // 00275 DSOEXPORT bool mouseMoved(boost::int32_t x, boost::int32_t y); 00276 00278 // 00281 DSOEXPORT bool mouseClick(bool press); 00282 00284 // 00289 DSOEXPORT bool mouseWheel(int delta); 00290 00292 // 00296 DSOEXPORT bool keyEvent(key::code k, bool down); 00297 00299 // 00301 std::pair<boost::int32_t, boost::int32_t> mousePosition() const; 00302 00303 void setDragState(const DragState& st); 00304 00306 // 00308 Movie& getRootMovie() { 00309 return *_rootMovie; 00310 } 00311 00313 // 00315 float frameRate() const { 00316 return _rootMovie->frameRate(); 00317 } 00318 00319 void stop_drag() { 00320 _dragState.reset(); 00321 } 00322 00324 // 00334 boost::uint32_t addIntervalTimer(std::auto_ptr<Timer> timer); 00335 00337 // 00341 // 00343 // 00346 // 00349 // 00352 void addLoadableObject(as_object* obj, std::auto_ptr<IOChannel> str); 00353 00354 void addAdvanceCallback(ActiveRelay* obj); 00355 00356 void removeAdvanceCallback(ActiveRelay* obj); 00357 00359 // 00361 bool clearIntervalTimer(boost::uint32_t x); 00362 00364 // 00368 size_t get_current_frame() const { 00369 return _rootMovie->get_current_frame(); 00370 } 00371 00372 void set_background_color(const rgba& color); 00373 00374 void set_background_alpha(float alpha); 00375 00377 VM& getVM() { return _vm; } 00378 00381 // 00385 bool advance(); 00386 00390 // 00393 int timeToNextFrame() const; 00394 00396 // 00406 void advanceMovie(); 00407 00409 // 00411 void goto_frame(size_t target_frame_number) { 00412 _rootMovie->goto_frame(target_frame_number); 00413 } 00414 00415 void display(); 00416 00418 size_t nextUnnamedInstance() { 00419 return ++_unnamedInstance; 00420 } 00421 00423 void add_key_listener(Button* listener); 00424 00426 void remove_key_listener(Button* listener); 00427 00429 // 00435 DisplayObject* getFocus(); 00436 00438 // 00444 bool setFocus(DisplayObject* to); 00445 00446 DSOEXPORT void add_invalidated_bounds(InvalidatedRanges& ranges, 00447 bool force); 00448 00450 // 00457 DisplayObject* getActiveEntityUnderPointer() const; 00458 00460 // 00464 const DisplayObject* getEntityUnderPointer() const; 00465 00467 DisplayObject* getDraggingCharacter() const; 00468 00469 bool testInvariant() const; 00470 00472 enum DisplayState { 00473 DISPLAYSTATE_NORMAL, 00474 DISPLAYSTATE_FULLSCREEN 00475 }; 00476 00478 enum ScaleMode { 00479 SCALEMODE_SHOWALL, 00480 SCALEMODE_NOSCALE, 00481 SCALEMODE_EXACTFIT, 00482 SCALEMODE_NOBORDER 00483 }; 00484 00486 enum StageHorizontalAlign { 00487 STAGE_H_ALIGN_C, 00488 STAGE_H_ALIGN_L, 00489 STAGE_H_ALIGN_R 00490 }; 00491 00493 enum StageVerticalAlign { 00494 STAGE_V_ALIGN_C, 00495 STAGE_V_ALIGN_T, 00496 STAGE_V_ALIGN_B 00497 }; 00498 00500 enum AlignMode { 00501 STAGE_ALIGN_L, 00502 STAGE_ALIGN_T, 00503 STAGE_ALIGN_R, 00504 STAGE_ALIGN_B 00505 }; 00506 00508 enum AllowScriptAccessMode { 00509 SCRIPT_ACCESS_NEVER, 00510 SCRIPT_ACCESS_SAME_DOMAIN, 00511 SCRIPT_ACCESS_ALWAYS 00512 }; 00513 00515 void setQuality(Quality q); 00516 00518 Quality getQuality() const { return _quality; } 00519 00522 void setStageAlignment(short s); 00523 00526 void setAllowScriptAccess(AllowScriptAccessMode mode); 00527 00529 AllowScriptAccessMode getAllowScriptAccess(); 00530 00531 typedef std::pair<StageHorizontalAlign, StageVerticalAlign> StageAlign; 00532 00535 StageAlign getStageAlignment() const; 00536 00539 bool getShowMenuState() const; 00540 00543 void setShowMenuState(bool state); 00544 00546 void setStageScaleMode(ScaleMode sm); 00547 00549 ScaleMode getStageScaleMode() const { return _scaleMode; } 00550 00551 // The string representation of the current align mode. 00552 std::string getStageAlignMode() const; 00553 00555 DisplayState getStageDisplayState() const { return _displayState; } 00556 00557 // The string representation of the current align mode. 00558 void setStageDisplayState(const DisplayState ds); 00559 00561 enum ActionPriorityLevel { 00563 PRIORITY_INIT, 00565 PRIORITY_CONSTRUCT, 00567 PRIORITY_DOACTION, 00569 PRIORITY_SIZE 00570 }; 00571 00573 // 00577 typedef boost::array<boost::ptr_deque<ExecutableCode>, PRIORITY_SIZE> 00578 ActionQueue; 00579 00581 void pushAction(std::auto_ptr<ExecutableCode> code, size_t lvl); 00582 00584 void pushAction(const action_buffer& buf, DisplayObject* target); 00585 00587 // 00598 void markReachableResources() const; 00599 00603 // 00608 void addLiveChar(MovieClip* ch) 00609 { 00610 // Don't register the object in the list twice 00611 #if GNASH_PARANOIA_LEVEL > 1 00612 assert(std::find(_liveChars.begin(), _liveChars.end(), ch) == 00613 _liveChars.end()); 00614 #endif 00615 _liveChars.push_front(ch); 00616 } 00617 00619 void reset(); 00620 00622 // 00632 void disableScripts(); 00633 00635 bool scriptsDisabled() const { return _disableScripts; }; 00636 00639 // 00645 void flushHigherPriorityActionQueues(); 00646 00647 DisplayObject* findCharacterByTarget(const std::string& tgtstr) const; 00648 00650 // 00654 // 00666 void loadMovie(const std::string& url, const std::string& target, 00667 const std::string& data, MovieClip::VariablesMethod method, 00668 as_object* handler=0) 00669 { 00670 _movieLoader.loadMovie(url, target, data, method, handler); 00671 } 00672 00674 // 00678 // 00686 void getURL(const std::string& urlstr, const std::string& target, 00687 const std::string& data, MovieClip::VariablesMethod method); 00688 00689 00690 key::code lastKeyEvent() const { 00691 return _lastKeyEvent; 00692 } 00693 00694 const Keys& unreleasedKeys() const { 00695 return _unreleasedKeys; 00696 } 00697 00700 void setHostFD(int fd) { 00701 assert(fd >= 0); 00702 _hostfd = fd; 00703 } 00704 00707 void setControlFD(int fd) { 00708 _controlfd = fd; 00709 } 00710 00715 int getHostFD() const { 00716 return _hostfd; 00717 } 00718 00719 int getControlFD() const { 00720 return _controlfd; 00721 } 00722 00732 DSOEXPORT void registerFSCommandCallback(FsCallback* handler) { 00733 _fsCommandHandler = handler; 00734 } 00735 00737 DSOEXPORT void handleFsCommand(const std::string& cmd, 00738 const std::string& arg) const; 00739 00746 DSOEXPORT void registerEventCallback(HostInterface* handler) { 00747 _interfaceHandler = handler; 00748 } 00749 00751 // 00753 void callInterface(const HostInterface::Message& e) const; 00754 00756 // 00761 // 00764 template<typename T> T callInterface(const HostInterface::Message& e) const; 00765 00770 // 00781 void setScriptLimits(boost::uint16_t recursion, boost::uint16_t timeout); 00782 00785 boost::uint16_t getRecursionLimit() const { 00786 return _recursionLimit; 00787 } 00788 00791 boost::uint16_t getTimeoutLimit() const 00792 { 00793 return _timeoutLimit; 00794 } 00795 00796 #ifdef USE_SWFTREE 00797 typedef tree<std::pair<std::string, std::string> > InfoTree; 00798 void getMovieInfo(InfoTree& tr, InfoTree::iterator it); 00799 void getCharacterTree(InfoTree& tr, InfoTree::iterator it); 00800 #endif 00801 00802 const RunResources& runResources() const { return _runResources; } 00803 00805 void addExternalCallback(const std::string& name, as_object* callback); 00806 00807 bool processInvoke(ExternalInterface::invoke_t *); 00808 00809 std::string callExternalCallback(const std::string &name, 00810 const std::vector<as_value>& args); 00811 00812 std::string callExternalJavascript(const std::string &name, 00813 const std::vector<as_value>& args); 00814 00816 // 00821 void removeQueuedConstructor(DisplayObject* target); 00822 00823 GC& gc() { 00824 return _gc; 00825 } 00826 00827 private: 00828 00830 // 00852 void setRootMovie(Movie* movie); 00853 00855 bool notify_mouse_listeners(const event_id& event); 00856 00860 bool fire_mouse_event(); 00861 00863 void doMouseDrag(); 00864 00866 void executeAdvanceCallbacks(); 00867 00869 void executeTimers(); 00870 00872 void cleanupAndCollect(); 00873 00877 // 00889 InteractiveObject* getTopmostMouseEntity(boost::int32_t x, 00890 boost::int32_t y) const; 00891 00894 void cleanupDisplayList(); 00895 00897 void advanceLiveChars(); 00898 00902 void setInvalidated() { _invalidated = true; } 00903 00905 // 00908 void clearInvalidated() { _invalidated = false; } 00909 00911 // 00918 bool isInvalidated() { return _invalidated; } 00919 00921 // 00924 size_t minPopulatedPriorityQueue() const; 00925 00929 size_t processActionQueue(size_t lvl); 00930 00931 bool processingActions() const { 00932 return (_processingActionLevel < PRIORITY_SIZE); 00933 } 00934 00935 const DisplayObject* findDropTarget(boost::int32_t x, boost::int32_t y, 00936 DisplayObject* dragging) const; 00937 00938 void handleActionLimitHit(const std::string& ref); 00939 00941 // 00946 // 00948 Listeners _keyListeners; 00949 00950 GC _gc; 00951 00952 const RunResources& _runResources; 00953 00956 VM _vm; 00957 00959 HostInterface* _interfaceHandler; 00960 00962 FsCallback* _fsCommandHandler; 00963 00965 // 00970 typedef std::list<MovieClip*> LiveChars; 00971 00973 LiveChars _liveChars; 00974 00975 ActionQueue _actionQueue; 00976 00978 void processActionQueue(); 00979 00981 size_t _stageWidth; 00982 size_t _stageHeight; 00983 00984 rgba m_background_color; 00985 bool m_background_color_set; 00986 00987 boost::int32_t _mouseX; 00988 boost::int32_t _mouseY; 00989 00990 MouseButtonState _mouseButtonState; 00991 00993 typedef std::set<ActiveRelay*> ObjectCallbacks; 00994 ObjectCallbacks _objectCallbacks; 00995 00996 LoadCallbacks _loadCallbacks; 00997 00998 typedef std::map<boost::uint32_t, boost::shared_ptr<Timer> > TimerMap; 00999 01000 TimerMap _intervalTimers; 01001 01002 size_t _lastTimerId; 01003 01005 Keys _unreleasedKeys; 01006 01007 key::code _lastKeyEvent; 01008 01010 DisplayObject* _currentFocus; 01011 01013 DragState _dragState; 01014 01015 typedef std::map<int, MovieClip*> Levels; 01016 01018 // 01022 Levels _movies; 01023 01027 Movie* _rootMovie; 01028 01030 bool _invalidated; 01031 01034 bool _disableScripts; 01035 int _processingActionLevel; 01036 01038 // 01040 int _hostfd; 01041 int _controlfd; 01042 01044 // 01047 Quality _quality; 01048 01050 std::bitset<4u> _alignMode; 01051 01052 AllowScriptAccessMode _allowScriptAccess; 01053 01055 bool _showMenu; 01056 01058 ScaleMode _scaleMode; 01059 01061 DisplayState _displayState; 01062 01063 // Maximum number of recursions set in the ScriptLimits tag. 01064 boost::uint16_t _recursionLimit; 01065 01066 // Timeout in seconds for script execution, set in the ScriptLimits tag. 01067 boost::uint16_t _timeoutLimit; 01068 01069 // delay between movie advancement, in milliseconds 01070 size_t _movieAdvancementDelay; 01071 01072 // time of last movie advancement, in milliseconds 01073 size_t _lastMovieAdvancement; 01074 01076 size_t _unnamedInstance; 01077 01078 MovieLoader _movieLoader; 01079 }; 01080 01082 // 01090 bool isLevelTarget(int version, const std::string& name, unsigned int& levelno); 01091 01092 DSOEXPORT short stringToStageAlign(const std::string& s); 01093 01094 template<typename T> 01095 T 01096 movie_root::callInterface(const HostInterface::Message& e) const 01097 { 01098 if (!_interfaceHandler) { 01099 log_error("Hosting application registered no callback for " 01100 "messages, can't call %s(%s)"); 01101 return T(); 01102 } 01103 01104 try { 01105 return boost::any_cast<T>(_interfaceHandler->call(e)); 01106 } 01107 catch (const boost::bad_any_cast&) { 01108 log_error(_("Unexpected type from host interface when requesting " 01109 "%1%"), e); 01110 return T(); 01111 } 01112 } 01113 01114 01115 } // namespace gnash 01116 01117 #endif // GNASH_MOVIE_ROOT_H 01118 01119 // Local Variables: 01120 // mode: C++ 01121 // indent-tabs-mode: nil 01122 // End: