gnome-session r4850 - in branches/dbus_based: . gnome-session
- From: mccann svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-session r4850 - in branches/dbus_based: . gnome-session
- Date: Sun, 27 Jul 2008 02:51:16 +0000 (UTC)
Author: mccann
Date: Sun Jul 27 02:51:16 2008
New Revision: 4850
URL: http://svn.gnome.org/viewvc/gnome-session?rev=4850&view=rev
Log:
2008-07-26 William Jon McCann <jmccann redhat com>
* configure.in:
* gnome-session/Makefile.am:
* gnome-session/gsm-inhibit-dialog.c (scale_pixbuf), (get_cmap),
(pixbuf_get_from_pixmap), (get_pixmap_for_window),
(get_pixbuf_for_window), (add_inhibitor), (setup_dialog),
(gsm_inhibit_dialog_constructor):
* gnome-session/test-inhibit.c (do_inhibit_for_window),
(on_widget_show), (main):
Add ability to get a window snapshot of application.
Modified:
branches/dbus_based/ChangeLog
branches/dbus_based/configure.in
branches/dbus_based/gnome-session/Makefile.am
branches/dbus_based/gnome-session/gsm-inhibit-dialog.c
branches/dbus_based/gnome-session/test-inhibit.c
Modified: branches/dbus_based/configure.in
==============================================================================
--- branches/dbus_based/configure.in (original)
+++ branches/dbus_based/configure.in Sun Jul 27 02:51:16 2008
@@ -173,6 +173,19 @@
AC_SUBST(X_LIBS)
dnl ====================================================================
+dnl XRender checks
+dnl ====================================================================
+
+PKG_CHECK_MODULES(XRENDER, xrender, have_xrender=yes, have_xrender=no)
+AM_CONDITIONAL(HAVE_XRENDER, test x$have_xrender = xyes)
+if test $have_xrender=yes; then
+ AC_DEFINE(HAVE_XRENDER, 1, [Have the Render X extension])
+fi
+AC_SUBST(HAVE_XRENDER)
+AC_SUBST(XRENDER_CFLAGS)
+AC_SUBST(XRENDER_LIBS)
+
+dnl ====================================================================
dnl Language Support
dnl ====================================================================
GETTEXT_PACKAGE=gnome-session-2.0
@@ -354,4 +367,5 @@
Maintainer mode: ${USE_MAINTAINER_MODE}
PolicyKit support : ${have_polkit}
+ XComposite support : ${have_xcomposite}
"
Modified: branches/dbus_based/gnome-session/Makefile.am
==============================================================================
--- branches/dbus_based/gnome-session/Makefile.am (original)
+++ branches/dbus_based/gnome-session/Makefile.am Sun Jul 27 02:51:16 2008
@@ -34,6 +34,7 @@
$(NULL)
test_inhibit_LDADD = \
+ $(GNOME_SESSION_LIBS) \
$(DBUS_GLIB_LIBS) \
$(NULL)
Modified: branches/dbus_based/gnome-session/gsm-inhibit-dialog.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-inhibit-dialog.c (original)
+++ branches/dbus_based/gnome-session/gsm-inhibit-dialog.c Sun Jul 27 02:51:16 2008
@@ -29,6 +29,7 @@
#include <glib/gi18n.h>
#include <glib-object.h>
#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
#include <glade/glade-xml.h>
#include <gconf/gconf-client.h>
@@ -37,6 +38,10 @@
#include "eggdesktopfile.h"
#include "util.h"
+#ifdef HAVE_XRENDER
+#include <X11/extensions/Xrender.h>
+#endif
+
#define GSM_INHIBIT_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_INHIBIT_DIALOG, GsmInhibitDialogPrivate))
#define GLADE_XML_FILE "gsm-inhibit-dialog.glade"
@@ -45,6 +50,10 @@
#define DEFAULT_ICON_SIZE 64
#endif
+#ifndef DEFAULT_SNAPSHOT_SIZE
+#define DEFAULT_SNAPSHOT_SIZE 128
+#endif
+
#define DIALOG_RESPONSE_LOCK_SCREEN 1
struct GsmInhibitDialogPrivate
@@ -53,6 +62,9 @@
int action;
GsmInhibitorStore *inhibitors;
GtkListStore *list_store;
+ gboolean have_xrender;
+ int xrender_event_base;
+ int xrender_error_base;
};
enum {
@@ -71,7 +83,7 @@
static void gsm_inhibit_dialog_class_init (GsmInhibitDialogClass *klass);
static void gsm_inhibit_dialog_init (GsmInhibitDialog *inhibit_dialog);
-static void gsm_inhibit_dialog_finalize (GObject *object);
+static void gsm_inhibit_dialog_finalize (GObject *object);
G_DEFINE_TYPE (GsmInhibitDialog, gsm_inhibit_dialog, GTK_TYPE_DIALOG)
@@ -89,7 +101,7 @@
static void
on_response (GsmInhibitDialog *dialog,
- gint response_id)
+ gint response_id)
{
switch (response_id) {
case DIALOG_RESPONSE_LOCK_SCREEN:
@@ -110,8 +122,8 @@
static gboolean
find_inhibitor (GsmInhibitDialog *dialog,
- guint cookie,
- GtkTreeIter *iter)
+ guint cookie,
+ GtkTreeIter *iter)
{
GtkTreeModel *model;
gboolean found_item;
@@ -245,6 +257,210 @@
return retval;
}
+
+static GdkPixbuf *
+scale_pixbuf (GdkPixbuf *pixbuf,
+ int max_width,
+ int max_height,
+ gboolean no_stretch_hint)
+{
+ int pw;
+ int ph;
+ float scale_factor_x = 1.0;
+ float scale_factor_y = 1.0;
+ float scale_factor = 1.0;
+
+ pw = gdk_pixbuf_get_width (pixbuf);
+ ph = gdk_pixbuf_get_height (pixbuf);
+
+ /* Determine which dimension requires the smallest scale. */
+ scale_factor_x = (float) max_width / (float) pw;
+ scale_factor_y = (float) max_height / (float) ph;
+
+ if (scale_factor_x > scale_factor_y) {
+ scale_factor = scale_factor_y;
+ } else {
+ scale_factor = scale_factor_x;
+ }
+
+ /* always scale down, allow to disable scaling up */
+ if (scale_factor < 1.0 || !no_stretch_hint) {
+ int scale_x = (int) (pw * scale_factor);
+ int scale_y = (int) (ph * scale_factor);
+ g_debug ("Scaling to %dx%d", scale_x, scale_y);
+ return gdk_pixbuf_scale_simple (pixbuf,
+ scale_x,
+ scale_y,
+ GDK_INTERP_BILINEAR);
+ } else {
+ return g_object_ref (pixbuf);
+ }
+}
+
+#ifdef HAVE_XRENDER
+
+/* adapted from metacity */
+static GdkColormap*
+get_cmap (GdkPixmap *pixmap)
+{
+ GdkColormap *cmap;
+
+ cmap = gdk_drawable_get_colormap (pixmap);
+ if (cmap) {
+ g_object_ref (G_OBJECT (cmap));
+ }
+
+ if (cmap == NULL) {
+ if (gdk_drawable_get_depth (pixmap) == 1) {
+ g_debug ("Using NULL colormap for snapshotting bitmap\n");
+ cmap = NULL;
+ } else {
+ g_debug ("Using system cmap to snapshot pixmap\n");
+ cmap = gdk_screen_get_system_colormap (gdk_drawable_get_screen (pixmap));
+
+ g_object_ref (G_OBJECT (cmap));
+ }
+ }
+
+ /* Be sure we aren't going to blow up due to visual mismatch */
+ if (cmap &&
+ (gdk_colormap_get_visual (cmap)->depth !=
+ gdk_drawable_get_depth (pixmap))) {
+ cmap = NULL;
+ g_debug ("Switching back to NULL cmap because of depth mismatch\n");
+ }
+
+ return cmap;
+}
+
+static GdkPixbuf *
+pixbuf_get_from_pixmap (Pixmap xpixmap)
+{
+ GdkDrawable *drawable;
+ GdkPixbuf *retval;
+ GdkColormap *cmap;
+ int width;
+ int height;
+
+ retval = NULL;
+ cmap = NULL;
+
+ g_debug ("GsmInhibitDialog: getting foreign pixmap for %u", (guint)xpixmap);
+ drawable = gdk_pixmap_foreign_new (xpixmap);
+ if (GDK_IS_PIXMAP (drawable)) {
+ cmap = get_cmap (drawable);
+ gdk_drawable_get_size (drawable,
+ &width,
+ &height);
+ g_debug ("GsmInhibitDialog: getting pixbuf w=%d h=%d", width, height);
+
+ retval = gdk_pixbuf_get_from_drawable (NULL,
+ drawable,
+ cmap,
+ 0, 0,
+ 0, 0,
+ width, height);
+ }
+ if (cmap) {
+ g_object_unref (G_OBJECT (cmap));
+ }
+ if (drawable) {
+ g_object_unref (G_OBJECT (drawable));
+ }
+
+ return retval;
+}
+
+static Pixmap
+get_pixmap_for_window (Window window)
+{
+ XWindowAttributes attr;
+ XRenderPictureAttributes pa;
+ Pixmap pixmap;
+ XRenderPictFormat *format;
+ Picture src_picture;
+ Picture dst_picture;
+ gboolean has_alpha;
+ int x;
+ int y;
+ int width;
+ int height;
+
+ XGetWindowAttributes (GDK_DISPLAY (), window, &attr);
+
+ format = XRenderFindVisualFormat (GDK_DISPLAY (), attr.visual);
+ has_alpha = (format->type == PictTypeDirect && format->direct.alphaMask);
+ x = attr.x;
+ y = attr.y;
+ width = attr.width;
+ height = attr.height;
+
+ pa.subwindow_mode = IncludeInferiors; /* Don't clip child widgets */
+
+ src_picture = XRenderCreatePicture (GDK_DISPLAY (), window, format, CPSubwindowMode, &pa);
+
+ pixmap = XCreatePixmap (GDK_DISPLAY (),
+ window,
+ width, height,
+ attr.depth);
+
+ dst_picture = XRenderCreatePicture (GDK_DISPLAY (), pixmap, format, 0, 0);
+ XRenderComposite (GDK_DISPLAY (),
+ has_alpha ? PictOpOver : PictOpSrc,
+ src_picture,
+ None,
+ dst_picture,
+ 0, 0, 0, 0,
+ 0, 0,
+ width, height);
+
+
+ return pixmap;
+}
+
+#endif /* HAVE_COMPOSITE */
+
+static GdkPixbuf *
+get_pixbuf_for_window (guint xid,
+ int width,
+ int height)
+{
+ GdkPixbuf *pixbuf = NULL;
+#ifdef HAVE_XRENDER
+ Window xwindow;
+ Pixmap xpixmap;
+
+ xwindow = (Window) xid;
+ xpixmap = get_pixmap_for_window (xwindow);
+ if (xpixmap == None) {
+ g_debug ("GsmInhibitDialog: Unable to get window snapshot for %u", xid);
+ return NULL;
+ } else {
+ g_debug ("GsmInhibitDialog: Got xpixmap %u", (guint)xpixmap);
+ }
+
+ pixbuf = pixbuf_get_from_pixmap (xpixmap);
+
+ if (xpixmap != None) {
+ gdk_error_trap_push ();
+ XFreePixmap (GDK_DISPLAY (), xpixmap);
+ gdk_display_sync (gdk_display_get_default ());
+ gdk_error_trap_pop ();
+ }
+
+ if (pixbuf != NULL) {
+ GdkPixbuf *scaled;
+ g_debug ("GsmInhibitDialog: scaling pixbuf to w=%d h=%d", width, height);
+ scaled = scale_pixbuf (pixbuf, width, height, TRUE);
+ g_object_unref (pixbuf);
+ pixbuf = scaled;
+ }
+#else
+ g_debug ("GsmInhibitDialog: no support for getting window snapshot");
+#endif
+ return pixbuf;
+}
+
static void
add_inhibitor (GsmInhibitDialog *dialog,
GsmInhibitor *inhibitor)
@@ -257,6 +473,7 @@
EggDesktopFile *desktop_file;
GError *error;
char **search_dirs;
+ guint xid;
/* FIXME: get info from xid */
@@ -272,6 +489,15 @@
desktop_filename = g_strdup (app_id);
}
+ xid = gsm_inhibitor_get_toplevel_xid (inhibitor);
+ g_debug ("GsmInhibitDialog: inhibitor has XID %u", xid);
+ if (xid > 0 && dialog->priv->have_xrender) {
+ pixbuf = get_pixbuf_for_window (xid, DEFAULT_SNAPSHOT_SIZE, DEFAULT_SNAPSHOT_SIZE);
+ if (pixbuf == NULL) {
+ g_debug ("GsmInhibitDialog: unable to read pixbuf from %u", xid);
+ }
+ }
+
if (desktop_filename != NULL) {
/* FIXME: maybe also append the autostart dirs ? */
search_dirs = gsm_util_get_app_dirs ();
@@ -301,12 +527,14 @@
name = egg_desktop_file_get_name (desktop_file);
icon_name = egg_desktop_file_get_icon (desktop_file);
- pixbuf = _load_icon (gtk_icon_theme_get_default (),
- icon_name,
- DEFAULT_ICON_SIZE,
- DEFAULT_ICON_SIZE,
- DEFAULT_ICON_SIZE,
- NULL);
+ if (pixbuf == NULL) {
+ pixbuf = _load_icon (gtk_icon_theme_get_default (),
+ icon_name,
+ DEFAULT_ICON_SIZE,
+ DEFAULT_ICON_SIZE,
+ DEFAULT_ICON_SIZE,
+ NULL);
+ }
}
}
@@ -384,9 +612,9 @@
}
static void
-on_store_inhibitor_added (GsmInhibitorStore *store,
- guint cookie,
- GsmInhibitDialog *dialog)
+on_store_inhibitor_added (GsmInhibitorStore *store,
+ guint cookie,
+ GsmInhibitDialog *dialog)
{
GsmInhibitor *inhibitor;
GtkTreeIter iter;
@@ -404,9 +632,9 @@
}
static void
-on_store_inhibitor_removed (GsmInhibitorStore *store,
- guint cookie,
- GsmInhibitDialog *dialog)
+on_store_inhibitor_removed (GsmInhibitorStore *store,
+ guint cookie,
+ GsmInhibitDialog *dialog)
{
GtkTreeIter iter;
@@ -485,9 +713,9 @@
static void
gsm_inhibit_dialog_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
GsmInhibitDialog *dialog = GSM_INHIBIT_DIALOG (object);
@@ -505,11 +733,11 @@
}
static void
-name_cell_data_func (GtkTreeViewColumn *tree_column,
- GtkCellRenderer *cell,
- GtkTreeModel *model,
- GtkTreeIter *iter,
- GsmInhibitDialog *dialog)
+name_cell_data_func (GtkTreeViewColumn *tree_column,
+ GtkCellRenderer *cell,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ GsmInhibitDialog *dialog)
{
char *name;
char *reason;
@@ -536,8 +764,8 @@
}
static gboolean
-add_to_model (guint cookie,
- GsmInhibitor *inhibitor,
+add_to_model (guint cookie,
+ GsmInhibitor *inhibitor,
GsmInhibitDialog *dialog)
{
add_inhibitor (dialog, inhibitor);
@@ -612,9 +840,6 @@
/* IMAGE COLUMN */
renderer = gtk_cell_renderer_pixbuf_new ();
- gtk_cell_renderer_set_fixed_size (renderer,
- DEFAULT_ICON_SIZE,
- DEFAULT_ICON_SIZE);
column = gtk_tree_view_column_new ();
gtk_tree_view_column_pack_start (column, renderer, FALSE);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
@@ -645,8 +870,8 @@
static GObject *
gsm_inhibit_dialog_constructor (GType type,
- guint n_construct_properties,
- GObjectConstructParam *construct_properties)
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
{
GsmInhibitDialog *dialog;
@@ -654,7 +879,21 @@
n_construct_properties,
construct_properties));
+#ifdef HAVE_XRENDER
+ gdk_error_trap_push ();
+ if (XRenderQueryExtension (GDK_DISPLAY (), &dialog->priv->xrender_event_base, &dialog->priv->xrender_error_base)) {
+ g_warning ("GsmInhibitDialog: Initialized XRender extension");
+ dialog->priv->have_xrender = TRUE;
+ } else {
+ g_warning ("GsmInhibitDialog: Unable to initialize XRender extension");
+ dialog->priv->have_xrender = FALSE;
+ }
+ gdk_display_sync (gdk_display_get_default ());
+ gdk_error_trap_pop ();
+#endif /* HAVE_XRENDER */
+
setup_dialog (dialog);
+
gtk_widget_show_all (GTK_WIDGET (dialog));
return G_OBJECT (dialog);
@@ -752,7 +991,7 @@
GtkWidget *
gsm_inhibit_dialog_new (GsmInhibitorStore *inhibitors,
- int action)
+ int action)
{
GObject *object;
Modified: branches/dbus_based/gnome-session/test-inhibit.c
==============================================================================
--- branches/dbus_based/gnome-session/test-inhibit.c (original)
+++ branches/dbus_based/gnome-session/test-inhibit.c Sun Jul 27 02:51:16 2008
@@ -26,7 +26,8 @@
#include <string.h>
#include <unistd.h>
-#include <glib.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
#include <dbus/dbus-glib.h>
#define SM_DBUS_NAME "org.gnome.SessionManager"
@@ -68,7 +69,7 @@
} GsmInhibitFlag;
static gboolean
-do_inhibit (void)
+do_inhibit_for_window (GdkWindow *window)
{
GError *error;
gboolean res;
@@ -86,7 +87,7 @@
app_id = "nautilus";
reason = "A file transfer is in progress.";
#endif
- toplevel_xid = 0;
+ toplevel_xid = GDK_DRAWABLE_XID (window);
flags = GSM_INHIBITOR_FLAG_LOGOUT
| GSM_INHIBITOR_FLAG_SWITCH_USER
| GSM_INHIBITOR_FLAG_SUSPEND;
@@ -147,15 +148,28 @@
return TRUE;
}
+static void
+on_widget_show (GtkWidget *dialog,
+ gpointer data)
+{
+ gboolean res;
+
+ res = do_inhibit_for_window (dialog->window);
+ if (! res) {
+ g_warning ("Unable to register client with session manager");
+ }
+}
+
int
main (int argc,
char *argv[])
{
- gboolean res;
+ gboolean res;
+ GtkWidget *dialog;
g_log_set_always_fatal (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING);
- g_type_init ();
+ gtk_init (&argc, &argv);
res = session_manager_connect ();
if (! res) {
@@ -163,12 +177,19 @@
exit (1);
}
- res = do_inhibit ();
- if (! res) {
- g_warning ("Unable to register client with session manager");
- }
+ g_timeout_add_seconds (30, (GSourceFunc)gtk_main_quit, NULL);
+
+ dialog = gtk_message_dialog_new (NULL,
+ 0,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_CANCEL,
+ "Inhibiting logout, switch user, and suspend.");
+
+ g_signal_connect (dialog, "response", G_CALLBACK (gtk_main_quit), NULL);
+ g_signal_connect (dialog, "show", G_CALLBACK (on_widget_show), NULL);
+ gtk_widget_show (dialog);
- sleep (30);
+ gtk_main ();
do_uninhibit ();
session_manager_disconnect ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]