gnome-utils r8018 - in trunk: . gnome-screenshot
- From: ebassi svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-utils r8018 - in trunk: . gnome-screenshot
- Date: Mon, 25 Aug 2008 15:59:57 +0000 (UTC)
Author: ebassi
Date: Mon Aug 25 15:59:57 2008
New Revision: 8018
URL: http://svn.gnome.org/viewvc/gnome-utils?rev=8018&view=rev
Log:
2008-08-25 Emmanuele Bassi <ebassi gnome org>
Bug 549033 â Drop hard dependency on X, use Gdk instead (Cosimo
Cecchi)
* configure.ac: Fix the dependencies check for gnome-screenshot.
* gnome-screenshot/screenshot-utils.[ch]: Drop the usage of
X11 API wherever is possible and use GDK instead. We still need
to use XShapeGetRectangles because GDK doesn't have a similar
API.
* gnome-screenshot/gnome-screenshot.c:
(finish_prepare_screenshot): Update for the new internal API changes.
Modified:
trunk/ChangeLog
trunk/configure.ac
trunk/gnome-screenshot/gnome-screenshot.c
trunk/gnome-screenshot/screenshot-utils.c
trunk/gnome-screenshot/screenshot-utils.h
Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac (original)
+++ trunk/configure.ac Mon Aug 25 15:59:57 2008
@@ -1,4 +1,4 @@
-AC_INIT([gnome-utils], [2.21.0],
+AC_INIT([gnome-utils], [2.23.0],
[http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-utils])
AM_CONFIG_HEADER(config.h)
AM_INIT_AUTOMAKE
@@ -53,7 +53,7 @@
# change to C+1:0:0
# - If the interface is the same as the previous version, change to C:R+1:A
-LIBGDICT_LT_VERSION=6:0:0
+LIBGDICT_LT_VERSION=6:1:0
AC_SUBST(LIBGDICT_LT_VERSION)
dnl *****************************************
@@ -139,14 +139,11 @@
dnl *****************************************
dnl screenshot modules
dnl *****************************************
-#AC_CHECK_HEADERS(X11/extensions/shape.h, XSHAPE_LIBS="-lXext")
-#AC_CHECK_HEADERS(X11/extensions/Xfixes.h, XFIXES_LIBS="-lXfixes", , [#include <X11/Xlib.h>])
-#AC_SUBST(XSHAPE_LIBS)
-#AC_SUBST(XFIXES_LIBS)
-
-PKG_CHECK_MODULES(SCREENSHOT, xext dnl
- xfixes dnl
- gio-2.0 >= $GLIB_REQUIRED dnl
+
+AC_CHECK_HEADERS(X11/extensions/shape.h, XSHAPE_LIBS="-lXext")
+AC_SUBST(XSHAPE_LIBS)
+
+PKG_CHECK_MODULES(SCREENSHOT, gio-2.0 >= $GLIB_REQUIRED dnl
gtk+-2.0 >= $GTK_REQUIRED dnl
libgnomeui-2.0 >= $LIBGNOMEUI_REQUIRED dnl
libglade-2.0 >= $LIBGLADE_REQUIRED)
Modified: trunk/gnome-screenshot/gnome-screenshot.c
==============================================================================
--- trunk/gnome-screenshot/gnome-screenshot.c (original)
+++ trunk/gnome-screenshot/gnome-screenshot.c Mon Aug 25 15:59:57 2008
@@ -703,24 +703,24 @@
finish_prepare_screenshot (char *initial_uri)
{
ScreenshotDialog *dialog;
- Window win;
+ GdkWindow *window;
if (!screenshot_grab_lock ())
exit (0);
if (take_window_shot)
{
- win = screenshot_find_current_window (include_border);
- if (win == None)
+ window = screenshot_find_current_window ();
+ if (!window)
{
take_window_shot = FALSE;
- win = GDK_ROOT_WINDOW ();
+ window = gdk_get_default_root_window ();
}
else
{
gchar *tmp;
- window_title = screenshot_get_window_title (win);
+ window_title = screenshot_get_window_title (window);
tmp = screenshot_sanitize_filename (window_title);
g_free (window_title);
window_title = tmp;
@@ -728,10 +728,10 @@
}
else
{
- win = GDK_ROOT_WINDOW ();
+ window = gdk_get_default_root_window ();
}
- screenshot = screenshot_get_pixbuf (win, include_pointer);
+ screenshot = screenshot_get_pixbuf (window, include_pointer, include_border);
if (take_window_shot) {
switch (border_effect[0])
Modified: trunk/gnome-screenshot/screenshot-utils.c
==============================================================================
--- trunk/gnome-screenshot/screenshot-utils.c (original)
+++ trunk/gnome-screenshot/screenshot-utils.c Mon Aug 25 15:59:57 2008
@@ -1,6 +1,7 @@
/* screenshot-utils.c - common functions for GNOME Screenshot
*
* Copyright (C) 2001-2006 Jonathan Blandford <jrb alum mit edu>
+ * Copyright (C) 2008 Cosimo Cecchi <cosimoc gnome org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
@@ -20,8 +21,8 @@
#include "config.h"
#include "screenshot-utils.h"
-#include <X11/Xatom.h>
#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
#include <glib.h>
#include <glib/gi18n.h>
@@ -29,214 +30,57 @@
#include <X11/extensions/shape.h>
#endif
-#include <X11/extensions/Xfixes.h>
-
static GtkWidget *selection_window;
#define SELECTION_NAME "_GNOME_PANEL_SCREENSHOT"
-
-/* Functions to deal with properties from libwnck */
-static char * text_property_to_utf8 (const XTextProperty *prop);
-static Window get_window_property (Window xwindow,
- Atom atom);
-static char *get_text_property (Window xwindow,
- Atom atom);
-static char *get_utf8_property (Window xwindow,
- Atom atom);
-static gboolean get_atom_property (Window xwindow,
- Atom atom,
- Atom *val);
-
static char *
-text_property_to_utf8 (const XTextProperty *prop)
+get_utf8_property (GdkWindow *window,
+ GdkAtom atom)
{
- char **list;
- int count;
+ gboolean res;
+ GdkAtom utf8_string;
+ GdkAtom type;
+ int actual_format, actual_length;
+ guchar *data;
char *retval;
- list = NULL;
-
- count = gdk_text_property_to_utf8_list (gdk_x11_xatom_to_atom (prop->encoding),
- prop->format,
- prop->value,
- prop->nitems,
- &list);
-
- if (count == 0)
+ utf8_string = gdk_x11_xatom_to_atom (gdk_x11_get_xatom_by_name ("UTF8_STRING"));
+ res = gdk_property_get (window, atom, utf8_string,
+ 0, G_MAXLONG, FALSE,
+ &type,
+ &actual_format, &actual_length,
+ &data);
+ if (!res)
return NULL;
- retval = list[0];
- list[0] = g_strdup (""); /* something to free */
-
- g_strfreev (list);
-
- return retval;
-}
-
-/* Borrowed from libwnck */
-static Window
-get_window_property (Window xwindow,
- Atom atom)
-{
- Atom type;
- int format;
- gulong nitems;
- gulong bytes_after;
- Window *w;
- int err, result;
- Window retval;
-
- gdk_error_trap_push ();
-
- type = None;
- result = XGetWindowProperty (gdk_display,
- xwindow,
- atom,
- 0, G_MAXLONG,
- False, XA_WINDOW, &type, &format, &nitems,
- &bytes_after, (unsigned char **) &w);
- err = gdk_error_trap_pop ();
-
- if (err != Success ||
- result != Success)
- return None;
-
- if (type != XA_WINDOW)
+ if (type != utf8_string || actual_format != 8 || actual_length == 0)
{
- XFree (w);
- return None;
+ g_free (data);
+ return NULL;
}
- retval = *w;
- XFree (w);
-
- return retval;
-}
-
-static char*
-get_text_property (Window xwindow,
- Atom atom)
-{
- XTextProperty text;
- char *retval;
-
- gdk_error_trap_push ();
-
- text.nitems = 0;
- if (XGetTextProperty (gdk_display,
- xwindow,
- &text,
- atom))
+ if (!g_utf8_validate ((gchar *) data, actual_length, NULL))
{
- retval = text_property_to_utf8 (&text);
+ char *atom_name = gdk_atom_name (atom);
- if (text.nitems > 0)
- XFree (text.value);
- }
- else
- {
- retval = NULL;
- }
-
- gdk_error_trap_pop ();
-
- return retval;
-}
-
-static char *
-get_utf8_property (Window xwindow,
- Atom atom)
-{
- Atom type;
- int format;
- gulong nitems;
- gulong bytes_after;
- guchar *val;
- int err, result;
- char *retval;
- Atom utf8_string;
+ g_warning ("Property `%s' (format: %d, length: %d) contained "
+ "invalid UTF-8",
+ atom_name,
+ actual_format,
+ actual_length);
- utf8_string = gdk_x11_get_xatom_by_name ("UTF8_STRING");
+ g_free (atom_name);
+ g_free (data);
- gdk_error_trap_push ();
- type = None;
- val = NULL;
- result = XGetWindowProperty (gdk_display,
- xwindow,
- atom,
- 0, G_MAXLONG,
- False, utf8_string,
- &type, &format, &nitems,
- &bytes_after, (guchar **)&val);
- err = gdk_error_trap_pop ();
-
- if (err != Success ||
- result != Success)
- return NULL;
-
- if (type != utf8_string ||
- format != 8 ||
- nitems == 0)
- {
- if (val)
- XFree (val);
- return NULL;
- }
-
- if (!g_utf8_validate ((gchar *)val, nitems, NULL))
- {
- g_warning ("Property %s contained invalid UTF-8\n",
- gdk_x11_get_xatom_name (atom));
- XFree (val);
return NULL;
}
- retval = g_strndup ((gchar *)val, nitems);
-
- XFree (val);
-
- return retval;
-}
+ retval = g_strndup ((gchar *) data, actual_length);
-static gboolean
-get_atom_property (Window xwindow,
- Atom atom,
- Atom *val)
-{
- Atom type;
- int format;
- gulong nitems;
- gulong bytes_after;
- unsigned char *a;
- int err, result;
-
- *val = 0;
-
- gdk_error_trap_push ();
- type = None;
- result = XGetWindowProperty (gdk_display,
- xwindow,
- atom,
- 0, G_MAXLONG,
- False, XA_ATOM, &type, &format, &nitems,
- &bytes_after, &a);
- err = gdk_error_trap_pop ();
- if (err != Success ||
- result != Success)
- return FALSE;
-
- if (type != XA_ATOM)
- {
- XFree (a);
- return FALSE;
- }
-
- *val = *a;
+ g_free (data);
- XFree (a);
-
- return TRUE;
+ return retval;
}
/* To make sure there is only one screenshot taken at a time,
@@ -246,13 +90,14 @@
gboolean
screenshot_grab_lock (void)
{
- Atom selection_atom;
+ GdkAtom selection_atom;
GdkCursor *cursor;
gboolean result = FALSE;
- selection_atom = gdk_x11_get_xatom_by_name (SELECTION_NAME);
- XGrabServer (GDK_DISPLAY ());
- if (XGetSelectionOwner (GDK_DISPLAY(), selection_atom) != None)
+ selection_atom = gdk_atom_intern (SELECTION_NAME, FALSE);
+ gdk_x11_grab_server ();
+
+ if (gdk_selection_owner_get (selection_atom) != NULL)
goto out;
selection_window = gtk_invisible_new ();
@@ -270,7 +115,7 @@
result = TRUE;
out:
- XUngrabServer (GDK_DISPLAY ());
+ gdk_x11_ungrab_server ();
gdk_flush ();
return result;
@@ -284,222 +129,187 @@
gtk_widget_destroy (selection_window);
selection_window = NULL;
}
- gdk_flush ();
-}
-
-
-static Window
-find_toplevel_window (Window xid)
-{
- Window root, parent, *children;
- unsigned int nchildren;
-
- do
- {
- if (XQueryTree (GDK_DISPLAY (), xid, &root,
- &parent, &children, &nchildren) == 0)
- {
- g_warning ("Couldn't find window manager window");
- return None;
- }
-
- if (root == parent)
- return xid;
- xid = parent;
- }
- while (TRUE);
+ gdk_flush ();
}
-static Window
+static GdkWindow *
screenshot_find_active_window (void)
{
- Window retval = None;
- Window root_window;
+ GdkWindow *window;
+ GdkScreen *default_screen;
- root_window = GDK_ROOT_WINDOW ();
+ default_screen = gdk_screen_get_default ();
+ window = gdk_screen_get_active_window (default_screen);
- if (gdk_net_wm_supports (gdk_atom_intern ("_NET_ACTIVE_WINDOW", FALSE)))
- {
- retval = get_window_property (root_window,
- gdk_x11_get_xatom_by_name ("_NET_ACTIVE_WINDOW"));
- }
-
- return retval;
+ return window;
}
-
+
static gboolean
-screenshot_window_is_desktop (Window xid)
+screenshot_window_is_desktop (GdkWindow *window)
{
- Window root_window = GDK_ROOT_WINDOW ();
+ GdkWindow *root_window = gdk_get_default_root_window ();
+ GdkWindowTypeHint window_type_hint;
- if (xid == root_window)
+ if (window == root_window)
return TRUE;
- if (gdk_net_wm_supports (gdk_atom_intern ("_NET_WM_WINDOW_TYPE", FALSE)))
- {
- gboolean retval;
- Atom property;
+ window_type_hint = gdk_window_get_type_hint (window);
+ if (window_type_hint == GDK_WINDOW_TYPE_HINT_DESKTOP)
+ return TRUE;
- retval = get_atom_property (xid,
- gdk_x11_get_xatom_by_name ("_NET_WM_WINDOW_TYPE"),
- &property);
- if (retval &&
- property == gdk_x11_get_xatom_by_name ("_NET_WM_WINDOW_TYPE_DESKTOP"))
- return TRUE;
- }
return FALSE;
-}
-
-/* We don't actually honor include_decoration here. We need to search
- * for WM_STATE;
- */
-static Window
-screenshot_find_pointer_window (void)
-{
- Window root_window, root_return, child;
- int unused;
- guint mask;
-
- root_window = GDK_ROOT_WINDOW ();
-
- XQueryPointer (GDK_DISPLAY (), root_window,
- &root_return, &child, &unused,
- &unused, &unused, &unused, &mask);
-
- return child;
+
}
#define MAXIMUM_WM_REPARENTING_DEPTH 4
-/* adopted from eel code */
-static Window
-look_for_hint_helper (Window xid,
- Atom property,
+static GdkWindow *
+look_for_hint_helper (GdkWindow *window,
+ GdkAtom property,
int depth)
{
- Atom actual_type;
- int actual_format;
- gulong nitems, bytes_after;
- gulong *prop;
- Window root, parent, *children, window;
- unsigned int nchildren, i;
-
- if (XGetWindowProperty (GDK_DISPLAY (), xid, property, 0, 1,
- False, AnyPropertyType, &actual_type,
- &actual_format, &nitems, &bytes_after,
- (gpointer) &prop) == Success
- && prop != NULL && actual_format == 32 && prop[0] == NormalState)
+ gboolean res;
+ GdkAtom actual_type;
+ int actual_format, actual_length;
+ guchar *data;
+
+ res = gdk_property_get (window, property, GDK_NONE,
+ 0, 1, FALSE,
+ &actual_type,
+ &actual_format, &actual_length,
+ &data);
+
+ if (res == TRUE &&
+ data != NULL &&
+ actual_format == 32 &&
+ data[0] == 1)
{
- if (prop != NULL)
- {
- XFree (prop);
- }
+ g_free (data);
- return xid;
+ return window;
}
if (depth < MAXIMUM_WM_REPARENTING_DEPTH)
{
- if (XQueryTree (GDK_DISPLAY (), xid, &root,
- &parent, &children, &nchildren) != 0)
- {
- window = None;
+ GList *children, *l;
- for (i = 0; i < nchildren; i++)
- {
- window = look_for_hint_helper (children[i],
- property,
- depth + 1);
- if (window != None)
- break;
- }
+ children = gdk_window_get_children (window);
+ if (children != NULL)
+ {
+ for (l = children; l; l = l->next)
+ {
+ window = look_for_hint_helper (l->data, property, depth + 1);
+ if (window)
+ break;
+ }
- if (children != NULL)
- XFree (children);
+ g_list_free (children);
- if (window)
- return window;
- }
+ if (window)
+ return window;
+ }
}
- return None;
+ return NULL;
}
-static Window
-look_for_hint (Window xid,
- Atom property)
+static GdkWindow *
+look_for_hint (GdkWindow *window,
+ GdkAtom property)
{
- Window retval;
+ GdkWindow *retval;
- retval = look_for_hint_helper (xid, property, 0);
+ retval = look_for_hint_helper (window, property, 0);
return retval;
}
-
-Window
-screenshot_find_current_window (gboolean include_decoration)
+GdkWindow *
+screenshot_find_current_window ()
{
- Window current_window;
+ GdkWindow *current_window;
- /* First, search for _NET_ACTIVE_WINDOW */
current_window = screenshot_find_active_window ();
-
- /* IF there's no _NET_ACTIVE_WINDOW, we fall back to returning the
- * Window that the cursor is in.*/
- if (current_window == None)
- current_window = screenshot_find_pointer_window ();
+
+ /* If there's no active window, we fall back to returning the
+ * window that the cursor is in.
+ */
+ if (!current_window)
+ current_window = gdk_window_at_pointer (NULL, NULL);
if (current_window)
{
if (screenshot_window_is_desktop (current_window))
- /* if the current window is the desktop (eg. nautilus), we
- * return None, as getting the whole screen makes more sense. */
- return None;
-
- /* Once we have a window, we walk the widget tree looking for
- * the appropriate window. */
- current_window = find_toplevel_window (current_window);
- if (! include_decoration)
+ /* if the current window is the desktop (e.g. nautilus), we
+ * return NULL, as getting the whole screen makes more sense.
+ */
+ return NULL;
+
+ /* Once we have a window, we take the toplevel ancestor. */
+ current_window = gdk_window_get_toplevel (current_window);
+ }
+
+ return current_window;
+}
+
+static Window
+find_wm_window (Window xid)
+{
+ Window root, parent, *children;
+ unsigned int nchildren;
+
+ do
+ {
+ if (XQueryTree (GDK_DISPLAY (), xid, &root,
+ &parent, &children, &nchildren) == 0)
{
- Window new_window;
- new_window = look_for_hint (current_window, gdk_x11_get_xatom_by_name ("WM_STATE"));
- if (new_window)
- current_window = new_window;
+ g_warning ("Couldn't find window manager window");
+ return None;
}
+
+ if (root == parent)
+ return xid;
+
+ xid = parent;
}
- return current_window;
+ while (TRUE);
}
+
GdkPixbuf *
-screenshot_get_pixbuf (Window w, gboolean include_pointer)
+screenshot_get_pixbuf (GdkWindow *window,
+ gboolean include_pointer,
+ gboolean include_border)
{
- GdkWindow *window, *root;
+ GdkWindow *root;
GdkPixbuf *screenshot;
- gint x_real_orig, y_real_orig;
- gint x_orig, y_orig;
- gint real_width, real_height;
- gint width, height;
+ gint x_real_orig, y_real_orig, x_orig, y_orig;
+ gint width, real_width, height, real_height;
-#ifdef HAVE_X11_EXTENSIONS_SHAPE_H
- XRectangle *rectangles;
- GdkPixbuf *tmp;
- int rectangle_count, rectangle_order, i;
-#endif
+ /* If the screenshot should include the border, we look for the WM window. */
+ if (include_border)
+ {
+ Window xid, wm;
- window = gdk_window_foreign_new (w);
- if (window == NULL)
- return NULL;
-
- root = gdk_window_foreign_new (GDK_ROOT_WINDOW ());
- gdk_drawable_get_size (window, &real_width, &real_height);
+ xid = GDK_WINDOW_XWINDOW (window);
+ wm = find_wm_window (xid);
+
+ if (wm != None)
+ window = gdk_window_foreign_new (wm);
+
+ /* fallback to no border if we can't find the WM window. */
+ }
+
+ root = gdk_get_default_root_window ();
+
+ gdk_drawable_get_size (window, &real_width, &real_height);
gdk_window_get_origin (window, &x_real_orig, &y_real_orig);
x_orig = x_real_orig;
y_orig = y_real_orig;
- width = real_width;
+ width = real_width;
height = real_height;
if (x_orig < 0)
@@ -507,6 +317,7 @@
width = width + x_orig;
x_orig = 0;
}
+
if (y_orig < 0)
{
height = height + y_orig;
@@ -515,154 +326,127 @@
if (x_orig + width > gdk_screen_width ())
width = gdk_screen_width () - x_orig;
+
if (y_orig + height > gdk_screen_height ())
height = gdk_screen_height () - y_orig;
-
+
+ screenshot = gdk_pixbuf_get_from_drawable (NULL, root, NULL,
+ x_orig, y_orig, 0, 0,
+ width, height);
#ifdef HAVE_X11_EXTENSIONS_SHAPE_H
- tmp = gdk_pixbuf_get_from_drawable (NULL, root, NULL,
- x_orig, y_orig, 0, 0,
- width, height);
-
- rectangles = XShapeGetRectangles (GDK_DISPLAY (), GDK_WINDOW_XWINDOW (window),
- ShapeBounding, &rectangle_count, &rectangle_order);
- if (rectangle_count > 0)
- {
- gboolean has_alpha = gdk_pixbuf_get_has_alpha (tmp);
-
- screenshot = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
- width, height);
- gdk_pixbuf_fill (screenshot, 0);
-
- for (i = 0; i < rectangle_count; i++)
- {
- gint rec_x, rec_y;
- gint rec_width, rec_height;
- gint y;
-
- rec_x = rectangles[i].x;
- rec_y = rectangles[i].y;
- rec_width = rectangles[i].width;
- rec_height = rectangles[i].height;
-
- if (x_real_orig < 0)
- {
- rec_x += x_real_orig;
- rec_x = MAX(rec_x, 0);
- rec_width += x_real_orig;
- }
- if (y_real_orig < 0)
- {
- rec_y += y_real_orig;
- rec_y = MAX(rec_y, 0);
- rec_height += y_real_orig;
- }
-
- if (x_orig + rec_x + rec_width > gdk_screen_width ())
- rec_width = gdk_screen_width () - x_orig - rec_x;
- if (y_orig + rec_y + rec_height > gdk_screen_height ())
- rec_height = gdk_screen_height () - y_orig - rec_y;
-
- for (y = rec_y; y < rec_y + rec_height; y++)
- {
- guchar *src_pixels, *dest_pixels;
- gint x;
-
- src_pixels = gdk_pixbuf_get_pixels (tmp) +
- y * gdk_pixbuf_get_rowstride(tmp) +
- rec_x * (has_alpha ? 4 : 3);
- dest_pixels = gdk_pixbuf_get_pixels (screenshot) +
- y * gdk_pixbuf_get_rowstride (screenshot) +
- rec_x * 4;
-
- for (x = 0; x < rec_width; x++)
- {
- *dest_pixels++ = *src_pixels ++;
- *dest_pixels++ = *src_pixels ++;
- *dest_pixels++ = *src_pixels ++;
- if (has_alpha)
- *dest_pixels++ = *src_pixels++;
- else
- *dest_pixels++ = 255;
- }
- }
- }
- g_object_unref (tmp);
- }
- else
+ if (include_border)
{
- screenshot = tmp;
+ XRectangle *rectangles;
+ GdkPixbuf *tmp;
+ int rectangle_count, rectangle_order, i;
+
+ /* we must use XShape to avoid showing what's under the rounder corners
+ * of the WM decoration.
+ */
+
+ rectangles = XShapeGetRectangles (GDK_DISPLAY (),
+ GDK_WINDOW_XWINDOW (window),
+ ShapeBounding,
+ &rectangle_count,
+ &rectangle_order);
+ if (rectangle_count > 0)
+ {
+ gboolean has_alpha = gdk_pixbuf_get_has_alpha (screenshot);
+
+ tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height);
+ gdk_pixbuf_fill (tmp, 0);
+
+ for (i = 0; i < rectangle_count; i++)
+ {
+ gint rec_x, rec_y;
+ gint rec_width, rec_height;
+ gint y;
+
+ rec_x = rectangles[i].x;
+ rec_y = rectangles[i].y;
+ rec_width = rectangles[i].width;
+ rec_height = rectangles[i].height;
+
+ if (x_real_orig < 0)
+ {
+ rec_x += x_real_orig;
+ rec_x = MAX(rec_x, 0);
+ rec_width += x_real_orig;
+ }
+
+ if (y_real_orig < 0)
+ {
+ rec_y += y_real_orig;
+ rec_y = MAX(rec_y, 0);
+ rec_height += y_real_orig;
+ }
+
+ if (x_orig + rec_x + rec_width > gdk_screen_width ())
+ rec_width = gdk_screen_width () - x_orig - rec_x;
+
+ if (y_orig + rec_y + rec_height > gdk_screen_height ())
+ rec_height = gdk_screen_height () - y_orig - rec_y;
+
+ for (y = rec_y; y < rec_y + rec_height; y++)
+ {
+ guchar *src_pixels, *dest_pixels;
+ gint x;
+
+ src_pixels = gdk_pixbuf_get_pixels (screenshot)
+ + y * gdk_pixbuf_get_rowstride(screenshot)
+ + rec_x * (has_alpha ? 4 : 3);
+ dest_pixels = gdk_pixbuf_get_pixels (tmp)
+ + y * gdk_pixbuf_get_rowstride (tmp)
+ + rec_x * 4;
+
+ for (x = 0; x < rec_width; x++)
+ {
+ *dest_pixels++ = *src_pixels++;
+ *dest_pixels++ = *src_pixels++;
+ *dest_pixels++ = *src_pixels++;
+
+ if (has_alpha)
+ *dest_pixels++ = *src_pixels++;
+ else
+ *dest_pixels++ = 255;
+ }
+ }
+ }
+
+ g_object_unref (screenshot);
+ screenshot = tmp;
+ }
}
-#else /* HAVE_X11_EXTENSIONS_SHAPE_H */
- screenshot = gdk_pixbuf_get_from_drawable (NULL, root, NULL,
- x_orig, y_orig, 0, 0,
- width, height);
#endif /* HAVE_X11_EXTENSIONS_SHAPE_H */
if (include_pointer)
{
- XFixesCursorImage *cursor_image;
+ GdkCursor *cursor;
+ GdkPixbuf *cursor_pixbuf;
- cursor_image = XFixesGetCursorImage (GDK_DISPLAY ());
-
- if (cursor_image != NULL)
+ cursor = gdk_cursor_new_for_display (gdk_display_get_default (), GDK_LEFT_PTR);
+ cursor_pixbuf = gdk_cursor_get_image (cursor);
+
+ if (cursor_pixbuf != NULL)
{
GdkRectangle r1, r2;
- int cx, cy, i, j, k;
- int r, g, b, a;
- guchar *pixels, *p;
- int rowstride;
- unsigned long pixel;
+ gint cx, cy;
- cx = cursor_image->x - cursor_image->xhot;
- cy = cursor_image->y - cursor_image->yhot;
+ gdk_window_get_pointer (window, &cx, &cy, NULL);
r1.x = x_real_orig;
r1.y = y_real_orig;
r1.width = real_width;
r1.height = real_height;
+
r2.x = cx;
r2.y = cy;
- r2.width = cursor_image->width;
- r2.height = cursor_image->height;
- if (gdk_rectangle_intersect (&r1, &r2, &r2))
- {
- GdkPixbuf *cursor_pixbuf;
+ r2.width = gdk_pixbuf_get_width (cursor_pixbuf);
+ r2.height = gdk_pixbuf_get_height (cursor_pixbuf);
- cursor_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
- TRUE, 8,
- cursor_image->width,
- cursor_image->height);
- pixels = gdk_pixbuf_get_pixels (cursor_pixbuf);
- rowstride = gdk_pixbuf_get_rowstride (cursor_pixbuf);
- for (i = 0, k = 0; i < cursor_image->height; i++)
- {
- p = pixels + i * rowstride;
- for (j = 0; j < cursor_image->width; j++, k++)
- {
- pixel = cursor_image->pixels[k];
-
- b = pixel & 0xff;
- g = (pixel >> 8) & 0xff;
- r = (pixel >> 16) & 0xff;
- a = (pixel >> 24) & 0xff;
-
- if (a != 0)
- {
- p[0] = r * 255 / a;
- p[1] = g * 255 / a;
- p[2] = b * 255 / a;
- p[3] = a;
- }
- else
- {
- p[0] = p[1] = p[2] = p[3] = 0;
- }
-
- p += 4;
- }
- }
-
+ if (gdk_rectangle_intersect (&r1, &r2, &r2))
+ {
gdk_pixbuf_composite (cursor_pixbuf, screenshot,
r2.x - x_real_orig, r2.y - y_real_orig,
r2.width, r2.height,
@@ -670,11 +454,10 @@
1.0, 1.0,
GDK_INTERP_BILINEAR,
255);
-
- g_object_unref (cursor_pixbuf);
}
- XFree (cursor_image);
+ g_object_unref (cursor_pixbuf);
+ gdk_cursor_unref (cursor);
}
}
@@ -682,29 +465,18 @@
}
gchar *
-screenshot_get_window_title (Window w)
+screenshot_get_window_title (GdkWindow *win)
{
gchar *name;
- w = find_toplevel_window (w);
- w = look_for_hint (w, gdk_x11_get_xatom_by_name ("WM_STATE"));
+ win = gdk_window_get_toplevel (win);
+ win = look_for_hint (win, gdk_x11_xatom_to_atom (gdk_x11_get_xatom_by_name ("WM_STATE")));
- if (w)
- {
- name = get_utf8_property (w, gdk_x11_get_xatom_by_name ("_NET_WM_NAME"));
- if (name)
- return name;
+ name = get_utf8_property (win, gdk_x11_xatom_to_atom (gdk_x11_get_xatom_by_name ("_NET_WM_NAME")));
+ if (name)
+ return name;
- name = get_text_property (w, gdk_x11_get_xatom_by_name ("WM_NAME"));
-
- if (name)
- return name;
-
- name = get_text_property (w, gdk_x11_get_xatom_by_name ("WM_CLASS"));
-
- if (name)
- return name;
- }
+ /* TODO: maybe we should also look at WM_NAME and WM_CLASS? */
return g_strdup (_("Untitled Window"));
}
@@ -736,7 +508,6 @@
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
-
}
void
Modified: trunk/gnome-screenshot/screenshot-utils.h
==============================================================================
--- trunk/gnome-screenshot/screenshot-utils.h (original)
+++ trunk/gnome-screenshot/screenshot-utils.h Mon Aug 25 15:59:57 2008
@@ -27,10 +27,11 @@
gboolean screenshot_grab_lock (void);
void screenshot_release_lock (void);
-gchar *screenshot_get_window_title (Window w);
-Window screenshot_find_current_window (gboolean include_decoration);
-GdkPixbuf *screenshot_get_pixbuf (Window w,
- gboolean include_pointer);
+gchar *screenshot_get_window_title (GdkWindow *win);
+GdkWindow *screenshot_find_current_window (void);
+GdkPixbuf *screenshot_get_pixbuf (GdkWindow *win,
+ gboolean include_pointer,
+ gboolean include_border);
void screenshot_show_error_dialog (GtkWindow *parent,
const gchar *message,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]