diff -p -up gdm-2.30.3/gui/simple-greeter/branding.c.improve-greeter-transparency gdm-2.30.3/gui/simple-greeter/branding.c --- gdm-2.30.3/gui/simple-greeter/branding.c.improve-greeter-transparency 2010-06-29 15:05:18.000000000 +0200 +++ gdm-2.30.3/gui/simple-greeter/branding.c 2010-06-29 15:05:18.000000000 +0200 @@ -0,0 +1,1508 @@ + +#include <gtk/gtk.h> +#include <gdk/gdkx.h> +#include <X11/Xlib.h> +#include <X11/Xatom.h> + +#include <string.h> +#include <time.h> +#include "branding.h" + + +#define TYPE_BACKGROUND_MONITOR (background_monitor_get_type ()) +#define BACKGROUND_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), \ + TYPE_BACKGROUND_MONITOR, \ + BackgroundMonitor)) +#define BACKGROUND_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), \ + TYPE_BACKGROUND_MONITOR, \ + BackgroundMonitorClass)) +#define IS_BACKGROUND_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), \ + TYPE_BACKGROUND_MONITOR)) +#define IS_BACKGROUND_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), \ + TYPE_BACKGROUND_MONITOR)) +#define BACKGROUND_MONITOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), \ + TYPE_BACKGROUND_MONITOR, \ + BackgroundMonitorClass)) + +typedef struct _BackgroundMonitorClass BackgroundMonitorClass; + +GType background_monitor_get_type (void); + + +static GdkPixbuf * +cairo_rgbdata_to_pixbuf (unsigned char *data, + int width, + int height) +{ + GdkPixbuf *retval; + unsigned char *dstptr; + unsigned char *srcptr; + int align; + + g_assert (width > 0 && height > 0); + + if (!data) + return NULL; + + retval = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height); + if (!retval) + return NULL; + + dstptr = gdk_pixbuf_get_pixels (retval); + srcptr = data; + align = gdk_pixbuf_get_rowstride (retval) - (width * 3); + +#if G_BYTE_ORDER == G_LITTLE_ENDIAN +/* cairo == 00RRGGBB */ +#define CAIRO_RED 2 +#define CAIRO_GREEN 1 +#define CAIRO_BLUE 0 +#else +/* cairo == BBGGRR00 */ +#define CAIRO_RED 1 +#define CAIRO_GREEN 2 +#define CAIRO_BLUE 3 +#endif + + while (height--) { + int x = width; + while (x--) { + /* pixbuf == BBGGRR */ + dstptr[0] = srcptr[CAIRO_RED]; + dstptr[1] = srcptr[CAIRO_GREEN]; + dstptr[2] = srcptr[CAIRO_BLUE]; + + dstptr += 3; + srcptr += 4; + } + + dstptr += align; + } +#undef CAIRO_RED +#undef CAIRO_GREEN +#undef CAIRO_BLUE + + return retval; +} + + + +enum { + CHANGED, + LAST_SIGNAL +}; + +static void background_monitor_changed (BackgroundMonitor *monitor); + +static GdkFilterReturn background_monitor_xevent_filter (GdkXEvent *xevent, + GdkEvent *event, + gpointer data); + +struct _BackgroundMonitorClass { + GObjectClass parent_class; + void (*changed) (BackgroundMonitor *monitor); +}; + +struct _BackgroundMonitor { + GObject parent_instance; + + GdkScreen *screen; + + Window xwindow; + GdkWindow *gdkwindow; + + Atom xatom; + GdkAtom gdkatom; + + GdkPixmap *gdkpixmap; + GdkPixbuf *gdkpixbuf; + + int width; + int height; + + gboolean display_grabbed; +}; + +G_DEFINE_TYPE (BackgroundMonitor, background_monitor, G_TYPE_OBJECT) + +static BackgroundMonitor **global_background_monitors = NULL; + +static guint signals [LAST_SIGNAL] = { 0 }; + +static void +background_monitor_finalize (GObject *object) +{ + BackgroundMonitor *monitor; + + monitor = BACKGROUND_MONITOR (object); + + gdk_window_remove_filter ( + monitor->gdkwindow, background_monitor_xevent_filter, monitor); + g_signal_handlers_disconnect_by_func (monitor->screen, + background_monitor_changed, monitor); + + if (monitor->gdkpixmap) + g_object_unref (monitor->gdkpixmap); + monitor->gdkpixmap = NULL; + + if (monitor->gdkpixbuf) + g_object_unref (monitor->gdkpixbuf); + monitor->gdkpixbuf = NULL; + + G_OBJECT_CLASS (background_monitor_parent_class)->finalize (object); +} + +static void +background_monitor_class_init (BackgroundMonitorClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + signals [CHANGED] = + g_signal_new ("changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (BackgroundMonitorClass, changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + object_class->finalize = background_monitor_finalize; +} + +static void +background_monitor_init (BackgroundMonitor *monitor) +{ + monitor->screen = NULL; + + monitor->gdkwindow = NULL; + monitor->xwindow = None; + + monitor->gdkatom = gdk_atom_intern_static_string ("_XROOTPMAP_ID"); + monitor->xatom = gdk_x11_atom_to_xatom (monitor->gdkatom); + + monitor->gdkpixmap = NULL; + monitor->gdkpixbuf = NULL; + + monitor->display_grabbed = FALSE; +} + +static void +background_monitor_connect_to_screen (BackgroundMonitor *monitor, + GdkScreen *screen) +{ + if (monitor->screen != NULL && monitor->gdkwindow != NULL) { + gdk_window_remove_filter (monitor->gdkwindow, + background_monitor_xevent_filter, + monitor); + } + + monitor->screen = screen; + g_signal_connect_swapped (screen, "size-changed", + G_CALLBACK (background_monitor_changed), monitor); + + monitor->gdkwindow = gdk_screen_get_root_window (screen); + monitor->xwindow = gdk_x11_drawable_get_xid (monitor->gdkwindow); + + gdk_window_add_filter ( + monitor->gdkwindow, background_monitor_xevent_filter, monitor); + + gdk_window_set_events ( + monitor->gdkwindow, + gdk_window_get_events (monitor->gdkwindow) | GDK_PROPERTY_CHANGE_MASK); +} + +static BackgroundMonitor * +background_monitor_new (GdkScreen *screen) +{ + BackgroundMonitor *monitor; + + monitor = g_object_new (TYPE_BACKGROUND_MONITOR, NULL); + + background_monitor_connect_to_screen (monitor, screen); + + return monitor; +} + +static BackgroundMonitor * +background_monitor_get_for_screen (GdkScreen *screen) +{ + int screen_number; + + screen_number = gdk_screen_get_number (screen); + + if (!global_background_monitors) { + int n_screens; + + n_screens = gdk_display_get_n_screens (gdk_display_get_default ()); + + global_background_monitors = g_new0 (BackgroundMonitor *, n_screens); + } + + if (!global_background_monitors [screen_number]) { + global_background_monitors [screen_number] = + background_monitor_new (screen); + + g_object_add_weak_pointer ( + G_OBJECT (global_background_monitors [screen_number]), + (void **) &global_background_monitors [screen_number]); + + return global_background_monitors [screen_number]; + } + + return g_object_ref (global_background_monitors [screen_number]); +} + +static void +background_monitor_changed (BackgroundMonitor *monitor) +{ + if (monitor->gdkpixmap) + g_object_unref (monitor->gdkpixmap); + monitor->gdkpixmap = NULL; + + if (monitor->gdkpixbuf) + g_object_unref (monitor->gdkpixbuf); + monitor->gdkpixbuf = NULL; + + g_signal_emit (monitor, signals [CHANGED], 0); +} + +static GdkFilterReturn +background_monitor_xevent_filter (GdkXEvent *xevent, + GdkEvent *event, + gpointer data) +{ + BackgroundMonitor *monitor; + XEvent *xev; + + g_return_val_if_fail (IS_BACKGROUND_MONITOR (data), GDK_FILTER_CONTINUE); + + monitor = BACKGROUND_MONITOR (data); + xev = (XEvent *) xevent; + + if (xev->type == PropertyNotify && + xev->xproperty.atom == monitor->xatom && + xev->xproperty.window == monitor->xwindow) + background_monitor_changed (monitor); + + return GDK_FILTER_CONTINUE; +} + +static void +background_monitor_setup_pixmap (BackgroundMonitor *monitor) +{ + Pixmap *prop_data = NULL; + GdkAtom prop_type; + + g_assert (monitor->display_grabbed); + + if (!gdk_property_get ( + monitor->gdkwindow, monitor->gdkatom, + gdk_x11_xatom_to_atom (XA_PIXMAP), 0, 10, + FALSE, &prop_type, NULL, NULL, (gpointer) &prop_data)) + return; + + if ((prop_type == GDK_TARGET_PIXMAP) && prop_data && prop_data [0]) { + GdkDisplay *display; + + g_assert (monitor->gdkpixmap == NULL); + + display = gdk_screen_get_display (monitor->screen); + + monitor->gdkpixmap = gdk_pixmap_foreign_new_for_display (display, + prop_data [0]); + + if (!monitor->gdkpixmap) + g_warning ("couldn't get background pixmap\n"); + } + + g_free (prop_data); +} + +static GdkPixbuf * +background_monitor_tile_background (BackgroundMonitor *monitor, + int width, + int height) +{ + GdkPixbuf *retval; + int tilewidth, tileheight; + + retval = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height); + + tilewidth = gdk_pixbuf_get_width (monitor->gdkpixbuf); + tileheight = gdk_pixbuf_get_height (monitor->gdkpixbuf); + + if (tilewidth == 1 && tileheight == 1) { + guchar *pixels; + int n_channels; + guint32 pixel = 0; + + n_channels = gdk_pixbuf_get_n_channels (monitor->gdkpixbuf); + pixels = gdk_pixbuf_get_pixels (monitor->gdkpixbuf); + + if (pixels) { + if (n_channels == 4) + pixel = ((guint32 *) pixels) [0]; + else if (n_channels == 3) + pixel = pixels [0] << 24 | pixels [1] << 16 | pixels [2] << 8; + } + + gdk_pixbuf_fill (retval, pixel); + } else { + unsigned char *data; + cairo_t *cr; + cairo_surface_t *surface; + cairo_pattern_t *pattern; + + data = g_malloc (width * height * 4); + if (!data) + return NULL; + + surface = cairo_image_surface_create_for_data (data, + CAIRO_FORMAT_RGB24, + width, height, + width * 4); + cr = cairo_create (surface); + cairo_set_source_rgb (cr, 1, 1, 1); + cairo_paint (cr); + + gdk_cairo_set_source_pixbuf (cr, monitor->gdkpixbuf, 0, 0); + pattern = cairo_get_source (cr); + cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); + cairo_rectangle (cr, 0, 0, width, height); + cairo_fill (cr); + + cairo_destroy (cr); + cairo_surface_destroy (surface); + + retval = cairo_rgbdata_to_pixbuf (data, width, height); + + g_free (data); + } + + return retval; +} + +static void +background_monitor_setup_pixbuf (BackgroundMonitor *monitor) +{ + GdkColormap *colormap = NULL; + GdkDisplay *display; + int rwidth, rheight; + int pwidth, pheight; + + display = gdk_screen_get_display (monitor->screen); + + gdk_x11_display_grab (display); + monitor->display_grabbed = TRUE; + + if (!monitor->gdkpixmap) + background_monitor_setup_pixmap (monitor); + + if (!monitor->gdkpixmap) { + gdk_x11_display_ungrab (display); + monitor->display_grabbed = FALSE; + return; + } + + gdk_drawable_get_size ( + GDK_DRAWABLE (monitor->gdkpixmap), &pwidth, &pheight); + + gdk_window_get_geometry (monitor->gdkwindow, + NULL, NULL, &rwidth, &rheight, NULL); + + monitor->width = MIN (pwidth, rwidth); + monitor->height = MIN (pheight, rheight); + + colormap = gdk_drawable_get_colormap (monitor->gdkwindow); + + g_assert (monitor->gdkpixbuf == NULL); + monitor->gdkpixbuf = gdk_pixbuf_get_from_drawable ( + NULL, monitor->gdkpixmap, colormap, + 0, 0, 0, 0, + monitor->width, monitor->height); + + gdk_x11_display_ungrab (display); + monitor->display_grabbed = FALSE; + + if (monitor->gdkpixbuf == NULL) + return; + + if ((monitor->width < rwidth || monitor->height < rheight)) { + GdkPixbuf *tiled; + + tiled = background_monitor_tile_background ( + monitor, rwidth, rheight); + g_object_unref (monitor->gdkpixbuf); + monitor->gdkpixbuf = tiled; + + monitor->width = rwidth; + monitor->height = rheight; + } +} + +static GdkPixbuf * +background_monitor_get_region (BackgroundMonitor *monitor, + int x, + int y, + int width, + int height) +{ + GdkPixbuf *pixbuf, *tmpbuf; + int subwidth, subheight; + int subx, suby; + + if (!monitor->gdkpixbuf) + background_monitor_setup_pixbuf (monitor); + + if (!monitor->gdkpixbuf) + return NULL; + + subwidth = MIN (width, monitor->width - x); + subheight = MIN (height, monitor->height - y); + /* if x or y are negative numbers */ + subwidth = MIN (subwidth, width + x); + subheight = MIN (subheight, height + y); + + subx = MAX (x, 0); + suby = MAX (y, 0); + + if ((subwidth <= 0) || (subheight <= 0) || + (monitor->width-x < 0) || (monitor->height-y < 0) ) + /* region is completely offscreen */ + return gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, + width, height); + + pixbuf = gdk_pixbuf_new_subpixbuf ( + monitor->gdkpixbuf, subx, suby, subwidth, subheight); + + if ((subwidth < width) || (subheight < height)) { + tmpbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, + width, height); + gdk_pixbuf_copy_area (pixbuf, 0, 0, subwidth, subheight, + tmpbuf, (x < 0) ? -x : 0, (y < 0) ? -y : 0); + g_object_unref (pixbuf); + pixbuf = tmpbuf; + } + + return pixbuf; +} + + +typedef struct +{ + GdkPixbuf *pixbuf; + GSList *scaled; + gboolean stretch; + gint border_left; + gint border_right; + gint border_bottom; + gint border_top; + guint hints[3][3]; +} ConstraintScale; +typedef enum +{ + COMPONENT_NORTH_WEST = 1 << 0, + COMPONENT_NORTH = 1 << 1, + COMPONENT_NORTH_EAST = 1 << 2, + COMPONENT_WEST = 1 << 3, + COMPONENT_CENTER = 1 << 4, + COMPONENT_EAST = 1 << 5, + COMPONENT_SOUTH_EAST = 1 << 6, + COMPONENT_SOUTH = 1 << 7, + COMPONENT_SOUTH_WEST = 1 << 8, + COMPONENT_ALL = 1 << 9 +} ConstraintScaleComponent; + +typedef enum { + THEME_CONSTANT_ROWS = 1 << 0, + THEME_CONSTANT_COLS = 1 << 1, + THEME_MISSING = 1 << 2 +} ThemeRenderHints; + + + +static GdkPixbuf * +bilinear_gradient (GdkPixbuf *src, + gint src_x, + gint src_y, + gint width, + gint height) +{ + guint n_channels = gdk_pixbuf_get_n_channels (src); + guint src_rowstride = gdk_pixbuf_get_rowstride (src); + guchar *src_pixels = gdk_pixbuf_get_pixels (src); + guchar *p1, *p2, *p3, *p4; + guint dest_rowstride; + guchar *dest_pixels; + GdkPixbuf *result; + int i, j, k; + + p1 = src_pixels + (src_y - 1) * src_rowstride + (src_x - 1) * n_channels; + p2 = p1 + n_channels; + p3 = src_pixels + src_y * src_rowstride + (src_x - 1) * n_channels; + p4 = p3 + n_channels; + + result = gdk_pixbuf_new (GDK_COLORSPACE_RGB, n_channels == 4, 8, + width, height); + dest_rowstride = gdk_pixbuf_get_rowstride (result); + dest_pixels = gdk_pixbuf_get_pixels (result); + + for (i = 0; i < height; i++) + { + guchar *p = dest_pixels + dest_rowstride *i; + guint v[4]; + gint dv[4]; + + for (k = 0; k < n_channels; k++) + { + guint start = ((height - i) * p1[k] + (1 + i) * p3[k]) / (height + 1); + guint end = ((height - i) * p2[k] + (1 + i) * p4[k]) / (height + 1); + + dv[k] = (((gint)end - (gint)start) << 16) / (width + 1); + v[k] = (start << 16) + dv[k] + 0x8000; + } + + for (j = width; j; j--) + { + for (k = 0; k < n_channels; k++) + { + *(p++) = v[k] >> 16; + v[k] += dv[k]; + } + } + } + + return result; +} + +static GdkPixbuf * +horizontal_gradient (GdkPixbuf *src, + gint src_x, + gint src_y, + gint width, + gint height) +{ + guint n_channels = gdk_pixbuf_get_n_channels (src); + guint src_rowstride = gdk_pixbuf_get_rowstride (src); + guchar *src_pixels = gdk_pixbuf_get_pixels (src); + guint dest_rowstride; + guchar *dest_pixels; + GdkPixbuf *result; + int i, j, k; + + result = gdk_pixbuf_new (GDK_COLORSPACE_RGB, n_channels == 4, 8, + width, height); + dest_rowstride = gdk_pixbuf_get_rowstride (result); + dest_pixels = gdk_pixbuf_get_pixels (result); + + for (i = 0; i < height; i++) + { + guchar *p = dest_pixels + dest_rowstride *i; + guchar *p1 = src_pixels + (src_y + i) * src_rowstride + (src_x - 1) * n_channels; + guchar *p2 = p1 + n_channels; + + guint v[4]; + gint dv[4]; + + for (k = 0; k < n_channels; k++) + { + dv[k] = (((gint)p2[k] - (gint)p1[k]) << 16) / (width + 1); + v[k] = (p1[k] << 16) + dv[k] + 0x8000; + } + + for (j = width; j; j--) + { + for (k = 0; k < n_channels; k++) + { + *(p++) = v[k] >> 16; + v[k] += dv[k]; + } + } + } + + return result; +} + +static GdkPixbuf * +vertical_gradient (GdkPixbuf *src, + gint src_x, + gint src_y, + gint width, + gint height) +{ + guint n_channels = gdk_pixbuf_get_n_channels (src); + guint src_rowstride = gdk_pixbuf_get_rowstride (src); + guchar *src_pixels = gdk_pixbuf_get_pixels (src); + guchar *top_pixels, *bottom_pixels; + guint dest_rowstride; + guchar *dest_pixels; + GdkPixbuf *result; + int i, j; + + top_pixels = src_pixels + (src_y - 1) * src_rowstride + (src_x) * n_channels; + bottom_pixels = top_pixels + src_rowstride; + + result = gdk_pixbuf_new (GDK_COLORSPACE_RGB, n_channels == 4, 8, + width, height); + dest_rowstride = gdk_pixbuf_get_rowstride (result); + dest_pixels = gdk_pixbuf_get_pixels (result); + + for (i = 0; i < height; i++) + { + guchar *p = dest_pixels + dest_rowstride *i; + guchar *p1 = top_pixels; + guchar *p2 = bottom_pixels; + + for (j = width * n_channels; j; j--) + *(p++) = ((height - i) * *(p1++) + (1 + i) * *(p2++)) / (height + 1); + } + + return result; +} + +static GdkPixbuf * +replicate_single (GdkPixbuf *src, + gint src_x, + gint src_y, + gint width, + gint height) +{ + guint n_channels = gdk_pixbuf_get_n_channels (src); + guchar *pixels = (gdk_pixbuf_get_pixels (src) + + src_y * gdk_pixbuf_get_rowstride (src) + + src_x * n_channels); + guchar r = *(pixels++); + guchar g = *(pixels++); + guchar b = *(pixels++); + guint dest_rowstride; + guchar *dest_pixels; + guchar a = 0; + GdkPixbuf *result; + int i, j; + + if (n_channels == 4) + a = *(pixels++); + + result = gdk_pixbuf_new (GDK_COLORSPACE_RGB, n_channels == 4, 8, + width, height); + dest_rowstride = gdk_pixbuf_get_rowstride (result); + dest_pixels = gdk_pixbuf_get_pixels (result); + + for (i = 0; i < height; i++) + { + guchar *p = dest_pixels + dest_rowstride *i; + + for (j = 0; j < width; j++) + { + *(p++) = r; + *(p++) = g; + *(p++) = b; + + if (n_channels == 4) + *(p++) = a; + } + } + + return result; +} + +static GdkPixbuf * +replicate_rows (GdkPixbuf *src, + gint src_x, + gint src_y, + gint width, + gint height) +{ + guint n_channels = gdk_pixbuf_get_n_channels (src); + guint src_rowstride = gdk_pixbuf_get_rowstride (src); + guchar *pixels = (gdk_pixbuf_get_pixels (src) + src_y * src_rowstride + src_x * n_channels); + guchar *dest_pixels; + GdkPixbuf *result; + guint dest_rowstride; + int i; + + result = gdk_pixbuf_new (GDK_COLORSPACE_RGB, n_channels == 4, 8, + width, height); + dest_rowstride = gdk_pixbuf_get_rowstride (result); + dest_pixels = gdk_pixbuf_get_pixels (result); + + for (i = 0; i < height; i++) + memcpy (dest_pixels + dest_rowstride * i, pixels, n_channels * width); + + return result; +} + +static GdkPixbuf * +replicate_cols (GdkPixbuf *src, + gint src_x, + gint src_y, + gint width, + gint height) +{ + guint n_channels = gdk_pixbuf_get_n_channels (src); + guint src_rowstride = gdk_pixbuf_get_rowstride (src); + guchar *pixels = (gdk_pixbuf_get_pixels (src) + src_y * src_rowstride + src_x * n_channels); + guchar *dest_pixels; + GdkPixbuf *result; + guint dest_rowstride; + int i, j; + + result = gdk_pixbuf_new (GDK_COLORSPACE_RGB, n_channels == 4, 8, + width, height); + dest_rowstride = gdk_pixbuf_get_rowstride (result); + dest_pixels = gdk_pixbuf_get_pixels (result); + + for (i = 0; i < height; i++) + { + guchar *p = dest_pixels + dest_rowstride * i; + guchar *q = pixels + src_rowstride * i; + + guchar r = *(q++); + guchar g = *(q++); + guchar b = *(q++); + guchar a = 0; + + if (n_channels == 4) + a = *(q++); + + for (j = 0; j < width; j++) + { + *(p++) = r; + *(p++) = g; + *(p++) = b; + + if (n_channels == 4) + *(p++) = a; + } + } + + return result; +} + +/* Scale the rectangle (src_x, src_y, src_width, src_height) + * onto the rectangle (dest_x, dest_y, dest_width, dest_height) + * of the destination, and render into a pixbuf + */ + +static void +cs_render (GdkPixbuf *src, + guint hints, + GdkPixbuf *scaled, + gint src_x, + gint src_y, + gint src_width, + gint src_height, + gint dest_x, + gint dest_y, + gint dest_width, + gint dest_height) +{ + GdkPixbuf *tmp_pixbuf; + GdkRectangle rect; + int x_offset, y_offset; + gboolean has_alpha = gdk_pixbuf_get_has_alpha (src); + gint src_rowstride = gdk_pixbuf_get_rowstride (src); + gint src_n_channels = gdk_pixbuf_get_n_channels (src); + + if (dest_width <= 0 || dest_height <= 0) + return; + + rect.x = dest_x; + rect.y = dest_y; + rect.width = dest_width; + rect.height = dest_height; + + if (hints & THEME_MISSING) + return; + + if (dest_width == src_width && dest_height == src_height) + { + tmp_pixbuf = g_object_ref (src); + + x_offset = src_x + rect.x - dest_x; + y_offset = src_y + rect.y - dest_y; + } + else if (src_width == 0 && src_height == 0) + { + tmp_pixbuf = bilinear_gradient (src, src_x, src_y, dest_width, dest_height); + + x_offset = rect.x - dest_x; + y_offset = rect.y - dest_y; + } + else if (src_width == 0 && dest_height == src_height) + { + tmp_pixbuf = horizontal_gradient (src, src_x, src_y, dest_width, dest_height); + + x_offset = rect.x - dest_x; + y_offset = rect.y - dest_y; + } + else if (src_height == 0 && dest_width == src_width) + { + tmp_pixbuf = vertical_gradient (src, src_x, src_y, dest_width, dest_height); + + x_offset = rect.x - dest_x; + y_offset = rect.y - dest_y; + } + else if ((hints & THEME_CONSTANT_COLS) && (hints & THEME_CONSTANT_ROWS)) + { + tmp_pixbuf = replicate_single (src, src_x, src_y, dest_width, dest_height); + + x_offset = rect.x - dest_x; + y_offset = rect.y - dest_y; + } + else if (dest_width == src_width && (hints & THEME_CONSTANT_COLS)) + { + tmp_pixbuf = replicate_rows (src, src_x, src_y, dest_width, dest_height); + + x_offset = rect.x - dest_x; + y_offset = rect.y - dest_y; + } + else if (dest_height == src_height && (hints & THEME_CONSTANT_ROWS)) + { + tmp_pixbuf = replicate_cols (src, src_x, src_y, dest_width, dest_height); + + x_offset = rect.x - dest_x; + y_offset = rect.y - dest_y; + } + else + { + double x_scale = (double)dest_width / src_width; + double y_scale = (double)dest_height / src_height; + guchar *pixels; + GdkPixbuf *partial_src; + + pixels = (gdk_pixbuf_get_pixels (src) + + src_y * src_rowstride + + src_x * src_n_channels); + + partial_src = gdk_pixbuf_new_from_data (pixels, GDK_COLORSPACE_RGB, + has_alpha, + 8, src_width, src_height, + src_rowstride, + NULL, NULL); + + tmp_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, + has_alpha, 8, + rect.width, rect.height); + + gdk_pixbuf_scale (partial_src, tmp_pixbuf, + 0, 0, rect.width, rect.height, + dest_x - rect.x, dest_y - rect.y, + x_scale, y_scale, + GDK_INTERP_BILINEAR); + + gdk_pixbuf_unref (partial_src); + + x_offset = 0; + y_offset = 0; + } + + if (rect.x >= 0 && rect.x + rect.width <= gdk_pixbuf_get_width (scaled) && + rect.y >= 0 && rect.y + rect.height <= gdk_pixbuf_get_height (scaled)) + { + gdk_pixbuf_copy_area (tmp_pixbuf, + x_offset, y_offset, + rect.width, rect.height, + scaled, + rect.x, + rect.y); + } + gdk_pixbuf_unref (tmp_pixbuf); +} + +static guint +compute_hint (GdkPixbuf *pixbuf, + gint x0, + gint x1, + gint y0, + gint y1) +{ + int i, j; + int hints = THEME_CONSTANT_ROWS | THEME_CONSTANT_COLS | THEME_MISSING; + int n_channels = gdk_pixbuf_get_n_channels (pixbuf); + + guchar *data = gdk_pixbuf_get_pixels (pixbuf); + int rowstride = gdk_pixbuf_get_rowstride (pixbuf); + + if (x0 == x1 || y0 == y1) + return 0; + + for (i = y0; i < y1; i++) + { + guchar *p = data + i * rowstride + x0 * n_channels; + guchar r = p[0]; + guchar g = p[1]; + guchar b = p[2]; + guchar a = 0; + + if (n_channels == 4) + a = p[3]; + + for (j = x0; j < x1 ; j++) + { + if (n_channels != 4 || p[3] != 0) + { + hints &= ~THEME_MISSING; + if (!(hints & THEME_CONSTANT_ROWS)) + goto cols; + } + + if (r != *(p++) || + g != *(p++) || + b != *(p++) || + (n_channels != 4 && a != *(p++))) + { + hints &= ~THEME_CONSTANT_ROWS; + if (!(hints & THEME_MISSING)) + goto cols; + } + } + } + + cols: + for (i = y0 + 1; i < y1; i++) + { + guchar *base = data + y0 * rowstride + x0 * n_channels; + guchar *p = data + i * rowstride + x0 * n_channels; + + if (memcmp (p, base, n_channels * (x1 - x0)) != 0) + { + hints &= ~THEME_CONSTANT_COLS; + return hints; + } + } + + return hints; +} + +static void +constraint_scale_compute_hints (ConstraintScale *cs_pb) +{ + int i, j; + gint width = gdk_pixbuf_get_width (cs_pb->pixbuf); + gint height = gdk_pixbuf_get_height (cs_pb->pixbuf); + + if (cs_pb->border_left + cs_pb->border_right > width || + cs_pb->border_top + cs_pb->border_bottom > height) + { + g_warning ("Invalid borders specified"); + if (cs_pb->border_left + cs_pb->border_right > width) + { + cs_pb->border_left = width / 2; + cs_pb->border_right = (width + 1) / 2; + } + if (cs_pb->border_bottom + cs_pb->border_top > height) + { + cs_pb->border_top = height / 2; + cs_pb->border_bottom = (height + 1) / 2; + } + } + + for (i = 0; i < 3; i++) + { + gint y0, y1; + + switch (i) + { + case 0: + y0 = 0; + y1 = cs_pb->border_top; + break; + case 1: + y0 = cs_pb->border_top; + y1 = height - cs_pb->border_bottom; + break; + default: + y0 = height - cs_pb->border_bottom; + y1 = height; + break; + } + + for (j = 0; j < 3; j++) + { + gint x0, x1; + + switch (j) + { + case 0: + x0 = 0; + x1 = cs_pb->border_left; + break; + case 1: + x0 = cs_pb->border_left; + x1 = width - cs_pb->border_right; + break; + default: + x0 = width - cs_pb->border_right; + x1 = width; + break; + } + + cs_pb->hints[i][j] = compute_hint (cs_pb->pixbuf, x0, x1, y0, y1); + } + } + +} + +static GdkPixbuf * +constraint_scale (GdkPixbuf *pixbuf, + /*gint x, + gint y,*/ + gint width, + gint height, + gint border_left, + gint border_right, + gint border_bottom, + gint border_top) +{ + gint src_x[4], src_y[4], dest_x[4], dest_y[4]; + gint pixbuf_width = gdk_pixbuf_get_width (pixbuf); + gint pixbuf_height = gdk_pixbuf_get_height (pixbuf); + ConstraintScale *cs_pb = g_new0 (ConstraintScale, 1); + guint component_mask = COMPONENT_ALL; + + cs_pb->pixbuf = pixbuf; + cs_pb->stretch = TRUE; + cs_pb->border_left = border_left; + cs_pb->border_right = border_right; + cs_pb->border_bottom = border_bottom; + cs_pb->border_top = border_top; + constraint_scale_compute_hints (cs_pb); + + if (cs_pb->stretch) + { + GdkPixbuf *scaled = NULL; + + if (!scaled) + { + scaled = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (cs_pb->pixbuf), + gdk_pixbuf_get_has_alpha (cs_pb->pixbuf), + gdk_pixbuf_get_bits_per_sample (cs_pb->pixbuf), + width, + height); + + gdk_pixbuf_fill (scaled, 0x00000000); + + + src_x[0] = 0; + src_x[1] = cs_pb->border_left; + src_x[2] = pixbuf_width - cs_pb->border_right; + src_x[3] = pixbuf_width; + + src_y[0] = 0; + src_y[1] = cs_pb->border_top; + src_y[2] = pixbuf_height - cs_pb->border_bottom; + src_y[3] = pixbuf_height; + + dest_x[0] = 0; + dest_x[1] = cs_pb->border_left; + dest_x[2] = width - cs_pb->border_right; + dest_x[3] = width; + + dest_y[0] = 0; + dest_y[1] = cs_pb->border_top; + dest_y[2] = height - cs_pb->border_bottom; + dest_y[3] = height; + + + if (component_mask & COMPONENT_ALL) + component_mask = (COMPONENT_ALL - 1) & ~component_mask; + +#define RENDER_COMPONENT(X1,X2,Y1,Y2) \ + cs_render (pixbuf, cs_pb->hints[Y1][X1], \ + scaled, \ + src_x[X1], src_y[Y1], \ + src_x[X2] - src_x[X1], src_y[Y2] - src_y[Y1], \ + dest_x[X1], dest_y[Y1], \ + dest_x[X2] - dest_x[X1], dest_y[Y2] - dest_y[Y1]); + + if (component_mask & COMPONENT_NORTH_WEST) + RENDER_COMPONENT (0, 1, 0, 1); + + if (component_mask & COMPONENT_NORTH) + RENDER_COMPONENT (1, 2, 0, 1); + + if (component_mask & COMPONENT_NORTH_EAST) + RENDER_COMPONENT (2, 3, 0, 1); + + if (component_mask & COMPONENT_WEST) + RENDER_COMPONENT (0, 1, 1, 2); + + if (component_mask & COMPONENT_CENTER) + RENDER_COMPONENT (1, 2, 1, 2); + + if (component_mask & COMPONENT_EAST) + RENDER_COMPONENT (2, 3, 1, 2); + + if (component_mask & COMPONENT_SOUTH_WEST) + RENDER_COMPONENT (0, 1, 2, 3); + + if (component_mask & COMPONENT_SOUTH) + RENDER_COMPONENT (1, 2, 2, 3); + + if (component_mask & COMPONENT_SOUTH_EAST) + RENDER_COMPONENT (2, 3, 2, 3); + } + + return scaled; + } + return NULL; +} + +static GdkPixbuf * +composite_image_onto_desktop (GdmWidgetBackground *background); + + +static void +free_prepared_resources (GdmWidgetBackground *background) +{ + background->prepared = FALSE; + + if (background->pixmap) + g_object_unref (background->pixmap); + background->pixmap = NULL; +} + +static void +free_composited_resources (GdmWidgetBackground *background) +{ + + free_prepared_resources (background); + + background->composited = FALSE; + + if (background->composited_image) + g_object_unref (background->composited_image); + background->composited_image = NULL; +} + +static void +load_background_file (GdmWidgetBackground *background) +{ + GError *error = NULL; + + if (!g_file_test (background->image, G_FILE_TEST_IS_REGULAR)) + return; + + background->loaded_image = + gdk_pixbuf_new_from_file (background->image, &error); + if (!background->loaded_image) { + g_assert (error != NULL); + g_warning (G_STRLOC ": unable to open '%s': %s", + background->image, error->message); + g_error_free (error); + } + +} + +static void +set_pixbuf_background (GdmWidgetBackground *background) +{ + g_assert (background->composited_image != NULL); + GtkStyle *style; + + gdk_pixbuf_render_pixmap_and_mask_for_colormap ( + background->composited_image, + background->colormap, + &background->pixmap, NULL, 128); + + gdk_window_set_back_pixmap ( + background->window, background->pixmap, FALSE); + + style = gtk_style_copy (background->widget->style); + if (style->bg_pixmap[GTK_STATE_NORMAL]) + g_object_unref (style->bg_pixmap[GTK_STATE_NORMAL]); + style->bg_pixmap[GTK_STATE_NORMAL] = g_object_ref (background->pixmap); + gtk_widget_set_style (background->widget, style); + g_object_unref (style); +} + +static GdkPixbuf * +get_scaled_pixbuf (GdmWidgetBackground *background) +{ + GdkPixbuf *scaled; + int orig_width, orig_height; + int widget_width, widget_height; + + load_background_file (background); + if (!background->loaded_image) + return NULL; + + orig_width = gdk_pixbuf_get_width (background->loaded_image); + orig_height = gdk_pixbuf_get_height (background->loaded_image); + + widget_width = background->region.width; + widget_height = background->region.height; + + + if (widget_width == orig_width && + widget_height == orig_height) { + scaled = background->loaded_image; + g_object_ref (scaled); + } else { + scaled = constraint_scale (background->loaded_image, + widget_width, widget_height, + background->border_left, background->border_right, + background->border_top, background->border_bottom); + } + + + + return scaled; +} + + +static gboolean +background_prepare (GdmWidgetBackground *background) { + if (!background->colormap || !background->transformed) + return FALSE; + free_prepared_resources (background); + + set_pixbuf_background (background); + + background->prepared = TRUE; + +// background->notify_changed (background, background->user_data); + + return TRUE; +} + +static void +free_transformed_resources (GdmWidgetBackground *background) +{ + free_composited_resources (background); + + background->transformed = FALSE; + + + if (background->transformed_image) + g_object_unref (background->transformed_image); + background->transformed_image = NULL; +} + +static gboolean +background_composite (GdmWidgetBackground *background) +{ + free_composited_resources (background); + + if (background->transformed_image) { + background->composited_image = + composite_image_onto_desktop (background); + } + background->composited = TRUE; + + background_prepare (background); + + return TRUE; +} + +static gboolean +background_transform (GdmWidgetBackground *background) +{ + if (background->region.width == -1) + return FALSE; + + free_transformed_resources (background); + + background->transformed_image = + get_scaled_pixbuf (background); + + background->transformed = TRUE; + + background_composite (background); + + return TRUE; +} + + + +static void +background_changed (BackgroundMonitor *monitor, + GdmWidgetBackground *background) +{ + GdkPixbuf *tmp; + tmp = background->desktop; + background->desktop = background_monitor_get_region ( + background->monitor, + background->region.x, + background->region.y, + background->region.width, + background->region.height); + + if (tmp) + g_object_unref (tmp); + + background_composite (background); +} + + +static GdkPixbuf * +get_desktop_pixbuf (GdmWidgetBackground *background) +{ + GdkPixbuf *desktop; + + if (!background->monitor) { + background->monitor = + background_monitor_get_for_screen ( + gdk_drawable_get_screen (background->window)); + + background->monitor_signal = + g_signal_connect ( + background->monitor, "changed", + G_CALLBACK (background_changed), background); + } + + desktop = background_monitor_get_region ( + background->monitor, + background->region.x, + background->region.y, + background->region.width, + background->region.height); + + return desktop; +} + +static GdkPixbuf * +composite_image_onto_desktop (GdmWidgetBackground *background) +{ + GdkPixbuf *retval; + int width, height; + unsigned char *data; + cairo_t *cr; + cairo_surface_t *surface; + cairo_pattern_t *pattern; + + if (!background->desktop) + background->desktop = get_desktop_pixbuf (background); + + if (!background->desktop) + return NULL; + + width = gdk_pixbuf_get_width (background->desktop); + height = gdk_pixbuf_get_height (background->desktop); + + data = g_malloc (width * height * 4); + if (!data) + return NULL; + + surface = cairo_image_surface_create_for_data (data, + CAIRO_FORMAT_RGB24, + width, height, + width * 4); + cr = cairo_create (surface); + cairo_set_source_rgb (cr, 1, 1, 1); + cairo_paint (cr); + + gdk_cairo_set_source_pixbuf (cr, background->desktop, 0, 0); + cairo_rectangle (cr, 0, 0, width, height); + cairo_fill (cr); + + gdk_cairo_set_source_pixbuf (cr, background->transformed_image, 0, 0); + pattern = cairo_get_source (cr); + cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); + cairo_rectangle (cr, 0, 0, width, height); + cairo_fill (cr); + + cairo_destroy (cr); + cairo_surface_destroy (surface); + + retval = cairo_rgbdata_to_pixbuf (data, width, height); + + g_free (data); + + return retval; +} + +void +gdm_widget_background_change_region (GdmWidgetBackground *background, + int x, + int y, + int width, + int height) +{ + gboolean need_to_retransform = FALSE; + + if (background->region.x == x && + background->region.y == y && + background->region.width == width && + background->region.height == height) + return; + + if ((background->region.width != width || + background->region.height != height)) { + need_to_retransform = TRUE; + } + + background->region.x = x; + background->region.y = y; + background->region.width = width; + background->region.height = height; + + if (background->desktop) + g_object_unref (background->desktop); + background->desktop = NULL; + + // FIXME + background_transform (background); + + return; + if (need_to_retransform || ! background->transformed) + /* only retransform the background if we have in + fact changed size*/ + background_transform (background); + else + background_composite (background); +} + +void +gdm_widget_background_realized (GdmWidgetBackground *background, + GtkWidget *widget) +{ + g_return_if_fail (widget!= NULL); + g_return_if_fail (widget->window!= NULL); + + if (background->window && background->colormap && background->gc) + return; + + if (!background->window) { + background->window = g_object_ref (widget->window); + } + + if (!background->colormap) + background->colormap = + g_object_ref (gdk_drawable_get_colormap (widget->window)); + + if (!background->gc) + background->gc = gdk_gc_new (widget->window); + + if (!background->widget) + background->widget = g_object_ref (widget); + + background_prepare (background); +} + +void gdm_widget_background_init (GdmWidgetBackground *background) { + background->image = NULL; + background->loaded_image = NULL; + background->window = NULL; + background->monitor = NULL; + background->desktop = NULL; + background->monitor_signal = -1; + background->region.x = -1; + background->region.y = -1; + background->region.width = -1; + background->region.height = -1; + background->transformed_image = NULL; + background->composited_image = NULL; + background->pixmap = NULL; + background->colormap = NULL; + background->prepared = FALSE; + background->composited= FALSE; + background->transformed= FALSE; + background->gc = NULL; + background->border_left = 0; + background->border_right= 0; + background->border_top= 0; + background->border_bottom = 0; +} + diff -p -up gdm-2.30.3/gui/simple-greeter/branding.h.improve-greeter-transparency gdm-2.30.3/gui/simple-greeter/branding.h --- gdm-2.30.3/gui/simple-greeter/branding.h.improve-greeter-transparency 2010-06-29 15:05:18.000000000 +0200 +++ gdm-2.30.3/gui/simple-greeter/branding.h 2010-06-29 15:05:18.000000000 +0200 @@ -0,0 +1,49 @@ +#ifndef __BRANDING_H +#define __BRANDING_H + +#include <gtk/gtk.h> + +typedef struct _BackgroundMonitor BackgroundMonitor; + + +typedef struct _GdmWidgetBackground GdmWidgetBackground; + +struct _GdmWidgetBackground { + char *image; + GdkPixbuf *loaded_image; + + GdkWindow *window; + GtkWidget *widget; + BackgroundMonitor *monitor; + GdkPixbuf *desktop; + gulong monitor_signal; + GdkRectangle region; + GdkPixbuf *transformed_image; + GdkPixbuf *composited_image; + GdkPixmap *pixmap; + GdkColormap *colormap; + gboolean prepared; + gboolean transformed; + gboolean composited; + GdkGC *gc; + gint border_left; + gint border_right; + gint border_bottom; + gint border_top; + +}; + +void gdm_widget_background_init (GdmWidgetBackground *background); +void gdm_widget_background_change_region (GdmWidgetBackground *background, + int x, + int y, + int width, + int height); +void +gdm_widget_background_realized (GdmWidgetBackground *background, + GtkWidget *widget); + + + + +#endif /* __BRANDING_H */ diff -p -up gdm-2.30.3/gui/simple-greeter/gdm-greeter-login-window.c.improve-greeter-transparency gdm-2.30.3/gui/simple-greeter/gdm-greeter-login-window.c --- gdm-2.30.3/gui/simple-greeter/gdm-greeter-login-window.c.improve-greeter-transparency 2010-06-28 19:23:25.000000000 +0200 +++ gdm-2.30.3/gui/simple-greeter/gdm-greeter-login-window.c 2010-06-29 15:06:30.000000000 +0200 @@ -64,6 +64,8 @@ #define PW_ENTRY_SIZE GDM_MAX_PASS #endif +#include "branding.h" + #define CK_NAME "org.freedesktop.ConsoleKit" #define CK_PATH "/org/freedesktop/ConsoleKit" #define CK_INTERFACE "org.freedesktop.ConsoleKit" @@ -106,6 +108,7 @@ struct GdmGreeterLoginWindowPrivate guint is_interactive : 1; guint user_chooser_loaded : 1; GConfClient *client; + GdmWidgetBackground background; gboolean banner_message_enabled; guint gconf_cnxn; @@ -1138,6 +1141,7 @@ load_theme (GdmGreeterLoginWindow *login GtkWidget *box; GtkWidget *image; GError* error = NULL; + GdkColor color; gdm_profile_start (NULL); @@ -1220,12 +1224,21 @@ load_theme (GdmGreeterLoginWindow *login box = GTK_WIDGET (gtk_builder_get_object (login_window->priv->builder, "computer-info-event-box")); g_signal_connect (box, "button-press-event", G_CALLBACK (on_computer_info_label_button_press), login_window); + if (login_window->priv->user_list_disabled) { switch_mode (login_window, MODE_AUTHENTICATION); } else { switch_mode (login_window, MODE_SELECTION); } + gdk_color_parse ("white", &color); + gtk_widget_modify_fg (login_window->priv->auth_banner_label, GTK_STATE_NORMAL, &color); + gtk_widget_modify_fg (GTK_WIDGET(gtk_builder_get_object (login_window->priv->builder, "computer-info-name-label")), GTK_STATE_NORMAL, &color); + gtk_widget_modify_fg (GTK_WIDGET(gtk_builder_get_object (login_window->priv->builder, "auth-prompt-label")), GTK_STATE_NORMAL, &color); + gtk_widget_modify_fg (GTK_WIDGET(gtk_builder_get_object (login_window->priv->builder, "computer-info-version-label")), GTK_STATE_NORMAL, &color); + gtk_widget_modify_fg (GTK_WIDGET(gtk_builder_get_object (login_window->priv->builder, "auth-message-label")), GTK_STATE_NORMAL, &color); + gtk_widget_modify_fg (GTK_WIDGET(gtk_builder_get_object (login_window->priv->builder, "auth-message-label")), GTK_STATE_NORMAL, &color); + gdm_profile_end (NULL); } @@ -1340,6 +1353,54 @@ update_banner_message (GdmGreeterLoginWi } } +static void +gdm_greeter_login_window_set_background_region (GdmGreeterLoginWindow *login_window) { + GtkWidget *widget; + int origin_x = -1, origin_y = -1; + + widget = GTK_WIDGET (login_window); + + if (!gtk_widget_get_realized (widget)) + return; + + gdk_window_get_origin (widget->window, &origin_x, &origin_y); + + gdm_widget_background_change_region ( + &login_window->priv->background, + origin_x, origin_y, + widget->allocation.width, + widget->allocation.height); +} + +static gboolean +configure_function (GtkWidget *widget, + gpointer user_data) +{ + gdm_greeter_login_window_set_background_region ((GdmGreeterLoginWindow*) (widget)); + return FALSE; +} + +static gboolean +map_function (GtkWidget *widget, + GdkEvent *event, + gpointer user_data) +{ + gdm_greeter_login_window_set_background_region ((GdmGreeterLoginWindow*) (widget)); + return FALSE; +} + +static void +realize_function (GtkWidget *widget) +{ + GdmGreeterLoginWindow *login_window = (GdmGreeterLoginWindow *) widget; + + GTK_WIDGET_CLASS (gdm_greeter_login_window_parent_class)->realize (widget); + + gdm_widget_background_realized (&login_window->priv->background, widget); +} + + + static GObject * gdm_greeter_login_window_constructor (GType type, guint n_construct_properties, @@ -1353,10 +1414,16 @@ gdm_greeter_login_window_constructor (GT n_construct_properties, construct_properties)); + g_signal_connect (login_window, "map", G_CALLBACK (map_function), login_window); + g_signal_connect (login_window, "configure_event", G_CALLBACK (configure_function), login_window); + g_signal_connect (login_window, "realize", G_CALLBACK (realize_function), login_window); + load_theme (login_window); update_banner_message (login_window); + gtk_frame_set_shadow_type(GTK_FRAME (gtk_builder_get_object (login_window->priv->builder, "window-frame")), GTK_SHADOW_NONE); + gdm_profile_end (NULL); return G_OBJECT (login_window); @@ -1532,6 +1599,14 @@ gdm_greeter_login_window_init (GdmGreete login_window->priv = GDM_GREETER_LOGIN_WINDOW_GET_PRIVATE (login_window); login_window->priv->timed_login_enabled = FALSE; login_window->priv->dialog_mode = MODE_UNDEFINED; + gdm_widget_background_init(&login_window->priv->background); + + login_window->priv->background.image = g_strdup (UIDIR "/" "box.png"); + login_window->priv->background.border_left= 5; + login_window->priv->background.border_right= 5; + login_window->priv->background.border_bottom= 60; + login_window->priv->background.border_top= 60; + client = gconf_client_get_default (); error = NULL; @@ -1550,7 +1625,6 @@ gdm_greeter_login_window_init (GdmGreete login_window->priv->user_list_disabled = user_list_disable; gtk_window_set_title (GTK_WINDOW (login_window), _("Login Window")); - /*gtk_window_set_opacity (GTK_WINDOW (login_window), 0.85);*/ gtk_window_set_position (GTK_WINDOW (login_window), GTK_WIN_POS_CENTER_ALWAYS); gtk_window_set_deletable (GTK_WINDOW (login_window), FALSE); gtk_window_set_decorated (GTK_WINDOW (login_window), FALSE); diff -p -up gdm-2.30.3/gui/simple-greeter/gdm-greeter-panel.c.improve-greeter-transparency gdm-2.30.3/gui/simple-greeter/gdm-greeter-panel.c --- gdm-2.30.3/gui/simple-greeter/gdm-greeter-panel.c.improve-greeter-transparency 2010-06-28 19:23:25.000000000 +0200 +++ gdm-2.30.3/gui/simple-greeter/gdm-greeter-panel.c 2010-06-29 15:07:53.000000000 +0200 @@ -56,6 +56,8 @@ #include "na-tray.h" +#include "branding.h" + #define CK_NAME "org.freedesktop.ConsoleKit" #define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager" #define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager" @@ -83,6 +85,7 @@ struct GdmGreeterPanelPrivate GtkWidget *language_option_widget; GtkWidget *layout_option_widget; GtkWidget *session_option_widget; + GdmWidgetBackground background; GdmTimer *animation_timer; double progress; @@ -230,6 +233,44 @@ on_screen_size_changed (GdkScreen gtk_widget_queue_resize (GTK_WIDGET (panel)); } +static void +gdm_greeter_panel_set_background_region (GdmGreeterPanel *panel) { + GtkWidget *widget; + int origin_x = -1, origin_y = -1; + + widget = GTK_WIDGET (panel); + + if (!gtk_widget_get_realized (widget)) + return; + + gdk_window_get_origin (widget->window, &origin_x, &origin_y); + + gdm_widget_background_change_region ( + &panel->priv->background, + origin_x, origin_y, + widget->allocation.width, + widget->allocation.height); +} + + +static gboolean +configure_function (GtkWidget *widget, + gpointer user_data) +{ + gdm_greeter_panel_set_background_region((GdmGreeterPanel*) (widget)); +// set_panelparent_bg (widget, get_overlay_pb (), 0, 0, 5, 0); + return FALSE; +} + +static gboolean +map_function (GtkWidget *widget, + GdkEvent *event, + gpointer user_data) +{ + gdm_greeter_panel_set_background_region((GdmGreeterPanel*) (widget)); + + return FALSE; +} static void gdm_greeter_panel_real_realize (GtkWidget *widget) { @@ -245,6 +286,7 @@ gdm_greeter_panel_real_realize (GtkWidge "size_changed", G_CALLBACK (on_screen_size_changed), widget); + gdm_widget_background_realized (&((GdmGreeterPanel *)widget)->priv->background, widget); } static void @@ -862,7 +904,18 @@ setup_panel (GdmGreeterPanel *panel) G_CALLBACK (on_animation_tick), panel); - gdm_profile_end (NULL); + gdm_widget_background_init(&panel->priv->background); + + panel->priv->background.image = g_strdup (UIDIR "/" "bottom-panel-image.png"); + panel->priv->background.border_left= 0; + panel->priv->background.border_right = 0; + panel->priv->background.border_bottom= 5; + panel->priv->background.border_top= 0; + + g_signal_connect (panel, "map", G_CALLBACK (map_function), panel); + g_signal_connect (panel, "configure_event", G_CALLBACK (configure_function), panel); + + gdm_profile_end (NULL); } static GObject * diff -p -up gdm-2.30.3/gui/simple-greeter/Makefile.am.improve-greeter-transparency gdm-2.30.3/gui/simple-greeter/Makefile.am --- gdm-2.30.3/gui/simple-greeter/Makefile.am.improve-greeter-transparency 2010-06-28 19:23:25.000000000 +0200 +++ gdm-2.30.3/gui/simple-greeter/Makefile.am 2010-06-29 15:05:18.000000000 +0200 @@ -85,6 +85,8 @@ test_greeter_login_window_SOURCES = \ gdm-user-chooser-widget.c \ gdm-user-chooser-dialog.h \ gdm-user-chooser-dialog.c \ + branding.c \ + branding.h \ $(NULL) test_greeter_login_window_LDADD = \ @@ -134,6 +136,8 @@ test_greeter_panel_SOURCES = \ gdm-sessions.c \ gdm-session-option-widget.h \ gdm-session-option-widget.c \ + branding.c \ + branding.h \ $(NULL) test_greeter_panel_LDADD = \ @@ -320,6 +324,8 @@ gdm_simple_greeter_SOURCES = \ gdm-session-option-widget.c \ gdm-user-chooser-widget.h \ gdm-user-chooser-widget.c \ + branding.c \ + branding.h \ $(NULL) gdm_simple_greeter_LDADD = \