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