Files
evolution/modules/audio-inline/e-mail-formatter-audio-inline.c
Dan Vrátil 9311914746 Mail formatter rewrite - convert some plugins to modules
audio-inline, itip-formatter, prefer-plain, tnef-attachments
and vcard-inline plugins were converted to modules so that they
can fit into concept of the new formatter.

Every module still installs .eplug file, because there is no
suitable API at the moment to register plugins to the plugins dialog
and to extend the Preferences dialog.
2012-06-06 15:29:38 +02:00

384 lines
10 KiB
C

/*
* e-mail-formatter-audio-inline.c
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) version 3.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*/
#include "e-mail-formatter-audio-inline.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <glib/gi18n-lib.h>
#include <libebackend/libebackend.h>
#include <em-format/e-mail-formatter-extension.h>
#include <em-format/e-mail-formatter.h>
#include "e-util/e-mktemp.h"
#include <camel/camel.h>
#include <gst/gst.h>
#include "e-mail-part-audio-inline.h"
#define d(x)
typedef struct _EMailFormatterAudioInline {
EExtension parent;
} EMailFormatterAudioInline;
typedef struct _EMailFormatterAudioInlineClass {
EExtensionClass parent_class;
} EMailFormatterAudioInlineClass;
GType e_mail_formatter_audio_inline_get_type (void);
static void e_mail_formatter_formatter_extension_interface_init (EMailFormatterExtensionInterface *iface);
static void e_mail_formatter_mail_extension_interface_init (EMailExtensionInterface *iface);
G_DEFINE_DYNAMIC_TYPE_EXTENDED (
EMailFormatterAudioInline,
e_mail_formatter_audio_inline,
E_TYPE_EXTENSION,
0,
G_IMPLEMENT_INTERFACE_DYNAMIC (
E_TYPE_MAIL_EXTENSION,
e_mail_formatter_mail_extension_interface_init)
G_IMPLEMENT_INTERFACE_DYNAMIC (
E_TYPE_MAIL_FORMATTER_EXTENSION,
e_mail_formatter_formatter_extension_interface_init));
static const gchar* formatter_mime_types[] = { "application/vnd.evolution.widget.audio-inline",
"audio/ac3", "audio/x-ac3",
"audio/basic", "audio/mpeg",
"audio/x-mpeg", "audio/mpeg3",
"audio/x-mpeg3", "audio/mp3",
"audio/x-mp3", "audio/mp4",
"audio/flac", "audio/x-flac",
"audio/mod", "audio/x-mod",
"audio/x-wav", "audio/microsoft-wav",
"audio/x-wma", "audio/x-ms-wma",
"application/ogg", "application/x-ogg",
NULL };
static void
pause_clicked (GtkWidget *button,
EMailPartAudioInline *part)
{
if (part->playbin) {
/* pause playing */
gst_element_set_state (part->playbin, GST_STATE_PAUSED);
}
}
static void
stop_clicked (GtkWidget *button,
EMailPartAudioInline *part)
{
if (part->playbin) {
/* ready to play */
gst_element_set_state (part->playbin, GST_STATE_READY);
part->target_state = GST_STATE_READY;
}
}
static void
set_audiosink (GstElement *playbin)
{
GstElement *audiosink;
/* now it's time to get the audio sink */
audiosink = gst_element_factory_make ("gconfaudiosink", "play_audio");
if (audiosink == NULL) {
audiosink = gst_element_factory_make ("autoaudiosink", "play_audio");
}
if (audiosink) {
g_object_set (playbin, "audio-sink", audiosink, NULL);
}
}
static gboolean
gst_callback (GstBus *bus,
GstMessage *message,
gpointer data)
{
EMailPartAudioInline *part = data;
GstMessageType msg_type;
g_return_val_if_fail (part != NULL, TRUE);
g_return_val_if_fail (part->playbin != NULL, TRUE);
msg_type = GST_MESSAGE_TYPE (message);
switch (msg_type) {
case GST_MESSAGE_ERROR:
gst_element_set_state (part->playbin, GST_STATE_NULL);
break;
case GST_MESSAGE_EOS:
gst_element_set_state (part->playbin, GST_STATE_READY);
break;
case GST_MESSAGE_STATE_CHANGED:
{
GstState old_state, new_state;
if (GST_MESSAGE_SRC (message) != GST_OBJECT (part->playbin))
break;
gst_message_parse_state_changed (message, &old_state, &new_state, NULL);
if (old_state == new_state)
break;
if (part->play_button)
gtk_widget_set_sensitive (
part->play_button,
new_state <= GST_STATE_PAUSED);
if (part->pause_button)
gtk_widget_set_sensitive (
part->pause_button,
new_state > GST_STATE_PAUSED);
if (part->stop_button)
gtk_widget_set_sensitive (
part->stop_button,
new_state >= GST_STATE_PAUSED);
}
break;
default:
break;
}
return TRUE;
}
static void
play_clicked (GtkWidget *button,
EMailPartAudioInline *part)
{
GstState cur_state;
d(printf ("audio inline formatter: play\n"));
if (!part->filename) {
CamelStream *stream;
CamelDataWrapper *data;
GError *error = NULL;
gint argc = 1;
const gchar *argv [] = { "org_gnome_audio_inline", NULL };
/* FIXME this is ugly, we should stream this directly to gstreamer */
part->filename = e_mktemp ("org-gnome-audio-inline-file-XXXXXX");
d(printf ("audio inline formatter: write to temp file %s\n", po->filename));
stream = camel_stream_fs_new_with_name (
part->filename, O_RDWR | O_CREAT | O_TRUNC, 0600, NULL);
data = camel_medium_get_content (CAMEL_MEDIUM (part->parent.part));
camel_data_wrapper_decode_to_stream_sync (data, stream, NULL, NULL);
camel_stream_flush (stream, NULL, NULL);
g_object_unref (stream);
d(printf ("audio inline formatter: init gst playbin\n"));
if (gst_init_check (&argc, (gchar ***) &argv, &error)) {
gchar *uri;
GstBus *bus;
/* create a disk reader */
part->playbin = gst_element_factory_make ("playbin", "playbin");
if (part->playbin == NULL) {
g_printerr ("Failed to create gst_element_factory playbin; check your installation\n");
return;
}
uri = g_filename_to_uri (part->filename, NULL, NULL);
g_object_set (part->playbin, "uri", uri, NULL);
g_free (uri);
set_audiosink (part->playbin);
bus = gst_element_get_bus (part->playbin);
part->bus_id = gst_bus_add_watch (bus, gst_callback, part);
gst_object_unref (bus);
} else {
g_printerr ("GStreamer failed to initialize: %s",error ? error->message : "");
g_error_free (error);
}
}
gst_element_get_state (part->playbin, &cur_state, NULL, 0);
if (cur_state >= GST_STATE_PAUSED) {
gst_element_set_state (part->playbin, GST_STATE_READY);
}
if (part->playbin) {
/* start playing */
gst_element_set_state (part->playbin, GST_STATE_PLAYING);
}
}
static GtkWidget *
add_button (GtkWidget *box,
const gchar *stock_icon,
GCallback cb,
gpointer data,
gboolean sensitive)
{
GtkWidget *button;
button = gtk_button_new_from_stock (stock_icon);
gtk_widget_set_sensitive (button, sensitive);
g_signal_connect (button, "clicked", cb, data);
gtk_widget_show (button);
gtk_box_pack_end (GTK_BOX (box), button, TRUE, TRUE, 0);
return button;
}
static gboolean
emfe_audio_inline_format (EMailFormatterExtension *extension,
EMailFormatter *formatter,
EMailFormatterContext *context,
EMailPart *part,
CamelStream *stream,
GCancellable *cancellable)
{
gchar *str;
str = g_strdup_printf (
"<object type=\"application/vnd.evolution.widget.audio-inline\" "
"width=\"100%%\" height=\"auto\" data=\"%s\" id=\"%s\"></object>",
part->id, part->id);
camel_stream_write_string (stream, str, cancellable, NULL);
g_free (str);
return TRUE;
}
static GtkWidget *
emfe_audio_inline_get_widget (EMailFormatterExtension *extension,
EMailPartList *context,
EMailPart *part,
GHashTable *params)
{
GtkWidget *box;
EMailPartAudioInline *ai_part;
g_return_val_if_fail (E_MAIL_PART_IS (part, EMailPartAudioInline), NULL);
ai_part = (EMailPartAudioInline *) part;
/* it is OK to call UI functions here, since we are called from UI thread */
box = gtk_hbutton_box_new ();
ai_part->play_button = g_object_ref (
add_button (box, GTK_STOCK_MEDIA_PLAY,
G_CALLBACK (play_clicked), part, TRUE));
ai_part->pause_button = g_object_ref (
add_button (box, GTK_STOCK_MEDIA_PAUSE,
G_CALLBACK (pause_clicked), part, FALSE));
ai_part->stop_button = g_object_ref (
add_button (box, GTK_STOCK_MEDIA_STOP,
G_CALLBACK (stop_clicked), part, FALSE));
gtk_widget_show (box);
return box;
}
static const gchar *
emfe_audio_inline_get_display_name (EMailFormatterExtension *extension)
{
return _("Audio Player");
}
static const gchar *
emfe_audio_inline_get_description (EMailFormatterExtension *extension)
{
return _("Play the attachment in embedded audio player");
}
static const gchar **
emfe_audio_inline_mime_types (EMailExtension *extension)
{
return formatter_mime_types;
}
static void
e_mail_formatter_audio_inline_constructed (GObject *object)
{
EExtensible *extensible;
EMailExtensionRegistry *reg;
extensible = e_extension_get_extensible (E_EXTENSION (object));
reg = E_MAIL_EXTENSION_REGISTRY (extensible);
e_mail_extension_registry_add_extension (reg, E_MAIL_EXTENSION (object));
}
static void
e_mail_formatter_audio_inline_class_init (EMailFormatterAudioInlineClass *klass)
{
GObjectClass *object_class;
EExtensionClass *extension_class;
e_mail_formatter_audio_inline_parent_class = g_type_class_peek_parent (klass);
object_class = G_OBJECT_CLASS (klass);
object_class->constructed = e_mail_formatter_audio_inline_constructed;
extension_class = E_EXTENSION_CLASS (klass);
extension_class->extensible_type = E_TYPE_MAIL_FORMATTER_EXTENSION_REGISTRY;
}
static void
e_mail_formatter_formatter_extension_interface_init (EMailFormatterExtensionInterface *iface)
{
iface->format = emfe_audio_inline_format;
iface->get_widget = emfe_audio_inline_get_widget;
iface->get_display_name = emfe_audio_inline_get_display_name;
iface->get_description = emfe_audio_inline_get_description;
}
static void
e_mail_formatter_mail_extension_interface_init (EMailExtensionInterface *iface)
{
iface->mime_types = emfe_audio_inline_mime_types;
}
static void
e_mail_formatter_audio_inline_init (EMailFormatterAudioInline *formatter)
{
}
void
e_mail_formatter_audio_inline_type_register (GTypeModule *type_module)
{
e_mail_formatter_audio_inline_register_type (type_module);
}
static void
e_mail_formatter_audio_inline_class_finalize (EMailFormatterAudioInlineClass *klass)
{
}