=== modified file '.bzrignore' --- .bzrignore 2008-12-12 16:57:22 +0000 +++ .bzrignore 2009-04-20 16:29:39 +0000 @@ -331,3 +331,5 @@ testsuite/actionscript.all/site.bak testsuite/libamf.all/site.bak testsuite/libnet.all/generate_amfbins +gui/gtk_widget/gnash.c +py-compile === modified file 'configure.ac' --- configure.ac 2009-04-16 00:11:19 +0000 +++ configure.ac 2009-04-20 14:26:09 +0000 @@ -1111,6 +1111,14 @@ dnl If python support is enabled, look for the flags and libs if test x"$python" = xyes; then GNASH_PATH_PYTHON + + AM_PATH_PYTHON + AC_PATH_PROG(PYGTK_CODEGEN, pygtk-codegen-2.0, no) + + PKG_CHECK_MODULES(PYGTK, pygtk-2.0) + + PYGTK_DEFSDIR=`$PKG_CONFIG --variable=defsdir pygtk-2.0` + AC_SUBST(PYGTK_DEFSDIR) fi AM_CONDITIONAL([USE_PYTHON], test x"$python" != xno) @@ -2224,6 +2232,7 @@ testsuite/libamf.all/Makefile testsuite/libnet.all/Makefile gui/Makefile +gui/gtk_widget/Makefile gui/Info.plist extensions/Makefile extensions/dejagnu/Makefile === modified file 'gui/Makefile.am' --- gui/Makefile.am 2009-04-06 20:29:42 +0000 +++ gui/Makefile.am 2009-04-20 14:45:53 +0000 @@ -22,6 +22,9 @@ AUTOMAKE_OPTIONS = -Wno-portability +SUBDIRS = \ + gtk_widget + localedir = $(datadir)/locale # this is where Gnash plugins get installed === modified file 'gui/am-frag/gtk.am' --- gui/am-frag/gtk.am 2009-02-25 22:33:03 +0000 +++ gui/am-frag/gtk.am 2009-04-20 14:27:36 +0000 @@ -32,14 +32,14 @@ if BUILD_OGL_RENDERER gtk_gnash_CPPFLAGS += $(OPENGL_CFLAGS) gtk_gnash_SOURCES += gtk_glue_gtkglext.cpp gtk_glue_gtkglext.h \ - gtk.cpp gtksup.h gtk_glue.h + gtk.cpp gtksup.h gtk_glue.h gnash-canvas.cpp gtk_gnash_LDADD = $(top_builddir)/backend/libgnashogl.la \ $(GNASH_LIBS) $(GTK_LIBS) $(OPENGL_LIBS) endif # BUILD_OGL_RENDERER if BUILD_AGG_RENDERER gtk_gnash_CPPFLAGS += $(AGG_CFLAGS) gtk_gnash_SOURCES += gtk_glue_agg.cpp gtk_glue_agg.h \ - gtk.cpp gtksup.h gtk_glue.h + gtk.cpp gtksup.h gtk_glue.h gnash-canvas.cpp gtk_gnash_LDADD = $(top_builddir)/backend/libgnashagg.la \ $(GNASH_LIBS) $(GTK_LIBS) $(AGG_LIBS) $(CAIRO_LIBS) if HAVE_XV @@ -50,7 +50,7 @@ if BUILD_CAIRO_RENDERER gtk_gnash_CPPFLAGS += $(CAIRO_CFLAGS) gtk_gnash_SOURCES += gtk_glue_cairo.cpp gtk_glue_cairo.h \ - gtk.cpp gtksup.h gtk_glue.h + gtk.cpp gtksup.h gtk_glue.h gnash-canvas.cpp gtk_gnash_LDADD = $(top_builddir)/backend/libgnashcairo.la \ $(GNASH_LIBS) $(GTK_LIBS) $(CAIRO_LIBS) endif # BUILD_CAIRO_RENDERER === added file 'gui/gnash-canvas.cpp' --- gui/gnash-canvas.cpp 1970-01-01 00:00:00 +0000 +++ gui/gnash-canvas.cpp 2009-04-18 19:00:59 +0000 @@ -0,0 +1,192 @@ +// gnash-canvas.cpp: Gtk canvas widget for gnash +// +// Copyright (C) 2009 Free Software Foundation, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +// + +#include "gnash-canvas.h" + +#include "log.h" +#include "gtk_glue.h" + +#ifdef RENDERER_OPENGL +#include "gtk_glue_gtkglext.h" +#endif + +#ifdef RENDERER_CAIRO +#include "gtk_glue_cairo.h" +#endif + +#ifdef RENDERER_AGG +#include "gtk_glue_agg.h" +#ifdef HAVE_XV +#include "gtk_glue_agg_xv.h" +#endif // HAVE_XV +#endif + +struct _GnashCanvas { + GtkDrawingArea base_instance; + + std::auto_ptr glue; + gnash::render_handler *renderer; +}; + +G_DEFINE_TYPE(GnashCanvas, gnash_canvas, GTK_TYPE_DRAWING_AREA) + +static GObjectClass *parent_class = NULL; + +static void gnash_canvas_class_init(GnashCanvasClass *gnash_canvas_class); +static void gnash_canvas_init(GnashCanvas *canvas); +static void gnash_canvas_size_allocate(GtkWidget *widget, GtkAllocation *allocation); +static gboolean gnash_canvas_expose_event(GtkWidget *widget, GdkEventExpose *event); +static gboolean gnash_canvas_configure_event(GtkWidget *widget, GdkEventConfigure *event); + +GtkWidget * +gnash_canvas_new (void) +{ + GNASH_REPORT_FUNCTION; + return GTK_WIDGET(g_object_new (GNASH_TYPE_CANVAS, NULL)); +} + +static void +gnash_canvas_class_init(GnashCanvasClass *gnash_canvas_class) +{ + GNASH_REPORT_FUNCTION; + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(gnash_canvas_class); + + parent_class = (GObjectClass *) g_type_class_peek_parent(gnash_canvas_class); + + widget_class->size_allocate = gnash_canvas_size_allocate; + widget_class->expose_event = gnash_canvas_expose_event; + widget_class->configure_event = gnash_canvas_configure_event; +} + +static void +gnash_canvas_init(GnashCanvas *canvas) +{ + GNASH_REPORT_FUNCTION; + gtk_widget_set_double_buffered(GTK_WIDGET(canvas), FALSE); + + // If we don't set this flag we won't be able to grab focus + // ( grabFocus() would be a no-op ) + GTK_WIDGET_SET_FLAGS (GTK_WIDGET(canvas), GTK_CAN_FOCUS); +} + +static void +gnash_canvas_size_allocate(GtkWidget *widget, GtkAllocation *allocation) +{ + GNASH_REPORT_FUNCTION; + GnashCanvas *canvas = GNASH_CANVAS(widget); + + gnash::log_debug("gnash_canvas_size_allocate %d %d", allocation->width, allocation->height); + + canvas->glue->setRenderHandlerSize(allocation->width, allocation->height); + GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation); +} + +static gboolean +gnash_canvas_expose_event(GtkWidget *widget, GdkEventExpose *event) +{ + GnashCanvas *canvas = GNASH_CANVAS(widget); + gint num_rects; + GdkRectangle* rects; + + // In some versions of GTK this can't be const... + GdkRegion* nonconst_region = const_cast(event->region); + + gdk_region_get_rectangles (nonconst_region, &rects, &num_rects); + assert(num_rects); + + for (int i=0; iglue->render(cur_rect.x, cur_rect.y, cur_rect.x + cur_rect.width, + cur_rect.y + cur_rect.height); + } + + g_free(rects); + + return TRUE; +} + +static gboolean +gnash_canvas_configure_event(GtkWidget *widget, GdkEventConfigure *event) +{ + GNASH_REPORT_FUNCTION; + GnashCanvas *canvas = GNASH_CANVAS(widget); + canvas->glue->configure(widget, event); + + return FALSE; +} + +void +gnash_canvas_setup(GnashCanvas *canvas, int argc, char **argv[]) +{ + GNASH_REPORT_FUNCTION; + // TODO: don't rely on a macro to select renderer +#ifdef RENDERER_CAIRO + canvas->glue.reset(new gnash::GtkCairoGlue); +#elif defined(RENDERER_OPENGL) + canvas->glue.reset(new gnash::GtkGlExtGlue); +#elif defined(RENDERER_AGG) && !defined(HAVE_XV) + canvas->glue.reset(new gnash::GtkAggGlue); +#elif defined(RENDERER_AGG) && defined(HAVE_XV) + RcInitFile& rcfile = RcInitFile::getDefaultInstance(); + + if (rcfile.useXv()) { + canvas->glue.reset(new gnash::GtkAggXvGlue); + if (!canvas->glue->init (argc, argv)) { + canvas->glue.reset(new gnash::GtkAggGlue); + canvas->glue->init(argc, argv); + } + } else { + canvas->glue.reset(new gnash::GtkAggGlue); + canvas->glue->init(argc, argv); + } +#endif + +#if ! (defined(HAVE_XV) && defined(RENDERER_AGG)) + canvas->glue->init (argc, argv); +#endif + +#ifdef RENDERER_OPENGL + // OpenGL glue needs to prepare the drawing area for OpenGL rendering before + // widgets are realized and before the configure event is fired. + // TODO: find a way to make '_glue' use independent from actual renderer in use + canvas->glue->prepDrawingArea(canvas); +#endif + +#if defined(RENDERER_CAIRO) || defined(RENDERER_AGG) + // cairo needs the _drawingArea.window to prepare it .. + // TODO: find a way to make 'glue' use independent from actual renderer in use + canvas->glue->prepDrawingArea(GTK_WIDGET(canvas)); +#endif + + canvas->renderer = canvas->glue->createRenderHandler(); + set_render_handler(canvas->renderer); +} + +void +gnash_canvas_before_rendering(GnashCanvas *canvas) +{ + canvas->glue->beforeRendering(); +} + +gnash::render_handler * +gnash_canvas_get_renderer(GnashCanvas *canvas) +{ + return canvas->renderer; +} + === added file 'gui/gnash-canvas.h' --- gui/gnash-canvas.h 1970-01-01 00:00:00 +0000 +++ gui/gnash-canvas.h 2009-04-18 09:39:41 +0000 @@ -0,0 +1,52 @@ +// gnash-canvas.h: Gtk canvas widget for gnash +// +// Copyright (C) 2009 Free Software Foundation, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +// + +#ifndef __GNASH_CANVAS_H__ +#define __GNASH_CANVAS_H__ + +#include +#include "render_handler.h" + +G_BEGIN_DECLS + +typedef struct _GnashCanvas GnashCanvas; +typedef struct _GnashCanvasClass GnashCanvasClass; + +#define GNASH_TYPE_CANVAS (gnash_canvas_get_type()) +#define GNASH_CANVAS(object) (G_TYPE_CHECK_INSTANCE_CAST((object), GNASH_TYPE_CANVAS, GnashCanvas)) +#define GNASH_CANVAS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNASH_TYPE_CANVAS, GnashCanvasClass)) +#define GNASH_IS_CANVAS(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), GNASH_TYPE_CANVAS)) +#define GNASH_IS_CANVAS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNASH_TYPE_CANVAS)) +#define GNASH_CANVAS_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), GNASH_TYPE_CANVAS, GnashCanvasClass)) + +struct _GnashCanvasClass { + GtkDrawingAreaClass base_class; +}; + +GType gnash_canvas_get_type (void); +GtkWidget *gnash_canvas_new (void); + +void gnash_canvas_setup (GnashCanvas *canvas, int argc, char **argv[]); +void gnash_canvas_before_rendering (GnashCanvas *canvas); +gnash::render_handler *gnash_canvas_get_renderer (GnashCanvas *canvas); + +G_END_DECLS + +#endif + === modified file 'gui/gtk.cpp' --- gui/gtk.cpp 2009-03-26 08:16:06 +0000 +++ gui/gtk.cpp 2009-04-20 14:38:37 +0000 @@ -42,6 +42,8 @@ #include #include +#include "gnash-canvas.h" + #ifdef HAVE_FFMPEG_AVCODEC_H extern "C" { # include "ffmpeg/avcodec.h" // Only for the version number @@ -58,21 +60,6 @@ # include "gst/gstversion.h" // Only for the version number #endif -#ifdef RENDERER_OPENGL -#include "gtk_glue_gtkglext.h" -#endif - -#ifdef RENDERER_CAIRO -#include "gtk_glue_cairo.h" -#endif - -#ifdef RENDERER_AGG -#include "gtk_glue_agg.h" -#ifdef HAVE_XV -#include "gtk_glue_agg_xv.h" -#endif // HAVE_XV -#endif - #ifdef GUI_HILDON # include #endif @@ -102,8 +89,6 @@ // Event handlers gboolean realizeEvent(GtkWidget *widget, GdkEvent *event, gpointer data); gboolean deleteEvent(GtkWidget *widget, GdkEvent *event, gpointer data); - gboolean exposeEvent(GtkWidget *widget, GdkEventExpose *event, - gpointer data); gboolean configureEvent(GtkWidget *widget, GdkEventConfigure *event, gpointer data); gboolean keyPressEvent(GtkWidget *widget, GdkEventKey *event, @@ -152,11 +137,10 @@ ,_window(0) ,_resumeButton(0) ,_overlay(0) - ,_drawingArea(0) + ,_canvas(0) ,_popup_menu(0) ,_menubar(0) ,_vbox(0) - ,_glue() ,_advanceSourceTimer(0) { } @@ -170,34 +154,6 @@ #ifdef GUI_HILDON _hildon_program = hildon_program_get_instance(); #endif - - // TODO: don't rely on a macro to select renderer -#ifdef RENDERER_CAIRO - _glue.reset(new GtkCairoGlue); -#elif defined(RENDERER_OPENGL) - _glue.reset(new GtkGlExtGlue); -#elif defined(RENDERER_AGG) && !defined(HAVE_XV) - _glue.reset(new GtkAggGlue); -#elif defined(RENDERER_AGG) && defined(HAVE_XV) - RcInitFile& rcfile = RcInitFile::getDefaultInstance(); - - if (rcfile.useXv()) { - _glue.reset(new GtkAggXvGlue); - if (!_glue->init (argc, argv)) { - _glue.reset(new GtkAggGlue); - _glue->init(argc, argv); - } - } else { - _glue.reset(new GtkAggGlue); - _glue->init(argc, argv); - } -#endif - -#if ! (defined(HAVE_XV) && defined(RENDERER_AGG)) - if (!_glue->init (argc, argv)) { - return false; - } -#endif addPixmapDirectory (PKGDATADIR); @@ -216,11 +172,13 @@ addGnashIcon(GTK_WINDOW(_window)); - _drawingArea = gtk_drawing_area_new(); + _canvas = gnash_canvas_new(); + gnash_canvas_setup(GNASH_CANVAS(_canvas), argc, argv); + _renderer = gnash_canvas_get_renderer(GNASH_CANVAS(_canvas)); // Increase reference count to prevent its destruction (which could happen // later if we remove it from its container). - g_object_ref(G_OBJECT(_drawingArea)); + g_object_ref(G_OBJECT(_canvas)); _resumeButton = gtk_button_new(); gtk_container_add(GTK_CONTAINER(_resumeButton), @@ -233,19 +191,8 @@ // This callback indirectly results in playHook() being called. g_signal_connect(_resumeButton, "clicked", G_CALLBACK(menuPlay), this); - // If we don't set this flag we won't be able to grab focus - // ( grabFocus() would be a no-op ) - GTK_WIDGET_SET_FLAGS (GTK_WIDGET(_drawingArea), GTK_CAN_FOCUS); - createMenu(); -#ifdef RENDERER_OPENGL - // OpenGL _glue needs to prepare the drawing area for OpenGL rendering before - // widgets are realized and before the configure event is fired. - // TODO: find a way to make '_glue' use independent from actual renderer in use - _glue->prepDrawingArea(_drawingArea); -#endif - // A vertical box is used to allow display of the menu bar and paused widget _vbox = gtk_vbox_new(FALSE, 0); gtk_widget_show(_vbox); @@ -257,19 +204,13 @@ } #endif - gtk_box_pack_start(GTK_BOX(_vbox), _drawingArea, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(_vbox), _canvas, TRUE, TRUE, 0); setupEvents(); gtk_widget_realize(_window); - gtk_widget_show(_drawingArea); + gtk_widget_show(_canvas); gtk_widget_show(_window); - -#if defined(RENDERER_CAIRO) || defined(RENDERER_AGG) - // cairo needs the _drawingArea.window to prepare it .. - // TODO: find a way to make '_glue' use independent from actual renderer in use - _glue->prepDrawingArea(_drawingArea); -#endif #ifdef USE_LIRC lirc = new Lirc(); @@ -280,10 +221,6 @@ log_debug(_("LIRC daemon not running")); } #endif - - _renderer = _glue->createRenderHandler(); - if ( ! _renderer ) return false; - set_render_handler(_renderer); // The first time stop() was called, stopHook() might not have had a chance // to do anything, because GTK+ wasn't garanteed to be initialised. @@ -396,7 +333,7 @@ // It could be a good hack if it were done earlier. // There really doesn't seem to be a proper way of setting the // starting size of a widget but allowing it to be shrunk. - gtk_widget_set_size_request(_drawingArea, -1, -1); + gtk_widget_set_size_request(_canvas, -1, -1); gtk_window_fullscreen(GTK_WINDOW(_window)); showMenu(false); @@ -467,7 +404,7 @@ } // The parent of _drawingArea is different for the plugin in fullscreen - gdk_window_set_cursor(_drawingArea->window, gdkcursor); + gdk_window_set_cursor(_canvas->window, gdkcursor); if (gdkcursor) { gdk_cursor_unref(gdkcursor); @@ -493,7 +430,7 @@ GdkCursor* cursor = gdk_cursor_new_from_pixmap(pixmap, pixmap, color, color, 0, 0); - gdk_window_set_cursor (_drawingArea->window, cursor); + gdk_window_set_cursor (_canvas->window, cursor); g_free(color); g_object_unref(pixmap); @@ -558,11 +495,11 @@ void GtkGui::setupWindowEvents() { - g_signal_connect(gtk_widget_get_toplevel(_drawingArea), + g_signal_connect(gtk_widget_get_toplevel(_canvas), "delete_event", G_CALLBACK(deleteEvent), this); - g_signal_connect(gtk_widget_get_toplevel(_drawingArea), + g_signal_connect(gtk_widget_get_toplevel(_canvas), "key_press_event", G_CALLBACK(keyPressEvent), this); - g_signal_connect(gtk_widget_get_toplevel(_drawingArea), + g_signal_connect(gtk_widget_get_toplevel(_canvas), "key_release_event", G_CALLBACK(keyReleaseEvent), this); } @@ -573,29 +510,30 @@ setupWindowEvents(); - gtk_widget_add_events(_drawingArea, GDK_EXPOSURE_MASK + gtk_widget_add_events(_canvas, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_POINTER_MOTION_MASK); - g_signal_connect_swapped(_drawingArea, "button_press_event", + g_signal_connect_swapped(_canvas, "button_press_event", G_CALLBACK(popupHandler), _popup_menu); - g_signal_connect(_drawingArea, "button_press_event", + g_signal_connect(_canvas, "button_press_event", G_CALLBACK(buttonPressEvent), this); - g_signal_connect(_drawingArea, "button_release_event", + g_signal_connect(_canvas, "button_release_event", G_CALLBACK(buttonReleaseEvent), this); - g_signal_connect(_drawingArea, "motion_notify_event", + g_signal_connect(_canvas, "motion_notify_event", G_CALLBACK(motionNotifyEvent), this); - g_signal_connect_after(_drawingArea, "realize", + g_signal_connect_after(_canvas, "realize", G_CALLBACK (realizeEvent), NULL); - g_signal_connect(_drawingArea, "configure_event", + + // connect_after because we are going to cause a rendering and the canvas + // widget should have had a chance to update the size of the render area + g_signal_connect_after(_canvas, "configure_event", G_CALLBACK (configureEvent), this); - g_signal_connect(_drawingArea, "expose_event", - G_CALLBACK (exposeEvent), this); return true; } @@ -603,7 +541,7 @@ void GtkGui::grabFocus() { - gtk_widget_grab_focus(GTK_WIDGET(_drawingArea)); + gtk_widget_grab_focus(GTK_WIDGET(_canvas)); } void @@ -722,7 +660,7 @@ // Advantage: The window is sized correctly, no matter what other // widgets are visible // Disadvantage: The window cannot be shrinked, which is bad. - gtk_widget_set_size_request(_drawingArea, width, height); + gtk_widget_set_size_request(_canvas, width, height); } return ret; @@ -819,7 +757,6 @@ _height = height; _validbounds.setTo(0, 0, _width, _height); - _glue->setRenderHandlerSize(_width, _height); return true; } @@ -827,34 +764,13 @@ void GtkGui::beforeRendering() { - _glue->beforeRendering(); + gnash_canvas_before_rendering(GNASH_CANVAS(_canvas)); } void GtkGui::renderBuffer() { - gdk_window_process_updates(_drawingArea->window, false); -} - -void -GtkGui::expose(const GdkRegion *region) -{ - gint num_rects; - GdkRectangle* rects; - - // In some versions of GTK this can't be const... - GdkRegion* nonconst_region = const_cast(region); - - gdk_region_get_rectangles (nonconst_region, &rects, &num_rects); - assert(num_rects); - - for (int i=0; irender(cur_rect.x, cur_rect.y, cur_rect.x + cur_rect.width, - cur_rect.y + cur_rect.height); - } - - g_free(rects); + gdk_window_process_updates(_canvas->window, false); } void @@ -897,7 +813,7 @@ // We add the rectangle to the part of the window to be redrawn // (also known as the "clipping" or "damaged" area). in renderBuffer(), // we force a redraw. - gdk_window_invalidate_rect(_drawingArea->window, &rect, false); + gdk_window_invalidate_rect(_canvas->window, &rect, false); } } @@ -2291,31 +2207,14 @@ /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// - -gboolean -exposeEvent(GtkWidget *const /*widget*/, GdkEventExpose *const event, - const gpointer data) -{ - - GtkGui* gui = static_cast(data); - - gui->expose(event->region); - - return TRUE; -} - -gboolean -configureEvent(GtkWidget *const widget, GdkEventConfigure *const event, +gboolean +configureEvent(GtkWidget *const /*widget*/, GdkEventConfigure *const event, const gpointer data) { GtkGui* obj = static_cast(data); - - GtkGlue& glue = obj->rendererGlue(); - - glue.configure(widget, event); obj->resize_view(event->width, event->height); - return TRUE; + return FALSE; } gboolean === added directory 'gui/gtk_widget' === added file 'gui/gtk_widget/Makefile.am' --- gui/gtk_widget/Makefile.am 1970-01-01 00:00:00 +0000 +++ gui/gtk_widget/Makefile.am 2009-04-20 15:36:56 +0000 @@ -0,0 +1,59 @@ +pkgpythondir = $(pyexecdir)/gtk-2.0 +pkgpyexecdir = $(pyexecdir)/gtk-2.0 + +GNASH_INCLUDES = \ + -I$(top_srcdir)/gui \ + -I$(top_srcdir)/libbase \ + -I$(top_srcdir)/backend \ + -I$(top_srcdir)/libcore \ + -I$(top_srcdir)/libcore/swf \ + -I$(top_srcdir)/libcore/vm \ + -I$(top_srcdir)/libcore/parser \ + -I$(top_srcdir)/libmedia \ + -I$(top_srcdir)/libmedia/gst \ + -I$(top_srcdir)/libsound + +INCLUDES = \ + $(PYTHON_CFLAGS) \ + $(PYGTK_CFLAGS) \ + $(GTK2_CFLAGS) \ + $(GNASH_INCLUDES) + +pkgpyexec_LTLIBRARIES = gnash.la + +GNASH_LIBS = \ + $(top_builddir)/libamf/libgnashamf.la \ + $(top_builddir)/libnet/libgnashnet.la \ + $(top_builddir)/libmedia/libgnashmedia.la \ + $(top_builddir)/libsound/libgnashsound.la \ + $(top_builddir)/libcore/libgnashcore.la \ + $(top_builddir)/backend/libgnashcairo.la \ + $(top_builddir)/libbase/libgnashbase.la + +gnash_la_LDFLAGS = -module -avoid-version -export-symbols-regex initgnash +gnash_la_LIBADD = \ + $(GNASH_LIBS) \ + $(GTK2_LIBS) \ + $(DEPS_LIBS) + +gnash_la_SOURCES = \ + gnash.c \ + gnashmodule.c \ + gnash-view.cpp \ + $(top_srcdir)/gui/gnash-canvas.cpp \ + $(top_srcdir)/gui/gtk_glue_cairo.cpp + +gnash.c: gnash.defs gnash.override + +CLEANFILES = gnash.c +EXTRA_DIST = gnash.override gnash.defs + +.defs.c: + (cd $(srcdir)\ + && $(PYGTK_CODEGEN) \ + --register $(PYGTK_DEFSDIR)/gdk-types.defs \ + --register $(PYGTK_DEFSDIR)/gtk-types.defs \ + --override $*.override \ + --prefix py$* $*.defs) > gen-$*.c \ + && cp gen-$*.c $*.c \ + && rm -f gen-$*.c === added file 'gui/gtk_widget/gnash-test.c' --- gui/gtk_widget/gnash-test.c 1970-01-01 00:00:00 +0000 +++ gui/gtk_widget/gnash-test.c 2009-04-18 20:02:16 +0000 @@ -0,0 +1,56 @@ +// gnash-window.c: Gtk canvas widget for gnash +// +// Copyright (C) 2009 Free Software Foundation, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +// + +#include + +#include "gnash-view.h" + +static void destroy( GtkWidget *widget, + gpointer data ) +{ + gtk_main_quit (); +} + +int main( int argc, + char *argv[] ) +{ + GtkWidget *window; + GtkWidget *view; + + gtk_init (&argc, &argv); + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + + g_signal_connect (G_OBJECT (window), "destroy", + G_CALLBACK (destroy), NULL); + + view = gnash_view_new (); + + gtk_container_add (GTK_CONTAINER (window), view); + gtk_widget_show (view); + + gtk_widget_show (window); + + gnash_view_load_movie(GNASH_VIEW(view), argv[1]); + gnash_view_start(GNASH_VIEW(view)); + + gtk_main (); + + return 0; +} === added file 'gui/gtk_widget/gnash-view.cpp' --- gui/gtk_widget/gnash-view.cpp 1970-01-01 00:00:00 +0000 +++ gui/gtk_widget/gnash-view.cpp 2009-04-20 11:57:37 +0000 @@ -0,0 +1,370 @@ +// gnash-view.cpp: Gtk view widget for gnash +// +// Copyright (C) 2009 Free Software Foundation, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +// + +#include "gnash-view.h" +#include "gnash-canvas.h" + +#include +#include +#include + +#include "log.h" + +#include "VM.h" +#include "movie_definition.h" +#include "movie_root.h" // for Abstract callbacks +#include "sound_handler.h" +#include "MediaHandler.h" +#include "RunInfo.h" // for passing handlers and other data to the core. +#include "VirtualClock.h" +#include "SystemClock.h" +#include "smart_ptr.h" + +#ifdef USE_FFMPEG +# include "MediaHandlerFfmpeg.h" +#elif defined(USE_GST) +# include "MediaHandlerGst.h" +#endif + +struct _GnashView { + GtkBin base_instance; + + GnashCanvas *canvas; + + std::auto_ptr media_handler; + boost::shared_ptr sound_handler; + + /// Handlers (for sound etc) for a libcore run. + // + /// This must be kept alive for the entire lifetime of the movie_root + /// (currently: of the Gui). + std::auto_ptr run_info; + + std::auto_ptr movie_definition; + std::auto_ptr stage; + std::auto_ptr system_clock; + std::auto_ptr virtual_clock; + guint advance_timer; +}; + +G_DEFINE_TYPE(GnashView, gnash_view, GTK_TYPE_BIN) + +static GObjectClass *parent_class = NULL; + +static void gnash_view_class_init(GnashViewClass *gnash_view_class); +static void gnash_view_init(GnashView *view); +static void gnash_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation); +static void gnash_view_size_request (GtkWidget *widget, GtkRequisition *requisition); +static gboolean gnash_view_key_press_event(GtkWidget *widget, GdkEventKey *event); +static gnash::key::code gdk_to_gnash_key(guint key); +static int gdk_to_gnash_modifier(int state); +static gboolean gnash_view_advance_movie(GnashView *view); +static void gnash_view_display(GnashView *view); + +GtkWidget * +gnash_view_new (void) +{ + return GTK_WIDGET(g_object_new (GNASH_TYPE_VIEW, NULL)); +} + +static void +gnash_view_class_init(GnashViewClass *gnash_view_class) +{ + GNASH_REPORT_FUNCTION; + parent_class = (GObjectClass *) g_type_class_peek_parent(gnash_view_class); + + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (gnash_view_class); + widget_class->size_allocate = gnash_view_size_allocate; + widget_class->size_request = gnash_view_size_request; + widget_class->key_press_event = gnash_view_key_press_event; +} + +static void +gnash_view_init(GnashView *view) +{ + GNASH_REPORT_FUNCTION; + + gnash::gnashInit(); + gnash::LogFile& dbglogfile = gnash::LogFile::getDefaultInstance(); + dbglogfile.setVerbosity(); + dbglogfile.setVerbosity(); + dbglogfile.setVerbosity(); + + // Init media +#ifdef USE_FFMPEG + view->media_handler.reset( new gnash::media::ffmpeg::MediaHandlerFfmpeg() ); + gnash::media::MediaHandler::set(view->media_handler); +#elif defined(USE_GST) + view->media_handler.reset( new gnash::media::gst::MediaHandlerGst() ); + gnash::media::MediaHandler::set(view->media_handler); +#else + log_error(_("No media support compiled in")); +#endif + + // Init sound +#ifdef SOUND_SDL + try { + view->sound_handler.reset(gnash::sound::create_sound_handler_sdl("")); + } catch (gnash::SoundException& ex) { + gnash::log_error(_("Could not create sound handler: %s." + " Will continue w/out sound."), ex.what()); + } +#elif defined(SOUND_GST) + view->sound_handler.reset(media::create_sound_handler_gst()); +#else + gnash::log_error(_("Sound requested but no sound support compiled in")); +#endif + + view->canvas = GNASH_CANVAS(gnash_canvas_new()); + gnash_canvas_setup(view->canvas, 0, NULL); + gtk_container_add (GTK_CONTAINER (view), GTK_WIDGET(view->canvas)); + gtk_widget_show (GTK_WIDGET(view->canvas)); +} + +static void +gnash_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation) +{ + GnashView *view = GNASH_VIEW(widget); + widget->allocation = *allocation; + gtk_widget_size_allocate (GTK_BIN(widget)->child, allocation); + + if( view->stage.get() != NULL) { + view->stage->set_display_viewport(0, 0, allocation->width, allocation->height); + + gnash::render_handler *renderer = gnash_canvas_get_renderer(view->canvas); + float xscale = allocation->width / view->movie_definition->get_width_pixels(); + float yscale = allocation->height / view->movie_definition->get_height_pixels(); + renderer->set_scale(xscale, yscale); + } +} + +static void +gnash_view_size_request (GtkWidget *widget, GtkRequisition *requisition) +{ + GnashView *view = GNASH_VIEW(widget); + if( view->movie_definition.get() == NULL ) { + requisition->width = 0; + requisition->height = 0; + } else { + requisition->width = view->movie_definition->get_width_pixels(); + requisition->height = view->movie_definition->get_height_pixels(); + } +} + +static gboolean +gnash_view_key_press_event(GtkWidget *widget, GdkEventKey *event) +{ + if (GNASH_VIEW(widget)->stage.get() == NULL) + return FALSE; + + gnash::key::code c = gdk_to_gnash_key(event->keyval); + //int mod = gdk_to_gnash_modifier(event->state); + + if (c != gnash::key::INVALID) { + if( GNASH_VIEW(widget)->stage->notify_key_event(c, true) ) + gnash_view_display(GNASH_VIEW(widget)); + return TRUE; + } + + return FALSE; +} + +void +gnash_view_load_movie(GnashView *view, gchar *path) +{ + GNASH_REPORT_FUNCTION; + + // The RunInfo should be populated before parsing. + view->run_info.reset(new gnash::RunInfo(path)); + view->run_info->setSoundHandler(view->sound_handler); + + std::auto_ptr np(new gnash::IncrementalRename(gnash::URL(path))); + boost::shared_ptr sp(new gnash::StreamProvider(np)); + view->run_info->setStreamProvider(sp); + + // Load the actual movie. + gnash::RcInitFile& rcfile = gnash::RcInitFile::getDefaultInstance(); + + const std::string& str_path(path); + size_t lastSlash = str_path.find_last_of('/'); + std::string dir = str_path.substr(0, lastSlash+1); + rcfile.addLocalSandboxPath(dir); + gnash::log_debug(_("%s appended to local sandboxes"), dir.c_str()); + + rcfile.addLocalSandboxPath(str_path); + gnash::log_debug(_("%s appended to local sandboxes"), path); + + view->movie_definition.reset(gnash::create_library_movie(gnash::URL(path), + *view->run_info, path, false)); + + // NOTE: it's important that _systemClock is constructed + // before and destroyed after _virtualClock ! + view->system_clock.reset(new gnash::SystemClock()); + view->virtual_clock.reset(new gnash::InterruptableVirtualClock(*view->system_clock)); + view->stage.reset(new gnash::movie_root(*view->movie_definition, *view->virtual_clock, *view->run_info)); + view->movie_definition->completeLoad(); + + view->advance_timer = g_timeout_add_full(G_PRIORITY_LOW, 10, + (GSourceFunc)gnash_view_advance_movie, view, NULL); + + gtk_widget_queue_resize (GTK_WIDGET(view)); +} + +void +gnash_view_start(GnashView *view) +{ + GNASH_REPORT_FUNCTION; + + std::auto_ptr mr ( view->movie_definition->createMovie() ); + + view->stage->setRootMovie( mr.release() ); // will construct the instance + + bool background = true; // ?? + view->stage->set_background_alpha(background ? 1.0f : 0.05f); + + // @todo since we registered the sound handler, shouldn't we know + // already what it is ?! + gnash::sound::sound_handler* s = view->stage->runInfo().soundHandler(); + if ( s ) s->unpause(); + + gnash::log_debug("Starting virtual clock"); + view->virtual_clock->resume(); + + gnash_view_advance_movie(view); +} + +static gboolean +gnash_view_advance_movie(GnashView *view) +{ + view->stage->advance(); + + gnash_view_display(view); + + return TRUE; +} + +static void +gnash_view_display(GnashView *view) +{ + gnash::InvalidatedRanges changed_ranges; + changed_ranges.setWorld(); + + gnash::render_handler *renderer = gnash_canvas_get_renderer(view->canvas); + renderer->set_invalidated_regions(changed_ranges); + gdk_window_invalidate_rect(GTK_WIDGET(view->canvas)->window, NULL, false); + + gnash_canvas_before_rendering(view->canvas); + view->stage->display(); + + gdk_window_process_updates(GTK_WIDGET(view->canvas)->window, false); +} + +static gnash::key::code +gdk_to_gnash_key(guint key) +{ + gnash::key::code c(gnash::key::INVALID); + + // ascii 32-126 in one range: + if (key >= GDK_space && key <= GDK_asciitilde) { + c = (gnash::key::code) ((key - GDK_space) + gnash::key::SPACE); + } + + // Function keys: + else if (key >= GDK_F1 && key <= GDK_F15) { + c = (gnash::key::code) ((key - GDK_F1) + gnash::key::F1); + } + + // Keypad: + else if (key >= GDK_KP_0 && key <= GDK_KP_9) { + c = (gnash::key::code) ((key - GDK_KP_0) + gnash::key::KP_0); + } + + // Extended ascii: + else if (key >= GDK_nobreakspace && key <= GDK_ydiaeresis) { + c = (gnash::key::code) ((key - GDK_nobreakspace) + + gnash::key::NOBREAKSPACE); + } + + // non-character keys don't correlate, so use a look-up table. + else { + struct { + guint gdk; + gnash::key::code gs; + } table[] = { + { GDK_BackSpace, gnash::key::BACKSPACE }, + { GDK_Tab, gnash::key::TAB }, + { GDK_Clear, gnash::key::CLEAR }, + { GDK_Return, gnash::key::ENTER }, + + { GDK_Shift_L, gnash::key::SHIFT }, + { GDK_Shift_R, gnash::key::SHIFT }, + { GDK_Control_L, gnash::key::CONTROL }, + { GDK_Control_R, gnash::key::CONTROL }, + { GDK_Alt_L, gnash::key::ALT }, + { GDK_Alt_R, gnash::key::ALT }, + { GDK_Caps_Lock, gnash::key::CAPSLOCK }, + + { GDK_Escape, gnash::key::ESCAPE }, + + { GDK_Page_Down, gnash::key::PGDN }, + { GDK_Page_Up, gnash::key::PGUP }, + { GDK_Home, gnash::key::HOME }, + { GDK_End, gnash::key::END }, + { GDK_Left, gnash::key::LEFT }, + { GDK_Up, gnash::key::UP }, + { GDK_Right, gnash::key::RIGHT }, + { GDK_Down, gnash::key::DOWN }, + { GDK_Insert, gnash::key::INSERT }, + { GDK_Delete, gnash::key::DELETEKEY }, + + { GDK_Help, gnash::key::HELP }, + { GDK_Num_Lock, gnash::key::NUM_LOCK }, + + { GDK_VoidSymbol, gnash::key::INVALID } + }; + + for (int i = 0; table[i].gdk != GDK_VoidSymbol; i++) { + if (key == table[i].gdk) { + c = table[i].gs; + break; + } + } + } + + return c; +} + +static int +gdk_to_gnash_modifier(int state) +{ + int modifier = gnash::key::GNASH_MOD_NONE; + + if (state & GDK_SHIFT_MASK) { + modifier = modifier | gnash::key::GNASH_MOD_SHIFT; + } + if (state & GDK_CONTROL_MASK) { + modifier = modifier | gnash::key::GNASH_MOD_CONTROL; + } + if (state & GDK_MOD1_MASK) { + modifier = modifier | gnash::key::GNASH_MOD_ALT; + } + + return modifier; +} + === added file 'gui/gtk_widget/gnash-view.h' --- gui/gtk_widget/gnash-view.h 1970-01-01 00:00:00 +0000 +++ gui/gtk_widget/gnash-view.h 2009-04-19 09:39:39 +0000 @@ -0,0 +1,50 @@ +// gnash-view.h: Gtk view widget for gnash +// +// Copyright (C) 2009 Free Software Foundation, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +// + +#ifndef __GNASH_VIEW_H__ +#define __GNASH_VIEW_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GnashView GnashView; +typedef struct _GnashViewClass GnashViewClass; + +#define GNASH_TYPE_VIEW (gnash_view_get_type()) +#define GNASH_VIEW(object) (G_TYPE_CHECK_INSTANCE_CAST((object), GNASH_TYPE_VIEW, GnashView)) +#define GNASH_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNASH_TYPE_VIEW, GnashViewClass)) +#define GNASH_IS_VIEW(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), GNASH_TYPE_VIEW)) +#define GNASH_IS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNASH_TYPE_VIEW)) +#define GNASH_VIEW_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), GNASH_TYPE_VIEW, GnashViewClass)) + +struct _GnashViewClass { + GtkBinClass base_class; +}; + +GType gnash_view_get_type (void); +GtkWidget *gnash_view_new (void); + +void gnash_view_start (GnashView *view); +void gnash_view_load_movie (GnashView *view, gchar *path); + +G_END_DECLS + +#endif + === added file 'gui/gtk_widget/gnash.defs' --- gui/gtk_widget/gnash.defs 1970-01-01 00:00:00 +0000 +++ gui/gtk_widget/gnash.defs 2009-04-20 12:00:55 +0000 @@ -0,0 +1,22 @@ +(define-object View + (in-module "Gnash") + (parent "GtkBin") + (c-name "GnashView") + (gtype-id "GNASH_TYPE_VIEW") +) + +(define-method start + (of-object "GnashView") + (c-name "gnash_view_start") + (return-type "none") +) + +(define-method load_movie + (of-object "GnashView") + (c-name "gnash_view_load_movie") + (parameters + '("gchar*" "path") + ) + (return-type "none") +) + === added file 'gui/gtk_widget/gnash.override' --- gui/gtk_widget/gnash.override 1970-01-01 00:00:00 +0000 +++ gui/gtk_widget/gnash.override 2009-04-20 16:17:19 +0000 @@ -0,0 +1,17 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- */ +%% +headers +#include +#include + +#include "gnash-view.h" + +%% +modulename gnash +%% +import gtk.Bin as PyGtkBin_Type +%% +ignore-glob + *_get_type + _* + === added file 'gui/gtk_widget/gnashmodule.c' --- gui/gtk_widget/gnashmodule.c 1970-01-01 00:00:00 +0000 +++ gui/gtk_widget/gnashmodule.c 2009-04-20 12:11:45 +0000 @@ -0,0 +1,22 @@ +#include + +void pygnash_register_classes (PyObject *d); + +extern PyMethodDef pygnash_functions[]; + +DL_EXPORT(void) +initgnash(void) +{ + PyObject *m, *d; + + init_pygobject (); + + m = Py_InitModule ("gnash", pygnash_functions); + d = PyModule_GetDict (m); + + pygnash_register_classes (d); + + if (PyErr_Occurred ()) { + Py_FatalError ("can't initialise module gnash"); + } +} === added file 'gui/gtk_widget/test.py' --- gui/gtk_widget/test.py 1970-01-01 00:00:00 +0000 +++ gui/gtk_widget/test.py 2009-04-20 12:01:51 +0000 @@ -0,0 +1,15 @@ +import gtk +import gnash + +w = gtk.Window() + +v = gnash.View() +w.add(v) +v.show() + +v.load_movie('/home/tomeu/Desktop/EatBoom.swf') +v.start() + +w.show() + +gtk.main() === modified file 'gui/gtksup.h' --- gui/gtksup.h 2009-02-11 14:10:33 +0000 +++ gui/gtksup.h 2009-04-17 09:09:08 +0000 @@ -28,6 +28,8 @@ #include #include +#include "gnash-canvas.h" + #ifdef GUI_HILDON extern "C" { # include @@ -139,8 +141,6 @@ virtual void error(const std::string& msg); - GtkGlue& rendererGlue() { return *_glue; } - private: #ifdef GUI_HILDON @@ -154,7 +154,7 @@ GtkWidget* _overlay; // The area rendered into by Gnash - GtkWidget* _drawingArea; + GtkWidget* _canvas; GtkMenu* _popup_menu; GtkWidget* _menubar; @@ -172,8 +172,6 @@ GtkTreeModel* makeTreeModel (std::auto_ptr treepointer); #endif - std::auto_ptr _glue; - void stopHook(); void playHook();