]> git.sesse.net Git - vlc/blob - bindings/phonon/vlc/vlcloader.cpp
73e42da2dfb921d1e7bfb400f9f00e34cb36bc17
[vlc] / bindings / phonon / vlc / vlcloader.cpp
1 /*****************************************************************************
2  * VLC backend for the Phonon library                                        *
3  * Copyright (C) 2007-2008 Tanguy Krotoff <tkrotoff@gmail.com>               *
4  * Copyright (C) 2008 Lukas Durfina <lukas.durfina@gmail.com>                *
5  * Copyright (C) 2009 Fathi Boudra <fabo@kde.org>                            *
6  *                                                                           *
7  * This program is free software; you can redistribute it and/or             *
8  * modify it under the terms of the GNU Lesser General Public                *
9  * License as published by the Free Software Foundation; either              *
10  * version 3 of the License, or (at your option) any later version.          *
11  *                                                                           *
12  * This program is distributed in the hope that it will be useful,           *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
15  * Lesser General Public License for more details.                           *
16  *                                                                           *
17  * You should have received a copy of the GNU Lesser General Public          *
18  * License along with this package; if not, write to the Free Software       *
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA *
20  *****************************************************************************/
21
22 #include "vlcloader.h"
23
24 #include <QtCore/QDebug>
25 #include <QtCore/QDir>
26 #include <QtCore/QLibrary>
27 #include <QtCore/QSettings>
28 #include <QtCore/QString>
29 #include <QtCore/QStringList>
30
31 // Global variables
32 libvlc_instance_t *vlc_instance = 0;
33 libvlc_exception_t *vlc_exception = new libvlc_exception_t();
34 libvlc_media_player_t *vlc_current_media_player = 0;
35
36 namespace Phonon
37 {
38 namespace VLC {
39
40 bool vlcInit()
41 {
42     // Global variables
43     vlc_instance = 0;
44     vlc_exception = new libvlc_exception_t();
45
46     QString path = vlcPath();
47     if (!path.isEmpty()) {
48         QString pluginsPath = path;
49 #if defined(Q_OS_UNIX)
50         pluginsPath.append("/vlc");
51 #elif defined(Q_OS_WIN)
52         pluginsPath.append("\\plugins");
53 #endif
54         // VLC command line options. See vlc --full-help
55         const char *vlcArgs[] = {
56             path.toLatin1().constData(),
57             "--plugin-path=", pluginsPath.toAscii().constData(),
58             "--verbose=2",
59             "--intf=dummy",
60             "--extraintf=logger",
61             "--ignore-config",
62             "--reset-plugins-cache",
63             "--no-media-library",
64             "--no-one-instance",
65             "--no-osd",
66             "--no-stats",
67             "--no-video-title-show"
68         };
69
70         libvlc_exception_init(vlc_exception);
71
72         // Create and initialize a libvlc instance (it should be done only once)
73         vlc_instance = libvlc_new(sizeof(vlcArgs) / sizeof(*vlcArgs),
74                                   vlcArgs,
75                                   vlc_exception);
76         vlcExceptionRaised();
77
78         return true;
79     } else {
80         return false;
81     }
82 }
83
84 void vlcRelease()
85 {
86     libvlc_release(vlc_instance);
87     vlcExceptionRaised();
88     vlcUnload();
89 }
90
91 void vlcExceptionRaised()
92 {
93     if (libvlc_exception_raised(vlc_exception)) {
94         qDebug() << "libvlc exception:" << libvlc_exception_get_message(vlc_exception);
95         libvlc_exception_clear(vlc_exception);
96     }
97 }
98
99 #if defined(Q_OS_UNIX)
100 static bool libGreaterThan(const QString &lhs, const QString &rhs)
101 {
102     QStringList lhsparts = lhs.split(QLatin1Char('.'));
103     QStringList rhsparts = rhs.split(QLatin1Char('.'));
104     Q_ASSERT(lhsparts.count() > 1 && rhsparts.count() > 1);
105
106     for (int i = 1; i < rhsparts.count(); ++i) {
107         if (lhsparts.count() <= i)
108             // left hand side is shorter, so it's less than rhs
109             return false;
110
111         bool ok = false;
112         int b = 0;
113         int a = lhsparts.at(i).toInt(&ok);
114         if (ok)
115             b = rhsparts.at(i).toInt(&ok);
116         if (ok) {
117             // both toInt succeeded
118             if (a == b)
119                 continue;
120             return a > b;
121         } else {
122             // compare as strings;
123             if (lhsparts.at(i) == rhsparts.at(i))
124                 continue;
125             return lhsparts.at(i) > rhsparts.at(i);
126         }
127     }
128
129     // they compared strictly equally so far
130     // lhs cannot be less than rhs
131     return true;
132 }
133 #endif
134
135 static QStringList findAllLibVlc()
136 {
137     QStringList paths;
138 #if defined(Q_OS_UNIX)
139     paths = QString::fromLatin1(qgetenv("LD_LIBRARY_PATH"))
140             .split(QLatin1Char(':'), QString::SkipEmptyParts);
141     paths << QLatin1String("/usr/lib") << QLatin1String("/usr/local/lib");
142
143     QStringList foundVlcs;
144     foreach (const QString &path, paths) {
145         QDir dir = QDir(path);
146         QStringList entryList = dir.entryList(QStringList() << QLatin1String("libvlc.*"), QDir::Files);
147
148         qSort(entryList.begin(), entryList.end(), libGreaterThan);
149         foreach (const QString &entry, entryList)
150             foundVlcs << path + QLatin1Char('/') + entry;
151     }
152
153     return foundVlcs;
154 #elif defined(Q_OS_WIN)
155     // Read VLC version and installation directory from Windows registry
156     QSettings settings(QSettings::SystemScope, "VideoLAN", "VLC");
157     QString vlcVersion = settings.value("Version").toString();
158     QString vlcInstallDir = settings.value("InstallDir").toString();
159     if (vlcVersion.startsWith("1.0") && !vlcInstallDir.isEmpty()) {
160         paths << vlcInstallDir + QLatin1Char('\\') + "libvlc";
161         return paths;
162     } else {
163         return QString();
164     }
165 #endif
166 }
167
168 static QLibrary *vlcLibrary = 0;
169
170 QString vlcPath()
171 {
172     static QString path;
173     if (!path.isEmpty()) {
174         return path;
175     }
176
177     vlcLibrary = new QLibrary();
178     QStringList paths = findAllLibVlc();
179     foreach(path, paths) {
180         vlcLibrary->setFileName(path);
181
182         if (vlcLibrary->resolve("libvlc_exception_init")) {
183             return path;
184         } else {
185             qDebug("Cannot resolve the symbol or load VLC library");
186         }
187         qWarning() << vlcLibrary->errorString();
188     }
189
190     vlcUnload();
191
192     return QString();
193 }
194
195 void vlcUnload()
196 {
197     vlcLibrary->unload();
198     delete vlcLibrary;
199     vlcLibrary = 0;
200 }
201
202 }
203 } // Namespace Phonon::VLC