From 30e2d15a0a2b1c39900e50ec932655877d548723 Mon Sep 17 00:00:00 2001 From: Roman Moravcik Date: Mon, 18 Jan 2010 09:43:44 +0100 Subject: [PATCH] Created fork of mafw-gst-renderer with subtitles support --- Makefile.am | 2 +- applet/Makefile.am | 12 + applet/cpmpsubtitles.c | 561 +++++++++++++++++++++++ applet/cpmpsubtitles.desktop | 9 + configure.ac | 18 +- debian/control | 21 +- debian/mafw-gst-renderer.install.in | 1 - debian/mafw-gst-renderer.postinst | 6 - debian/mafw-gst-renderer.prerm | 6 - debian/mafw-gst-subtitles-renderer.install.in | 3 + debian/mafw-gst-subtitles-renderer.postinst | 6 + debian/mafw-gst-subtitles-renderer.prerm | 6 + libmafw-gst-renderer/mafw-gst-renderer-utils.c | 143 ++++++ libmafw-gst-renderer/mafw-gst-renderer-utils.h | 2 + libmafw-gst-renderer/mafw-gst-renderer-worker.c | 37 +- libmafw-gst-renderer/mafw-gst-renderer-worker.h | 11 + libmafw-gst-renderer/mafw-gst-renderer.c | 117 +++++ 17 files changed, 937 insertions(+), 24 deletions(-) create mode 100644 applet/Makefile.am create mode 100644 applet/cpmpsubtitles.c create mode 100644 applet/cpmpsubtitles.desktop delete mode 100644 debian/mafw-gst-renderer.install.in delete mode 100644 debian/mafw-gst-renderer.postinst delete mode 100644 debian/mafw-gst-renderer.prerm create mode 100644 debian/mafw-gst-subtitles-renderer.install.in create mode 100644 debian/mafw-gst-subtitles-renderer.postinst create mode 100644 debian/mafw-gst-subtitles-renderer.prerm diff --git a/Makefile.am b/Makefile.am index 6ab6aea..ce4bb8d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,7 +6,7 @@ # Copyright (C) 2007, 2008, 2009 Nokia. All rights reserved. -SUBDIRS = libmafw-gst-renderer +SUBDIRS = libmafw-gst-renderer applet if ENABLE_TESTS SUBDIRS += tests diff --git a/applet/Makefile.am b/applet/Makefile.am new file mode 100644 index 0000000..957dc9b --- /dev/null +++ b/applet/Makefile.am @@ -0,0 +1,12 @@ +lib_LTLIBRARIES = libcpmpsubtitles.la + +libcpmpsubtitles_la_SOURCES = cpmpsubtitles.c +libcpmpsubtitles_la_LIBADD = $(MAFW_SUBTITLES_CPA_LIBS) +libcpmpsubtitles_la_CPPFLAGS = $(MAFW_SUBTITLES_CPA_CFLAGS) +libcpmpsubtitles_la_LDFLAGS = module -avoid-version + +libdir = $(CPA_PLUGINDIR) + +desktop_DATA = cpmpsubtitles.desktop +desktopdir = $(CPA_DESKTOPDIR) +EXTRA_DIST = $(desktop_DATA) diff --git a/applet/cpmpsubtitles.c b/applet/cpmpsubtitles.c new file mode 100644 index 0000000..740ec5d --- /dev/null +++ b/applet/cpmpsubtitles.c @@ -0,0 +1,561 @@ +/* + * Subtitles control panel applet. + * Copyright (C) 2010 Roman Moravcik + * + * encodings structure imported from totem-subtitle-encoding.c + * Copyright (C) 2001-2006 Bastien Nocera + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#include +#include +#include + +#include + + +#define GETTEXT_PACKAGE "osso-applet-subtitles" +#include + +#define GCONF_MAFW_GST_SUBTITLE_RENDERER "/system/mafw/mafw-gst-renderer" +#define _HL(str) dgettext("hildon-libs",str) + +typedef enum +{ + SUBTITLE_ENCODING_CURRENT_LOCALE, + + SUBTITLE_ENCODING_ISO_8859_6, + SUBTITLE_ENCODING_IBM_864, + SUBTITLE_ENCODING_MAC_ARABIC, + SUBTITLE_ENCODING_WINDOWS_1256, + + SUBTITLE_ENCODING_ARMSCII_8, + + SUBTITLE_ENCODING_ISO_8859_4, + SUBTITLE_ENCODING_ISO_8859_13, + SUBTITLE_ENCODING_WINDOWS_1257, + + SUBTITLE_ENCODING_ISO_8859_14, + + SUBTITLE_ENCODING_ISO_8859_2, + SUBTITLE_ENCODING_IBM_852, + SUBTITLE_ENCODING_MAC_CE, + SUBTITLE_ENCODING_WINDOWS_1250, + + SUBTITLE_ENCODING_GB18030, + SUBTITLE_ENCODING_GB2312, + SUBTITLE_ENCODING_GBK, + SUBTITLE_ENCODING_HZ, + + SUBTITLE_ENCODING_BIG5, + SUBTITLE_ENCODING_BIG5_HKSCS, + SUBTITLE_ENCODING_EUC_TW, + + SUBTITLE_ENCODING_MAC_CROATIAN, + + SUBTITLE_ENCODING_ISO_8859_5, + SUBTITLE_ENCODING_IBM_855, + SUBTITLE_ENCODING_ISO_IR_111, + SUBTITLE_ENCODING_KOI8_R, + SUBTITLE_ENCODING_MAC_CYRILLIC, + SUBTITLE_ENCODING_WINDOWS_1251, + + SUBTITLE_ENCODING_CP_866, + + SUBTITLE_ENCODING_MAC_UKRAINIAN, + SUBTITLE_ENCODING_KOI8_U, + + SUBTITLE_ENCODING_GEOSTD8, + + SUBTITLE_ENCODING_ISO_8859_7, + SUBTITLE_ENCODING_MAC_GREEK, + SUBTITLE_ENCODING_WINDOWS_1253, + + SUBTITLE_ENCODING_MAC_GUJARATI, + + SUBTITLE_ENCODING_MAC_GURMUKHI, + + SUBTITLE_ENCODING_ISO_8859_8_I, + SUBTITLE_ENCODING_IBM_862, + SUBTITLE_ENCODING_MAC_HEBREW, + SUBTITLE_ENCODING_WINDOWS_1255, + + SUBTITLE_ENCODING_ISO_8859_8, + + SUBTITLE_ENCODING_MAC_DEVANAGARI, + + SUBTITLE_ENCODING_MAC_ICELANDIC, + + SUBTITLE_ENCODING_EUC_JP, + SUBTITLE_ENCODING_ISO_2022_JP, + SUBTITLE_ENCODING_SHIFT_JIS, + + SUBTITLE_ENCODING_EUC_KR, + SUBTITLE_ENCODING_ISO_2022_KR, + SUBTITLE_ENCODING_JOHAB, + SUBTITLE_ENCODING_UHC, + + SUBTITLE_ENCODING_ISO_8859_10, + + SUBTITLE_ENCODING_MAC_FARSI, + + SUBTITLE_ENCODING_ISO_8859_16, + SUBTITLE_ENCODING_MAC_ROMANIAN, + + SUBTITLE_ENCODING_ISO_8859_3, + + SUBTITLE_ENCODING_TIS_620, + + SUBTITLE_ENCODING_ISO_8859_9, + SUBTITLE_ENCODING_IBM_857, + SUBTITLE_ENCODING_MAC_TURKISH, + SUBTITLE_ENCODING_WINDOWS_1254, + + SUBTITLE_ENCODING_UTF_7, + SUBTITLE_ENCODING_UTF_8, + SUBTITLE_ENCODING_UTF_16, + SUBTITLE_ENCODING_UCS_2, + SUBTITLE_ENCODING_UCS_4, + + SUBTITLE_ENCODING_ISO_8859_1, + SUBTITLE_ENCODING_ISO_8859_15, + SUBTITLE_ENCODING_IBM_850, + SUBTITLE_ENCODING_MAC_ROMAN, + SUBTITLE_ENCODING_WINDOWS_1252, + + SUBTITLE_ENCODING_TCVN, + SUBTITLE_ENCODING_VISCII, + SUBTITLE_ENCODING_WINDOWS_1258, + + SUBTITLE_ENCODING_LAST +} SubtitleEncodingIndex; + + +typedef struct { + int index; + const char *charset; + const char *name; +} SubtitleEncoding; + + +static SubtitleEncoding encodings[] = { + {SUBTITLE_ENCODING_CURRENT_LOCALE, NULL, "Current Locale"}, + + {SUBTITLE_ENCODING_ISO_8859_6, "ISO-8859-6", "Arabic"}, + {SUBTITLE_ENCODING_IBM_864, "IBM864", "Arabic"}, + {SUBTITLE_ENCODING_MAC_ARABIC, "MAC_ARABIC", "Arabic"}, + {SUBTITLE_ENCODING_WINDOWS_1256, "WINDOWS-1256", "Arabic"}, + + {SUBTITLE_ENCODING_ARMSCII_8, "ARMSCII-8", "Armenian"}, + + {SUBTITLE_ENCODING_ISO_8859_4, "ISO-8859-4", "Baltic"}, + {SUBTITLE_ENCODING_ISO_8859_13, "ISO-8859-13", "Baltic"}, + {SUBTITLE_ENCODING_WINDOWS_1257, "WINDOWS-1257", "Baltic"}, + + {SUBTITLE_ENCODING_ISO_8859_14, "ISO-8859-14", "Celtic"}, + + {SUBTITLE_ENCODING_ISO_8859_2, "ISO-8859-2", "Central European"}, + {SUBTITLE_ENCODING_IBM_852, "IBM852", "Central European"}, + {SUBTITLE_ENCODING_MAC_CE, "MAC_CE", "Central European"}, + {SUBTITLE_ENCODING_WINDOWS_1250, "WINDOWS-1250", "Central European"}, + + {SUBTITLE_ENCODING_GB18030, "GB18030", "Chinese Simplified"}, + {SUBTITLE_ENCODING_GB2312, "GB2312", "Chinese Simplified"}, + {SUBTITLE_ENCODING_GBK, "GBK", "Chinese Simplified"}, + {SUBTITLE_ENCODING_HZ, "HZ", "Chinese Simplified"}, + + {SUBTITLE_ENCODING_BIG5, "BIG5", "Chinese Traditional"}, + {SUBTITLE_ENCODING_BIG5_HKSCS, "BIG5-HKSCS", "Chinese Traditional"}, + {SUBTITLE_ENCODING_EUC_TW, "EUC-TW", "Chinese Traditional"}, + + {SUBTITLE_ENCODING_MAC_CROATIAN, "MAC_CROATIAN", "Croatian"}, + + {SUBTITLE_ENCODING_ISO_8859_5, "ISO-8859-5", "Cyrillic"}, + {SUBTITLE_ENCODING_IBM_855, "IBM855", "Cyrillic"}, + {SUBTITLE_ENCODING_ISO_IR_111, "ISO-IR-111", "Cyrillic"}, + {SUBTITLE_ENCODING_KOI8_R, "KOI8-R", "Cyrillic"}, + {SUBTITLE_ENCODING_MAC_CYRILLIC, "MAC-CYRILLIC", "Cyrillic"}, + {SUBTITLE_ENCODING_WINDOWS_1251, "WINDOWS-1251", "Cyrillic"}, + + {SUBTITLE_ENCODING_CP_866, "CP866", "Cyrillic/Russian"}, + + {SUBTITLE_ENCODING_MAC_UKRAINIAN, "MAC_UKRAINIAN", "Cyrillic/Ukrainian"}, + {SUBTITLE_ENCODING_KOI8_U, "KOI8-U", "Cyrillic/Ukrainian"}, + + {SUBTITLE_ENCODING_GEOSTD8, "GEORGIAN-PS", "Georgian"}, + + {SUBTITLE_ENCODING_ISO_8859_7, "ISO-8859-7", "Greek"}, + {SUBTITLE_ENCODING_MAC_GREEK, "MAC_GREEK", "Greek"}, + {SUBTITLE_ENCODING_WINDOWS_1253, "WINDOWS-1253", "Greek"}, + + {SUBTITLE_ENCODING_MAC_GUJARATI, "MAC_GUJARATI", "Gujarati"}, + + {SUBTITLE_ENCODING_MAC_GURMUKHI, "MAC_GURMUKHI", "Gurmukhi"}, + + {SUBTITLE_ENCODING_ISO_8859_8_I, "ISO-8859-8-I", "Hebrew"}, + {SUBTITLE_ENCODING_IBM_862, "IBM862", "Hebrew"}, + {SUBTITLE_ENCODING_MAC_HEBREW, "MAC_HEBREW", "Hebrew"}, + {SUBTITLE_ENCODING_WINDOWS_1255, "WINDOWS-1255", "Hebrew"}, + + {SUBTITLE_ENCODING_ISO_8859_8, "ISO-8859-8", "Hebrew Visual"}, + + {SUBTITLE_ENCODING_MAC_DEVANAGARI, "MAC_DEVANAGARI", "Hindi"}, + + {SUBTITLE_ENCODING_MAC_ICELANDIC, "MAC_ICELANDIC", "Icelandic"}, + + {SUBTITLE_ENCODING_EUC_JP, "EUC-JP", "Japanese"}, + {SUBTITLE_ENCODING_ISO_2022_JP, "ISO2022JP", "Japanese"}, + {SUBTITLE_ENCODING_SHIFT_JIS, "SHIFT-JIS", "Japanese"}, + + {SUBTITLE_ENCODING_EUC_KR, "EUC-KR", "Korean"}, + {SUBTITLE_ENCODING_ISO_2022_KR, "ISO2022KR", "Korean"}, + {SUBTITLE_ENCODING_JOHAB, "JOHAB", "Korean"}, + {SUBTITLE_ENCODING_UHC, "UHC", "Korean"}, + + {SUBTITLE_ENCODING_ISO_8859_10, "ISO-8859-10", "Nordic"}, + + {SUBTITLE_ENCODING_MAC_FARSI, "MAC_FARSI", "Persian"}, + + {SUBTITLE_ENCODING_ISO_8859_16, "ISO-8859-16", "Romanian"}, + {SUBTITLE_ENCODING_MAC_ROMANIAN, "MAC_ROMANIAN", "Romanian"}, + + {SUBTITLE_ENCODING_ISO_8859_3, "ISO-8859-3", "South European"}, + + {SUBTITLE_ENCODING_TIS_620, "TIS-620", "Thai"}, + + {SUBTITLE_ENCODING_ISO_8859_9, "ISO-8859-9", "Turkish"}, + {SUBTITLE_ENCODING_IBM_857, "IBM857", "Turkish"}, + {SUBTITLE_ENCODING_MAC_TURKISH, "MAC_TURKISH", "Turkish"}, + {SUBTITLE_ENCODING_WINDOWS_1254, "WINDOWS-1254", "Turkish"}, + + {SUBTITLE_ENCODING_UTF_7, "UTF-7", "Unicode"}, + {SUBTITLE_ENCODING_UTF_8, "UTF-8", "Unicode"}, + {SUBTITLE_ENCODING_UTF_16, "UTF-16", "Unicode"}, + {SUBTITLE_ENCODING_UCS_2, "UCS-2", "Unicode"}, + {SUBTITLE_ENCODING_UCS_4, "UCS-4", "Unicode"}, + + {SUBTITLE_ENCODING_ISO_8859_1, "ISO-8859-1", "Western"}, + {SUBTITLE_ENCODING_ISO_8859_15, "ISO-8859-15", "Western"}, + {SUBTITLE_ENCODING_IBM_850, "IBM850", "Western"}, + {SUBTITLE_ENCODING_MAC_ROMAN, "MAC_ROMAN", "Western"}, + {SUBTITLE_ENCODING_WINDOWS_1252, "WINDOWS-1252", "Western"}, + + {SUBTITLE_ENCODING_TCVN, "TCVN", "Vietnamese"}, + {SUBTITLE_ENCODING_VISCII, "VISCII", "Vietnamese"}, + {SUBTITLE_ENCODING_WINDOWS_1258, "WINDOWS-1258", "Vietnamese"} +}; + +static gboolean +gconf_get_bool (GConfClient *client, + const gchar *key) +{ + gboolean value = FALSE; + gchar *tmp = NULL; + + tmp = g_strdup_printf ("%s/%s", GCONF_MAFW_GST_SUBTITLE_RENDERER, key); + + value = gconf_client_get_bool (client, tmp, NULL); + + if (tmp) + g_free (tmp); + + return value; +} + +static void +gconf_set_bool (GConfClient *client, + const gchar *key, + gboolean value) +{ + gchar *tmp = NULL; + + tmp = g_strdup_printf ("%s/%s", GCONF_MAFW_GST_SUBTITLE_RENDERER, key); + + gconf_client_set_bool (client, tmp, value, NULL); + + if (tmp) + g_free (tmp); +} + +static gchar * +gconf_get_string (GConfClient *client, + gchar *key) +{ + gchar *value = FALSE; + gchar *tmp = NULL; + + tmp = g_strdup_printf ("%s/%s", GCONF_MAFW_GST_SUBTITLE_RENDERER, key); + + value = gconf_client_get_string (client, tmp, NULL); + + if (tmp) + g_free (tmp); + + return value; +} + +static void +gconf_set_string (GConfClient *client, + gchar *key, + const gchar *value) +{ + gchar *tmp = NULL; + + tmp = g_strdup_printf ("%s/%s", GCONF_MAFW_GST_SUBTITLE_RENDERER, key); + + if (value) + gconf_client_set_string (client, tmp, value, NULL); + else + gconf_client_unset (client, tmp, NULL); + + if (tmp) + g_free (tmp); +} + +static void +font_selector_dialog (HildonButton *button, + gpointer user_data) +{ + GtkWidget *dialog, *hbox; + + dialog = gtk_dialog_new (); + gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); + gtk_window_set_title (GTK_WINDOW (dialog), _("Subtitle font")); + gtk_dialog_add_button(GTK_DIALOG (dialog), "OK", GTK_RESPONSE_ACCEPT); + + hbox = gtk_hbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox); + + // pango_font_description_from_string + + /* Run the dialog */ + gtk_widget_show_all (GTK_WIDGET (dialog)); + if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { + // pango_font_description_to_string + } + + gtk_widget_destroy(GTK_WIDGET(dialog)); +} + + +static GtkWidget * +create_encoding_selector (void) +{ + GtkWidget *selector; + gint index = 0; + + selector = hildon_touch_selector_new_text (); + + while (index < SUBTITLE_ENCODING_LAST) { + gchar *encoding = NULL; + + if (encodings[index].charset) { + encoding = g_strdup_printf ("%s (%s)", encodings[index].name, + encodings[index].charset); + } else { + encoding = g_strdup_printf ("%s", encodings[index].name); + } + + hildon_touch_selector_insert_text (HILDON_TOUCH_SELECTOR (selector), + encodings[index].index, + encoding); + if (encoding) + g_free (encoding); + index++; + } + + return selector; +} + +static GtkWidget * +create_autoload_subtitles_button (GConfClient *gconf_client) +{ + GtkWidget *button; + gboolean autoload_subtitles = FALSE; + + button = hildon_check_button_new (HILDON_SIZE_FINGER_HEIGHT); + gtk_button_set_label (GTK_BUTTON (button), _("Automatically load subtitle files")); + + autoload_subtitles = gconf_get_bool (gconf_client, "autoload_subtitles"); + if (autoload_subtitles) + hildon_check_button_set_active (HILDON_CHECK_BUTTON (button), TRUE); + else + hildon_check_button_set_active (HILDON_CHECK_BUTTON (button), FALSE); + + return button; +} + +static void +save_autoload_subtitles (GConfClient *gconf_client, + GtkWidget *widget) +{ + if (hildon_check_button_get_active (HILDON_CHECK_BUTTON (widget))) + gconf_set_bool (gconf_client, "autoload_subtitles", TRUE); + else + gconf_set_bool (gconf_client, "autoload_subtitles", FALSE); +} + +static GtkWidget * +create_subtitles_font_button (GConfClient *gconf_client) +{ + GtkWidget *button; + const gchar *font = NULL; + + button = hildon_button_new (HILDON_SIZE_FINGER_HEIGHT, + HILDON_BUTTON_ARRANGEMENT_VERTICAL); + hildon_button_set_title (HILDON_BUTTON (button), _("Font")); + hildon_button_set_alignment (HILDON_BUTTON (button), 0.0, 0.5, 1.0, 0.0); + hildon_button_set_title_alignment (HILDON_BUTTON(button), 0.0, 0.5); + hildon_button_set_value_alignment (HILDON_BUTTON (button), 0.0, 0.5); + + g_signal_connect (button, "clicked", G_CALLBACK (font_selector_dialog), NULL); + + font = gconf_get_string (gconf_client, "subtitle_font"); + if (font) { + hildon_button_set_value (HILDON_BUTTON (button), font); + } else { + hildon_button_set_value (HILDON_BUTTON (button), "Sans Bold 18"); + } + return button; +} + +static void +save_subtitles_font (GConfClient *gconf_client, + GtkWidget *widget) +{ + const gchar *font = NULL; + + font = hildon_button_get_value (HILDON_BUTTON (widget)); + gconf_set_string (gconf_client, "subtitle_font", font); +} + +static GtkWidget * +create_subtitles_encoding_button (GConfClient *gconf_client) +{ + GtkWidget *button, *selector; + const gchar *encoding = NULL; + + button = hildon_picker_button_new (HILDON_SIZE_FINGER_HEIGHT, + HILDON_BUTTON_ARRANGEMENT_VERTICAL); + hildon_button_set_title (HILDON_BUTTON (button), _("Encoding")); + hildon_button_set_alignment (HILDON_BUTTON (button), 0.0, 0.5, 1.0, 0.0); + hildon_button_set_title_alignment (HILDON_BUTTON(button), 0.0, 0.5); + hildon_button_set_value_alignment (HILDON_BUTTON (button), 0.0, 0.5); + + selector = create_encoding_selector (); + hildon_picker_button_set_selector (HILDON_PICKER_BUTTON (button), + HILDON_TOUCH_SELECTOR (selector)); + + encoding = gconf_get_string (gconf_client, "subtitle_encoding"); + if (encoding) { + /* skip current locale */ + gint index = 1; + + while (index < SUBTITLE_ENCODING_LAST) { + if (strcmp (encodings[index].charset, encoding) == 0) { + hildon_picker_button_set_active (HILDON_PICKER_BUTTON (button), + index); + break; + } + index++; + } + } else { + hildon_picker_button_set_active (HILDON_PICKER_BUTTON (button), + SUBTITLE_ENCODING_CURRENT_LOCALE); + } + + return button; +} + +static void +save_subtitles_encoding (GConfClient *gconf_client, + GtkWidget *widget) +{ + gint encoding = 0, index = 0; + + encoding = hildon_picker_button_get_active (HILDON_PICKER_BUTTON (widget)); + + while (index < SUBTITLE_ENCODING_LAST) { + if (encoding == index) { + gconf_set_string (gconf_client, "subtitle_encoding", + encodings[index].charset); + break; + } + index++; + } +} + +osso_return_t +execute (osso_context_t *osso, + gpointer data, + gboolean user_activated) +{ + GConfClient *gconf_client = NULL; + GtkWidget *dialog, *vbox, *autoload_subtitles_button; + GtkWidget *subtitles_font_button, *subtitles_encoding_button; + + gconf_client = gconf_client_get_default (); + if (gconf_client == NULL) { + return OSSO_ERROR; + } + + dialog = gtk_dialog_new (); + gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (data)); + gtk_window_set_title (GTK_WINDOW (dialog), _("Subtitles")); + gtk_dialog_add_button(GTK_DIALOG (dialog), _HL("wdgt_bd_save"), GTK_RESPONSE_ACCEPT); + + vbox = gtk_vbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), vbox); + + /* autoload subtitles button */ + autoload_subtitles_button = create_autoload_subtitles_button (gconf_client); + gtk_box_pack_start (GTK_BOX (vbox), autoload_subtitles_button, TRUE, TRUE, 0); + + /* font selector */ + subtitles_font_button = create_subtitles_font_button (gconf_client); + gtk_box_pack_start (GTK_BOX (vbox), subtitles_font_button, TRUE, TRUE, 0); + + /* font encoding */ + subtitles_encoding_button = create_subtitles_encoding_button (gconf_client); + gtk_box_pack_start (GTK_BOX (vbox), subtitles_encoding_button, TRUE, TRUE, 0); + + /* Run the dialog */ + gtk_widget_show_all (GTK_WIDGET (dialog)); + if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { + /* save autoload subtitles option */ + save_autoload_subtitles (gconf_client, autoload_subtitles_button); + + /* save subtitle font option */ + save_subtitles_font (gconf_client, subtitles_font_button); + + /* save subtitle encoding option */ + save_subtitles_encoding (gconf_client, subtitles_encoding_button); + } + + gtk_widget_destroy(GTK_WIDGET(dialog)); + return OSSO_OK; +} + +osso_return_t +save_state (osso_context_t *osso, + gpointer data) +{ + return OSSO_OK; +} + diff --git a/applet/cpmpsubtitles.desktop b/applet/cpmpsubtitles.desktop new file mode 100644 index 0000000..4c95f1e --- /dev/null +++ b/applet/cpmpsubtitles.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Encoding=UTF-8 +Version=1.0 +Name=Subtitles +Comment=Control panel to configure subtitles for mafw-gst-subtitles-renderer +Type=HildonControlPanelPlugin +Icon=general_video_file +X-control-panel-plugin=libcpmpsubtitles.so +Categories=extras diff --git a/configure.ac b/configure.ac index 9b146ec..d55a909 100644 --- a/configure.ac +++ b/configure.ac @@ -209,14 +209,30 @@ fi AM_CONDITIONAL(ENABLE_COVERAGE, [test "x$enable_coverage" != xno && test -n "$LCOV"]) +dnl Control Panel +PKG_CHECK_MODULES([MAFW_SUBTITLES_CPA], [libosso >= 2.0 + hildon-1 >= 2.1 + hildon-control-panel + gtk+-2.0 + gconf-2.0]) + +CPA_PLUGINDIR=`pkg-config hildon-control-panel --variable=pluginlibdir` +CPA_DESKTOPDIR=`pkg-config hildon-control-panel --variable=plugindesktopentrydir` + +AC_SUBST(MAFW_SUBTITLES_CPA_CFLAGS) +AC_SUBST(MAFW_SUBTITLES_CPA_LIBS) +AC_SUBST(CPA_DESKTOPDIR) +AC_SUBST(CPA_PLUGINDIR) + dnl Output files. AC_CONFIG_FILES([ Makefile mafw-gst-renderer-uninstalled.pc libmafw-gst-renderer/Makefile + applet/Makefile tests/Makefile - debian/mafw-gst-renderer.install + debian/mafw-gst-subtitles-renderer.install ]) AC_OUTPUT diff --git a/debian/control b/debian/control index f475874..be953a3 100644 --- a/debian/control +++ b/debian/control @@ -1,7 +1,8 @@ -Source: mafw-gst-renderer +Source: mafw-gst-subtitles-renderer Section: misc Priority: optional -Maintainer: Juha Kellokoski +Maintainer: Roman Moravcik > +XSBC-Original-Maintainer: Juha Kellokoski Build-Depends: debhelper (>= 4.0.0), libglib2.0-dev, libgstreamer0.10-dev (>= 0.10.20-0maemo3), libgstreamer-plugins-base0.10-dev (>= 0.10.20-0maemo5), @@ -12,17 +13,21 @@ Build-Depends: debhelper (>= 4.0.0), libglib2.0-dev, libgconf2-dev, libosso-gnomevfs2-dev Standards-Version: 3.7.2 -Package: mafw-gst-renderer +Package: mafw-gst-subtitles-renderer Section: libs Architecture: any -Depends: gconf2, ${shlibs:Depends}, ${misc:Depends} -Description: MAFW gst renderer plugin +Depends: gconf2, ${shlibs:Depends}, ${misc:Depends}, gstreamer0.10-plugins-base-subtitles (= 0.10.25-0maemo7+0m5) +Replaces: mafw-gst-renderer +Provides: mafw-gst-renderer +Description: MAFW gst renderer plugin with subtitles support Renderer plugin for MAFW-gst -Package: mafw-gst-renderer-dbg +Package: mafw-gst-subtitles-renderer-dbg Section: devel Architecture: any Priority: extra -Depends: mafw-gst-renderer (= ${binary:Version}) -Description: debug symbols for mafw-gst-renderer +Depends: mafw-gst-subtitles-renderer (= ${binary:Version}) +Replaces: mafw-gst-renderer-dbg +Provides: mafw-gst-renderer-dbg +Description: debug symbols for mafw-gst-subtitles-renderer MAFW-gst renderer debug symbols diff --git a/debian/mafw-gst-renderer.install.in b/debian/mafw-gst-renderer.install.in deleted file mode 100644 index f350be5..0000000 --- a/debian/mafw-gst-renderer.install.in +++ /dev/null @@ -1 +0,0 @@ -@plugindir@/*.so diff --git a/debian/mafw-gst-renderer.postinst b/debian/mafw-gst-renderer.postinst deleted file mode 100644 index 924970d..0000000 --- a/debian/mafw-gst-renderer.postinst +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -#DEBHELPER# - -test -x /usr/bin/mafw.sh && /usr/bin/mafw.sh start mafw-gst-renderer -7 \ -|| true; diff --git a/debian/mafw-gst-renderer.prerm b/debian/mafw-gst-renderer.prerm deleted file mode 100644 index 084ef87..0000000 --- a/debian/mafw-gst-renderer.prerm +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -#DEBHELPER# - -test -x /usr/bin/mafw.sh && /usr/bin/mafw.sh stop mafw-gst-renderer \ -|| true; diff --git a/debian/mafw-gst-subtitles-renderer.install.in b/debian/mafw-gst-subtitles-renderer.install.in new file mode 100644 index 0000000..426082a --- /dev/null +++ b/debian/mafw-gst-subtitles-renderer.install.in @@ -0,0 +1,3 @@ +@plugindir@/*.so +/usr/lib/hildon-control-panel/libcpmpsubtitles.so +/usr/share/applications/hildon-control-panel/cpmpsubtitles.desktop \ No newline at end of file diff --git a/debian/mafw-gst-subtitles-renderer.postinst b/debian/mafw-gst-subtitles-renderer.postinst new file mode 100644 index 0000000..924970d --- /dev/null +++ b/debian/mafw-gst-subtitles-renderer.postinst @@ -0,0 +1,6 @@ +#!/bin/sh + +#DEBHELPER# + +test -x /usr/bin/mafw.sh && /usr/bin/mafw.sh start mafw-gst-renderer -7 \ +|| true; diff --git a/debian/mafw-gst-subtitles-renderer.prerm b/debian/mafw-gst-subtitles-renderer.prerm new file mode 100644 index 0000000..084ef87 --- /dev/null +++ b/debian/mafw-gst-subtitles-renderer.prerm @@ -0,0 +1,6 @@ +#!/bin/sh + +#DEBHELPER# + +test -x /usr/bin/mafw.sh && /usr/bin/mafw.sh stop mafw-gst-renderer \ +|| true; diff --git a/libmafw-gst-renderer/mafw-gst-renderer-utils.c b/libmafw-gst-renderer/mafw-gst-renderer-utils.c index 0169862..42dae31 100644 --- a/libmafw-gst-renderer/mafw-gst-renderer-utils.c +++ b/libmafw-gst-renderer/mafw-gst-renderer-utils.c @@ -28,6 +28,9 @@ #include +#include +#include + #include "mafw-gst-renderer-utils.h" #undef G_LOG_DOMAIN @@ -102,4 +105,144 @@ gboolean uri_is_stream(const gchar *uri) } } +/* + * Imported from totem-uri.c + * Copyright (C) 2004 Bastien Nocera + */ + +/* List from xine-lib's demux_sputext.c */ +static const char subtitle_ext[][4] = { + "sub", + "srt", + "smi", + "ssa", + "ass", + "asc" +}; + +static inline gboolean +uri_exists (const char *uri) +{ + GFile *file = g_file_new_for_uri (uri); + if (file != NULL) { + if (g_file_query_exists (file, NULL)) { + g_object_unref (file); + return TRUE; + } + g_object_unref (file); + } + return FALSE; +} + +static char * +uri_get_subtitle_for_uri (const char *uri) +{ + char *subtitle; + guint len, i; + gint suffix; + + /* Find the filename suffix delimiter */ + len = strlen (uri); + for (suffix = len - 1; suffix > 0; suffix--) { + if (uri[suffix] == G_DIR_SEPARATOR || + (uri[suffix] == '/')) { + /* This filename has no extension; we'll need to + * add one */ + suffix = len; + break; + } + if (uri[suffix] == '.') { + /* Found our extension marker */ + break; + } + } + if (suffix < 0) + return NULL; + + /* Generate a subtitle string with room at the end to store the + * 3 character extensions for which we want to search */ + subtitle = g_malloc0 (suffix + 4 + 1); + g_return_val_if_fail (subtitle != NULL, NULL); + g_strlcpy (subtitle, uri, suffix + 4 + 1); + g_strlcpy (subtitle + suffix, ".???", 5); + + /* Search for any files with one of our known subtitle extensions */ + for (i = 0; i < G_N_ELEMENTS (subtitle_ext) ; i++) { + char *subtitle_ext_upper; + memcpy (subtitle + suffix + 1, subtitle_ext[i], 3); + + if (uri_exists (subtitle)) + return subtitle; + + /* Check with upper-cased extension */ + subtitle_ext_upper = g_ascii_strup (subtitle_ext[i], -1); + memcpy (subtitle + suffix + 1, subtitle_ext_upper, 3); + g_free (subtitle_ext_upper); + + if (uri_exists (subtitle)) + return subtitle; + } + g_free (subtitle); + return NULL; +} + +static char * +uri_get_subtitle_in_subdir (GFile *file, const char *subdir) +{ + char *filename, *subtitle, *full_path_str; + GFile *parent, *full_path, *directory; + + /* Get the sibling directory @subdir of the file @file */ + parent = g_file_get_parent (file); + directory = g_file_get_child (parent, subdir); + g_object_unref (parent); + + /* Get the file of the same name as @file in the @subdir directory */ + filename = g_file_get_basename (file); + full_path = g_file_get_child (directory, filename); + g_object_unref (directory); + g_free (filename); + + /* Get the subtitles from that URI */ + full_path_str = g_file_get_uri (full_path); + g_object_unref (full_path); + subtitle = uri_get_subtitle_for_uri (full_path_str); + g_free (full_path_str); + + return subtitle; +} + +char * +uri_get_subtitle_uri (const char *uri) +{ + GFile *file; + char *subtitle; + + if (g_str_has_prefix (uri, "http") != FALSE) + return NULL; + + /* Has the user specified a subtitle file manually? */ + if (strstr (uri, "#subtitle:") != NULL) + return NULL; + + /* Does the file exist? */ + file = g_file_new_for_uri (uri); + if (g_file_query_exists (file, NULL) != TRUE) { + g_object_unref (file); + return NULL; + } + + /* Try in the current directory */ + subtitle = uri_get_subtitle_for_uri (uri); + if (subtitle != NULL) { + g_object_unref (file); + return subtitle; + } + + subtitle = uri_get_subtitle_in_subdir (file, "subtitles"); + g_object_unref (file); + + return subtitle; +} + /* vi: set noexpandtab ts=8 sw=8 cino=t0,(0: */ diff --git a/libmafw-gst-renderer/mafw-gst-renderer-utils.h b/libmafw-gst-renderer/mafw-gst-renderer-utils.h index 57bbe81..fd3f44c 100644 --- a/libmafw-gst-renderer/mafw-gst-renderer-utils.h +++ b/libmafw-gst-renderer/mafw-gst-renderer-utils.h @@ -29,6 +29,8 @@ gboolean convert_utf8(const gchar *src, gchar **dst); gboolean uri_is_playlist(const gchar *uri); gboolean uri_is_stream(const gchar *uri); +char *uri_get_subtitle_uri(const char *uri); + G_END_DECLS #endif /* vi: set noexpandtab ts=8 sw=8 cino=t0,(0: */ diff --git a/libmafw-gst-renderer/mafw-gst-renderer-worker.c b/libmafw-gst-renderer/mafw-gst-renderer-worker.c index 0cd1ec4..8c81870 100644 --- a/libmafw-gst-renderer/mafw-gst-renderer-worker.c +++ b/libmafw-gst-renderer/mafw-gst-renderer-worker.c @@ -1666,11 +1666,27 @@ static void _start_play(MafwGstRendererWorker *worker) { MafwGstRenderer *renderer = (MafwGstRenderer*) worker->owner; GstStateChangeReturn state_change_info; + char *autoload_sub = NULL; g_assert(worker->pipeline); g_object_set(G_OBJECT(worker->pipeline), "uri", worker->media.location, NULL); + if (worker->subtitles.enabled) { + autoload_sub = uri_get_subtitle_uri(worker->media.location); + if (autoload_sub) { + g_debug("SUBURI: %s", autoload_sub); + g_object_set(G_OBJECT(worker->pipeline), + "suburi", autoload_sub, + "subtitle-font-desc", worker->subtitles.font, + "subtitle-encoding", worker->subtitles.encoding, + NULL); + + gst_element_set_state(worker->pipeline, GST_STATE_READY); + g_free(autoload_sub); + } + } + g_debug("URI: %s", worker->media.location); g_debug("setting pipeline to PAUSED"); @@ -1768,7 +1784,7 @@ static void _construct_pipeline(MafwGstRendererWorker *worker) G_CALLBACK(_stream_info_cb), worker); #ifndef MAFW_GST_RENDERER_DISABLE_PULSE_VOLUME - g_object_set(worker->pipeline, "flags", 99, NULL); + g_object_set(worker->pipeline, "flags", 103, NULL); /* Set audio and video sinks ourselves. We create and configure them only once. */ @@ -1810,6 +1826,21 @@ static void _construct_pipeline(MafwGstRendererWorker *worker) TRUE, NULL); } g_object_set(worker->pipeline, "video-sink", worker->vsink, NULL); + + if (!worker->tsink) { + worker->tsink = gst_element_factory_make("textoverlay", NULL); + if (!worker->tsink) { + g_critical("Failed to create pipeline text sink"); + g_signal_emit_by_name(MAFW_EXTENSION (worker->owner), + "error", + MAFW_RENDERER_ERROR, + MAFW_RENDERER_ERROR_UNABLE_TO_PERFORM, + "Could not create text sink"); + g_assert_not_reached(); + } + gst_object_ref(worker->tsink); + } + g_object_set(worker->pipeline, "text-sink", worker->tsink, NULL); } /* @@ -2335,8 +2366,12 @@ MafwGstRendererWorker *mafw_gst_renderer_worker_new(gpointer owner) worker->colorkey = -1; worker->vsink = NULL; worker->asink = NULL; + worker->tsink = NULL; worker->tag_list = NULL; worker->current_metadata = NULL; + worker->subtitles.enabled = FALSE; + worker->subtitles.font = NULL; + worker->subtitles.encoding = NULL; #ifdef HAVE_GDKPIXBUF worker->current_frame_on_pause = FALSE; diff --git a/libmafw-gst-renderer/mafw-gst-renderer-worker.h b/libmafw-gst-renderer/mafw-gst-renderer-worker.h index d59c09a..01c8156 100644 --- a/libmafw-gst-renderer/mafw-gst-renderer-worker.h +++ b/libmafw-gst-renderer/mafw-gst-renderer-worker.h @@ -64,6 +64,10 @@ typedef enum { * seekable: Tells whether the media can be seeked * par_n: Video pixel aspect ratio numerator * par_d: Video pixel aspect ratio denominator + * subtitles: Configuration of subtitles. + * enabled: Are subtitles enabled + * font: Subtitles font description + * encoding: Subtitles encoding * owner: Owner of the worker; usually a MafwGstRenderer (FIXME USUALLY?) * pipeline: Playback pipeline * bus: Message bus @@ -81,6 +85,7 @@ typedef enum { * seek_position: Indicates the pos where to seek, in seconds * vsink: Video sink element of the pipeline * asink: Audio sink element of the pipeline + * tsink: Text sink element of the pipeline * xid: XID for video playback * current_frame_on_pause: whether to emit current frame when pausing */ @@ -96,6 +101,11 @@ struct _MafwGstRendererWorker { gint par_n; gint par_d; } media; + struct { + gboolean enabled; + gchar *font; + gchar *encoding; + } subtitles; PlaybackMode mode; struct { GSList *items; @@ -150,6 +160,7 @@ struct _MafwGstRendererWorker { gboolean in_ready; GstElement *vsink; GstElement *asink; + GstElement *tsink; XID xid; gboolean autopaint; gint colorkey; diff --git a/libmafw-gst-renderer/mafw-gst-renderer.c b/libmafw-gst-renderer/mafw-gst-renderer.c index 6412b13..1e593de 100644 --- a/libmafw-gst-renderer/mafw-gst-renderer.c +++ b/libmafw-gst-renderer/mafw-gst-renderer.c @@ -56,6 +56,7 @@ #define GCONF_OSSO_AF "/system/osso/af" #define GCONF_BATTERY_COVER_OPEN "/system/osso/af/mmc-cover-open" +#define GCONF_MAFW_GST_SUBTITLE_RENDERER "/system/mafw/mafw-gst-renderer" #define HAL_VIDEOOUT_UDI "/org/freedesktop/Hal/devices" \ "/platform_soc_audio_logicaldev_input" @@ -95,6 +96,16 @@ static void _battery_cover_open_cb(GConfClient *client, GConfEntry *entry, MafwGstRenderer *renderer); +static void _autoload_subtitles_changed_cb(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + MafwGstRenderer *renderer); + +static void _subtitle_font_changed_cb(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + MafwGstRenderer *renderer); + /*---------------------------------------------------------------------------- Gnome VFS notifications ----------------------------------------------------------------------------*/ @@ -347,6 +358,57 @@ static void mafw_gst_renderer_init(MafwGstRenderer *self) g_error_free(error); } + gconf_client_add_dir(renderer->gconf_client, + GCONF_MAFW_GST_SUBTITLE_RENDERER, + GCONF_CLIENT_PRELOAD_ONELEVEL, + &error); + if (error) { + g_warning("%s", error->message); + g_error_free(error); + error = NULL; + } + + gconf_client_notify_add(renderer->gconf_client, + GCONF_MAFW_GST_SUBTITLE_RENDERER "/autoload_subtitles", + (GConfClientNotifyFunc) _autoload_subtitles_changed_cb, + renderer, + NULL, &error); + if (error) { + g_warning("%s", error->message); + g_error_free(error); + } + + gconf_client_notify_add(renderer->gconf_client, + GCONF_MAFW_GST_SUBTITLE_RENDERER "/subtitle_encoding", + (GConfClientNotifyFunc) _subtitle_font_changed_cb, + renderer, + NULL, &error); + if (error) { + g_warning("%s", error->message); + g_error_free(error); + } + + gconf_client_notify_add(renderer->gconf_client, + GCONF_MAFW_GST_SUBTITLE_RENDERER "/subtitle_font", + (GConfClientNotifyFunc) _subtitle_font_changed_cb, + renderer, + NULL, &error); + if (error) { + g_warning("%s", error->message); + g_error_free(error); + } + + if (self->worker->pipeline) { + gconf_client_notify(renderer->gconf_client, + GCONF_MAFW_GST_SUBTITLE_RENDERER "/autoload_subtitles"); + + gconf_client_notify(renderer->gconf_client, + GCONF_MAFW_GST_SUBTITLE_RENDERER "/subtitle_encoding"); + + gconf_client_notify(renderer->gconf_client, + GCONF_MAFW_GST_SUBTITLE_RENDERER "/subtitle_font"); + } + if (gnome_vfs_init()) { GnomeVFSVolumeMonitor *monitor = gnome_vfs_get_volume_monitor(); g_signal_connect(monitor, "volume-pre-unmount", @@ -830,6 +892,61 @@ static void _battery_cover_open_cb(GConfClient *client, } } +static void _autoload_subtitles_changed_cb(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + MafwGstRenderer *renderer) +{ + GConfValue *value = NULL; + gboolean enabled = FALSE; + + value = gconf_entry_get_value(entry); + if (value == NULL) + return; + + enabled = gconf_value_get_bool(value); + + if (enabled) + renderer->worker->subtitles.enabled = TRUE; + else + renderer->worker->subtitles.enabled = FALSE; +} + +static void _subtitle_font_changed_cb(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + MafwGstRenderer *renderer) +{ + const gchar *key = NULL; + GConfValue *value = NULL; + const gchar *str_value = NULL; + + key = gconf_entry_get_key(entry); + + /* Only key without absolute path is required */ + key += strlen(GCONF_MAFW_GST_SUBTITLE_RENDERER) + 1; + + value = gconf_entry_get_value(entry); + if (value == NULL) + return; + + str_value = gconf_value_get_string(value); + + if (strcmp(key, "subtitle_font") == 0) { + if (renderer->worker->subtitles.font) + g_free(renderer->worker->subtitles.font); + + renderer->worker->subtitles.font = g_strdup(str_value); + } else if (strcmp(key, "subtitle_encoding") == 0) { + if (renderer->worker->subtitles.encoding) + g_free(renderer->worker->subtitles.encoding); + + renderer->worker->subtitles.encoding = g_strdup(str_value); + } else { + g_warning("Wrong %s key, %s", GCONF_MAFW_GST_SUBTITLE_RENDERER, key); + } +} + /*---------------------------------------------------------------------------- Gnome VFS notifications ----------------------------------------------------------------------------*/ -- 1.7.9.5