cvs20080628 - trunk
[gitenigma.git] / lib / dvb / serviceexternal.cpp
blobca2ac8b3f939f0793f4281eed71e868f6035ad68
1 #include <stdio.h>
2 #include <sys/stat.h>
4 #include <lib/gui/ewindow.h>
5 #include <lib/gui/elabel.h>
6 #include <lib/gui/ebutton.h>
7 #include <lib/gui/emessage.h>
8 #include <lib/gui/listbox.h>
9 #include <lib/dvb/servicefile.h>
10 #include <lib/gdi/lcd.h>
11 #include <lib/system/init.h>
12 #include <lib/system/init_num.h>
13 #include <lib/system/info.h>
14 #include <lib/dvb/serviceexternal.h>
17 * In order to register an external (media)player to a file extension (e.g. ".xyz", place
18 * a .cfg file in the plugin directory, with contents:
20 * type=5
21 * pattern=.xyz
22 * command=/usr/bin/xzyplay
23 * needrc=1 (if your player needs the rc)
24 * needlcd=1 (if your player needs the lcd)
25 * needfb=1 (if your player needs the framebuffer)
27 * Now when a file "filename.xyz" is selected in filemode, the external player will be started:
29 * /usr/bin/xyzplay /path/to/file/filename.xyz
31 * In order to register an external (media)player to a directory, we need to match a certain
32 * file inside the directory (e.g. 'dirname/special.file'). Place a .cfg file in the plugin
33 * directory, with contents:
35 * type=5
36 * dirpattern=filename.xyz
37 * command=/usr/bin/xyzplay
38 * needrc=1 (if your player needs the rc)
39 * needlcd=1 (if your player needs the lcd)
40 * needfb=1 (if your player needs the framebuffer)
42 * Now at the same level as 'dirname', an entry 'Start player' will be shown in filemode.
43 * When this entry is selected, the player will be started with the command:
45 * /usr/bin/xyzplay /path/to/dir/dirname
48 * Only one 'pattern' is allowed per type 5 plugin. Also, only one 'dirpattern' is allowed
49 * per type 5 plugin.
50 * However, it is allowed to have both a 'pattern' and a 'dirpattern' in the same cfg file.
54 eServiceHandlerExternal *eServiceHandlerExternal::instance = NULL;
56 eServiceHandlerExternal::eServiceHandlerExternal(): eServiceHandler(0x0fff)
58 if (eServiceInterface::getInstance()->registerHandler(id, this) < 0)
60 eFatal("couldn't register eServiceHandlerExternal %d", id);
62 instance = this;
63 CONNECT(eServiceFileHandler::getInstance()->fileHandlers, eServiceHandlerExternal::addFile);
64 CONNECT(eServiceFileHandler::getInstance()->directoryHandlers, eServiceHandlerExternal::addDirectory);
65 eDebug("eServiceHandlerExternal registered");
68 eServiceHandlerExternal::~eServiceHandlerExternal()
70 eServiceInterface::getInstance()->unregisterHandler(id);
73 void eServiceHandlerExternal::addFileHandler(const eString &pattern, const eString &command, int needfb, int needrc, int needlcd)
75 FileExtensionScriptInfo info;
76 info.needfb = needfb;
77 info.needrc = needrc;
78 info.needlcd = needlcd;
79 info.command = command;
80 info.pattern = pattern;
81 extensionFileList.push_back(info);
84 void eServiceHandlerExternal::addDirectoryHandler(const eString &pattern, const eString &command, int needfb, int needrc, int needlcd)
86 FileExtensionScriptInfo info;
87 info.needfb = needfb;
88 info.needrc = needrc;
89 info.needlcd = needlcd;
90 info.command = command;
91 info.pattern = pattern;
93 * make sure we have a trailing slash in our pattern,
94 * as this is how we'll get offered our directory names
96 if (info.pattern.right(1) != "/") info.pattern += "/";
97 extensionDirectoryList.push_back(info);
100 void eServiceHandlerExternal::addFile(void *node, const eString &filename)
102 for (unsigned int i = 0; i < extensionFileList.size(); i++)
104 int matchsize = extensionFileList[i].pattern.length();
105 if (filename.right(matchsize).upper() == extensionFileList[i].pattern.upper())
107 eServiceReference ref(id, 0, filename);
108 eString filenamestripped = filename;
110 uint i = filename.find_last_of('/');
111 if (i != eString::npos)
113 filenamestripped = filename.mid(i + 1, filename.length());
115 ref.descr = filenamestripped.c_str();
116 eServiceFileHandler::getInstance()->addReference(node, ref);
117 eDebug("Add file: %s", filename.c_str());
118 return;
123 void eServiceHandlerExternal::addDirectory(void *node, const eString &filename)
125 for (unsigned int i = 0; i < extensionDirectoryList.size(); i++)
127 int matchsize = extensionDirectoryList[i].pattern.length();
128 if (filename.right(matchsize).upper() == extensionDirectoryList[i].pattern.upper())
130 eServiceReference ref(id, 0, filename);
131 ref.descr = _("Start player");
132 eServiceFileHandler::getInstance()->addReference(node, ref);
133 eDebug("Add directory: %s", filename.c_str());
134 return;
139 int eServiceHandlerExternal::play(const eServiceReference &service, int workaround)
141 if (service.path)
143 struct stat64 s;
144 if (::stat64(service.path.c_str(), &s))
146 eDebug("file %s does not exist.. don't play", service.path.c_str() );
147 return -1;
150 else
152 return -1;
155 if (service.path.right(1) == "/")
157 /* trailing slash: service is a directory */
158 for (unsigned int i = 0; i < extensionDirectoryList.size(); i++)
160 int matchsize = extensionDirectoryList[i].pattern.length();
161 if (service.path.right(matchsize).upper() == extensionDirectoryList[i].pattern.upper())
163 eString command = extensionDirectoryList[i].command + " \"" + service.path + "\"";
164 eDebug("play command %s\n", command.c_str());
165 ePlayerThread *p = new ePlayerThread(command, extensionDirectoryList[i].needfb, extensionDirectoryList[i].needrc, extensionDirectoryList[i].needlcd);
166 p->start();
167 return 0;
171 else
173 /* service is a normal file */
174 for (unsigned int i = 0; i < extensionFileList.size(); i++)
176 int matchsize = extensionFileList[i].pattern.length();
177 if (service.path.right(matchsize).upper() == extensionFileList[i].pattern.upper())
179 eString command = extensionFileList[i].command + " \"" + service.path + "\"";
180 eDebug("play command %s\n", command.c_str());
181 ePlayerThread *p = new ePlayerThread(command, extensionFileList[i].needfb, extensionFileList[i].needrc, extensionFileList[i].needlcd);
182 p->start();
183 return 0;
187 return -1;
190 int eServiceHandlerExternal::stop(int workaround)
192 eDebug("Stop file\n");
193 return 0;
196 eService *eServiceHandlerExternal::addRef(const eServiceReference &service)
198 return eServiceFileHandler::getInstance()->addRef(service);
201 void eServiceHandlerExternal::removeRef(const eServiceReference &service)
203 return eServiceFileHandler::getInstance()->removeRef(service);
206 void ePlayerThread::start()
208 if (!thread_running())
210 if (needrc)
212 eRCInput::getInstance()->lock();
215 if (needfb)
217 fbClass::getInstance()->lock();
220 #ifndef DISABLE_LCD
221 if (needlcd && eSystemInfo::getInstance()->hasLCD())
223 eDBoxLCD::getInstance()->lock();
225 #endif
227 run();
229 else
231 eDebug("don't start player.. another one is running");
235 void ePlayerThread::thread()
237 if (thread_running())
239 eDebug("player thread running.. start player now");
241 else
243 eDebug("start player now");
245 system(command.c_str());
246 eDebug("player finished");
249 void ePlayerThread::recv_msg(const int &)
251 finalize_player();
254 void ePlayerThread::thread_finished()
256 message.send(1);
259 void ePlayerThread::finalize_player()
261 if (needfb)
263 fbClass::getInstance()->unlock();
266 #ifndef DISABLE_LCD
267 if (needlcd && eSystemInfo::getInstance()->hasLCD())
269 eDBoxLCD::getInstance()->unlock();
271 #endif
273 if (needrc)
275 eRCInput::getInstance()->unlock();
277 delete this;
280 eAutoInitP0<eServiceHandlerExternal> i_eServiceHandlerExternal(eAutoInitNumbers::service + 2, "eServiceHandlerExternal");