00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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"
00069 #endif
00070
00071 #include "smart_ptr.h"
00072 #include "dsodefs.h"
00073 #include "MouseButtonState.h"
00074 #include "drag_state.h"
00075 #include "GnashKey.h"
00076 #include "Movie.h"
00077 #include "gnash.h"
00078 #include "MovieClip.h"
00079 #include "SimpleBuffer.h"
00080 #include "MovieLoader.h"
00081 #include "ExternalInterface.h"
00082
00083 #ifdef USE_SWFTREE
00084 # include "tree.hh"
00085 #endif
00086
00087
00088
00089
00090
00091
00092 #ifndef GNASH_PARANOIA_LEVEL
00093 # define GNASH_PARANOIA_LEVEL 1
00094 #endif
00095
00096 #include <map>
00097 #include <string>
00098 #include <vector>
00099 #include <deque>
00100 #include <list>
00101 #include <set>
00102 #include <bitset>
00103 #include <boost/noncopyable.hpp>
00104 #include <boost/thread/thread.hpp>
00105
00106
00107 namespace gnash {
00108 class ExecutableCode;
00109 class URL;
00110 class Timer;
00111 class MovieClip;
00112 class VirtualClock;
00113 class IOChannel;
00114 class RunResources;
00115 class Button;
00116 }
00117
00118 namespace gnash
00119 {
00120
00121 struct DepthComparator
00122 {
00123 typedef MovieClip* LevelMovie;
00124
00125 bool operator() (const LevelMovie& d1, const LevelMovie& d2)
00126 {
00127 return d1->get_depth() < d2->get_depth();
00128 }
00129 };
00130
00132
00137
00140
00145
00147 class DSOEXPORT movie_root : boost::noncopyable
00148 {
00149 public:
00150
00152 typedef std::list<Button*> Listeners;
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
00177 movie_root(const movie_definition& def, VirtualClock& clock,
00178 const RunResources& runResources);
00179
00180 ~movie_root();
00181
00183
00185
00191 Movie* init(movie_definition* def,
00192 const MovieClip::MovieVariables& variables,
00193 const MovieClip::MovieVariables& scriptables);
00194
00196
00200 MovieClip* getLevel(unsigned int num) const;
00201
00203
00208 void setLevel(unsigned int num, Movie* movie);
00209
00211
00219 void replaceLevel(unsigned int num, Movie* external_movie);
00220
00222
00235 void swapLevels(MovieClip* sp, int depth);
00236
00238
00246 void dropLevel(int depth);
00247
00249
00252
00255 void setDimensions(size_t w, size_t h);
00256
00258 size_t getStageWidth() const;
00259
00261 size_t getStageHeight() const;
00262
00264
00273 DSOEXPORT bool mouseMoved(boost::int32_t x, boost::int32_t y);
00274
00276
00279 DSOEXPORT bool mouseClick(bool press);
00280
00282
00287 DSOEXPORT bool mouseWheel(int delta);
00288
00290
00294 DSOEXPORT bool keyEvent(key::code k, bool down);
00295
00297
00299 void get_mouse_state(boost::int32_t& x, boost::int32_t& y);
00300
00301 void get_drag_state(drag_state& st);
00302
00303 void set_drag_state(const drag_state& st);
00304
00306 const Movie& getRootMovie() const
00307 {
00308 return *_rootMovie;
00309 }
00310
00312
00316 Movie* topLevelMovie() const
00317 {
00318 return _rootMovie;
00319 }
00320
00322
00324 float frameRate() const {
00325 return _rootMovie->frameRate();
00326 }
00327
00328 void stop_drag()
00329 {
00330 m_drag_state.reset();
00331 }
00332
00334
00345 unsigned int add_interval_timer(std::auto_ptr<Timer> timer);
00346
00348
00352
00354
00357
00360
00363 void addLoadableObject(as_object* obj, std::auto_ptr<IOChannel> str);
00364
00365 void addAdvanceCallback(ActiveRelay* obj);
00366
00367 void removeAdvanceCallback(ActiveRelay* obj);
00368
00370
00373 bool clear_interval_timer(unsigned int x);
00374
00376
00380 size_t get_current_frame() const
00381 {
00382 return _rootMovie->get_current_frame();
00383 }
00384
00385 void set_background_color(const rgba& color);
00386
00387 void set_background_alpha(float alpha);
00388
00390 VM& getVM() { return _vm; }
00391
00394
00398 bool advance();
00399
00403
00406 int timeToNextFrame() const;
00407
00409
00419 void advanceMovie();
00420
00422
00424 void goto_frame(size_t target_frame_number)
00425 {
00426 _rootMovie->goto_frame(target_frame_number);
00427 }
00428
00429 void display();
00430
00432
00434 void set_play_state(MovieClip::PlayState s)
00435 {
00436 _rootMovie->setPlayState(s);
00437 }
00438
00440 size_t nextUnnamedInstance();
00441
00443 void add_key_listener(Button* listener);
00444
00446 void remove_key_listener(Button* listener);
00447
00449
00455 DisplayObject* getFocus();
00456
00458
00464 bool setFocus(DisplayObject* to);
00465
00466 DSOEXPORT void add_invalidated_bounds(InvalidatedRanges& ranges,
00467 bool force);
00468
00470
00477 DisplayObject* getActiveEntityUnderPointer() const;
00478
00480
00484 const DisplayObject* getEntityUnderPointer() const;
00485
00487 DisplayObject* getDraggingCharacter() const;
00488
00489 bool testInvariant() const;
00490
00492 enum DisplayState {
00493 DISPLAYSTATE_NORMAL,
00494 DISPLAYSTATE_FULLSCREEN
00495 };
00496
00498 enum ScaleMode {
00499 SCALEMODE_SHOWALL,
00500 SCALEMODE_NOSCALE,
00501 SCALEMODE_EXACTFIT,
00502 SCALEMODE_NOBORDER
00503 };
00504
00506 enum StageHorizontalAlign {
00507 STAGE_H_ALIGN_C,
00508 STAGE_H_ALIGN_L,
00509 STAGE_H_ALIGN_R
00510 };
00511
00513 enum StageVerticalAlign {
00514 STAGE_V_ALIGN_C,
00515 STAGE_V_ALIGN_T,
00516 STAGE_V_ALIGN_B
00517 };
00518
00520 enum AlignMode {
00521 STAGE_ALIGN_L,
00522 STAGE_ALIGN_T,
00523 STAGE_ALIGN_R,
00524 STAGE_ALIGN_B
00525 };
00526
00528 enum AllowScriptAccessMode {
00529 SCRIPT_ACCESS_NEVER,
00530 SCRIPT_ACCESS_SAME_DOMAIN,
00531 SCRIPT_ACCESS_ALWAYS
00532 };
00533
00535 void setQuality(Quality q);
00536
00538 Quality getQuality() const { return _quality; }
00539
00542 void setStageAlignment(short s);
00543
00546 void setAllowScriptAccess(AllowScriptAccessMode mode);
00547
00549 AllowScriptAccessMode getAllowScriptAccess();
00550
00551 typedef std::pair<StageHorizontalAlign, StageVerticalAlign> StageAlign;
00552
00555 StageAlign getStageAlignment() const;
00556
00559 bool getShowMenuState() const;
00560
00563 void setShowMenuState(bool state);
00564
00565
00566
00567 void setMarshallExceptions(bool x) { _marshallExceptions = x; };
00568 bool getMarshallExceptions() { return _marshallExceptions; };
00569
00571 void setStageScaleMode(ScaleMode sm);
00572
00574 ScaleMode getStageScaleMode() const { return _scaleMode; }
00575
00576
00577 std::string getStageAlignMode() const;
00578
00580 DisplayState getStageDisplayState() const { return _displayState; }
00581
00582
00583 void setStageDisplayState(const DisplayState ds);
00584
00586 enum ActionPriorityLevel {
00588 PRIORITY_INIT,
00590 PRIORITY_CONSTRUCT,
00592 PRIORITY_DOACTION,
00594 PRIORITY_SIZE
00595 };
00596
00598 void pushAction(std::auto_ptr<ExecutableCode> code, size_t lvl);
00599
00601 void pushAction(const action_buffer& buf, DisplayObject* target);
00602
00603 #ifdef GNASH_USE_GC
00604
00605
00616 void markReachableResources() const;
00617 #endif // GNASH_USE_GC
00618
00622
00627 void addLiveChar(MovieClip* ch)
00628 {
00629
00630 #if GNASH_PARANOIA_LEVEL > 1
00631 assert(std::find(_liveChars.begin(), _liveChars.end(), ch) ==
00632 _liveChars.end());
00633 #endif
00634 _liveChars.push_front(ch);
00635 }
00636
00638
00642 void clear();
00643
00645 void reset();
00646
00648
00658 void disableScripts();
00659
00661 bool scriptsDisabled() const { return _disableScripts; };
00662
00665
00671 void flushHigherPriorityActionQueues();
00672
00673 DisplayObject* findCharacterByTarget(const std::string& tgtstr) const;
00674
00676
00680
00692 void loadMovie(const std::string& url, const std::string& target,
00693 const std::string& data, MovieClip::VariablesMethod method,
00694 as_object* handler=0)
00695 {
00696 _movieLoader.loadMovie(url, target, data, method, handler);
00697 }
00698
00700
00704
00712 void getURL(const std::string& urlstr, const std::string& target,
00713 const std::string& data, MovieClip::VariablesMethod method);
00714
00715
00716 key::code lastKeyEvent() const {
00717 return _lastKeyEvent;
00718 }
00719
00720 const Keys& unreleasedKeys() const {
00721 return _unreleasedKeys;
00722 }
00723
00726 void setHostFD(int fd)
00727 {
00728 assert(fd >= 0);
00729 _hostfd = fd;
00730 }
00731
00734 void setControlFD(int fd)
00735 {
00736 _controlfd = fd;
00737 }
00738
00743 int getHostFD() const
00744 {
00745 return _hostfd;
00746 }
00747
00748 int getControlFD() const
00749 {
00750 return _controlfd;
00751 }
00752
00753
00755 class AbstractFsCallback {
00756 public:
00757 virtual void notify(const std::string& cmd, const std::string& arg)=0;
00758 virtual ~AbstractFsCallback() {}
00759 };
00760
00770 DSOEXPORT void registerFSCommandCallback(AbstractFsCallback* handler)
00771 {
00772 _fsCommandHandler = handler;
00773 }
00774
00776 DSOEXPORT void handleFsCommand(const std::string& cmd,
00777 const std::string& arg) const;
00778
00780 class AbstractIfaceCallback
00781 {
00782 public:
00783
00785
00789 virtual std::string call(const std::string& cmd,
00790 const std::string& arg = std::string()) = 0;
00791
00794 virtual bool yesNo(const std::string& cmd) = 0;
00795
00797 virtual void exit() = 0;
00798
00800
00802 virtual void error(const std::string& ) {}
00803
00804 virtual ~AbstractIfaceCallback() {}
00805 };
00806
00813 DSOEXPORT void registerEventCallback(AbstractIfaceCallback* handler)
00814 {
00815 _interfaceHandler = handler;
00816 }
00817
00821 DSOEXPORT std::string callInterface(const std::string& cmd,
00822 const std::string& arg = std::string()) const;
00823
00825
00827
00830 DSOEXPORT void errorInterface(const std::string& msg) const;
00831
00836
00847 void setScriptLimits(boost::uint16_t recursion, boost::uint16_t timeout);
00848
00851 boost::uint16_t getRecursionLimit() const
00852 {
00853 return _recursionLimit;
00854 }
00855
00858 boost::uint16_t getTimeoutLimit() const
00859 {
00860 return _timeoutLimit;
00861 }
00862
00863 #ifdef USE_SWFTREE
00864 typedef std::pair<std::string, std::string> StringPair;
00865 void getMovieInfo(tree<StringPair>& tr, tree<StringPair>::iterator it);
00866 void getCharacterTree(tree<StringPair>& tr, tree<StringPair>::iterator it);
00867 #endif
00868
00870
00873 const std::string& getOriginalURL() const { return _originalURL; }
00874
00875 const RunResources& runResources() const { return _runResources; }
00876
00877 void addExternalCallback(as_object *obj, const std::string &name,
00878 as_object *callback);
00879
00880 bool processInvoke(ExternalInterface::invoke_t *);
00881
00882 std::string callExternalCallback(const std::string &name,
00883 const std::vector<as_value>& args);
00884
00885 std::string callExternalJavascript(const std::string &name,
00886 const std::vector<as_value>& args);
00887
00889
00894 void removeQueuedConstructor(DisplayObject* target);
00895
00896 private:
00897
00899
00921 void setRootMovie(Movie* movie);
00922
00924 bool notify_mouse_listeners(const event_id& event);
00925
00929 bool fire_mouse_event();
00930
00931 const RunResources& _runResources;
00932
00934
00937 const std::string _originalURL;
00938
00941 VM& _vm;
00942
00944 AbstractIfaceCallback* _interfaceHandler;
00945
00947 AbstractFsCallback* _fsCommandHandler;
00948
00950 void doMouseDrag();
00951
00953 void clearActionQueue();
00954
00956 void clearIntervalTimers();
00957
00959 void executeAdvanceCallbacks();
00960
00962 void executeTimers();
00963
00965 void cleanupAndCollect();
00966
00970
00982 InteractiveObject* getTopmostMouseEntity(boost::int32_t x,
00983 boost::int32_t y) const;
00984
00987 void cleanupDisplayList();
00988
00990 void advanceLiveChars();
00991
00995 void setInvalidated() { _invalidated = true; }
00996
00998
01001 void clearInvalidated() { _invalidated = false; }
01002
01004
01011 bool isInvalidated() { return _invalidated; }
01012
01014
01017 size_t minPopulatedPriorityQueue() const;
01018
01022 size_t processActionQueue(size_t lvl);
01023
01024 bool processingActions() const
01025 {
01026 return (_processingActionLevel < PRIORITY_SIZE);
01027 }
01028
01029 const DisplayObject* findDropTarget(boost::int32_t x, boost::int32_t y,
01030 DisplayObject* dragging) const;
01031
01032 void handleActionLimitHit(const std::string& ref);
01033
01035
01040 typedef std::list<MovieClip*> LiveChars;
01041
01043 LiveChars _liveChars;
01044
01046
01050 typedef std::deque<ExecutableCode*> ActionQueue;
01051 ActionQueue _actionQueue[PRIORITY_SIZE];
01052
01054 void processActionQueue();
01055
01057 size_t _stageWidth;
01058 size_t _stageHeight;
01059
01060 rgba m_background_color;
01061 bool m_background_color_set;
01062
01063 boost::int32_t _mouseX;
01064 boost::int32_t _mouseY;
01065
01066 MouseButtonState _mouseButtonState;
01067
01069 typedef std::set<ActiveRelay*> ObjectCallbacks;
01070 ObjectCallbacks _objectCallbacks;
01071
01072 LoadCallbacks _loadCallbacks;
01073
01074 typedef std::map<int, Timer*> TimerMap;
01075 TimerMap _intervalTimers;
01076 unsigned int _lastTimerId;
01077
01079 Keys _unreleasedKeys;
01080
01081 key::code _lastKeyEvent;
01082
01084 Listeners _keyListeners;
01085
01087 DisplayObject* _currentFocus;
01088
01090 drag_state m_drag_state;
01091
01092 typedef std::map<int, MovieClip*> Levels;
01093
01095
01099 Levels _movies;
01100
01104 Movie* _rootMovie;
01105
01107 bool _invalidated;
01108
01111 bool _disableScripts;
01112 int _processingActionLevel;
01113
01115
01117 int _hostfd;
01118 int _controlfd;
01119
01121
01124 Quality _quality;
01125
01127 std::bitset<4u> _alignMode;
01128
01129 AllowScriptAccessMode _allowScriptAccess;
01130 bool _marshallExceptions;
01131
01133 bool _showMenu;
01134
01136 ScaleMode _scaleMode;
01137
01139 DisplayState _displayState;
01140
01141
01142 boost::uint16_t _recursionLimit;
01143
01144
01145 boost::uint16_t _timeoutLimit;
01146
01147
01148 size_t _movieAdvancementDelay;
01149
01150
01151 size_t _lastMovieAdvancement;
01152
01154 size_t _unnamedInstance;
01155
01156 MovieLoader _movieLoader;
01157 };
01158
01160
01168 bool isLevelTarget(int version, const std::string& name, unsigned int& levelno);
01169
01170 DSOEXPORT short stringToStageAlign(const std::string& s);
01171
01172 }
01173
01174 #endif // GNASH_MOVIE_ROOT_H
01175
01176
01177
01178
01179