[gtk-vnc-devel] API for capturing display to a pixbuf



The attached patch adds a new API


    GdkPixbuf *vnc_display_get_pixbuf(VncDisplay *vnc);

which captures the contents of the remote display into a pixbuf. The primary
motivation is that this pixbuf can then be saved to a file. eg this allows
the viewer to implement 'take a screenshot' functionality - I've added to the
example programs so that 'F12' saves the display to gvncviewer.png

Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 
changeset:   24:725c05c132d2
tag:         tip
user:        "Daniel P. Berrange <berrange redhat com>"
date:        Thu Jul 05 16:43:33 2007 -0400
files:       examples/gvncviewer.c examples/gvncviewer.py src/libgtk-vnc_sym.version src/vncdisplay.c src/vncdisplay.h src/vncshmimage.c src/vncshmimage.h
description:
Added API for getting a pixbuf of display data (eg for taking screenshots)


diff -r 7f9c4f423f86 -r 725c05c132d2 examples/gvncviewer.c
--- a/examples/gvncviewer.c	Thu Jul 05 13:48:15 2007 -0400
+++ b/examples/gvncviewer.c	Thu Jul 05 16:43:33 2007 -0400
@@ -1,5 +1,6 @@
 #include "vncdisplay.h"
 #include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
 #include <stdlib.h>
 
 #include <sys/socket.h>
@@ -8,6 +9,18 @@
 #include <arpa/inet.h>
 
 GtkWidget *window;
+GtkWidget *vnc;
+
+gboolean vnc_screenshot(GtkWidget *window, GdkEvent *ev)
+{
+	if (ev->key.keyval == GDK_F12) {
+		GdkPixbuf *pix = vnc_display_get_pixbuf(VNC_DISPLAY(vnc));
+		gdk_pixbuf_save(pix, "gvncviewer.png", "png", NULL, "tEXt::Generator App", "gvncviewer", NULL);
+		gdk_pixbuf_unref(pix);
+		printf("Screenshot saved to gvncviewer.png\n");
+	}
+	return FALSE;
+}
 
 void vnc_disconnect(GtkWidget *vnc)
 {
@@ -78,7 +91,6 @@ void vnc_credential(GtkWidget *vnc, int 
 
 int main(int argc, char **argv)
 {
-	GtkWidget *vnc;
 	char *ret = NULL;
 
 	if (argc != 3 && argc != 4) {
@@ -111,6 +123,9 @@ int main(int argc, char **argv)
 	gtk_signal_connect(GTK_OBJECT(vnc), "vnc-auth-credential",
 			   GTK_SIGNAL_FUNC(vnc_credential), NULL);
 
+	gtk_signal_connect(GTK_OBJECT(window), "key-press-event",
+			   GTK_SIGNAL_FUNC(vnc_screenshot), NULL);
+
 	gtk_main();
 
 	return 0;
diff -r 7f9c4f423f86 -r 725c05c132d2 examples/gvncviewer.py
--- a/examples/gvncviewer.py	Thu Jul 05 13:48:15 2007 -0400
+++ b/examples/gvncviewer.py	Thu Jul 05 16:43:33 2007 -0400
@@ -9,6 +9,15 @@ if len(sys.argv) != 3 and len(sys.argv) 
     sys.exit(1)
 
 w = gtk.Window()
+v = gtkvnc.Display()
+
+def vnc_keypress(src, ev):
+    if ev.keyval == gtk.gdk.keyval_from_name("F12"):
+        pix = v.get_pixbuf()
+
+        pix.save("gvncviewer.png", "png", { "tEXt::Generator App": "gvncviewer.py" })
+        print "Screenshot saved to gvncviewer.png"
+    return False
 
 def vnc_disconnect(src):
     print "VNC disconnected"
@@ -48,7 +57,7 @@ def vnc_credential(src, type):
         src.set_credential(type, data)
     dialog.destroy()
 
-v = gtkvnc.Display()
+
 w.add(v)
 v.realize()
 
@@ -59,6 +68,7 @@ v.connect("vnc-disconnected", vnc_discon
 v.connect("vnc-disconnected", vnc_disconnect)
 v.connect("vnc-initialized", vnc_initialize)
 v.connect("vnc-auth-credential", vnc_credential)
+w.connect("key-press-event", vnc_keypress)
 w.connect("delete-event", gtk.main_quit)
 
 gtk.main()
diff -r 7f9c4f423f86 -r 725c05c132d2 src/libgtk-vnc_sym.version
--- a/src/libgtk-vnc_sym.version	Thu Jul 05 13:48:15 2007 -0400
+++ b/src/libgtk-vnc_sym.version	Thu Jul 05 16:43:33 2007 -0400
@@ -12,6 +12,8 @@
 
     vnc_display_set_credential;
 
+    vnc_display_get_pixbuf;
+
     vnc_display_set_use_shm;
     vnc_display_get_width;
     vnc_display_get_height;
diff -r 7f9c4f423f86 -r 725c05c132d2 src/vncdisplay.c
--- a/src/vncdisplay.c	Thu Jul 05 13:48:15 2007 -0400
+++ b/src/vncdisplay.c	Thu Jul 05 16:43:33 2007 -0400
@@ -747,6 +747,14 @@ GType vnc_display_credential_get_type(vo
 }
 
 
+GdkPixbuf * vnc_display_get_pixbuf(VncDisplay *obj)
+{
+	if (!obj->priv->gvnc ||
+	    !gvnc_is_connected(obj->priv->gvnc))
+		return NULL;
+
+	return vnc_shm_image_get_pixbuf(obj->priv->shm_image);
+}
 
 
 int vnc_display_get_width(VncDisplay *obj)
diff -r 7f9c4f423f86 -r 725c05c132d2 src/vncdisplay.h
--- a/src/vncdisplay.h	Thu Jul 05 13:48:15 2007 -0400
+++ b/src/vncdisplay.h	Thu Jul 05 16:43:33 2007 -0400
@@ -78,6 +78,7 @@ gboolean	vnc_display_set_credential(VncD
 gboolean	vnc_display_set_credential(VncDisplay *obj, int type, const gchar *data);
 
 void		vnc_display_set_use_shm(VncDisplay *obj, gboolean enable);
+GdkPixbuf *     vnc_display_get_pixbuf(VncDisplay *obj);
 
 int		vnc_display_get_width(VncDisplay *obj);
 int		vnc_display_get_height(VncDisplay *obj);
diff -r 7f9c4f423f86 -r 725c05c132d2 src/vncshmimage.c
--- a/src/vncshmimage.c	Thu Jul 05 13:48:15 2007 -0400
+++ b/src/vncshmimage.c	Thu Jul 05 16:43:33 2007 -0400
@@ -191,6 +191,39 @@ void vnc_shm_image_draw(VncShmImage *obj
 			     width, height, False);
 }
 
+GdkPixbuf *     vnc_shm_image_get_pixbuf(VncShmImage *obj)
+{
+	VncShmImagePrivate *priv = obj->priv;
+	if (priv->image) {
+		GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
+						   FALSE,
+						   8,
+						   obj->width,
+						   obj->height);
+
+		if (!gdk_pixbuf_get_from_image(pixbuf,
+					       priv->image,
+					       gdk_colormap_get_system(),
+					       0,0,0,0,
+					       obj->width,
+					       obj->height)) {
+			gdk_pixbuf_unref(pixbuf);
+			return NULL;
+		}
+		return pixbuf;
+	} else {
+		return gdk_pixbuf_new_from_data((guchar *)priv->ximage,
+						GDK_COLORSPACE_RGB,
+						FALSE,
+						obj->bpp * 8,
+						obj->width,
+						obj->height,
+						obj->bytes_per_line,
+						NULL,
+						NULL);
+	}
+}
+
 GType vnc_shm_image_get_type(void)
 {
 	static GType type;
@@ -218,3 +251,11 @@ GType vnc_shm_image_get_type(void)
 	return type;
 }
 
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 7f9c4f423f86 -r 725c05c132d2 src/vncshmimage.h
--- a/src/vncshmimage.h	Thu Jul 05 13:48:15 2007 -0400
+++ b/src/vncshmimage.h	Thu Jul 05 16:43:33 2007 -0400
@@ -67,6 +67,16 @@ void		vnc_shm_image_draw(VncShmImage *ob
 				   gint xdest, gint ydest,
 				   gint width, gint height);
 
+GdkPixbuf *     vnc_shm_image_get_pixbuf(VncShmImage *obj);
+
 G_END_DECLS
 
 #endif
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */



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