[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