add movemode in channellist (later it should only useable in bouquets)
[enigma2.git] / lib / service / iservice.h
1 #ifndef __lib_dvb_iservice_h
2 #define __lib_dvb_iservice_h
3
4 #include <lib/python/swig.h>
5 #include <lib/base/object.h>
6 #include <string>
7 #include <connection.h>
8 #include <list>
9
10 class eServiceReference
11 {
12 public:
13         enum
14         {
15                 idInvalid=-1,
16                 idStructure,    // service_id == 0 is root
17                 idDVB,
18                 idFile,
19                 idUser=0x1000
20         };
21         int type;
22
23         int flags; // flags will NOT be compared.
24         enum
25         {
26                 isDirectory=1,          // SHOULD enter  (implies mustDescent)
27                 mustDescent=2,          // cannot be played directly - often used with "isDirectory" (implies canDescent)
28                 /*
29                         for example:
30                                 normal services have none of them - they can be fed directly into the "play"-handler.
31                                 normal directories have both of them set - you cannot play a directory directly and the UI should descent into it.
32                                 playlists have "mustDescent", but not "isDirectory" - you don't want the user to browse inside the playlist (unless he really wants)
33                                 services with sub-services have none of them, instead the have the "canDecsent" flag (as all of the above)
34                 */
35                 canDescent=4,                   // supports enterDirectory/leaveDirectory
36                 flagDirectory=isDirectory|mustDescent|canDescent,
37                 shouldSort=8,                   // should be ASCII-sorted according to service_name. great for directories.
38                 hasSortKey=16,          // has a sort key in data[3]. not having a sort key implies 0.
39                 sort1=32                                        // sort key is 1 instead of 0
40         };
41
42         inline int getSortKey() const { return (flags & hasSortKey) ? data[3] : ((flags & sort1) ? 1 : 0); }
43
44         int data[8];
45         std::string path;
46
47         eServiceReference()
48                 : type(idInvalid), flags(0)
49         {
50         }
51
52         eServiceReference(int type, int flags)
53                 : type(type), flags(flags)
54         {
55                 memset(data, 0, sizeof(data));
56         }
57         eServiceReference(int type, int flags, int data0)
58                 : type(type), flags(flags)
59         {
60                 memset(data, 0, sizeof(data));
61                 data[0]=data0;
62         }
63         eServiceReference(int type, int flags, int data0, int data1)
64                 : type(type), flags(flags)
65         {
66                 memset(data, 0, sizeof(data));
67                 data[0]=data0;
68                 data[1]=data1;
69         }
70         eServiceReference(int type, int flags, int data0, int data1, int data2)
71                 : type(type), flags(flags)
72         {
73                 memset(data, 0, sizeof(data));
74                 data[0]=data0;
75                 data[1]=data1;
76                 data[2]=data2;
77         }
78         eServiceReference(int type, int flags, int data0, int data1, int data2, int data3)
79                 : type(type), flags(flags)
80         {
81                 memset(data, 0, sizeof(data));
82                 data[0]=data0;
83                 data[1]=data1;
84                 data[2]=data2;
85                 data[3]=data3;
86         }
87         eServiceReference(int type, int flags, int data0, int data1, int data2, int data3, int data4)
88                 : type(type), flags(flags)
89         {
90                 memset(data, 0, sizeof(data));
91                 data[0]=data0;
92                 data[1]=data1;
93                 data[2]=data2;
94                 data[3]=data3;
95                 data[4]=data4;
96         }
97         eServiceReference(int type, int flags, const std::string &path)
98                 : type(type), flags(flags), path(path)
99         {
100                 memset(data, 0, sizeof(data));
101         }
102         eServiceReference(const std::string &string);
103         std::string toString() const;
104         bool operator==(const eServiceReference &c) const
105         {
106                 if (type != c.type)
107                         return 0;
108                 return /* (flags == c.flags) && */ (memcmp(data, c.data, sizeof(int)*8)==0) && (path == c.path);
109         }
110         bool operator!=(const eServiceReference &c) const
111         {
112                 return !(*this == c);
113         }
114         bool operator<(const eServiceReference &c) const
115         {
116                 if (type < c.type)
117                         return 1;
118
119                 if (type > c.type)
120                         return 0;
121                         
122 /*              if (flags < c.flags)
123                         return 1;
124                 if (flags > c.flags)
125                         return 0; */
126
127                 int r=memcmp(data, c.data, sizeof(int)*8);
128                 if (r)
129                         return r < 0;
130                 return path < c.path;
131         }
132         operator bool() const
133         {
134                 return valid();
135         }
136         
137         int valid() const
138         {
139                 return type != idInvalid;
140         }
141 };
142
143 SWIG_ALLOW_OUTPUT_SIMPLE(eServiceReference);
144
145 typedef unsigned long long pts_t;
146
147         /* the reason we have the servicereference as additional argument is
148            that we don't have to create one object for every entry in a possibly
149            large list, provided that no state information is nessesary to deliver
150            the required information. Anyway - ref *must* be the same as the argument
151            to the info() or getIServiceInformation call! */
152
153         /* About the usage of SWIG_VOID:
154            SWIG_VOID(real_returntype_t) hides a return value from swig. This is used for
155            the "superflouus" RESULT return values.
156            
157            Python code has to check the returned pointer against 0. This works,
158            as all functions returning instances in smartpointers AND having a 
159            RESULT have to BOTH return non-zero AND set the pointer to zero.
160            
161            Python code thus can't check for the reason, but the reason isn't
162            user-servicable anyway. If you want to return a real reason which
163            goes beyong "it just doesn't work", use extra variables for this,
164            not the RESULT.
165            
166            Hide the result only if there is another way to check for failure! */
167            
168 class iStaticServiceInformation: public iObject
169 {
170 public:
171         virtual SWIG_VOID(RESULT) getName(const eServiceReference &ref, std::string &SWIG_OUTPUT)=0;
172         
173                 // doesn't need to be implemented, should return -1 then.
174         virtual int getLength(const eServiceReference &ref)=0;
175 };
176
177 TEMPLATE_TYPEDEF(ePtr<iStaticServiceInformation>, iStaticServiceInformationPtr);
178
179 class eServiceEvent;
180
181 TEMPLATE_TYPEDEF(ePtr<eServiceEvent>, eServiceEventPtr);
182
183 class iServiceInformation: public iObject
184 {
185 public:
186         virtual SWIG_VOID(RESULT) getName(std::string &SWIG_OUTPUT)=0;
187         virtual SWIG_VOID(RESULT) getEvent(ePtr<eServiceEvent> &SWIG_OUTPUT, int nownext);
188 };
189
190 TEMPLATE_TYPEDEF(ePtr<iServiceInformation>, iServiceInformationPtr);
191
192 class iPauseableService: public iObject
193 {
194 public:
195         virtual RESULT pause()=0;
196         virtual RESULT unpause()=0;
197 };
198
199 TEMPLATE_TYPEDEF(ePtr<iPauseableService>, iPauseableServicePtr);
200
201 class iSeekableService: public iObject
202 {
203 public:
204         virtual RESULT getLength(pts_t &SWIG_OUTPUT)=0;
205         virtual RESULT seekTo(pts_t to)=0;
206         virtual RESULT getPlayPosition(pts_t &SWIG_OUTPUT)=0;
207 };
208
209 TEMPLATE_TYPEDEF(ePtr<iSeekableService>, iSeekableServicePtr);
210
211 class iPlayableService: public iObject
212 {
213         friend class iServiceHandler;
214 public:
215         enum
216         {
217                 evStart,
218                 evEnd,
219                 
220                 // when iServiceInformation is implemented:
221                 evUpdatedEventInfo
222         };
223         virtual RESULT connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)=0;
224         virtual RESULT start()=0;
225         virtual RESULT stop()=0;
226         virtual SWIG_VOID(RESULT) seek(ePtr<iSeekableService> &SWIG_OUTPUT)=0;
227         virtual SWIG_VOID(RESULT) pause(ePtr<iPauseableService> &SWIG_OUTPUT)=0;
228         virtual SWIG_VOID(RESULT) info(ePtr<iServiceInformation> &SWIG_OUTPUT)=0;
229 };
230
231 TEMPLATE_TYPEDEF(ePtr<iPlayableService>, iPlayableServicePtr);
232
233 class iRecordableService: public iObject
234 {
235 public:
236         virtual RESULT prepare()=0;
237         virtual RESULT start()=0;
238         virtual RESULT stop()=0;
239 };
240
241 TEMPLATE_TYPEDEF(ePtr<iRecordableService>, iRecordableServicePtr);
242
243 // TEMPLATE_TYPEDEF(std::list<eServiceReference>, eServiceReferenceList);
244
245 class iListableService: public iObject
246 {
247 public:
248                 /* legacy interface: get a list */
249         virtual RESULT getContent(std::list<eServiceReference> &list)=0;
250         
251                 /* new, shiny interface: streaming. */
252         virtual SWIG_VOID(RESULT) getNext(eServiceReference &SWIG_OUTPUT)=0;
253         
254                 /* use this for sorting. output is not sorted because of either
255                  - performance reasons: the whole list must be buffered or
256                  - the interface would be restricted to a list. streaming
257                    (as well as a future "active" extension) won't be possible.
258                 */
259         virtual int compareLessEqual(const eServiceReference &, const eServiceReference &)=0;
260 };
261
262 TEMPLATE_TYPEDEF(ePtr<iListableService>, iListableServicePtr);
263
264         /* a helper class which can be used as argument to stl's sort(). */
265 class iListableServiceCompare
266 {
267         ePtr<iListableService> m_list;
268 public:
269         iListableServiceCompare(iListableService *list): m_list(list) { }
270         bool operator()(const eServiceReference &a, const eServiceReference &b)
271         {
272                 return m_list->compareLessEqual(a, b);
273         }
274 };
275
276 class iServiceOfflineOperations: public iObject
277 {
278 public:
279                 /* to delete a service, forever. */
280         virtual RESULT deleteFromDisk(int simulate=1)=0;
281         
282                 /* for transferring a service... */
283         virtual SWIG_VOID(RESULT) getListOfFilenames(std::list<std::string> &SWIG_OUTPUT)=0;
284         
285                 // TODO: additional stuff, like a conversion interface?
286 };
287
288 class iServiceHandler: public iObject
289 {
290 public:
291         virtual SWIG_VOID(RESULT) play(const eServiceReference &, ePtr<iPlayableService> &SWIG_OUTPUT)=0;
292         virtual SWIG_VOID(RESULT) record(const eServiceReference &, ePtr<iRecordableService> &SWIG_OUTPUT)=0;
293         virtual SWIG_VOID(RESULT) list(const eServiceReference &, ePtr<iListableService> &SWIG_OUTPUT)=0;
294         virtual SWIG_VOID(RESULT) info(const eServiceReference &, ePtr<iStaticServiceInformation> &SWIG_OUTPUT)=0;
295         virtual SWIG_VOID(RESULT) offlineOperations(const eServiceReference &, ePtr<iServiceOfflineOperations> &SWIG_OUTPUT)=0;
296 };
297
298 TEMPLATE_TYPEDEF(ePtr<iServiceHandler>, iServiceHandlerPtr);
299
300 #endif