Author: kelnos
Date: 2006-07-14 21:49:22 +0000 (Fri, 14 Jul 2006)
New Revision: 22449

Modified:
   xfdesktop/trunk/src/xfce-desktop.c
Log:
redo how the backdrop is drawn to fix ugly gradients on 16-bit displays
(bug 1819).  this also makes drawing quite a bit simpler and possibly even
a bit faster.


Modified: xfdesktop/trunk/src/xfce-desktop.c
===================================================================
--- xfdesktop/trunk/src/xfce-desktop.c  2006-07-14 18:49:46 UTC (rev 22448)
+++ xfdesktop/trunk/src/xfce-desktop.c  2006-07-14 21:49:22 UTC (rev 22449)
@@ -223,6 +223,8 @@
 {
     gchar property_name[128];
     
+    gdk_error_trap_push();
+    
     g_snprintf(property_name, 128, XFDESKTOP_IMAGE_FILE_FMT, monitor);
     if(filename) {
         gdk_property_change(gdk_screen_get_root_window(desktop->priv->gscreen),
@@ -234,19 +236,47 @@
         gdk_property_delete(gdk_screen_get_root_window(desktop->priv->gscreen),
                             gdk_atom_intern(property_name, FALSE));
     }
+    
+    gdk_error_trap_pop();
 }
 
 static void
+set_real_root_window_pixmap(GdkScreen *gscreen,
+                            GdkPixmap *pmap)
+{
+    Window xid;
+    GdkWindow *groot;
+    
+    xid = GDK_DRAWABLE_XID(pmap);
+    groot = gdk_screen_get_root_window(gscreen);
+    
+    gdk_error_trap_push();
+    
+    /* set root property for transparent Eterms */
+    gdk_property_change(groot,
+            gdk_atom_intern("_XROOTPMAP_ID", FALSE),
+            gdk_atom_intern("PIXMAP", FALSE), 32,
+            GDK_PROP_MODE_REPLACE, (guchar *)&xid, 1);
+    /* set this other property because someone might need it sometime. */
+    gdk_property_change(groot,
+            gdk_atom_intern("ESETROOT_PMAP_ID", FALSE),
+            gdk_atom_intern("PIXMAP", FALSE), 32,
+            GDK_PROP_MODE_REPLACE, (guchar *)&xid, 1);
+    /* and set the root window's BG pixmap, because aterm is somewhat lame. */
+    gdk_window_set_back_pixmap(groot, pmap, FALSE);
+    /* there really should be a standard for this crap... */
+    
+    gdk_error_trap_pop();
+}
+
+static void
 backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data)
 {
     XfceDesktop *desktop = XFCE_DESKTOP(user_data);
+    GdkPixmap *pmap = desktop->priv->bg_pixmap;
+    GdkScreen *gscreen = desktop->priv->gscreen;
     GdkPixbuf *pix;
-    GdkPixmap *pmap = NULL;
-    GdkColormap *cmap;
-    GdkScreen *gscreen;
     GdkRectangle rect;
-    Pixmap xid;
-    GdkWindow *groot;
     gint i, monitor = -1;
     
     TRACE("entering");
@@ -258,9 +288,6 @@
     
     TRACE("really entering");
     
-    gscreen = desktop->priv->gscreen;
-    cmap = 
gdk_drawable_get_colormap(GDK_DRAWABLE(GTK_WIDGET(desktop)->window));
-    
     for(i = 0; i < XFCE_DESKTOP(desktop)->priv->nbackdrops; i++) {
         if(backdrop == XFCE_DESKTOP(desktop)->priv->backdrops[i]) {
             monitor = i;
@@ -275,86 +302,24 @@
     if(!pix)
         return;
     
-    if(desktop->priv->nbackdrops == 1) {    
-        /* optimised for single monitor: just dump the pixbuf into a pixmap */
-        gdk_pixbuf_render_pixmap_and_mask_for_colormap(pix, cmap, &pmap, NULL, 
0);
-        g_object_unref(G_OBJECT(pix));
-        if(!pmap)
-            return;
+    if(desktop->priv->nbackdrops == 1) {
+        /* single monitor */
         rect.x = rect.y = 0;
         rect.width = gdk_screen_get_width(gscreen);
         rect.height = gdk_screen_get_height(gscreen);
-    } else {
-        /* multiple monitors (xinerama): download the current backdrop, paint
-         * over the correct area, and upload it back.  this is slow, but
-         * probably still faster than redoing the whole thing. */
-        GdkPixmap *cur_pmap = NULL;
-        GdkPixbuf *cur_pbuf = NULL;
-        gint swidth, sheight;
-        
-        swidth = gdk_screen_get_width(gscreen);
-        sheight = gdk_screen_get_height(gscreen);
-        
-        cur_pmap = desktop->priv->bg_pixmap;
-        if(cur_pmap) {
-            gint pw, ph;
-            gdk_drawable_get_size(GDK_DRAWABLE(cur_pmap), &pw, &ph);
-            if(pw == swidth && ph == sheight) {
-                cur_pbuf = gdk_pixbuf_get_from_drawable(NULL, 
-                        GDK_DRAWABLE(cur_pmap), cmap, 0, 0, 0, 0, swidth,
-                        sheight);
-            } else
-                cur_pmap = NULL;
-        }
-        /* if the style's bg_pixmap was empty, or the above failed... */
-        if(!cur_pmap) {
-            cur_pbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8,
-                    swidth, sheight);
-        }
-        
+    } else
         gdk_screen_get_monitor_geometry(gscreen, monitor, &rect);
-        gdk_pixbuf_copy_area(pix, 0, 0, gdk_pixbuf_get_width(pix),
-                gdk_pixbuf_get_height(pix), cur_pbuf, rect.x, rect.y);
-        g_object_unref(G_OBJECT(pix));
-        pmap = NULL;
-        gdk_pixbuf_render_pixmap_and_mask_for_colormap(cur_pbuf, cmap,
-                &pmap, NULL, 0);
-        g_object_unref(G_OBJECT(cur_pbuf));
-        if(!pmap)
-            return;
-    }
+
+    gdk_draw_pixbuf(GDK_DRAWABLE(pmap), GTK_WIDGET(desktop)->style->black_gc,
+                    pix, 0, 0, rect.x, rect.y,
+                    gdk_pixbuf_get_width(pix), gdk_pixbuf_get_height(pix),
+                    GDK_RGB_DITHER_MAX, 0, 0);
+    g_object_unref(G_OBJECT(pix));
     
-    xid = GDK_DRAWABLE_XID(pmap);
-    groot = gdk_screen_get_root_window(gscreen);
-    
-    gdk_error_trap_push();
-    
-    /* set root property for transparent Eterms */
-    gdk_property_change(groot,
-            gdk_atom_intern("_XROOTPMAP_ID", FALSE),
-            gdk_atom_intern("PIXMAP", FALSE), 32,
-            GDK_PROP_MODE_REPLACE, (guchar *)&xid, 1);
-    /* set this other property because someone might need it sometime. */
-    gdk_property_change(groot,
-            gdk_atom_intern("ESETROOT_PMAP_ID", FALSE),
-            gdk_atom_intern("PIXMAP", FALSE), 32,
-            GDK_PROP_MODE_REPLACE, (guchar *)&xid, 1);
-    /* and set the root window's BG pixmap, because aterm is somewhat lame. */
-    gdk_window_set_back_pixmap(groot, pmap, FALSE);
-    /* there really should be a standard for this crap... */
-    
-    /* clear the old pixmap, if any */
-    if(desktop->priv->bg_pixmap)
-        g_object_unref(G_OBJECT(desktop->priv->bg_pixmap));
-    
-    /* set the new pixmap and tell gtk to redraw it */
-    desktop->priv->bg_pixmap = pmap;
-    gdk_window_set_back_pixmap(GTK_WIDGET(desktop)->window, pmap, FALSE);
+    /* tell gtk to redraw the repainted area */
     gtk_widget_queue_draw_area(GTK_WIDGET(desktop), rect.x, rect.y,
                                rect.width, rect.height);
     
-    gdk_error_trap_pop();
-    
     set_imgfile_root_property(desktop,
                               xfce_backdrop_get_image_filename(backdrop),
                               monitor);
@@ -374,10 +339,13 @@
     gtk_widget_set_size_request(GTK_WIDGET(desktop), w, h);
     gtk_window_resize(GTK_WINDOW(desktop), w, h);
     
-    if(desktop->priv->bg_pixmap) {
-        g_object_unref(G_OBJECT(desktop->priv->bg_pixmap));
-        desktop->priv->bg_pixmap = NULL;
-    }
+    g_object_unref(G_OBJECT(desktop->priv->bg_pixmap));
+    desktop->priv->bg_pixmap = 
gdk_pixmap_new(GDK_DRAWABLE(GTK_WIDGET(desktop)->window),
+                                              w, h, -1);
+    set_real_root_window_pixmap(desktop->priv->gscreen,
+                                desktop->priv->bg_pixmap);
+    gdk_window_set_back_pixmap(GTK_WIDGET(desktop)->window,
+                               desktop->priv->bg_pixmap, FALSE);
     
     /* special case for 1 backdrop to handle xinerama stretching properly.
      * this is broken if it ever becomes possible to change the number of
@@ -452,8 +420,6 @@
     }
 }
 
-
-
 static void
 screen_set_selection(XfceDesktop *desktop)
 {
@@ -554,7 +520,7 @@
 {
     XfceDesktop *desktop = XFCE_DESKTOP(widget);
     GdkAtom atom;
-    gint i;
+    gint i, sw, sh;
     Window xid;
     GdkDisplay *gdpy;
     GdkWindow *groot;
@@ -563,6 +529,8 @@
     TRACE("entering");
     
     gtk_window_set_screen(GTK_WINDOW(desktop), desktop->priv->gscreen);
+    sw = gdk_screen_get_width(desktop->priv->gscreen);
+    sh = gdk_screen_get_height(desktop->priv->gscreen);
     
     /* chain up */
     GTK_WIDGET_CLASS(xfce_desktop_parent_class)->realize(widget);
@@ -571,9 +539,7 @@
     if(GTK_WIDGET_DOUBLE_BUFFERED(GTK_WIDGET(desktop)))
         gtk_widget_set_double_buffered(GTK_WIDGET(desktop), FALSE);
     
-    gtk_widget_set_size_request(GTK_WIDGET(desktop),
-                      gdk_screen_get_width(desktop->priv->gscreen),
-                      gdk_screen_get_height(desktop->priv->gscreen));
+    gtk_widget_set_size_request(GTK_WIDGET(desktop), sw, sh);
     gtk_window_move(GTK_WINDOW(desktop), 0, 0);
     
     atom = gdk_atom_intern("_NET_WM_WINDOW_TYPE_DESKTOP", FALSE);
@@ -608,6 +574,13 @@
                 rect.width, rect.height);
     }
     
+    desktop->priv->bg_pixmap = 
gdk_pixmap_new(GDK_DRAWABLE(GTK_WIDGET(desktop)->window),
+                                              sw, sh, -1);
+    set_real_root_window_pixmap(desktop->priv->gscreen,
+                                desktop->priv->bg_pixmap);
+    gdk_window_set_back_pixmap(GTK_WIDGET(desktop)->window,
+                               desktop->priv->bg_pixmap, FALSE);
+    
     for(i = 0; i < desktop->priv->nbackdrops; i++) {
         g_signal_connect(G_OBJECT(desktop->priv->backdrops[i]), "changed",
                 G_CALLBACK(backdrop_changed_cb), desktop);
@@ -648,6 +621,7 @@
     gdk_property_delete(groot, gdk_atom_intern("NAUTILUS_DESKTOP_WINDOW_ID", 
FALSE));
     gdk_property_delete(groot, gdk_atom_intern("_XROOTPMAP_ID", FALSE));
     gdk_property_delete(groot, gdk_atom_intern("ESETROOT_PMAP_ID", FALSE));
+    gdk_window_set_back_pixmap(groot, NULL, FALSE);
     
     if(desktop->priv->backdrops) {
         for(i = 0; i < desktop->priv->nbackdrops; i++) {
@@ -659,10 +633,8 @@
         desktop->priv->backdrops = NULL;
     }
     
-    if(desktop->priv->bg_pixmap) {
-        g_object_unref(G_OBJECT(desktop->priv->bg_pixmap));
-        desktop->priv->bg_pixmap = NULL;
-    }
+    g_object_unref(G_OBJECT(desktop->priv->bg_pixmap));
+    desktop->priv->bg_pixmap = NULL;
     
     gtk_window_set_icon(GTK_WINDOW(widget), NULL);
     
@@ -720,10 +692,8 @@
 {
     XfceDesktop *desktop = XFCE_DESKTOP(w);
     
-    if(desktop->priv->bg_pixmap) {
-        gdk_window_set_back_pixmap(w->window, desktop->priv->bg_pixmap, FALSE);
-        gtk_widget_queue_draw(w);
-    }
+    gdk_window_set_back_pixmap(w->window, desktop->priv->bg_pixmap, FALSE);
+    gtk_widget_queue_draw(w);
 }
 
 

_______________________________________________
Xfce4-commits mailing list
Xfce4-commits@xfce.org
http://foo-projects.org/mailman/listinfo/xfce4-commits

Reply via email to