~walkerlee/totem/pre-interview

« back to all changes in this revision

Viewing changes to src/totem-missing-plugins.c

Tags: 2.24.3-3
* totem-mozilla.docs: ship README.browser-plugin which explains how to 
  disable the plugin for some MIME types.
* rules: remove the hack that only let totem-xine support VCDs and 
  DVDs, now that GStreamer supports them. Closes: #370789.
* 01_fake_keypresses.patch: new patch. Completely disable the broken 
  XTEST code that generates fake keypresses. Closes: #500330.
* 90_autotools.patch: regenerated.
* Build-depend on nautilus 2.22 to be sure to build the extension for 
  the correct version.
* totem-xine depends on libxine1-x.
* Standards version is 3.8.1.
* Upload to unstable.
* 04_tracker_build.patch: new patch, stolen upstream. Fix build with 
  latest tracker version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* totem-missing-plugins.c
2
 
 
3
 
   Copyright (C) 2007 Tim-Philipp Müller <tim centricular net>
4
 
 
5
 
   The Gnome Library is free software; you can redistribute it and/or
6
 
   modify it under the terms of the GNU Library General Public License as
7
 
   published by the Free Software Foundation; either version 2 of the
8
 
   License, or (at your option) any later version.
9
 
 
10
 
   The Gnome Library is distributed in the hope that it will be useful,
11
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 
   Library General Public License for more details.
14
 
 
15
 
   You should have received a copy of the GNU Library General Public
16
 
   License along with the Gnome Library; see the file COPYING.LIB.  If not,
17
 
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
 
   Boston, MA 02111-1307, USA.
19
 
 
20
 
   Author: Tim-Philipp Müller <tim centricular net>
21
 
 */
22
 
 
23
 
#include "config.h"
24
 
 
25
 
#include "totem-missing-plugins.h"
26
 
 
27
 
#ifdef ENABLE_MISSING_PLUGIN_INSTALLATION
28
 
 
29
 
#include "totem-private.h"
30
 
#include "bacon-video-widget.h"
31
 
 
32
 
#include <gst/pbutils/pbutils.h>
33
 
#include <gst/pbutils/install-plugins.h>
34
 
 
35
 
#include <gst/gst.h> /* for gst_registry_update */
36
 
 
37
 
#include <gtk/gtk.h>
38
 
 
39
 
#ifdef GDK_WINDOWING_X11
40
 
#include <gdk/gdkx.h>
41
 
#endif
42
 
 
43
 
#include <string.h>
44
 
 
45
 
GST_DEBUG_CATEGORY_EXTERN (_totem_gst_debug_cat);
46
 
#define GST_CAT_DEFAULT _totem_gst_debug_cat
47
 
 
48
 
/* list of blacklisted detail strings */
49
 
static GList *blacklisted_plugins = NULL;
50
 
 
51
 
typedef struct
52
 
{
53
 
        gboolean   playing;
54
 
        gchar    **descriptions;
55
 
        gchar    **details;
56
 
        Totem     *totem;
57
 
}
58
 
TotemCodecInstallContext;
59
 
 
60
 
static gboolean
61
 
totem_codec_install_plugin_is_blacklisted (const gchar * detail)
62
 
{
63
 
        GList *res;
64
 
 
65
 
        res = g_list_find_custom (blacklisted_plugins,
66
 
                                  detail,
67
 
                                  (GCompareFunc) strcmp);
68
 
 
69
 
        return (res != NULL);   
70
 
}
71
 
 
72
 
static void
73
 
totem_codec_install_blacklist_plugin (const gchar * detail)
74
 
{
75
 
        if (!totem_codec_install_plugin_is_blacklisted (detail))
76
 
        {
77
 
                blacklisted_plugins = g_list_prepend (blacklisted_plugins,
78
 
                                                      g_strdup (detail));
79
 
        }
80
 
}
81
 
 
82
 
static void
83
 
totem_codec_install_context_free (TotemCodecInstallContext *ctx)
84
 
{
85
 
        g_strfreev (ctx->descriptions);
86
 
        g_strfreev (ctx->details);
87
 
        g_free (ctx);
88
 
}
89
 
 
90
 
static void
91
 
on_plugin_installation_done (GstInstallPluginsReturn res, gpointer user_data)
92
 
{
93
 
        TotemCodecInstallContext *ctx = (TotemCodecInstallContext *) user_data;
94
 
        gchar **p;
95
 
 
96
 
        GST_INFO ("res = %d (%s)", res, gst_install_plugins_return_get_name (res));
97
 
 
98
 
        switch (res)
99
 
        {
100
 
                /* treat partial success the same as success; in the worst case we'll
101
 
                 * just do another round and get NOT_FOUND as result that time */
102
 
                case GST_INSTALL_PLUGINS_PARTIAL_SUCCESS:
103
 
                case GST_INSTALL_PLUGINS_SUCCESS:
104
 
                        {
105
 
                                /* blacklist installed plugins too, so that we don't get
106
 
                                 * into endless installer loops in case of inconsistencies */
107
 
                                for (p = ctx->details; p != NULL && *p != NULL; ++p)
108
 
                                        totem_codec_install_blacklist_plugin (*p);
109
 
 
110
 
                                bacon_video_widget_stop (ctx->totem->bvw);
111
 
                                g_message ("Missing plugins installed. Updating plugin registry ...");
112
 
 
113
 
                                /* force GStreamer to re-read its plugin registry */
114
 
                                if (gst_update_registry ())
115
 
                                {
116
 
                                        g_message ("Plugin registry updated, trying again.");
117
 
                                        bacon_video_widget_play (ctx->totem->bvw, NULL);
118
 
                                } else {
119
 
                                        g_warning ("GStreamer registry update failed");
120
 
                                        /* FIXME: should we show an error message here? */
121
 
                                }
122
 
                        }
123
 
                        break;
124
 
                case GST_INSTALL_PLUGINS_NOT_FOUND:
125
 
                        {
126
 
                                g_message ("No installation candidate for missing plugins found.");
127
 
 
128
 
                                /* NOT_FOUND should only be returned if not a single one of the
129
 
                                 * requested plugins was found; if we managed to play something
130
 
                                 * anyway, we should just continue playing what we have and
131
 
                                 * blacklist the requested plugins for this session; if we
132
 
                                 * could not play anything we should blacklist them as well,
133
 
                                 * so the install wizard isn't called again for nothing */
134
 
                                for (p = ctx->details; p != NULL && *p != NULL; ++p)
135
 
                                        totem_codec_install_blacklist_plugin (*p);
136
 
 
137
 
                                if (ctx->playing)
138
 
                                {
139
 
                                        bacon_video_widget_play (ctx->totem->bvw, NULL);
140
 
                                } else {
141
 
                                        /* wizard has not shown error, do stop/play again,
142
 
                                         * so that an error message gets shown */
143
 
                                        bacon_video_widget_stop (ctx->totem->bvw);
144
 
                                        bacon_video_widget_play (ctx->totem->bvw, NULL);
145
 
                                }
146
 
                        }
147
 
                        break;
148
 
                case GST_INSTALL_PLUGINS_USER_ABORT:
149
 
                        {
150
 
                                /* blacklist on user abort, so we show an error next time (or
151
 
                                 * just play what we can) instead of calling the installer */
152
 
                                for (p = ctx->details; p != NULL && *p != NULL; ++p)
153
 
                                        totem_codec_install_blacklist_plugin (*p);
154
 
 
155
 
                                if (ctx->playing) {
156
 
                                        bacon_video_widget_play (ctx->totem->bvw, NULL);
157
 
                                } else {
158
 
                                        /* if we couldn't play anything, do stop/play again,
159
 
                                         * so that an error message gets shown */
160
 
                                        bacon_video_widget_stop (ctx->totem->bvw);
161
 
                                        bacon_video_widget_play (ctx->totem->bvw, NULL);
162
 
                                }
163
 
                        }
164
 
                        break;
165
 
                case GST_INSTALL_PLUGINS_ERROR:
166
 
                case GST_INSTALL_PLUGINS_CRASHED:
167
 
                default:
168
 
                        {
169
 
                                g_message ("Missing plugin installation failed: %s",
170
 
                                           gst_install_plugins_return_get_name (res));
171
 
 
172
 
                                if (ctx->playing)
173
 
                                        bacon_video_widget_play (ctx->totem->bvw, NULL);
174
 
                                else
175
 
                                        bacon_video_widget_stop (ctx->totem->bvw);
176
 
                                break;
177
 
                        }
178
 
        }
179
 
 
180
 
        totem_codec_install_context_free (ctx);
181
 
}
182
 
 
183
 
static gboolean
184
 
totem_on_missing_plugins_event (BaconVideoWidget *bvw, char **details,
185
 
                                char **descriptions, gboolean playing,
186
 
                                Totem *totem)
187
 
{
188
 
        GstInstallPluginsContext *install_ctx;
189
 
        TotemCodecInstallContext *ctx;
190
 
        GstInstallPluginsReturn status;
191
 
        guint i, num;
192
 
 
193
 
        num = g_strv_length (details);
194
 
        g_return_val_if_fail (num > 0 && g_strv_length (descriptions) == num, FALSE);
195
 
 
196
 
        ctx = g_new0 (TotemCodecInstallContext, 1);
197
 
        ctx->descriptions = g_strdupv (descriptions);
198
 
        ctx->details = g_strdupv (details);
199
 
        ctx->playing = playing;
200
 
        ctx->totem = totem;
201
 
 
202
 
        for (i = 0; i < num; ++i)
203
 
        {
204
 
                if (totem_codec_install_plugin_is_blacklisted (ctx->details[i]))
205
 
                {
206
 
                        g_message ("Missing plugin: %s (ignoring)", ctx->details[i]);
207
 
                        g_free (ctx->details[i]);
208
 
                        g_free (ctx->descriptions[i]);
209
 
                        ctx->details[i] = ctx->details[num-1];
210
 
                        ctx->descriptions[i] = ctx->descriptions[num-1];
211
 
                        ctx->details[num-1] = NULL;
212
 
                        ctx->descriptions[num-1] = NULL;
213
 
                        --num;
214
 
                        --i;
215
 
                } else {
216
 
                        g_message ("Missing plugin: %s (%s)", ctx->details[i], ctx->descriptions[i]);
217
 
                }
218
 
        }
219
 
 
220
 
        if (num == 0)
221
 
        {
222
 
                g_message ("All missing plugins are blacklisted, doing nothing");
223
 
                totem_codec_install_context_free (ctx);
224
 
                return FALSE;
225
 
        }
226
 
 
227
 
        install_ctx = gst_install_plugins_context_new ();
228
 
 
229
 
#ifdef GDK_WINDOWING_X11
230
 
        if (totem->win != NULL && GTK_WIDGET_REALIZED (totem->win))
231
 
        {
232
 
                gulong xid = 0;
233
 
 
234
 
                xid = GDK_WINDOW_XWINDOW (GTK_WIDGET (totem->win)->window);
235
 
                gst_install_plugins_context_set_xid (install_ctx, xid);
236
 
        }
237
 
#endif
238
 
 
239
 
        status = gst_install_plugins_async (ctx->details, install_ctx,
240
 
                                            on_plugin_installation_done,
241
 
                                            ctx);
242
 
 
243
 
        gst_install_plugins_context_free (install_ctx);
244
 
 
245
 
        GST_INFO ("gst_install_plugins_async() result = %d", status);
246
 
 
247
 
        if (status != GST_INSTALL_PLUGINS_STARTED_OK)
248
 
        {
249
 
                if (status == GST_INSTALL_PLUGINS_HELPER_MISSING)
250
 
                {
251
 
                        g_message ("Automatic missing codec installation not supported "
252
 
                                   "(helper script missing)");
253
 
                } else {
254
 
                        g_warning ("Failed to start codec installation: %s",
255
 
                                   gst_install_plugins_return_get_name (status));
256
 
                }
257
 
                totem_codec_install_context_free (ctx);
258
 
                return FALSE;
259
 
        }
260
 
 
261
 
        /* if we managed to start playing, pause playback, since some install
262
 
         * wizard should now take over in a second anyway and the user might not
263
 
         * be able to use totem's controls while the wizard is running */
264
 
        if (playing)
265
 
                bacon_video_widget_pause (bvw);
266
 
 
267
 
        return TRUE;
268
 
}
269
 
 
270
 
#endif /* ENABLE_MISSING_PLUGIN_INSTALLATION */
271
 
 
272
 
void
273
 
totem_missing_plugins_setup (Totem *totem)
274
 
{
275
 
#ifdef ENABLE_MISSING_PLUGIN_INSTALLATION
276
 
        g_signal_connect (G_OBJECT (totem->bvw),
277
 
                        "missing-plugins",
278
 
                        G_CALLBACK (totem_on_missing_plugins_event),
279
 
                        totem);
280
 
 
281
 
        gst_pb_utils_init ();
282
 
 
283
 
        GST_INFO ("Set up support for automatic missing plugin installation");
284
 
#endif
285
 
}