[Xfce4-commits] <xfce4-screenshooter:master> Capture the cursor using XFIXES (bug #7567).

Jérôme Guelfucci noreply at xfce.org
Wed May 11 01:22:01 CEST 2011


Updating branch refs/heads/master
         to af0904e147c72fadf8bdea4345a067c6500d91e8 (commit)
       from 21f850342ff6b54919b3cbd60696dfac09112034 (commit)

commit af0904e147c72fadf8bdea4345a067c6500d91e8
Author: Guido Berhoerster <gber at opensuse.org>
Date:   Wed May 11 01:05:34 2011 +0200

    Capture the cursor using XFIXES (bug #7567).

 Makefile.am                 |    4 +-
 configure.ac.in             |    2 +
 lib/screenshooter-capture.c |  123 ++++++++++++++++++++++++++++++++++++-------
 lib/screenshooter-capture.h |    3 +
 4 files changed, 112 insertions(+), 20 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index c50b9e3..703a761 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -39,6 +39,7 @@ lib_libscreenshooter_la_CFLAGS = \
 	@LIBXFCE4UTIL_CFLAGS@ \
 	@LIBXFCE4UI_CFLAGS@ \
 	@SOUP_CFLAGS@ \
+	@XFIXES_CFLAGS@ \
   -DPACKAGE_LOCALE_DIR=\"$(localedir)\"
 
 lib_libscreenshooter_la_LIBADD = \
@@ -49,7 +50,8 @@ lib_libscreenshooter_la_LIBADD = \
   @GLIB_LIBS@ \
 	@SOUP_LIBS@ \
 	@LIBXEXT_LIBS@ \
-	@LIBX11_LIBS@
+	@LIBX11_LIBS@ \
+	@XFIXES_LIBS@
 
 lib_libscreenshooter_built_sources = \
 	lib/screenshooter-marshal.c lib/screenshooter-marshal.h
diff --git a/configure.ac.in b/configure.ac.in
index 3367312..3f44a44 100644
--- a/configure.ac.in
+++ b/configure.ac.in
@@ -55,6 +55,7 @@ XDT_CHECK_PACKAGE([GLIB], [glib-2.0], [2.16.0])
 XDT_CHECK_PACKAGE([SOUP], [libsoup-2.4], [2.26.0])
 XDT_CHECK_PACKAGE([EXO], [exo-1], [0.5.0])
 XDT_CHECK_PACKAGE([LIBXEXT], [xext], [1.0.0])
+XDT_CHECK_OPTIONAL_PACKAGE([XFIXES], [xfixes], [4.0.0], [xfixes], [XFIXES extension support])
 XDT_CHECK_LIBX11()
 
 dnl **************************
@@ -116,6 +117,7 @@ echo ""
 echo "Build Configuration:"
 echo ""
 
+echo "  * XFIXES support:                $XFIXES_FOUND"
 echo "  * Debugging support:             $enable_debug"
 
 echo ""
diff --git a/lib/screenshooter-capture.c b/lib/screenshooter-capture.c
index 32b32e6..881a942 100644
--- a/lib/screenshooter-capture.c
+++ b/lib/screenshooter-capture.c
@@ -53,6 +53,14 @@ typedef struct
 static GdkWindow       *get_active_window                   (GdkScreen      *screen,
                                                              gboolean       *needs_unref,
                                                              gboolean       *border);
+static void             free_pixmap_data                    (guchar *pixels,
+                                                             gpointer data);
+static GdkPixbuf       *get_cursor_pixbuf                   (GdkDisplay *display,
+                                                             GdkWindow *root,
+                                                             gint *cursorx,
+                                                             gint *cursory,
+                                                             gint *xhot,
+                                                             gint *yhot);
 static GdkPixbuf       *get_window_screenshot               (GdkWindow      *window,
                                                              gboolean        show_mouse,
                                                              gboolean        border);
@@ -165,6 +173,98 @@ find_wm_window (Window xid)
 }
 
 
+static void free_pixmap_data (guchar *pixels,  gpointer data)
+{
+  g_free (pixels);
+}
+
+
+static GdkPixbuf *get_cursor_pixbuf (GdkDisplay *display,
+                                     GdkWindow *root,
+                                     gint *cursorx,
+                                     gint *cursory,
+                                     gint *xhot,
+                                     gint *yhot)
+{
+  GdkCursor *cursor = NULL;
+  GdkPixbuf *cursor_pixbuf = NULL;
+
+#ifdef HAVE_XFIXES
+  int event_basep;
+  int error_basep;
+  XFixesCursorImage *cursor_image = NULL;
+  guchar *cursor_pixmap_data = NULL;
+  gint i, j;
+  guint32 tmp;
+
+  if (!XFixesQueryExtension (GDK_DISPLAY_XDISPLAY (display),
+                             &event_basep,
+                             &error_basep))
+    goto fallback;
+
+  TRACE ("Get the mouse cursor, its image, position and hotspot");
+
+  cursor_image = XFixesGetCursorImage (GDK_DISPLAY_XDISPLAY (display));
+  if (cursor_image == NULL)
+    goto fallback;
+
+  *cursorx = cursor_image->x;
+  *cursory = cursor_image->y;
+  *xhot = cursor_image->xhot;
+  *yhot = cursor_image->yhot;
+
+  /* cursor_image->pixels contains premultiplied 32-bit ARGB data stored in
+   * long (!)
+   */
+  cursor_pixmap_data = g_new (guchar,
+                              cursor_image->width * cursor_image->height * 4);
+  for (i = 0, j = 0; i < cursor_image->width * cursor_image->height;
+       i++, j += 4)
+    {
+      tmp = ((guint32)cursor_image->pixels[i] << 8) | \
+            ((guint32)cursor_image->pixels[i] >> 24);
+      cursor_pixmap_data[j] = tmp >> 24;
+      cursor_pixmap_data[j + 1] = (tmp >> 16) & 0xff;
+      cursor_pixmap_data[j + 2] = (tmp >> 8) & 0xff;
+      cursor_pixmap_data[j + 3] = tmp & 0xff;
+    }
+  cursor_pixbuf = gdk_pixbuf_new_from_data (cursor_pixmap_data,
+                                            GDK_COLORSPACE_RGB,
+                                            TRUE,
+                                            8,
+                                            cursor_image->width,
+                                            cursor_image->height,
+                                            cursor_image->width * 4,
+                                            free_pixmap_data,
+                                            NULL);
+
+  XFree(cursor_image);
+  if (cursor_pixbuf != NULL)
+    return cursor_pixbuf;
+
+fallback:
+#endif
+  TRACE ("Get the mouse cursor and its image through fallback mode");
+
+  cursor = gdk_cursor_new_for_display (display, GDK_LEFT_PTR);
+  cursor_pixbuf = gdk_cursor_get_image (cursor);
+  if (cursor_pixbuf == NULL)
+    return NULL;
+
+  TRACE ("Get the coordinates of the cursor");
+
+  gdk_window_get_pointer (root, cursorx, cursory, NULL);
+
+  TRACE ("Get the cursor hotspot");
+
+  sscanf (gdk_pixbuf_get_option (cursor_pixbuf, "x_hot"), "%d", xhot);
+  sscanf (gdk_pixbuf_get_option (cursor_pixbuf, "y_hot"), "%d", yhot);
+
+  gdk_cursor_unref (cursor);
+
+  return cursor_pixbuf;
+}
+
 
 static GdkPixbuf
 *get_window_screenshot (GdkWindow *window,
@@ -317,28 +417,16 @@ static GdkPixbuf
 
   if (show_mouse)
     {
-        GdkCursor *cursor;
+        gint cursorx, cursory, xhot, yhot;
         GdkPixbuf *cursor_pixbuf;
+        GdkDisplay *display = gdk_display_get_default ();
 
-        /* Add the mouse pointer to the grabbed screenshot */
-        TRACE ("Get the mouse cursor and its image");
-
-        cursor = gdk_cursor_new_for_display (gdk_display_get_default (), GDK_LEFT_PTR);
-        cursor_pixbuf = gdk_cursor_get_image (cursor);
+        cursor_pixbuf = get_cursor_pixbuf (display, root, &cursorx, &cursory,
+                                           &xhot, &yhot);
 
         if (G_LIKELY (cursor_pixbuf != NULL))
           {
             GdkRectangle rectangle_window, rectangle_cursor;
-            gint cursorx, cursory, xhot, yhot;
-
-            TRACE ("Get the coordinates of the cursor");
-
-            gdk_window_get_pointer (root, &cursorx, &cursory, NULL);
-
-            TRACE ("Get the cursor hotspot");
-
-            sscanf (gdk_pixbuf_get_option (cursor_pixbuf, "x_hot"), "%d", &xhot);
-            sscanf (gdk_pixbuf_get_option (cursor_pixbuf, "y_hot"), "%d", &yhot);
 
             /* rectangle_window stores the window coordinates */
             rectangle_window.x = x_orig;
@@ -370,15 +458,12 @@ static GdkPixbuf
 
             g_object_unref (cursor_pixbuf);
           }
-
-        gdk_cursor_unref (cursor);
     }
 
   return screenshot;
 }
 
 
-
 /* Callbacks for the rubber banding function */
 static gboolean cb_key_pressed (GtkWidget   *widget,
                                 GdkEventKey *event,
diff --git a/lib/screenshooter-capture.h b/lib/screenshooter-capture.h
index 804ad03..7f871f3 100644
--- a/lib/screenshooter-capture.h
+++ b/lib/screenshooter-capture.h
@@ -26,6 +26,9 @@
 
 #include "screenshooter-global.h"
 
+#ifdef HAVE_XFIXES
+#include <X11/extensions/Xfixes.h>
+#endif
 #include <X11/extensions/shape.h>
 #include <gdk/gdkkeysyms.h>
 #include <gdk/gdkx.h>



More information about the Xfce4-commits mailing list