diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/bacon-video-widget.c | 120 | ||||
-rw-r--r-- | src/backend/bacon-video-widget.h | 2 | ||||
-rw-r--r-- | src/test-totem.c | 31 | ||||
-rw-r--r-- | src/totem-menu.c | 69 | ||||
-rw-r--r-- | src/totem-menu.h | 6 |
5 files changed, 157 insertions, 71 deletions
diff --git a/src/backend/bacon-video-widget.c b/src/backend/bacon-video-widget.c index 8e3306952..3ca45043d 100644 --- a/src/backend/bacon-video-widget.c +++ b/src/backend/bacon-video-widget.c @@ -99,6 +99,9 @@ #define REVERSE_RATE -1.0 #define DIRECTION_STR (forward == FALSE ? "reverse" : "forward") +#define BVW_TRACK_NONE -2 +#define BVW_TRACK_AUTO -1 + #define is_error(e, d, c) \ (e->domain == GST_##d##_ERROR && \ e->code == GST_##d##_ERROR_##c) @@ -2585,12 +2588,9 @@ bacon_video_widget_get_property (GObject * object, guint property_id, * bacon_video_widget_get_subtitle: * @bvw: a #BaconVideoWidget * - * Returns the index of the current subtitles. - * - * If the widget is not playing, <code class="literal">-2</code> will be returned. If no subtitles are - * being used, <code class="literal">-1</code> is returned. + * Returns the id of the current subtitles. * - * Return value: the subtitle index + * Return value: the subtitle id **/ int bacon_video_widget_get_subtitle (BaconVideoWidget * bvw) @@ -2598,13 +2598,13 @@ bacon_video_widget_get_subtitle (BaconVideoWidget * bvw) int subtitle = -1; gint flags; - g_return_val_if_fail (BACON_IS_VIDEO_WIDGET (bvw), -2); - g_return_val_if_fail (bvw->play != NULL, -2); + g_return_val_if_fail (BACON_IS_VIDEO_WIDGET (bvw), BVW_TRACK_NONE); + g_return_val_if_fail (bvw->play != NULL, BVW_TRACK_NONE); g_object_get (bvw->play, "flags", &flags, NULL); if ((flags & GST_PLAY_FLAG_TEXT) == 0) - return -2; + return BVW_TRACK_NONE; g_object_get (G_OBJECT (bvw->play), "current-text", &subtitle, NULL); @@ -2615,8 +2615,8 @@ static gboolean sublang_is_valid (int sublang, int n_sublang) { - if (sublang == -1 || - sublang == -2) + if (sublang == BVW_TRACK_AUTO || + sublang == BVW_TRACK_NONE) return TRUE; if (sublang < 0) return FALSE; @@ -2628,10 +2628,9 @@ sublang_is_valid (int sublang, /** * bacon_video_widget_set_subtitle: * @bvw: a #BaconVideoWidget - * @subtitle: a subtitle index + * @subtitle: a subtitle id * - * Sets the subtitle index for @bvw. If @subtitle is <code class="literal">-1</code>, no subtitles will - * be used. + * Sets the subtitle id for @bvw. **/ void bacon_video_widget_set_subtitle (BaconVideoWidget * bvw, int subtitle) @@ -2647,7 +2646,7 @@ bacon_video_widget_set_subtitle (BaconVideoWidget * bvw, int subtitle) g_return_if_fail (sublang_is_valid (subtitle, n_text)); - if (subtitle == -2) { + if (subtitle == BVW_TRACK_NONE) { flags &= ~GST_PLAY_FLAG_TEXT; subtitle = -1; } else { @@ -2664,11 +2663,30 @@ bacon_video_widget_set_subtitle (BaconVideoWidget * bvw, int subtitle) } } +static BvwLangInfo * +find_next_info_for_id (GList *list, + int current) +{ + GList *l; + + if (list == NULL) + return NULL; + for (l = list; l != NULL; l = l->next) { + BvwLangInfo *info = l->data; + if (info->id == current) { + if (l->next == NULL) + return list->data; + return l->next->data; + } + } + return NULL; +} + /** * bacon_video_widget_set_next_subtitle: * @bvw: a #BaconVideoWidget * - * Switch to the next text subtitle index for the current video. See + * Switch to the next text subtitle for the current video. See * bacon_video_widget_set_subtitle(). * * Since: 3.12 @@ -2676,16 +2694,18 @@ bacon_video_widget_set_subtitle (BaconVideoWidget * bvw, int subtitle) void bacon_video_widget_set_next_subtitle (BaconVideoWidget *bvw) { - int n_text; + BvwLangInfo *info; int current_text; - g_object_get (bvw->play, "current-text", ¤t_text, "n-text", &n_text, NULL); - - current_text++; - if (current_text >= n_text) - current_text = -2; - - bacon_video_widget_set_subtitle (bvw, current_text); + current_text = bacon_video_widget_get_subtitle (bvw); + info = find_next_info_for_id (bvw->subtitles, current_text); + if (!info) { + GST_DEBUG ("Could not find next subtitle id (current = %d)", current_text); + return; + } + GST_DEBUG ("Switching from subtitle %d to next %d", current_text, info->id); + bacon_video_widget_set_subtitle (bvw, info->id); + g_signal_emit (bvw, bvw_signals[SIGNAL_SUBTITLES_CHANGED], 0); } static gboolean @@ -2845,6 +2865,7 @@ get_lang_list_for_type (BaconVideoWidget * bvw, const gchar * type_name) g_signal_emit_by_name (G_OBJECT (bvw->play), signal, i, &tags); info = g_new0 (BvwLangInfo, 1); + info->id = i; if (tags) { gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &info->language); @@ -2867,11 +2888,10 @@ static void print_lang_list (GList *list) { GList *l; - guint i; - for (l = list, i = 0; l != NULL; l = l->next, i++) { + for (l = list; l != NULL; l = l->next) { BvwLangInfo *info = l->data; - GST_DEBUG (" %d: %s / %s / %s", i, + GST_DEBUG (" %d: %s / %s / %s", info->id, GST_STR_NULL (info->title), GST_STR_NULL (info->language), GST_STR_NULL (info->codec)); @@ -2884,6 +2904,15 @@ update_subtitles_tracks (BaconVideoWidget *bvw) g_autolist(BvwLangInfo) list; list = get_lang_list_for_type (bvw, "TEXT"); + + /* Add "none" if there's subs */ + if (list != NULL || bvw->subtitle_uri != NULL) { + BvwLangInfo *info; + info = g_new0 (BvwLangInfo, 1); + info->id = BVW_TRACK_NONE; + info->codec = g_strdup ("none"); + list = g_list_prepend (list, info); + } if (bvw_lang_infos_equal (list, bvw->subtitles)) return FALSE; if (bvw->subtitles) @@ -2900,6 +2929,15 @@ update_languages_tracks (BaconVideoWidget *bvw) g_autolist(BvwLangInfo) list; list = get_lang_list_for_type (bvw, "AUDIO"); + + /* Add "auto" if we have a DVD */ + if (g_str_has_prefix (bvw->mrl, "dvd:")) { + BvwLangInfo *info; + info = g_new0 (BvwLangInfo, 1); + info->id = 0; + info->codec = g_strdup ("auto"); + list = g_list_prepend (list, info); + } if (bvw_lang_infos_equal (list, bvw->languages)) return FALSE; if (bvw->languages) @@ -2965,7 +3003,7 @@ bacon_video_widget_get_languages (BaconVideoWidget * bvw) * bacon_video_widget_get_language: * @bvw: a #BaconVideoWidget * - * Returns the index of the current audio language. + * Returns the id of the current audio language. * * If the widget is not playing, or the default language is in use, <code class="literal">-1</code> will be returned. * @@ -2989,8 +3027,7 @@ bacon_video_widget_get_language (BaconVideoWidget * bvw) * @bvw: a #BaconVideoWidget * @language: an audio language index * - * Sets the audio language index for @bvw. If @language is <code class="literal">-1</code>, the default language will - * be used. + * Sets the audio language id for @bvw. **/ void bacon_video_widget_set_language (BaconVideoWidget * bvw, int language) @@ -3005,11 +3042,6 @@ bacon_video_widget_set_language (BaconVideoWidget * bvw, int language) g_return_if_fail (sublang_is_valid (language, n_lang)); - if (language == -1) - language = 0; - else if (language == -2) - language = -1; - GST_DEBUG ("setting language to %d", language); g_object_set (bvw->play, "current-audio", language, NULL); @@ -3030,7 +3062,7 @@ bacon_video_widget_set_language (BaconVideoWidget * bvw, int language) * bacon_video_widget_set_next_language: * @bvw: a #BaconVideoWidget * - * Switch to the next audio language index for the current video. See + * Switch to the next audio language for the current video. See * bacon_video_widget_set_language(). * * Since: 3.12 @@ -3038,16 +3070,18 @@ bacon_video_widget_set_language (BaconVideoWidget * bvw, int language) void bacon_video_widget_set_next_language (BaconVideoWidget *bvw) { - int n_audio; + BvwLangInfo *info; int current_audio; - g_object_get (bvw->play, "current-audio", ¤t_audio, "n-audio", &n_audio, NULL); - - current_audio++; - if (current_audio >= n_audio) - current_audio = -2; - - bacon_video_widget_set_language (bvw, current_audio); + g_object_get (bvw->play, "current-audio", ¤t_audio, NULL); + info = find_next_info_for_id (bvw->languages, current_audio); + if (!info) { + GST_DEBUG ("Could not find next language id (current = %d)", current_audio); + return; + } + GST_DEBUG ("Switching from audio track %d to next %d", current_audio, info->id); + bacon_video_widget_set_language (bvw, info->id); + g_signal_emit (bvw, bvw_signals[SIGNAL_LANGUAGES_CHANGED], 0); } /** diff --git a/src/backend/bacon-video-widget.h b/src/backend/bacon-video-widget.h index 19e0a59c1..0e6c77b22 100644 --- a/src/backend/bacon-video-widget.h +++ b/src/backend/bacon-video-widget.h @@ -343,6 +343,7 @@ void bacon_video_widget_dvd_event (BaconVideoWidget *bvw, * @language: the ISO-639 language code for the track, or "und" if unknown. * Can never be %NULL. * @codec: the codec for the track, or %NULL if unknown or unset. + * @index: an opaque track identifier. * * #BvwLangInfo holds the title, language code and codec for each * subtitle or audio track for a media, which would allow the @@ -352,6 +353,7 @@ typedef struct { char *title; char *language; char *codec; + guint id; } BvwLangInfo; void bacon_video_widget_lang_info_free (BvwLangInfo *info); diff --git a/src/test-totem.c b/src/test-totem.c index 1de005b1b..de4520a22 100644 --- a/src/test-totem.c +++ b/src/test-totem.c @@ -23,6 +23,15 @@ bvw_lang_info_new (const char *title, return info; } +static const char * +nth_label (GList *list, guint index) +{ + MenuItem *item = g_list_nth_data (list, index); + if (!item) + return NULL; + return item->label; +} + static void test_menus_lang_info (void) { @@ -36,8 +45,8 @@ test_menus_lang_info (void) ret = bvw_lang_info_to_menu_labels (l, BVW_TRACK_TYPE_AUDIO); g_list_free_full (l, (GDestroyNotify) bacon_video_widget_lang_info_free); - g_assert_cmpstr (g_list_nth_data (ret, 0), ==, "Audio Track #1"); - g_assert_cmpstr (g_list_nth_data (ret, 1), ==, "Audio Track #2"); + g_assert_cmpstr (nth_label (ret, 0), ==, "Audio Track #1"); + g_assert_cmpstr (nth_label (ret, 1), ==, "Audio Track #2"); g_list_free_full (ret, g_free); /* Same language, same codecs */ @@ -49,9 +58,9 @@ test_menus_lang_info (void) ret = bvw_lang_info_to_menu_labels (l, BVW_TRACK_TYPE_AUDIO); g_list_free_full (l, (GDestroyNotify) bacon_video_widget_lang_info_free); - g_assert_cmpstr (g_list_nth_data (ret, 0), ==, "English #1"); - g_assert_cmpstr (g_list_nth_data (ret, 1), ==, "English #2"); - g_assert_cmpstr (g_list_nth_data (ret, 2), ==, "French"); + g_assert_cmpstr (nth_label (ret, 0), ==, "English #1"); + g_assert_cmpstr (nth_label (ret, 1), ==, "English #2"); + g_assert_cmpstr (nth_label (ret, 2), ==, "French"); g_list_free_full (ret, g_free); /* Same language, different codecs */ @@ -63,9 +72,9 @@ test_menus_lang_info (void) ret = bvw_lang_info_to_menu_labels (l, BVW_TRACK_TYPE_AUDIO); g_list_free_full (l, (GDestroyNotify) bacon_video_widget_lang_info_free); - g_assert_cmpstr (g_list_nth_data (ret, 0), ==, "English — Dolby Pro Racing"); - g_assert_cmpstr (g_list_nth_data (ret, 1), ==, "English — Dolby Amateur 5.1"); - g_assert_cmpstr (g_list_nth_data (ret, 2), ==, "French"); + g_assert_cmpstr (nth_label (ret, 0), ==, "English — Dolby Pro Racing"); + g_assert_cmpstr (nth_label (ret, 1), ==, "English — Dolby Amateur 5.1"); + g_assert_cmpstr (nth_label (ret, 2), ==, "French"); g_list_free_full (ret, g_free); /* Different languages */ @@ -77,9 +86,9 @@ test_menus_lang_info (void) ret = bvw_lang_info_to_menu_labels (l, BVW_TRACK_TYPE_AUDIO); g_list_free_full (l, (GDestroyNotify) bacon_video_widget_lang_info_free); - g_assert_cmpstr (g_list_nth_data (ret, 0), ==, "English"); - g_assert_cmpstr (g_list_nth_data (ret, 1), ==, "Spanish; Castilian"); - g_assert_cmpstr (g_list_nth_data (ret, 2), ==, "French"); + g_assert_cmpstr (nth_label (ret, 0), ==, "English"); + g_assert_cmpstr (nth_label (ret, 1), ==, "Spanish; Castilian"); + g_assert_cmpstr (nth_label (ret, 2), ==, "French"); g_list_free_full (ret, g_free); } diff --git a/src/totem-menu.c b/src/totem-menu.c index 3016ad5fd..d92414d8f 100644 --- a/src/totem-menu.c +++ b/src/totem-menu.c @@ -419,6 +419,36 @@ get_language_name_no_und (const char *lang, return NULL; } +void +free_menu_item (MenuItem *item) +{ + if (!item) + return; + g_free (item->label); + g_free (item); +} + +static MenuItem * +create_special_menu_item (BvwLangInfo *info) +{ + MenuItem *menu_item; + const char *label; + + if (g_strcmp0 (info->codec, "auto") == 0) { + /* Translators: an entry in the "Languages" menu, used to choose the audio language of a DVD */ + label = C_("Language", "Auto"); + } else if (g_strcmp0 (info->codec, "none") == 0) { + /* Translators: an entry in the "Subtitles" menu, used to choose the subtitle language of a DVD */ + label = _("None"); + } else + return NULL; + + menu_item = g_new0 (MenuItem, 1); + menu_item->label = g_strdup (_(label)); + menu_item->id = info->id; + return menu_item; +} + GList * bvw_lang_info_to_menu_labels (GList *langs, BvwTrackType track_type) @@ -435,6 +465,9 @@ bvw_lang_info_to_menu_labels (GList *langs, int num; char *id; + if (!info->language) + continue; + num = hash_table_num_instances (lang_table, info->language); num++; g_hash_table_insert (lang_table, @@ -453,9 +486,16 @@ bvw_lang_info_to_menu_labels (GList *langs, printed_table = g_hash_table_new (g_str_hash, g_str_equal); for (l = langs; l != NULL; l = l->next) { BvwLangInfo *info = l->data; + MenuItem *menu_item; int num; char *str; + menu_item = create_special_menu_item (info); + if (menu_item) { + ret = g_list_prepend (ret, menu_item); + continue; + } + num = hash_table_num_instances (lang_table, info->language); g_assert (num >= 1); if (num > 1) { @@ -483,7 +523,10 @@ bvw_lang_info_to_menu_labels (GList *langs, str = g_strdup (get_language_name_no_und (info->language, track_type)); } - ret = g_list_prepend (ret, str); + menu_item = g_new0 (MenuItem, 1); + menu_item->label = str; + menu_item->id = info->id; + ret = g_list_prepend (ret, menu_item); } g_hash_table_destroy (printed_table); @@ -510,13 +553,12 @@ static void add_lang_action (GMenu *menu, const char *action, const char *label, - int lang_id) + int id) { - char *escaped_label; + g_autofree char *escaped_label = NULL; escaped_label = escape_label_for_menu (label); - add_lang_item (menu, escaped_label, action, lang_id); - g_free (escaped_label); + add_lang_item (menu, escaped_label, action, id); } static void @@ -526,22 +568,15 @@ create_lang_actions (GMenu *menu, BvwTrackType track_type) { GList *ui_list, *l; - guint i; - - if (track_type == BVW_TRACK_TYPE_SUBTITLE) { - /* Translators: an entry in the "Subtitles" menu, used to choose the subtitle language of a DVD */ - add_lang_action (menu, action, _("None"), -2); - } - - /* Translators: an entry in the "Languages" menu, used to choose the audio language of a DVD */ - add_lang_action (menu, action, C_("Language", "Auto"), -1); ui_list = bvw_lang_info_to_menu_labels (list, track_type); - for (l = ui_list, i = 0; l != NULL; l = l->next, i++) - add_lang_action (menu, action, l->data, i); + for (l = ui_list; l != NULL; l = l->next) { + MenuItem *item = l->data; + add_lang_action (menu, action, item->label, item->id); + } - g_list_free_full (ui_list, (GDestroyNotify) g_free); + g_list_free_full (ui_list, (GDestroyNotify) free_menu_item); } static void diff --git a/src/totem-menu.h b/src/totem-menu.h index f826e0219..035535871 100644 --- a/src/totem-menu.h +++ b/src/totem-menu.h @@ -35,8 +35,14 @@ void totem_subtitles_menu_update (Totem *totem); void totem_languages_menu_update (Totem *totem); /* For test use only */ +typedef struct { + char *label; + int id; +} MenuItem; + GList *bvw_lang_info_to_menu_labels (GList *langs, BvwTrackType track_type); +void free_menu_item (MenuItem *item); G_END_DECLS |