eff03436d1a42dd1f4a4e9cbd3e3e7a918a45c10
[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 #ifndef SWIG
350         std::string m_description;
351         std::string m_language; /* iso639 */
352 #endif
353         std::string getDescription() { return m_description; }
354         std::string getLanguage() { return m_language; }
355 };
356
357 SWIG_ALLOW_OUTPUT_SIMPLE(iAudioTrackInfo);
358
359 class iAudioTrackSelection: public iObject
360 {
361 #ifdef SWIG
362         iAudioTrackSelection();
363         ~iAudioTrackSelection();
364 #endif
365 public:
366         virtual int getNumberOfTracks()=0;
367         virtual RESULT selectTrack(unsigned int i)=0;
368         virtual SWIG_VOID(RESULT) getTrackInfo(struct iAudioTrackInfo &SWIG_OUTPUT, unsigned int n)=0;
369 };
370
371 TEMPLATE_TYPEDEF(ePtr<iAudioTrackSelection>, iAudioTrackSelectionPtr);
372
373 class iAudioChannelSelection: public iObject
374 {
375 #ifdef SWIG
376         iAudioChannelSelection();
377         ~iAudioChannelSelection();
378 #endif
379 public:
380         enum { LEFT, STEREO, RIGHT };
381         virtual int getCurrentChannel()=0;
382         virtual RESULT selectChannel(int i)=0;
383 };
384
385 TEMPLATE_TYPEDEF(ePtr<iAudioChannelSelection>, iAudioChannelSelectionPtr);
386
387 class iAudioDelay: public iObject
388 {
389 #ifdef SWIG
390         iAudioDelay();
391         ~iAudioDelay();
392 #endif
393 public:
394         virtual int getAC3Delay()=0;
395         virtual int getPCMDelay()=0;
396         virtual void setAC3Delay(int)=0;
397         virtual void setPCMDelay(int)=0;
398 };
399
400 TEMPLATE_TYPEDEF(ePtr<iAudioDelay>, iAudioDelayPtr);
401
402 class iRadioText: public iObject
403 {
404 #ifdef SWIG
405         iRadioText();
406         ~iRadioText();
407 #endif
408 public:
409         virtual std::string getRadioText(int x=0)=0;
410 };
411
412 TEMPLATE_TYPEDEF(ePtr<iRadioText>, iRadioTextPtr);
413
414 class iSubserviceList: public iObject
415 {
416 #ifdef SWIG
417         iSubserviceList();
418         ~iSubserviceList();
419 #endif
420 public:
421         virtual int getNumberOfSubservices()=0;
422         virtual SWIG_VOID(RESULT) getSubservice(eServiceReference &SWIG_OUTPUT, unsigned int n)=0;
423 };
424
425 TEMPLATE_TYPEDEF(ePtr<iSubserviceList>, iSubserviceListPtr);
426
427 class iTimeshiftService: public iObject
428 {
429 #ifdef SWIG
430         iTimeshiftService();
431         ~iTimeshiftService();
432 #endif
433 public:
434         virtual RESULT startTimeshift()=0;
435         virtual RESULT stopTimeshift()=0;
436         
437         virtual int isTimeshiftActive()=0;
438                         /* this essentially seeks to the relative end of the timeshift buffer */
439         virtual RESULT activateTimeshift()=0;
440 };
441
442 TEMPLATE_TYPEDEF(ePtr<iTimeshiftService>, iTimeshiftServicePtr);
443
444         /* not related to eCueSheet */
445 class iCueSheet: public iObject
446 {
447 #ifdef SWIG
448         iCueSheet();
449         ~iCueSheet();
450 #endif
451 public:
452                         /* returns a list of (pts, what)-tuples */
453         virtual PyObject *getCutList() = 0;
454         virtual void setCutList(PyObject *list) = 0;
455         virtual void setCutListEnable(int enable) = 0;
456         enum { cutIn = 0, cutOut = 1, cutMark = 2 };
457 };
458
459 TEMPLATE_TYPEDEF(ePtr<iCueSheet>, iCueSheetPtr);
460
461 class eWidget;
462 class PyList;
463
464 class iSubtitleOutput: public iObject
465 {
466 public:
467         virtual RESULT enableSubtitles(eWidget *parent, PyObject *entry)=0;
468         virtual RESULT disableSubtitles(eWidget *parent)=0;
469         virtual PyObject *getSubtitleList()=0;
470 };
471
472 TEMPLATE_TYPEDEF(ePtr<iSubtitleOutput>, iSubtitleOutputPtr);
473
474 class iPlayableService: public iObject
475 {
476 #ifdef SWIG
477         iPlayableService();
478         ~iPlaybleService();
479 #endif
480         friend class iServiceHandler;
481 public:
482         enum
483         {
484                         /* these first two events are magical, and should only
485                            be generated if you know what you're doing. */
486                 evStart,
487                 evEnd,
488                 
489                 evTuneFailed,
490                         // when iServiceInformation is implemented:
491                 evUpdatedEventInfo,
492                 evUpdatedInfo,
493
494                         /* when seek() is implemented: */               
495                 evSeekableStatusChanged, /* for example when timeshifting */
496                 
497                 evEOF,
498                 evSOF, /* bounced against start of file (when seeking backwards) */
499                 
500                         /* only when cueSheet is implemented */
501                 evCuesheetChanged,
502
503                 evUpdatedRadioText
504         };
505         virtual RESULT connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)=0;
506         virtual RESULT start()=0;
507         virtual RESULT stop()=0;
508                         /* might have to be changed... */
509         virtual RESULT setTarget(int target)=0;
510         virtual SWIG_VOID(RESULT) seek(ePtr<iSeekableService> &SWIG_OUTPUT)=0;
511         virtual SWIG_VOID(RESULT) pause(ePtr<iPauseableService> &SWIG_OUTPUT)=0;
512         virtual SWIG_VOID(RESULT) info(ePtr<iServiceInformation> &SWIG_OUTPUT)=0;
513         virtual SWIG_VOID(RESULT) audioTracks(ePtr<iAudioTrackSelection> &SWIG_OUTPUT)=0;
514         virtual SWIG_VOID(RESULT) audioChannel(ePtr<iAudioChannelSelection> &SWIG_OUTPUT)=0;
515         virtual SWIG_VOID(RESULT) subServices(ePtr<iSubserviceList> &SWIG_OUTPUT)=0;
516         virtual SWIG_VOID(RESULT) frontendInfo(ePtr<iFrontendInformation> &SWIG_OUTPUT)=0;
517         virtual SWIG_VOID(RESULT) timeshift(ePtr<iTimeshiftService> &SWIG_OUTPUT)=0;
518         virtual SWIG_VOID(RESULT) cueSheet(ePtr<iCueSheet> &SWIG_OUTPUT)=0;
519         virtual SWIG_VOID(RESULT) subtitle(ePtr<iSubtitleOutput> &SWIG_OUTPUT)=0;
520         virtual SWIG_VOID(RESULT) audioDelay(ePtr<iAudioDelay> &SWIG_OUTPUT)=0;
521         virtual SWIG_VOID(RESULT) radioText(ePtr<iRadioText> &SWIG_OUTPUT)=0;
522 };
523
524 TEMPLATE_TYPEDEF(ePtr<iPlayableService>, iPlayableServicePtr);
525
526 class iRecordableService: public iObject
527 {
528 #ifdef SWIG
529         iRecordableService();
530         ~iRecordableService();
531 #endif
532 public:
533         virtual RESULT prepare(const char *filename, time_t begTime=-1, time_t endTime=-1, int eit_event_id=-1)=0;
534         virtual RESULT start()=0;
535         virtual RESULT stop()=0;
536         virtual SWIG_VOID(RESULT) frontendInfo(ePtr<iFrontendInformation> &SWIG_OUTPUT)=0;
537 };
538
539 TEMPLATE_TYPEDEF(ePtr<iRecordableService>, iRecordableServicePtr);
540
541 // TEMPLATE_TYPEDEF(std::list<eServiceReference>, eServiceReferenceList);
542
543 class iMutableServiceList: public iObject
544 {
545 #ifdef SWIG
546         iMutableServiceList();
547         ~iMutableServiceList();
548 #endif
549 public:
550                 /* flush changes */
551         virtual RESULT flushChanges()=0;
552                 /* adds a service to a list */
553         virtual RESULT addService(eServiceReference &ref, eServiceReference before=eServiceReference())=0;
554                 /* removes a service from a list */
555         virtual RESULT removeService(eServiceReference &ref)=0;
556                 /* moves a service in a list, only if list suppports a specific sort method. */
557                 /* pos is the new, absolute position from 0..size-1 */
558         virtual RESULT moveService(eServiceReference &ref, int pos)=0;
559                 /* set name of list, for bouquets this is the visible bouquet name */
560         virtual RESULT setListName(const std::string &name)=0;
561 };
562
563 TEMPLATE_TYPEDEF(ePtr<iMutableServiceList>, iMutableServiceListPtr);
564
565 class iListableService: public iObject
566 {
567 #ifdef SWIG
568         iListableService();
569         ~iListableService();
570 #endif
571 public:
572                 /* legacy interface: get a list */
573         virtual RESULT getContent(std::list<eServiceReference> &list, bool sorted=false)=0;
574         virtual PyObject *getContent(const char* format, bool sorted=false)=0;
575
576                 /* new, shiny interface: streaming. */
577         virtual SWIG_VOID(RESULT) getNext(eServiceReference &SWIG_OUTPUT)=0;
578         
579                 /* use this for sorting. output is not sorted because of either
580                  - performance reasons: the whole list must be buffered or
581                  - the interface would be restricted to a list. streaming
582                    (as well as a future "active" extension) won't be possible.
583                 */
584         virtual int compareLessEqual(const eServiceReference &, const eServiceReference &)=0;
585         
586         virtual SWIG_VOID(RESULT) startEdit(ePtr<iMutableServiceList> &SWIG_OUTPUT)=0;
587 };
588
589 TEMPLATE_TYPEDEF(ePtr<iListableService>, iListableServicePtr);
590
591 #ifndef SWIG
592         /* a helper class which can be used as argument to stl's sort(). */
593 class iListableServiceCompare
594 {
595         ePtr<iListableService> m_list;
596 public:
597         iListableServiceCompare(iListableService *list): m_list(list) { }
598         bool operator()(const eServiceReference &a, const eServiceReference &b)
599         {
600                 return m_list->compareLessEqual(a, b);
601         }
602 };
603 #endif
604
605 class iServiceOfflineOperations: public iObject
606 {
607 #ifdef SWIG
608         iServiceOfflineOperations();
609         ~iServiceOfflineOperations();
610 #endif
611 public:
612                 /* to delete a service, forever. */
613         virtual RESULT deleteFromDisk(int simulate=1)=0;
614         
615                 /* for transferring a service... */
616         virtual SWIG_VOID(RESULT) getListOfFilenames(std::list<std::string> &SWIG_OUTPUT)=0;
617         
618                 // TODO: additional stuff, like a conversion interface?
619 };
620
621 TEMPLATE_TYPEDEF(ePtr<iServiceOfflineOperations>, iServiceOfflineOperationsPtr);
622
623 class iServiceHandler: public iObject
624 {
625 #ifdef SWIG
626         iServiceHandler();
627         ~iServiceHandler();
628 #endif
629 public:
630         virtual SWIG_VOID(RESULT) play(const eServiceReference &, ePtr<iPlayableService> &SWIG_OUTPUT)=0;
631         virtual SWIG_VOID(RESULT) record(const eServiceReference &, ePtr<iRecordableService> &SWIG_OUTPUT)=0;
632         virtual SWIG_VOID(RESULT) list(const eServiceReference &, ePtr<iListableService> &SWIG_OUTPUT)=0;
633         virtual SWIG_VOID(RESULT) info(const eServiceReference &, ePtr<iStaticServiceInformation> &SWIG_OUTPUT)=0;
634         virtual SWIG_VOID(RESULT) offlineOperations(const eServiceReference &, ePtr<iServiceOfflineOperations> &SWIG_OUTPUT)=0;
635 };
636
637 TEMPLATE_TYPEDEF(ePtr<iServiceHandler>, iServiceHandlerPtr);
638
639 #endif