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