1 /*
2  * This file is part of bino, a 3D video player.
3  *
4  * Copyright (C) 2010, 2011, 2015, 2016
5  * Martin Lambers <marlam@marlam.de>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (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
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "config.h"
22 
23 extern "C"
24 {
25 #define __STDC_CONSTANT_MACROS
26 #include <libavformat/avformat.h>
27 #include <libavdevice/avdevice.h>
28 #include <libavcodec/avcodec.h>
29 #include <libswscale/swscale.h>
30 }
31 
32 #include <ass/ass.h>
33 
34 #if !defined(__APPLE__) || defined(HAVE_AL_AL_H)
35 #  include <AL/al.h>
36 #  include <AL/alc.h>
37 #else
38 #  include <OpenAL/al.h>
39 #  include <OpenAL/alc.h>
40 #endif
41 
42 #include <GL/glew.h>
43 
44 #include <QGLWidget>
45 
46 #if HAVE_LIBEQUALIZER
47 #  include <eq/eq.h>
48 #endif
49 
50 #include "base/str.h"
51 
52 #include "base/gettext.h"
53 #define _(string) gettext(string)
54 
55 
56 static std::vector<std::string> ffmpeg_v;
57 static std::vector<std::string> libass_v;
58 static std::vector<std::string> openal_v;
59 static std::vector<std::string> opengl_v;
60 static std::vector<std::string> glew_v;
61 static std::vector<std::string> equalizer_v;
62 static std::vector<std::string> lirc_v;
63 static std::vector<std::string> qt_v;
64 
ffmpeg_versions()65 static void ffmpeg_versions()
66 {
67     if (ffmpeg_v.size() == 0)
68     {
69         ffmpeg_v.push_back(str::asprintf("libavformat %d.%d.%d / %d.%d.%d",
70                     LIBAVFORMAT_VERSION_MAJOR, LIBAVFORMAT_VERSION_MINOR, LIBAVFORMAT_VERSION_MICRO,
71                     avformat_version() >> 16, avformat_version() >> 8 & 0xff, avformat_version() & 0xff));
72         ffmpeg_v.push_back(str::asprintf("libavdevice %d.%d.%d / %d.%d.%d",
73                     LIBAVDEVICE_VERSION_MAJOR, LIBAVDEVICE_VERSION_MINOR, LIBAVDEVICE_VERSION_MICRO,
74                     avdevice_version() >> 16, avdevice_version() >> 8 & 0xff, avdevice_version() & 0xff));
75         ffmpeg_v.push_back(str::asprintf("libavcodec %d.%d.%d / %d.%d.%d",
76                     LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, LIBAVCODEC_VERSION_MICRO,
77                     avcodec_version() >> 16, avcodec_version() >> 8 & 0xff, avcodec_version() & 0xff));
78         ffmpeg_v.push_back(str::asprintf("libswscale %d.%d.%d / %d.%d.%d",
79                     LIBSWSCALE_VERSION_MAJOR, LIBSWSCALE_VERSION_MINOR, LIBSWSCALE_VERSION_MICRO,
80                     swscale_version() >> 16, swscale_version() >> 8 & 0xff, swscale_version() & 0xff));
81     }
82 }
83 
libass_versions()84 static void libass_versions()
85 {
86     if (libass_v.size() == 0)
87     {
88         libass_v.push_back(LIBASS_PKGCONFIG_VERSION);
89     }
90 }
91 
set_openal_versions()92 void set_openal_versions()
93 {
94     if (openal_v.size() == 0)
95     {
96         openal_v.push_back(std::string("Version ") + static_cast<const char *>(alGetString(AL_VERSION)));
97         openal_v.push_back(std::string("Renderer ") + static_cast<const char *>(alGetString(AL_RENDERER)));
98         openal_v.push_back(std::string("Vendor ") + static_cast<const char *>(alGetString(AL_VENDOR)));
99     }
100 }
101 
openal_versions()102 static void openal_versions()
103 {
104     if (openal_v.size() == 0)
105     {
106         ALCdevice *device = alcOpenDevice(NULL);
107         if (device)
108         {
109             ALCcontext *context = alcCreateContext(device, NULL);
110             if (context)
111             {
112                 alcMakeContextCurrent(context);
113                 set_openal_versions();
114                 alcMakeContextCurrent(NULL);
115                 alcDestroyContext(context);
116             }
117             alcCloseDevice(device);
118         }
119         if (openal_v.size() == 0)
120         {
121             openal_v.push_back(_("unknown"));
122         }
123     }
124 }
125 
set_opengl_versions()126 void set_opengl_versions()
127 {
128     if (opengl_v.size() == 0)
129     {
130         opengl_v.push_back(std::string("Version ") + reinterpret_cast<const char *>(glGetString(GL_VERSION)));
131         opengl_v.push_back(std::string("Renderer ") + reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
132         opengl_v.push_back(std::string("Vendor ") + reinterpret_cast<const char *>(glGetString(GL_VENDOR)));
133     }
134 }
135 
opengl_versions()136 static void opengl_versions()
137 {
138     if (opengl_v.size() == 0)
139     {
140 #ifdef Q_WS_X11
141         // This only works on Qt4, but that's ok...
142         const char *display = getenv("DISPLAY");
143         bool have_display = (display && display[0] != '\0');
144 #else
145         bool have_display = true;
146 #endif
147         if (have_display)
148         {
149             QGLWidget *tmpwidget = new QGLWidget();
150             if (tmpwidget->context()->isValid())
151             {
152                 tmpwidget->makeCurrent();
153                 set_opengl_versions();
154             }
155             delete tmpwidget;
156         }
157         if (opengl_v.size() == 0)
158         {
159             opengl_v.push_back(_("unknown"));
160         }
161     }
162 }
163 
glew_versions()164 static void glew_versions()
165 {
166     if (glew_v.size() == 0)
167     {
168         glew_v.push_back(reinterpret_cast<const char *>(glewGetString(GLEW_VERSION)));
169     }
170 }
171 
equalizer_versions()172 static void equalizer_versions()
173 {
174     if (equalizer_v.size() == 0)
175     {
176 #if HAVE_LIBEQUALIZER
177         equalizer_v.push_back(str::asprintf("%d.%d.%d / %d.%d.%d",
178                     EQ_VERSION_MAJOR, EQ_VERSION_MINOR, EQ_VERSION_PATCH,
179                     static_cast<int>(eq::Version::getMajor()),
180                     static_cast<int>(eq::Version::getMinor()),
181                     static_cast<int>(eq::Version::getPatch())));
182 #else
183         equalizer_v.push_back(_("not used"));
184 #endif
185     }
186 }
187 
lirc_versions()188 static void lirc_versions()
189 {
190     if (lirc_v.size() == 0)
191     {
192 #if HAVE_LIRC
193         lirc_v.push_back(LIRC_PKGCONFIG_VERSION);
194 #else
195         lirc_v.push_back(_("not used"));
196 #endif
197     }
198 }
199 
qt_versions()200 static void qt_versions()
201 {
202     if (qt_v.size() == 0)
203     {
204         qt_v.push_back(std::string(QT_VERSION_STR) + " / " + qVersion());
205     }
206 }
207 
lib_versions(bool html)208 std::vector<std::string> lib_versions(bool html)
209 {
210     ffmpeg_versions();
211     libass_versions();
212     openal_versions();
213     opengl_versions();
214     glew_versions();
215     equalizer_versions();
216     lirc_versions();
217     qt_versions();
218 
219     std::vector<std::string> v;
220     if (html)
221     {
222         v.push_back("<ul>");
223         v.push_back("<li><a href=\"http://ffmpeg.org/\">FFmpeg</a>");
224         for (size_t i = 0; i < ffmpeg_v.size(); i++)
225         {
226             v.push_back(std::string("<br>") + ffmpeg_v[i]);
227         }
228         v.push_back("</li>");
229         v.push_back("<li><a href=\"http://code.google.com/p/libass/\">LibASS</a>");
230         for (size_t i = 0; i < libass_v.size(); i++)
231         {
232             v.push_back(std::string("<br>") + libass_v[i]);
233         }
234         v.push_back("</li>");
235         v.push_back("<li><a href=\"http://kcat.strangesoft.net/openal.html\">OpenAL</a>");
236         for (size_t i = 0; i < openal_v.size(); i++)
237         {
238             v.push_back(std::string("<br>") + openal_v[i]);
239         }
240         v.push_back("</li>");
241         v.push_back("<li><a href=\"http://www.opengl.org/\">OpenGL</a>");
242         for (size_t i = 0; i < opengl_v.size(); i++)
243         {
244             v.push_back(std::string("<br>") + opengl_v[i]);
245         }
246         v.push_back("</li>");
247         v.push_back("<li><a href=\"http://glew.sourceforge.net/\">GLEW</a>");
248         for (size_t i = 0; i < glew_v.size(); i++)
249         {
250             v.push_back(std::string("<br>") + glew_v[i]);
251         }
252         v.push_back("</li>");
253         v.push_back("<li><a href=\"http://www.equalizergraphics.com/\">Equalizer</a>");
254         for (size_t i = 0; i < equalizer_v.size(); i++)
255         {
256             v.push_back(std::string("<br>") + equalizer_v[i]);
257         }
258         v.push_back("</li>");
259         v.push_back("<li><a href=\"http://www.lirc.org/\">LIRC</a>");
260         for (size_t i = 0; i < lirc_v.size(); i++)
261         {
262             v.push_back(std::string("<br>") + lirc_v[i]);
263         }
264         v.push_back("</li>");
265         v.push_back("<li><a href=\"http://qt.nokia.com/\">Qt</a>");
266         for (size_t i = 0; i < qt_v.size(); i++)
267         {
268             v.push_back(std::string("<br>") + qt_v[i]);
269         }
270         v.push_back("</li>");
271         v.push_back("</ul>");
272     }
273     else
274     {
275         v.push_back("FFmpeg:");
276         for (size_t i = 0; i < ffmpeg_v.size(); i++)
277         {
278             v.push_back(std::string("    ") + ffmpeg_v[i]);
279         }
280         v.push_back("LibASS:");
281         for (size_t i = 0; i < libass_v.size(); i++)
282         {
283             v.push_back(std::string("    ") + libass_v[i]);
284         }
285         v.push_back("OpenAL:");
286         for (size_t i = 0; i < openal_v.size(); i++)
287         {
288             v.push_back(std::string("    ") + openal_v[i]);
289         }
290         v.push_back("OpenGL:");
291         for (size_t i = 0; i < opengl_v.size(); i++)
292         {
293             v.push_back(std::string("    ") + opengl_v[i]);
294         }
295         v.push_back("GLEW:");
296         for (size_t i = 0; i < glew_v.size(); i++)
297         {
298             v.push_back(std::string("    ") + glew_v[i]);
299         }
300         v.push_back("Equalizer:");
301         for (size_t i = 0; i < equalizer_v.size(); i++)
302         {
303             v.push_back(std::string("    ") + equalizer_v[i]);
304         }
305         v.push_back("LIRC:");
306         for (size_t i = 0; i < lirc_v.size(); i++)
307         {
308             v.push_back(std::string("    ") + lirc_v[i]);
309         }
310         v.push_back("Qt:");
311         for (size_t i = 0; i < qt_v.size(); i++)
312         {
313             v.push_back(std::string("    ") + qt_v[i]);
314         }
315     }
316 
317     return v;
318 }
319