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