hythmbox-2.98/lib/rb-missing-plugins.c

No issues found

Incomplete coverage

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
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
  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 (&param[0], G_TYPE_POINTER);
 93 	g_value_set_pointer (&param[0], NULL);
 94 	g_value_init (&param[1], G_TYPE_BOOLEAN);
 95 	g_value_set_boolean (&param[1], retry);
 96 
 97 	g_closure_invoke (ctx->closure, NULL, 2, param, NULL);
 98 	g_value_unset (&param[0]);
 99 	g_value_unset (&param[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 }