summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@gnome.org>2007-12-13 12:33:48 +0100
committerBenjamin Otte <otte@gnome.org>2007-12-13 12:33:48 +0100
commite1d4ccd0c7cab8503b1817654d42072f788d61b1 (patch)
treea2d5e3adbd5cff4ebbf8215b3386c341a2a9f09a
parente7012491570fdccd3b43245ec120c2c4f245debd (diff)
port the first parts of swfdec-gtk to the DirectFB lib
-rw-r--r--configure.ac5
-rw-r--r--player/Makefile.am4
-rw-r--r--player/main.c23
-rw-r--r--swfdec-directfb/.gitignore9
-rw-r--r--swfdec-directfb/Makefile.am26
-rw-r--r--swfdec-directfb/swfdec-directfb.h26
-rw-r--r--swfdec-directfb/swfdec_directfb_main.c46
-rw-r--r--swfdec-directfb/swfdec_directfb_main.h32
-rw-r--r--swfdec-directfb/swfdec_directfb_player.c301
-rw-r--r--swfdec-directfb/swfdec_directfb_player.h71
-rw-r--r--swfdec-directfb/swfdec_source.c183
-rw-r--r--swfdec-directfb/swfdec_source.h34
12 files changed, 740 insertions, 20 deletions
diff --git a/configure.ac b/configure.ac
index f8c3a10..238802d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -73,6 +73,11 @@ fi
AC_SUBST(GLOBAL_CFLAGS)
+SWFDEC_DFB_CFLAGS="-I\$(top_srcdir) $SWFDEC_CFLAGS $DIRECTFB_CFLAGS $CAIRO_CFLAGS"
+SWFDEC_DFB_LIBS="\$(top_builddir)/swfdec-directfb/libswfdec-directfb-$SWFDEC_MAJORMINOR.la $SWFDEC_LIBS $DIRECTFB_LIBS $CAIRO_LIBS"
+AC_SUBST(SWFDEC_DFB_CFLAGS)
+AC_SUBST(SWFDEC_DFB_LIBS)
+
AC_CONFIG_FILES(
Makefile
data/swfdec-directfb.pc
diff --git a/player/Makefile.am b/player/Makefile.am
index d7729ee..ccd4e4d 100644
--- a/player/Makefile.am
+++ b/player/Makefile.am
@@ -3,6 +3,6 @@ noinst_PROGRAMS = swfdec-directfb-player
swfdec_directfb_player_SOURCES = \
main.c
-swfdec_directfb_player_CFLAGS = $(GLOBAL_CFLAGS) $(DIRECTFB_CFLAGS) $(SWFDEC_CFLAGS) $(CAIRO_CFLAGS)
-swfdec_directfb_player_LDFLAGS = $(DIRECTFB_LIBS) $(SWFDEC_LIBS) $(CAIRO_LIBS)
+swfdec_directfb_player_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_DFB_CFLAGS)
+swfdec_directfb_player_LDFLAGS = $(SWFDEC_DFB_LIBS)
diff --git a/player/main.c b/player/main.c
index 25044bb..308e697 100644
--- a/player/main.c
+++ b/player/main.c
@@ -21,6 +21,7 @@
#include "config.h"
#endif
#include <libswfdec/swfdec.h>
+#include <swfdec-directfb/swfdec-directfb.h>
#include <directfb.h>
#include <cairo-directfb.h>
#include <stdio.h>
@@ -93,18 +94,7 @@ main (int argc, char *argv[])
return 1;
}
- player = swfdec_player_new_from_file (argv[1]);
- /* advance till initialized or fail */
- /* NB: This method only knows for file loading */
- while (!swfdec_player_is_initialized (player)) {
- long next_event = swfdec_player_get_next_event (player);
- if (next_event < 0) {
- g_object_unref (player);
- g_printerr ("\"%s\" is not a file Swfdec can play.\n", argv[1]);
- return 1;
- }
- swfdec_player_advance (player, next_event);
- }
+ player = swfdec_dfb_player_new_from_file (argv[1]);
ERROR_CHECK (DirectFBCreate (&data.dfb));
if (size) {
@@ -119,8 +109,7 @@ main (int argc, char *argv[])
return 1;
}
} else {
- dsc.flags = DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT;
- swfdec_player_get_default_size (player, &w, &h);
+ dsc.flags = DSDESC_CAPS;
}
dsc.caps = DSCAPS_DOUBLE | DSCAPS_PRIMARY;
@@ -134,10 +123,8 @@ main (int argc, char *argv[])
render (player, &data, 0, 0, dsc.width, dsc.height);
g_signal_connect (player, "invalidate", G_CALLBACK (invalidate), &data);
- while (TRUE) {
- int next_event = swfdec_player_get_next_event (player);
- swfdec_player_advance (player, next_event);
- };
+ swfdec_dfb_player_set_playing (SWFDEC_DFB_PLAYER (player), TRUE);
+ swfdec_dfb_main ();
return 0;
}
diff --git a/swfdec-directfb/.gitignore b/swfdec-directfb/.gitignore
new file mode 100644
index 0000000..4c5e0d6
--- /dev/null
+++ b/swfdec-directfb/.gitignore
@@ -0,0 +1,9 @@
+.deps
+.libs
+
+Makefile
+Makefile.in
+*.o
+*.la
+*.lo
+*.loT
diff --git a/swfdec-directfb/Makefile.am b/swfdec-directfb/Makefile.am
index e69de29..c23a890 100644
--- a/swfdec-directfb/Makefile.am
+++ b/swfdec-directfb/Makefile.am
@@ -0,0 +1,26 @@
+lib_LTLIBRARIES = libswfdec-directfb-@SWFDEC_MAJORMINOR@.la
+
+libswfdec_directfb_@SWFDEC_MAJORMINOR@_la_SOURCES = \
+ swfdec_source.c \
+ swfdec_directfb_main.c \
+ swfdec_directfb_player.c
+
+noinst_HEADERS = \
+ swfdec_source.h
+
+libswfdec_directfb_@SWFDEC_MAJORMINOR@_la_CFLAGS = \
+ -I$(top_srcdir) $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(DIRECTFB_CFLAGS) \
+ $(CAIRO_CFLAGS) $(AUDIO_CFLAGS) \
+ -DG_LOG_DOMAIN=\"Swfdec-DirectFB\"
+
+libswfdec_directfb_@SWFDEC_MAJORMINOR@_la_LDFLAGS = \
+ -version-info $(SWFDEC_LIBVERSION) \
+ -export-symbols-regex '^(swfdec_.*)' \
+ $(GTK_LIBS) $(SWFDEC_LIBS) $(AUDIO_LIBS) $(CAIRO_LIBS)
+
+libswfdec_@SWFDEC_MAJORMINOR@includedir = $(includedir)/swfdec-@SWFDEC_MAJORMINOR@/libswfdec-directfb
+libswfdec_@SWFDEC_MAJORMINOR@include_HEADERS = \
+ swfdec-directfb.h \
+ swfdec_directfb_main.h \
+ swfdec_directfb_player.h
+
diff --git a/swfdec-directfb/swfdec-directfb.h b/swfdec-directfb/swfdec-directfb.h
new file mode 100644
index 0000000..1091919
--- /dev/null
+++ b/swfdec-directfb/swfdec-directfb.h
@@ -0,0 +1,26 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
+ *
+ * This library 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.1 of the License, or (at your option) any later version.
+ *
+ * This library 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef __SWFDEC_DIRECTFB_H__
+#define __SWFDEC_DIRECTFB_H__
+
+#include <swfdec-directfb/swfdec_directfb_main.h>
+#include <swfdec-directfb/swfdec_directfb_player.h>
+
+#endif
diff --git a/swfdec-directfb/swfdec_directfb_main.c b/swfdec-directfb/swfdec_directfb_main.c
new file mode 100644
index 0000000..5d17125
--- /dev/null
+++ b/swfdec-directfb/swfdec_directfb_main.c
@@ -0,0 +1,46 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
+ *
+ * This library 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.1 of the License, or (at your option) any later version.
+ *
+ * This library 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "swfdec-directfb/swfdec_directfb_main.h"
+
+static GMainLoop *loop = NULL;
+
+void
+swfdec_dfb_main (void)
+{
+ g_return_if_fail (loop == NULL);
+
+ loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (loop);
+ g_main_loop_unref (loop);
+ loop = NULL;
+}
+
+void
+swfdec_dfb_main_quit (void)
+{
+ g_return_if_fail (loop != NULL);
+
+ g_main_loop_quit (loop);
+}
+
diff --git a/swfdec-directfb/swfdec_directfb_main.h b/swfdec-directfb/swfdec_directfb_main.h
new file mode 100644
index 0000000..800844d
--- /dev/null
+++ b/swfdec-directfb/swfdec_directfb_main.h
@@ -0,0 +1,32 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
+ *
+ * This library 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.1 of the License, or (at your option) any later version.
+ *
+ * This library 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef _SWFDEC_DFB_MAIN_H_
+#define _SWFDEC_DFB_MAIN_H_
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+void swfdec_dfb_main (void);
+void swfdec_dfb_main_quit (void);
+
+
+G_END_DECLS
+#endif
diff --git a/swfdec-directfb/swfdec_directfb_player.c b/swfdec-directfb/swfdec_directfb_player.c
new file mode 100644
index 0000000..15a3542
--- /dev/null
+++ b/swfdec-directfb/swfdec_directfb_player.c
@@ -0,0 +1,301 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
+ *
+ * This library 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.1 of the License, or (at your option) any later version.
+ *
+ * This library 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "swfdec-directfb/swfdec_directfb_player.h"
+#include "swfdec-directfb/swfdec_source.h"
+
+enum {
+ PROP_0,
+ PROP_PLAYING,
+ PROP_AUDIO,
+ PROP_SPEED
+};
+
+/*** dfb-doc ***/
+
+/**
+ * SECTION:SwfdecDfbPlayer
+ * @title: SwfdecDfbPlayer
+ * @short_description: an improved #SwfdecPlayer
+ *
+ * The #SwfdecDfbPlayer adds common functionality to the rather barebones
+ * #SwfdecPlayer class, such as automatic playback and audio handling. Note
+ * that by default, the player will be paused, so you need to call
+ * swfdec_dfb_player_set_playing () on the new player.
+ *
+ * @see_also: SwfdecPlayer
+ */
+
+/**
+ * SwfdecDfbPlayer:
+ *
+ * The structure for the Swfdec Dfb player contains no public fields.
+ */
+
+/*** SWFDEC_DFB_PLAYER ***/
+
+G_DEFINE_TYPE (SwfdecDfbPlayer, swfdec_dfb_player, SWFDEC_TYPE_PLAYER)
+
+static void
+swfdec_dfb_player_get_property (GObject *object, guint param_id, GValue *value,
+ GParamSpec * pspec)
+{
+ SwfdecDfbPlayer *player = SWFDEC_DFB_PLAYER (object);
+
+ switch (param_id) {
+ case PROP_PLAYING:
+ g_value_set_boolean (value, player->source != NULL);
+ break;
+ case PROP_AUDIO:
+ g_value_set_boolean (value, player->audio_enabled);
+ break;
+ case PROP_SPEED:
+ g_value_set_double (value, player->speed);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+swfdec_dfb_player_set_property (GObject *object, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ SwfdecDfbPlayer *player = SWFDEC_DFB_PLAYER (object);
+
+ switch (param_id) {
+ case PROP_PLAYING:
+ swfdec_dfb_player_set_playing (player, g_value_get_boolean (value));
+ break;
+ case PROP_AUDIO:
+ swfdec_dfb_player_set_audio_enabled (player, g_value_get_boolean (value));
+ break;
+ case PROP_SPEED:
+ swfdec_dfb_player_set_speed (player, g_value_get_double (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+swfdec_dfb_player_dispose (GObject *object)
+{
+ SwfdecDfbPlayer *player = SWFDEC_DFB_PLAYER (object);
+
+ swfdec_dfb_player_set_playing (player, FALSE);
+
+ G_OBJECT_CLASS (swfdec_dfb_player_parent_class)->dispose (object);
+}
+
+static void
+swfdec_dfb_player_class_init (SwfdecDfbPlayerClass * g_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (g_class);
+
+ object_class->dispose = swfdec_dfb_player_dispose;
+ object_class->get_property = swfdec_dfb_player_get_property;
+ object_class->set_property = swfdec_dfb_player_set_property;
+
+ g_object_class_install_property (object_class, PROP_PLAYING,
+ g_param_spec_boolean ("playing", "playing", "TRUE if the player is playing (d'oh)",
+ FALSE, G_PARAM_READWRITE));
+ g_object_class_install_property (object_class, PROP_AUDIO,
+ g_param_spec_boolean ("audio-enabled", "audio enabled", "TRUE if automatic audio handling is enabled",
+ TRUE, G_PARAM_READWRITE));
+ g_object_class_install_property (object_class, PROP_SPEED,
+ g_param_spec_double ("speed", "speed", "desired playback speed",
+ G_MINDOUBLE, G_MAXDOUBLE, 1.0, G_PARAM_READWRITE));
+}
+
+static void
+swfdec_dfb_player_init (SwfdecDfbPlayer * player)
+{
+ player->speed = 1.0;
+ player->audio_enabled = TRUE;
+}
+
+/*** PUBLIC API ***/
+
+/**
+ * swfdec_dfb_player_new:
+ * @debugger: %NULL or a #SwfdecAsDebugger to debug this player
+ *
+ * Creates a new Swfdec Dfb player.
+ * This function calls swfdec_init () for you if it wasn't called before.
+ *
+ * Returns: The new player
+ **/
+SwfdecPlayer *
+swfdec_dfb_player_new (SwfdecAsDebugger *debugger)
+{
+ SwfdecPlayer *player;
+
+ swfdec_init ();
+ player = g_object_new (SWFDEC_TYPE_DFB_PLAYER, "debugger", debugger, NULL);
+
+ return player;
+}
+
+/**
+ * swfdec_dfb_player_new_from_file:
+ * @filename: name of file to play
+ *
+ * Create a player to play back the given file. Note that there is no way to
+ * figure out if the referenced URI really references a file that Swfdec can
+ * play back. If you need this, you should use #SwfdecDfbLoader directly and
+ * use its error property.
+ * This function calls swfdec_init () for you if it wasn't called before.
+ *
+ * Returns: a new player.
+ **/
+SwfdecPlayer *
+swfdec_dfb_player_new_from_file (const char *filename)
+{
+ SwfdecLoader *loader;
+ SwfdecPlayer *player;
+
+ g_return_val_if_fail (filename != NULL, NULL);
+
+ player = swfdec_dfb_player_new (NULL);
+ loader = swfdec_file_loader_new (filename);
+ swfdec_player_set_loader (player, loader);
+
+ return player;
+}
+
+/**
+ * swfdec_dfb_player_set_playing:
+ * @player: a #SwfdecDfbPlayer
+ * @playing: if the player should play or not
+ *
+ * Sets if @player should be playing or not. If the player is playing, a timer
+ * will be attached to the default main loop that periodically calls
+ * swfdec_player_advance().
+ **/
+void
+swfdec_dfb_player_set_playing (SwfdecDfbPlayer *player, gboolean playing)
+{
+ g_return_if_fail (SWFDEC_IS_DFB_PLAYER (player));
+
+ if (playing && player->source == NULL) {
+ player->source = swfdec_iterate_source_new (SWFDEC_PLAYER (player), player->speed);
+ g_source_attach (player->source, NULL);
+ } else if (!playing && player->source != NULL) {
+ g_source_destroy (player->source);
+ g_source_unref (player->source);
+ player->source = NULL;
+ }
+ g_object_notify (G_OBJECT (player), "playing");
+}
+
+/**
+ * swfdec_dfb_player_get_playing:
+ * @player: a #SwfdecDfbPlayer
+ *
+ * Queries if the player is playing.
+ *
+ * Returns: %TRUE if the player is playing
+ **/
+gboolean
+swfdec_dfb_player_get_playing (SwfdecDfbPlayer *player)
+{
+ g_return_val_if_fail (SWFDEC_IS_DFB_PLAYER (player), FALSE);
+
+ return player->source != NULL;
+}
+
+/**
+ * swfdec_dfb_player_set_audio_enabled:
+ * @player: a #SwfdecDfbPlayer
+ * @enabled: %TRUE to enable audio
+ *
+ * Enables or disables automatic audio playback.
+ **/
+void
+swfdec_dfb_player_set_audio_enabled (SwfdecDfbPlayer *player, gboolean enabled)
+{
+ g_return_if_fail (SWFDEC_IS_DFB_PLAYER (player));
+
+ if (player->audio_enabled == enabled)
+ return;
+ player->audio_enabled = enabled;
+ g_object_notify (G_OBJECT (player), "audio-enabled");
+}
+
+/**
+ * swfdec_dfb_player_get_audio_enabled:
+ * @player: a #SwfdecDfbPlayer
+ *
+ * Queries if audio playback for @player is enabled or not.
+ *
+ * Returns: %TRUE if audio playback is enabled
+ **/
+gboolean
+swfdec_dfb_player_get_audio_enabled (SwfdecDfbPlayer *player)
+{
+ g_return_val_if_fail (SWFDEC_IS_DFB_PLAYER (player), FALSE);
+
+ return player->audio_enabled;
+}
+
+/**
+ * swfdec_dfb_player_set_speed:
+ * @player: a #SwfdecDfbPlayer
+ * @speed: the new playback speed
+ *
+ * Sets the new playback speed. 1.0 means the default speed, bigger values
+ * make playback happen faster. Audio will only play back if the speed is
+ * 1.0. Note that if the player is not playing when calling this function,
+ * it will not automatically start.
+ **/
+void
+swfdec_dfb_player_set_speed (SwfdecDfbPlayer *player, double speed)
+{
+ g_return_if_fail (SWFDEC_IS_DFB_PLAYER (player));
+ g_return_if_fail (speed > 0.0);
+
+ player->speed = speed;
+ if (player->source)
+ swfdec_iterate_source_set_speed (player->source, player->speed);
+ g_object_notify (G_OBJECT (player), "speed");
+}
+
+/**
+ * swfdec_dfb_player_get_speed:
+ * @player: a #SwfdecDfbPlayer
+ *
+ * Queries the current playback speed. If the player is currently paused, it
+ * will report the speed that it would use if playing.
+ *
+ * Returns: the current playback speed.
+ **/
+double
+swfdec_dfb_player_get_speed (SwfdecDfbPlayer *player)
+{
+ g_return_val_if_fail (SWFDEC_IS_DFB_PLAYER (player), FALSE);
+
+ return player->speed;
+}
diff --git a/swfdec-directfb/swfdec_directfb_player.h b/swfdec-directfb/swfdec_directfb_player.h
new file mode 100644
index 0000000..8825b55
--- /dev/null
+++ b/swfdec-directfb/swfdec_directfb_player.h
@@ -0,0 +1,71 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
+ *
+ * This library 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.1 of the License, or (at your option) any later version.
+ *
+ * This library 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef _SWFDEC_DFB_PLAYER_H_
+#define _SWFDEC_DFB_PLAYER_H_
+
+#include <libswfdec/swfdec.h>
+
+G_BEGIN_DECLS
+
+typedef struct _SwfdecDfbPlayer SwfdecDfbPlayer;
+typedef struct _SwfdecDfbPlayerClass SwfdecDfbPlayerClass;
+
+#define SWFDEC_TYPE_DFB_PLAYER (swfdec_dfb_player_get_type())
+#define SWFDEC_IS_DFB_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_DFB_PLAYER))
+#define SWFDEC_IS_DFB_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_DFB_PLAYER))
+#define SWFDEC_DFB_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_DFB_PLAYER, SwfdecDfbPlayer))
+#define SWFDEC_DFB_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_DFB_PLAYER, SwfdecDfbPlayerClass))
+#define SWFDEC_DFB_PLAYER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_DFB_PLAYER, SwfdecDfbPlayerClass))
+
+struct _SwfdecDfbPlayer
+{
+ SwfdecPlayer player;
+
+ GSource * source; /* source if playing, NULL otherwise */
+ gboolean audio_enabled; /* TRUE if audio should be played */
+ double speed; /* desired playback speed */
+};
+
+struct _SwfdecDfbPlayerClass
+{
+ SwfdecPlayerClass player_class;
+};
+
+GType swfdec_dfb_player_get_type (void);
+
+SwfdecPlayer * swfdec_dfb_player_new (SwfdecAsDebugger * debugger);
+SwfdecPlayer * swfdec_dfb_player_new_from_file (const char * filename);
+
+void swfdec_dfb_player_set_playing (SwfdecDfbPlayer * player,
+ gboolean playing);
+gboolean swfdec_dfb_player_get_playing (SwfdecDfbPlayer * player);
+void swfdec_dfb_player_set_audio_enabled
+ (SwfdecDfbPlayer * player,
+ gboolean enabled);
+gboolean swfdec_dfb_player_get_audio_enabled
+ (SwfdecDfbPlayer * player);
+void swfdec_dfb_player_set_speed (SwfdecDfbPlayer * player,
+ double speed);
+double swfdec_dfb_player_get_speed (SwfdecDfbPlayer * player);
+
+
+
+G_END_DECLS
+#endif
diff --git a/swfdec-directfb/swfdec_source.c b/swfdec-directfb/swfdec_source.c
new file mode 100644
index 0000000..471b99b
--- /dev/null
+++ b/swfdec-directfb/swfdec_source.c
@@ -0,0 +1,183 @@
+/* Swfdec
+ * Copyright (C) 2006 Benjamin Otte <otte@gnome.org>
+ *
+ * This library 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.1 of the License, or (at your option) any later version.
+ *
+ * This library 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "swfdec_source.h"
+
+static glong
+my_time_val_difference (const GTimeVal *compare, const GTimeVal *now)
+{
+ return (compare->tv_sec - now->tv_sec) * 1000 +
+ (compare->tv_usec - now->tv_usec) / 1000;
+}
+
+/*** SwfdecIterateSource ***/
+
+typedef struct _SwfdecIterateSource SwfdecIterateSource;
+struct _SwfdecIterateSource {
+ GSource source;
+ SwfdecPlayer * player; /* player we manage or NULL if player was deleted */
+ double speed; /* inverse playback speed (so 0.5 means double speed) */
+ gulong notify; /* set for iterate notifications (only valid when player != NULL) */
+ GTimeVal last; /* last time */
+};
+
+static glong
+swfdec_iterate_get_msecs_to_next_event (GSource *source_)
+{
+ SwfdecIterateSource *source = (SwfdecIterateSource *) source_;
+ GTimeVal now;
+ glong diff;
+
+ g_assert (source->player);
+ diff = swfdec_player_get_next_event (source->player);
+ if (diff == -1)
+ return G_MAXLONG;
+ diff *= source->speed;
+ g_source_get_current_time (source_, &now);
+ /* should really add to source->last instead of subtracting from now */
+ g_time_val_add (&now, -diff * 1000);
+ diff = my_time_val_difference (&source->last, &now);
+
+ return diff;
+}
+
+static gboolean
+swfdec_iterate_prepare (GSource *source, gint *timeout)
+{
+ glong diff;
+
+ diff = swfdec_iterate_get_msecs_to_next_event (source);
+ if (((SwfdecIterateSource *) source)->player == NULL) {
+ *timeout = 0;
+ return TRUE;
+ }
+
+ if (diff == G_MAXLONG) {
+ *timeout = -1;
+ return FALSE;
+ } else if (diff <= 0) {
+ *timeout = 0;
+ return TRUE;
+ } else {
+ *timeout = diff;
+ return FALSE;
+ }
+}
+
+static gboolean
+swfdec_iterate_check (GSource *source)
+{
+ glong diff;
+
+ if (((SwfdecIterateSource *) source)->player == NULL)
+ return 0;
+ diff = swfdec_iterate_get_msecs_to_next_event (source);
+ return diff < 0;
+}
+
+static gboolean
+swfdec_iterate_dispatch (GSource *source_, GSourceFunc callback, gpointer user_data)
+{
+ SwfdecIterateSource *source = (SwfdecIterateSource *) source_;
+ glong diff;
+
+ if (source->player == NULL)
+ return FALSE;
+ diff = swfdec_iterate_get_msecs_to_next_event (source_);
+ if (diff > 0)
+ return TRUE;
+ diff = swfdec_player_get_next_event (source->player) - diff;
+ swfdec_player_advance (source->player, diff);
+ return TRUE;
+}
+
+static void
+swfdec_iterate_finalize (GSource *source_)
+{
+ SwfdecIterateSource *source = (SwfdecIterateSource *) source_;
+
+ if (source->notify && source->player) {
+ g_signal_handler_disconnect (source->player, source->notify);
+ }
+ if (source->player) {
+ g_object_remove_weak_pointer (G_OBJECT (source->player), (gpointer) &source->player);
+ }
+}
+
+GSourceFuncs swfdec_iterate_funcs = {
+ swfdec_iterate_prepare,
+ swfdec_iterate_check,
+ swfdec_iterate_dispatch,
+ swfdec_iterate_finalize
+};
+
+static void
+swfdec_iterate_source_advance_cb (SwfdecPlayer *player, guint msecs,
+ guint audio_frames, SwfdecIterateSource *source)
+{
+ g_time_val_add (&source->last, msecs * 1000 * source->speed);
+}
+
+GSource *
+swfdec_iterate_source_new (SwfdecPlayer *player, double speed)
+{
+ SwfdecIterateSource *source;
+
+ g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL);
+ g_return_val_if_fail (speed > 0.0, NULL);
+
+ source = (SwfdecIterateSource *) g_source_new (&swfdec_iterate_funcs,
+ sizeof (SwfdecIterateSource));
+ source->player = player;
+ g_object_add_weak_pointer (G_OBJECT (source->player), (gpointer) &source->player);
+ source->speed = 1.0 / speed;
+ source->notify = g_signal_connect (player, "advance",
+ G_CALLBACK (swfdec_iterate_source_advance_cb), source);
+ g_get_current_time (&source->last);
+
+ return (GSource *) source;
+}
+
+void
+swfdec_iterate_source_set_speed (GSource *source, double speed)
+{
+ /* FIXME: need a return_if_fail if wrong source? */
+ g_return_if_fail (speed > 0.0);
+
+ ((SwfdecIterateSource *) source)->speed = 1.0 / speed;
+}
+
+guint
+swfdec_iterate_add (SwfdecPlayer *player)
+{
+ GSource *source;
+ guint id;
+
+ g_return_val_if_fail (SWFDEC_IS_PLAYER (player), 0);
+
+ source = swfdec_iterate_source_new (player, 1.0);
+
+ id = g_source_attach (source, NULL);
+ g_source_unref (source);
+
+ return id;
+}
diff --git a/swfdec-directfb/swfdec_source.h b/swfdec-directfb/swfdec_source.h
new file mode 100644
index 0000000..0c7c383
--- /dev/null
+++ b/swfdec-directfb/swfdec_source.h
@@ -0,0 +1,34 @@
+/* Swfdec
+ * Copyright (C) 2006 Benjamin Otte <otte@gnome.org>
+ *
+ * This library 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.1 of the License, or (at your option) any later version.
+ *
+ * This library 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef _SWFDEC_SOURCE_H_
+#define _SWFDEC_SOURCE_H_
+
+#include <libswfdec/swfdec.h>
+
+G_BEGIN_DECLS
+
+GSource * swfdec_iterate_source_new (SwfdecPlayer * player,
+ double speed);
+void swfdec_iterate_source_set_speed (GSource * source,
+ double speed);
+guint swfdec_iterate_add (SwfdecPlayer * player);
+
+G_END_DECLS
+#endif