? gnome-screenshot.diff
Index: configure.in
===================================================================
RCS file: /cvs/gnome/gnome-utils/configure.in,v
retrieving revision 1.381
diff -u -3 -p -r1.381 configure.in
--- configure.in	1 May 2005 22:39:53 -0000	1.381
+++ configure.in	20 May 2005 23:00:19 -0000
@@ -51,6 +51,27 @@ AC_SUBST(LIBGLADE_CFLAGS)
 AC_SUBST(LIBGLADE_LIBS)
 
 dnl *****************************************
+dnl gnome-screenshot can use GStreamer
+dnl *****************************************
+AC_ARG_ENABLE(gst,
+	AC_HELP_STRING([--enable-gst],[use GStreamer, if available]),
+	[case "${enableval}" in
+		yes) ENABLE_GST=yes ;;
+		no)  ENABLE_GST=no ;;
+		*) AC_MSG_ERROR(bad value ${enableval} for --enable-gst) ;;
+		esac],
+	[ENABLE_GST=yes])
+if test "x$ENABLE_GST" = "xyes"; then
+	PKG_CHECK_MODULES(GST, gstreamer-0.8 gstreamer-gconf-0.8,
+		AC_DEFINE(USE_GST, 1, [defined if using GStreamer]),
+		[ USE_GST=""])
+else
+	USE_GST=""
+fi 
+AC_SUBST(GST_CFLAGS)
+AC_SUBST(GST_LIBS)
+
+dnl *****************************************
 dnl gdict needs libgnomeprint and libgnomeprintui
 dnl *****************************************
 PKG_CHECK_MODULES(LIBGNOMEPRINT,libgnomeprint-2.2 >= $LIBGNOMEPRINT_REQUIRED \
@@ -444,6 +465,13 @@ if test "x$build_gfloppy" = "xtrue"; the
 	echo "Build gfloppy                     : YES"
 else
 	echo "Build gfloppy                     : NO"
+fi
+
+dnl <= gnome-screenshot =>
+if test "x$ENABLE_GST" = "xyes"; then
+	echo "gnome-screenshot                  : YES (including support for GStreamer)"
+else
+	echo "gnome-screenshot                  : YES (without support for GStreamer)"
 fi
 
 echo ""
Index: gnome-screenshot/Makefile.am
===================================================================
RCS file: /cvs/gnome/gnome-utils/gnome-screenshot/Makefile.am,v
retrieving revision 1.1
diff -u -3 -p -r1.1 Makefile.am
--- gnome-screenshot/Makefile.am	3 Nov 2004 16:45:00 -0000	1.1
+++ gnome-screenshot/Makefile.am	20 May 2005 23:00:21 -0000
@@ -15,6 +15,7 @@ INCLUDES =							\
 	-DGNOMELOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\"	\
 	-DGLADEDIR=\""$(gladedir)"\"				\
 	$(SCREENSHOT_CFLAGS)					\
+	$(GST_CFLAGS)	\
 	$(NULL)
 
 bin_PROGRAMS = \
@@ -43,6 +44,7 @@ gnome_screenshot_LDFLAGS = -export-dynam
 gnome_screenshot_LDADD =		\
 	$(XSHAPE_LIBS)			\
 	$(SCREENSHOT_LIBS)		\
+	$(GST_LIBS)	\
 	$(NULL)
 
 gladedir = $(datadir)/gnome-screenshot/glade
Index: gnome-screenshot/gnome-panel-screenshot.c
===================================================================
RCS file: /cvs/gnome/gnome-utils/gnome-screenshot/gnome-panel-screenshot.c,v
retrieving revision 1.85
diff -u -3 -p -r1.85 gnome-panel-screenshot.c
--- gnome-screenshot/gnome-panel-screenshot.c	16 May 2005 19:32:04 -0000	1.85
+++ gnome-screenshot/gnome-panel-screenshot.c	20 May 2005 23:00:21 -0000
@@ -47,19 +47,23 @@
 #include "screenshot-dialog.h"
 #include "screenshot-xfer.h"
 
-static GdkPixbuf *screenshot = NULL;
+#ifdef USE_GST
+#include <gst/gst.h>
+#include <gst/gconf/gconf.h>
+#endif
 
 /* Global variables*/
 static char *last_save_dir = NULL;
 static char *window_title = NULL;
 static char *temporary_file = NULL;
-static gboolean drop_shadow = TRUE;
 static gboolean save_immediately = FALSE;
 
 /* Options */
 static gboolean take_window_shot = FALSE;
 static gboolean include_border = FALSE;
 static char *border_effect = NULL;
+static gint duration = 0;
+static gint framerate = 10;
 
 /* some local prototypes */
 static void display_help           (ScreenshotDialog *dialog);
@@ -97,24 +101,27 @@ display_help (ScreenshotDialog *dialog)
 /* We assume that uri is valid and has been tested elsewhere
  */
 static char *
-generate_filename_for_uri (const char *uri)
+generate_filename_for_uri (const char *uri, const gchar *ext)
 {
   char *retval;
   char *tmp;
   char *file_name;
   int i = 1;
 
+	g_return_val_if_fail (ext != NULL, NULL);
+	g_return_val_if_fail (uri != NULL, NULL);
+
   if (window_title)
     {
       /* translators: this is the name of the file that gets made up
        * with the screenshot if a specific window is taken */
-      file_name = g_strdup_printf (_("Screenshot-%s.png"), window_title);
+      file_name = g_strdup_printf (_("Screenshot-%s.%s"), window_title, ext);
     }
   else
     {
       /* translators: this is the name of the file that gets made up
        * with the screenshot if the entire screen is taken */
-      file_name = g_strdup (_("Screenshot.png"));
+      file_name = g_strdup_printf (_("Screenshot.%s"), ext);
     }
 
   tmp = g_filename_from_utf8 (file_name, -1, NULL, NULL, NULL);
@@ -152,7 +159,7 @@ generate_filename_for_uri (const char *u
 	  /* translators: this is the name of the file that gets
 	   * made up with the screenshot if a specific window is
 	   * taken */
-	  file_name = g_strdup_printf (_("Screenshot-%s-%d.png"),
+	  file_name = g_strdup_printf (_("Screenshot-%s-%d.%s"), ext,
 				       window_title, i);
 	}
       else
@@ -160,7 +167,7 @@ generate_filename_for_uri (const char *u
 	  /* translators: this is the name of the file that gets
 	   * made up with the screenshot if the entire screen is
 	   * taken */
-	  file_name = g_strdup_printf (_("Screenshot-%d.png"), i);
+	  file_name = g_strdup_printf (_("Screenshot-%d.%s"), i, ext);
 	}
 
       tmp = g_filename_from_utf8 (file_name, -1, NULL, NULL, NULL);
@@ -173,37 +180,24 @@ generate_filename_for_uri (const char *u
   while (TRUE);
 }
 
-static void
-save_folder_to_gconf (ScreenshotDialog *dialog)
-{
-  GConfClient *gconf_client;
-  char *folder;
-
-  gconf_client = gconf_client_get_default ();
-
-  folder = screenshot_dialog_get_folder (dialog);
-  /* Error is NULL, as there's nothing we can do */
-  gconf_client_set_string (gconf_client,
-			   "/apps/gnome-screenshot/last_save_directory",
-			   folder, NULL);
-
-  g_object_unref (gconf_client);
-}
-
 static gboolean
-try_to_save (ScreenshotDialog *dialog,
-	     const char       *target)
+try_to_save (ScreenshotDialog *dialog, const gchar *source_path)
 {
   GnomeVFSResult result;
   GnomeVFSURI *source_uri;
   GnomeVFSURI *target_uri;
 
-  g_assert (temporary_file);
+	g_return_val_if_fail (source_path, FALSE);
 
   screenshot_dialog_set_busy (dialog, TRUE);
 
-  source_uri = gnome_vfs_uri_new (temporary_file);
-  target_uri = gnome_vfs_uri_new (target);
+  source_uri = gnome_vfs_uri_new (source_path);
+  target_uri = gnome_vfs_uri_new (screenshot_dialog_get_uri (dialog));
+	if (gnome_vfs_uri_equal (source_uri, target_uri)) {
+		gnome_vfs_uri_unref (source_uri);
+		gnome_vfs_uri_unref (target_uri);
+		return TRUE;
+	}
 
   result = screenshot_xfer_uri (source_uri,
 				target_uri,
@@ -216,7 +210,13 @@ try_to_save (ScreenshotDialog *dialog,
 
   if (result == GNOME_VFS_OK)
     {
-      save_folder_to_gconf (dialog);
+			GConfClient *gconf_client;
+
+			gconf_client = gconf_client_get_default ();
+			gconf_client_set_string (gconf_client,
+					"/apps/gnome-screenshot/last_save_directory",
+					screenshot_dialog_get_folder (dialog), NULL);
+			g_object_unref (gconf_client);
       return TRUE;
     }
 
@@ -246,7 +246,6 @@ run_dialog (ScreenshotDialog *dialog)
   GtkWidget *toplevel;
   int result;
   int keep_going;
-  char *uri;
 
   toplevel = screenshot_dialog_get_toplevel (dialog);
 
@@ -261,7 +260,6 @@ run_dialog (ScreenshotDialog *dialog)
 	  keep_going = TRUE;
 	  break;
 	case GTK_RESPONSE_OK:
-	  uri = screenshot_dialog_get_uri (dialog);
 	  if (temporary_file == NULL)
 	    {
 	      save_immediately = TRUE;
@@ -272,8 +270,8 @@ run_dialog (ScreenshotDialog *dialog)
 	    {
 	      /* We've saved the temporary file.  Lets try to copy it to the
 	       * correct location */
-	      if (! try_to_save (dialog, uri))
-		keep_going = TRUE;
+	      if (!try_to_save (dialog, temporary_file))
+					keep_going = TRUE;
 	    }
 	  break;
 	default:
@@ -283,12 +281,100 @@ run_dialog (ScreenshotDialog *dialog)
   while (keep_going);
 }
 
+#ifdef USE_GST
+
+static gboolean
+stop_func (gpointer d)
+{
+	if (!GST_IS_ELEMENT (d)) return FALSE;
+	gst_element_set_state (GST_ELEMENT (d), GST_STATE_READY);
+	return FALSE;
+}
+
+static void
+prepare_screenshot_gst (void)
+{
+	GstElement *e;
+	GError *error = NULL;
+	GtkWidget *d;
+	ScreenshotDialog *sd;
+	guint major, minor, age;
+	GTimer *timer;
+	gchar *pipeline, *audio_src, *video_src;
+
+	/* Create the pipeline */
+	temporary_file = generate_filename_for_uri (last_save_dir, "ogg");
+	audio_src = gst_gconf_get_string ("default/audiosrc");
+	video_src = gst_gconf_get_string ("default/videosrc");
+	pipeline = g_strdup_printf (""
+			"%s ! video/x-raw-rgb,framerate=(double)%i ! "
+			"ffmpegcolorspace ! "
+			"theoraenc ! "
+			"oggmux name=mux "
+			"  { %s ! audioconvert ! rawvorbisenc ! queue ! mux. } "
+			"  { mux. ! queue ! gnomevfssink location=%s }"
+			"",
+			video_src, framerate, audio_src, temporary_file);
+	g_free (video_src);
+	g_free (audio_src);
+	e = gst_parse_launch (pipeline, &error);
+	g_free (pipeline);
+	if (error || !e) {
+		if (e) g_object_unref (G_OBJECT (e));
+		unlink (temporary_file);
+		g_free (temporary_file);
+		temporary_file = NULL;
+		if (error)
+			d = gtk_message_dialog_new (NULL, 0,
+					GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
+					_("Unable to take a screenshot: %s"), error->message);
+		else
+			d = gtk_message_dialog_new (NULL, 0,
+					GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
+					_("Unable to take a screenshot."));
+		if (error) g_error_free (error);
+		gtk_dialog_run (GTK_DIALOG (d));
+		gtk_widget_destroy (d);
+		exit (1);
+	}
+
+	/*
+	 * Take the screenshot. The syntax changed between
+	 * the different versions of GStreamer.
+	 */
+	gst_version (&major, &minor, &age);
+	switch (minor) {
+	case 8:
+		gst_element_set_state (e, GST_STATE_PLAYING);
+		timer = g_timer_new ();
+		g_timer_start (timer);
+		while (g_timer_elapsed (timer, NULL) < (gdouble) duration)
+			gst_bin_iterate (GST_BIN (e));
+		g_timer_destroy (timer);
+		break;
+	case 9:
+	default:
+		g_timeout_add (duration * 1000, stop_func, e);
+		gst_element_set_state (e, GST_STATE_PLAYING);
+		break;
+	}
+	gst_element_set_state (e, GST_STATE_READY);
+	g_object_unref (G_OBJECT (e));
+
+	/* Ask the user where to store the file. */
+	sd = screenshot_dialog_new (NULL, temporary_file, take_window_shot);
+	run_dialog (sd);
+}
+
+#endif
+
 static void
 prepare_screenshot (void)
 {
   ScreenshotDialog *dialog;
   Window win;
   char *initial_uri;
+	GdkPixbuf *screenshot;
 
   if (!screenshot_grab_lock ())
     exit (0);
@@ -318,7 +404,7 @@ prepare_screenshot (void)
 
   screenshot = screenshot_get_pixbuf (win);
 
-  if (take_window_shot && drop_shadow)
+  if (take_window_shot)
     {
       GdkPixbuf *old = screenshot;
 
@@ -343,7 +429,7 @@ prepare_screenshot (void)
 
 
   /* If uri isn't local, we should do this async before taking the sshot */
-  initial_uri = generate_filename_for_uri (last_save_dir);
+  initial_uri = generate_filename_for_uri (last_save_dir, "png");
   dialog = screenshot_dialog_new (screenshot, initial_uri, take_window_shot);
   g_free (initial_uri);
 
@@ -357,7 +443,11 @@ static gboolean
 prepare_screenshot_timeout (gpointer data)
 {
   gtk_main_quit ();
+#ifdef USE_GST
+	prepare_screenshot_gst ();
+#else
   prepare_screenshot ();
+#endif
 
   return FALSE;
 }
@@ -411,6 +501,11 @@ main (int argc, char *argv[])
       {"include-border", '\0', POPT_ARG_NONE, NULL, 0, N_("Include the window border with the screenshot"), NULL},
       {"delay", '\0', POPT_ARG_INT, NULL, 0, N_("Take screenshot after specified delay [in seconds]"), NULL},
       {"border-effect", '\0', POPT_ARG_STRING, NULL, 0, N_("Effect to add to the window border"), NULL},
+#ifdef USE_GST
+			{"duration", '\0', POPT_ARG_INT, NULL, duration, N_("Take screenshots for a specified duration [in seconds]"), NULL},
+			{"framerate", '\0', POPT_ARG_INT, NULL, framerate, N_("Take screenshots using a specified framerate [in frames per second]"), NULL},
+			{NULL, '\0', POPT_ARG_INCLUDE_TABLE, NULL, 0, "GStreamer", NULL},
+#endif
       {NULL, '\0', 0, NULL, 0, NULL, NULL}
     };
 
@@ -418,6 +513,11 @@ main (int argc, char *argv[])
   opts[1].arg = &include_border_arg;
   opts[2].arg = &delay_arg;
   opts[3].arg = &border_effect_arg;
+#ifdef USE_GST
+	opts[4].arg = &duration;
+	opts[5].arg = &framerate;
+	opts[6].arg = (void *) gst_init_get_popt_table ();
+#endif
 
   setlocale (LC_ALL, "");
   bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
@@ -446,6 +546,11 @@ main (int argc, char *argv[])
       border_effect = border_effect_arg;
     }
 
+#ifdef USE_GST
+	framerate = MAX (1, framerate);
+	duration = MAX (0, duration);
+#endif
+
   if (delay_arg > 0)
     {      
       g_timeout_add (delay_arg * 1000,
@@ -455,7 +560,14 @@ main (int argc, char *argv[])
     }
   else
     {
+#ifdef USE_GST
+			if (duration)
+				prepare_screenshot_gst ();
+			else
+				prepare_screenshot ();
+#else
       prepare_screenshot ();
+#endif
     }
 
   return 0;
Index: gnome-screenshot/screenshot-dialog.c
===================================================================
RCS file: /cvs/gnome/gnome-utils/gnome-screenshot/screenshot-dialog.c,v
retrieving revision 1.6
diff -u -3 -p -r1.6 screenshot-dialog.c
--- gnome-screenshot/screenshot-dialog.c	22 Jan 2005 12:34:12 -0000	1.6
+++ gnome-screenshot/screenshot-dialog.c	20 May 2005 23:00:21 -0000
@@ -198,12 +198,6 @@ screenshot_dialog_new (GdkPixbuf *screen
       exit (1);
     }
 
-  width = gdk_pixbuf_get_width (screenshot);
-  height = gdk_pixbuf_get_height (screenshot);
-
-  width /= 5;
-  height /= 5;
-
   toplevel = glade_xml_get_widget (dialog->xml, "toplevel");
   aspect_frame = glade_xml_get_widget (dialog->xml, "aspect_frame");
   preview_darea = glade_xml_get_widget (dialog->xml, "preview_darea");
@@ -219,11 +213,17 @@ screenshot_dialog_new (GdkPixbuf *screen
   g_free (current_folder);
   g_free (current_name);
 
-  gtk_widget_set_size_request (preview_darea, width, height);
+	if (!screenshot) {
+		gtk_widget_show_all (toplevel);
+		gtk_widget_hide (aspect_frame);
+		return dialog;
+	}
+
+	width = gdk_pixbuf_get_width (screenshot);
+	height = gdk_pixbuf_get_height (screenshot);
+  gtk_widget_set_size_request (preview_darea, width / 5, height / 5);
   gtk_aspect_frame_set (GTK_ASPECT_FRAME (aspect_frame), 0.0, 0.5,
-			gdk_pixbuf_get_width (screenshot)/
-			(gfloat) gdk_pixbuf_get_height (screenshot),
-			FALSE);
+			width / (gfloat) height, FALSE);
   g_signal_connect (toplevel, "key_press_event", G_CALLBACK (on_toplevel_key_press_event), dialog);
   g_signal_connect (preview_darea, "expose_event", G_CALLBACK (on_preview_expose_event), dialog);
   g_signal_connect (preview_darea, "button_press_event", G_CALLBACK (on_preview_button_press_event), dialog);
