No issues found
Tool | Failure ID | Location | Function | Message | Data |
---|---|---|---|---|---|
clang-analyzer | no-output-found | rb-missing-plugins.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None | |
clang-analyzer | no-output-found | rb-missing-plugins.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None |
1 /* rb-missing-plugins.c
2
3 Copyright (C) 2007 Tim-Philipp M端ller <tim centricular net>
4 Copyright (C) 2007 Jonathan Matthew <jonathan@d14n.org>
5
6 The Gnome Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
10
11 The Gnome Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public
17 License along with the Gnome Library; see the file COPYING.LIB. If not,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20
21 Based on totem-missing-plugins.c, authored by Tim-Philipp M端ller <tim centricular net>
22 */
23
24 #include "config.h"
25
26 #include "rb-missing-plugins.h"
27
28 #include "rb-debug.h"
29
30 #include <gst/pbutils/pbutils.h>
31 #include <gst/pbutils/install-plugins.h>
32
33 #include <gst/gst.h> /* for gst_registry_update */
34
35 #include <gtk/gtk.h>
36
37 #ifdef GDK_WINDOWING_X11
38 #include <gdk/gdkx.h>
39 #endif
40
41 #include <string.h>
42
43 /* list of blacklisted detail strings */
44 static GList *blacklisted_plugins = NULL;
45
46 /* parent window for installer */
47 static gpointer parent_window = NULL;
48
49 typedef struct
50 {
51 GClosure *closure;
52 gchar **details;
53 } RBPluginInstallContext;
54
55 static gboolean
56 rb_plugin_install_plugin_is_blacklisted (const gchar * detail)
57 {
58 GList *res;
59
60 res = g_list_find_custom (blacklisted_plugins,
61 detail,
62 (GCompareFunc) strcmp);
63
64 return (res != NULL);
65 }
66
67 static void
68 rb_plugin_install_blacklist_plugin (const gchar * detail)
69 {
70 if (!rb_plugin_install_plugin_is_blacklisted (detail)) {
71 blacklisted_plugins = g_list_prepend (blacklisted_plugins,
72 g_strdup (detail));
73 }
74 }
75
76 static void
77 rb_plugin_install_context_free (RBPluginInstallContext *ctx)
78 {
79 rb_debug ("cleaning up plugin install context %p", ctx);
80 g_strfreev (ctx->details);
81 g_closure_unref (ctx->closure);
82 g_free (ctx);
83 }
84
85 static void
86 rb_plugin_install_done (RBPluginInstallContext *ctx, gboolean retry)
87 {
88 GValue param[2] = { {0,}, {0,} };
89
90 rb_debug ("invoking plugin install context %p callback: retry %d", ctx, retry);
91
92 g_value_init (¶m[0], G_TYPE_POINTER);
93 g_value_set_pointer (¶m[0], NULL);
94 g_value_init (¶m[1], G_TYPE_BOOLEAN);
95 g_value_set_boolean (¶m[1], retry);
96
97 g_closure_invoke (ctx->closure, NULL, 2, param, NULL);
98 g_value_unset (¶m[0]);
99 g_value_unset (¶m[1]);
100 }
101
102 static void
103 on_plugin_installation_done (GstInstallPluginsReturn res, gpointer user_data)
104 {
105 RBPluginInstallContext *ctx = (RBPluginInstallContext *) user_data;
106 gchar **p;
107 gboolean retry;
108
109 rb_debug ("res = %d (%s)", res, gst_install_plugins_return_get_name (res));
110
111 switch (res)
112 {
113 /* treat partial success the same as success; in the worst case we'll
114 * just do another round and get NOT_FOUND as result that time */
115 case GST_INSTALL_PLUGINS_PARTIAL_SUCCESS:
116 case GST_INSTALL_PLUGINS_SUCCESS:
117 {
118 /* blacklist installed plugins too, so that we don't get
119 * into endless installer loops in case of inconsistencies */
120 for (p = ctx->details; p != NULL && *p != NULL; ++p) {
121 rb_plugin_install_blacklist_plugin (*p);
122 }
123
124 g_message ("Missing plugins installed. Updating plugin registry ...");
125
126 /* force GStreamer to re-read its plugin registry */
127 retry = gst_update_registry ();
128
129 rb_plugin_install_done (ctx, retry);
130 break;
131 }
132
133 case GST_INSTALL_PLUGINS_NOT_FOUND:
134 {
135 g_message ("No installation candidate for missing plugins found.");
136
137 /* NOT_FOUND should only be returned if not a single one of the
138 * requested plugins was found; if we managed to play something
139 * anyway, we should just continue playing what we have and
140 * blacklist the requested plugins for this session; if we
141 * could not play anything we should blacklist them as well,
142 * so the install wizard isn't called again for nothing */
143 for (p = ctx->details; p != NULL && *p != NULL; ++p) {
144 rb_plugin_install_blacklist_plugin (*p);
145 }
146
147 rb_plugin_install_done (ctx, FALSE);
148 break;
149 }
150
151 case GST_INSTALL_PLUGINS_USER_ABORT:
152 {
153 /* blacklist on user abort, so we show an error next time (or
154 * just play what we can) instead of calling the installer */
155 for (p = ctx->details; p != NULL && *p != NULL; ++p) {
156 rb_plugin_install_blacklist_plugin (*p);
157 }
158
159 rb_plugin_install_done (ctx, FALSE);
160 break;
161 }
162
163 case GST_INSTALL_PLUGINS_ERROR:
164 case GST_INSTALL_PLUGINS_CRASHED:
165 default:
166 {
167 g_message ("Missing plugin installation failed: %s",
168 gst_install_plugins_return_get_name (res));
169
170 rb_plugin_install_done (ctx, FALSE);
171 break;
172 }
173 }
174
175 rb_plugin_install_context_free (ctx);
176 }
177
178 gboolean
179 rb_missing_plugins_install (const char **details, gboolean ignore_blacklist, GClosure *closure)
180 {
181 RBPluginInstallContext *ctx;
182 GstInstallPluginsContext *install_ctx;
183 GstInstallPluginsReturn status;
184 int i, num;
185
186 num = g_strv_length ((char **)details);
187 g_return_val_if_fail (num > 0, FALSE);
188
189 ctx = g_new0 (RBPluginInstallContext, 1);
190 ctx->closure = g_closure_ref (closure);
191 ctx->details = g_strdupv ((char **)details);
192
193 num = g_strv_length (ctx->details);
194 for (i = 0; i < num; ++i) {
195 if (ignore_blacklist == FALSE && rb_plugin_install_plugin_is_blacklisted (ctx->details[i])) {
196 g_message ("Missing plugin: %s (ignoring)", ctx->details[i]);
197 g_free (ctx->details[i]);
198 ctx->details[i] = ctx->details[num-1];
199 ctx->details[num-1] = NULL;
200 --num;
201 --i;
202 } else {
203 g_message ("Missing plugin: %s", ctx->details[i]);
204 }
205 }
206
207 if (num == 0) {
208 g_message ("All missing plugins are blacklisted, doing nothing");
209 rb_plugin_install_context_free (ctx);
210 return FALSE;
211 }
212
213 install_ctx = gst_install_plugins_context_new ();
214
215 if (parent_window != NULL && gtk_widget_get_realized (GTK_WIDGET (parent_window))) {
216 #ifdef GDK_WINDOWING_X11
217 gulong xid = 0;
218 xid = gdk_x11_window_get_xid (gtk_widget_get_window (GTK_WIDGET (parent_window)));
219 gst_install_plugins_context_set_xid (install_ctx, xid);
220 #endif
221 }
222
223 status = gst_install_plugins_async (ctx->details, install_ctx,
224 on_plugin_installation_done,
225 ctx);
226
227 gst_install_plugins_context_free (install_ctx);
228
229 rb_debug ("gst_install_plugins_async() result = %d", status);
230
231 if (status != GST_INSTALL_PLUGINS_STARTED_OK) {
232 if (status == GST_INSTALL_PLUGINS_HELPER_MISSING) {
233 g_message ("Automatic missing codec installation not supported "
234 "(helper script missing)");
235 } else {
236 g_warning ("Failed to start codec installation: %s",
237 gst_install_plugins_return_get_name (status));
238 }
239 rb_plugin_install_context_free (ctx);
240 return FALSE;
241 }
242
243 return TRUE;
244 }
245
246 void
247 rb_missing_plugins_init (GtkWindow *window)
248 {
249 parent_window = window;
250 g_object_add_weak_pointer (G_OBJECT (parent_window), &parent_window);
251
252 gst_pb_utils_init ();
253
254 GST_INFO ("Set up support for automatic missing plugin installation");
255 }