File indexing completed on 2024-04-21 04:54:08
0001 /* 0002 SPDX-FileCopyrightText: 2004 Koos Vriezen <koos.vriezen@xs4all.nl> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 0006 until boost gets common, a more or less compatable one .. 0007 */ 0008 0009 #ifndef _KMPLAYER_PLAYLIST_H_ 0010 #define _KMPLAYER_PLAYLIST_H_ 0011 0012 #include "config-kmplayer.h" 0013 #include <sys/time.h> 0014 0015 #include <QString> 0016 0017 #include "kmplayercommon_export.h" 0018 #include "kmplayertypes.h" 0019 #include "kmplayershared.h" 0020 0021 typedef struct _cairo_surface cairo_surface_t; 0022 0023 class QTextStream; 0024 class QUrl; 0025 0026 namespace KMPlayer { 0027 0028 class Document; 0029 class KMPLAYERCOMMON_EXPORT Node; 0030 class TextNode; 0031 class Posting; 0032 class Mrl; 0033 class ElementPrivate; 0034 class Visitor; 0035 class MediaInfo; 0036 0037 template <class T> class KMPLAYERCOMMON_EXPORT GlobalShared 0038 { 0039 T **global; 0040 int refcount; 0041 public: 0042 GlobalShared (T **glob); 0043 virtual ~GlobalShared () {} 0044 0045 void ref () { refcount++; } 0046 void unref(); 0047 }; 0048 0049 template <class T> 0050 inline GlobalShared<T>::GlobalShared (T **glob) : global (glob), refcount (1) { 0051 *global = static_cast <T*> (this); 0052 } 0053 0054 template <class T> inline void GlobalShared<T>::unref() { 0055 if (--refcount <= 0) { 0056 *global = nullptr; 0057 delete this; 0058 } 0059 } 0060 0061 /* 0062 * Base class for objects that will be used as SharedPtr/WeakPtr pointers. 0063 * Item<T> keeps its own copy of the shared SharedData<T> as a weak refence. 0064 * \sa: self() 0065 */ 0066 template <class T> 0067 class KMPLAYERCOMMON_EXPORT Item 0068 { 0069 friend class SharedPtr<T>; 0070 friend class WeakPtr<T>; 0071 public: 0072 typedef SharedPtr <T> SharedType; 0073 typedef WeakPtr <T> WeakType; 0074 0075 SharedType self () const { return m_self; } 0076 protected: 0077 Item (); 0078 WeakType m_self; 0079 private: 0080 Item (const Item <T> &); // forbidden copy constructor 0081 }; 0082 0083 /** 0084 * Because of the m_self member of Item<T>, it's not allowed to assign a 0085 * Item<T>* directly to SharedPtr<Item<T>>. Item<T>* will then reside in 0086 * two independent SharedData<Item<T>> objects. 0087 * So specialize constructor and assignment operators to fetch the 0088 * SharedData<Item<T>> from the Item<T>* instead of creating a new one 0089 */ 0090 #define ITEM_AS_POINTER(CLASS) \ 0091 template <> inline SharedPtr<CLASS>::SharedPtr (CLASS * t) \ 0092 : data (t ? t->m_self.data : nullptr) { \ 0093 if (data) \ 0094 data->addRef (); \ 0095 } \ 0096 \ 0097 template <> \ 0098 inline SharedPtr<CLASS> & SharedPtr<CLASS>::operator = (CLASS * t) { \ 0099 if (t) { \ 0100 operator = (t->m_self); \ 0101 } else if (data) { \ 0102 data->release (); \ 0103 data = nullptr; \ 0104 } \ 0105 return *this; \ 0106 } \ 0107 \ 0108 template <> inline WeakPtr<CLASS>::WeakPtr (CLASS * t) \ 0109 : data (t ? t->m_self.data : nullptr) { \ 0110 if (data) \ 0111 data->addWeakRef (); \ 0112 } \ 0113 \ 0114 template <> \ 0115 inline WeakPtr<CLASS> & WeakPtr<CLASS>::operator = (CLASS * t) { \ 0116 if (t) { \ 0117 operator = (t->m_self); \ 0118 } else if (data) { \ 0119 data->releaseWeak (); \ 0120 data = nullptr; \ 0121 } \ 0122 return *this; \ 0123 } 0124 0125 /* 0126 * A double linked list of ListNodeBase<T> nodes 0127 */ 0128 template <class T> 0129 class KMPLAYERCOMMON_EXPORT List 0130 { 0131 public: 0132 List () {} 0133 List (typename Item<T>::SharedType f, typename Item<T>::SharedType l) 0134 : m_first (f), m_last (l) {} 0135 ~List () { clear (); } 0136 0137 T* first () const { return m_first.ptr (); } 0138 T* last () const { return m_last.ptr (); } 0139 void append (T *c); 0140 void splice (T *pos, List <T> &lst); 0141 void insertBefore (T *c, T *b); 0142 void remove (T *c); 0143 void clear (); 0144 unsigned int length () const; 0145 T* item (int i) const; 0146 0147 protected: 0148 typename Item<T>::SharedType m_first; 0149 typename Item<T>::WeakType m_last; 0150 }; 0151 0152 /* 0153 * Base class for double linked list nodes of SharedPtr/WeakPtr objects. 0154 * The linkage is a shared nextSibling and a weak previousSibling. 0155 */ 0156 template <class T> 0157 class KMPLAYERCOMMON_EXPORT ListNodeBase : public Item <T> 0158 { 0159 friend class List<T>; 0160 public: 0161 T* nextSibling () const { return m_next.ptr (); } 0162 T* previousSibling () const { return m_prev.ptr (); } 0163 protected: 0164 ListNodeBase () {} 0165 typename Item<T>::SharedType m_next; 0166 typename Item<T>::WeakType m_prev; 0167 }; 0168 0169 /* 0170 * ListNode for class T storage 0171 */ 0172 template <class T> 0173 class ListNode : public ListNodeBase <ListNode <T> > { 0174 public: 0175 ListNode (T d) : data (d) {} 0176 T data; 0177 }; 0178 0179 /* 0180 * Base class for double linked tree nodes having parent/siblings/children. 0181 * The linkage is a shared firstChild and weak parentNode. 0182 */ 0183 template <class T> 0184 class KMPLAYERCOMMON_EXPORT TreeNode : public ListNodeBase <T> 0185 { 0186 public: 0187 void insertBefore (T *c, T *b); 0188 void appendChild (T *c); 0189 void removeChild (typename Item<T>::SharedType c); 0190 0191 bool hasChildNodes () const { return m_first_child != nullptr; } 0192 T* parentNode () const { return m_parent.ptr (); } 0193 T* firstChild () const { return m_first_child.ptr (); } 0194 T* lastChild () const { return m_last_child.ptr (); } 0195 0196 protected: 0197 TreeNode () {} 0198 void insertBeforeImpl (T *c, T *b); 0199 void appendChildImpl (T *c); 0200 void removeChildImpl (typename Item<T>::SharedType c); 0201 typename Item<T>::WeakType m_parent; 0202 typename Item<T>::SharedType m_first_child; 0203 typename Item<T>::WeakType m_last_child; 0204 }; 0205 0206 /** 0207 * Attribute having a name/value pair for use with Elements 0208 */ 0209 class KMPLAYERCOMMON_EXPORT Attribute : public ListNodeBase <Attribute> 0210 { 0211 public: 0212 Attribute () {} 0213 Attribute (const TrieString &ns, const TrieString &n, const QString &v); 0214 ~Attribute () {} 0215 TrieString ns () const { return m_namespace; } 0216 TrieString name () const { return m_name; } 0217 QString value () const { return m_value; } 0218 void setName (const TrieString &); 0219 void setValue (const QString &); 0220 protected: 0221 TrieString m_namespace; 0222 TrieString m_name; 0223 QString m_value; 0224 }; 0225 0226 ITEM_AS_POINTER(KMPlayer::Attribute) 0227 0228 /** 0229 * Object should scale according the passed Fit value in SizedEvent 0230 */ 0231 enum Fit { 0232 fit_default, // fill hidden 0233 fit_fill, // fill complete area, no aspect preservation 0234 fit_hidden, // keep aspect and don't scale, cut off what doesn't fit 0235 fit_meet, // keep aspect and scale so that the smallest size just fits 0236 fit_slice, // keep aspect and scale so that the largest size just fits 0237 fit_scroll // keep aspect and don't scale, add scollbars if needed 0238 }; 0239 0240 enum MessageType 0241 { 0242 MsgEventTimer = 0, 0243 MsgEventClicked, 0244 MsgEventPointerMoved, 0245 MsgEventPointerInBounds, 0246 MsgEventPointerOutBounds, 0247 MsgEventStarting, 0248 MsgEventStarted, 0249 MsgEventStopped, 0250 MsgMediaFinished, 0251 MsgStateChanged, 0252 MsgAccessKey, 0253 // the above messages are ordered like SMIL timing events 0254 MsgMediaPrefetch, 0255 MsgMediaReady, 0256 MsgMediaUpdated, 0257 MsgEventPostponed, 0258 MsgSurfaceBoundsUpdate, // bool parent surface resized 0259 MsgSurfaceUpdate, 0260 MsgSurfaceAttach, 0261 MsgStateFreeze, 0262 MsgStateRewind, 0263 MsgChildReady, 0264 MsgChildTransformedIn, 0265 MsgChildFinished, 0266 0267 MsgInfoString // QString* 0268 }; 0269 0270 enum RoleType 0271 { 0272 RoleReady, 0273 RoleMediaManager, 0274 RoleTiming, 0275 RoleDisplay, 0276 RoleChildDisplay, // Mrl* 0277 RoleSizer, 0278 RoleReceivers, 0279 RolePlaylist 0280 }; 0281 0282 #define MsgUnhandled ((void *) 357L) 0283 0284 #define MsgBool(x) \ 0285 (void*)(long)(x) 0286 0287 #define nodeMessageReceivers(node, msg) \ 0288 (ConnectionList*)(node)->role (RoleReceivers, (void*)(long)(msg)) 0289 0290 // convenient types 0291 typedef void Role; 0292 typedef Item<Node>::SharedType NodePtr; 0293 typedef Item<Node>::WeakType NodePtrW; 0294 typedef Item<Attribute>::SharedType AttributePtr; 0295 typedef Item<Attribute>::WeakType AttributePtrW; 0296 typedef List<Node> NodeList; // eg. for Node's children 0297 typedef List<Attribute> AttributeList; // eg. for Element's attributes 0298 typedef ListNode<NodePtrW> NodeRefItem; // Node for ref Nodes 0299 ITEM_AS_POINTER(KMPlayer::NodeRefItem) 0300 typedef ListNode<NodePtr> NodeStoreItem; // list stores Nodes 0301 typedef List<NodeStoreItem> NodeStoreList; 0302 typedef NodeRefItem::SharedType NodeRefItemPtr; 0303 typedef NodeRefItem::WeakType NodeRefItemPtrW; 0304 typedef List<NodeRefItem> NodeRefList; // ref nodes, eg. event receivers 0305 0306 template <> void TreeNode<Node>::appendChild (Node *c); 0307 template <> void TreeNode<Node>::insertBefore (Node *c, Node *b); 0308 template <> void TreeNode<Node>::removeChild (NodePtr c); 0309 0310 /* 0311 * Message connection between signaler and the listener node 0312 */ 0313 0314 class ConnectionList; 0315 0316 #ifdef KMPLAYER_TEST_CONNECTION 0317 extern int connection_counter; 0318 #endif 0319 0320 struct VirtualVoid { 0321 virtual ~VirtualVoid () {} 0322 }; 0323 0324 struct KeyLoad : public VirtualVoid { 0325 KeyLoad (int ch) : key (ch) {} 0326 int key; 0327 }; 0328 0329 struct Connection { 0330 NodePtrW connectee; // the one that will, when ever, trigger the event 0331 NodePtrW connecter; // the one that will, when ever, receive the event 0332 Connection (Node *invoker, Node*receiver, VirtualVoid *payload); 0333 ~Connection () { 0334 delete payload; 0335 #ifdef KMPLAYER_TEST_CONNECTION 0336 connection_counter--; 0337 #endif 0338 } 0339 VirtualVoid *payload; 0340 ConnectionList *list; 0341 Connection **link; 0342 Connection *prev; 0343 Connection *next; 0344 }; 0345 0346 class ConnectionLink { 0347 #ifdef KMPLAYER_TEST_CONNECTION 0348 public: 0349 #endif 0350 mutable Connection *connection; 0351 public: 0352 ConnectionLink (); 0353 ~ConnectionLink (); 0354 0355 bool connect (Node *signaler, MessageType msg, Node *receiver, 0356 VirtualVoid *payload=nullptr); 0357 void disconnect () const; 0358 void assign (const ConnectionLink *link) const; 0359 0360 Node *signaler () const; 0361 private: 0362 ConnectionLink (const ConnectionLink &); 0363 ConnectionLink &operator = (const ConnectionLink &); 0364 }; 0365 0366 class ConnectionList { 0367 #ifdef KMPLAYER_TEST_CONNECTION 0368 public: 0369 #endif 0370 friend class ConnectionLink; 0371 Connection *link_first; 0372 Connection *link_last; 0373 Connection *link_next; 0374 public: 0375 ConnectionList (); 0376 ~ConnectionList () KMPLAYERCOMMON_EXPORT; 0377 0378 Connection *first () { 0379 link_next = link_first ? link_first->next : nullptr; 0380 return link_first; 0381 } 0382 Connection *next () { 0383 Connection *tmp = link_next; 0384 link_next = link_next ? link_next->next : nullptr; 0385 return tmp; 0386 } 0387 void clear (); 0388 }; 0389 0390 0391 struct XMLStringlet { 0392 const QString str; 0393 XMLStringlet (const QString & s) : str (s) {} 0394 }; 0395 0396 QTextStream & operator << (QTextStream &out, const XMLStringlet &txt); 0397 0398 /* 0399 * Base class for XML nodes. Provides a w3c's DOM like API 0400 * 0401 * Most severe traps with using SharedPtr/WeakPtr for tree nodes: 0402 * - pointer ends up in two independent shared objects (hopefully with 0403 * template specialization for constructor for T* and assignment of T* should 0404 * be enough of defences ..) 0405 * - Node added two times (added ASSERT in appendChild/insertBefore) 0406 * - Node is destroyed before being stored in a SharedPtr with kmplayer usage 0407 * of each object having a WeakPtr to itself (eg. be extremely careful with 0408 * using m_self in the constructor, no SharedPtr storage yet) 0409 * 0410 * Livetime of an element is 0411 |-->state_activated<-->state_began<-->state_finished-->state_deactivated-->| 0412 In scope begin event end event Out scope 0413 */ 0414 class KMPLAYERCOMMON_EXPORT Node : public TreeNode <Node> 0415 { 0416 friend class DocumentBuilder; 0417 public: 0418 enum State { 0419 state_init, state_deferred, 0420 state_activated, state_began, state_finished, 0421 state_deactivated, state_resetting 0422 }; 0423 enum PlayType { 0424 play_type_none, play_type_unknown, play_type_info, 0425 play_type_image, play_type_audio, play_type_video 0426 }; 0427 virtual ~Node (); 0428 Document * document (); 0429 virtual Mrl * mrl (); 0430 virtual Node *childFromTag (const QString & tag); 0431 void characterData(const QString& s) KMPLAYERCOMMON_NO_EXPORT; 0432 QString innerText () const; 0433 QString innerXML () const; 0434 QString outerXML () const; 0435 virtual const char * nodeName () const; 0436 virtual QString nodeValue () const; 0437 virtual void setNodeName (const QString &) {} 0438 0439 /** 0440 * If this is a derived Mrl object and has a SRC attribute 0441 */ 0442 virtual PlayType playType (); 0443 bool isPlayable () { return playType () > play_type_none; } 0444 virtual bool isElementNode () const { return false; } 0445 /** 0446 * If this node purpose is for storing runtime data only, 0447 * ie. node doesn't exist in the original document 0448 */ 0449 bool auxiliaryNode () const { return auxiliary_node; } 0450 void setAuxiliaryNode (bool b) { auxiliary_node = b; } 0451 /* 0452 * Message send to this node 0453 */ 0454 virtual void message (MessageType msg, void *content=nullptr); 0455 /* 0456 * Query a role this Node may fulfill 0457 */ 0458 virtual void *role (RoleType msg, void *content=nullptr); 0459 /* 0460 * Dispatch Event to all connectors of MessageType 0461 */ 0462 void deliver(MessageType msg, void *content) KMPLAYERCOMMON_NO_EXPORT; 0463 /** 0464 * Alternative to event handling is the Visitor pattern 0465 */ 0466 virtual void accept (Visitor *); 0467 /** 0468 * Activates element, sets state to state_activated. Will call activate() on 0469 * firstChild or call deactivate(). 0470 */ 0471 virtual void activate (); 0472 /** 0473 * if state is between state_activated and state_deactivated 0474 */ 0475 bool active () const 0476 { return state >= state_deferred && state < state_deactivated; } 0477 /** 0478 * if state is between state_activated and state_finished 0479 */ 0480 bool unfinished () const 0481 { return state > state_deferred && state < state_finished; } 0482 /** 0483 * Defers an activated, so possible playlists items can be added. 0484 */ 0485 virtual void defer (); 0486 /** 0487 * Puts a deferred element in activated again, calls activate() again 0488 */ 0489 virtual void undefer (); 0490 /** 0491 * Sets state to state_begin when active 0492 */ 0493 virtual void begin (); 0494 /** 0495 * Sets state to state_finish when >= state_activated. 0496 * Notifies parent with a MsgChildFinished message. 0497 */ 0498 virtual void finish (); 0499 /** 0500 * Stops element, sets state to state_deactivated. Calls deactivate() on 0501 * activated/deferred children. May call childDone() when active() and not 0502 * finished yet. 0503 */ 0504 virtual void deactivate (); 0505 /** 0506 * Resets element, calls deactivate() if state is state_activated and sets 0507 * state to state_init. 0508 */ 0509 virtual void reset (); 0510 virtual void clear (); 0511 void clearChildren (); 0512 void replaceChild(NodePtr _new, NodePtr old) KMPLAYERCOMMON_NO_EXPORT; 0513 /* 0514 * Get rid of whitespace only text nodes 0515 */ 0516 void normalize (); 0517 KMPLAYERCOMMON_NO_EXPORT bool isDocument () const { return m_doc == m_self; } 0518 0519 NodeList childNodes() const KMPLAYERCOMMON_NO_EXPORT; 0520 void setState (State nstate); 0521 /* 0522 * Open tag is found by parser, attributes are set 0523 */ 0524 virtual void opened (); 0525 /* 0526 * Close tag is found by parser, children are appended 0527 */ 0528 virtual void closed (); 0529 protected: 0530 Node(NodePtr& d, short _id=0); 0531 NodePtr m_doc; 0532 public: 0533 State state; 0534 short id; 0535 bool auxiliary_node : 1; 0536 bool open : 1; 0537 }; 0538 0539 ITEM_AS_POINTER(KMPlayer::Node) 0540 0541 const short id_node_document = 1; 0542 const short id_node_record_document = 2; 0543 const short id_node_grab_document = 3; 0544 const short id_node_text = 5; 0545 const short id_node_cdata = 6; 0546 0547 const short id_node_group_node = 25; 0548 const short id_node_playlist_document = 26; 0549 const short id_node_playlist_item = 27; 0550 const short id_node_param = 28; 0551 const short id_node_html_object = 29; 0552 const short id_node_html_embed = 30; 0553 const short id_node_svg = 31; 0554 0555 /* 0556 * Element node, XML node that can have attributes 0557 */ 0558 class KMPLAYERCOMMON_EXPORT Element : public Node 0559 { 0560 public: 0561 ~Element () override; 0562 void setAttributes (const AttributeList &attrs); 0563 void setAttribute (const TrieString & name, const QString & value); 0564 QString getAttribute (const TrieString & name); 0565 KMPLAYERCOMMON_NO_EXPORT AttributeList &attributes () { return m_attributes; } 0566 KMPLAYERCOMMON_NO_EXPORT AttributeList attributes () const { return m_attributes; } 0567 virtual void init (); 0568 void reset () override; 0569 void clear () override; 0570 bool isElementNode () const override { return true; } 0571 void accept (Visitor * v) override; 0572 /** 0573 * Params are like attributes, but meant to be set dynamically. Caller may 0574 * pass a modification id, that it can use to restore the old value. 0575 * Param will be auto removed on deactivate 0576 */ 0577 void setParam (const TrieString ¶, const QString &val, int *mod_id=nullptr); 0578 QString param (const TrieString & para); 0579 void resetParam (const TrieString & para, int mod_id); 0580 /** 0581 * Called from (re)setParam for specialized interpretation of params 0582 **/ 0583 virtual void parseParam (const TrieString &, const QString &) {} 0584 protected: 0585 Element (NodePtr & d, short id=0); 0586 AttributeList m_attributes; 0587 private: 0588 ElementPrivate * d; 0589 }; 0590 0591 template <class T> 0592 inline T * convertNode (NodePtr e) 0593 { 0594 return static_cast <T *> (e.ptr ()); 0595 } 0596 0597 KMPLAYERCOMMON_NO_EXPORT 0598 inline Node *findChildWithId (const Node *p, const short id) { 0599 for (Node *c = p->firstChild (); c; c = c->nextSibling ()) 0600 if (id == c->id) 0601 return c; 0602 return nullptr; 0603 } 0604 0605 class KMPLAYERCOMMON_EXPORT PlaylistRole 0606 { 0607 public: 0608 PlaylistRole () : editable (false) {} 0609 0610 QString caption () const; 0611 void setCaption (const QString &t); 0612 0613 QString title; 0614 bool editable; 0615 }; 0616 0617 /** 0618 * Element representing a playable link, like URL to a movie or playlist. 0619 */ 0620 class KMPLAYERCOMMON_EXPORT Mrl : public Element, public PlaylistRole 0621 { 0622 protected: 0623 Mrl (NodePtr & d, short id=0); 0624 Node *childFromTag (const QString & tag) override; 0625 void parseParam (const TrieString &, const QString &) override; 0626 unsigned int cached_ismrl_version; 0627 PlayType cached_play_type; 0628 0629 public: 0630 enum { SingleMode = 0, WindowMode }; 0631 0632 ~Mrl () override; 0633 PlayType playType () override; 0634 Mrl * mrl () override; 0635 /// Returns the resolved full url 0636 QString absolutePath () const; 0637 0638 void activate () override; 0639 void begin () override; 0640 void defer () override; 0641 void undefer () override; 0642 void deactivate () override; 0643 void message (MessageType msg, void *content=nullptr) override; 0644 void *role (RoleType msg, void *content=nullptr) override; 0645 0646 static unsigned int parseTimeString (const QString &s); 0647 0648 /** 0649 * If this Mrl is top node of external document, opener has the 0650 * location in SCR. Typically that's the parent of this node. 0651 */ 0652 NodePtrW opener; //if this node is top node of external document, 0653 MediaInfo *media_info; 0654 QString src; 0655 QString mimetype; 0656 SSize size; 0657 float aspect; 0658 int repeat; 0659 unsigned char view_mode; 0660 bool resolved; 0661 bool bookmarkable; 0662 bool access_granted; 0663 }; 0664 0665 /** 0666 * Document listener interface 0667 */ 0668 class KMPLAYERCOMMON_EXPORT PlayListNotify 0669 { 0670 public: 0671 virtual ~PlayListNotify() { } 0672 /** 0673 * Element has activated or deactivated notification 0674 */ 0675 virtual void stateElementChanged(Node *n, Node::State os, Node::State ns)=0; 0676 /** 0677 * Ask for connection bitrates settings 0678 */ 0679 virtual void bitRates (int & preferred, int & maximal) = 0; 0680 /** 0681 * Sets next call to Document::timer() or -1 to cancel a previous call 0682 */ 0683 virtual void setTimeout (int ms) = 0; 0684 /** 0685 * Request to open url with mimetype 0686 */ 0687 virtual void openUrl (const QUrl &, const QString &t, const QString &srv)=0; 0688 /** 0689 * Dis/Enable repaint updaters 0690 */ 0691 virtual void enableRepaintUpdaters (bool enable, unsigned int off_time)=0; 0692 }; 0693 0694 /* 0695 * A generic type for posting messages 0696 **/ 0697 class KMPLAYERCOMMON_EXPORT Posting 0698 { 0699 public: 0700 Posting (Node *n, MessageType msg, VirtualVoid *p=nullptr) 0701 : source (n), message (msg), payload (p) {} 0702 virtual ~Posting () {} 0703 NodePtrW source; 0704 MessageType message; 0705 VirtualVoid *payload; 0706 }; 0707 0708 /** 0709 * Posting signaling a timer event 0710 */ 0711 class TimerPosting : public Posting 0712 { 0713 public: 0714 TimerPosting (int ms, unsigned eid=0); 0715 unsigned event_id; 0716 int milli_sec; 0717 bool interval; // set to 'true' in 'Node::message()' to make it repeat 0718 }; 0719 0720 class UpdateEvent 0721 { 0722 public: 0723 UpdateEvent (Document *, unsigned int off_time); 0724 unsigned int cur_event_time; 0725 unsigned int skipped_time; 0726 }; 0727 0728 /** 0729 * Event signaling postponed or proceeded 0730 */ 0731 class PostponedEvent 0732 { 0733 public: 0734 PostponedEvent (bool postponed); 0735 bool is_postponed; // postponed or proceeded 0736 }; 0737 0738 /** 0739 * Postpone object representing a postponed document 0740 * During its livetime, no TimerEvent's happen 0741 */ 0742 class Postpone 0743 { 0744 friend class Document; 0745 struct timeval postponed_time; 0746 NodePtrW m_doc; 0747 Postpone (NodePtr doc); 0748 public: 0749 ~Postpone (); 0750 }; 0751 0752 typedef SharedPtr <Postpone> PostponePtr; 0753 typedef WeakPtr <Postpone> PostponePtrW; 0754 0755 struct EventData 0756 { 0757 EventData (Node *t, Posting *e, EventData *n); 0758 ~EventData (); 0759 0760 NodePtrW target; 0761 Posting *event; 0762 struct timeval timeout; 0763 0764 EventData *next; 0765 }; 0766 0767 /** 0768 * The root of the DOM tree 0769 */ 0770 class KMPLAYERCOMMON_EXPORT Document : public Mrl 0771 { 0772 friend class Postpone; 0773 public: 0774 Document (const QString &, PlayListNotify * notify = nullptr); 0775 ~Document () override; 0776 Node *getElementById (const QString & id); 0777 Node *getElementById (Node *start, const QString & id, bool inter_doc); 0778 /** All nodes have shared pointers to Document, 0779 * so explicitly dispose it (calls clear and set m_doc to 0L) 0780 * */ 0781 void dispose (); 0782 Node *childFromTag (const QString & tag) override; 0783 KMPLAYERCOMMON_NO_EXPORT const char * nodeName () const override { return "document"; } 0784 void activate () override; 0785 void defer () override; 0786 void undefer () override; 0787 void reset () override; 0788 0789 Posting *post (Node *n, Posting *event); 0790 void cancelPosting (Posting *event); 0791 void pausePosting (Posting *e); 0792 void unpausePosting (Posting *e, int ms); 0793 0794 void timeOfDay (struct timeval &); 0795 PostponePtr postpone (); 0796 bool postponed () const { return !!postpone_ref || !! postpone_lock; } 0797 /** 0798 * Called by PlayListNotify, processes events in event_queue with timeout set to now 0799 */ 0800 void timer (); 0801 void updateTimeout (); 0802 /** 0803 * Document has list of postponed receivers, eg. for running (gif)movies 0804 */ 0805 void *role (RoleType msg, void *content=nullptr) override; 0806 0807 PlayListNotify *notify_listener; 0808 unsigned int m_tree_version; 0809 unsigned int last_event_time; 0810 private: 0811 void proceed (const struct timeval & postponed_time); 0812 void insertPosting (Node *n, Posting *e, const struct timeval &tv); 0813 void setNextTimeout (const struct timeval &now); 0814 0815 PostponePtrW postpone_ref; 0816 PostponePtr postpone_lock; 0817 ConnectionList m_PostponedListeners; 0818 EventData *event_queue; 0819 EventData *paused_queue; 0820 EventData *cur_event; 0821 int cur_timeout; 0822 struct timeval first_event_time; 0823 }; 0824 0825 namespace SMIL { 0826 class Smil; 0827 class Layout; 0828 class RegionBase; 0829 class Seq; 0830 class Switch; 0831 class Par; 0832 class Excl; 0833 class Transition; 0834 class AnimateBase; 0835 class MediaType; 0836 class TextMediaType; 0837 class RefMediaType; 0838 class Brush; 0839 class SmilText; 0840 class TextFlow; 0841 class TemporalMoment; 0842 class PriorityClass; 0843 class Anchor; 0844 class Area; 0845 } 0846 namespace RP { 0847 class Imfl; 0848 class Crossfade; 0849 class Fadein; 0850 class Fadeout; 0851 class Fill; 0852 class Wipe; 0853 class ViewChange; 0854 class Animate; 0855 } 0856 0857 class Visitor 0858 { 0859 public: 0860 Visitor () {} 0861 virtual ~Visitor () {} 0862 virtual void visit (Node *) {} 0863 virtual void visit (TextNode *); 0864 virtual void visit (Element *); 0865 virtual void visit (SMIL::Smil *) {} 0866 virtual void visit (SMIL::Layout *); 0867 virtual void visit (SMIL::RegionBase *); 0868 virtual void visit (SMIL::Seq *); 0869 virtual void visit (SMIL::Switch *); 0870 virtual void visit (SMIL::Par *); 0871 virtual void visit (SMIL::Excl *); 0872 virtual void visit (SMIL::Transition *); 0873 virtual void visit (SMIL::AnimateBase *); 0874 virtual void visit (SMIL::PriorityClass *); 0875 virtual void visit (SMIL::MediaType *); 0876 virtual void visit (SMIL::TextMediaType *); 0877 virtual void visit (SMIL::RefMediaType *); 0878 virtual void visit (SMIL::Brush *); 0879 virtual void visit (SMIL::SmilText *); 0880 virtual void visit (SMIL::TextFlow *); 0881 virtual void visit (SMIL::TemporalMoment *); 0882 virtual void visit (SMIL::Anchor *); 0883 virtual void visit (SMIL::Area *); 0884 virtual void visit (RP::Imfl *) {} 0885 virtual void visit (RP::Crossfade *) {} 0886 virtual void visit (RP::Fadein *) {} 0887 virtual void visit (RP::Fadeout *) {} 0888 virtual void visit (RP::Fill *) {} 0889 virtual void visit (RP::Wipe *) {} 0890 virtual void visit (RP::ViewChange *) {} 0891 virtual void visit (RP::Animate *) {} 0892 }; 0893 0894 /** 0895 * Represents XML text, like "some text" in '<foo>some text</foo>' 0896 */ 0897 class KMPLAYERCOMMON_EXPORT TextNode : public Node 0898 { 0899 public: 0900 TextNode(NodePtr& d, const QString& s, short _id = id_node_text); 0901 ~TextNode () override {} 0902 void appendText (const QString & s); 0903 void setText (const QString & txt) { text = txt; } 0904 const char * nodeName () const override { return "#text"; } 0905 void accept (Visitor *v) override { v->visit (this); } 0906 QString nodeValue () const override; 0907 protected: 0908 QString text; 0909 }; 0910 0911 /** 0912 * Represents cdata sections, like "some text" in '<![CDATA[some text]]>' 0913 */ 0914 class KMPLAYERCOMMON_EXPORT CData : public TextNode 0915 { 0916 public: 0917 CData(NodePtr& d, const QString& s); 0918 ~CData () override {} 0919 const char * nodeName () const override { return "#cdata"; } 0920 }; 0921 0922 /** 0923 * Unrecognized tag by parent element or just some auxiliary node 0924 */ 0925 class KMPLAYERCOMMON_EXPORT DarkNode : public Element 0926 { 0927 public: 0928 DarkNode (NodePtr & d, const QByteArray &n, short id=0); 0929 ~DarkNode () override {} 0930 const char * nodeName () const override { return name.data (); } 0931 Node *childFromTag (const QString & tag) override; 0932 protected: 0933 QByteArray name; 0934 }; 0935 0936 //----------------------------------------------------------------------------- 0937 0938 /** 0939 * just some url, can get a SMIL, RSS, or ASX childtree 0940 */ 0941 class KMPLAYERCOMMON_EXPORT GenericURL : public Mrl 0942 { 0943 public: 0944 GenericURL(NodePtr &d, const QString &s, const QString &n=QString ()); 0945 KMPLAYERCOMMON_NO_EXPORT const char * nodeName () const override { return "url"; } 0946 void closed() override KMPLAYERCOMMON_NO_EXPORT; 0947 }; 0948 0949 /** 0950 * Non url mrl 0951 */ 0952 class KMPLAYERCOMMON_EXPORT GenericMrl : public Mrl 0953 { 0954 public: 0955 GenericMrl (NodePtr & d) : Mrl (d), node_name ("mrl") {} 0956 GenericMrl(NodePtr &d, const QString &s, const QString &name=QString (), const QByteArray &tag=QByteArray ("mrl")); 0957 KMPLAYERCOMMON_NO_EXPORT const char * nodeName () const override { return node_name.data (); } 0958 void closed () override; 0959 void *role (RoleType msg, void *content=nullptr) override; 0960 QByteArray node_name; 0961 }; 0962 0963 KMPLAYERCOMMON_EXPORT 0964 void readXML (NodePtr root, QTextStream & in, const QString & firstline, bool set_opener=true); 0965 KMPLAYERCOMMON_EXPORT Node * fromXMLDocumentTag (NodePtr & d, const QString & tag); 0966 0967 template <class T> 0968 inline Item<T>::Item () : m_self (static_cast <T*> (this), true) {} 0969 0970 template <class T> inline void List<T>::append (T *c) { 0971 if (!m_first) { 0972 m_first = c->m_self; 0973 m_last = c->m_self; 0974 } else { 0975 m_last->m_next = c->m_self; 0976 c->m_prev = m_last; 0977 m_last = c->m_self; 0978 } 0979 } 0980 0981 template <class T> inline void List<T>::splice (T *pos, List <T> &lst) { 0982 if (lst.m_first) { 0983 if (!pos) { 0984 if (!m_first) 0985 m_first = lst.m_first; 0986 else 0987 m_last->m_next = lst.m_first; 0988 m_last = lst.m_last; 0989 } else { 0990 lst.m_last->m_next = pos; 0991 if (!pos->m_prev) // pos must be first 0992 m_first = lst.m_first; 0993 else 0994 pos->m_prev->m_next = lst.m_first; 0995 } 0996 lst.m_first = NULL; 0997 lst.m_last = NULL; 0998 } 0999 } 1000 1001 template <class T> inline void List<T>::insertBefore (T *c, T *b) { 1002 if (!b) { 1003 append (c); 1004 } else { 1005 c->m_next = b->m_self; 1006 if (b->m_prev) { 1007 b->m_prev->m_next = c->m_self; 1008 c->m_prev = b->m_prev; 1009 } else { 1010 c->m_prev = nullptr; 1011 m_first = c->m_self; 1012 } 1013 b->m_prev = c->m_self; 1014 } 1015 } 1016 1017 template <class T> inline void List<T>::remove (T *c) { 1018 typename Item<T>::SharedType s = c->m_self; 1019 if (c->m_prev) 1020 c->m_prev->m_next = c->m_next; 1021 else 1022 m_first = c->m_next; 1023 if (c->m_next) { 1024 c->m_next->m_prev = c->m_prev; 1025 c->m_next = nullptr; 1026 } else { 1027 m_last = c->m_prev; 1028 } 1029 c->m_prev = nullptr; 1030 } 1031 1032 template <class T> inline unsigned int List<T>::length () const { 1033 unsigned int count = 0; 1034 for (T *t = m_first.ptr (); t; t = t->nextSibling ()) 1035 count++; 1036 return count; 1037 } 1038 1039 template <class T> inline void List<T>::clear () { 1040 m_first = m_last = nullptr; 1041 } 1042 1043 template <class T> 1044 inline T* List<T>::item (int i) const { 1045 for (T *t = m_first.ptr (); t; t = t->nextSibling(), --i) 1046 if (i == 0) 1047 return t; 1048 return NULL; 1049 } 1050 1051 template <class T> 1052 inline void TreeNode<T>::appendChildImpl (T *c) { 1053 if (!m_first_child) { 1054 m_first_child = c->m_self; 1055 m_last_child = c->m_self; 1056 } else { 1057 m_last_child->m_next = c->m_self; 1058 c->m_prev = m_last_child; 1059 m_last_child = c->m_self; 1060 } 1061 c->m_parent = Item<T>::m_self; 1062 } 1063 1064 template <class T> 1065 inline void TreeNode<T>::insertBeforeImpl (T *c, T *b) { 1066 if (!b) { 1067 appendChild (c); 1068 } else { 1069 c->m_next = b->m_self; 1070 if (b->m_prev) { 1071 b->m_prev->m_next = c->m_self; 1072 c->m_prev = b->m_prev; 1073 } else { 1074 c->m_prev = nullptr; 1075 m_first_child = c->m_self; 1076 } 1077 b->m_prev = c->m_self; 1078 c->m_parent = Item<T>::m_self; 1079 } 1080 } 1081 1082 template <class T> 1083 inline void TreeNode<T>::removeChildImpl (typename Item<T>::SharedType c) { 1084 if (c->m_prev) { 1085 c->m_prev->m_next = c->m_next; 1086 } else 1087 m_first_child = c->m_next; 1088 if (c->m_next) { 1089 c->m_next->m_prev = c->m_prev; 1090 c->m_next = nullptr; 1091 } else 1092 m_last_child = c->m_prev; 1093 c->m_prev = nullptr; 1094 c->m_parent = nullptr; 1095 } 1096 1097 inline NodeList Node::childNodes () const { 1098 return NodeList (m_first_child, m_last_child); 1099 } 1100 1101 } // KMPlayer namespace 1102 1103 #endif //_KMPLAYER_PLAYLIST_H_