Merge lp:~om26er/ubuntu/natty/totem/totem-fixes into lp:~ubuntu-desktop/totem/ubuntu

Proposed by Omer Akram
Status: Merged
Merged at revision: 99
Proposed branch: lp:~om26er/ubuntu/natty/totem/totem-fixes
Merge into: lp:~ubuntu-desktop/totem/ubuntu
Diff against target: 677 lines (+642/-0)
6 files modified
debian/changelog (+12/-0)
debian/patches/74_add_new_playlist_api.patch (+296/-0)
debian/patches/74_fix_compile.patch (+20/-0)
debian/patches/74_use_new_playlist_api.patch (+275/-0)
debian/patches/75_fix_screenshotting_of_interlaced_videos.patch (+35/-0)
debian/patches/series (+4/-0)
To merge this branch: bzr merge lp:~om26er/ubuntu/natty/totem/totem-fixes
Reviewer Review Type Date Requested Status
Ubuntu Sponsors Pending
Review via email: mp+53427@code.launchpad.net

Description of the change

backporting the fixes for bug 705361 and bug 659001 from gnome git.

builds on 32-bit https://launchpad.net/~om26er/+archive/unity/+buildjob/2322265 64-bit is still waiting to build

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2011-02-17 01:22:04 +0000
3+++ debian/changelog 2011-03-15 12:48:47 +0000
4@@ -1,3 +1,15 @@
5+totem (2.32.0-0ubuntu10) natty; urgency=low
6+
7+ * debian/patches/74_add_new_playlist_api.patch
8+ debian/patches/74_use_new_playlist_api.patch:
9+ - Fix the DnD of files in the playlist sidepane. (LP: #659001)
10+ * debian/patches/74_fix_compile.patch:
11+ - Fix compiling after the above two patches.
12+ * debian/patches/75_fix_screenshotting_of_interlaced_videos.patch:
13+ - Take screenshot does not work for some videos. (LP: #705361)
14+
15+ -- Omer Akram <om26er@ubuntu.com> Tue, 15 Mar 2011 17:29:09 +0500
16+
17 totem (2.32.0-0ubuntu9) natty; urgency=low
18
19 * debian/{control{,.in},rules}: enable PIE build for security hardening
20
21=== added file 'debian/patches/74_add_new_playlist_api.patch'
22--- debian/patches/74_add_new_playlist_api.patch 1970-01-01 00:00:00 +0000
23+++ debian/patches/74_add_new_playlist_api.patch 2011-03-15 12:48:47 +0000
24@@ -0,0 +1,296 @@
25+From: Omer Akram <om26er@ubuntu.com>
26+Author: Philip Withnall <philip@tecnocode.co.uk>
27+Subject: Add totem_playlist_add_mrls() API.
28+Origin: http://git.gnome.org/browse/totem/commit/?h=gnome-2-32&id=a9ed336231663812c58ac0fb544d9b9a9862a90e
29+Bug: https://bugs.gnome.org/636686
30+Bug-Ubuntu: https://launchpad.net/bugs/659001
31+
32+--- a/src/totem-playlist.c
33++++ b/src/totem-playlist.c
34+@@ -1949,6 +1949,257 @@ totem_playlist_add_mrl_sync (TotemPlaylist *playlist, const char *mrl, const cha
35+ return handle_parse_result (totem_pl_parser_parse (playlist->priv->parser, mrl, FALSE), playlist, mrl, display_name);
36+ }
37+
38++typedef struct {
39++ TotemPlaylist *playlist;
40++ GList *mrls; /* list of TotemPlaylistMrlDatas */
41++ gboolean cursor;
42++ GAsyncReadyCallback callback;
43++ gpointer user_data;
44++
45++ guint next_index_to_add;
46++ GList *unadded_entries; /* list of TotemPlaylistMrlDatas */
47++ volatile gint entries_remaining;
48++} AddMrlsOperationData;
49++
50++static void
51++add_mrls_operation_data_free (AddMrlsOperationData *data)
52++{
53++ /* Remove the cursor, if one was set */
54++ if (data->cursor)
55++ unset_waiting_cursor (data->playlist);
56++
57++ g_list_foreach (data->mrls, (GFunc) totem_playlist_mrl_data_free, NULL);
58++ g_list_free (data->mrls);
59++ g_object_unref (data->playlist);
60++
61++ g_slice_free (AddMrlsOperationData, data);
62++}
63++
64++struct TotemPlaylistMrlData {
65++ gchar *mrl;
66++ gchar *display_name;
67++
68++ /* Implementation details */
69++ AddMrlsOperationData *operation_data;
70++ guint index;
71++};
72++
73++/**
74++ * totem_playlist_mrl_data_new:
75++ * @mrl: a MRL
76++ * @display_name: (allow-none): a human-readable display name for the MRL, or %NULL
77++ *
78++ * Create a new #TotemPlaylistMrlData struct storing the given @mrl and @display_name.
79++ *
80++ * This will typically be immediately appended to a #GList to be passed to totem_playlist_add_mrls().
81++ *
82++ * Return value: (transfer full): a new #TotemPlaylistMrlData; free with totem_playlist_mrl_data_free()
83++ *
84++ * Since: 3.0
85++ */
86++TotemPlaylistMrlData *
87++totem_playlist_mrl_data_new (const gchar *mrl,
88++ const gchar *display_name)
89++{
90++ TotemPlaylistMrlData *data;
91++
92++ g_return_val_if_fail (mrl != NULL && *mrl != '\0', NULL);
93++
94++ data = g_slice_new (TotemPlaylistMrlData);
95++ data->mrl = g_strdup (mrl);
96++ data->display_name = g_strdup (display_name);
97++
98++ return data;
99++}
100++
101++/**
102++ * totem_playlist_mrl_data_free:
103++ * @data: (transfer full): a #TotemPlaylistMrlData
104++ *
105++ * Free the given #TotemPlaylistMrlData struct. This should not generally be called by code outside #TotemPlaylist.
106++ *
107++ * Since: 3.0
108++ */
109++void
110++totem_playlist_mrl_data_free (TotemPlaylistMrlData *data)
111++{
112++ g_return_if_fail (data != NULL);
113++
114++ /* NOTE: This doesn't call add_mrls_operation_data_free() on @data->operation_data, since it's shared with other instances of
115++ * TotemPlaylistMrlData, and not truly reference counted. */
116++ g_free (data->display_name);
117++ g_free (data->mrl);
118++
119++ g_slice_free (TotemPlaylistMrlData, data);
120++}
121++
122++static void
123++add_mrls_finish_operation (AddMrlsOperationData *operation_data)
124++{
125++ /* Check whether this is the final callback invocation; iff it is, we can call the user's callback for the entire operation and free the
126++ * operation data */
127++ if (g_atomic_int_dec_and_test (&(operation_data->entries_remaining)) == TRUE) {
128++ GSimpleAsyncResult *async_result;
129++
130++ async_result = g_simple_async_result_new (G_OBJECT (operation_data->playlist), operation_data->callback, operation_data->user_data,
131++ totem_playlist_add_mrls);
132++ g_simple_async_result_complete (async_result);
133++ g_object_unref (async_result);
134++
135++ add_mrls_operation_data_free (operation_data);
136++ }
137++}
138++
139++/* Called exactly once for each MRL in a totem_playlist_add_mrls() operation. Called in the thread running the main loop. If the MRL which has just
140++ * been parsed is the next one in the sequence (of entries in @mrls as passed to totem_playlist_add_mrls()), it's added to the playlist proper.
141++ * Otherwise, it's added to a sorted queue of MRLs which have had their callbacks called out of order.
142++ * When a MRL is added to the playlist proper, any successor MRLs which are in the sorted queue are also added to the playlist proper.
143++ * When add_mrls_cb() is called for the last time for a given call to totem_playlist_add_mrls(), it calls the user's callback for the operation
144++ * (passed as @callback to totem_playlist_add_mrls()) and frees the #AddMrlsOperationData struct. This is handled by add_mrls_finish_operation().
145++ * The #TotemPlaylistMrlData for each MRL is freed by add_mrls_operation_data_free() at the end of the entire operation. */
146++static void
147++add_mrls_cb (TotemPlParser *parser, GAsyncResult *result, TotemPlaylistMrlData *mrl_data)
148++{
149++ TotemPlParserResult res;
150++ AddMrlsOperationData *operation_data = mrl_data->operation_data;
151++
152++ /* Finish parsing the playlist */
153++ res = totem_pl_parser_parse_finish (parser, result, NULL);
154++
155++ g_assert (mrl_data->index >= operation_data->next_index_to_add);
156++
157++ if (mrl_data->index == operation_data->next_index_to_add) {
158++ GList *i;
159++
160++ /* The entry is the next one in the order, so doesn't need to be added to the unadded list, and can be added to playlist proper */
161++ operation_data->next_index_to_add++;
162++ handle_parse_result (res, operation_data->playlist, mrl_data->mrl, mrl_data->display_name);
163++
164++ /* See if we can now add any other entries which have already been processed */
165++ for (i = operation_data->unadded_entries;
166++ i != NULL && ((TotemPlaylistMrlData*) i->data)->index == operation_data->next_index_to_add;
167++ i = g_list_delete_link (i, i)) {
168++ TotemPlaylistMrlData *_mrl_data = (TotemPlaylistMrlData*) i->data;
169++
170++ operation_data->next_index_to_add++;
171++ handle_parse_result (res, operation_data->playlist, _mrl_data->mrl, _mrl_data->display_name);
172++ }
173++
174++ operation_data->unadded_entries = i;
175++ } else {
176++ GList *i;
177++
178++ /* The entry has been parsed out of order, so needs to be added (in the correct position) to the unadded list for latter addition to
179++ * the playlist proper */
180++ for (i = operation_data->unadded_entries; i != NULL && mrl_data->index > ((TotemPlaylistMrlData*) i->data)->index; i = i->next);
181++ operation_data->unadded_entries = g_list_insert_before (operation_data->unadded_entries, i, mrl_data);
182++ }
183++
184++ /* Check whether this is the last callback; call the user's callback for the entire operation and free the operation data if appropriate */
185++ add_mrls_finish_operation (operation_data);
186++}
187++
188++/**
189++ * totem_playlist_add_mrls:
190++ * @self: a #TotemPlaylist
191++ * @mrls: (element-type TotemPlaylistMrlData) (transfer full): a list of #TotemPlaylistMrlData structs
192++ * @cursor: %TRUE to set a waiting cursor on the playlist for the duration of the operation, %FALSE otherwise
193++ * @cancellable: (allow-none): a #Cancellable, or %NULL
194++ * @callback: (scope async) (allow-none): callback to call once all the MRLs have been added to the playlist, or %NULL
195++ * @user_data: (closure) (allow-none): user data to pass to @callback, or %NULL
196++ *
197++ * Add the MRLs listed in @mrls to the playlist asynchronously, and ensuring that they're added to the playlist in the order they appear in the
198++ * input #GList.
199++ *
200++ * @mrls should be a #GList of #TotemPlaylistMrlData structs, each created with totem_playlist_mrl_data_new(). This function takes ownership of both
201++ * the list and its elements when called, so don't free either after calling totem_playlist_add_mrls().
202++ *
203++ * @callback will be called after all the MRLs in @mrls have been parsed and (if they were parsed successfully) added to the playlist. In the
204++ * callback function, totem_playlist_add_mrls_finish() should be called to check for errors.
205++ *
206++ * Since: 3.0
207++ */
208++void
209++totem_playlist_add_mrls (TotemPlaylist *self,
210++ GList *mrls,
211++ gboolean cursor,
212++ GCancellable *cancellable,
213++ GAsyncReadyCallback callback,
214++ gpointer user_data)
215++{
216++ AddMrlsOperationData *operation_data;
217++ GList *i;
218++ guint mrl_index = 0;
219++
220++ g_return_if_fail (TOTEM_IS_PLAYLIST (self));
221++ g_return_if_fail (mrls != NULL);
222++ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
223++
224++ /* Build the data struct to pass to the callback function */
225++ operation_data = g_slice_new (AddMrlsOperationData);
226++ operation_data->playlist = g_object_ref (self);
227++ operation_data->mrls = mrls;
228++ operation_data->cursor = cursor;
229++ operation_data->callback = callback;
230++ operation_data->user_data = user_data;
231++ operation_data->next_index_to_add = mrl_index;
232++ operation_data->unadded_entries = NULL;
233++ g_atomic_int_set (&(operation_data->entries_remaining), 1);
234++
235++ /* Display a waiting cursor if required */
236++ if (cursor)
237++ set_waiting_cursor (self);
238++
239++ for (i = mrls; i != NULL; i = i->next) {
240++ TotemPlaylistMrlData *mrl_data = (TotemPlaylistMrlData*) i->data;
241++
242++ if (mrl_data == NULL)
243++ continue;
244++
245++ /* Set the item's parsing index, so that it's inserted into the playlist in the position it appeared in @mrls */
246++ mrl_data->operation_data = operation_data;
247++ mrl_data->index = mrl_index++;
248++
249++ g_atomic_int_inc (&(operation_data->entries_remaining));
250++
251++ /* Start parsing the playlist. Once this is complete, add_mrls_cb() is called (i.e. it's called exactly once for each entry in
252++ * @mrls).
253++ * TODO: Cancellation is currently not supoprted, since no consumers of this API make use of it, and it needs careful thought when
254++ * being implemented, as a separate #GCancellable instance will have to be created for each parallel computation. */
255++ totem_pl_parser_parse_async (self->priv->parser, mrl_data->mrl, FALSE, NULL, (GAsyncReadyCallback) add_mrls_cb, mrl_data);
256++ }
257++
258++ /* Deal with the case that all async operations completed before we got to this point (since we've held a reference to the operation data so
259++ * that it doesn't get freed prematurely if all the scheduled async parse operations complete before we've finished scheduling the rest. */
260++ add_mrls_finish_operation (operation_data);
261++}
262++
263++/**
264++ * totem_playlist_add_mrls_finish:
265++ * @self: a #TotemPlaylist
266++ * @result: the #GAsyncResult that was provided to the callback
267++ * @error: (allow-none): a #GError for error reporting, or %NULL
268++ *
269++ * Finish an asynchronous batch MRL addition operation started by totem_playlist_add_mrls().
270++ *
271++ * Return value: %TRUE on success, %FALSE otherwise
272++ *
273++ * Since: 3.0
274++ */
275++gboolean
276++totem_playlist_add_mrls_finish (TotemPlaylist *self,
277++ GAsyncResult *result,
278++ GError **error)
279++{
280++ g_return_val_if_fail (TOTEM_IS_PLAYLIST (self), FALSE);
281++ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
282++ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
283++ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), totem_playlist_add_mrls), FALSE);
284++
285++ /* We don't have anything to return at the moment. */
286++ return TRUE;
287++}
288++
289+ static gboolean
290+ totem_playlist_clear_cb (GtkTreeModel *model,
291+ GtkTreePath *path,
292+diff --git a/src/totem-playlist.h b/src/totem-playlist.h
293+index d7e5a65..7342e0a 100644
294+--- a/src/totem-playlist.h
295++++ b/src/totem-playlist.h
296+@@ -100,6 +100,22 @@ gboolean totem_playlist_add_mrl_sync (TotemPlaylist *playlist,
297+ const char *mrl,
298+ const char *display_name);
299+
300++typedef struct TotemPlaylistMrlData TotemPlaylistMrlData;
301++
302++TotemPlaylistMrlData *totem_playlist_mrl_data_new (const gchar *mrl,
303++ const gchar *display_name);
304++void totem_playlist_mrl_data_free (TotemPlaylistMrlData *data);
305++
306++void totem_playlist_add_mrls (TotemPlaylist *self,
307++ GList *mrls,
308++ gboolean cursor,
309++ GCancellable *cancellable,
310++ GAsyncReadyCallback callback,
311++ gpointer user_data);
312++gboolean totem_playlist_add_mrls_finish (TotemPlaylist *self,
313++ GAsyncResult *result,
314++ GError **error);
315++
316+ void totem_playlist_save_current_playlist (TotemPlaylist *playlist,
317+ const char *output);
318+ void totem_playlist_save_current_playlist_ext (TotemPlaylist *playlist,
319+--
320+cgit v0.8.3.4
321
322=== added file 'debian/patches/74_fix_compile.patch'
323--- debian/patches/74_fix_compile.patch 1970-01-01 00:00:00 +0000
324+++ debian/patches/74_fix_compile.patch 2011-03-15 12:48:47 +0000
325@@ -0,0 +1,20 @@
326+From: Omer Akram <om26er@ubuntu.com>
327+Author: Bastien Nocera <hadess@hadess.net>
328+Subject: Publish: Make it compile again.
329+Origin: http://git.gnome.org/browse/totem/commit/?h=gnome-2-32&id=67c4c2e07b00487391ab8b906360d3f3f09e9b84
330+Bug: https://bugs.gnome.org/636686
331+Bug-Ubuntu: https://launchpad.net/bugs/659001
332+
333+--- a/src/plugins/publish/totem-publish.c
334++++ b/src/plugins/publish/totem-publish.c
335+@@ -443,7 +443,7 @@ totem_publish_plugin_load_playlist (TotemPublishPlugin *self,
336+
337+ /* Add the MRLs to the playlist asynchronously and in order */
338+ if (mrl_list != NULL)
339+- totem_playlist_add_mrls (self->priv->totem->playlist, g_list_reverse (mrl_list), FALSE, NULL, NULL, NULL);
340++ totem_playlist_add_mrls (self->totem->playlist, g_list_reverse (mrl_list), FALSE, NULL, NULL, NULL);
341+ }
342+
343+ out:
344+--
345+cgit v0.8.3.4
346
347=== added file 'debian/patches/74_use_new_playlist_api.patch'
348--- debian/patches/74_use_new_playlist_api.patch 1970-01-01 00:00:00 +0000
349+++ debian/patches/74_use_new_playlist_api.patch 2011-03-15 12:48:47 +0000
350@@ -0,0 +1,275 @@
351+From: Omer Akram <om26er@ubuntu.com>
352+Author: Philip Withnall <philip@tecnocode.co.uk>
353+Subject: Use the new totem_playlist_add_mrls() API to add multiple playlist entries.
354+Origin: http://git.gnome.org/browse/totem/commit/?h=gnome-2-32&id=75f0ef09df10d3a1d6a8a3063c3258b128bc2e08
355+Bug: https://bugs.gnome.org/636686
356+Bug-Ubuntu: https://launchpad.net/bugs/659001
357+
358+--- a/src/plugins/publish/totem-publish.c
359++++ b/src/plugins/publish/totem-publish.c
360+@@ -412,6 +412,7 @@ totem_publish_plugin_load_playlist (TotemPublishPlugin *self,
361+
362+ if (contents && g_key_file_load_from_data (keyfile, contents, length, G_KEY_FILE_NONE, &error)) {
363+ gint i, n_entries;
364++ GList *mrl_list = NULL;
365+
366+ /* returns zero in case of errors */
367+ n_entries = g_key_file_get_integer (keyfile, "playlist", "NumberOfEntries", &error);
368+@@ -434,11 +435,15 @@ totem_publish_plugin_load_playlist (TotemPublishPlugin *self,
369+ g_free (key);
370+
371+ if (mrl)
372+- totem_playlist_add_mrl (self->totem->playlist, mrl, title, FALSE, NULL, NULL, NULL);
373++ mrl_list = g_list_prepend (mrl_list, totem_playlist_mrl_data_new (mrl, title));
374+
375+ g_free (title);
376+ g_free (mrl);
377+ }
378++
379++ /* Add the MRLs to the playlist asynchronously and in order */
380++ if (mrl_list != NULL)
381++ totem_playlist_add_mrls (self->priv->totem->playlist, g_list_reverse (mrl_list), FALSE, NULL, NULL, NULL);
382+ }
383+
384+ out:
385+diff --git a/src/totem-object.c b/src/totem-object.c
386+index badf169..dc17a45 100644
387+--- a/src/totem-object.c
388++++ b/src/totem-object.c
389+@@ -2136,31 +2136,20 @@ totem_action_show_help (Totem *totem)
390+ }
391+ }
392+
393+-typedef struct {
394+- gint add_mrl_complete;
395+- Totem *totem;
396+-} DropFilesData;
397+-
398+ /* This is called in the main thread */
399+ static void
400+-totem_action_drop_files_finished (TotemPlaylist *playlist, GAsyncResult *result, DropFilesData *data)
401++totem_action_drop_files_finished (TotemPlaylist *playlist, GAsyncResult *result, TotemObject *totem)
402+ {
403+- /* When add_mrl_complete reaches 0, this is the last callback to occur and we can safely reconnect the playlist's changed signal (which was
404+- * disconnected below in totem_action_drop_files(). We can also free the data struct and generally clean up. */
405+- if (g_atomic_int_dec_and_test (&(data->add_mrl_complete)) == TRUE) {
406+- char *mrl, *subtitle;
407++ char *mrl, *subtitle;
408+
409+- /* Reconnect the signal */
410+- g_signal_connect (G_OBJECT (playlist), "changed", G_CALLBACK (playlist_changed_cb), data->totem);
411+- mrl = totem_playlist_get_current_mrl (playlist, &subtitle);
412+- totem_action_set_mrl_and_play (data->totem, mrl, subtitle);
413+- g_free (mrl);
414+- g_free (subtitle);
415++ /* Reconnect the playlist's changed signal (which was disconnected below in totem_action_drop_files(). */
416++ g_signal_connect (G_OBJECT (playlist), "changed", G_CALLBACK (playlist_changed_cb), totem);
417++ mrl = totem_playlist_get_current_mrl (playlist, &subtitle);
418++ totem_action_set_mrl_and_play (totem, mrl, subtitle);
419++ g_free (mrl);
420++ g_free (subtitle);
421+
422+- /* Free the data struct */
423+- g_object_unref (data->totem);
424+- g_slice_free (DropFilesData, data);
425+- }
426++ g_object_unref (totem);
427+ }
428+
429+ static gboolean
430+@@ -2169,8 +2158,7 @@ totem_action_drop_files (Totem *totem, GtkSelectionData *data,
431+ {
432+ char **list;
433+ guint i, len;
434+- DropFilesData *drop_files_data = NULL /* shut up gcc */;
435+- GList *p, *file_list;
436++ GList *p, *file_list, *mrl_list = NULL;
437+ gboolean cleared = FALSE;
438+
439+ list = g_uri_list_extract_uris ((const char *) gtk_selection_data_get_data (data));
440+@@ -2210,18 +2198,11 @@ totem_action_drop_files (Totem *totem, GtkSelectionData *data,
441+ g_signal_handlers_disconnect_by_func (G_OBJECT (totem->playlist), playlist_changed_cb, totem);
442+ totem_playlist_clear (totem->playlist);
443+ cleared = TRUE;
444+-
445+- /* Allocate some shared memory to count how many add_mrl operations have completed (see the comment below).
446+- * It's freed in totem_action_drop_files_cb() once all add_mrl operations have finished. */
447+- drop_files_data = g_slice_new (DropFilesData);
448+- drop_files_data->add_mrl_complete = len;
449+- drop_files_data->totem = g_object_ref (totem);
450+ }
451+
452+ /* Add each MRL to the playlist asynchronously */
453+ for (p = file_list; p != NULL; p = p->next) {
454+- const char *filename;
455+- char *title;
456++ const char *filename, *title;
457+
458+ filename = p->data;
459+ title = NULL;
460+@@ -2237,15 +2218,17 @@ totem_action_drop_files (Totem *totem, GtkSelectionData *data,
461+ }
462+ }
463+
464+- /* Add the MRL to the playlist. We need to reconnect playlist's "changed" signal once all of the add_mrl operations have completed,
465+- * so we use a piece of allocated memory shared between the async operations to count how many have completed.
466+- * If we haven't cleared the playlist, there's no need to do this. */
467+- if (cleared == TRUE) {
468+- totem_playlist_add_mrl (totem->playlist, filename, title, TRUE, NULL,
469+- (GAsyncReadyCallback) totem_action_drop_files_finished, drop_files_data);
470+- } else {
471+- totem_playlist_add_mrl (totem->playlist, filename, title, TRUE, NULL, NULL, NULL);
472+- }
473++ /* Add the MRL data to the list of MRLs to add to the playlist */
474++ mrl_list = g_list_prepend (mrl_list, totem_playlist_mrl_data_new (filename, title));
475++ }
476++
477++ /* Add the MRLs to the playlist asynchronously and in order. We need to reconnect playlist's "changed" signal once all of the add-MRL
478++ * operations have completed. If we haven't cleared the playlist, there's no need to do this. */
479++ if (mrl_list != NULL && cleared == TRUE) {
480++ totem_playlist_add_mrls (totem->playlist, g_list_reverse (mrl_list), TRUE, NULL,
481++ (GAsyncReadyCallback) totem_action_drop_files_finished, g_object_ref (totem));
482++ } else if (mrl_list != NULL) {
483++ totem_playlist_add_mrls (totem->playlist, g_list_reverse (mrl_list), TRUE, NULL, NULL, NULL);
484+ }
485+
486+ bail:
487+@@ -2736,6 +2719,7 @@ static gboolean
488+ totem_action_open_files_list (Totem *totem, GSList *list)
489+ {
490+ GSList *l;
491++ GList *mrl_list = NULL;
492+ gboolean changed;
493+ gboolean cleared;
494+
495+@@ -2789,10 +2773,10 @@ totem_action_open_files_list (Totem *totem, GSList *list)
496+ totem_action_load_media_device (totem, data);
497+ changed = TRUE;
498+ } else if (g_str_has_prefix (filename, "dvb:/") != FALSE) {
499+- totem_playlist_add_mrl (totem->playlist, data, NULL, FALSE, NULL, NULL, NULL);
500++ mrl_list = g_list_prepend (mrl_list, totem_playlist_mrl_data_new (data, NULL));
501+ changed = TRUE;
502+ } else {
503+- totem_playlist_add_mrl (totem->playlist, filename, NULL, FALSE, NULL, NULL, NULL);
504++ mrl_list = g_list_prepend (mrl_list, totem_playlist_mrl_data_new (filename, NULL));
505+ changed = TRUE;
506+ }
507+ }
508+@@ -2800,6 +2784,10 @@ totem_action_open_files_list (Totem *totem, GSList *list)
509+ g_free (filename);
510+ }
511+
512++ /* Add the MRLs to the playlist asynchronously and in order */
513++ if (mrl_list != NULL)
514++ totem_playlist_add_mrls (totem->playlist, g_list_reverse (mrl_list), FALSE, NULL, NULL, NULL);
515++
516+ gdk_window_set_cursor (gtk_widget_get_window (totem->win), NULL);
517+
518+ /* ... and reconnect because we're nice people */
519+diff --git a/src/totem-playlist.c b/src/totem-playlist.c
520+index eac7ced..f893575 100644
521+--- a/src/totem-playlist.c
522++++ b/src/totem-playlist.c
523+@@ -489,6 +489,8 @@ gtk_tree_selection_has_selected (GtkTreeSelection *selection)
524+ static void
525+ drop_finished_cb (TotemPlaylist *playlist, GAsyncResult *result, gpointer user_data)
526+ {
527++ totem_playlist_add_mrls_finish (playlist, result, NULL);
528++
529+ /* Emit the "changed" signal once the last dropped MRL has been added to the playlist */
530+ g_signal_emit (G_OBJECT (playlist),
531+ totem_playlist_table_signals[CHANGED], 0,
532+@@ -506,7 +508,7 @@ drop_cb (GtkWidget *widget,
533+ TotemPlaylist *playlist)
534+ {
535+ char **list;
536+- GList *p, *file_list;
537++ GList *p, *file_list, *mrl_list = NULL;
538+ guint i;
539+ GdkDragAction action;
540+
541+@@ -570,16 +572,16 @@ drop_cb (GtkWidget *widget,
542+ }
543+ }
544+
545+- /* Add the MRL to the playlist asynchronously. If it's the last MRL, emit the "changed"
546+- * signal once we're done adding it */
547+- if (p->next == NULL)
548+- totem_playlist_add_mrl (playlist, filename, title, TRUE, NULL, (GAsyncReadyCallback) drop_finished_cb, NULL);
549+- else
550+- totem_playlist_add_mrl (playlist, filename, title, TRUE, NULL, NULL, NULL);
551+-
552++ /* Add the MRL to the list of MRLs to be added to the playlist */
553++ mrl_list = g_list_prepend (mrl_list, totem_playlist_mrl_data_new (filename, title));
554+ g_free (filename);
555+ }
556+
557++ /* Add all the MRLs to the playlist asynchronously, emitting the "changed" signal once we're done.
558++ * Note that this takes ownership of @mrl_list. */
559++ if (mrl_list != NULL)
560++ totem_playlist_add_mrls (playlist, g_list_reverse (mrl_list), TRUE, NULL, (GAsyncReadyCallback) drop_finished_cb, NULL);
561++
562+ g_strfreev (list);
563+ g_list_free (file_list);
564+ gtk_drag_finish (context, TRUE, FALSE, _time);
565+@@ -853,20 +855,22 @@ void
566+ totem_playlist_add_files (GtkWidget *widget, TotemPlaylist *playlist)
567+ {
568+ GSList *filenames, *l;
569++ GList *mrl_list = NULL;
570+
571+ filenames = totem_add_files (totem_playlist_get_toplevel (playlist), NULL);
572+ if (filenames == NULL)
573+ return;
574+
575+ for (l = filenames; l != NULL; l = l->next) {
576+- char *mrl;
577+-
578+- mrl = l->data;
579+- totem_playlist_add_mrl (playlist, mrl, NULL, TRUE, NULL, NULL, NULL);
580++ char *mrl = l->data;
581++ mrl_list = g_list_prepend (mrl_list, totem_playlist_mrl_data_new (mrl, NULL));
582+ g_free (mrl);
583+ }
584+
585+ g_slist_free (filenames);
586++
587++ if (mrl_list != NULL)
588++ totem_playlist_add_mrls (playlist, g_list_reverse (mrl_list), TRUE, NULL, NULL, NULL);
589+ }
590+
591+ static void
592+diff --git a/src/totem-video-list.c b/src/totem-video-list.c
593+index f6fc828..bb01931 100644
594+--- a/src/totem-video-list.c
595++++ b/src/totem-video-list.c
596+@@ -461,6 +461,7 @@ add_to_playlist_action_callback (GtkAction *action, TotemVideoList *self)
597+ GtkTreePath *path;
598+ GtkTreeIter iter;
599+ gchar *mrl, *display_name;
600++ GList *mrl_list = NULL;
601+ GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self));
602+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
603+ GList *l = gtk_tree_selection_get_selected_rows (selection, NULL);
604+@@ -482,7 +483,7 @@ add_to_playlist_action_callback (GtkAction *action, TotemVideoList *self)
605+ continue;
606+ }
607+
608+- totem_playlist_add_mrl (playlist, mrl, display_name, TRUE, NULL, NULL, NULL);
609++ mrl_list = g_list_prepend (mrl_list, totem_playlist_mrl_data_new (mrl, display_name));
610+
611+ g_free (mrl);
612+ g_free (display_name);
613+@@ -490,6 +491,10 @@ add_to_playlist_action_callback (GtkAction *action, TotemVideoList *self)
614+
615+ g_list_foreach (l, (GFunc) gtk_tree_path_free, NULL);
616+ g_list_free (l);
617++
618++ /* Asynchronously add all the MRLs to the playlist in order */
619++ if (mrl_list != NULL)
620++ totem_playlist_add_mrls (playlist, g_list_reverse (mrl_list), TRUE, NULL, NULL, NULL);
621+ }
622+
623+ void
624+--
625+cgit v0.8.3.4
626
627=== added file 'debian/patches/75_fix_screenshotting_of_interlaced_videos.patch'
628--- debian/patches/75_fix_screenshotting_of_interlaced_videos.patch 1970-01-01 00:00:00 +0000
629+++ debian/patches/75_fix_screenshotting_of_interlaced_videos.patch 2011-03-15 12:48:47 +0000
630@@ -0,0 +1,35 @@
631+From: Omer Akram <om26er@ubuntu.com>
632+Author: Tim-Philipp Müller <tim@centricular.net>
633+Subject: Fix screenshotting of interlaced videos.
634+Origin: http://git.gnome.org/browse/totem/commit/?id=b427beeab1d41154b4243d51b500839db543deea
635+Bug: https://bugs.gnome.org/640933
636+Bug-Ubuntu: https://launchpad.net/bugs/705361
637+
638+--- a/src/backend/bacon-video-widget-gst-0.10.c
639++++ b/src/backend/bacon-video-widget-gst-0.10.c
640+@@ -6427,7 +6427,10 @@ bacon_video_widget_get_current_frame (BaconVideoWidget * bvw)
641+ "depth", G_TYPE_INT, 24,
642+ /* Note: we don't ask for a specific width/height here, so that
643+ * videoscale can adjust dimensions from a non-1/1 pixel aspect
644+- * ratio to a 1/1 pixel-aspect-ratio */
645++ * ratio to a 1/1 pixel-aspect-ratio. We also don't ask for a
646++ * specific framerate, because the input framerate won't
647++ * necessarily match the output framerate if there's a deinterlacer
648++ * in the pipeline. */
649+ "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
650+ "endianness", G_TYPE_INT, G_BIG_ENDIAN,
651+ "red_mask", G_TYPE_INT, 0xff0000,
652+@@ -6435,11 +6438,6 @@ bacon_video_widget_get_current_frame (BaconVideoWidget * bvw)
653+ "blue_mask", G_TYPE_INT, 0x0000ff,
654+ NULL);
655+
656+- if (bvw->priv->video_fps_n > 0 && bvw->priv->video_fps_d > 0) {
657+- gst_caps_set_simple (to_caps, "framerate", GST_TYPE_FRACTION,
658+- bvw->priv->video_fps_n, bvw->priv->video_fps_d, NULL);
659+- }
660+-
661+ GST_DEBUG ("frame caps: %" GST_PTR_FORMAT, GST_BUFFER_CAPS (buf));
662+ GST_DEBUG ("pixbuf caps: %" GST_PTR_FORMAT, to_caps);
663+
664+--
665+cgit v0.8.3.4
666
667=== modified file 'debian/patches/series'
668--- debian/patches/series 2011-01-29 14:57:16 +0000
669+++ debian/patches/series 2011-03-15 12:48:47 +0000
670@@ -6,3 +6,7 @@
671 71_add_show_tooltip_uri_property.patch
672 72_dont_display_URIs_in_youtube_tooltips.patch
673 73_show_video_title.patch
674+74_add_new_playlist_api.patch
675+74_use_new_playlist_api.patch
676+74_fix_compile.patch
677+75_fix_screenshotting_of_interlaced_videos.patch

Subscribers

People subscribed via source and target branches

to all changes: