Benjamin Otte
2007-Mar-27 08:16 UTC
[Swfdec] 15 commits - configure.ac doc/Makefile.am doc/swfdec-docs.sgml doc/swfdec-sections.txt doc/swfdec.types libswfdec-gtk/.gitignore libswfdec-gtk/Makefile.am libswfdec-gtk/swfdec-gtk.h libswfdec-gtk/swfdec_gtk_player.c libswfdec-gtk/swfdec_gtk_player.h libswfdec-gtk/swfdec_gtk_widget.c libswfdec-gtk/swfdec_gtk_widget.h libswfdec-gtk/swfdec_playback_alsa.c libswfdec-gtk/swfdec_playback.h libswfdec-gtk/swfdec_playback_none.c libswfdec-gtk/swfdec_source.c libswfdec-gtk/swfdec_source.h libswfdec/js libswfdec/Makefile.am Makefile.am player/.gitignore player/Makefile.am player/swfdebug.c player/swfdec_debug_widget.c player/swfdec_debug_widget.h player/swfdec_playback_alsa.c player/swfdec_playback.h player/swfdec_playback_none.c player/swfdec_player_manager.c player/swfdec_source.c player/swfdec_source.h player/swfdec_widget.c player/swfdec_widget.h player/swfplay.c swfdec-gtk.pc.in test/image test/Makefile.am test/sound test/trace test/various
Makefile.am | 10 configure.ac | 51 +- doc/Makefile.am | 16 doc/swfdec-docs.sgml | 7 doc/swfdec-sections.txt | 53 ++ doc/swfdec.types | 2 libswfdec-gtk/.gitignore | 14 libswfdec-gtk/Makefile.am | 40 + libswfdec-gtk/swfdec-gtk.h | 17 libswfdec-gtk/swfdec_gtk_player.c | 338 ++++++++++++++++ libswfdec-gtk/swfdec_gtk_player.h | 56 ++ libswfdec-gtk/swfdec_gtk_widget.c | 717 +++++++++++++++++++++++++++++++++++ libswfdec-gtk/swfdec_gtk_widget.h | 73 +++ libswfdec-gtk/swfdec_playback.h | 8 libswfdec-gtk/swfdec_playback_alsa.c | 25 - libswfdec-gtk/swfdec_playback_none.c | 4 libswfdec-gtk/swfdec_source.c | 9 libswfdec-gtk/swfdec_source.h | 2 libswfdec/Makefile.am | 4 libswfdec/js/Makefile.am | 2 player/.gitignore | 2 player/Makefile.am | 39 - player/swfdebug.c | 9 player/swfdec_debug_widget.c | 25 - player/swfdec_debug_widget.h | 8 player/swfdec_player_manager.c | 2 player/swfdec_widget.c | 450 --------------------- player/swfdec_widget.h | 73 --- player/swfplay.c | 46 -- swfdec-gtk.pc.in | 11 test/Makefile.am | 24 - test/image/Makefile.am | 4 test/sound/Makefile.am | 4 test/trace/Makefile.am | 4 test/various/Makefile.am | 8 35 files changed, 1474 insertions(+), 683 deletions(-) New commits: diff-tree 58cd315b3b41e451e7f94b282e8a4fe8e787069e (from 18bb6f82cd25bee7c1786cecc6051bf5c4574e56) Author: Benjamin Otte <otte@gnome.org> Date: Mon Mar 26 18:55:39 2007 +0200 add a default header diff --git a/libswfdec-gtk/Makefile.am b/libswfdec-gtk/Makefile.am index b787c6e..93b6897 100644 --- a/libswfdec-gtk/Makefile.am +++ b/libswfdec-gtk/Makefile.am @@ -29,6 +29,7 @@ libswfdec_gtk_@SWFDEC_MAJORMINOR@_la_LDF $(GTK_LIBS) $(SWFDEC_LIBS) $(AUDIO_LIBS) libswfdec_@SWFDEC_MAJORMINOR@includedir = $(includedir)/swfdec-@SWFDEC_MAJORMINOR@/libswfdec libswfdec_@SWFDEC_MAJORMINOR@include_HEADERS = \ + swfdec-gtk.h \ swfdec_gtk_player.h \ swfdec_gtk_widget.h diff --git a/libswfdec-gtk/swfdec-gtk.h b/libswfdec-gtk/swfdec-gtk.h new file mode 100644 index 0000000..c9a0ac8 --- /dev/null +++ b/libswfdec-gtk/swfdec-gtk.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_GTK_H__ +#define __SWFDEC_GTK_H__ + +#include <libswfdec-gtk/swfdec_gtk_player.h> +#include <libswfdec-gtk/swfdec_gtk_widget.h> + +#endif diff-tree 18bb6f82cd25bee7c1786cecc6051bf5c4574e56 (from 56b33194342c5635e12adeb2e02f6badf4ebba30) Author: Benjamin Otte <otte@gnome.org> Date: Mon Mar 26 18:55:22 2007 +0200 enable audio playback by default diff --git a/libswfdec-gtk/swfdec_gtk_player.c b/libswfdec-gtk/swfdec_gtk_player.c index 92d8231..475cd3f 100644 --- a/libswfdec-gtk/swfdec_gtk_player.c +++ b/libswfdec-gtk/swfdec_gtk_player.c @@ -152,6 +152,7 @@ static void swfdec_gtk_player_init (SwfdecGtkPlayer * player) { player->speed = 1.0; + player->audio_enabled = TRUE; } /*** PUBLIC API ***/ diff-tree 56b33194342c5635e12adeb2e02f6badf4ebba30 (from cc49873efa4dec9ef12869809050f102ec9d4998) Author: Benjamin Otte <otte@gnome.org> Date: Mon Mar 26 18:52:44 2007 +0200 update to use SwfdecGtkPlayer diff --git a/player/swfplay.c b/player/swfplay.c index 0a3805c..db08066 100644 --- a/player/swfplay.c +++ b/player/swfplay.c @@ -24,14 +24,10 @@ #include <math.h> #include <libswfdec/swfdec.h> -#include <libswfdec-gtk/swfdec_playback.h> -#include <libswfdec-gtk/swfdec_source.h> -#include <libswfdec-gtk/swfdec_gtk_widget.h> +#include <libswfdec-gtk/swfdec-gtk.h> #include "swfdec_slow_loader.h" -static gpointer playback; - static void set_title (GtkWindow *window, const char *filename) { @@ -61,20 +57,6 @@ view_swf (SwfdecPlayer *player, double s } static void -play_swf (SwfdecPlayer *player, double speed) -{ - GSource *source; - - source = swfdec_iterate_source_new (player, speed); - g_source_attach (source, NULL); - - gtk_main (); - - g_source_destroy (source); - g_source_unref (source); -} - -static void print_trace (SwfdecPlayer *player, const char *message, gpointer unused) { g_print ("%s\n", message); @@ -133,7 +115,7 @@ main (int argc, char *argv[]) g_error_free (error); return 1; } - player = swfdec_player_new (); + player = swfdec_gtk_player_new (); if (trace) g_signal_connect (player, "trace", G_CALLBACK (print_trace), NULL); @@ -149,18 +131,16 @@ main (int argc, char *argv[]) return 1; } + if (no_sound) + swfdec_gtk_player_set_audio (SWFDEC_GTK_PLAYER (player), FALSE); + + swfdec_gtk_player_set_speed (SWFDEC_GTK_PLAYER (player), speed / 100.); + swfdec_gtk_player_set_playing (SWFDEC_GTK_PLAYER (player), TRUE); + window = view_swf (player, scale, use_image); set_title (GTK_WINDOW (window), argv[1]); - if (no_sound || speed != 100) { - playback = NULL; - } else { - playback = swfdec_playback_open (player, g_main_context_default ()); - } - play_swf (player, speed / 100.); - - if (playback) - swfdec_playback_close (playback); + gtk_main (); g_object_unref (player); player = NULL; diff-tree cc49873efa4dec9ef12869809050f102ec9d4998 (from f0088c36f8e0f02c6a850e3d7bb53695ba972ab5) Author: Benjamin Otte <otte@gnome.org> Date: Mon Mar 26 18:45:09 2007 +0200 update the docs for SwfdecGtkPlayer diff --git a/doc/Makefile.am b/doc/Makefile.am index d9700aa..0b037de 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -109,6 +109,7 @@ IGNORE_HFILES= \ swfdec_xml.h EXTRA_HFILES = \ + ../libswfdec-gtk/swfdec_gtk_player.h \ ../libswfdec-gtk/swfdec_gtk_widget.h # Images to copy into HTML directory. diff --git a/doc/swfdec-docs.sgml b/doc/swfdec-docs.sgml index 432547b..e5b1d71 100644 --- a/doc/swfdec-docs.sgml +++ b/doc/swfdec-docs.sgml @@ -8,6 +8,7 @@ <chapter> <title>Swfdec Gtk library</title> + <xi:include href="xml/SwfdecGtkPlayer.xml"/> <xi:include href="xml/SwfdecGtkWidget.xml"/> </chapter> <chapter> diff --git a/doc/swfdec-sections.txt b/doc/swfdec-sections.txt index 942f73c..f33b594 100644 --- a/doc/swfdec-sections.txt +++ b/doc/swfdec-sections.txt @@ -108,6 +108,29 @@ swfdec_mouse_cursor_get_type <SECTION> +<FILE>SwfdecGtkPlayer</FILE> +<TITLE>SwfdecGtkPlayer</TITLE> +SwfdecGtkPlayer +swfdec_gtk_player_new +swfdec_gtk_player_new_from_file +swfdec_gtk_player_get_playing +swfdec_gtk_player_set_playing +swfdec_gtk_player_get_speed +swfdec_gtk_player_set_speed +swfdec_gtk_player_get_audio +swfdec_gtk_player_set_audio +<SUBSECTION Standard> +SwfdecGtkPlayerClass +swfdec_gtk_player_get_type +SWFDEC_GTK_PLAYER +SWFDEC_GTK_PLAYER_CLASS +SWFDEC_GTK_PLAYER_GET_CLASS +SWFDEC_IS_GTK_PLAYER +SWFDEC_IS_GTK_PLAYER_CLASS +SWFDEC_TYPE_GTK_PLAYER +</SECTION> + +<SECTION> <FILE>SwfdecGtkWidget</FILE> <TITLE>SwfdecGtkWidget</TITLE> SwfdecGtkWidget diff --git a/doc/swfdec.types b/doc/swfdec.types index c3030f0..dbd39e4 100644 --- a/doc/swfdec.types +++ b/doc/swfdec.types @@ -3,4 +3,6 @@ swfdec_player_get_type swfdec_audio_get_type swfdec_loader_get_type +swfdec_gtk_player_get_type +swfdec_gtk_widget_get_type diff-tree f0088c36f8e0f02c6a850e3d7bb53695ba972ab5 (from a7771114e2f618c43b3758797e1bcea6c5ce9dc7) Author: Benjamin Otte <otte@gnome.org> Date: Mon Mar 26 18:44:50 2007 +0200 Add SwfdecGtkPlayer It's basically a SwfdecPlayer that integrates into the main loop and does audio playback diff --git a/libswfdec-gtk/Makefile.am b/libswfdec-gtk/Makefile.am index 1c35f3e..b787c6e 100644 --- a/libswfdec-gtk/Makefile.am +++ b/libswfdec-gtk/Makefile.am @@ -13,6 +13,7 @@ lib_LTLIBRARIES = libswfdec-gtk-@SWFDEC_ libswfdec_gtk_@SWFDEC_MAJORMINOR@_la_SOURCES = \ swfdec_playback.c \ swfdec_source.c \ + swfdec_gtk_player.c \ swfdec_gtk_widget.c noinst_HEADERS = \ @@ -21,13 +22,14 @@ noinst_HEADERS = \ libswfdec_gtk_@SWFDEC_MAJORMINOR@_la_CFLAGS = \ $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(GTK_CFLAGS) $(AUDIO_CFLAGS) \ - -DG_LOG_DOMAIN=\"Swfdec-Gtk\" + -DG_LOG_DOMAIN=\"Swfdec-Gtk\" -DXP_UNIX libswfdec_gtk_@SWFDEC_MAJORMINOR@_la_LDFLAGS = \ -version-info $(SWFDEC_LIBVERSION) \ -export-symbols-regex '^(swfdec_.*)' \ $(GTK_LIBS) $(SWFDEC_LIBS) $(AUDIO_LIBS) libswfdec_@SWFDEC_MAJORMINOR@includedir = $(includedir)/swfdec-@SWFDEC_MAJORMINOR@/libswfdec libswfdec_@SWFDEC_MAJORMINOR@include_HEADERS = \ + swfdec_gtk_player.h \ swfdec_gtk_widget.h endif diff --git a/libswfdec-gtk/swfdec_gtk_player.c b/libswfdec-gtk/swfdec_gtk_player.c new file mode 100644 index 0000000..92d8231 --- /dev/null +++ b/libswfdec-gtk/swfdec_gtk_player.c @@ -0,0 +1,337 @@ +/* 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 <libswfdec/swfdec_player_internal.h> +#include "libswfdec-gtk/swfdec_gtk_player.h" +#include "libswfdec-gtk/swfdec_playback.h" +#include "libswfdec-gtk/swfdec_source.h" + +struct _SwfdecGtkPlayer +{ + SwfdecPlayer player; + + GSource * source; /* source if playing, NULL otherwise */ + SwfdecPlayback * playback; /* audio playback object */ + gboolean audio_enabled; /* TRUE if audio should be played */ + double speed; /* desired playback speed */ +}; + +struct _SwfdecGtkPlayerClass +{ + SwfdecPlayerClass player_class; +}; + +enum { + PROP_0, + PROP_PLAYING, + PROP_AUDIO, + PROP_SPEED +}; + +/*** gtk-doc ***/ + +/** + * SECTION:SwfdecGtkPlayer + * @title: SwfdecGtkPlayer + * @short_description: an improved #SwfdecPlayer + * + * The #SwfdecGtkPlayer 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_gtk_player_set_playing () on the new player. + * + * @see_also: SwfdecPlayer + */ + +/** + * SwfdecGtkPlayer: + * + * The structure for the Swfdec Gtk player contains no public fields. + */ + +/*** SWFDEC_GTK_PLAYER ***/ + +G_DEFINE_TYPE (SwfdecGtkPlayer, swfdec_gtk_player, SWFDEC_TYPE_PLAYER) + +static void +swfdec_gtk_player_get_property (GObject *object, guint param_id, GValue *value, + GParamSpec * pspec) +{ + SwfdecGtkPlayer *player = SWFDEC_GTK_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_gtk_player_set_property (GObject *object, guint param_id, const GValue *value, + GParamSpec *pspec) +{ + SwfdecGtkPlayer *player = SWFDEC_GTK_PLAYER (object); + + switch (param_id) { + case PROP_PLAYING: + swfdec_gtk_player_set_playing (player, g_value_get_boolean (value)); + break; + case PROP_AUDIO: + swfdec_gtk_player_set_audio (player, g_value_get_boolean (value)); + break; + case PROP_SPEED: + swfdec_gtk_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_gtk_player_dispose (GObject *object) +{ + SwfdecGtkPlayer *player = SWFDEC_GTK_PLAYER (object); + + swfdec_gtk_player_set_playing (player, FALSE); + g_assert (player->playback == NULL); + + G_OBJECT_CLASS (swfdec_gtk_player_parent_class)->dispose (object); +} + +static void +swfdec_gtk_player_class_init (SwfdecGtkPlayerClass * g_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (g_class); + + object_class->dispose = swfdec_gtk_player_dispose; + object_class->get_property = swfdec_gtk_player_get_property; + object_class->set_property = swfdec_gtk_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_gtk_player_init (SwfdecGtkPlayer * player) +{ + player->speed = 1.0; +} + +/*** PUBLIC API ***/ + +/** + * swfdec_gtk_player_new: + * + * Creates a new Swfdec Gtk player. + * This function calls swfdec_init () for you if it wasn't called before. + * + * Returns: The new player + **/ +SwfdecPlayer * +swfdec_gtk_player_new (void) +{ + SwfdecPlayer *player; + + swfdec_init (); + player = g_object_new (SWFDEC_TYPE_GTK_PLAYER, NULL); + + return player; +} + +/** + * swfdec_gtk_player_new_from_file: + * @filename: name of the file to play + * @error: return location for error or %NULL + * + * Tries to create a player to play back the given file. If the file does not + * exist or another error occurs, %NULL is returned. + * This function calls swfdec_init () for you if it wasn't called before. + * + * Returns: a new player or %NULL on error. + **/ +SwfdecPlayer * +swfdec_player_new_from_file (const char *filename, GError **error) +{ + SwfdecLoader *loader; + SwfdecPlayer *player; + + g_return_val_if_fail (filename != NULL, NULL); + + loader = swfdec_loader_new_from_file (filename, error); + if (loader == NULL) + return NULL; + player = swfdec_gtk_player_new (); + swfdec_player_set_loader (player, loader); + + return player; +} + +static void +swfdec_gtk_player_update_audio (SwfdecGtkPlayer *player) +{ + gboolean should_play = player->audio_enabled; + + should_play &= (player->source != NULL); + should_play &= (player->speed == 1.0); + + if (should_play && player->playback == NULL) { + player->playback = swfdec_playback_open (SWFDEC_PLAYER (player), + g_main_context_default ()); + } else if (!should_play && player->playback != NULL) { + swfdec_playback_close (player->playback); + player->playback = NULL; + } +} + +/** + * swfdec_gtk_player_set_playing: + * @player: a #SwfdecGtkPlayer + * @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_gtk_player_set_playing (SwfdecGtkPlayer *player, gboolean playing) +{ + g_return_if_fail (SWFDEC_IS_GTK_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); + } + swfdec_gtk_player_update_audio (player); + g_object_notify (G_OBJECT (player), "playing"); +} + +/** + * swfdec_gtk_player_get_playing: + * @player: a #SwfdecGtkPlayer + * + * Queries if the player is playing. + * + * Returns: %TRUE if the player is playing + **/ +gboolean +swfdec_gtk_player_get_playing (SwfdecGtkPlayer *player) +{ + g_return_val_if_fail (SWFDEC_IS_GTK_PLAYER (player), FALSE); + + return player->source != NULL; +} + +/** + * swfdec_gtk_player_set_audio: + * @player: a #SwfdecGtkPlayer + * @enabled: %TRUE to enable audio + * + * Enables or disables automatic audio playback. + **/ +void +swfdec_gtk_player_set_audio (SwfdecGtkPlayer *player, gboolean enabled) +{ + g_return_if_fail (SWFDEC_IS_GTK_PLAYER (player)); + + if (player->audio_enabled == enabled) + return; + player->audio_enabled = enabled; + swfdec_gtk_player_update_audio (player); + g_object_notify (G_OBJECT (player), "audio-enabled"); +} + +/** + * swfdec_gtk_player_get_audio: + * @player: a #SwfdecGtkPlayer + * + * Queries if audio playback for @player is enabled or not. + * + * Returns: %TRUE if audio playback is enabled + **/ +gboolean +swfdec_gtk_player_get_audio (SwfdecGtkPlayer *player) +{ + g_return_val_if_fail (SWFDEC_IS_GTK_PLAYER (player), FALSE); + + return player->audio_enabled; +} + +/** + * swfdec_gtk_player_set_speed: + * @player: a #SwfdecGtkPlayer + * @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_gtk_player_set_speed (SwfdecGtkPlayer *player, double speed) +{ + g_return_if_fail (SWFDEC_IS_GTK_PLAYER (player)); + g_return_if_fail (speed > 0.0); + + player->speed = speed; + swfdec_gtk_player_update_audio (player); + if (player->source) + swfdec_iterate_source_set_speed (player->source, player->speed); + g_object_notify (G_OBJECT (player), "speed"); +} + +/** + * swfdec_gtk_player_get_speed: + * @player: a #SwfdecGtkPlayer + * + * 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_gtk_player_get_speed (SwfdecGtkPlayer *player) +{ + g_return_val_if_fail (SWFDEC_IS_GTK_PLAYER (player), FALSE); + + return player->speed; +} diff --git a/libswfdec-gtk/swfdec_gtk_player.h b/libswfdec-gtk/swfdec_gtk_player.h new file mode 100644 index 0000000..c5a9c17 --- /dev/null +++ b/libswfdec-gtk/swfdec_gtk_player.h @@ -0,0 +1,56 @@ +/* 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_GTK_PLAYER_H_ +#define _SWFDEC_GTK_PLAYER_H_ + +#include <libswfdec/swfdec.h> + +G_BEGIN_DECLS + +typedef struct _SwfdecGtkPlayer SwfdecGtkPlayer; +typedef struct _SwfdecGtkPlayerClass SwfdecGtkPlayerClass; + +#define SWFDEC_TYPE_GTK_PLAYER (swfdec_gtk_player_get_type()) +#define SWFDEC_IS_GTK_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_GTK_PLAYER)) +#define SWFDEC_IS_GTK_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_GTK_PLAYER)) +#define SWFDEC_GTK_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_GTK_PLAYER, SwfdecGtkPlayer)) +#define SWFDEC_GTK_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_GTK_PLAYER, SwfdecGtkPlayerClass)) +#define SWFDEC_GTK_PLAYER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_GTK_PLAYER, SwfdecGtkPlayerClass)) + +GType swfdec_gtk_player_get_type (void); + +SwfdecPlayer * swfdec_gtk_player_new (void); +SwfdecPlayer * swfdec_gtk_player_new_from_file (const char * filename, + GError ** error); + +void swfdec_gtk_player_set_playing (SwfdecGtkPlayer * player, + gboolean playing); +gboolean swfdec_gtk_player_get_playing (SwfdecGtkPlayer * player); +void swfdec_gtk_player_set_audio (SwfdecGtkPlayer * player, + gboolean enabled); +gboolean swfdec_gtk_player_get_audio (SwfdecGtkPlayer * player); +void swfdec_gtk_player_set_speed (SwfdecGtkPlayer * player, + double speed); +double swfdec_gtk_player_get_speed (SwfdecGtkPlayer * player); + + + +G_END_DECLS +#endif diff-tree a7771114e2f618c43b3758797e1bcea6c5ce9dc7 (from 9d9cebe02b434c2554fb6953aa47d2a1e8e7e7f7) Author: Benjamin Otte <otte@gnome.org> Date: Mon Mar 26 18:42:03 2007 +0200 add swfdec_iterate_source_set_speed diff --git a/libswfdec-gtk/swfdec_source.c b/libswfdec-gtk/swfdec_source.c index 81e383b..f001de3 100644 --- a/libswfdec-gtk/swfdec_source.c +++ b/libswfdec-gtk/swfdec_source.c @@ -141,6 +141,15 @@ swfdec_iterate_source_new (SwfdecPlayer 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) { diff --git a/libswfdec-gtk/swfdec_source.h b/libswfdec-gtk/swfdec_source.h index 4321d6d..0c7c383 100644 --- a/libswfdec-gtk/swfdec_source.h +++ b/libswfdec-gtk/swfdec_source.h @@ -26,6 +26,8 @@ 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 diff-tree 9d9cebe02b434c2554fb6953aa47d2a1e8e7e7f7 (from 1eb5785b0e4e1440f9bae4b6e74f761a6672c82a) Author: Benjamin Otte <otte@gnome.org> Date: Mon Mar 26 17:43:46 2007 +0200 hack to convince gtk-doc to read two subdirs for docs diff --git a/doc/Makefile.am b/doc/Makefile.am index d373503..d9700aa 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -33,7 +33,7 @@ SCAN_OPTIONS # Extra options to supply to gtkdoc-mkdb. # e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml -MKDB_OPTIONS=--sgml-mode --output-format=xml +MKDB_OPTIONS=--sgml-mode --output-format=xml --source-dir=../libswfdec-gtk # Extra options to supply to gtkdoc-mktmpl # e.g. MKTMPL_OPTIONS=--only-section-tmpl diff-tree 1eb5785b0e4e1440f9bae4b6e74f761a6672c82a (from c2006dbbccaac8dda324afc39691536a95e7cb47) Author: Benjamin Otte <otte@gnome.org> Date: Mon Mar 26 17:43:10 2007 +0200 Add API docs diff --git a/libswfdec-gtk/swfdec_gtk_widget.c b/libswfdec-gtk/swfdec_gtk_widget.c index 84bddf1..dcd39a0 100644 --- a/libswfdec-gtk/swfdec_gtk_widget.c +++ b/libswfdec-gtk/swfdec_gtk_widget.c @@ -40,11 +40,36 @@ struct _SwfdecGtkWidgetPrivate enum { PROP_0, PROP_PLAYER, + PROP_SCALE, PROP_INTERACTIVE, PROP_RENDERER_SET, PROP_RENDERER }; +/*** gtk-doc ***/ + +/** + * SECTION:SwfdecGtkWidget + * @title: SwfdecGtkWidget + * @short_description: a #GtkWidget for embedding SWF files + * + * This is a widget for playing Flash movies rendered with Swfdec in a Gtk + * application. It supports a lot of advanced features, if you want to use + * them. If you don't want to use them and just want to embed a movie in + * your application, swfdec_gtk_widget_new() will probably be the only + * function you need. + * + * @see_also: SwfdecGtkPlayer + */ + +/** + * SwfdecGtkWidget: + * + * The structure for the Swfdec Gtk widget contains no public fields. + */ + +/*** SWFDEC_GTK_WIDGET ***/ + G_DEFINE_TYPE (SwfdecGtkWidget, swfdec_gtk_widget, GTK_TYPE_WIDGET) static gboolean @@ -168,6 +193,9 @@ swfdec_gtk_widget_get_property (GObject case PROP_PLAYER: g_value_set_object (value, priv->player); break; + case PROP_SCALE: + g_value_set_double (value, priv->set_scale); + break; case PROP_INTERACTIVE: g_value_set_boolean (value, priv->interactive); break; @@ -194,6 +222,9 @@ swfdec_gtk_widget_set_property (GObject case PROP_PLAYER: swfdec_gtk_widget_set_player (widget, g_value_get_object (value)); break; + case PROP_SCALE: + swfdec_gtk_widget_set_scale (widget, g_value_get_double (value)); + break; case PROP_INTERACTIVE: swfdec_gtk_widget_set_interactive (widget, g_value_get_boolean (value)); break; @@ -291,7 +322,10 @@ swfdec_gtk_widget_update_cursor (SwfdecG if (window == NULL) return; - g_object_get (priv->player, "mouse-cursor", &swfcursor, NULL); + if (priv->interactive) + swfcursor = SWFDEC_MOUSE_CURSOR_NORMAL; + else + g_object_get (priv->player, "mouse-cursor", &swfcursor, NULL); switch (swfcursor) { case SWFDEC_MOUSE_CURSOR_NONE: @@ -379,6 +413,9 @@ swfdec_gtk_widget_class_init (SwfdecGtkW g_object_class_install_property (object_class, PROP_PLAYER, g_param_spec_object ("player", "player", "player that is displayed", SWFDEC_TYPE_PLAYER, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, PROP_SCALE, + g_param_spec_double ("scale", "scale", "scale factor to use or 0.0 for automatic", + 0.0, G_MAXDOUBLE, 0.0, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_INTERACTIVE, g_param_spec_boolean ("interactive", "interactive", "if mouse events are processed", TRUE, G_PARAM_READWRITE)); @@ -440,6 +477,15 @@ swfdec_gtk_widget_notify_cb (SwfdecPlaye } } +/*** PUBLIC API ***/ + +/** + * swfdec_gtk_widget_set_player: + * @widget: a #SwfdecGtkWidget + * @player: the #SwfdecPlayer to display or %NULL for none + * + * Sets the new player to display in @widget. + **/ void swfdec_gtk_widget_set_player (SwfdecGtkWidget *widget, SwfdecPlayer *player) { @@ -467,6 +513,14 @@ swfdec_gtk_widget_set_player (SwfdecGtkW g_object_notify (G_OBJECT (widget), "player"); } +/** + * swfdec_gtk_widget_get_player: + * @widget: a #SwfdecGtkWidget + * + * Gets the player that is currently played back in this @widget. + * + * Returns: the #SwfdecPlayer or %NULL if none + **/ SwfdecPlayer * swfdec_gtk_widget_get_player (SwfdecGtkWidget *widget) { @@ -475,6 +529,14 @@ swfdec_gtk_widget_get_player (SwfdecGtkW return widget->priv->player; } +/** + * swfdec_gtk_widget_new: + * @player: a #SwfdecPlayer or %NULL + * + * Creates a new #SwfdecGtkWidget to display @player. + * + * Returns: the new widget that displays @player + **/ GtkWidget * swfdec_gtk_widget_new (SwfdecPlayer *player) { @@ -487,6 +549,14 @@ swfdec_gtk_widget_new (SwfdecPlayer *pla return GTK_WIDGET (widget); } +/** + * swfdec_gtk_widget_set_scale: + * @widget: a #SwfdecGtkWidget + * @scale: scale factor to use or 0 for automatic + * + * Sets the scale factor to use. If you set @scale to 0, the movie is displayed + * as big as the window is. + **/ void swfdec_gtk_widget_set_scale (SwfdecGtkWidget *widget, double scale) { @@ -495,8 +565,18 @@ swfdec_gtk_widget_set_scale (SwfdecGtkWi widget->priv->set_scale = scale; gtk_widget_queue_resize (GTK_WIDGET (widget)); + g_object_notify (G_OBJECT (widget), "scale"); } +/** + * swfdec_gtk_widget_get_scale: + * @widget: a #SwfdecGtkWidget + * + * Gets the user-set scale factor for this @widget. If you want the scale + * factor that is currently in effect, use swfdec_gtk_widget_get_current_scale(). + * + * Returns: The current scale factor or 0.0 if automatic. + **/ double swfdec_gtk_widget_get_scale (SwfdecGtkWidget *widget) { @@ -505,6 +585,17 @@ swfdec_gtk_widget_get_scale (SwfdecGtkWi return widget->priv->set_scale; } +/** + * swfdec_gtk_widget_get_current_scale: + * @widget: a #SwfdecGtkWidget + * + * Queries the current scale factor in use. The returned value is undefined + * if the widget has not been allocated a size. This value is only different + * from the value returned by swfdec_gtk_widget_get_scale(), if automatic + * scaling is in effect. + * + * Returns: The current scale factor. + **/ double swfdec_gtk_widget_get_current_scale (SwfdecGtkWidget *widget) { @@ -513,14 +604,34 @@ swfdec_gtk_widget_get_current_scale (Swf return widget->priv->real_scale; } +/** + * swfdec_gtk_widget_set_interactive: + * @widget: a #SwfdecGtkWidget + * @interactive: %TRUE to make the widget interactive + * + * Sets the widget to be interactive or not. An interactive widget processes + * mouse and keyboard events, while a non-interactive widget does not care about + * user input. Widgets are interactive by default. + **/ void swfdec_gtk_widget_set_interactive (SwfdecGtkWidget *widget, gboolean interactive) { g_return_if_fail (SWFDEC_IS_GTK_WIDGET (widget)); widget->priv->interactive = interactive; + swfdec_gtk_widget_update_cursor (widget); + g_object_notify (G_OBJECT (widget), "interactive"); } +/** + * swfdec_gtk_widget_get_interactive: + * @widget: a #SwfdecGtkWidget + * + * Queries if the @widget is currently interactive. See + * swfdec_gtk_widget_set_interactive() for details. + * + * Returns: %TRUE if the widget is interactive, %FALSE otherwise. + **/ gboolean swfdec_gtk_widget_get_interactive (SwfdecGtkWidget *widget) { @@ -529,6 +640,15 @@ swfdec_gtk_widget_get_interactive (Swfde return widget->priv->interactive; } +/** + * swfdec_gtk_widget_set_renderer: + * @widget: a #SwfdecGtkWidget + * @renderer: a #cairo_surface_type_t for the intermediate renderer + * + * Tells @widget to use an intermediate surface for rendering. This is + * useful for debugging or performance measurements inside swfdec and is + * probably not interesting for anyone else. + **/ void swfdec_gtk_widget_set_renderer (SwfdecGtkWidget *widget, cairo_surface_type_t renderer) { @@ -542,6 +662,13 @@ swfdec_gtk_widget_set_renderer (SwfdecGt g_object_notify (G_OBJECT (widget), "renderer"); } +/** + * swfdec_gtk_widget_unset_renderer: + * @widget: a #SwfdecGtkWidget + * + * Unsets the use of an intermediate rendering surface. See + * swfdec_gtk_widget_set_renderer() for details. + **/ void swfdec_gtk_widget_unset_renderer (SwfdecGtkWidget *widget) { @@ -553,6 +680,16 @@ swfdec_gtk_widget_unset_renderer (Swfdec g_object_notify (G_OBJECT (widget), "renderer-set"); } +/** + * swfdec_gtk_widget_get_renderer: + * @widget: a #SwfdecGtkWidget + * + * Gets the intermediate renderer that is or would be in use by @widget. Use + * swfdec_gtk_widget_uses_renderer() to check if an intermediate renderer is in + * use. See swfdec_gtk_widget_set_renderer() for details. + * + * Returns: the type of the intermediate renderer + **/ cairo_surface_type_t swfdec_gtk_widget_get_renderer (SwfdecGtkWidget *widget) { @@ -561,6 +698,15 @@ swfdec_gtk_widget_get_renderer (SwfdecGt return widget->priv->renderer; } +/** + * swfdec_gtk_widget_uses_renderer: + * @widget: a #SwfdecGtkWidget + * + * Queries if an intermediate renderer set via swfdec_gtk_widget_set_renderer() + * is currently in use. + * + * Returns: %TRUE if an intermediate renderer is used. + **/ gboolean swfdec_gtk_widget_uses_renderer (SwfdecGtkWidget *widget) { diff --git a/libswfdec-gtk/swfdec_gtk_widget.h b/libswfdec-gtk/swfdec_gtk_widget.h index fa9580e..c7799ed 100644 --- a/libswfdec-gtk/swfdec_gtk_widget.h +++ b/libswfdec-gtk/swfdec_gtk_widget.h @@ -39,12 +39,13 @@ struct _SwfdecGtkWidget { GtkWidget widget; + /*< private >*/ SwfdecGtkWidgetPrivate * priv; }; struct _SwfdecGtkWidgetClass { - GtkWidgetClass widget_class; + GtkWidgetClass widget_class; }; GType swfdec_gtk_widget_get_type (void); diff-tree c2006dbbccaac8dda324afc39691536a95e7cb47 (from 5c55ebf25f01e1e43276df79e1ca08a5decd2f05) Author: Benjamin Otte <otte@gnome.org> Date: Mon Mar 26 17:42:33 2007 +0200 Use a SwfdecPlayback struct instead of gpointer makes gcc catch more errors diff --git a/libswfdec-gtk/swfdec_playback.h b/libswfdec-gtk/swfdec_playback.h index 8b894cf..8be67dd 100644 --- a/libswfdec-gtk/swfdec_playback.h +++ b/libswfdec-gtk/swfdec_playback.h @@ -24,10 +24,12 @@ G_BEGIN_DECLS -gpointer swfdec_playback_open (SwfdecPlayer * player, - GMainContext * context); +typedef struct _SwfdecPlayback SwfdecPlayback; -void swfdec_playback_close (gpointer sound); +SwfdecPlayback *swfdec_playback_open (SwfdecPlayer * player, + GMainContext * context); + +void swfdec_playback_close (SwfdecPlayback * sound); G_END_DECLS #endif diff --git a/libswfdec-gtk/swfdec_playback_alsa.c b/libswfdec-gtk/swfdec_playback_alsa.c index ea47099..8160f1c 100644 --- a/libswfdec-gtk/swfdec_playback_alsa.c +++ b/libswfdec-gtk/swfdec_playback_alsa.c @@ -22,7 +22,7 @@ #endif #include <alsa/asoundlib.h> -#include "swfdec_source.h" +#include "swfdec_playback.h" /* Why ALSA sucks for beginners: * - snd_pcm_delay is not sample-exact, but period-exact most of the time. @@ -41,14 +41,14 @@ /*** DEFINITIONS ***/ -typedef struct { +struct _SwfdecPlayback { SwfdecPlayer * player; GList * streams; /* all Stream objects */ GMainContext * context; /* context we work in */ -} Sound; +}; typedef struct { - Sound * sound; /* reference to sound object */ + SwfdecPlayback * sound; /* reference to sound object */ SwfdecAudio * audio; /* the audio we play back */ snd_pcm_t * pcm; /* the pcm we play back to */ GSource ** sources; /* sources for writing data */ @@ -193,7 +193,7 @@ swfdec_stream_start (Stream *stream) } static void -swfdec_stream_open (Sound *sound, SwfdecAudio *audio) +swfdec_stream_open (SwfdecPlayback *sound, SwfdecAudio *audio) { Stream *stream; snd_pcm_t *ret; @@ -274,7 +274,7 @@ swfdec_stream_close (Stream *stream) static void advance_before (SwfdecPlayer *player, guint msecs, guint audio_samples, gpointer data) { - Sound *sound = data; + SwfdecPlayback *sound = data; GList *walk; for (walk = sound->streams; walk; walk = walk->next) { @@ -288,13 +288,13 @@ advance_before (SwfdecPlayer *player, gu } static void -audio_added (SwfdecPlayer *player, SwfdecAudio *audio, Sound *sound) +audio_added (SwfdecPlayer *player, SwfdecAudio *audio, SwfdecPlayback *sound) { swfdec_stream_open (sound, audio); } static void -audio_removed (SwfdecPlayer *player, SwfdecAudio *audio, Sound *sound) +audio_removed (SwfdecPlayer *player, SwfdecAudio *audio, SwfdecPlayback *sound) { GList *walk; @@ -308,16 +308,16 @@ audio_removed (SwfdecPlayer *player, Swf g_assert_not_reached (); } -gpointer +SwfdecPlayback * swfdec_playback_open (SwfdecPlayer *player, GMainContext *context) { - Sound *sound; + SwfdecPlayback *sound; const GList *walk; g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL); g_return_val_if_fail (context != NULL, NULL); - sound = g_new0 (Sound, 1); + sound = g_new0 (SwfdecPlayback, 1); sound->player = g_object_ref (player); g_signal_connect (player, "advance", G_CALLBACK (advance_before), sound); g_signal_connect (player, "audio-added", G_CALLBACK (audio_added), sound); @@ -331,9 +331,8 @@ swfdec_playback_open (SwfdecPlayer *play } void -swfdec_playback_close (gpointer data) +swfdec_playback_close (SwfdecPlayback *sound) { - Sound *sound = data; #define REMOVE_HANDLER_FULL(obj,func,data,count) G_STMT_START {\ if (g_signal_handlers_disconnect_by_func ((obj), \ G_CALLBACK (func), (data)) != (count)) { \ diff --git a/libswfdec-gtk/swfdec_playback_none.c b/libswfdec-gtk/swfdec_playback_none.c index 6464a4a..79651d6 100644 --- a/libswfdec-gtk/swfdec_playback_none.c +++ b/libswfdec-gtk/swfdec_playback_none.c @@ -25,14 +25,14 @@ /* STUBS ONLY - audio is disabled */ -gpointer +SwfdecPlayback * swfdec_playback_open (SwfdecPlayer *player, GMainContext *context) { return GINT_TO_POINTER (-1); } void -swfdec_playback_close (gpointer sound) +swfdec_playback_close (SwfdecPlayback *sound) { g_assert (sound == GINT_TO_POINTER (-1)); } diff-tree 5c55ebf25f01e1e43276df79e1ca08a5decd2f05 (from d88f4665b965a124dad44a70fa1ca859340cd59c) Author: Benjamin Otte <otte@gnome.org> Date: Mon Mar 26 16:51:19 2007 +0200 hook up libswfdec-gtk diff --git a/doc/Makefile.am b/doc/Makefile.am index fdb3962..d373503 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -25,7 +25,7 @@ DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sg DOC_SOURCE_DIR=../libswfdec # Extra options to pass to gtkdoc-scangobj. Not normally needed. -SCANGOBJ_OPTIONS=--type-init-func="swfdec_init()" +SCANGOBJ_OPTIONS=--type-init-func="swfdec_init(); gtk_init (NULL, NULL);" # Extra options to supply to gtkdoc-scan. # e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" @@ -46,8 +46,8 @@ FIXXREF_OPTIONS # Used for dependencies. The docs will be rebuilt if any of these change. # e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h # e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c -HFILE_GLOB=$(top_srcdir)/libswfdec/*.h -CFILE_GLOB=$(top_srcdir)/libswfdec/*.c +HFILE_GLOB=$(top_srcdir)/libswfdec/*.h $(top_srcdir)/libswfdec-gtk/*.h +CFILE_GLOB=$(top_srcdir)/libswfdec/*.c $(top_srcdir)/libswfdec-gtk/*.c # Header files to ignore when scanning. # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h @@ -108,6 +108,9 @@ IGNORE_HFILES= \ swfdec_video_movie.h \ swfdec_xml.h +EXTRA_HFILES = \ + ../libswfdec-gtk/swfdec_gtk_widget.h + # Images to copy into HTML directory. # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png HTML_IMAGES@@ -126,8 +129,8 @@ expand_content_files # signals and properties. # e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) # e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) -INCLUDES=$(SWFDEC_CFLAGS) $(CAIRO_CFLAGS) -GTKDOC_LIBS=$(SWFDEC_LIBS) +INCLUDES=$(SWFDEC_GTK_CFLAGS) $(CAIRO_CFLAGS) +GTKDOC_LIBS=$(SWFDEC_GTK_LIBS) # This includes the standard gtk-doc make rules, copied by gtkdocize. include $(top_srcdir)/gtk-doc.make diff --git a/doc/swfdec-docs.sgml b/doc/swfdec-docs.sgml index 64e00e5..432547b 100644 --- a/doc/swfdec-docs.sgml +++ b/doc/swfdec-docs.sgml @@ -7,7 +7,11 @@ </bookinfo> <chapter> - <title>Public API</title> + <title>Swfdec Gtk library</title> + <xi:include href="xml/SwfdecGtkWidget.xml"/> + </chapter> + <chapter> + <title>Swfdec library</title> <xi:include href="xml/Enumerations.xml"/> <xi:include href="xml/SwfdecPlayer.xml"/> <xi:include href="xml/SwfdecAudio.xml"/> diff --git a/doc/swfdec-sections.txt b/doc/swfdec-sections.txt index f8a4514..942f73c 100644 --- a/doc/swfdec-sections.txt +++ b/doc/swfdec-sections.txt @@ -77,7 +77,7 @@ SwfdecBufferQueue swfdec_buffer_new swfdec_buffer_new_and_alloc swfdec_buffer_new_and_alloc0 -swfdec_buffer_new_with_data +swfdec_buffer_new_for_data swfdec_buffer_new_subbuffer swfdec_buffer_new_from_file swfdec_buffer_ref @@ -105,3 +105,31 @@ swfdec_loader_data_type_get_type SWFDEC_TYPE_MOUSE_CURSOR swfdec_mouse_cursor_get_type </SECTION> + + +<SECTION> +<FILE>SwfdecGtkWidget</FILE> +<TITLE>SwfdecGtkWidget</TITLE> +SwfdecGtkWidget +swfdec_gtk_widget_new +swfdec_gtk_widget_get_player +swfdec_gtk_widget_set_player +swfdec_gtk_widget_get_current_scale +swfdec_gtk_widget_get_scale +swfdec_gtk_widget_set_scale +swfdec_gtk_widget_get_interactive +swfdec_gtk_widget_set_interactive +swfdec_gtk_widget_get_renderer +swfdec_gtk_widget_uses_renderer +swfdec_gtk_widget_set_renderer +swfdec_gtk_widget_unset_renderer +<SUBSECTION Standard> +swfdec_gtk_widget_get_type +SwfdecGtkWidgetClass +SwfdecGtkWidgetPrivate +SWFDEC_GTK_WIDGET +SWFDEC_GTK_WIDGET_CLASS +SWFDEC_IS_GTK_WIDGET +SWFDEC_IS_GTK_WIDGET_CLASS +SWFDEC_TYPE_GTK_WIDGET +</SECTION> diff-tree d88f4665b965a124dad44a70fa1ca859340cd59c (from ad94392c93f6855d01fff706ba7d4827e01082c8) Author: Benjamin Otte <otte@gnome.org> Date: Mon Mar 26 16:50:57 2007 +0200 apparently I can't name functions correctly diff --git a/libswfdec-gtk/swfdec_gtk_widget.c b/libswfdec-gtk/swfdec_gtk_widget.c index 3f393cc..84bddf1 100644 --- a/libswfdec-gtk/swfdec_gtk_widget.c +++ b/libswfdec-gtk/swfdec_gtk_widget.c @@ -543,7 +543,7 @@ swfdec_gtk_widget_set_renderer (SwfdecGt } void -swfdec_gtk_player_unset_renderer (SwfdecGtkWidget *widget) +swfdec_gtk_widget_unset_renderer (SwfdecGtkWidget *widget) { g_return_if_fail (SWFDEC_IS_GTK_WIDGET (widget)); diff --git a/libswfdec-gtk/swfdec_gtk_widget.h b/libswfdec-gtk/swfdec_gtk_widget.h index a808da3..fa9580e 100644 --- a/libswfdec-gtk/swfdec_gtk_widget.h +++ b/libswfdec-gtk/swfdec_gtk_widget.h @@ -60,7 +60,7 @@ double swfdec_gtk_widget_get_scale (Sw double swfdec_gtk_widget_get_current_scale (SwfdecGtkWidget * widget); void swfdec_gtk_widget_set_renderer (SwfdecGtkWidget * widget, cairo_surface_type_t renderer); -void swfdec_gtk_player_unset_renderer (SwfdecGtkWidget * widget); +void swfdec_gtk_widget_unset_renderer (SwfdecGtkWidget * widget); cairo_surface_type_t swfdec_gtk_widget_get_renderer (SwfdecGtkWidget * widget); gboolean swfdec_gtk_widget_uses_renderer (SwfdecGtkWidget * widget); diff-tree ad94392c93f6855d01fff706ba7d4827e01082c8 (from 5956357f5cba90936a1aa15934957155400d272c) Author: Benjamin Otte <otte@gnome.org> Date: Mon Mar 26 16:26:46 2007 +0200 prepare the gtk widget for exporting its API diff --git a/libswfdec-gtk/Makefile.am b/libswfdec-gtk/Makefile.am index c9756be..1c35f3e 100644 --- a/libswfdec-gtk/Makefile.am +++ b/libswfdec-gtk/Makefile.am @@ -13,12 +13,11 @@ lib_LTLIBRARIES = libswfdec-gtk-@SWFDEC_ libswfdec_gtk_@SWFDEC_MAJORMINOR@_la_SOURCES = \ swfdec_playback.c \ swfdec_source.c \ - swfdec_widget.c + swfdec_gtk_widget.c noinst_HEADERS = \ swfdec_playback.h \ - swfdec_source.h \ - swfdec_widget.h + swfdec_source.h libswfdec_gtk_@SWFDEC_MAJORMINOR@_la_CFLAGS = \ $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(GTK_CFLAGS) $(AUDIO_CFLAGS) \ @@ -27,6 +26,9 @@ libswfdec_gtk_@SWFDEC_MAJORMINOR@_la_LDF -version-info $(SWFDEC_LIBVERSION) \ -export-symbols-regex '^(swfdec_.*)' \ $(GTK_LIBS) $(SWFDEC_LIBS) $(AUDIO_LIBS) +libswfdec_@SWFDEC_MAJORMINOR@includedir = $(includedir)/swfdec-@SWFDEC_MAJORMINOR@/libswfdec +libswfdec_@SWFDEC_MAJORMINOR@include_HEADERS = \ + swfdec_gtk_widget.h endif diff --git a/libswfdec-gtk/swfdec_gtk_widget.c b/libswfdec-gtk/swfdec_gtk_widget.c new file mode 100644 index 0000000..3f393cc --- /dev/null +++ b/libswfdec-gtk/swfdec_gtk_widget.c @@ -0,0 +1,571 @@ +/* Swfdec + * Copyright (C) 2006-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 <math.h> +#include <libswfdec-gtk/swfdec_gtk_widget.h> + +struct _SwfdecGtkWidgetPrivate +{ + SwfdecPlayer * player; /* the video we play */ + + double real_scale; /* the real scale factor used */ + double set_scale; /* the set scale factor of the video */ + gboolean renderer_set; /* TRUE if a special renderer has been set */ + cairo_surface_type_t renderer; /* the renderer that was set */ + gboolean interactive; /* if this gtk_widget propagates keyboard and mouse events */ + + int button; /* status of mouse button in displayed movie */ +}; + +enum { + PROP_0, + PROP_PLAYER, + PROP_INTERACTIVE, + PROP_RENDERER_SET, + PROP_RENDERER +}; + +G_DEFINE_TYPE (SwfdecGtkWidget, swfdec_gtk_widget, GTK_TYPE_WIDGET) + +static gboolean +swfdec_gtk_widget_motion_notify (GtkWidget *gtkwidget, GdkEventMotion *event) +{ + SwfdecGtkWidget *widget = SWFDEC_GTK_WIDGET (gtkwidget); + SwfdecGtkWidgetPrivate *priv = widget->priv; + int x, y; + + gdk_window_get_pointer (gtkwidget->window, &x, &y, NULL); + + if (priv->interactive) + swfdec_player_handle_mouse (priv->player, + x / priv->real_scale, y / priv->real_scale, priv->button); + + return FALSE; +} + +static gboolean +swfdec_gtk_widget_leave_notify (GtkWidget *gtkwidget, GdkEventCrossing *event) +{ + SwfdecGtkWidget *widget = SWFDEC_GTK_WIDGET (gtkwidget); + SwfdecGtkWidgetPrivate *priv = widget->priv; + + if (priv->interactive) { + priv->button = 0; + swfdec_player_handle_mouse (priv->player, + event->x / priv->real_scale, event->y / priv->real_scale, 0); + } + return FALSE; +} + +static gboolean +swfdec_gtk_widget_button_press (GtkWidget *gtkwidget, GdkEventButton *event) +{ + SwfdecGtkWidget *widget = SWFDEC_GTK_WIDGET (gtkwidget); + SwfdecGtkWidgetPrivate *priv = widget->priv; + + if (event->button == 1) { + priv->button = 1; + if (priv->interactive) + swfdec_player_handle_mouse (priv->player, + event->x / priv->real_scale, event->y / priv->real_scale, 1); + } + return FALSE; +} + +static gboolean +swfdec_gtk_widget_button_release (GtkWidget *gtkwidget, GdkEventButton *event) +{ + SwfdecGtkWidget *widget = SWFDEC_GTK_WIDGET (gtkwidget); + SwfdecGtkWidgetPrivate *priv = widget->priv; + + if (event->button == 1) { + priv->button = 0; + if (priv->interactive) + swfdec_player_handle_mouse (priv->player, + event->x / priv->real_scale, event->y / priv->real_scale, 0); + } + return FALSE; +} + +static cairo_surface_t * +swfdec_gtk_widget_create_renderer (cairo_surface_type_t type, int width, int height) +{ + switch (type) { + case CAIRO_SURFACE_TYPE_IMAGE: + return cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); + default: + break; + } + + return NULL; +} + +static gboolean +swfdec_gtk_widget_expose (GtkWidget *gtkwidget, GdkEventExpose *event) +{ + SwfdecGtkWidget *widget = SWFDEC_GTK_WIDGET (gtkwidget); + SwfdecGtkWidgetPrivate *priv = widget->priv; + cairo_t *cr; + cairo_surface_t *surface = NULL; + + if (event->window != gtkwidget->window) + return FALSE; + + if (!priv->renderer_set || + (surface = swfdec_gtk_widget_create_renderer (priv->renderer, + event->area.width, event->area.height)) == NULL) { + cr = gdk_cairo_create (gtkwidget->window); + } else { + cr = cairo_create (surface); + cairo_translate (cr, -event->area.x, -event->area.y); + } + cairo_scale (cr, priv->real_scale, priv->real_scale); + swfdec_player_render (priv->player, cr, + event->area.x / priv->real_scale, event->area.y / priv->real_scale, + event->area.width / priv->real_scale, event->area.height / priv->real_scale); + cairo_show_page (cr); + cairo_destroy (cr); + + if (surface) { + cairo_t *crw = gdk_cairo_create (gtkwidget->window); + cairo_set_source_surface (crw, surface, event->area.x, event->area.y); + cairo_paint (crw); + cairo_destroy (crw); + cairo_surface_destroy (surface); + } + + return FALSE; +} + +static void +swfdec_gtk_widget_get_property (GObject *object, guint param_id, GValue *value, + GParamSpec * pspec) +{ + SwfdecGtkWidget *widget = SWFDEC_GTK_WIDGET (object); + SwfdecGtkWidgetPrivate *priv = widget->priv; + + switch (param_id) { + case PROP_PLAYER: + g_value_set_object (value, priv->player); + break; + case PROP_INTERACTIVE: + g_value_set_boolean (value, priv->interactive); + break; + case PROP_RENDERER_SET: + g_value_set_boolean (value, priv->renderer_set); + break; + case PROP_RENDERER: + g_value_set_uint (value, priv->renderer); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +swfdec_gtk_widget_set_property (GObject *object, guint param_id, const GValue *value, + GParamSpec *pspec) +{ + SwfdecGtkWidget *widget = SWFDEC_GTK_WIDGET (object); + SwfdecGtkWidgetPrivate *priv = widget->priv; + + switch (param_id) { + case PROP_PLAYER: + swfdec_gtk_widget_set_player (widget, g_value_get_object (value)); + break; + case PROP_INTERACTIVE: + swfdec_gtk_widget_set_interactive (widget, g_value_get_boolean (value)); + break; + case PROP_RENDERER_SET: + priv->renderer_set = g_value_get_boolean (value); + gtk_widget_queue_draw (GTK_WIDGET (widget)); + break; + case PROP_RENDERER: + priv->renderer = g_value_get_uint (value); + if (priv->renderer_set) + gtk_widget_queue_draw (GTK_WIDGET (widget)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +swfdec_gtk_widget_dispose (GObject *object) +{ + SwfdecGtkWidget *widget = SWFDEC_GTK_WIDGET (object); + + swfdec_gtk_widget_set_player (widget, NULL); + + G_OBJECT_CLASS (swfdec_gtk_widget_parent_class)->dispose (object); +} + +static void +swfdec_gtk_widget_size_allocate (GtkWidget *gtkwidget, GtkAllocation *allocation) +{ + double scale; + int w, h; + SwfdecGtkWidget *widget = SWFDEC_GTK_WIDGET (gtkwidget); + SwfdecGtkWidgetPrivate *priv = widget->priv; + + gtkwidget->allocation = *allocation; + + swfdec_player_get_image_size (priv->player, &w, &h); + if (priv->set_scale > 0.0) { + scale = priv->set_scale; + } else if (priv->player == NULL) { + scale = 1.0; + } else { + if (w != 0 && h != 0) + scale = MIN ((double) allocation->width / w, (double) allocation->height / h); + else + scale = 1.0; + } + w = ceil (w * scale); + h = ceil (h * scale); + if (w > allocation->width) + w = allocation->width; + if (h > allocation->height) + h = allocation->height; + + if (GTK_WIDGET_REALIZED (gtkwidget)) { + gdk_window_move_resize (gtkwidget->window, + allocation->x + (allocation->width - w) / 2, + allocation->y + (allocation->height - h) / 2, + w, h); + } + priv->real_scale = scale; +} + +static void +swfdec_gtk_widget_size_request (GtkWidget *gtkwidget, GtkRequisition *req) +{ + double scale; + SwfdecGtkWidget * widget = SWFDEC_GTK_WIDGET (gtkwidget); + SwfdecGtkWidgetPrivate *priv = widget->priv; + + if (priv->player == NULL) { + req->width = req->height = 0; + } else { + swfdec_player_get_image_size (priv->player, + &req->width, &req->height); + } + if (priv->set_scale != 0.0) + scale = priv->set_scale; + else + scale = 1.0; + req->width = ceil (req->width * scale); + req->height = ceil (req->height * scale); +} + +static void +swfdec_gtk_widget_update_cursor (SwfdecGtkWidget *widget) +{ + GdkWindow *window = GTK_WIDGET (widget)->window; + GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (widget)); + SwfdecGtkWidgetPrivate *priv = widget->priv; + SwfdecMouseCursor swfcursor; + GdkCursor *cursor; + + if (window == NULL) + return; + g_object_get (priv->player, "mouse-cursor", &swfcursor, NULL); + + switch (swfcursor) { + case SWFDEC_MOUSE_CURSOR_NONE: + { + GdkBitmap *bitmap; + GdkColor color = { 0, 0, 0, 0 }; + char data = 0; + + bitmap = gdk_bitmap_create_from_data (window, &data, 1, 1); + if (bitmap == NULL) + return; + cursor = gdk_cursor_new_from_pixmap (bitmap, bitmap, &color, &color, 0, 0); + gdk_window_set_cursor (window, cursor); + gdk_cursor_unref (cursor); + g_object_unref (bitmap); + break; + } + case SWFDEC_MOUSE_CURSOR_TEXT: + cursor = gdk_cursor_new_for_display (display, GDK_XTERM); + gdk_window_set_cursor (window, cursor); + gdk_cursor_unref (cursor); + break; + case SWFDEC_MOUSE_CURSOR_CLICK: + cursor = gdk_cursor_new_for_display (display, GDK_HAND2); + gdk_window_set_cursor (window, cursor); + gdk_cursor_unref (cursor); + break; + case SWFDEC_MOUSE_CURSOR_NORMAL: + cursor = gdk_cursor_new_for_display (display, GDK_LEFT_PTR); + gdk_window_set_cursor (window, cursor); + gdk_cursor_unref (cursor); + break; + default: + g_warning ("invalid cursor %d", (int) swfcursor); + gdk_window_set_cursor (window, NULL); + break; + } +} + +static void +swfdec_gtk_widget_realize (GtkWidget *widget) +{ + GdkWindowAttr attributes; + gint attributes_mask; + + GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); + + attributes.window_type = GDK_WINDOW_CHILD; + attributes.x = widget->allocation.x; + attributes.y = widget->allocation.y; + attributes.width = widget->allocation.width; + attributes.height = widget->allocation.height; + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.event_mask = gtk_widget_get_events (widget); + attributes.event_mask |= GDK_EXPOSURE_MASK | + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_LEAVE_NOTIFY_MASK | + GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK; + + attributes_mask = GDK_WA_X | GDK_WA_Y; + + widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), + &attributes, attributes_mask); + gdk_window_set_user_data (widget->window, widget); + + widget->style = gtk_style_attach (widget->style, widget->window); + + if (SWFDEC_GTK_WIDGET (widget)->priv->player) { + swfdec_gtk_widget_update_cursor (SWFDEC_GTK_WIDGET (widget)); + } +} + +static void +swfdec_gtk_widget_class_init (SwfdecGtkWidgetClass * g_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (g_class); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (g_class); + + object_class->dispose = swfdec_gtk_widget_dispose; + object_class->get_property = swfdec_gtk_widget_get_property; + object_class->set_property = swfdec_gtk_widget_set_property; + + g_object_class_install_property (object_class, PROP_PLAYER, + g_param_spec_object ("player", "player", "player that is displayed", + SWFDEC_TYPE_PLAYER, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, PROP_INTERACTIVE, + g_param_spec_boolean ("interactive", "interactive", "if mouse events are processed", + TRUE, G_PARAM_READWRITE)); + g_object_class_install_property (object_class, PROP_RENDERER_SET, + g_param_spec_boolean ("renderer-set", "renderer set", "if an intermediate renderer should be used", + TRUE, G_PARAM_READWRITE)); + /* FIXME: get an enum for cairo_surface_type_t */ + g_object_class_install_property (object_class, PROP_RENDERER, + g_param_spec_uint ("renderer", "renderer", "cairo_surface_type_t of intermediate renderer to use", + 0, G_MAXUINT, CAIRO_SURFACE_TYPE_IMAGE, G_PARAM_READWRITE)); + + widget_class->realize = swfdec_gtk_widget_realize; + widget_class->size_request = swfdec_gtk_widget_size_request; + widget_class->size_allocate = swfdec_gtk_widget_size_allocate; + widget_class->expose_event = swfdec_gtk_widget_expose; + widget_class->button_press_event = swfdec_gtk_widget_button_press; + widget_class->button_release_event = swfdec_gtk_widget_button_release; + widget_class->motion_notify_event = swfdec_gtk_widget_motion_notify; + widget_class->leave_notify_event = swfdec_gtk_widget_leave_notify; + + g_type_class_add_private (object_class, sizeof (SwfdecGtkWidgetPrivate)); +} + +static void +swfdec_gtk_widget_init (SwfdecGtkWidget * widget) +{ + SwfdecGtkWidgetPrivate *priv; + + priv = widget->priv = G_TYPE_INSTANCE_GET_PRIVATE (widget, SWFDEC_TYPE_GTK_WIDGET, SwfdecGtkWidgetPrivate); + + priv->real_scale = 1.0; + priv->interactive = TRUE; + priv->renderer = CAIRO_SURFACE_TYPE_IMAGE; +} + +static void +swfdec_gtk_widget_invalidate_cb (SwfdecPlayer *player, double x, double y, + double width, double height, SwfdecGtkWidget *widget) +{ + SwfdecGtkWidgetPrivate *priv = widget->priv; + GdkRectangle rect; + + if (!GTK_WIDGET_REALIZED (widget)) + return; + rect.x = floor (x * priv->real_scale); + rect.y = floor (y * priv->real_scale); + rect.width = ceil ((x + width) * priv->real_scale) - rect.x; + rect.height = ceil ((y + height) * priv->real_scale) - rect.y; + gdk_window_invalidate_rect (GTK_WIDGET (widget)->window, &rect, FALSE); +} + +static void +swfdec_gtk_widget_notify_cb (SwfdecPlayer *player, GParamSpec *pspec, SwfdecGtkWidget *widget) +{ + if (g_str_equal (pspec->name, "mouse-cursor")) { + swfdec_gtk_widget_update_cursor (widget); + } else if (g_str_equal (pspec->name, "initialized")) { + gtk_widget_queue_resize (GTK_WIDGET (widget)); + } +} + +void +swfdec_gtk_widget_set_player (SwfdecGtkWidget *widget, SwfdecPlayer *player) +{ + SwfdecGtkWidgetPrivate *priv = widget->priv; + + g_return_if_fail (SWFDEC_IS_GTK_WIDGET (widget)); + g_return_if_fail (player == NULL || SWFDEC_IS_PLAYER (player)); + + if (priv->player) { + g_signal_handlers_disconnect_by_func (priv->player, swfdec_gtk_widget_invalidate_cb, widget); + g_signal_handlers_disconnect_by_func (priv->player, swfdec_gtk_widget_notify_cb, widget); + g_object_unref (priv->player); + } + priv->player = player; + if (player) { + g_signal_connect (player, "invalidate", G_CALLBACK (swfdec_gtk_widget_invalidate_cb), widget); + g_signal_connect (player, "notify", G_CALLBACK (swfdec_gtk_widget_notify_cb), widget); + g_object_ref (player); + swfdec_gtk_widget_update_cursor (widget); + } else { + if (GTK_WIDGET (widget)->window) + gdk_window_set_cursor (GTK_WIDGET (widget)->window, NULL); + } + gtk_widget_queue_resize (GTK_WIDGET (widget)); + g_object_notify (G_OBJECT (widget), "player"); +} + +SwfdecPlayer * +swfdec_gtk_widget_get_player (SwfdecGtkWidget *widget) +{ + g_return_val_if_fail (SWFDEC_IS_GTK_WIDGET (widget), NULL); + + return widget->priv->player; +} + +GtkWidget * +swfdec_gtk_widget_new (SwfdecPlayer *player) +{ + SwfdecGtkWidget *widget; + + g_return_val_if_fail (player == NULL || SWFDEC_IS_PLAYER (player), NULL); + + widget = g_object_new (SWFDEC_TYPE_GTK_WIDGET, "player", player, NULL); + + return GTK_WIDGET (widget); +} + +void +swfdec_gtk_widget_set_scale (SwfdecGtkWidget *widget, double scale) +{ + g_return_if_fail (SWFDEC_IS_GTK_WIDGET (widget)); + g_return_if_fail (scale >= 0.0); + + widget->priv->set_scale = scale; + gtk_widget_queue_resize (GTK_WIDGET (widget)); +} + +double +swfdec_gtk_widget_get_scale (SwfdecGtkWidget *widget) +{ + g_return_val_if_fail (SWFDEC_IS_GTK_WIDGET (widget), 1.0); + + return widget->priv->set_scale; +} + +double +swfdec_gtk_widget_get_current_scale (SwfdecGtkWidget *widget) +{ + g_return_val_if_fail (SWFDEC_IS_GTK_WIDGET (widget), 1.0); + + return widget->priv->real_scale; +} + +void +swfdec_gtk_widget_set_interactive (SwfdecGtkWidget *widget, gboolean interactive) +{ + g_return_if_fail (SWFDEC_IS_GTK_WIDGET (widget)); + + widget->priv->interactive = interactive; +} + +gboolean +swfdec_gtk_widget_get_interactive (SwfdecGtkWidget *widget) +{ + g_return_val_if_fail (SWFDEC_IS_GTK_WIDGET (widget), FALSE); + + return widget->priv->interactive; +} + +void +swfdec_gtk_widget_set_renderer (SwfdecGtkWidget *widget, cairo_surface_type_t renderer) +{ + g_return_if_fail (SWFDEC_IS_GTK_WIDGET (widget)); + + widget->priv->renderer = renderer; + if (widget->priv->renderer_set == FALSE) { + widget->priv->renderer_set = TRUE; + g_object_notify (G_OBJECT (widget), "renderer-set"); + } + g_object_notify (G_OBJECT (widget), "renderer"); +} + +void +swfdec_gtk_player_unset_renderer (SwfdecGtkWidget *widget) +{ + g_return_if_fail (SWFDEC_IS_GTK_WIDGET (widget)); + + if (widget->priv->renderer_set == FALSE) + return; + widget->priv->renderer_set = FALSE; + g_object_notify (G_OBJECT (widget), "renderer-set"); +} + +cairo_surface_type_t +swfdec_gtk_widget_get_renderer (SwfdecGtkWidget *widget) +{ + g_return_val_if_fail (SWFDEC_IS_GTK_WIDGET (widget), CAIRO_SURFACE_TYPE_IMAGE); + + return widget->priv->renderer; +} + +gboolean +swfdec_gtk_widget_uses_renderer (SwfdecGtkWidget *widget) +{ + g_return_val_if_fail (SWFDEC_IS_GTK_WIDGET (widget), FALSE); + + return widget->priv->renderer_set; +} + diff --git a/libswfdec-gtk/swfdec_gtk_widget.h b/libswfdec-gtk/swfdec_gtk_widget.h new file mode 100644 index 0000000..a808da3 --- /dev/null +++ b/libswfdec-gtk/swfdec_gtk_widget.h @@ -0,0 +1,72 @@ +/* Swfdec + * Copyright (C) 2006-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_GTK_WIDGET_H_ +#define _SWFDEC_GTK_WIDGET_H_ + +#include <gtk/gtk.h> +#include <libswfdec/swfdec.h> + +G_BEGIN_DECLS + +typedef struct _SwfdecGtkWidget SwfdecGtkWidget; +typedef struct _SwfdecGtkWidgetClass SwfdecGtkWidgetClass; +typedef struct _SwfdecGtkWidgetPrivate SwfdecGtkWidgetPrivate; + +#define SWFDEC_TYPE_GTK_WIDGET (swfdec_gtk_widget_get_type()) +#define SWFDEC_IS_GTK_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_GTK_WIDGET)) +#define SWFDEC_IS_GTK_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_GTK_WIDGET)) +#define SWFDEC_GTK_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_GTK_WIDGET, SwfdecGtkWidget)) +#define SWFDEC_GTK_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_GTK_WIDGET, SwfdecGtkWidgetClass)) + +struct _SwfdecGtkWidget +{ + GtkWidget widget; + + SwfdecGtkWidgetPrivate * priv; +}; + +struct _SwfdecGtkWidgetClass +{ + GtkWidgetClass widget_class; +}; + +GType swfdec_gtk_widget_get_type (void); + +GtkWidget * swfdec_gtk_widget_new (SwfdecPlayer * player); + +void swfdec_gtk_widget_set_player (SwfdecGtkWidget * widget, + SwfdecPlayer * player); +SwfdecPlayer * swfdec_gtk_widget_get_player (SwfdecGtkWidget * widget); +void swfdec_gtk_widget_set_scale (SwfdecGtkWidget * widget, + double scale); +double swfdec_gtk_widget_get_scale (SwfdecGtkWidget * widget); +double swfdec_gtk_widget_get_current_scale (SwfdecGtkWidget * widget); +void swfdec_gtk_widget_set_renderer (SwfdecGtkWidget * widget, + cairo_surface_type_t renderer); +void swfdec_gtk_player_unset_renderer (SwfdecGtkWidget * widget); +cairo_surface_type_t + swfdec_gtk_widget_get_renderer (SwfdecGtkWidget * widget); +gboolean swfdec_gtk_widget_uses_renderer (SwfdecGtkWidget * widget); +void swfdec_gtk_widget_set_interactive (SwfdecGtkWidget * widget, + gboolean interactive); +gboolean swfdec_gtk_widget_get_interactive (SwfdecGtkWidget * widget); + +G_END_DECLS +#endif diff --git a/libswfdec-gtk/swfdec_widget.c b/libswfdec-gtk/swfdec_widget.c deleted file mode 100644 index 99b414e..0000000 --- a/libswfdec-gtk/swfdec_widget.c +++ /dev/null @@ -1,450 +0,0 @@ -/* 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 <math.h> -#include "swfdec_widget.h" - -enum { - PROP_0, - PROP_PLAYER -}; - -G_DEFINE_TYPE (SwfdecWidget, swfdec_widget, GTK_TYPE_WIDGET) - -static gboolean -swfdec_widget_motion_notify (GtkWidget *gtkwidget, GdkEventMotion *event) -{ - SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget); - int x, y; - - gdk_window_get_pointer (gtkwidget->window, &x, &y, NULL); - - if (widget->interactive) - swfdec_player_handle_mouse (widget->player, - x / widget->real_scale, y / widget->real_scale, widget->button); - - return FALSE; -} - -static gboolean -swfdec_widget_leave_notify (GtkWidget *gtkwidget, GdkEventCrossing *event) -{ - SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget); - - if (widget->interactive) { - widget->button = 0; - swfdec_player_handle_mouse (widget->player, - event->x / widget->real_scale, event->y / widget->real_scale, 0); - } - return FALSE; -} - -static gboolean -swfdec_widget_button_press (GtkWidget *gtkwidget, GdkEventButton *event) -{ - SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget); - - if (event->button == 1) { - widget->button = 1; - if (widget->interactive) - swfdec_player_handle_mouse (widget->player, - event->x / widget->real_scale, event->y / widget->real_scale, 1); - } - return FALSE; -} - -static gboolean -swfdec_widget_button_release (GtkWidget *gtkwidget, GdkEventButton *event) -{ - SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget); - - if (event->button == 1) { - widget->button = 0; - if (widget->interactive) - swfdec_player_handle_mouse (widget->player, - event->x / widget->real_scale, event->y / widget->real_scale, 0); - } - return FALSE; -} - -static gboolean -swfdec_widget_expose (GtkWidget *gtkwidget, GdkEventExpose *event) -{ - SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget); - cairo_t *cr; - cairo_surface_t *surface = NULL; - - if (event->window != gtkwidget->window) - return FALSE; - - if (!widget->use_image) { - cr = gdk_cairo_create (gtkwidget->window); - } else { - surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, - event->area.width, event->area.height); - cr = cairo_create (surface); - cairo_translate (cr, -event->area.x, -event->area.y); - cairo_surface_destroy (surface); - } - cairo_scale (cr, widget->real_scale, widget->real_scale); - swfdec_player_render (widget->player, cr, - event->area.x / widget->real_scale, event->area.y / widget->real_scale, - event->area.width / widget->real_scale, event->area.height / widget->real_scale); - if (widget->use_image) { - cairo_t *crw = gdk_cairo_create (gtkwidget->window); - cairo_set_source_surface (crw, surface, event->area.x, event->area.y); - cairo_paint (crw); - cairo_destroy (crw); - } - - cairo_destroy (cr); - - return FALSE; -} - -static void -swfdec_widget_get_property (GObject *object, guint param_id, GValue *value, - GParamSpec * pspec) -{ - SwfdecWidget *widget = SWFDEC_WIDGET (object); - - switch (param_id) { - case PROP_PLAYER: - g_value_set_object (value, widget->player); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } -} - -static void -swfdec_widget_set_property (GObject *object, guint param_id, const GValue *value, - GParamSpec *pspec) -{ - SwfdecWidget *widget = SWFDEC_WIDGET (object); - - switch (param_id) { - case PROP_PLAYER: - swfdec_widget_set_player (widget, g_value_get_object (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } -} - -static void -swfdec_widget_dispose (GObject *object) -{ - SwfdecWidget *widget = SWFDEC_WIDGET (object); - - swfdec_widget_set_player (widget, NULL); - - G_OBJECT_CLASS (swfdec_widget_parent_class)->dispose (object); -} - -static void -swfdec_widget_size_allocate (GtkWidget *gtkwidget, GtkAllocation *allocation) -{ - double scale; - int w, h; - SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget); - - gtkwidget->allocation = *allocation; - - swfdec_player_get_image_size (widget->player, &w, &h); - if (widget->set_scale > 0.0) { - scale = widget->set_scale; - } else if (widget->player == NULL) { - scale = 1.0; - } else { - if (w != 0 && h != 0) - scale = MIN ((double) allocation->width / w, (double) allocation->height / h); - else - scale = 1.0; - } - w = ceil (w * scale); - h = ceil (h * scale); - if (w > allocation->width) - w = allocation->width; - if (h > allocation->height) - h = allocation->height; - - if (GTK_WIDGET_REALIZED (gtkwidget)) { - gdk_window_move_resize (gtkwidget->window, - allocation->x + (allocation->width - w) / 2, - allocation->y + (allocation->height - h) / 2, - w, h); - } - widget->real_scale = scale; -} - -static void -swfdec_widget_size_request (GtkWidget *gtkwidget, GtkRequisition *req) -{ - double scale; - SwfdecWidget * widget = SWFDEC_WIDGET (gtkwidget); - - if (widget->player == NULL) { - req->width = req->height = 0; - } else { - swfdec_player_get_image_size (widget->player, - &req->width, &req->height); - } - if (widget->set_scale != 0.0) - scale = widget->set_scale; - else - scale = 1.0; - req->width = ceil (req->width * scale); - req->height = ceil (req->height * scale); -} - -static void -swfdec_widget_update_cursor (SwfdecWidget *widget) -{ - GdkWindow *window = GTK_WIDGET (widget)->window; - GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (widget)); - SwfdecMouseCursor swfcursor; - GdkCursor *cursor; - - if (window == NULL) - return; - g_object_get (widget->player, "mouse-cursor", &swfcursor, NULL); - - switch (swfcursor) { - case SWFDEC_MOUSE_CURSOR_NONE: - { - GdkBitmap *bitmap; - GdkColor color = { 0, 0, 0, 0 }; - char data = 0; - - bitmap = gdk_bitmap_create_from_data (window, &data, 1, 1); - if (bitmap == NULL) - return; - cursor = gdk_cursor_new_from_pixmap (bitmap, bitmap, &color, &color, 0, 0); - gdk_window_set_cursor (window, cursor); - gdk_cursor_unref (cursor); - g_object_unref (bitmap); - break; - } - case SWFDEC_MOUSE_CURSOR_TEXT: - cursor = gdk_cursor_new_for_display (display, GDK_XTERM); - gdk_window_set_cursor (window, cursor); - gdk_cursor_unref (cursor); - break; - case SWFDEC_MOUSE_CURSOR_CLICK: - cursor = gdk_cursor_new_for_display (display, GDK_HAND2); - gdk_window_set_cursor (window, cursor); - gdk_cursor_unref (cursor); - break; - case SWFDEC_MOUSE_CURSOR_NORMAL: - cursor = gdk_cursor_new_for_display (display, GDK_LEFT_PTR); - gdk_window_set_cursor (window, cursor); - gdk_cursor_unref (cursor); - break; - default: - g_warning ("invalid cursor %d", (int) swfcursor); - gdk_window_set_cursor (window, NULL); - break; - } -} - -static void -swfdec_widget_realize (GtkWidget *widget) -{ - GdkWindowAttr attributes; - gint attributes_mask; - - GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); - - attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = widget->allocation.x; - attributes.y = widget->allocation.y; - attributes.width = widget->allocation.width; - attributes.height = widget->allocation.height; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.event_mask = gtk_widget_get_events (widget); - attributes.event_mask |= GDK_EXPOSURE_MASK | - GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_LEAVE_NOTIFY_MASK | - GDK_POINTER_MOTION_MASK | - GDK_POINTER_MOTION_HINT_MASK; - - attributes_mask = GDK_WA_X | GDK_WA_Y; - - widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), - &attributes, attributes_mask); - gdk_window_set_user_data (widget->window, widget); - - widget->style = gtk_style_attach (widget->style, widget->window); - - if (SWFDEC_WIDGET (widget)->player) { - swfdec_widget_update_cursor (SWFDEC_WIDGET (widget)); - } -} - -static void -swfdec_widget_class_init (SwfdecWidgetClass * g_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (g_class); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (g_class); - - object_class->dispose = swfdec_widget_dispose; - object_class->get_property = swfdec_widget_get_property; - object_class->set_property = swfdec_widget_set_property; - - g_object_class_install_property (object_class, PROP_PLAYER, - g_param_spec_object ("player", "player", "player that is displayed", - SWFDEC_TYPE_PLAYER, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - widget_class->realize = swfdec_widget_realize; - widget_class->size_request = swfdec_widget_size_request; - widget_class->size_allocate = swfdec_widget_size_allocate; - widget_class->expose_event = swfdec_widget_expose; - widget_class->button_press_event = swfdec_widget_button_press; - widget_class->button_release_event = swfdec_widget_button_release; - widget_class->motion_notify_event = swfdec_widget_motion_notify; - widget_class->leave_notify_event = swfdec_widget_leave_notify; -} - -static void -swfdec_widget_init (SwfdecWidget * widget) -{ - widget->real_scale = 1.0; - widget->interactive = TRUE; -} - -static void -swfdec_widget_invalidate_cb (SwfdecPlayer *player, double x, double y, - double width, double height, SwfdecWidget *widget) -{ - GdkRectangle rect; - - if (!GTK_WIDGET_REALIZED (widget)) - return; - rect.x = floor (x * widget->real_scale); - rect.y = floor (y * widget->real_scale); - rect.width = ceil ((x + width) * widget->real_scale) - rect.x; - rect.height = ceil ((y + height) * widget->real_scale) - rect.y; - gdk_window_invalidate_rect (GTK_WIDGET (widget)->window, &rect, FALSE); -} - -static void -swfdec_widget_notify_cb (SwfdecPlayer *player, GParamSpec *pspec, SwfdecWidget *widget) -{ - if (g_str_equal (pspec->name, "mouse-cursor")) { - swfdec_widget_update_cursor (widget); - } else if (g_str_equal (pspec->name, "initialized")) { - gtk_widget_queue_resize (GTK_WIDGET (widget)); - } -} - -void -swfdec_widget_set_player (SwfdecWidget *widget, SwfdecPlayer *player) -{ - g_return_if_fail (SWFDEC_IS_WIDGET (widget)); - g_return_if_fail (player == NULL || SWFDEC_IS_PLAYER (player)); - - if (widget->player) { - g_signal_handlers_disconnect_by_func (widget->player, swfdec_widget_invalidate_cb, widget); - g_signal_handlers_disconnect_by_func (widget->player, swfdec_widget_notify_cb, widget); - g_object_unref (widget->player); - } - widget->player = player; - if (player) { - g_signal_connect (player, "invalidate", G_CALLBACK (swfdec_widget_invalidate_cb), widget); - g_signal_connect (player, "notify", G_CALLBACK (swfdec_widget_notify_cb), widget); - g_object_ref (player); - swfdec_widget_update_cursor (widget); - } else { - if (GTK_WIDGET (widget)->window) - gdk_window_set_cursor (GTK_WIDGET (widget)->window, NULL); - } - gtk_widget_queue_resize (GTK_WIDGET (widget)); -} - -GtkWidget * -swfdec_widget_new (SwfdecPlayer *player) -{ - SwfdecWidget *widget; - - g_return_val_if_fail (player == NULL || SWFDEC_IS_PLAYER (player), NULL); - - widget = g_object_new (SWFDEC_TYPE_WIDGET, "player", player, NULL); - - return GTK_WIDGET (widget); -} - -void -swfdec_widget_set_scale (SwfdecWidget *widget, double scale) -{ - g_return_if_fail (SWFDEC_IS_WIDGET (widget)); - g_return_if_fail (scale >= 0.0); - - widget->set_scale = scale; - gtk_widget_queue_resize (GTK_WIDGET (widget)); -} - -double -swfdec_widget_get_scale (SwfdecWidget *widget) -{ - g_return_val_if_fail (SWFDEC_IS_WIDGET (widget), 1.0); - - return widget->set_scale; -} - -void -swfdec_widget_set_use_image (SwfdecWidget *widget, gboolean use_image) -{ - g_return_if_fail (SWFDEC_IS_WIDGET (widget)); - - widget->use_image = use_image; - gtk_widget_queue_draw (GTK_WIDGET (widget)); -} - -gboolean -swfdec_widget_get_use_image (SwfdecWidget *widget) -{ - g_return_val_if_fail (SWFDEC_IS_WIDGET (widget), 1.0); - - return widget->use_image; -} - -void -swfdec_widget_set_interactive (SwfdecWidget *widget, gboolean interactive) -{ - g_return_if_fail (SWFDEC_IS_WIDGET (widget)); - - widget->interactive = interactive; -} - -gboolean -swfdec_widget_get_interactive (SwfdecWidget *widget) -{ - g_return_val_if_fail (SWFDEC_IS_WIDGET (widget), FALSE); - - return widget->interactive; -} - diff --git a/libswfdec-gtk/swfdec_widget.h b/libswfdec-gtk/swfdec_widget.h deleted file mode 100644 index 1988f20..0000000 --- a/libswfdec-gtk/swfdec_widget.h +++ /dev/null @@ -1,73 +0,0 @@ -/* 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_WIDGET_H_ -#define _SWFDEC_WIDGET_H_ - -#include <gtk/gtk.h> -#include <libswfdec/swfdec.h> - -G_BEGIN_DECLS - -typedef struct _SwfdecWidget SwfdecWidget; -typedef struct _SwfdecWidgetClass SwfdecWidgetClass; - -#define SWFDEC_TYPE_WIDGET (swfdec_widget_get_type()) -#define SWFDEC_IS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_WIDGET)) -#define SWFDEC_IS_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_WIDGET)) -#define SWFDEC_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_WIDGET, SwfdecWidget)) -#define SWFDEC_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_WIDGET, SwfdecWidgetClass)) - -struct _SwfdecWidget -{ - GtkWidget widget; - - SwfdecPlayer * player; /* the video we play */ - - double real_scale; /* the real scale factor used */ - double set_scale; /* the set scale factor of the video */ - gboolean use_image; /* TRUE to draw to an image first before rendering to Gtk */ - gboolean interactive; /* if this widget propagates keyboard and mouse events */ - - int button; /* status of mouse button in displayed movie */ -}; - -struct _SwfdecWidgetClass -{ - GtkWidgetClass widget_class; -}; - -GType swfdec_widget_get_type (void); - -GtkWidget * swfdec_widget_new (SwfdecPlayer * player); - -void swfdec_widget_set_scale (SwfdecWidget * widget, - double scale); -double swfdec_widget_get_scale (SwfdecWidget * widget); -void swfdec_widget_set_use_image (SwfdecWidget * widget, - gboolean use_image); -gboolean swfdec_widget_get_use_image (SwfdecWidget * widget); -void swfdec_widget_set_interactive (SwfdecWidget * widget, - gboolean interactive); -gboolean swfdec_widget_get_interactive (SwfdecWidget * widget); -void swfdec_widget_set_player (SwfdecWidget * widget, - SwfdecPlayer * player); - -G_END_DECLS -#endif diff --git a/player/swfdebug.c b/player/swfdebug.c index c7f74d1..af7f7dc 100644 --- a/player/swfdebug.c +++ b/player/swfdebug.c @@ -118,9 +118,9 @@ message_display_cb (SwfdecPlayerManager } static void -interrupt_widget_cb (SwfdecPlayerManager *manager, GParamSpec *pspec, SwfdecWidget *widget) +interrupt_widget_cb (SwfdecPlayerManager *manager, GParamSpec *pspec, SwfdecGtkWidget *widget) { - swfdec_widget_set_interactive (widget, + swfdec_gtk_widget_set_interactive (widget, !swfdec_player_manager_get_interrupted (manager)); } @@ -292,8 +292,9 @@ view_swf (SwfdecPlayer *player, double s gtk_paned_add2 (GTK_PANED (hpaned), vbox); widget = swfdec_debug_widget_new (player); - swfdec_widget_set_scale (SWFDEC_WIDGET (widget), scale); - swfdec_widget_set_use_image (SWFDEC_WIDGET (widget), use_image); + swfdec_gtk_widget_set_scale (SWFDEC_GTK_WIDGET (widget), scale); + if (use_image) + swfdec_gtk_widget_set_renderer (SWFDEC_GTK_WIDGET (widget), CAIRO_SURFACE_TYPE_IMAGE); gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, TRUE, 0); signal_auto_connect (manager, "notify::interrupted", G_CALLBACK (interrupt_widget_cb), widget); diff --git a/player/swfdec_debug_widget.c b/player/swfdec_debug_widget.c index df5a9d5..4c7ebcc 100644 --- a/player/swfdec_debug_widget.c +++ b/player/swfdec_debug_widget.c @@ -25,7 +25,7 @@ #include "swfdec_debug_widget.h" -G_DEFINE_TYPE (SwfdecDebugWidget, swfdec_debug_widget, SWFDEC_TYPE_WIDGET) +G_DEFINE_TYPE (SwfdecDebugWidget, swfdec_debug_widget, SWFDEC_TYPE_GTK_WIDGET) static gboolean @@ -53,28 +53,30 @@ swfdec_debug_widget_invalidate_click_are static gboolean swfdec_debug_widget_button_press (GtkWidget *gtkwidget, GdkEventButton *event) { - SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget); + SwfdecGtkWidget *widget = SWFDEC_GTK_WIDGET (gtkwidget); SwfdecDebugWidget *debug = SWFDEC_DEBUG_WIDGET (gtkwidget); if (event->window != gtkwidget->window) return FALSE; - if (event->button == 1 && widget->interactive) { + if (event->button == 1 && swfdec_gtk_widget_get_interactive (widget)) { + double scale = swfdec_gtk_widget_get_scale (widget); + SwfdecPlayer *player = swfdec_gtk_widget_get_player (widget); switch (event->type) { case GDK_BUTTON_PRESS: swfdec_debug_widget_invalidate_click_area (debug); debug->x = event->x; debug->y = event->y; - swfdec_player_handle_mouse (widget->player, - debug->x / widget->real_scale, debug->y / widget->real_scale, - widget->button); + swfdec_player_handle_mouse (player, + debug->x / scale, debug->y / scale, + debug->button); swfdec_debug_widget_invalidate_click_area (debug); break; case GDK_2BUTTON_PRESS: - widget->button = 1 - widget->button; - swfdec_player_handle_mouse (widget->player, - debug->x / widget->real_scale, debug->y / widget->real_scale, - widget->button); + debug->button = 1 - debug->button; + swfdec_player_handle_mouse (player, + debug->x / scale, debug->y / scale, + debug->button); swfdec_debug_widget_invalidate_click_area (debug); break; default: @@ -93,7 +95,6 @@ swfdec_debug_widget_button_release (GtkW static gboolean swfdec_debug_widget_expose (GtkWidget *gtkwidget, GdkEventExpose *event) { - SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget); SwfdecDebugWidget *debug = SWFDEC_DEBUG_WIDGET (gtkwidget); cairo_t *cr; @@ -106,7 +107,7 @@ swfdec_debug_widget_expose (GtkWidget *g cr = gdk_cairo_create (gtkwidget->window); cairo_arc (cr, debug->x, debug->y, RADIUS - 1.5, 0.0, 2 * G_PI); - if (widget->button) { + if (debug->button) { cairo_set_source_rgba (cr, 0.25, 0.25, 0.25, 0.5); cairo_fill_preserve (cr); } diff --git a/player/swfdec_debug_widget.h b/player/swfdec_debug_widget.h index c11c8a4..b00117d 100644 --- a/player/swfdec_debug_widget.h +++ b/player/swfdec_debug_widget.h @@ -20,7 +20,7 @@ #ifndef _SWFDEC_DEBUG_WIDGET_H_ #define _SWFDEC_DEBUG_WIDGET_H_ -#include <libswfdec-gtk/swfdec_widget.h> +#include <libswfdec-gtk/swfdec_gtk_widget.h> G_BEGIN_DECLS @@ -35,15 +35,16 @@ typedef struct _SwfdecDebugWidgetClass S struct _SwfdecDebugWidget { - SwfdecWidget widget; + SwfdecGtkWidget widget; int x; int y; + int button; }; struct _SwfdecDebugWidgetClass { - SwfdecWidgetClass debug_widget_class; + SwfdecGtkWidgetClass debug_widget_class; }; GType swfdec_debug_widget_get_type (void); diff --git a/player/swfplay.c b/player/swfplay.c index e9d62ad..0a3805c 100644 --- a/player/swfplay.c +++ b/player/swfplay.c @@ -26,7 +26,7 @@ #include <libswfdec-gtk/swfdec_playback.h> #include <libswfdec-gtk/swfdec_source.h> -#include <libswfdec-gtk/swfdec_widget.h> +#include <libswfdec-gtk/swfdec_gtk_widget.h> #include "swfdec_slow_loader.h" @@ -49,9 +49,10 @@ view_swf (SwfdecPlayer *player, double s GtkWidget *window, *widget; window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - widget = swfdec_widget_new (player); - swfdec_widget_set_scale (SWFDEC_WIDGET (widget), scale); - swfdec_widget_set_use_image (SWFDEC_WIDGET (widget), use_image); + widget = swfdec_gtk_widget_new (player); + swfdec_gtk_widget_set_scale (SWFDEC_GTK_WIDGET (widget), scale); + if (use_image) + swfdec_gtk_widget_set_renderer (SWFDEC_GTK_WIDGET (widget), CAIRO_SURFACE_TYPE_IMAGE); gtk_container_add (GTK_CONTAINER (window), widget); g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); gtk_widget_show_all (window); diff-tree 5956357f5cba90936a1aa15934957155400d272c (from a6845d55ff3420aa75dd666e70ecf5dfb4fb5dd4) Author: Benjamin Otte <otte@gnome.org> Date: Mon Mar 26 12:46:56 2007 +0200 movie libswfdecui to libswfdec-gtk and make libswfdec-gtk an installed library diff --git a/configure.ac b/configure.ac index 5ac3db0..65be1fc 100644 --- a/configure.ac +++ b/configure.ac @@ -122,7 +122,11 @@ if test "$with_audio" = "auto" -o "$with if test "$AUDIO_TYPE" = "alsa"; then with_audio=alsa else - AC_MSG_WARN([no alsa audio support]) + if test "$with_audio" = "alsa"; then + AC_MSG_ERROR([no alsa audio support]) + else + AC_MSG_WARN([no alsa audio support]) + fi fi AUDIO_CFLAGS=$ALSA_CFLAGS AUDIO_LIBS=$ALSA_LIBS @@ -207,6 +211,11 @@ SWFDEC_LIBS="\$(top_builddir)/libswfdec/ AC_SUBST(SWFDEC_LIBS) AC_SUBST(SWFDEC_CFLAGS) +SWFDEC_GTK_CFLAGS="$SWFDEC_CFLAGS" +SWFDEC_GTK_LIBS="\$(top_builddir)/libswfdec-gtk/libswfdec-gtk-$SWFDEC_MAJORMINOR.la $SWFDEC_LIBS" +AC_SUBST(SWFDEC_GTK_LIBS) +AC_SUBST(SWFDEC_GTK_CFLAGS) + GTK_DOC_CHECK([1.6]) if test "x${prefix}" = "xNONE"; then diff --git a/libswfdec-gtk/.gitignore b/libswfdec-gtk/.gitignore index 87c0f2d..cad6c66 100644 --- a/libswfdec-gtk/.gitignore +++ b/libswfdec-gtk/.gitignore @@ -11,3 +11,4 @@ Makefile.in *.lo *.loT +swfdec_playback.c diff --git a/libswfdec-gtk/Makefile.am b/libswfdec-gtk/Makefile.am index e69de29..c9756be 100644 --- a/libswfdec-gtk/Makefile.am +++ b/libswfdec-gtk/Makefile.am @@ -0,0 +1,35 @@ +if WITH_GTK + +# this workaround is needed or autotools don't generate the .deps/*.Plo files correctly +swfdec_playback.c: swfdec_playback_$(AUDIO_TYPE).c Makefile + cmp -s $(srcdir)/swfdec_playback_$(AUDIO_TYPE).c swfdec_playback.c \ + || cp $(srcdir)/swfdec_playback_$(AUDIO_TYPE).c swfdec_playback.c + +BUILT_SOURCES = swfdec_playback.c +CLEANFILES = swfdec_playback.c + +lib_LTLIBRARIES = libswfdec-gtk-@SWFDEC_MAJORMINOR@.la + +libswfdec_gtk_@SWFDEC_MAJORMINOR@_la_SOURCES = \ + swfdec_playback.c \ + swfdec_source.c \ + swfdec_widget.c + +noinst_HEADERS = \ + swfdec_playback.h \ + swfdec_source.h \ + swfdec_widget.h + +libswfdec_gtk_@SWFDEC_MAJORMINOR@_la_CFLAGS = \ + $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(GTK_CFLAGS) $(AUDIO_CFLAGS) \ + -DG_LOG_DOMAIN=\"Swfdec-Gtk\" +libswfdec_gtk_@SWFDEC_MAJORMINOR@_la_LDFLAGS = \ + -version-info $(SWFDEC_LIBVERSION) \ + -export-symbols-regex '^(swfdec_.*)' \ + $(GTK_LIBS) $(SWFDEC_LIBS) $(AUDIO_LIBS) + +endif + +EXTRA_DIST = \ + swfdec_playback_alsa.c \ + swfdec_playback_none.c diff --git a/libswfdec-gtk/swfdec_playback.h b/libswfdec-gtk/swfdec_playback.h new file mode 100644 index 0000000..8b894cf --- /dev/null +++ b/libswfdec-gtk/swfdec_playback.h @@ -0,0 +1,33 @@ +/* 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_PLAYBACK_H_ +#define _SWFDEC_PLAYBACK_H_ + +#include <libswfdec/swfdec.h> + +G_BEGIN_DECLS + +gpointer swfdec_playback_open (SwfdecPlayer * player, + GMainContext * context); + +void swfdec_playback_close (gpointer sound); + +G_END_DECLS +#endif diff --git a/libswfdec-gtk/swfdec_playback_alsa.c b/libswfdec-gtk/swfdec_playback_alsa.c new file mode 100644 index 0000000..ea47099 --- /dev/null +++ b/libswfdec-gtk/swfdec_playback_alsa.c @@ -0,0 +1,355 @@ +/* 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 <alsa/asoundlib.h> +#include "swfdec_source.h" + +/* Why ALSA sucks for beginners: + * - snd_pcm_delay is not sample-exact, but period-exact most of the time. + * Yay for getting told the time every 512 samples when a human notices + * a delay of 100 samples (oooops) + * - lots of functions are simply not implemented. So the super-smart idea + * of using snd_pcm_rewind to avoid XRUNS and still get low latency has + * some issues when dmix just returns -EIO all of the time. That wouldn't + * be so bad if there was actually a way to query if it's supported. + * - But to make up for all this, you have 10 hardware parameters, 10 + * software parameters and 10 configuration parameters. All of this is + * naturally supported on 10 driver APIs depending on kernel. So if your + * sound card seems to do weird stuff, that is not my fault. + * Welcome to Linux sound in the 21st century. + */ + +/*** DEFINITIONS ***/ + +typedef struct { + SwfdecPlayer * player; + GList * streams; /* all Stream objects */ + GMainContext * context; /* context we work in */ +} Sound; + +typedef struct { + Sound * sound; /* reference to sound object */ + SwfdecAudio * audio; /* the audio we play back */ + snd_pcm_t * pcm; /* the pcm we play back to */ + GSource ** sources; /* sources for writing data */ + guint n_sources; /* number of sources */ + guint offset; /* offset into sound */ +} Stream; + +#define ALSA_TRY(func,msg) G_STMT_START{ \ + int err = func; \ + if (err < 0) \ + g_printerr (msg ": %s\n", snd_strerror (err)); \ +}G_STMT_END + +#define ALSA_ERROR(func,msg,retval) G_STMT_START { \ + int err = func; \ + if (err < 0) { \ + g_printerr (msg ": %s\n", snd_strerror (err)); \ + return retval; \ + } \ +}G_STMT_END + +/*** STREAMS ***/ + +static snd_pcm_uframes_t +write_player (Stream *stream, const snd_pcm_channel_area_t *dst, + snd_pcm_uframes_t offset, snd_pcm_uframes_t avail) +{ + /* FIXME: do a long path if this doesn't hold */ + g_assert (dst[1].first - dst[0].first == 16); + g_assert (dst[0].addr == dst[1].addr); + g_assert (dst[0].step == dst[1].step); + g_assert (dst[0].step == 32); + + memset (dst[0].addr + offset * dst[0].step / 8, 0, avail * 4); + swfdec_audio_render (stream->audio, dst[0].addr + offset * dst[0].step / 8, + stream->offset, avail); + //g_print ("rendering %u %u\n", stream->offset, (guint) avail); + return avail; +} + +static gboolean +try_write (Stream *stream) +{ + snd_pcm_sframes_t avail_result; + snd_pcm_uframes_t offset, avail; + const snd_pcm_channel_area_t *dst; + + while (TRUE) { + avail_result = snd_pcm_avail_update (stream->pcm); + ALSA_ERROR (avail_result, "snd_pcm_avail_update failed", FALSE); + if (avail_result == 0) + return TRUE; + avail = avail_result; + ALSA_ERROR (snd_pcm_mmap_begin (stream->pcm, &dst, &offset, &avail), + "snd_pcm_mmap_begin failed", FALSE); + //g_print (" avail = %u\n", (guint) avail); + + avail = write_player (stream, dst, offset, avail); + if (snd_pcm_mmap_commit (stream->pcm, offset, avail) < 0) { + g_printerr ("snd_pcm_mmap_commit failed\n"); + return FALSE; + } + stream->offset += avail; + //g_print ("offset: %u (+%u)\n", stream->offset, (guint) avail); + } + return TRUE; +} + +static void +swfdec_stream_remove_handlers (Stream *stream) +{ + unsigned int i; + + for (i = 0; i < stream->n_sources; i++) { + if (stream->sources[i]) { + g_source_destroy (stream->sources[i]); + g_source_unref (stream->sources[i]); + stream->sources[i] = NULL; + } + } +} + +static void swfdec_stream_start (Stream *stream); +static gboolean +handle_stream (GIOChannel *source, GIOCondition cond, gpointer data) +{ + Stream *stream = data; + snd_pcm_state_t state; + + state = snd_pcm_state (stream->pcm); + if (state != SND_PCM_STATE_RUNNING) { + swfdec_stream_start (stream); + } else { + try_write (stream); + } + return TRUE; +} + +static void +swfdec_stream_install_handlers (Stream *stream) +{ + if (stream->n_sources > 0) { + struct pollfd polls[stream->n_sources]; + unsigned int i, count; + if (stream->n_sources > 1) + g_printerr ("attention: more than one fd!\n"); + count = snd_pcm_poll_descriptors (stream->pcm, polls, stream->n_sources); + for (i = 0; i < count; i++) { + if (stream->sources[i] != NULL) + continue; + GIOChannel *channel = g_io_channel_unix_new (polls[i].fd); + stream->sources[i] = g_io_create_watch (channel, polls[i].events); + g_source_set_priority (stream->sources[i], G_PRIORITY_HIGH); + g_source_set_callback (stream->sources[i], (GSourceFunc) handle_stream, stream, NULL); + g_io_channel_unref (channel); + g_source_attach (stream->sources[i], stream->sound->context); + } + } +} + +static void +swfdec_stream_start (Stream *stream) +{ + snd_pcm_state_t state = snd_pcm_state (stream->pcm); + switch (state) { + case SND_PCM_STATE_XRUN: + ALSA_ERROR (snd_pcm_prepare (stream->pcm), "no prepare",); + //g_print ("XRUN!\n"); + /* fall through */ + case SND_PCM_STATE_SUSPENDED: + case SND_PCM_STATE_PREPARED: + stream->offset = 0; + //g_print ("offset: %u (delay: %ld)\n", sound->offset, delay); + if (try_write (stream)) { + ALSA_ERROR (snd_pcm_start (stream->pcm), "error starting",); + swfdec_stream_install_handlers (stream); + } + break; + default: + break; + } +} + +static void +swfdec_stream_open (Sound *sound, SwfdecAudio *audio) +{ + Stream *stream; + snd_pcm_t *ret; + snd_pcm_hw_params_t *hw_params; + unsigned int rate; + snd_pcm_uframes_t uframes; + + /* "default" uses dmix, and dmix ticks way slow, so this thingy here stutters */ + ALSA_ERROR (snd_pcm_open (&ret, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK), + "Failed to open sound device", ); + + snd_pcm_hw_params_alloca (&hw_params); + if (snd_pcm_hw_params_any (ret, hw_params) < 0) { + g_printerr ("No sound format available\n"); + return; + } + if (snd_pcm_hw_params_set_access (ret, hw_params, SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0) { + g_printerr ("Failed setting access\n"); + goto fail; + } + if (snd_pcm_hw_params_set_format (ret, hw_params, SND_PCM_FORMAT_S16) < 0) { + g_printerr ("Failed setting format\n"); + goto fail; + } + if (snd_pcm_hw_params_set_channels (ret, hw_params, 2) < 0) { + g_printerr ("Failed setting channels\n"); + goto fail; + } + rate = 44100; + if (snd_pcm_hw_params_set_rate_near (ret, hw_params, &rate, 0) < 0) { + g_printerr ("Failed setting rate\n"); + goto fail; + } + uframes = 16384; + if (snd_pcm_hw_params_set_buffer_size_near (ret, hw_params, &uframes) < 0) { + g_printerr ("Failed setting buffer size\n"); + goto fail; + } + if (snd_pcm_hw_params (ret, hw_params) < 0) { + g_printerr ("Could not set hardware parameters\n"); + goto fail; + } +#if 0 + { + snd_output_t *log; + snd_output_stdio_attach (&log, stderr, 0); + snd_pcm_hw_params_dump (hw_params, log); + } +#endif + stream = g_new0 (Stream, 1); + stream->sound = sound; + stream->audio = g_object_ref (audio); + stream->pcm = ret; + stream->n_sources = snd_pcm_poll_descriptors_count (ret); + if (stream->n_sources > 0) + stream->sources = g_new0 (GSource *, stream->n_sources); + sound->streams = g_list_prepend (sound->streams, stream); + swfdec_stream_start (stream); + return; + +fail: + snd_pcm_close (ret); +} + +static void +swfdec_stream_close (Stream *stream) +{ + ALSA_TRY (snd_pcm_close (stream->pcm), "failed closing"); + swfdec_stream_remove_handlers (stream); + g_free (stream->sources); + stream->sound->streams = g_list_remove (stream->sound->streams, stream); + g_object_unref (stream->audio); + g_free (stream); +} + +/*** SOUND ***/ + +static void +advance_before (SwfdecPlayer *player, guint msecs, guint audio_samples, gpointer data) +{ + Sound *sound = data; + GList *walk; + + for (walk = sound->streams; walk; walk = walk->next) { + Stream *stream = walk->data; + if (audio_samples >= stream->offset) { + stream->offset = 0; + } else { + stream->offset -= audio_samples; + } + } +} + +static void +audio_added (SwfdecPlayer *player, SwfdecAudio *audio, Sound *sound) +{ + swfdec_stream_open (sound, audio); +} + +static void +audio_removed (SwfdecPlayer *player, SwfdecAudio *audio, Sound *sound) +{ + GList *walk; + + for (walk = sound->streams; walk; walk = walk->next) { + Stream *stream = walk->data; + if (stream->audio == audio) { + swfdec_stream_close (stream); + return; + } + } + g_assert_not_reached (); +} + +gpointer +swfdec_playback_open (SwfdecPlayer *player, GMainContext *context) +{ + Sound *sound; + const GList *walk; + + g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL); + g_return_val_if_fail (context != NULL, NULL); + + sound = g_new0 (Sound, 1); + sound->player = g_object_ref (player); + g_signal_connect (player, "advance", G_CALLBACK (advance_before), sound); + g_signal_connect (player, "audio-added", G_CALLBACK (audio_added), sound); + g_signal_connect (player, "audio-removed", G_CALLBACK (audio_removed), sound); + for (walk = swfdec_player_get_audio (player); walk; walk = walk->next) { + swfdec_stream_open (sound, walk->data); + } + g_main_context_ref (context); + sound->context = context; + return sound; +} + +void +swfdec_playback_close (gpointer data) +{ + Sound *sound = data; +#define REMOVE_HANDLER_FULL(obj,func,data,count) G_STMT_START {\ + if (g_signal_handlers_disconnect_by_func ((obj), \ + G_CALLBACK (func), (data)) != (count)) { \ + g_assert_not_reached (); \ + } \ +} G_STMT_END +#define REMOVE_HANDLER(obj,func,data) REMOVE_HANDLER_FULL (obj, func, data, 1) + + while (sound->streams) + swfdec_stream_close (sound->streams->data); + REMOVE_HANDLER (sound->player, advance_before, sound); + REMOVE_HANDLER (sound->player, audio_added, sound); + REMOVE_HANDLER (sound->player, audio_removed, sound); + g_object_unref (sound->player); + g_main_context_unref (sound->context); + g_free (sound); +} + + diff --git a/libswfdec-gtk/swfdec_playback_none.c b/libswfdec-gtk/swfdec_playback_none.c new file mode 100644 index 0000000..6464a4a --- /dev/null +++ b/libswfdec-gtk/swfdec_playback_none.c @@ -0,0 +1,38 @@ +/* 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_playback.h" + +/* STUBS ONLY - audio is disabled */ + +gpointer +swfdec_playback_open (SwfdecPlayer *player, GMainContext *context) +{ + return GINT_TO_POINTER (-1); +} + +void +swfdec_playback_close (gpointer sound) +{ + g_assert (sound == GINT_TO_POINTER (-1)); +} diff --git a/libswfdec-gtk/swfdec_source.c b/libswfdec-gtk/swfdec_source.c new file mode 100644 index 0000000..81e383b --- /dev/null +++ b/libswfdec-gtk/swfdec_source.c @@ -0,0 +1,158 @@ +/* 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; + double speed; /* inverse playback speed (so 0.5 means double speed) */ + gulong notify; /* set for iterate notifications */ + GTimeVal last; /* last time */ +}; + +static glong +swfdec_iterate_get_msecs_to_next_event (GSource *source_) +{ + SwfdecIterateSource *source = (SwfdecIterateSource *) source_; + GTimeVal now; + glong diff; + + diff = swfdec_player_get_next_event (source->player); + if (diff == 0) + return G_MAXLONG; + diff *= source->speed; + g_source_get_current_time (source_, &now); + /* should really add to source->last instead of sutracting 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 = swfdec_iterate_get_msecs_to_next_event (source); + + 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 = 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 = 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) { + g_signal_handler_disconnect (source->player, source->notify); + } + g_object_unref (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 = g_object_ref (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; +} + +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/libswfdec-gtk/swfdec_source.h b/libswfdec-gtk/swfdec_source.h new file mode 100644 index 0000000..4321d6d --- /dev/null +++ b/libswfdec-gtk/swfdec_source.h @@ -0,0 +1,32 @@ +/* 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); +guint swfdec_iterate_add (SwfdecPlayer * player); + +G_END_DECLS +#endif diff --git a/libswfdec-gtk/swfdec_widget.c b/libswfdec-gtk/swfdec_widget.c new file mode 100644 index 0000000..99b414e --- /dev/null +++ b/libswfdec-gtk/swfdec_widget.c @@ -0,0 +1,450 @@ +/* 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 <math.h> +#include "swfdec_widget.h" + +enum { + PROP_0, + PROP_PLAYER +}; + +G_DEFINE_TYPE (SwfdecWidget, swfdec_widget, GTK_TYPE_WIDGET) + +static gboolean +swfdec_widget_motion_notify (GtkWidget *gtkwidget, GdkEventMotion *event) +{ + SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget); + int x, y; + + gdk_window_get_pointer (gtkwidget->window, &x, &y, NULL); + + if (widget->interactive) + swfdec_player_handle_mouse (widget->player, + x / widget->real_scale, y / widget->real_scale, widget->button); + + return FALSE; +} + +static gboolean +swfdec_widget_leave_notify (GtkWidget *gtkwidget, GdkEventCrossing *event) +{ + SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget); + + if (widget->interactive) { + widget->button = 0; + swfdec_player_handle_mouse (widget->player, + event->x / widget->real_scale, event->y / widget->real_scale, 0); + } + return FALSE; +} + +static gboolean +swfdec_widget_button_press (GtkWidget *gtkwidget, GdkEventButton *event) +{ + SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget); + + if (event->button == 1) { + widget->button = 1; + if (widget->interactive) + swfdec_player_handle_mouse (widget->player, + event->x / widget->real_scale, event->y / widget->real_scale, 1); + } + return FALSE; +} + +static gboolean +swfdec_widget_button_release (GtkWidget *gtkwidget, GdkEventButton *event) +{ + SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget); + + if (event->button == 1) { + widget->button = 0; + if (widget->interactive) + swfdec_player_handle_mouse (widget->player, + event->x / widget->real_scale, event->y / widget->real_scale, 0); + } + return FALSE; +} + +static gboolean +swfdec_widget_expose (GtkWidget *gtkwidget, GdkEventExpose *event) +{ + SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget); + cairo_t *cr; + cairo_surface_t *surface = NULL; + + if (event->window != gtkwidget->window) + return FALSE; + + if (!widget->use_image) { + cr = gdk_cairo_create (gtkwidget->window); + } else { + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, + event->area.width, event->area.height); + cr = cairo_create (surface); + cairo_translate (cr, -event->area.x, -event->area.y); + cairo_surface_destroy (surface); + } + cairo_scale (cr, widget->real_scale, widget->real_scale); + swfdec_player_render (widget->player, cr, + event->area.x / widget->real_scale, event->area.y / widget->real_scale, + event->area.width / widget->real_scale, event->area.height / widget->real_scale); + if (widget->use_image) { + cairo_t *crw = gdk_cairo_create (gtkwidget->window); + cairo_set_source_surface (crw, surface, event->area.x, event->area.y); + cairo_paint (crw); + cairo_destroy (crw); + } + + cairo_destroy (cr); + + return FALSE; +} + +static void +swfdec_widget_get_property (GObject *object, guint param_id, GValue *value, + GParamSpec * pspec) +{ + SwfdecWidget *widget = SWFDEC_WIDGET (object); + + switch (param_id) { + case PROP_PLAYER: + g_value_set_object (value, widget->player); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +swfdec_widget_set_property (GObject *object, guint param_id, const GValue *value, + GParamSpec *pspec) +{ + SwfdecWidget *widget = SWFDEC_WIDGET (object); + + switch (param_id) { + case PROP_PLAYER: + swfdec_widget_set_player (widget, g_value_get_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +swfdec_widget_dispose (GObject *object) +{ + SwfdecWidget *widget = SWFDEC_WIDGET (object); + + swfdec_widget_set_player (widget, NULL); + + G_OBJECT_CLASS (swfdec_widget_parent_class)->dispose (object); +} + +static void +swfdec_widget_size_allocate (GtkWidget *gtkwidget, GtkAllocation *allocation) +{ + double scale; + int w, h; + SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget); + + gtkwidget->allocation = *allocation; + + swfdec_player_get_image_size (widget->player, &w, &h); + if (widget->set_scale > 0.0) { + scale = widget->set_scale; + } else if (widget->player == NULL) { + scale = 1.0; + } else { + if (w != 0 && h != 0) + scale = MIN ((double) allocation->width / w, (double) allocation->height / h); + else + scale = 1.0; + } + w = ceil (w * scale); + h = ceil (h * scale); + if (w > allocation->width) + w = allocation->width; + if (h > allocation->height) + h = allocation->height; + + if (GTK_WIDGET_REALIZED (gtkwidget)) { + gdk_window_move_resize (gtkwidget->window, + allocation->x + (allocation->width - w) / 2, + allocation->y + (allocation->height - h) / 2, + w, h); + } + widget->real_scale = scale; +} + +static void +swfdec_widget_size_request (GtkWidget *gtkwidget, GtkRequisition *req) +{ + double scale; + SwfdecWidget * widget = SWFDEC_WIDGET (gtkwidget); + + if (widget->player == NULL) { + req->width = req->height = 0; + } else { + swfdec_player_get_image_size (widget->player, + &req->width, &req->height); + } + if (widget->set_scale != 0.0) + scale = widget->set_scale; + else + scale = 1.0; + req->width = ceil (req->width * scale); + req->height = ceil (req->height * scale); +} + +static void +swfdec_widget_update_cursor (SwfdecWidget *widget) +{ + GdkWindow *window = GTK_WIDGET (widget)->window; + GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (widget)); + SwfdecMouseCursor swfcursor; + GdkCursor *cursor; + + if (window == NULL) + return; + g_object_get (widget->player, "mouse-cursor", &swfcursor, NULL); + + switch (swfcursor) { + case SWFDEC_MOUSE_CURSOR_NONE: + { + GdkBitmap *bitmap; + GdkColor color = { 0, 0, 0, 0 }; + char data = 0; + + bitmap = gdk_bitmap_create_from_data (window, &data, 1, 1); + if (bitmap == NULL) + return; + cursor = gdk_cursor_new_from_pixmap (bitmap, bitmap, &color, &color, 0, 0); + gdk_window_set_cursor (window, cursor); + gdk_cursor_unref (cursor); + g_object_unref (bitmap); + break; + } + case SWFDEC_MOUSE_CURSOR_TEXT: + cursor = gdk_cursor_new_for_display (display, GDK_XTERM); + gdk_window_set_cursor (window, cursor); + gdk_cursor_unref (cursor); + break; + case SWFDEC_MOUSE_CURSOR_CLICK: + cursor = gdk_cursor_new_for_display (display, GDK_HAND2); + gdk_window_set_cursor (window, cursor); + gdk_cursor_unref (cursor); + break; + case SWFDEC_MOUSE_CURSOR_NORMAL: + cursor = gdk_cursor_new_for_display (display, GDK_LEFT_PTR); + gdk_window_set_cursor (window, cursor); + gdk_cursor_unref (cursor); + break; + default: + g_warning ("invalid cursor %d", (int) swfcursor); + gdk_window_set_cursor (window, NULL); + break; + } +} + +static void +swfdec_widget_realize (GtkWidget *widget) +{ + GdkWindowAttr attributes; + gint attributes_mask; + + GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); + + attributes.window_type = GDK_WINDOW_CHILD; + attributes.x = widget->allocation.x; + attributes.y = widget->allocation.y; + attributes.width = widget->allocation.width; + attributes.height = widget->allocation.height; + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.event_mask = gtk_widget_get_events (widget); + attributes.event_mask |= GDK_EXPOSURE_MASK | + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_LEAVE_NOTIFY_MASK | + GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK; + + attributes_mask = GDK_WA_X | GDK_WA_Y; + + widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), + &attributes, attributes_mask); + gdk_window_set_user_data (widget->window, widget); + + widget->style = gtk_style_attach (widget->style, widget->window); + + if (SWFDEC_WIDGET (widget)->player) { + swfdec_widget_update_cursor (SWFDEC_WIDGET (widget)); + } +} + +static void +swfdec_widget_class_init (SwfdecWidgetClass * g_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (g_class); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (g_class); + + object_class->dispose = swfdec_widget_dispose; + object_class->get_property = swfdec_widget_get_property; + object_class->set_property = swfdec_widget_set_property; + + g_object_class_install_property (object_class, PROP_PLAYER, + g_param_spec_object ("player", "player", "player that is displayed", + SWFDEC_TYPE_PLAYER, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + widget_class->realize = swfdec_widget_realize; + widget_class->size_request = swfdec_widget_size_request; + widget_class->size_allocate = swfdec_widget_size_allocate; + widget_class->expose_event = swfdec_widget_expose; + widget_class->button_press_event = swfdec_widget_button_press; + widget_class->button_release_event = swfdec_widget_button_release; + widget_class->motion_notify_event = swfdec_widget_motion_notify; + widget_class->leave_notify_event = swfdec_widget_leave_notify; +} + +static void +swfdec_widget_init (SwfdecWidget * widget) +{ + widget->real_scale = 1.0; + widget->interactive = TRUE; +} + +static void +swfdec_widget_invalidate_cb (SwfdecPlayer *player, double x, double y, + double width, double height, SwfdecWidget *widget) +{ + GdkRectangle rect; + + if (!GTK_WIDGET_REALIZED (widget)) + return; + rect.x = floor (x * widget->real_scale); + rect.y = floor (y * widget->real_scale); + rect.width = ceil ((x + width) * widget->real_scale) - rect.x; + rect.height = ceil ((y + height) * widget->real_scale) - rect.y; + gdk_window_invalidate_rect (GTK_WIDGET (widget)->window, &rect, FALSE); +} + +static void +swfdec_widget_notify_cb (SwfdecPlayer *player, GParamSpec *pspec, SwfdecWidget *widget) +{ + if (g_str_equal (pspec->name, "mouse-cursor")) { + swfdec_widget_update_cursor (widget); + } else if (g_str_equal (pspec->name, "initialized")) { + gtk_widget_queue_resize (GTK_WIDGET (widget)); + } +} + +void +swfdec_widget_set_player (SwfdecWidget *widget, SwfdecPlayer *player) +{ + g_return_if_fail (SWFDEC_IS_WIDGET (widget)); + g_return_if_fail (player == NULL || SWFDEC_IS_PLAYER (player)); + + if (widget->player) { + g_signal_handlers_disconnect_by_func (widget->player, swfdec_widget_invalidate_cb, widget); + g_signal_handlers_disconnect_by_func (widget->player, swfdec_widget_notify_cb, widget); + g_object_unref (widget->player); + } + widget->player = player; + if (player) { + g_signal_connect (player, "invalidate", G_CALLBACK (swfdec_widget_invalidate_cb), widget); + g_signal_connect (player, "notify", G_CALLBACK (swfdec_widget_notify_cb), widget); + g_object_ref (player); + swfdec_widget_update_cursor (widget); + } else { + if (GTK_WIDGET (widget)->window) + gdk_window_set_cursor (GTK_WIDGET (widget)->window, NULL); + } + gtk_widget_queue_resize (GTK_WIDGET (widget)); +} + +GtkWidget * +swfdec_widget_new (SwfdecPlayer *player) +{ + SwfdecWidget *widget; + + g_return_val_if_fail (player == NULL || SWFDEC_IS_PLAYER (player), NULL); + + widget = g_object_new (SWFDEC_TYPE_WIDGET, "player", player, NULL); + + return GTK_WIDGET (widget); +} + +void +swfdec_widget_set_scale (SwfdecWidget *widget, double scale) +{ + g_return_if_fail (SWFDEC_IS_WIDGET (widget)); + g_return_if_fail (scale >= 0.0); + + widget->set_scale = scale; + gtk_widget_queue_resize (GTK_WIDGET (widget)); +} + +double +swfdec_widget_get_scale (SwfdecWidget *widget) +{ + g_return_val_if_fail (SWFDEC_IS_WIDGET (widget), 1.0); + + return widget->set_scale; +} + +void +swfdec_widget_set_use_image (SwfdecWidget *widget, gboolean use_image) +{ + g_return_if_fail (SWFDEC_IS_WIDGET (widget)); + + widget->use_image = use_image; + gtk_widget_queue_draw (GTK_WIDGET (widget)); +} + +gboolean +swfdec_widget_get_use_image (SwfdecWidget *widget) +{ + g_return_val_if_fail (SWFDEC_IS_WIDGET (widget), 1.0); + + return widget->use_image; +} + +void +swfdec_widget_set_interactive (SwfdecWidget *widget, gboolean interactive) +{ + g_return_if_fail (SWFDEC_IS_WIDGET (widget)); + + widget->interactive = interactive; +} + +gboolean +swfdec_widget_get_interactive (SwfdecWidget *widget) +{ + g_return_val_if_fail (SWFDEC_IS_WIDGET (widget), FALSE); + + return widget->interactive; +} + diff --git a/libswfdec-gtk/swfdec_widget.h b/libswfdec-gtk/swfdec_widget.h new file mode 100644 index 0000000..1988f20 --- /dev/null +++ b/libswfdec-gtk/swfdec_widget.h @@ -0,0 +1,73 @@ +/* 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_WIDGET_H_ +#define _SWFDEC_WIDGET_H_ + +#include <gtk/gtk.h> +#include <libswfdec/swfdec.h> + +G_BEGIN_DECLS + +typedef struct _SwfdecWidget SwfdecWidget; +typedef struct _SwfdecWidgetClass SwfdecWidgetClass; + +#define SWFDEC_TYPE_WIDGET (swfdec_widget_get_type()) +#define SWFDEC_IS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_WIDGET)) +#define SWFDEC_IS_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_WIDGET)) +#define SWFDEC_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_WIDGET, SwfdecWidget)) +#define SWFDEC_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_WIDGET, SwfdecWidgetClass)) + +struct _SwfdecWidget +{ + GtkWidget widget; + + SwfdecPlayer * player; /* the video we play */ + + double real_scale; /* the real scale factor used */ + double set_scale; /* the set scale factor of the video */ + gboolean use_image; /* TRUE to draw to an image first before rendering to Gtk */ + gboolean interactive; /* if this widget propagates keyboard and mouse events */ + + int button; /* status of mouse button in displayed movie */ +}; + +struct _SwfdecWidgetClass +{ + GtkWidgetClass widget_class; +}; + +GType swfdec_widget_get_type (void); + +GtkWidget * swfdec_widget_new (SwfdecPlayer * player); + +void swfdec_widget_set_scale (SwfdecWidget * widget, + double scale); +double swfdec_widget_get_scale (SwfdecWidget * widget); +void swfdec_widget_set_use_image (SwfdecWidget * widget, + gboolean use_image); +gboolean swfdec_widget_get_use_image (SwfdecWidget * widget); +void swfdec_widget_set_interactive (SwfdecWidget * widget, + gboolean interactive); +gboolean swfdec_widget_get_interactive (SwfdecWidget * widget); +void swfdec_widget_set_player (SwfdecWidget * widget, + SwfdecPlayer * player); + +G_END_DECLS +#endif diff --git a/player/.gitignore b/player/.gitignore index c5a38e3..212cc97 100644 --- a/player/.gitignore +++ b/player/.gitignore @@ -9,9 +9,7 @@ Makefile.in *.o *.lo *.loT -swfdec_playback.c -libswfdecui.la swfdebug swfplay diff --git a/player/Makefile.am b/player/Makefile.am index f08f448..d22e527 100644 --- a/player/Makefile.am +++ b/player/Makefile.am @@ -1,21 +1,7 @@ if WITH_GTK -# this workaround is needed or autotools don't generate the .deps/*.Plo files correctly -swfdec_playback.c: swfdec_playback_$(AUDIO_TYPE).c Makefile - cmp -s $(srcdir)/swfdec_playback_$(AUDIO_TYPE).c swfdec_playback.c \ - || cp $(srcdir)/swfdec_playback_$(AUDIO_TYPE).c swfdec_playback.c - -BUILT_SOURCES = swfdec_playback.c -CLEANFILES = swfdec_playback.c - -noinst_LTLIBRARIES = libswfdecui.la noinst_PROGRAMS = swfplay swfdebug -libswfdecui_la_SOURCES = \ - swfdec_playback.c \ - swfdec_source.c \ - swfdec_widget.c - swfplay_SOURCES = \ swfdec_slow_loader.c \ swfplay.c @@ -35,23 +21,16 @@ noinst_HEADERS = \ swfdec_debug_scripts.h \ swfdec_debug_stack.h \ swfdec_debug_widget.h \ - swfdec_playback.h \ swfdec_player_manager.h \ - swfdec_source.h \ - swfdec_slow_loader.h \ - swfdec_widget.h - -libswfdecui_la_CFLAGS = $(GLOBAL_CFLAGS) $(GTK_CFLAGS) $(SWFDEC_CFLAGS) $(AUDIO_CFLAGS) -libswfdecui_la_LDFLAGS = $(GTK_LIBS) $(SWFDEC_LIBS) $(AUDIO_LIBS) -swfplay_CFLAGS = $(GLOBAL_CFLAGS) $(GTK_CFLAGS) $(SWFDEC_CFLAGS) -swfplay_LDFLAGS = $(GTK_LIBS) $(SWFDEC_LIBS) -swfplay_LDADD = libswfdecui.la -swfdebug_CFLAGS = $(GLOBAL_CFLAGS) $(GTK_CFLAGS) $(SWFDEC_CFLAGS) -DXP_UNIX -I$(top_builddir)/libswfdec/js -swfdebug_LDFLAGS = $(GTK_LIBS) $(SWFDEC_LIBS) -swfdebug_LDADD = libswfdecui.la $(top_builddir)/libswfdec/js/libjs.la + swfdec_slow_loader.h + +swfplay_CFLAGS = $(GLOBAL_CFLAGS) $(GTK_CFLAGS) $(SWFDEC_GTK_CFLAGS) +swfplay_LDFLAGS = $(GTK_LIBS) $(SWFDEC_GTK_LIBS) + +swfdebug_CFLAGS = $(GLOBAL_CFLAGS) $(GTK_CFLAGS) $(SWFDEC_GTK_CFLAGS) -DXP_UNIX -I$(top_builddir)/libswfdec/js +swfdebug_LDFLAGS = $(GTK_LIBS) $(SWFDEC_GTK_LIBS) +swfdebug_LDADD = $(top_builddir)/libswfdec/js/libjs.la + endif -EXTRA_DIST = \ - swfdec_playback_alsa.c \ - swfdec_playback_none.c diff --git a/player/swfdec_debug_widget.h b/player/swfdec_debug_widget.h index e4a34bf..c11c8a4 100644 --- a/player/swfdec_debug_widget.h +++ b/player/swfdec_debug_widget.h @@ -20,8 +20,7 @@ #ifndef _SWFDEC_DEBUG_WIDGET_H_ #define _SWFDEC_DEBUG_WIDGET_H_ -#include <gtk/gtk.h> -#include "swfdec_widget.h" +#include <libswfdec-gtk/swfdec_widget.h> G_BEGIN_DECLS diff --git a/player/swfdec_playback.h b/player/swfdec_playback.h deleted file mode 100644 index 8b894cf..0000000 --- a/player/swfdec_playback.h +++ /dev/null @@ -1,33 +0,0 @@ -/* 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_PLAYBACK_H_ -#define _SWFDEC_PLAYBACK_H_ - -#include <libswfdec/swfdec.h> - -G_BEGIN_DECLS - -gpointer swfdec_playback_open (SwfdecPlayer * player, - GMainContext * context); - -void swfdec_playback_close (gpointer sound); - -G_END_DECLS -#endif diff --git a/player/swfdec_playback_alsa.c b/player/swfdec_playback_alsa.c deleted file mode 100644 index ea47099..0000000 --- a/player/swfdec_playback_alsa.c +++ /dev/null @@ -1,355 +0,0 @@ -/* 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 <alsa/asoundlib.h> -#include "swfdec_source.h" - -/* Why ALSA sucks for beginners: - * - snd_pcm_delay is not sample-exact, but period-exact most of the time. - * Yay for getting told the time every 512 samples when a human notices - * a delay of 100 samples (oooops) - * - lots of functions are simply not implemented. So the super-smart idea - * of using snd_pcm_rewind to avoid XRUNS and still get low latency has - * some issues when dmix just returns -EIO all of the time. That wouldn't - * be so bad if there was actually a way to query if it's supported. - * - But to make up for all this, you have 10 hardware parameters, 10 - * software parameters and 10 configuration parameters. All of this is - * naturally supported on 10 driver APIs depending on kernel. So if your - * sound card seems to do weird stuff, that is not my fault. - * Welcome to Linux sound in the 21st century. - */ - -/*** DEFINITIONS ***/ - -typedef struct { - SwfdecPlayer * player; - GList * streams; /* all Stream objects */ - GMainContext * context; /* context we work in */ -} Sound; - -typedef struct { - Sound * sound; /* reference to sound object */ - SwfdecAudio * audio; /* the audio we play back */ - snd_pcm_t * pcm; /* the pcm we play back to */ - GSource ** sources; /* sources for writing data */ - guint n_sources; /* number of sources */ - guint offset; /* offset into sound */ -} Stream; - -#define ALSA_TRY(func,msg) G_STMT_START{ \ - int err = func; \ - if (err < 0) \ - g_printerr (msg ": %s\n", snd_strerror (err)); \ -}G_STMT_END - -#define ALSA_ERROR(func,msg,retval) G_STMT_START { \ - int err = func; \ - if (err < 0) { \ - g_printerr (msg ": %s\n", snd_strerror (err)); \ - return retval; \ - } \ -}G_STMT_END - -/*** STREAMS ***/ - -static snd_pcm_uframes_t -write_player (Stream *stream, const snd_pcm_channel_area_t *dst, - snd_pcm_uframes_t offset, snd_pcm_uframes_t avail) -{ - /* FIXME: do a long path if this doesn't hold */ - g_assert (dst[1].first - dst[0].first == 16); - g_assert (dst[0].addr == dst[1].addr); - g_assert (dst[0].step == dst[1].step); - g_assert (dst[0].step == 32); - - memset (dst[0].addr + offset * dst[0].step / 8, 0, avail * 4); - swfdec_audio_render (stream->audio, dst[0].addr + offset * dst[0].step / 8, - stream->offset, avail); - //g_print ("rendering %u %u\n", stream->offset, (guint) avail); - return avail; -} - -static gboolean -try_write (Stream *stream) -{ - snd_pcm_sframes_t avail_result; - snd_pcm_uframes_t offset, avail; - const snd_pcm_channel_area_t *dst; - - while (TRUE) { - avail_result = snd_pcm_avail_update (stream->pcm); - ALSA_ERROR (avail_result, "snd_pcm_avail_update failed", FALSE); - if (avail_result == 0) - return TRUE; - avail = avail_result; - ALSA_ERROR (snd_pcm_mmap_begin (stream->pcm, &dst, &offset, &avail), - "snd_pcm_mmap_begin failed", FALSE); - //g_print (" avail = %u\n", (guint) avail); - - avail = write_player (stream, dst, offset, avail); - if (snd_pcm_mmap_commit (stream->pcm, offset, avail) < 0) { - g_printerr ("snd_pcm_mmap_commit failed\n"); - return FALSE; - } - stream->offset += avail; - //g_print ("offset: %u (+%u)\n", stream->offset, (guint) avail); - } - return TRUE; -} - -static void -swfdec_stream_remove_handlers (Stream *stream) -{ - unsigned int i; - - for (i = 0; i < stream->n_sources; i++) { - if (stream->sources[i]) { - g_source_destroy (stream->sources[i]); - g_source_unref (stream->sources[i]); - stream->sources[i] = NULL; - } - } -} - -static void swfdec_stream_start (Stream *stream); -static gboolean -handle_stream (GIOChannel *source, GIOCondition cond, gpointer data) -{ - Stream *stream = data; - snd_pcm_state_t state; - - state = snd_pcm_state (stream->pcm); - if (state != SND_PCM_STATE_RUNNING) { - swfdec_stream_start (stream); - } else { - try_write (stream); - } - return TRUE; -} - -static void -swfdec_stream_install_handlers (Stream *stream) -{ - if (stream->n_sources > 0) { - struct pollfd polls[stream->n_sources]; - unsigned int i, count; - if (stream->n_sources > 1) - g_printerr ("attention: more than one fd!\n"); - count = snd_pcm_poll_descriptors (stream->pcm, polls, stream->n_sources); - for (i = 0; i < count; i++) { - if (stream->sources[i] != NULL) - continue; - GIOChannel *channel = g_io_channel_unix_new (polls[i].fd); - stream->sources[i] = g_io_create_watch (channel, polls[i].events); - g_source_set_priority (stream->sources[i], G_PRIORITY_HIGH); - g_source_set_callback (stream->sources[i], (GSourceFunc) handle_stream, stream, NULL); - g_io_channel_unref (channel); - g_source_attach (stream->sources[i], stream->sound->context); - } - } -} - -static void -swfdec_stream_start (Stream *stream) -{ - snd_pcm_state_t state = snd_pcm_state (stream->pcm); - switch (state) { - case SND_PCM_STATE_XRUN: - ALSA_ERROR (snd_pcm_prepare (stream->pcm), "no prepare",); - //g_print ("XRUN!\n"); - /* fall through */ - case SND_PCM_STATE_SUSPENDED: - case SND_PCM_STATE_PREPARED: - stream->offset = 0; - //g_print ("offset: %u (delay: %ld)\n", sound->offset, delay); - if (try_write (stream)) { - ALSA_ERROR (snd_pcm_start (stream->pcm), "error starting",); - swfdec_stream_install_handlers (stream); - } - break; - default: - break; - } -} - -static void -swfdec_stream_open (Sound *sound, SwfdecAudio *audio) -{ - Stream *stream; - snd_pcm_t *ret; - snd_pcm_hw_params_t *hw_params; - unsigned int rate; - snd_pcm_uframes_t uframes; - - /* "default" uses dmix, and dmix ticks way slow, so this thingy here stutters */ - ALSA_ERROR (snd_pcm_open (&ret, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK), - "Failed to open sound device", ); - - snd_pcm_hw_params_alloca (&hw_params); - if (snd_pcm_hw_params_any (ret, hw_params) < 0) { - g_printerr ("No sound format available\n"); - return; - } - if (snd_pcm_hw_params_set_access (ret, hw_params, SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0) { - g_printerr ("Failed setting access\n"); - goto fail; - } - if (snd_pcm_hw_params_set_format (ret, hw_params, SND_PCM_FORMAT_S16) < 0) { - g_printerr ("Failed setting format\n"); - goto fail; - } - if (snd_pcm_hw_params_set_channels (ret, hw_params, 2) < 0) { - g_printerr ("Failed setting channels\n"); - goto fail; - } - rate = 44100; - if (snd_pcm_hw_params_set_rate_near (ret, hw_params, &rate, 0) < 0) { - g_printerr ("Failed setting rate\n"); - goto fail; - } - uframes = 16384; - if (snd_pcm_hw_params_set_buffer_size_near (ret, hw_params, &uframes) < 0) { - g_printerr ("Failed setting buffer size\n"); - goto fail; - } - if (snd_pcm_hw_params (ret, hw_params) < 0) { - g_printerr ("Could not set hardware parameters\n"); - goto fail; - } -#if 0 - { - snd_output_t *log; - snd_output_stdio_attach (&log, stderr, 0); - snd_pcm_hw_params_dump (hw_params, log); - } -#endif - stream = g_new0 (Stream, 1); - stream->sound = sound; - stream->audio = g_object_ref (audio); - stream->pcm = ret; - stream->n_sources = snd_pcm_poll_descriptors_count (ret); - if (stream->n_sources > 0) - stream->sources = g_new0 (GSource *, stream->n_sources); - sound->streams = g_list_prepend (sound->streams, stream); - swfdec_stream_start (stream); - return; - -fail: - snd_pcm_close (ret); -} - -static void -swfdec_stream_close (Stream *stream) -{ - ALSA_TRY (snd_pcm_close (stream->pcm), "failed closing"); - swfdec_stream_remove_handlers (stream); - g_free (stream->sources); - stream->sound->streams = g_list_remove (stream->sound->streams, stream); - g_object_unref (stream->audio); - g_free (stream); -} - -/*** SOUND ***/ - -static void -advance_before (SwfdecPlayer *player, guint msecs, guint audio_samples, gpointer data) -{ - Sound *sound = data; - GList *walk; - - for (walk = sound->streams; walk; walk = walk->next) { - Stream *stream = walk->data; - if (audio_samples >= stream->offset) { - stream->offset = 0; - } else { - stream->offset -= audio_samples; - } - } -} - -static void -audio_added (SwfdecPlayer *player, SwfdecAudio *audio, Sound *sound) -{ - swfdec_stream_open (sound, audio); -} - -static void -audio_removed (SwfdecPlayer *player, SwfdecAudio *audio, Sound *sound) -{ - GList *walk; - - for (walk = sound->streams; walk; walk = walk->next) { - Stream *stream = walk->data; - if (stream->audio == audio) { - swfdec_stream_close (stream); - return; - } - } - g_assert_not_reached (); -} - -gpointer -swfdec_playback_open (SwfdecPlayer *player, GMainContext *context) -{ - Sound *sound; - const GList *walk; - - g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL); - g_return_val_if_fail (context != NULL, NULL); - - sound = g_new0 (Sound, 1); - sound->player = g_object_ref (player); - g_signal_connect (player, "advance", G_CALLBACK (advance_before), sound); - g_signal_connect (player, "audio-added", G_CALLBACK (audio_added), sound); - g_signal_connect (player, "audio-removed", G_CALLBACK (audio_removed), sound); - for (walk = swfdec_player_get_audio (player); walk; walk = walk->next) { - swfdec_stream_open (sound, walk->data); - } - g_main_context_ref (context); - sound->context = context; - return sound; -} - -void -swfdec_playback_close (gpointer data) -{ - Sound *sound = data; -#define REMOVE_HANDLER_FULL(obj,func,data,count) G_STMT_START {\ - if (g_signal_handlers_disconnect_by_func ((obj), \ - G_CALLBACK (func), (data)) != (count)) { \ - g_assert_not_reached (); \ - } \ -} G_STMT_END -#define REMOVE_HANDLER(obj,func,data) REMOVE_HANDLER_FULL (obj, func, data, 1) - - while (sound->streams) - swfdec_stream_close (sound->streams->data); - REMOVE_HANDLER (sound->player, advance_before, sound); - REMOVE_HANDLER (sound->player, audio_added, sound); - REMOVE_HANDLER (sound->player, audio_removed, sound); - g_object_unref (sound->player); - g_main_context_unref (sound->context); - g_free (sound); -} - - diff --git a/player/swfdec_playback_none.c b/player/swfdec_playback_none.c deleted file mode 100644 index 6464a4a..0000000 --- a/player/swfdec_playback_none.c +++ /dev/null @@ -1,38 +0,0 @@ -/* 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_playback.h" - -/* STUBS ONLY - audio is disabled */ - -gpointer -swfdec_playback_open (SwfdecPlayer *player, GMainContext *context) -{ - return GINT_TO_POINTER (-1); -} - -void -swfdec_playback_close (gpointer sound) -{ - g_assert (sound == GINT_TO_POINTER (-1)); -} diff --git a/player/swfdec_player_manager.c b/player/swfdec_player_manager.c index 0d22ab3..299c9ab 100644 --- a/player/swfdec_player_manager.c +++ b/player/swfdec_player_manager.c @@ -28,7 +28,7 @@ #include <libswfdec/js/jsdbgapi.h> #include <libswfdec/js/jsinterp.h> #include "swfdec_player_manager.h" -#include "swfdec_source.h" +#include <libswfdec-gtk/swfdec_source.h> enum { PROP_0, diff --git a/player/swfdec_source.c b/player/swfdec_source.c deleted file mode 100644 index 81e383b..0000000 --- a/player/swfdec_source.c +++ /dev/null @@ -1,158 +0,0 @@ -/* 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; - double speed; /* inverse playback speed (so 0.5 means double speed) */ - gulong notify; /* set for iterate notifications */ - GTimeVal last; /* last time */ -}; - -static glong -swfdec_iterate_get_msecs_to_next_event (GSource *source_) -{ - SwfdecIterateSource *source = (SwfdecIterateSource *) source_; - GTimeVal now; - glong diff; - - diff = swfdec_player_get_next_event (source->player); - if (diff == 0) - return G_MAXLONG; - diff *= source->speed; - g_source_get_current_time (source_, &now); - /* should really add to source->last instead of sutracting 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 = swfdec_iterate_get_msecs_to_next_event (source); - - 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 = 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 = 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) { - g_signal_handler_disconnect (source->player, source->notify); - } - g_object_unref (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 = g_object_ref (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; -} - -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/player/swfdec_source.h b/player/swfdec_source.h deleted file mode 100644 index 4321d6d..0000000 --- a/player/swfdec_source.h +++ /dev/null @@ -1,32 +0,0 @@ -/* 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); -guint swfdec_iterate_add (SwfdecPlayer * player); - -G_END_DECLS -#endif diff --git a/player/swfdec_widget.c b/player/swfdec_widget.c deleted file mode 100644 index 99b414e..0000000 --- a/player/swfdec_widget.c +++ /dev/null @@ -1,450 +0,0 @@ -/* 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 <math.h> -#include "swfdec_widget.h" - -enum { - PROP_0, - PROP_PLAYER -}; - -G_DEFINE_TYPE (SwfdecWidget, swfdec_widget, GTK_TYPE_WIDGET) - -static gboolean -swfdec_widget_motion_notify (GtkWidget *gtkwidget, GdkEventMotion *event) -{ - SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget); - int x, y; - - gdk_window_get_pointer (gtkwidget->window, &x, &y, NULL); - - if (widget->interactive) - swfdec_player_handle_mouse (widget->player, - x / widget->real_scale, y / widget->real_scale, widget->button); - - return FALSE; -} - -static gboolean -swfdec_widget_leave_notify (GtkWidget *gtkwidget, GdkEventCrossing *event) -{ - SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget); - - if (widget->interactive) { - widget->button = 0; - swfdec_player_handle_mouse (widget->player, - event->x / widget->real_scale, event->y / widget->real_scale, 0); - } - return FALSE; -} - -static gboolean -swfdec_widget_button_press (GtkWidget *gtkwidget, GdkEventButton *event) -{ - SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget); - - if (event->button == 1) { - widget->button = 1; - if (widget->interactive) - swfdec_player_handle_mouse (widget->player, - event->x / widget->real_scale, event->y / widget->real_scale, 1); - } - return FALSE; -} - -static gboolean -swfdec_widget_button_release (GtkWidget *gtkwidget, GdkEventButton *event) -{ - SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget); - - if (event->button == 1) { - widget->button = 0; - if (widget->interactive) - swfdec_player_handle_mouse (widget->player, - event->x / widget->real_scale, event->y / widget->real_scale, 0); - } - return FALSE; -} - -static gboolean -swfdec_widget_expose (GtkWidget *gtkwidget, GdkEventExpose *event) -{ - SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget); - cairo_t *cr; - cairo_surface_t *surface = NULL; - - if (event->window != gtkwidget->window) - return FALSE; - - if (!widget->use_image) { - cr = gdk_cairo_create (gtkwidget->window); - } else { - surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, - event->area.width, event->area.height); - cr = cairo_create (surface); - cairo_translate (cr, -event->area.x, -event->area.y); - cairo_surface_destroy (surface); - } - cairo_scale (cr, widget->real_scale, widget->real_scale); - swfdec_player_render (widget->player, cr, - event->area.x / widget->real_scale, event->area.y / widget->real_scale, - event->area.width / widget->real_scale, event->area.height / widget->real_scale); - if (widget->use_image) { - cairo_t *crw = gdk_cairo_create (gtkwidget->window); - cairo_set_source_surface (crw, surface, event->area.x, event->area.y); - cairo_paint (crw); - cairo_destroy (crw); - } - - cairo_destroy (cr); - - return FALSE; -} - -static void -swfdec_widget_get_property (GObject *object, guint param_id, GValue *value, - GParamSpec * pspec) -{ - SwfdecWidget *widget = SWFDEC_WIDGET (object); - - switch (param_id) { - case PROP_PLAYER: - g_value_set_object (value, widget->player); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } -} - -static void -swfdec_widget_set_property (GObject *object, guint param_id, const GValue *value, - GParamSpec *pspec) -{ - SwfdecWidget *widget = SWFDEC_WIDGET (object); - - switch (param_id) { - case PROP_PLAYER: - swfdec_widget_set_player (widget, g_value_get_object (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } -} - -static void -swfdec_widget_dispose (GObject *object) -{ - SwfdecWidget *widget = SWFDEC_WIDGET (object); - - swfdec_widget_set_player (widget, NULL); - - G_OBJECT_CLASS (swfdec_widget_parent_class)->dispose (object); -} - -static void -swfdec_widget_size_allocate (GtkWidget *gtkwidget, GtkAllocation *allocation) -{ - double scale; - int w, h; - SwfdecWidget *widget = SWFDEC_WIDGET (gtkwidget); - - gtkwidget->allocation = *allocation; - - swfdec_player_get_image_size (widget->player, &w, &h); - if (widget->set_scale > 0.0) { - scale = widget->set_scale; - } else if (widget->player == NULL) { - scale = 1.0; - } else { - if (w != 0 && h != 0) - scale = MIN ((double) allocation->width / w, (double) allocation->height / h); - else - scale = 1.0; - } - w = ceil (w * scale); - h = ceil (h * scale); - if (w > allocation->width) - w = allocation->width; - if (h > allocation->height) - h = allocation->height; - - if (GTK_WIDGET_REALIZED (gtkwidget)) { - gdk_window_move_resize (gtkwidget->window, - allocation->x + (allocation->width - w) / 2, - allocation->y + (allocation->height - h) / 2, - w, h); - } - widget->real_scale = scale; -} - -static void -swfdec_widget_size_request (GtkWidget *gtkwidget, GtkRequisition *req) -{ - double scale; - SwfdecWidget * widget = SWFDEC_WIDGET (gtkwidget); - - if (widget->player == NULL) { - req->width = req->height = 0; - } else { - swfdec_player_get_image_size (widget->player, - &req->width, &req->height); - } - if (widget->set_scale != 0.0) - scale = widget->set_scale; - else - scale = 1.0; - req->width = ceil (req->width * scale); - req->height = ceil (req->height * scale); -} - -static void -swfdec_widget_update_cursor (SwfdecWidget *widget) -{ - GdkWindow *window = GTK_WIDGET (widget)->window; - GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (widget)); - SwfdecMouseCursor swfcursor; - GdkCursor *cursor; - - if (window == NULL) - return; - g_object_get (widget->player, "mouse-cursor", &swfcursor, NULL); - - switch (swfcursor) { - case SWFDEC_MOUSE_CURSOR_NONE: - { - GdkBitmap *bitmap; - GdkColor color = { 0, 0, 0, 0 }; - char data = 0; - - bitmap = gdk_bitmap_create_from_data (window, &data, 1, 1); - if (bitmap == NULL) - return; - cursor = gdk_cursor_new_from_pixmap (bitmap, bitmap, &color, &color, 0, 0); - gdk_window_set_cursor (window, cursor); - gdk_cursor_unref (cursor); - g_object_unref (bitmap); - break; - } - case SWFDEC_MOUSE_CURSOR_TEXT: - cursor = gdk_cursor_new_for_display (display, GDK_XTERM); - gdk_window_set_cursor (window, cursor); - gdk_cursor_unref (cursor); - break; - case SWFDEC_MOUSE_CURSOR_CLICK: - cursor = gdk_cursor_new_for_display (display, GDK_HAND2); - gdk_window_set_cursor (window, cursor); - gdk_cursor_unref (cursor); - break; - case SWFDEC_MOUSE_CURSOR_NORMAL: - cursor = gdk_cursor_new_for_display (display, GDK_LEFT_PTR); - gdk_window_set_cursor (window, cursor); - gdk_cursor_unref (cursor); - break; - default: - g_warning ("invalid cursor %d", (int) swfcursor); - gdk_window_set_cursor (window, NULL); - break; - } -} - -static void -swfdec_widget_realize (GtkWidget *widget) -{ - GdkWindowAttr attributes; - gint attributes_mask; - - GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); - - attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = widget->allocation.x; - attributes.y = widget->allocation.y; - attributes.width = widget->allocation.width; - attributes.height = widget->allocation.height; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.event_mask = gtk_widget_get_events (widget); - attributes.event_mask |= GDK_EXPOSURE_MASK | - GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_LEAVE_NOTIFY_MASK | - GDK_POINTER_MOTION_MASK | - GDK_POINTER_MOTION_HINT_MASK; - - attributes_mask = GDK_WA_X | GDK_WA_Y; - - widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), - &attributes, attributes_mask); - gdk_window_set_user_data (widget->window, widget); - - widget->style = gtk_style_attach (widget->style, widget->window); - - if (SWFDEC_WIDGET (widget)->player) { - swfdec_widget_update_cursor (SWFDEC_WIDGET (widget)); - } -} - -static void -swfdec_widget_class_init (SwfdecWidgetClass * g_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (g_class); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (g_class); - - object_class->dispose = swfdec_widget_dispose; - object_class->get_property = swfdec_widget_get_property; - object_class->set_property = swfdec_widget_set_property; - - g_object_class_install_property (object_class, PROP_PLAYER, - g_param_spec_object ("player", "player", "player that is displayed", - SWFDEC_TYPE_PLAYER, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - widget_class->realize = swfdec_widget_realize; - widget_class->size_request = swfdec_widget_size_request; - widget_class->size_allocate = swfdec_widget_size_allocate; - widget_class->expose_event = swfdec_widget_expose; - widget_class->button_press_event = swfdec_widget_button_press; - widget_class->button_release_event = swfdec_widget_button_release; - widget_class->motion_notify_event = swfdec_widget_motion_notify; - widget_class->leave_notify_event = swfdec_widget_leave_notify; -} - -static void -swfdec_widget_init (SwfdecWidget * widget) -{ - widget->real_scale = 1.0; - widget->interactive = TRUE; -} - -static void -swfdec_widget_invalidate_cb (SwfdecPlayer *player, double x, double y, - double width, double height, SwfdecWidget *widget) -{ - GdkRectangle rect; - - if (!GTK_WIDGET_REALIZED (widget)) - return; - rect.x = floor (x * widget->real_scale); - rect.y = floor (y * widget->real_scale); - rect.width = ceil ((x + width) * widget->real_scale) - rect.x; - rect.height = ceil ((y + height) * widget->real_scale) - rect.y; - gdk_window_invalidate_rect (GTK_WIDGET (widget)->window, &rect, FALSE); -} - -static void -swfdec_widget_notify_cb (SwfdecPlayer *player, GParamSpec *pspec, SwfdecWidget *widget) -{ - if (g_str_equal (pspec->name, "mouse-cursor")) { - swfdec_widget_update_cursor (widget); - } else if (g_str_equal (pspec->name, "initialized")) { - gtk_widget_queue_resize (GTK_WIDGET (widget)); - } -} - -void -swfdec_widget_set_player (SwfdecWidget *widget, SwfdecPlayer *player) -{ - g_return_if_fail (SWFDEC_IS_WIDGET (widget)); - g_return_if_fail (player == NULL || SWFDEC_IS_PLAYER (player)); - - if (widget->player) { - g_signal_handlers_disconnect_by_func (widget->player, swfdec_widget_invalidate_cb, widget); - g_signal_handlers_disconnect_by_func (widget->player, swfdec_widget_notify_cb, widget); - g_object_unref (widget->player); - } - widget->player = player; - if (player) { - g_signal_connect (player, "invalidate", G_CALLBACK (swfdec_widget_invalidate_cb), widget); - g_signal_connect (player, "notify", G_CALLBACK (swfdec_widget_notify_cb), widget); - g_object_ref (player); - swfdec_widget_update_cursor (widget); - } else { - if (GTK_WIDGET (widget)->window) - gdk_window_set_cursor (GTK_WIDGET (widget)->window, NULL); - } - gtk_widget_queue_resize (GTK_WIDGET (widget)); -} - -GtkWidget * -swfdec_widget_new (SwfdecPlayer *player) -{ - SwfdecWidget *widget; - - g_return_val_if_fail (player == NULL || SWFDEC_IS_PLAYER (player), NULL); - - widget = g_object_new (SWFDEC_TYPE_WIDGET, "player", player, NULL); - - return GTK_WIDGET (widget); -} - -void -swfdec_widget_set_scale (SwfdecWidget *widget, double scale) -{ - g_return_if_fail (SWFDEC_IS_WIDGET (widget)); - g_return_if_fail (scale >= 0.0); - - widget->set_scale = scale; - gtk_widget_queue_resize (GTK_WIDGET (widget)); -} - -double -swfdec_widget_get_scale (SwfdecWidget *widget) -{ - g_return_val_if_fail (SWFDEC_IS_WIDGET (widget), 1.0); - - return widget->set_scale; -} - -void -swfdec_widget_set_use_image (SwfdecWidget *widget, gboolean use_image) -{ - g_return_if_fail (SWFDEC_IS_WIDGET (widget)); - - widget->use_image = use_image; - gtk_widget_queue_draw (GTK_WIDGET (widget)); -} - -gboolean -swfdec_widget_get_use_image (SwfdecWidget *widget) -{ - g_return_val_if_fail (SWFDEC_IS_WIDGET (widget), 1.0); - - return widget->use_image; -} - -void -swfdec_widget_set_interactive (SwfdecWidget *widget, gboolean interactive) -{ - g_return_if_fail (SWFDEC_IS_WIDGET (widget)); - - widget->interactive = interactive; -} - -gboolean -swfdec_widget_get_interactive (SwfdecWidget *widget) -{ - g_return_val_if_fail (SWFDEC_IS_WIDGET (widget), FALSE); - - return widget->interactive; -} - diff --git a/player/swfdec_widget.h b/player/swfdec_widget.h deleted file mode 100644 index 1988f20..0000000 --- a/player/swfdec_widget.h +++ /dev/null @@ -1,73 +0,0 @@ -/* 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_WIDGET_H_ -#define _SWFDEC_WIDGET_H_ - -#include <gtk/gtk.h> -#include <libswfdec/swfdec.h> - -G_BEGIN_DECLS - -typedef struct _SwfdecWidget SwfdecWidget; -typedef struct _SwfdecWidgetClass SwfdecWidgetClass; - -#define SWFDEC_TYPE_WIDGET (swfdec_widget_get_type()) -#define SWFDEC_IS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_WIDGET)) -#define SWFDEC_IS_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_WIDGET)) -#define SWFDEC_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_WIDGET, SwfdecWidget)) -#define SWFDEC_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_WIDGET, SwfdecWidgetClass)) - -struct _SwfdecWidget -{ - GtkWidget widget; - - SwfdecPlayer * player; /* the video we play */ - - double real_scale; /* the real scale factor used */ - double set_scale; /* the set scale factor of the video */ - gboolean use_image; /* TRUE to draw to an image first before rendering to Gtk */ - gboolean interactive; /* if this widget propagates keyboard and mouse events */ - - int button; /* status of mouse button in displayed movie */ -}; - -struct _SwfdecWidgetClass -{ - GtkWidgetClass widget_class; -}; - -GType swfdec_widget_get_type (void); - -GtkWidget * swfdec_widget_new (SwfdecPlayer * player); - -void swfdec_widget_set_scale (SwfdecWidget * widget, - double scale); -double swfdec_widget_get_scale (SwfdecWidget * widget); -void swfdec_widget_set_use_image (SwfdecWidget * widget, - gboolean use_image); -gboolean swfdec_widget_get_use_image (SwfdecWidget * widget); -void swfdec_widget_set_interactive (SwfdecWidget * widget, - gboolean interactive); -gboolean swfdec_widget_get_interactive (SwfdecWidget * widget); -void swfdec_widget_set_player (SwfdecWidget * widget, - SwfdecPlayer * player); - -G_END_DECLS -#endif diff --git a/player/swfplay.c b/player/swfplay.c index 6941529..e9d62ad 100644 --- a/player/swfplay.c +++ b/player/swfplay.c @@ -24,10 +24,11 @@ #include <math.h> #include <libswfdec/swfdec.h> -#include "swfdec_playback.h" +#include <libswfdec-gtk/swfdec_playback.h> +#include <libswfdec-gtk/swfdec_source.h> +#include <libswfdec-gtk/swfdec_widget.h> + #include "swfdec_slow_loader.h" -#include "swfdec_source.h" -#include "swfdec_widget.h" static gpointer playback; diff-tree a6845d55ff3420aa75dd666e70ecf5dfb4fb5dd4 (from 269d33989c8bd3c9328b80bb3e78527fa845f011) Author: Benjamin Otte <otte@gnome.org> Date: Mon Mar 26 12:21:27 2007 +0200 s/SWF_(CFLAGS|LIBS)/SWFDEC_\1/ diff --git a/configure.ac b/configure.ac index d56afba..5ac3db0 100644 --- a/configure.ac +++ b/configure.ac @@ -202,10 +202,10 @@ AM_CONDITIONAL(HAVE_FFMPEG, [test "x$HAV AC_SUBST(GLOBAL_CFLAGS) -SWF_CFLAGS="$SWF_CFLAGS -I\$(top_srcdir) $GLIB_CFLAGS" -SWF_LIBS="$SWF_LIBS \$(top_builddir)/libswfdec/libswfdec-$SWFDEC_MAJORMINOR.la $MAD_LIBS $GLIB_LIBS -lz" -AC_SUBST(SWF_LIBS) -AC_SUBST(SWF_CFLAGS) +SWFDEC_CFLAGS="-I\$(top_srcdir) $GLIB_CFLAGS" +SWFDEC_LIBS="\$(top_builddir)/libswfdec/libswfdec-$SWFDEC_MAJORMINOR.la $GLIB_LIBS -lz" +AC_SUBST(SWFDEC_LIBS) +AC_SUBST(SWFDEC_CFLAGS) GTK_DOC_CHECK([1.6]) diff --git a/doc/Makefile.am b/doc/Makefile.am index ba9c4cb..fdb3962 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -126,8 +126,8 @@ expand_content_files # signals and properties. # e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) # e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) -INCLUDES=$(SWF_CFLAGS) $(CAIRO_CFLAGS) -GTKDOC_LIBS=$(SWF_LIBS) +INCLUDES=$(SWFDEC_CFLAGS) $(CAIRO_CFLAGS) +GTKDOC_LIBS=$(SWFDEC_LIBS) # This includes the standard gtk-doc make rules, copied by gtkdocize. include $(top_srcdir)/gtk-doc.make diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am index 1270262..f7be47f 100644 --- a/libswfdec/Makefile.am +++ b/libswfdec/Makefile.am @@ -85,14 +85,14 @@ libswfdec_@SWFDEC_MAJORMINOR@_la_SOURCES swfdec_xml.c libswfdec_@SWFDEC_MAJORMINOR@_la_CFLAGS = \ - $(GLOBAL_CFLAGS) $(SWF_CFLAGS) $(CAIRO_CFLAGS) $(GLIB_CFLAGS) $(PANGO_CFLAGS) \ + $(GLOBAL_CFLAGS) $(CAIRO_CFLAGS) $(GLIB_CFLAGS) $(PANGO_CFLAGS) \ -I$(srcdir)/jpeg/ $(js_cflags) $(LIBOIL_CFLAGS) $(FFMPEG_CFLAGS) \ -DG_LOG_DOMAIN=\"Swfdec\" libswfdec_@SWFDEC_MAJORMINOR@_la_LDFLAGS = \ -version-info $(SWFDEC_LIBVERSION) \ -export-symbols-regex '^(swfdec_.*)' \ $(CAIRO_LIBS) $(GLIB_LIBS) $(PANGO_LIBS) $(MAD_LIBS) $(FFMPEG_LIBS) \ - $(LIBOIL_LIBS) + $(LIBOIL_LIBS) -lz public_headers = \ swfdec.h \ diff --git a/libswfdec/js/Makefile.am b/libswfdec/js/Makefile.am index 9350a6d..eda1132 100644 --- a/libswfdec/js/Makefile.am +++ b/libswfdec/js/Makefile.am @@ -89,7 +89,7 @@ jscpucfg_SOURCES = \ jscpucfg.c \ jscpucfg.h -libjs_la_CFLAGS = $(GLOBAL_CFLAGS) $(SWF_CFLAGS) $(GLIB_CFLAGS) -I. -I$(top_builddir)/libswfdec/js \ +libjs_la_CFLAGS = $(GLOBAL_CFLAGS) $(GLIB_CFLAGS) -I. -I$(top_builddir)/libswfdec/js \ -DXP_UNIX -DDEBUG -fno-strict-aliasing libjs_la_LDFLAGS = -lm diff --git a/player/Makefile.am b/player/Makefile.am index 03217f0..f08f448 100644 --- a/player/Makefile.am +++ b/player/Makefile.am @@ -41,13 +41,13 @@ noinst_HEADERS = \ swfdec_slow_loader.h \ swfdec_widget.h -libswfdecui_la_CFLAGS = $(GLOBAL_CFLAGS) $(GTK_CFLAGS) $(SWF_CFLAGS) $(AUDIO_CFLAGS) -libswfdecui_la_LDFLAGS = $(GTK_LIBS) $(SWF_LIBS) $(AUDIO_LIBS) -swfplay_CFLAGS = $(GLOBAL_CFLAGS) $(GTK_CFLAGS) $(SWF_CFLAGS) -swfplay_LDFLAGS = $(GTK_LIBS) $(SWF_LIBS) +libswfdecui_la_CFLAGS = $(GLOBAL_CFLAGS) $(GTK_CFLAGS) $(SWFDEC_CFLAGS) $(AUDIO_CFLAGS) +libswfdecui_la_LDFLAGS = $(GTK_LIBS) $(SWFDEC_LIBS) $(AUDIO_LIBS) +swfplay_CFLAGS = $(GLOBAL_CFLAGS) $(GTK_CFLAGS) $(SWFDEC_CFLAGS) +swfplay_LDFLAGS = $(GTK_LIBS) $(SWFDEC_LIBS) swfplay_LDADD = libswfdecui.la -swfdebug_CFLAGS = $(GLOBAL_CFLAGS) $(GTK_CFLAGS) $(SWF_CFLAGS) -DXP_UNIX -I$(top_builddir)/libswfdec/js -swfdebug_LDFLAGS = $(GTK_LIBS) $(SWF_LIBS) +swfdebug_CFLAGS = $(GLOBAL_CFLAGS) $(GTK_CFLAGS) $(SWFDEC_CFLAGS) -DXP_UNIX -I$(top_builddir)/libswfdec/js +swfdebug_LDFLAGS = $(GTK_LIBS) $(SWFDEC_LIBS) swfdebug_LDADD = libswfdecui.la $(top_builddir)/libswfdec/js/libjs.la endif diff --git a/test/Makefile.am b/test/Makefile.am index e31046b..a38faf4 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -8,24 +8,24 @@ else noinst_PROGRAMS = swfdec-extract dump parse endif -dump_CFLAGS = $(GLOBAL_CFLAGS) $(SWF_CFLAGS) $(CAIRO_CFLAGS) $(PANGO_CFLAGS) -DXP_UNIX -I$(top_builddir)/libswfdec/js -dump_LDFLAGS = $(SWF_LIBS) $(CAIRO_LIBS) $(PANGO_LIBS) +dump_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(CAIRO_CFLAGS) $(PANGO_CFLAGS) -DXP_UNIX -I$(top_builddir)/libswfdec/js +dump_LDFLAGS = $(SWFDEC_LIBS) $(CAIRO_LIBS) $(PANGO_LIBS) -parse_CFLAGS = $(GLOBAL_CFLAGS) $(SWF_CFLAGS) $(CAIRO_CFLAGS) -parse_LDFLAGS = $(SWF_LIBS) $(CAIRO_LIBS) +parse_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(CAIRO_CFLAGS) +parse_LDFLAGS = $(SWFDEC_LIBS) $(CAIRO_LIBS) -swfdec_extract_CFLAGS = $(GLOBAL_CFLAGS) $(SWF_CFLAGS) $(CAIRO_CFLAGS) -DXP_UNIX -I$(top_builddir)/libswfdec/js -swfdec_extract_LDFLAGS = $(SWF_LIBS) $(CAIRO_LIBS) +swfdec_extract_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(CAIRO_CFLAGS) -DXP_UNIX -I$(top_builddir)/libswfdec/js +swfdec_extract_LDFLAGS = $(SWFDEC_LIBS) $(CAIRO_LIBS) -libswfedit_la_CFLAGS = $(GLOBAL_CFLAGS) $(SWF_CFLAGS) $(GTK_CFLAGS) -DXP_UNIX -I$(top_builddir)/libswfdec/js -libswfedit_la_LDFLAGS = $(SWF_LIBS) $(GTK_LIBS) +libswfedit_la_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(GTK_CFLAGS) -DXP_UNIX -I$(top_builddir)/libswfdec/js +libswfedit_la_LDFLAGS = $(SWFDEC_LIBS) $(GTK_LIBS) -swfedit_CFLAGS = $(GLOBAL_CFLAGS) $(SWF_CFLAGS) $(GTK_CFLAGS) -DXP_UNIX -I$(top_builddir)/libswfdec/js -swfedit_LDFLAGS = $(SWF_LIBS) $(GTK_LIBS) +swfedit_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(GTK_CFLAGS) -DXP_UNIX -I$(top_builddir)/libswfdec/js +swfedit_LDFLAGS = $(SWFDEC_LIBS) $(GTK_LIBS) swfedit_LDADD = libswfedit.la -swfscript_CFLAGS = $(GLOBAL_CFLAGS) $(SWF_CFLAGS) $(GTK_CFLAGS) -DXP_UNIX -I$(top_builddir)/libswfdec/js -swfscript_LDFLAGS = $(SWF_LIBS) $(GTK_LIBS) +swfscript_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(GTK_CFLAGS) -DXP_UNIX -I$(top_builddir)/libswfdec/js +swfscript_LDFLAGS = $(SWFDEC_LIBS) $(GTK_LIBS) swfscript_LDADD = libswfedit.la libswfedit_la_SOURCES = \ diff --git a/test/image/Makefile.am b/test/image/Makefile.am index 84bed85..bbdbb2d 100644 --- a/test/image/Makefile.am +++ b/test/image/Makefile.am @@ -2,8 +2,8 @@ check_PROGRAMS = image TESTS = $(check_PROGRAMS) image_SOURCES = image.c -image_CFLAGS = $(GLOBAL_CFLAGS) $(SWF_CFLAGS) $(CAIRO_CFLAGS) -image_LDFLAGS = $(SWF_LIBS) $(CAIRO_LIBS) +image_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(CAIRO_CFLAGS) +image_LDFLAGS = $(SWFDEC_LIBS) $(CAIRO_LIBS) EXTRA_DIST = \ README \ diff --git a/test/sound/Makefile.am b/test/sound/Makefile.am index 411d1d1..9face8b 100644 --- a/test/sound/Makefile.am +++ b/test/sound/Makefile.am @@ -13,8 +13,8 @@ downsample_CFLAGS = $(GLOBAL_CFLAGS) $(G downsample_LDFLAGS = $(GLIB_LIBS) sound_SOURCES = sound.c -sound_CFLAGS = $(GLOBAL_CFLAGS) $(SWF_CFLAGS) $(CAIRO_CFLAGS) -sound_LDFLAGS = $(SWF_LIBS) $(CAIRO_LIBS) +sound_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(CAIRO_CFLAGS) +sound_LDFLAGS = $(SWFDEC_LIBS) $(CAIRO_LIBS) EXTRA_DIST = \ README \ diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am index f11d827..c7b4870 100644 --- a/test/trace/Makefile.am +++ b/test/trace/Makefile.am @@ -4,8 +4,8 @@ TESTS = $(check_PROGRAMS) trace_SOURCES = trace.c -trace_CFLAGS = $(GLOBAL_CFLAGS) $(SWF_CFLAGS) $(CAIRO_CFLAGS) -trace_LDFLAGS = $(SWF_LIBS) $(CAIRO_LIBS) +trace_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(CAIRO_CFLAGS) +trace_LDFLAGS = $(SWFDEC_LIBS) $(CAIRO_LIBS) EXTRA_DIST = \ README \ diff --git a/test/various/Makefile.am b/test/various/Makefile.am index b16762f..59beb05 100644 --- a/test/various/Makefile.am +++ b/test/various/Makefile.am @@ -2,10 +2,10 @@ check_PROGRAMS = ringbuffer urlencode TESTS = $(check_PROGRAMS) ringbuffer_SOURCES = ringbuffer.c -ringbuffer_CFLAGS = $(GLOBAL_CFLAGS) $(SWF_CFLAGS) $(CAIRO_CFLAGS) -ringbuffer_LDFLAGS = $(SWF_LIBS) $(CAIRO_LIBS) +ringbuffer_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(CAIRO_CFLAGS) +ringbuffer_LDFLAGS = $(SWFDEC_LIBS) $(CAIRO_LIBS) urlencode_SOURCES = urlencode.c -urlencode_CFLAGS = $(GLOBAL_CFLAGS) $(SWF_CFLAGS) $(CAIRO_CFLAGS) -urlencode_LDFLAGS = $(SWF_LIBS) $(CAIRO_LIBS) +urlencode_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(CAIRO_CFLAGS) +urlencode_LDFLAGS = $(SWFDEC_LIBS) $(CAIRO_LIBS) diff-tree 269d33989c8bd3c9328b80bb3e78527fa845f011 (from 20fce106dfb4e4f314fa9ed2eb639448a0b5d854) Author: Benjamin Otte <otte@gnome.org> Date: Mon Mar 26 12:04:30 2007 +0200 Add build infrastructure for a libswfdec-gtk diff --git a/Makefile.am b/Makefile.am index da1c94a..25bbed2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,6 @@ SUBDIRS= \ libswfdec \ + libswfdec-gtk \ player \ doc \ test @@ -18,13 +19,20 @@ EXTRA_DIST=depcomp \ m4/ax_create_stdint_h.m4 pkgconfigdir = $(libdir)/pkgconfig +if WITH_GTK +pkgconfig_DATA = swfdec-@SWFDEC_MAJORMINOR@.pc swfdec-gtk-@SWFDEC_MAJORMINOR@.pc +else pkgconfig_DATA = swfdec-@SWFDEC_MAJORMINOR@.pc +endif -CLEANFILES = swfdec-$(SWFDEC_MAJORMINOR).pc +CLEANFILES = swfdec-$(SWFDEC_MAJORMINOR).pc swfdec-gtk-$(SWFDEC_MAJORMINOR).pc swfdec-@SWFDEC_MAJORMINOR@.pc: swfdec.pc cp swfdec.pc swfdec-@SWFDEC_MAJORMINOR@.pc +swfdec-gtk-@SWFDEC_MAJORMINOR@.pc: swfdec-gtk.pc + cp swfdec-gtk.pc swfdec-gtk-@SWFDEC_MAJORMINOR@.pc + # build documentation when doing distcheck DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc diff --git a/configure.ac b/configure.ac index 70976c9..d56afba 100644 --- a/configure.ac +++ b/configure.ac @@ -82,13 +82,31 @@ fi AC_SUBST(PANGO_LIBS) AC_SUBST(PANGO_CFLAGS) -PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.8.0, HAVE_GTK=yes, HAVE_GTK=no) -AC_SUBST(GTK_LIBS) -AC_SUBST(GTK_CFLAGS) -if test "$HAVE_GTK" = "no"; then - AC_MSG_WARN([cannot find GTK+-2.0, player will be disabled]) +AC_ARG_ENABLE(gtk, + AS_HELP_STRING([--enable-gtk], + [enable Gtk integration (default=yes)])], + enable_gtk=$enableval, + enable_gtk="yes") + +dnl +dnl GTK: We want this for swfdec-gtk +dnl +GTK_REQUIRES=2.8.0 +AC_SUBST(GTK_REQUIRES) +if test "$enable_gtk" = "yes"; then + PKG_CHECK_MODULES(GTK, gtk+-2.0 >= $GTK_REQUIRES, HAVE_GTK=yes, HAVE_GTK=no) + if test "$HAVE_GTK" = "no"; then + AC_MSG_WARN([cannot find GTK+-2.0, player will be disabled]) + fi + if test "x$HAVE_GTK" = xyes; then + AC_DEFINE(HAVE_GTK, 1, [Define if Gtk is enabled]) + else + AC_MSG_ERROR([Couldn't find a suitable Gtk version. You need at least version $GTK_REQUIRES]) + fi +else + AC_MSG_WARN([*** Gtk support was not enabled. ***]) fi -AM_CONDITIONAL(WITH_GTK,[test "$HAVE_GTK" != "no"]) +AM_CONDITIONAL(WITH_GTK, [test "x$HAVE_GTK" = xyes]) dnl dnl audio backend @@ -211,6 +229,7 @@ doc/Makefile libswfdec/Makefile libswfdec/jpeg/Makefile libswfdec/js/Makefile +libswfdec-gtk/Makefile player/Makefile test/Makefile test/image/Makefile @@ -218,6 +237,7 @@ test/sound/Makefile test/trace/Makefile test/various/Makefile swfdec.pc +swfdec-gtk.pc swfdec.spec ) diff --git a/libswfdec-gtk/.gitignore b/libswfdec-gtk/.gitignore new file mode 100644 index 0000000..87c0f2d --- /dev/null +++ b/libswfdec-gtk/.gitignore @@ -0,0 +1,13 @@ +*~ +CVS +.cvsignore +.deps +.libs + +Makefile +Makefile.in +*.o +*.la +*.lo +*.loT + diff --git a/libswfdec-gtk/Makefile.am b/libswfdec-gtk/Makefile.am new file mode 100644 index 0000000..e69de29 diff --git a/swfdec-gtk.pc.in b/swfdec-gtk.pc.in new file mode 100644 index 0000000..1b866f0 --- /dev/null +++ b/swfdec-gtk.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@/swfdec-@SWFDEC_MAJORMINOR@ + +Name: swfdec-gtk +Description: Support for playing Flash files in Gtk using Swfdec +Version: @VERSION@ +Requires: swfdec-@SWFDEC_MAJORMINOR@ = @PACKAGE_VERSION@ gtk+-2.0 >= @GTK_REQUIRES@ +Libs: -L${libdir} -lswfdec-@SWFDEC_MAJORMINOR@ +Cflags: -I${includedir}
Maybe Matching Threads
- 15 commits - libswfdec/swfdec_as_strings.c libswfdec/swfdec_initialize.as libswfdec/swfdec_initialize.h libswfdec/swfdec_movie.c libswfdec/swfdec_movie.h libswfdec/swfdec_sprite.c libswfdec/swfdec_sprite_movie.c libswfdec/swfdec_system_as.c
- 2 commits - libswfdec-gtk/swfdec_gtk_loader.c libswfdec-gtk/swfdec_gtk_widget.c
- Branch 'vivi' - 15 commits - configure.ac libswfdec/Makefile.am libswfdec/swfdec_as_context.c libswfdec/swfdec_as_debugger.h libswfdec/swfdec_as_object.c libswfdec/swfdec_movie.c libswfdec/swfdec_script.c libswfdec/swfdec_types.h vivified/core vivified/ui
- 5 commits - libswfdec-gtk/Makefile.am libswfdec-gtk/swfdec_gtk_widget.c libswfdec/Makefile.am libswfdec/swfdec_script.h player/Makefile.am test/Makefile.am
- 13 commits - libswfdec-gtk/Makefile.am libswfdec-gtk/swfdec_gtk_keys.c libswfdec-gtk/swfdec_gtk_keys.h libswfdec-gtk/swfdec_gtk_widget.c libswfdec/Makefile.am libswfdec/swfdec_as_types.c libswfdec/swfdec.h libswfdec/swfdec_initialize.as