move dvb-t 5V antenna switching to better place
[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/python/python.h>
6 #include <lib/base/object.h>
7 #include <string>
8 #include <connection.h>
9 #include <list>
10
11 class eServiceEvent;
12
13 class eServiceReference
14 {
15 public:
16         enum
17         {
18                 idInvalid=-1,
19                 idStructure,    // service_id == 0 is root
20                 idDVB,
21                 idFile,
22                 idUser=0x1000
23         };
24         int type;
25
26         enum
27         {
28                 isDirectory=1,          // SHOULD enter  (implies mustDescent)
29                 mustDescent=2,          // cannot be played directly - often used with "isDirectory" (implies canDescent)
30                 /*
31                         for example:
32                                 normal services have none of them - they can be fed directly into the "play"-handler.
33                                 normal directories have both of them set - you cannot play a directory directly and the UI should descent into it.
34                                 playlists have "mustDescent", but not "isDirectory" - you don't want the user to browse inside the playlist (unless he really wants)
35                                 services with sub-services have none of them, instead the have the "canDecsent" flag (as all of the above)
36                 */
37                 canDescent=4,                   // supports enterDirectory/leaveDirectory
38                 flagDirectory=isDirectory|mustDescent|canDescent,
39                 shouldSort=8,                   // should be ASCII-sorted according to service_name. great for directories.
40                 hasSortKey=16,          // has a sort key in data[3]. not having a sort key implies 0.
41                 sort1=32                                        // sort key is 1 instead of 0
42         };
43         int flags; // flags will NOT be compared.
44
45         inline int getSortKey() const { return (flags & hasSortKey) ? data[3] : ((flags & sort1) ? 1 : 0); }
46
47 #ifndef SWIG
48         int data[8];
49         std::string path;
50 #endif
51         std::string getPath() { return path; }
52         void setPath( const std::string &n ) { path=n; }
53
54         unsigned int getUnsignedData(unsigned int num) const
55         {
56                 if ( num < sizeof(data)/sizeof(int) )
57                         return data[num];
58                 return 0;
59         }
60
61         int getData(unsigned int num) const
62         {
63                 if ( num < sizeof(data)/sizeof(int) )
64                         return data[num];
65                 return 0;
66         }
67
68         void setUnsignedData(unsigned int num, unsigned int val)
69         {
70                 if ( num < sizeof(data)/sizeof(int) )
71                         data[num] = val;
72         }
73
74         void setData(unsigned int num, int val)
75         {
76                 if ( num < sizeof(data)/sizeof(int) )
77                         data[num] = val;
78         }
79
80 // only for override service names in bouquets or to give servicerefs a name which not have a
81 // real existing service ( for dvb eServiceDVB )
82 #ifndef SWIG
83         std::string name;
84 #endif
85         std::string getName() { return name; }
86         void setName( const std::string &n ) { name=n; }
87
88         eServiceReference()
89                 : type(idInvalid), flags(0)
90         {
91                 memset(data, 0, sizeof(data));
92         }
93 #ifndef SWIG
94         eServiceReference(int type, int flags)
95                 : type(type), flags(flags)
96         {
97                 memset(data, 0, sizeof(data));
98         }
99         eServiceReference(int type, int flags, int data0)
100                 : type(type), flags(flags)
101         {
102                 memset(data, 0, sizeof(data));
103                 data[0]=data0;
104         }
105         eServiceReference(int type, int flags, int data0, int data1)
106                 : type(type), flags(flags)
107         {
108                 memset(data, 0, sizeof(data));
109                 data[0]=data0;
110                 data[1]=data1;
111         }
112         eServiceReference(int type, int flags, int data0, int data1, int data2)
113                 : type(type), flags(flags)
114         {
115                 memset(data, 0, sizeof(data));
116                 data[0]=data0;
117                 data[1]=data1;
118                 data[2]=data2;
119         }
120         eServiceReference(int type, int flags, int data0, int data1, int data2, int data3)
121                 : type(type), flags(flags)
122         {
123                 memset(data, 0, sizeof(data));
124                 data[0]=data0;
125                 data[1]=data1;
126                 data[2]=data2;
127                 data[3]=data3;
128         }
129         eServiceReference(int type, int flags, int data0, int data1, int data2, int data3, int data4)
130                 : type(type), flags(flags)
131         {
132                 memset(data, 0, sizeof(data));
133                 data[0]=data0;
134                 data[1]=data1;
135                 data[2]=data2;
136                 data[3]=data3;
137                 data[4]=data4;
138         }
139         eServiceReference(int type, int flags, const std::string &path)
140                 : type(type), flags(flags), path(path)
141         {
142                 memset(data, 0, sizeof(data));
143         }
144 #endif
145         eServiceReference(const std::string &string);
146         std::string toString() const;
147         bool operator==(const eServiceReference &c) const
148         {
149                 if (type != c.type)
150                         return 0;
151                 return (memcmp(data, c.data, sizeof(int)*8)==0) && (path == c.path);
152         }
153         bool operator!=(const eServiceReference &c) const
154         {
155                 return !(*this == c);
156         }
157         bool operator<(const eServiceReference &c) const
158         {
159                 if (type < c.type)
160                         return 1;
161
162                 if (type > c.type)
163                         return 0;
164
165                 int r=memcmp(data, c.data, sizeof(int)*8);
166                 if (r)
167                         return r < 0;
168                 return path < c.path;
169         }
170         operator bool() const
171         {
172                 return valid();
173         }
174         
175         int valid() const
176         {
177                 return type != idInvalid;
178         }
179 };
180
181 SWIG_ALLOW_OUTPUT_SIMPLE(eServiceReference);
182
183 extern PyObject *New_eServiceReference(const eServiceReference &ref); // defined in enigma_python.i
184
185 typedef long long pts_t;
186
187         /* the reason we have the servicereference as additional argument is
188            that we don't have to create one object for every entry in a possibly
189            large list, provided that no state information is nessesary to deliver
190            the required information. Anyway - ref *must* be the same as the argument
191            to the info() or getIServiceInformation call! */
192
193         /* About the usage of SWIG_VOID:
194            SWIG_VOID(real_returntype_t) hides a return value from swig. This is used for
195            the "superflouus" RESULT return values.
196            
197            Python code has to check the returned pointer against 0. This works,
198            as all functions returning instances in smartpointers AND having a 
199            RESULT have to BOTH return non-zero AND set the pointer to zero.
200            
201            Python code thus can't check for the reason, but the reason isn't
202            user-servicable anyway. If you want to return a real reason which
203            goes beyong "it just doesn't work", use extra variables for this,
204            not the RESULT.
205            
206            Hide the result only if there is another way to check for failure! */
207            
208 class iStaticServiceInformation: public iObject
209 {
210 #ifdef SWIG
211         iStaticServiceInformation();
212         ~iStaticServiceInformation();
213 #endif
214 public:
215         virtual SWIG_VOID(RESULT) getName(const eServiceReference &ref, std::string &SWIG_OUTPUT)=0;
216         
217                 // doesn't need to be implemented, should return -1 then.
218         virtual int getLength(const eServiceReference &ref);
219         virtual SWIG_VOID(RESULT) getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &SWIG_OUTPUT, time_t start_time=-1);
220                 // returns true when not implemented
221         virtual bool isPlayable(const eServiceReference &ref, const eServiceReference &ignore);
222
223         virtual int getInfo(const eServiceReference &ref, int w);
224         virtual std::string getInfoString(const eServiceReference &ref,int w);
225 };
226
227 TEMPLATE_TYPEDEF(ePtr<iStaticServiceInformation>, iStaticServiceInformationPtr);
228
229 TEMPLATE_TYPEDEF(ePtr<eServiceEvent>, eServiceEventPtr);
230
231 class iServiceInformation: public iObject
232 {
233 #ifdef SWIG
234         iServiceInformation();
235         ~iServiceInformation();
236 #endif
237 public:
238         virtual SWIG_VOID(RESULT) getName(std::string &SWIG_OUTPUT)=0;
239         virtual SWIG_VOID(RESULT) getEvent(ePtr<eServiceEvent> &SWIG_OUTPUT, int nownext);
240
241         enum {
242                 sIsCrypted,  /* is encrypted (no indication if decrypt was possible) */
243                 sAspect,     /* aspect ratio: 0=4:3, 1=16:9, 2=whatever we need */
244                 sIsMultichannel, /* multichannel *available* (probably not selected) */
245                 
246                         /* "user serviceable info" - they are not reliable. Don't use them for anything except the service menu!
247                            that's also the reason why they are so globally defined. 
248                            
249                            
250                            again - if somebody EVER tries to use this information for anything else than simply displaying it,
251                            i will change this to return a user-readable text like "zero x zero three three" (and change the
252                            exact spelling in every version) to stop that!
253                         */
254                 sVideoPID,
255                 sAudioPID,
256                 sPCRPID,
257                 sPMTPID,
258                 sTXTPID,
259                 
260                 sSID,
261                 sONID,
262                 sTSID,
263                 sNamespace,
264                 sProvider,
265                 
266                 sDescription,
267                 sServiceref,
268                 sTimeCreate,    // unix time or string
269                 
270                 sTitle,
271                 sArtist,
272                 sAlbum,
273                 sComment,
274                 sTracknumber,
275                 sGenre,
276                 sCAIDs,
277                 sVideoType  // MPEG2 MPEG4
278         };
279         enum { resNA = -1, resIsString = -2, resIsPyObject = -3 };
280
281         virtual int getInfo(int w);
282         virtual std::string getInfoString(int w);
283         virtual PyObject *getInfoObject(int w);
284 };
285
286 TEMPLATE_TYPEDEF(ePtr<iServiceInformation>, iServiceInformationPtr);
287
288 class iFrontendInformation: public iObject
289 {
290 #ifdef SWIG
291         iFrontendInformation();
292         ~iFrontendInformation();
293 #endif
294 public:
295         enum {
296                 bitErrorRate,
297                 signalPower,
298                 signalQuality,
299                 lockState,
300                 syncState,
301                 frontendNumber
302         };
303         virtual int getFrontendInfo(int w)=0;
304         virtual PyObject *getFrontendData(bool original=false)=0;
305 };
306
307 TEMPLATE_TYPEDEF(ePtr<iFrontendInformation>, iFrontendInformationPtr);
308
309 class iPauseableService: public iObject
310 {
311 #ifdef SWIG
312         iPausableService();
313         ~iPausableService();
314 #endif
315 public:
316         virtual RESULT pause()=0;
317         virtual RESULT unpause()=0;
318         
319                 /* hm. */
320         virtual RESULT setSlowMotion(int ratio=0)=0;
321         virtual RESULT setFastForward(int ratio=0)=0;
322 };
323
324 TEMPLATE_TYPEDEF(ePtr<iPauseableService>, iPauseableServicePtr);
325
326 class iSeekableService: public iObject
327 {
328 #ifdef SWIG
329         iSeekableService();
330         ~iSeekableService();
331 #endif
332 public:
333         virtual RESULT getLength(pts_t &SWIG_OUTPUT)=0;
334         virtual RESULT seekTo(pts_t to)=0;
335         enum { dirForward = +1, dirBackward = -1 };
336         virtual RESULT seekRelative(int direction, pts_t to)=0;
337         virtual RESULT getPlayPosition(pts_t &SWIG_OUTPUT)=0;
338                 /* if you want to do several seeks in a row, you can enable the trickmode. 
339                    audio will be switched off, sync will be disabled etc. */
340         virtual RESULT setTrickmode(int trick=0)=0;
341         virtual RESULT isCurrentlySeekable()=0;
342 };
343
344 TEMPLATE_TYPEDEF(ePtr<iSeekableService>, iSeekableServicePtr);
345
346 struct iAudioTrackInfo
347 {
348 #ifdef SWIG
349 private:
350         iAudioTrackInfo();
351         ~iAudioTrackInfo();
352 public:
353 #endif
354 #ifndef SWIG
355         std::string m_description;
356         std::string m_language; /* iso639 */
357 #endif
358         std::string getDescription() { return m_description; }
359         std::string getLanguage() { return m_language; }
360 };
361
362 SWIG_ALLOW_OUTPUT_SIMPLE(iAudioTrackInfo);
363
364 class iAudioTrackSelection: public iObject
365 {
366 #ifdef SWIG
367         iAudioTrackSelection();
368         ~iAudioTrackSelection();
369 #endif
370 public:
371         virtual int getNumberOfTracks()=0;
372         virtual RESULT selectTrack(unsigned int i)=0;
373         virtual SWIG_VOID(RESULT) getTrackInfo(struct iAudioTrackInfo &SWIG_OUTPUT, unsigned int n)=0;
374 };
375
376 TEMPLATE_TYPEDEF(ePtr<iAudioTrackSelection>, iAudioTrackSelectionPtr);
377
378 class iAudioChannelSelection: public iObject
379 {
380 #ifdef SWIG
381         iAudioChannelSelection();
382         ~iAudioChannelSelection();
383 #endif
384 public:
385         enum { LEFT, STEREO, RIGHT };
386         virtual int getCurrentChannel()=0;
387         virtual RESULT selectChannel(int i)=0;
388 };
389
390 TEMPLATE_TYPEDEF(ePtr<iAudioChannelSelection>, iAudioChannelSelectionPtr);
391
392 class iAudioDelay: public iObject
393 {
394 #ifdef SWIG
395         iAudioDelay();
396         ~iAudioDelay();
397 #endif
398 public:
399         virtual int getAC3Delay()=0;
400         virtual int getPCMDelay()=0;
401         virtual void setAC3Delay(int)=0;
402         virtual void setPCMDelay(int)=0;
403 };
404
405 TEMPLATE_TYPEDEF(ePtr<iAudioDelay>, iAudioDelayPtr);
406
407 class iSubserviceList: public iObject
408 {
409 #ifdef SWIG
410         iSubserviceList();
411         ~iSubserviceList();
412 #endif
413 public:
414         virtual int getNumberOfSubservices()=0;
415         virtual SWIG_VOID(RESULT) getSubservice(eServiceReference &SWIG_OUTPUT, unsigned int n)=0;
416 };
417
418 TEMPLATE_TYPEDEF(ePtr<iSubserviceList>, iSubserviceListPtr);
419
420 class iTimeshiftService: public iObject
421 {
422 #ifdef SWIG
423         iTimeshiftService();
424         ~iTimeshiftService();
425 #endif
426 public:
427         virtual RESULT startTimeshift()=0;
428         virtual RESULT stopTimeshift()=0;
429         
430         virtual int isTimeshiftActive()=0;
431                         /* this essentially seeks to the relative end of the timeshift buffer */
432         virtual RESULT activateTimeshift()=0;
433 };
434
435 TEMPLATE_TYPEDEF(ePtr<iTimeshiftService>, iTimeshiftServicePtr);
436
437         /* not related to eCueSheet */
438 class iCueSheet: public iObject
439 {
440 #ifdef SWIG
441         iCueSheet();
442         ~iCueSheet();
443 #endif
444 public:
445                         /* returns a list of (pts, what)-tuples */
446         virtual PyObject *getCutList() = 0;
447         virtual void setCutList(PyObject *list) = 0;
448         virtual void setCutListEnable(int enable) = 0;
449         enum { cutIn = 0, cutOut = 1, cutMark = 2 };
450 };
451
452 TEMPLATE_TYPEDEF(ePtr<iCueSheet>, iCueSheetPtr);
453
454 class eWidget;
455 class PyList;
456
457 class iSubtitleOutput: public iObject
458 {
459 public:
460         virtual RESULT enableSubtitles(eWidget *parent, PyObject *entry)=0;
461         virtual RESULT disableSubtitles(eWidget *parent)=0;
462         virtual PyObject *getSubtitleList()=0;
463 };
464
465 TEMPLATE_TYPEDEF(ePtr<iSubtitleOutput>, iSubtitleOutputPtr);
466
467 class iPlayableService: public iObject
468 {
469 #ifdef SWIG
470         iPlayableService();
471         ~iPlaybleService();
472 #endif
473         friend class iServiceHandler;
474 public:
475         enum
476         {
477                         /* these first two events are magical, and should only
478                            be generated if you know what you're doing. */
479                 evStart,
480                 evEnd,
481                 
482                 evTuneFailed,
483                         // when iServiceInformation is implemented:
484                 evUpdatedEventInfo,
485                 evUpdatedInfo,
486
487                         /* when seek() is implemented: */               
488                 evSeekableStatusChanged, /* for example when timeshifting */
489                 
490                 evEOF,
491                 evSOF, /* bounced against start of file (when seeking backwards) */
492                 
493                         /* only when cueSheet is implemented */
494                 evCuesheetChanged,
495         };
496         virtual RESULT connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)=0;
497         virtual RESULT start()=0;
498         virtual RESULT stop()=0;
499                         /* might have to be changed... */
500         virtual RESULT setTarget(int target)=0;
501         virtual SWIG_VOID(RESULT) seek(ePtr<iSeekableService> &SWIG_OUTPUT)=0;
502         virtual SWIG_VOID(RESULT) pause(ePtr<iPauseableService> &SWIG_OUTPUT)=0;
503         virtual SWIG_VOID(RESULT) info(ePtr<iServiceInformation> &SWIG_OUTPUT)=0;
504         virtual SWIG_VOID(RESULT) audioTracks(ePtr<iAudioTrackSelection> &SWIG_OUTPUT)=0;
505         virtual SWIG_VOID(RESULT) audioChannel(ePtr<iAudioChannelSelection> &SWIG_OUTPUT)=0;
506         virtual SWIG_VOID(RESULT) subServices(ePtr<iSubserviceList> &SWIG_OUTPUT)=0;
507         virtual SWIG_VOID(RESULT) frontendInfo(ePtr<iFrontendInformation> &SWIG_OUTPUT)=0;
508         virtual SWIG_VOID(RESULT) timeshift(ePtr<iTimeshiftService> &SWIG_OUTPUT)=0;
509         virtual SWIG_VOID(RESULT) cueSheet(ePtr<iCueSheet> &SWIG_OUTPUT)=0;
510         virtual SWIG_VOID(RESULT) subtitle(ePtr<iSubtitleOutput> &SWIG_OUTPUT)=0;
511         virtual SWIG_VOID(RESULT) audioDelay(ePtr<iAudioDelay> &SWIG_OUTPUT)=0;
512 };
513
514 TEMPLATE_TYPEDEF(ePtr<iPlayableService>, iPlayableServicePtr);
515
516 class iRecordableService: public iObject
517 {
518 #ifdef SWIG
519         iRecordableService();
520         ~iRecordableService();
521 #endif
522 public:
523         virtual RESULT prepare(const char *filename, time_t begTime=-1, time_t endTime=-1, int eit_event_id=-1)=0;
524         virtual RESULT start()=0;
525         virtual RESULT stop()=0;
526         virtual SWIG_VOID(RESULT) frontendInfo(ePtr<iFrontendInformation> &SWIG_OUTPUT)=0;
527 };
528
529 TEMPLATE_TYPEDEF(ePtr<iRecordableService>, iRecordableServicePtr);
530
531 // TEMPLATE_TYPEDEF(std::list<eServiceReference>, eServiceReferenceList);
532
533 class iMutableServiceList: public iObject
534 {
535 #ifdef SWIG
536         iMutableServiceList();
537         ~iMutableServiceList();
538 #endif
539 public:
540                 /* flush changes */
541         virtual RESULT flushChanges()=0;
542                 /* adds a service to a list */
543         virtual RESULT addService(eServiceReference &ref)=0;
544                 /* removes a service from a list */
545         virtual RESULT removeService(eServiceReference &ref)=0;
546                 /* moves a service in a list, only if list suppports a specific sort method. */
547                 /* pos is the new, absolute position from 0..size-1 */
548         virtual RESULT moveService(eServiceReference &ref, int pos)=0;
549                 /* set name of list, for bouquets this is the visible bouquet name */
550         virtual RESULT setListName(const std::string &name)=0;
551 };
552
553 TEMPLATE_TYPEDEF(ePtr<iMutableServiceList>, iMutableServiceListPtr);
554
555 class iListableService: public iObject
556 {
557 #ifdef SWIG
558         iListableService();
559         ~iListableService();
560 #endif
561 public:
562                 /* legacy interface: get a list */
563         virtual RESULT getContent(std::list<eServiceReference> &list, bool sorted=false)=0;
564         virtual PyObject *getContent(const char* format, bool sorted=false)=0;
565
566                 /* new, shiny interface: streaming. */
567         virtual SWIG_VOID(RESULT) getNext(eServiceReference &SWIG_OUTPUT)=0;
568         
569                 /* use this for sorting. output is not sorted because of either
570                  - performance reasons: the whole list must be buffered or
571                  - the interface would be restricted to a list. streaming
572                    (as well as a future "active" extension) won't be possible.
573                 */
574         virtual int compareLessEqual(const eServiceReference &, const eServiceReference &)=0;
575         
576         virtual SWIG_VOID(RESULT) startEdit(ePtr<iMutableServiceList> &SWIG_OUTPUT)=0;
577 };
578
579 TEMPLATE_TYPEDEF(ePtr<iListableService>, iListableServicePtr);
580
581 #ifndef SWIG
582         /* a helper class which can be used as argument to stl's sort(). */
583 class iListableServiceCompare
584 {
585         ePtr<iListableService> m_list;
586 public:
587         iListableServiceCompare(iListableService *list): m_list(list) { }
588         bool operator()(const eServiceReference &a, const eServiceReference &b)
589         {
590                 return m_list->compareLessEqual(a, b);
591         }
592 };
593 #endif
594
595 class iServiceOfflineOperations: public iObject
596 {
597 #ifdef SWIG
598         iServiceOfflineOperations();
599         ~iServiceOfflineOperations();
600 #endif
601 public:
602                 /* to delete a service, forever. */
603         virtual RESULT deleteFromDisk(int simulate=1)=0;
604         
605                 /* for transferring a service... */
606         virtual SWIG_VOID(RESULT) getListOfFilenames(std::list<std::string> &SWIG_OUTPUT)=0;
607         
608                 // TODO: additional stuff, like a conversion interface?
609 };
610
611 TEMPLATE_TYPEDEF(ePtr<iServiceOfflineOperations>, iServiceOfflineOperationsPtr);
612
613 class iServiceHandler: public iObject
614 {
615 #ifdef SWIG
616         iServiceHandler();
617         ~iServiceHandler();
618 #endif
619 public:
620         virtual SWIG_VOID(RESULT) play(const eServiceReference &, ePtr<iPlayableService> &SWIG_OUTPUT)=0;
621         virtual SWIG_VOID(RESULT) record(const eServiceReference &, ePtr<iRecordableService> &SWIG_OUTPUT)=0;
622         virtual SWIG_VOID(RESULT) list(const eServiceReference &, ePtr<iListableService> &SWIG_OUTPUT)=0;
623         virtual SWIG_VOID(RESULT) info(const eServiceReference &, ePtr<iStaticServiceInformation> &SWIG_OUTPUT)=0;
624         virtual SWIG_VOID(RESULT) offlineOperations(const eServiceReference &, ePtr<iServiceOfflineOperations> &SWIG_OUTPUT)=0;
625 };
626
627 TEMPLATE_TYPEDEF(ePtr<iServiceHandler>, iServiceHandlerPtr);
628
629 #endif