kov changed libgksu/branches/composited_fadeout/ChangeLog,
libgksu/branches/composited_fadeout/libgksu/libgksu.c
Gustavo Noronha
kov at alioth.debian.org
Tue Feb 20 14:21:49 CET 2007
Mensagem de log:
patch by Paul Betts <betts.62 at osu.edu> modified by myself to enable
composite fadeout when composite is available
-----
Modified: libgksu/branches/composited_fadeout/ChangeLog
===================================================================
--- libgksu/branches/composited_fadeout/ChangeLog 2007-02-20 13:11:52 UTC (rev 778)
+++ libgksu/branches/composited_fadeout/ChangeLog 2007-02-20 13:21:49 UTC (rev 779)
@@ -1,3 +1,10 @@
+2007-02-20 Gustavo Noronha Silva <kov at debian.org>
+
+ * libgksu/libgksu.c:
+ - accepted patch by Paul Betts <betts.62 at osu.edu>
+ with some slight modifications by me to introduce
+ composite fadeout if composite is available
+
2007-02-04 Gustavo Noronha Silva <kov at debian.org>
* Release 2.0.4
Modified: libgksu/branches/composited_fadeout/libgksu/libgksu.c
===================================================================
--- libgksu/branches/composited_fadeout/libgksu/libgksu.c 2007-02-20 13:11:52 UTC (rev 778)
+++ libgksu/branches/composited_fadeout/libgksu/libgksu.c 2007-02-20 13:21:49 UTC (rev 779)
@@ -52,6 +52,9 @@
#include "libgksu.h"
#include "../libgksuui/gksuui-dialog.h"
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
GType
gksu_error_get_type (void)
{
@@ -151,11 +154,58 @@
return FD;
}
+/* code borrowed and slightly modified from GTK+
+ *
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * Erwann Chenede <erwann.chenede at sun.com>
+ *
+ * GTK+ is licensed under the LGPL (see http://svn.gnome.org/viewcvs/gtk%2B/trunk/gdk/x11/gdkscreen-x11.c?revision=15560&view=markup)
+ */
+static GdkAtom
+make_cm_atom (GdkScreen *screen)
+{
+ gchar *name = g_strdup_printf ("_NET_WM_CM_S%d", gdk_screen_get_number(screen));
+ GdkAtom atom = gdk_atom_intern (name, FALSE);
+ g_free (name);
+ return atom;
+}
+
+static gboolean
+check_is_composited (GdkDisplay *display,
+ GdkScreen *screen)
+{
+ Atom xselection = gdk_x11_atom_to_xatom_for_display (display, make_cm_atom(screen));
+ Window xwindow;
+
+ xwindow = XGetSelectionOwner (GDK_DISPLAY_XDISPLAY (display), xselection);
+
+ return xwindow != None;
+}
+/* end of borrowed code */
+
+static gboolean
+is_screen_composited (GdkScreen *screen)
+{
+ static gboolean response_cached = FALSE;
+ static gboolean is_composited = FALSE;
+
+ if (response_cached)
+ return is_composited;
+
+ is_composited = check_is_composited (gdk_screen_get_display(screen), screen);
+ response_cached = TRUE;
+
+ return is_composited;
+}
+
/*
* code 'stolen' from gnome-session's logout.c
*
* Written by Owen Taylor <otaylor at redhat.com>
* Copyright (C) Red Hat
+ *
+ * Composite version by Paul Betts
*/
typedef struct {
GdkScreen *screen;
@@ -168,58 +218,82 @@
guchar *start_p, *end_p, *frame_p;
GTimeVal start_time;
GdkGC *gc;
+ gboolean use_composite;
} FadeoutData;
FadeoutData *fade_data = NULL;
static GList *fadeout_windows = NULL;
-#define FADE_DURATION 500.0
+#define FADE_WAIT 350.0
+#define FADE_DURATION 600.0
int
gsm_screen_get_width (GdkScreen *screen,
- int monitor)
+ int monitor)
{
- GdkRectangle geometry;
+ GdkRectangle geometry;
- gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
-
- return geometry.width;
+ gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
+ return geometry.width;
}
int
gsm_screen_get_height (GdkScreen *screen,
- int monitor)
+ int monitor)
{
- GdkRectangle geometry;
+ GdkRectangle geometry;
- gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
+ gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
- return geometry.height;
+ return geometry.height;
}
int
gsm_screen_get_x (GdkScreen *screen,
int monitor)
{
- GdkRectangle geometry;
+ GdkRectangle geometry;
- gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
+ gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
- return geometry.x;
+ return geometry.x;
}
int
gsm_screen_get_y (GdkScreen *screen,
int monitor)
{
- GdkRectangle geometry;
+ GdkRectangle geometry;
- gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
+ gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
- return geometry.y;
+ return geometry.y;
}
+#define OPAQUE 0xFFFFFFFF
+#define OPACITY_PROP "_NET_WM_WINDOW_OPACITY"
+
static void
+set_window_opacity (GdkWindow* window,
+ double level) /* 0.0 = transparent, 1.0 = opaque */
+{
+ /* FIXME: This is pretty hacky and only works on X; but then again, we
+ * don't have composite in Windows anyways
+ * Code from transset by Matthew Hawn */
+
+ Window win = GDK_DRAWABLE_XID(window);
+ Display* dpy = GDK_DRAWABLE_XDISPLAY(window);
+ unsigned int opacity = (unsigned int)(level * (double)OPAQUE);
+
+ if(opacity == OPAQUE)
+ XDeleteProperty(dpy, win, XInternAtom(dpy, OPACITY_PROP, False));
+ else
+ XChangeProperty(dpy, win, XInternAtom(dpy, OPACITY_PROP, False),
+ XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&opacity, 1L);
+ XSync(dpy, False);
+}
+
+static void
get_current_frame (FadeoutData *fadeout,
double sat)
{
@@ -266,7 +340,7 @@
{
p = pixels + (i * rowstride);
for (j = 0; j < width; j++)
- p [j] >>= 1;
+ p [j] >>= 1; /* Implies 50% darkened */
}
}
@@ -286,34 +360,48 @@
elapsed = G_MAXDOUBLE;
}
- if (elapsed > FADE_DURATION)
+ if (elapsed > FADE_DURATION + FADE_WAIT)
{
- gdk_draw_pixbuf (fadeout->draw_window,
- fadeout->gc,
- fadeout->end_pb,
- 0, 0,
- 0, 0,
- fadeout->area.width,
- fadeout->area.height,
- GDK_RGB_DITHER_NONE,
- 0, 0);
+ if(fadeout->use_composite)
+ set_window_opacity(fadeout->draw_window, 0.75);
+ else {
+ gdk_draw_pixbuf (fadeout->draw_window,
+ fadeout->gc,
+ fadeout->end_pb,
+ 0, 0,
+ 0, 0,
+ fadeout->area.width,
+ fadeout->area.height,
+ GDK_RGB_DITHER_NONE,
+ 0, 0);
+ }
return FALSE;
}
- percent = elapsed / FADE_DURATION;
+ /* We wait some extra time for the window to be created and visible
+ * before we start the fade; otherwise by the time we get a valid
+ * window, it's already done */
+ percent = (elapsed-FADE_WAIT) / FADE_DURATION;
+ percent = (percent < 0.0 ? 0.0 : percent);
- get_current_frame (fadeout, 1.0 - percent);
- gdk_draw_pixbuf (fadeout->draw_window,
- fadeout->gc,
- fadeout->frame,
- 0, 0,
- 0, 0,
- fadeout->area.width,
- fadeout->area.height,
- GDK_RGB_DITHER_NONE,
- 0, 0);
+ if(fadeout->use_composite) {
+ set_window_opacity(fadeout->draw_window, percent / 1.5);
+ }
+ else {
+ get_current_frame (fadeout, 1.0 - percent);
+ gdk_draw_pixbuf (fadeout->draw_window,
+ fadeout->gc,
+ fadeout->frame,
+ 0, 0,
+ 0, 0,
+ fadeout->area.width,
+ fadeout->area.height,
+ GDK_RGB_DITHER_NONE,
+ 0, 0);
+ }
+
gdk_flush ();
return TRUE;
@@ -350,23 +438,33 @@
elapsed = G_MAXDOUBLE;
}
+ /* We don't wait here because the window is already created */
if (elapsed > FADE_DURATION)
{
- gdk_draw_pixbuf (fadeout->draw_window,
- fadeout->gc,
- fadeout->end_pb,
- 0, 0,
- 0, 0,
- fadeout->area.width,
- fadeout->area.height,
- GDK_RGB_DITHER_NONE,
- 0, 0);
+ if(fadeout->use_composite) {
+ set_window_opacity(fadeout->draw_window, 0.0);
- g_object_unref (fadeout->gc);
- g_object_unref (fadeout->start_pb);
- g_object_unref (fadeout->end_pb);
- g_object_unref (fadeout->frame);
+ /* HACK: To avoid the flicker associated with the composite manager
+ * doing fancy effects on a closing window, we resize to very small */
+ gdk_window_resize(fadeout->draw_window, 4, 4);
+ }
+ else {
+ gdk_draw_pixbuf (fadeout->draw_window,
+ fadeout->gc,
+ fadeout->end_pb,
+ 0, 0,
+ 0, 0,
+ fadeout->area.width,
+ fadeout->area.height,
+ GDK_RGB_DITHER_NONE,
+ 0, 0);
+ g_object_unref (fadeout->gc);
+ g_object_unref (fadeout->start_pb);
+ g_object_unref (fadeout->end_pb);
+ g_object_unref (fadeout->frame);
+ }
+
g_free (fadeout);
hide_fadeout_windows ();
@@ -376,16 +474,20 @@
percent = elapsed / FADE_DURATION;
- get_current_frame (fadeout, percent);
- gdk_draw_pixbuf (fadeout->draw_window,
- fadeout->gc,
- fadeout->frame,
- 0, 0,
- 0, 0,
- fadeout->area.width,
- fadeout->area.height,
- GDK_RGB_DITHER_NONE,
- 0, 0);
+ if(fadeout->use_composite)
+ set_window_opacity(fadeout->draw_window, (0.75 - percent/1.5) );
+ else {
+ get_current_frame (fadeout, percent);
+ gdk_draw_pixbuf (fadeout->draw_window,
+ fadeout->gc,
+ fadeout->frame,
+ 0, 0,
+ 0, 0,
+ fadeout->area.width,
+ fadeout->area.height,
+ GDK_RGB_DITHER_NONE,
+ 0, 0);
+ }
gdk_flush ();
@@ -393,30 +495,48 @@
}
static void
-fadeout_screen (GdkScreen *screen,
- int monitor)
+fadeout_screen (GdkScreen *screen, int _)
{
GdkWindowAttr attr;
int attr_mask;
GdkGCValues values;
FadeoutData *fadeout;
+ GdkColor black = {0, 0, 0, 0};
+ GdkColormap* alpha_colormap;
fadeout = g_new (FadeoutData, 1);
fadeout->screen = screen;
- fadeout->monitor = monitor;
- fadeout->area.x = gsm_screen_get_x (screen, monitor);
- fadeout->area.y = gsm_screen_get_y (screen, monitor);
- fadeout->area.width = gsm_screen_get_width (screen, monitor);
- fadeout->area.height = gsm_screen_get_height (screen, monitor);
+ /* This code only dimms out the primary monitor, which doesn't make sense
+ * for gksu on Xinerama setups; I think it works by accident on non-composite
+ fadeout->monitor = monitor;
+ fadeout->area.x = gsm_screen_get_x (screen, monitor);
+ fadeout->area.y = gsm_screen_get_y (screen, monitor);
+ fadeout->area.width = gsm_screen_get_width (screen, monitor);
+ fadeout->area.height = gsm_screen_get_height (screen, monitor);
+ */
+ fadeout->area.x = 0; fadeout->area.y = 0;
+ fadeout->area.width = gdk_screen_get_width (screen);
+ fadeout->area.height = gdk_screen_get_height (screen);
+
+ /* Detect if we can use composite or not */
+ /* FIXME: This doesn't correctly tell if we actually have a composite manager
+ * running or not; this code is pretty hacky too */
+ alpha_colormap = gdk_screen_get_rgba_colormap(screen);
+ fadeout->use_composite = (alpha_colormap != NULL && is_screen_composited (screen));
+ if(fadeout->use_composite) {
+ g_warning("Using composite path...\n");
+ g_object_unref(alpha_colormap);
+ }
+
fadeout->root_window = gdk_screen_get_root_window (screen);
attr.window_type = GDK_WINDOW_CHILD;
attr.x = fadeout->area.x;
attr.y = fadeout->area.y;
- attr.width = fadeout->area.width;
- attr.height = fadeout->area.height;
+ attr.width = 4; /* We initially set these very small */
+ attr.height = 4; /* so that we don't get weird window effects on create */
attr.wclass = GDK_INPUT_OUTPUT;
attr.visual = gdk_screen_get_system_visual (fadeout->screen);
attr.colormap = gdk_screen_get_default_colormap (fadeout->screen);
@@ -426,41 +546,52 @@
fadeout->draw_window = gdk_window_new (fadeout->root_window, &attr, attr_mask);
fadeout_windows = g_list_prepend (fadeout_windows, fadeout->draw_window);
- fadeout->start_pb = gdk_pixbuf_get_from_drawable (NULL,
- fadeout->root_window,
- NULL,
- fadeout->area.x,
- fadeout->area.y,
- 0, 0,
- fadeout->area.width,
- fadeout->area.height);
+ /* No need for this nonsense if we've got native alpha */
+ if(!fadeout->use_composite) {
+ g_warning("Using non-composite path...\n");
+ fadeout->start_pb = gdk_pixbuf_get_from_drawable (NULL,
+ fadeout->root_window,
+ NULL,
+ fadeout->area.x,
+ fadeout->area.y,
+ 0, 0,
+ fadeout->area.width,
+ fadeout->area.height);
- fadeout->end_pb = gdk_pixbuf_copy (fadeout->start_pb);
- darken_pixbuf (fadeout->end_pb);
+ fadeout->end_pb = gdk_pixbuf_copy (fadeout->start_pb);
+ darken_pixbuf (fadeout->end_pb);
- fadeout->frame = gdk_pixbuf_copy (fadeout->start_pb);
- fadeout->rowstride = gdk_pixbuf_get_rowstride (fadeout->start_pb);
+ fadeout->frame = gdk_pixbuf_copy (fadeout->start_pb);
+ fadeout->rowstride = gdk_pixbuf_get_rowstride (fadeout->start_pb);
- fadeout->start_p = gdk_pixbuf_get_pixels (fadeout->start_pb);
- fadeout->end_p = gdk_pixbuf_get_pixels (fadeout->end_pb);
- fadeout->frame_p = gdk_pixbuf_get_pixels (fadeout->frame);
+ fadeout->start_p = gdk_pixbuf_get_pixels (fadeout->start_pb);
+ fadeout->end_p = gdk_pixbuf_get_pixels (fadeout->end_pb);
+ fadeout->frame_p = gdk_pixbuf_get_pixels (fadeout->frame);
- values.subwindow_mode = GDK_INCLUDE_INFERIORS;
+ values.subwindow_mode = GDK_INCLUDE_INFERIORS;
+ fadeout->gc = gdk_gc_new_with_values (fadeout->root_window, &values, GDK_GC_SUBWINDOW);
+ gdk_window_set_back_pixmap (fadeout->draw_window, NULL, FALSE);
+ }
- fadeout->gc = gdk_gc_new_with_values (fadeout->root_window, &values, GDK_GC_SUBWINDOW);
+ gdk_rgb_find_color(gdk_screen_get_default_colormap (fadeout->screen), &black);
+ gdk_window_set_background(fadeout->draw_window, &black);
- gdk_window_set_back_pixmap (fadeout->draw_window, NULL, FALSE);
gdk_window_show (fadeout->draw_window);
- gdk_draw_pixbuf (fadeout->draw_window,
- fadeout->gc,
- fadeout->frame,
- 0, 0,
- 0, 0,
- fadeout->area.width,
- fadeout->area.height,
- GDK_RGB_DITHER_NONE,
- 0, 0);
+ gdk_window_clear(fadeout->draw_window);
+ gdk_window_resize(fadeout->draw_window, fadeout->area.width, fadeout->area.height);
+ if(!alpha_colormap) {
+ gdk_draw_pixbuf (fadeout->draw_window,
+ fadeout->gc,
+ fadeout->frame,
+ 0, 0,
+ 0, 0,
+ fadeout->area.width,
+ fadeout->area.height,
+ GDK_RGB_DITHER_NONE,
+ 0, 0);
+ }
+
g_get_current_time (&fadeout->start_time);
g_idle_add ((GSourceFunc) fadeout_callback, fadeout);
@@ -866,19 +997,19 @@
}
else
{
- if (strcmp(gksu_context_get_user (context), "root") == 0)
- msg = g_strdup_printf (_("<b><big>Enter the administrative password"
- "</big></b>\n\n"
- "The application '%s' lets you "
- "modify essential parts of your "
- "system."),
+ if (strcmp(gksu_context_get_user (context), "root") == 0)
+ msg = g_strdup_printf (_("<b><big>Enter the administrative password"
+ "</big></b>\n\n"
+ "The application '%s' lets you "
+ "modify essential parts of your "
+ "system."),
command);
- else
- msg = g_strdup_printf (_("<b><big>Enter the password of %s to run "
- "the application '%s'"
- "</big></b>"),
+ else
+ msg = g_strdup_printf (_("<b><big>Enter the password of %s to run "
+ "the application '%s'"
+ "</big></b>"),
command, context->user);
- }
+ }
gksuui_dialog_set_message (GKSUUI_DIALOG(dialog), msg);
g_free (msg);
@@ -1339,7 +1470,7 @@
context->sn_context = NULL;
context->sn_id = NULL;
-
+
context->ref_count = 1;
get_configuration_options (context);
@@ -1780,7 +1911,7 @@
{
if (--context->ref_count == 0)
{
- gksu_context_free (context);
+ gksu_context_free (context);
}
}
@@ -1791,7 +1922,7 @@
if (!type_gksu_context)
type_gksu_context = g_boxed_type_register_static
- ("GksuContext",
+ ("GksuContext",
(GBoxedCopyFunc) gksu_context_ref,
(GBoxedFreeFunc) gksu_context_unref);
@@ -2371,7 +2502,7 @@
}
/*
- FIXME: need to set GError in a more detailed way
+ FIXME: need to set GError in a more detailed way
*/
if (!sudo_prepare_xauth (context))
{
@@ -2607,7 +2738,7 @@
fprintf (stderr, "Yeah, we're in...\n");
prompt_grab = gconf_client_get_bool (context->gconf_client, BASE_PATH "prompt",
- NULL);
+ NULL);
if (prompt_grab)
gksu_prompt_grab (context);
More information about the gksu-commits
mailing list