1 //=============================================================================
2 //
3 // File : MpXmmsInterface.cpp
4 // Creation date : Fri 25 Mar 2005 20:04:54 by Szymon Stefanek
5 //
6 // This file is part of the KVIrc IRC client distribution
7 // Copyright (C) 2005-2010 Szymon Stefanek <pragma at kvirc dot net>
8 //
9 // This program is FREE software. You can redistribute it and/or
10 // modify it under the terms of the GNU General Public License
11 // as published by the Free Software Foundation; either version 2
12 // of the License, or (at your option) any later version.
13 //
14 // This program is distributed in the HOPE that it will be USEFUL,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 // See the GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with this program. If not, write to the Free Software Foundation,
21 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 // Thnx to Alexander Stillich <torque at pltn dot org> for Audacious
24 // media player interface hints :)
25 //
26 //=============================================================================
27
28 #include "MpXmmsInterface.h"
29
30 #if(!defined(COMPILE_ON_WINDOWS) && !defined(COMPILE_ON_MAC) && !defined(COMPILE_ON_MINGW))
31
32 #include "KviLocale.h"
33
34 MP_IMPLEMENT_DESCRIPTOR(
35 KviXmmsInterface,
36 "xmms",
37 __tr2qs_ctx(
38 "An interface for the UNIX XMMS media player.\n"
39 "Download it from http://legacy.xmms2.org\n",
40 "mediaplayer"))
41
42 MP_IMPLEMENT_DESCRIPTOR(
43 KviAudaciousClassicInterface,
44 "audacious classic",
45 __tr2qs_ctx(
46 "An interface for the UNIX Audacious media player.\n"
47 "Download it from http://audacious-media-player.org\n",
48 "mediaplayer"))
49
50 static const char * xmms_lib_names[] = {
51 "libxmms.so",
52 "libxmms.so.1",
53 "/usr/lib/libxmms.so",
54 "/usr/lib/libxmms.so.1",
55 "/usr/local/lib/libxmms.so",
56 "/usr/local/lib/libxmms.so.1",
57 nullptr
58 };
59
60 static const char * audacious_lib_names[] = {
61 "libaudacious.so",
62 "libaudacious.so.4",
63 "/usr/lib/libaudacious.so",
64 "/usr/lib/libaudacious.so.4",
65 "/usr/local/lib/libaudacious.so",
66 "/usr/local/lib/libaudacious.so.4",
67 nullptr
68 };
69
KviXmmsInterface()70 KviXmmsInterface::KviXmmsInterface()
71 : MpInterface()
72 {
73 m_pPlayerLibrary = nullptr;
74 m_szPlayerLibraryName = "libxmms.so";
75 m_pLibraryPaths = xmms_lib_names;
76 }
77
~KviXmmsInterface()78 KviXmmsInterface::~KviXmmsInterface()
79 {
80 if(m_pPlayerLibrary)
81 {
82 m_pPlayerLibrary->unload();
83 delete m_pPlayerLibrary;
84 m_pPlayerLibrary = nullptr;
85 }
86 }
87
KviAudaciousClassicInterface()88 KviAudaciousClassicInterface::KviAudaciousClassicInterface()
89 : KviXmmsInterface()
90 {
91 m_szPlayerLibraryName = "libaudacious.so";
92 m_pLibraryPaths = audacious_lib_names;
93 }
94
95 KviAudaciousClassicInterface::~KviAudaciousClassicInterface()
96 = default;
97
loadPlayerLibrary()98 bool KviXmmsInterface::loadPlayerLibrary()
99 {
100 if(m_pPlayerLibrary && m_pPlayerLibrary->isLoaded())
101 return true;
102
103 const char ** lib_name = m_pLibraryPaths;
104 while(*lib_name)
105 {
106 m_pPlayerLibrary = new QLibrary(*lib_name);
107 if(m_pPlayerLibrary->load())
108 {
109 m_szPlayerLibraryName = *lib_name;
110 return true;
111 }
112 delete m_pPlayerLibrary;
113 m_pPlayerLibrary = nullptr;
114 lib_name++;
115 }
116 return false;
117 }
118
lookupSymbol(const char * szSymbolName)119 void * KviXmmsInterface::lookupSymbol(const char * szSymbolName)
120 {
121 if(!m_pPlayerLibrary)
122 {
123 if(!loadPlayerLibrary())
124 {
125 QString szTmp = QString(__tr2qs_ctx("Can't load the player library (%1)", "mediaplayer")).arg(m_szPlayerLibraryName);
126 setLastError(szTmp);
127 return nullptr;
128 }
129 }
130 void * symptr = (void *)m_pPlayerLibrary->resolve(szSymbolName);
131 if(!symptr)
132 {
133 QString szTmp = QString(__tr2qs_ctx("Can't find symbol %1 in %2", "mediaplayer")).arg(szSymbolName, m_szPlayerLibraryName);
134 setLastError(szTmp);
135 }
136 return symptr;
137 }
138
detect(bool)139 int KviXmmsInterface::detect(bool)
140 {
141 void * sym = lookupSymbol("xmms_remote_play");
142 return sym ? 80 : 0;
143 }
144
145 #define XMMS_SIMPLE_CALL(__symname) \
146 void (*sym)(int) = (void (*)(int))lookupSymbol(__symname); \
147 if(!sym) \
148 return false; \
149 sym(0); \
150 return true;
151
prev()152 bool KviXmmsInterface::prev()
153 {
154 XMMS_SIMPLE_CALL("xmms_remote_playlist_prev")
155 }
156
next()157 bool KviXmmsInterface::next()
158 {
159 XMMS_SIMPLE_CALL("xmms_remote_playlist_next")
160 }
161
play()162 bool KviXmmsInterface::play()
163 {
164 XMMS_SIMPLE_CALL("xmms_remote_play")
165 }
166
stop()167 bool KviXmmsInterface::stop()
168 {
169 XMMS_SIMPLE_CALL("xmms_remote_stop")
170 }
171
pause()172 bool KviXmmsInterface::pause()
173 {
174 XMMS_SIMPLE_CALL("xmms_remote_pause")
175 }
176
quit()177 bool KviXmmsInterface::quit()
178 {
179 XMMS_SIMPLE_CALL("xmms_remote_quit")
180 }
181
jumpTo(kvs_int_t & iPos)182 bool KviXmmsInterface::jumpTo(kvs_int_t & iPos)
183 {
184 void (*sym)(int, int) = (void (*)(int, int))lookupSymbol("xmms_remote_jump_to_time");
185 if(!sym)
186 return false;
187 sym(0, iPos);
188 return true;
189 }
190
setVol(kvs_int_t & iVol)191 bool KviXmmsInterface::setVol(kvs_int_t & iVol)
192 {
193 void (*sym)(int, int) = (void (*)(int, int))lookupSymbol("xmms_remote_set_main_volume");
194 if(!sym)
195 return false;
196 sym(0, 100 * iVol / 255);
197 return true;
198 }
199
getVol()200 int KviXmmsInterface::getVol()
201 {
202 int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_main_volume");
203 if(!sym)
204 return -1;
205 int iVol = sym(0);
206 return iVol * 255 / 100;
207 }
208
getRepeat()209 bool KviXmmsInterface::getRepeat()
210 {
211 bool (*sym)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_repeat");
212 if(!sym)
213 return false;
214 bool ret = sym(0);
215 return ret;
216 }
217
setRepeat(bool & bVal)218 bool KviXmmsInterface::setRepeat(bool & bVal)
219 {
220 bool (*sym1)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_repeat");
221 if(!sym1)
222 return false;
223 bool bNow = sym1(0);
224 if(bNow != bVal)
225 {
226 void (*sym2)(int) = (void (*)(int))lookupSymbol("xmms_remote_toggle_repeat");
227 if(!sym2)
228 return false;
229 sym2(0);
230 }
231 return true;
232 }
233
getShuffle()234 bool KviXmmsInterface::getShuffle()
235 {
236 bool (*sym)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_shuffle");
237 if(!sym)
238 return false;
239 bool ret = sym(0);
240 return ret;
241 }
242
setShuffle(bool & bVal)243 bool KviXmmsInterface::setShuffle(bool & bVal)
244 {
245 bool (*sym1)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_shuffle");
246 if(!sym1)
247 return false;
248 bool bNow = sym1(0);
249 if(bNow != bVal)
250 {
251 void (*sym2)(int) = (void (*)(int))lookupSymbol("xmms_remote_toggle_shuffle");
252 if(!sym2)
253 return false;
254 sym2(0);
255 }
256 return true;
257 }
258
status()259 MpInterface::PlayerStatus KviXmmsInterface::status()
260 {
261 bool (*sym1)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_paused");
262 if(sym1)
263 {
264 if(sym1(0))
265 return MpInterface::Paused;
266 bool (*sym2)(int) = (bool (*)(int))lookupSymbol("xmms_remote_is_playing");
267 if(sym2)
268 {
269 if(sym2(0))
270 return MpInterface::Playing;
271 else
272 return MpInterface::Stopped;
273 }
274 }
275
276 return MpInterface::Unknown;
277 }
278
playMrl(const QString & mrl)279 bool KviXmmsInterface::playMrl(const QString & mrl)
280 {
281 void (*sym)(int, char *) = (void (*)(int, char *))lookupSymbol("xmms_remote_playlist_add_url_string");
282 QByteArray tmp = mrl.toLocal8Bit();
283 if(!tmp.isEmpty())
284 {
285 if(sym)
286 {
287 sym(0, tmp.data());
288 int (*sym1)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_length");
289 if(sym1)
290 {
291 int len = sym1(0);
292 if(len > 0)
293 {
294 void (*sym2)(int, int) = (void (*)(int, int))lookupSymbol("xmms_remote_set_playlist_pos");
295 if(sym2)
296 {
297 sym2(0, len - 1);
298 }
299 else
300 return false;
301 }
302 else
303 return false;
304 }
305 else
306 return false;
307 }
308 else
309 return false;
310 }
311 return true;
312 }
313
nowPlaying()314 QString KviXmmsInterface::nowPlaying()
315 {
316 int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_pos");
317 if(!sym)
318 return QString();
319 int pos = sym(0);
320 char * (*sym2)(int, int) = (char * (*)(int, int))lookupSymbol("xmms_remote_get_playlist_title");
321 if(!sym2)
322 return QString();
323 return QString::fromLocal8Bit(sym2(0, pos));
324 }
325
mrl()326 QString KviXmmsInterface::mrl()
327 {
328 int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_pos");
329 if(!sym)
330 return QString();
331 int pos = sym(0);
332 char * (*sym2)(int, int) = (char * (*)(int, int))lookupSymbol("xmms_remote_get_playlist_file");
333 if(!sym2)
334 return QString();
335 QString ret = QString::fromLocal8Bit(sym2(0, pos));
336 if(ret.length() > 1)
337 if(ret[0] == '/')
338 ret.prepend("file://");
339 return ret;
340 }
341
position()342 int KviXmmsInterface::position()
343 {
344 int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_pos");
345 if(!sym)
346 return -1;
347 int pos = sym(0);
348 int (*sym2)(int, int) = (int (*)(int, int))lookupSymbol("xmms_remote_get_output_time");
349 if(!sym2)
350 return -1;
351 return sym2(0, pos);
352 }
353
length()354 int KviXmmsInterface::length()
355 {
356 int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_pos");
357 if(!sym)
358 return -1;
359 int pos = sym(0);
360 int (*sym2)(int, int) = (int (*)(int, int))lookupSymbol("xmms_remote_get_playlist_time");
361 if(!sym2)
362 return -1;
363 return sym2(0, pos);
364 }
365
getPlayListPos()366 int KviXmmsInterface::getPlayListPos()
367 {
368 int (*sym)(int) = (int (*)(int))lookupSymbol("xmms_remote_get_playlist_pos");
369 if(!sym)
370 return -1;
371 return sym(0);
372 }
373
374 #endif //!COMPILE_ON_WINDOWS
375