[snappy] Embed the Clutter Stage in a Gtk Window



commit 682cc2cea8248242a0f06ec510d5026ea1ef2257
Author: Luis de Bethencourt <luis debethencourt com>
Date:   Fri Nov 30 19:08:03 2012 -0500

    Embed the Clutter Stage in a Gtk Window

 configure.ac         |   13 ++++++++-
 src/Makefile.am      |    4 +-
 src/snappy.c         |   11 ++++----
 src/user_interface.c |   64 ++++++++++++++++++++++++++++++++++---------------
 src/user_interface.h |    4 +++
 5 files changed, 66 insertions(+), 30 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 4aa615b..bf703ce 100644
--- a/configure.ac
+++ b/configure.ac
@@ -35,7 +35,9 @@ AC_CANONICAL_HOST
 # keep one single GST_REQ, core/base should be same versions anyway
 GST_REQ=1.0.0
 CLUTTER_REQS=1.6.0
-CLUTTER_GST_REQS=1.9.92
+CLUTTER_GST_REQS=1.5.5
+CLUTTER_GTK_REQS=1.0.2
+GTK_REQS=3.0.0
 GIO_REQ=2.32
 
 PKG_CHECK_MODULES([GST], \
@@ -53,10 +55,17 @@ AC_SUBST(CLUTTER_CFLAGS)
 AC_SUBST(CLUTTER_LIBS)
 
 PKG_CHECK_MODULES([CLUTTER_GST], [clutter-gst-2.0 >= $CLUTTER_GST_REQS])
-
 AC_SUBST(CLUTTER_GST_CFLAGS)
 AC_SUBST(CLUTTER_GST_LIBS)
 
+PKG_CHECK_MODULES([CLUTTER_GTK], [clutter-gtk-1.0 >= $CLUTTER_GTK_REQS])
+AC_SUBST(CLUTTER_GTK_CFLAGS)
+AC_SUBST(CLUTTER_GTK_LIBS)
+
+PKG_CHECK_MODULES([GTK], [gtk+-3.0 >= $GTK_REQS])
+AC_SUBST(GTK_CFLAGS)
+AC_SUBST(GTK_LIBS)
+
 PKG_CHECK_MODULES(GIO, gio-2.0 >= $GIO_REQ)
 AC_SUBST(GIO_CFLAGS)
 AC_SUBST(GIO_LIBS)
diff --git a/src/Makefile.am b/src/Makefile.am
index 16f0edd..7a0e601 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -20,7 +20,7 @@ CLEANFILES =
 bin_PROGRAMS = snappy
 
 snappy_SOURCES = $(c_sources)
-snappy_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(CLUTTER_GST_CFLAGS) $(GIO_CFLAGS) $(XTEST_CFLAGS) -DSNAPPY_DATA_DIR="\"$(pkgdatadir)\""
-snappy_LDADD = $(CLUTTER_LIBS) $(GST_LIBS) $(CLUTTER_GST_LIBS) $(GIO_LIBS) $(XTEST_LIBS)
+snappy_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(CLUTTER_GST_CFLAGS) $(CLUTTER_GTK_CFLAGS) $(GTK_CFLAGS) $(GIO_CFLAGS) $(XTEST_CFLAGS) -DSNAPPY_DATA_DIR="\"$(pkgdatadir)\""
+snappy_LDADD = $(CLUTTER_LIBS) $(GST_LIBS) $(CLUTTER_GST_LIBS) $(CLUTTER_GTK_LIBS) $(GTK_LIBS) $(GIO_LIBS) $(XTEST_LIBS)
 
 noinst_HEADERS = $(public_headers)
diff --git a/src/snappy.c b/src/snappy.c
index 1da2fdc..e90a705 100644
--- a/src/snappy.c
+++ b/src/snappy.c
@@ -218,9 +218,8 @@ main (int argc, char *argv[])
   ui->tags = tags;
   ui->data_dir = data_dir;
   interface_init (ui);
-  video_texture = clutter_texture_new ();
-
-  clutter_gst_init (&argc, &argv);
+  video_texture = g_object_new (CLUTTER_TYPE_TEXTURE, "disable-slicing", TRUE,
+      NULL);
 
   version_str = gst_version_string ();
   GST_DEBUG_CATEGORY_INIT (_snappy_gst_debug, "snappy", 0,
@@ -234,8 +233,7 @@ main (int argc, char *argv[])
     GST_DEBUG ("autocluttersink not found, falling back to cluttersink\n");
     sink = gst_element_factory_make ("cluttersink", "cluttersink");
   }
-  g_object_set (G_OBJECT (sink), "texture", CLUTTER_TEXTURE (video_texture),
-      NULL);
+  g_object_set (G_OBJECT (sink), "texture", video_texture, NULL);
 
   ok = engine_init (engine, sink);
   if (!ok)
@@ -254,6 +252,7 @@ main (int argc, char *argv[])
   uri = g_list_first (uri_list)->data;
 
   /* Load engine and start interface */
+  gtk_clutter_init (&argc, &argv);
   engine_load_uri (engine, uri);
   interface_start (ui, uri);
 
@@ -276,7 +275,7 @@ main (int argc, char *argv[])
 #endif
 
   /* Main loop */
-  clutter_main ();
+  gtk_main ();
 
   /* Close snappy */
   close_down (ui, engine);
diff --git a/src/user_interface.c b/src/user_interface.c
index 5668c46..04fecfe 100644
--- a/src/user_interface.c
+++ b/src/user_interface.c
@@ -21,8 +21,11 @@
  */
 
 #include <string.h>
+
+#include <gtk/gtk.h>
 #include <clutter/clutter.h>
 #include <clutter-gst/clutter-gst.h>
+#include <clutter-gtk/clutter-gtk.h>
 
 #include "user_interface.h"
 #include "utils.h"
@@ -79,7 +82,7 @@ event_cb (ClutterStage * stage, ClutterEvent * event, UserInterface * ui)
         case CLUTTER_q:
         case CLUTTER_Escape:
         {
-          clutter_main_quit ();
+          gtk_main_quit ();
 
           handled = TRUE;
           break;
@@ -449,7 +452,7 @@ load_controls (UserInterface * ui)
       clutter_bind_constraint_new (ui->control_box, CLUTTER_BIND_SIZE, 0));
 
   g_free (vid_panel_png);
-  clutter_container_add_actor (CLUTTER_CONTAINER (ui->control_box),
+  clutter_actor_add_child (CLUTTER_ACTOR (ui->control_box),
       ui->control_bg);
   clutter_actor_add_constraint (ui->control_box,
       clutter_align_constraint_new (ui->stage, CLUTTER_ALIGN_X_AXIS, 0.5));
@@ -462,7 +465,7 @@ load_controls (UserInterface * ui)
   ui->main_box = clutter_actor_new ();
   clutter_actor_set_layout_manager (ui->main_box, main_box_layout);
 
-  clutter_container_add_actor (CLUTTER_CONTAINER (ui->control_box),
+  clutter_actor_add_child (CLUTTER_ACTOR (ui->control_box),
       CLUTTER_ACTOR (ui->main_box));
   clutter_actor_add_constraint (CLUTTER_ACTOR (ui->main_box),
       clutter_align_constraint_new (ui->stage, CLUTTER_ALIGN_X_AXIS, 0.03));
@@ -512,7 +515,7 @@ load_controls (UserInterface * ui)
 
   // background box rectangle shows as the border
   ui->control_seek1 = clutter_rectangle_new_with_color (&control_color1);
-  clutter_container_add_actor (CLUTTER_CONTAINER (seek_box), ui->control_seek1);
+  clutter_actor_add_child (CLUTTER_ACTOR (seek_box), ui->control_seek1);
   clutter_actor_add_constraint (ui->control_seek1,
       clutter_align_constraint_new (ui->stage, CLUTTER_ALIGN_X_AXIS, 0));
   clutter_actor_add_constraint (ui->control_seek1,
@@ -520,12 +523,12 @@ load_controls (UserInterface * ui)
 
   // smaller background rectangle inside seek1 to create a border
   ui->control_seek2 = clutter_rectangle_new_with_color (&control_color2);
-  clutter_container_add_actor (CLUTTER_CONTAINER (seek_box), ui->control_seek2);
+  clutter_actor_add_child (CLUTTER_ACTOR (seek_box), ui->control_seek2);
   clutter_actor_set_position (ui->control_seek2, SEEK_BORDER, SEEK_BORDER);
 
   // progress rectangle
   ui->control_seekbar = clutter_rectangle_new_with_color (&control_color1);
-  clutter_container_add_actor (CLUTTER_CONTAINER (seek_box),
+  clutter_actor_add_child (CLUTTER_ACTOR (seek_box),
       ui->control_seekbar);
   clutter_actor_set_position (ui->control_seekbar, SEEK_BORDER, SEEK_BORDER);
 
@@ -570,11 +573,11 @@ load_controls (UserInterface * ui)
   vol_int_box = clutter_box_new (vol_int_box_layout);
 
   ui->vol_int_bg = clutter_rectangle_new_with_color (&control_color1);
-  clutter_container_add_actor (CLUTTER_CONTAINER (vol_int_box), ui->vol_int_bg);
+  clutter_actor_add_child (CLUTTER_ACTOR (vol_int_box), ui->vol_int_bg);
   clutter_actor_set_position (ui->vol_int_bg, 0, 0);
 
   ui->vol_int = clutter_rectangle_new_with_color (&control_color1);
-  clutter_container_add_actor (CLUTTER_CONTAINER (vol_int_box), ui->vol_int);
+  clutter_actor_add_child (CLUTTER_ACTOR (vol_int_box), ui->vol_int);
 
   clutter_box_pack (CLUTTER_BOX (ui->volume_box), vol_int_box,
       "x-fill", FALSE,
@@ -1045,7 +1048,7 @@ interface_load_uri (UserInterface * ui, gchar * uri)
   ui->filename = g_path_get_basename (ui->fileuri);
 
   if (ui->stage != NULL) {
-    clutter_stage_set_title (CLUTTER_STAGE (ui->stage), ui->filename);
+    gtk_window_set_title (GTK_WINDOW (ui->window), "Clutter Embedding");
     clutter_text_set_text (CLUTTER_TEXT (ui->control_title), ui->filename);
   }
 
@@ -1107,7 +1110,31 @@ interface_start (UserInterface * ui, gchar * uri)
 
   ui->stage_width = ui->media_width;
   ui->stage_height = ui->media_height;
-  ui->stage = clutter_stage_get_default ();
+
+  /* Create the window and some child widgets: */
+  ui->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title (GTK_WINDOW (ui->window), ui->filename);
+  g_signal_connect (ui->window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+
+  ui->box = gtk_grid_new ();
+  gtk_orientable_set_orientation (GTK_ORIENTABLE (ui->box),
+      GTK_ORIENTATION_VERTICAL);
+  gtk_widget_set_hexpand (ui->box, TRUE);
+  gtk_widget_set_vexpand (ui->box, TRUE);
+  gtk_container_add (GTK_CONTAINER (ui->window), ui->box);
+
+  /* Create the clutter widget: */
+  ui->clutter_widget = gtk_clutter_embed_new ();
+  gtk_container_add (GTK_CONTAINER (ui->box), ui->clutter_widget);
+
+  /* Get the stage */
+  ui->stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (ui->clutter_widget));
+  clutter_actor_set_background_color (CLUTTER_ACTOR (ui->stage), &stage_color);
+  /* Set the size of the widget,
+   * because we should not set the size of its stage when using GtkClutterEmbed.
+   */
+  gtk_widget_set_size_request (ui->clutter_widget, ui->stage_width,
+      ui->stage_height);
 
   ui->controls_showing = FALSE;
   ui->keep_showing_controls = FALSE;
@@ -1122,11 +1149,6 @@ interface_start (UserInterface * ui, gchar * uri)
   ui->media_duration = -1;
   ui->duration_str = position_ns_to_str (ui->engine->media_duration);
 
-  clutter_stage_set_color (CLUTTER_STAGE (ui->stage), &stage_color);
-  clutter_actor_set_size (CLUTTER_ACTOR (ui->stage), ui->media_width,
-      ui->media_height);
-  clutter_stage_set_title (CLUTTER_STAGE (ui->stage), ui->filename);
-
   clutter_actor_set_size (CLUTTER_ACTOR (ui->stage), ui->stage_width,
       ui->stage_height);
   clutter_stage_set_user_resizable (CLUTTER_STAGE (ui->stage), TRUE);
@@ -1139,10 +1161,9 @@ interface_start (UserInterface * ui, gchar * uri)
   load_controls (ui);
 
   // Add video texture and control UI to stage
-  clutter_container_add (CLUTTER_CONTAINER (ui->stage), ui->texture, NULL);
+  clutter_actor_add_child (ui->stage, ui->texture);
   if (!ui->hide) {
-    clutter_container_add (CLUTTER_CONTAINER (ui->stage),
-        CLUTTER_ACTOR (ui->control_box), NULL);
+    clutter_actor_add_child (ui->stage, CLUTTER_ACTOR (ui->control_box));
   }
   clutter_actor_add_constraint (ui->texture,
       clutter_align_constraint_new (ui->stage, CLUTTER_ALIGN_X_AXIS, 0.5));
@@ -1153,6 +1174,7 @@ interface_start (UserInterface * ui, gchar * uri)
   clutter_actor_animate (CLUTTER_ACTOR (ui->control_box),
       CLUTTER_EASE_OUT_QUINT, G_TIME_SPAN_MILLISECOND, "opacity", 0, NULL);
 
+  /* Connect a signal handler to mouse clicks and key presses on the stage */
   g_signal_connect (CLUTTER_STAGE (ui->stage), "allocation-changed",
       G_CALLBACK (size_change), ui);
   g_signal_connect (CLUTTER_STAGE (ui->stage), "event", G_CALLBACK (event_cb),
@@ -1165,8 +1187,10 @@ interface_start (UserInterface * ui, gchar * uri)
 
   g_timeout_add (G_TIME_SPAN_MILLISECOND, progress_update_text, ui);
 
-  if (!ui->blind)
-    clutter_actor_show (ui->stage);
+  if (!ui->blind) {
+    /* Show the window */
+    gtk_widget_show_all (ui->window);
+  }
 }
 
 gboolean
diff --git a/src/user_interface.h b/src/user_interface.h
index 20d38cd..ba9f8ff 100644
--- a/src/user_interface.h
+++ b/src/user_interface.h
@@ -23,6 +23,8 @@
 #ifndef __USER_INTERFACE_H__
 #define __USER_INTERFACE_H__
 
+#include <gtk/gtk.h>
+
 #include "gst_engine.h"
 #include "screensaver.h"
 
@@ -96,6 +98,8 @@ struct _UserInterface
 
   GList *uri_list;
 
+  GtkWidget *window, *box, *clutter_widget;
+
   ClutterColor stage_color, control_color1, control_color2;
 
   ClutterActor *stage;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]