Enlightenment CVS committal

Author  : xcomputerman
Project : e17
Module  : proto

Dir     : e17/proto/esmart/src/trans


Modified Files:
        esmart_trans.c 


Log Message:
Esmart_Trans: Thorough cleanup of pixmap fetch function, modeled after
Evidence (thanks Azundris). Fixed bug affecting windows with negative x, y
coordinates - partially displayed windows should always render correctly
now.

===================================================================
RCS file: /cvsroot/enlightenment/e17/proto/esmart/src/trans/esmart_trans.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -3 -r1.6 -r1.7
--- esmart_trans.c      12 Jan 2004 15:54:12 -0000      1.6
+++ esmart_trans.c      21 Feb 2004 23:11:01 -0000      1.7
@@ -30,122 +30,147 @@
 static void _esmart_trans_x11_clip_set(Evas_Object *o, Evas_Object *clip);
 static void _esmart_trans_x11_clip_unset(Evas_Object *o);
 
-/**
- * Stolen from ev and iconbar, hopefully this should be shareable now
- */
 static Evas_Object *
-_esmart_trans_x11_pixmap_get(Evas *evas, Evas_Object *old,
-                        int x, int y, int w, int h)
+_esmart_trans_x11_pixmap_get(Evas *evas, Evas_Object *old, int x, int y, int w, int h)
 {
-  Atom            prop,type; 
-  int             format;
-  unsigned long   length,after;
-  unsigned char  *data;
-  Evas_Object    *new=NULL;
-  Pixmap          p;
-
-  if(old)
-    evas_object_del(old);
-
-  if((prop=XInternAtom(ecore_x_display_get(),"_XROOTPMAP_ID",True))!=None)
-  {
-    /* FIXME: CACHE ME! */
-    int ret=XGetWindowProperty(ecore_x_display_get(), 
-                              RootWindow(ecore_x_display_get(), 0),
-                               prop, 0L, 1L, False, AnyPropertyType, &type,
-                               &format,&length, &after,&data);
-    if((ret==Success)&&(type==XA_PIXMAP)&&((p=*((Pixmap *)data))!=None)) {
-      Imlib_Image  im;
-      unsigned int pw,ph, pb,pd;
-      int          px,py;
-      Window       win_dummy;
-      Status       st;
-
-      st=XGetGeometry(ecore_x_display_get(),p,&win_dummy, &px,&py,&pw,&ph, &pb, &pd);
-      if(st&&(pw>0)&&(ph>0)) {
-#  ifdef NOIR_DEBUG
-        fprintf(stderr,"bg_ebg_trans: transparency update %3d,%3d %3dx%3d\n",x,y,w,h);
-#  endif
-
-        imlib_context_set_drawable(*((Pixmap *)data));
-
-       if((x>=px)&&(y>=py)&&((x+w)<=(py+((signed int)pw)))&&((y+h)<=(py+((signed 
int)ph)))) 
-       {
-           im = imlib_create_image_from_drawable (0, x, y, w, h, 1);
-           imlib_context_set_image (im);
-       }
-       else /* tiled root pixmap */
-       {
-           Imlib_Image  dst;
-           int          sx, sy, dx, dy;
-
-           im=imlib_create_image_from_drawable(0, px, py, pw, ph, 1);
-           dst=imlib_create_image(w, h);
-           imlib_context_set_image(dst);
-           imlib_image_clear();
-           imlib_context_set_cliprect(0, 0, w, h);
-
-           dx = (x%pw);
-           dy = (y%ph);
-
-       /* There really ought to be a better way to do this, like
-        * negative coordinates, but I'm not sure those are valid */
-       imlib_blend_image_onto_image(im, 1, dx, dy, pw - dx, ph - dy, 
-                                    0, 0, pw - dx, ph - dy);
-       imlib_blend_image_onto_image(im, 1, 0, dy, dx, pw - dy,
-                                    pw - dx, 0, dx, ph -dy);
-       imlib_blend_image_onto_image(im, 1, dx, 0, pw - dx, dy,
-                                    0, ph - dy, pw - dx, dy);
-       imlib_blend_image_onto_image(im, 1, 0, 0, dx, dy,
-                                    pw - dx, ph - dy, dx, dy);
-                                    
-
-       for (sx = 0; sx < w; sx += pw)
-          for (sy = 0; sy < h; sy += ph)
-             if(sx || sy)
-              imlib_image_copy_rect(0, 0, pw, ph, sx, sy);
-           
-       imlib_context_set_image(im);
-           imlib_free_image();
-           imlib_context_set_image(dst); 
-       }
-        imlib_image_set_format("argb");
-        new=evas_object_image_add(evas);
-        evas_object_image_alpha_set(new,0);
-        evas_object_image_size_set(new,w,h);   /* thanks rephorm */
-        evas_object_image_data_copy_set(new,imlib_image_get_data_for_reading_only());
-        imlib_free_image();
-
-        evas_object_image_fill_set(new,0,0,w,h);
-        evas_object_resize(new,w,h);
-        evas_object_move(new,0,0);
-        evas_object_layer_set(new,-9999);
-        evas_object_image_data_update_add(new,0,0,w,h);
-        evas_object_show(new); }
-#if 1
-      else  /* this can happen with e16 */
-         /* It would be nice to somehow make this actually attempt to
-          * get the background pixmap from e16 on alternate desktops. */
-        fprintf(stderr,"bg_ebg_trans: got invalid pixmap from root-window, 
ignoring...\n");
-#endif
-    }
-    else
-      fprintf(stderr,"bg_ebg_trans: could not read root-window property 
_XROOTPMAP_ID...\n"); }
-  else
-    fprintf(stderr,"bg_ebg_trans: could not get XAtom _XROOTPMAP_ID...\n");
-
-  if(!new) {  /* fallback if no root pixmap is found */
-#if 1
-    fprintf(stderr,"bg_ebg_trans: cannot create transparency pixmap, no valid 
wallpaper set.\n");
-#endif
-    new=evas_object_rectangle_add(evas);
-    evas_object_resize(new,w,h);
-    evas_object_move(new,0,0);
-    evas_object_layer_set(new,-9999);
-    evas_object_color_set(new, 127,127,127, 255);
-    evas_object_show(new); }
+   int            ret;
+   unsigned char  *data;
+   Evas_Object    *new = NULL;
+   Ecore_X_Pixmap p;
+   Ecore_X_Atom   x_pixmap;
+   Ecore_X_Atom   rootpmap, rootcolor;
+   Ecore_X_Window root, *root_list;
+   int            offscreen = 0;
+
+   int            ox = 0, oy = 0;
+
+   if (old)
+      evas_object_del(old);
+   
+   x_pixmap = ecore_x_atom_get("PIXMAP");
+   rootpmap = ecore_x_atom_get("_XROOTPMAP_ID");
+   rootcolor = ecore_x_atom_get("_XROOTCOLOR_PIXEL");
+   root_list = ecore_x_window_root_list(&ret);
+   if(ret)
+      root = *root_list;
+   else
+      root = 0; /* Paranoid */
+
+   if (rootpmap)
+   {
+      ret = ecore_x_window_prop_property_get(root, rootpmap, 
+                                             x_pixmap, 32, &data, &ret);
+      if (ret && (p = *((Ecore_X_Pixmap *) data)))
+      {
+         Imlib_Image    im;
+         unsigned int   pw, ph;
+         int            px, py;
+            
+         ecore_x_pixmap_geometry_get(p, &px, &py, &pw, &ph);
+         if (pw && ph) {
+            imlib_context_set_drawable(*((Ecore_X_Pixmap *) data));
+
+            /* Check if the trans object will fit within the pixmap's boundaries */
+            if ((x >= px) && (y >= py) && ((x + w) <= (py + ((signed int) pw))) 
+                  && ((y + h) <= (py + ((signed int) ph))))
+            {
+               im = imlib_create_image_from_drawable(0, x, y, w, h, 1);
+               imlib_context_set_image(im);
+            }
+            else
+            {
+               Imlib_Image dest;
+               int         sx, sy, dx, dy;
+              
+               /* Resolve offscreen coordinates by drawing only visible component */
+               if (x < 0)
+               {
+                  w += x;
+                  ox = -x;
+                  x = 0;
+               }
+
+               if (y < 0)
+               {
+                  h += y;
+                  oy = -y;
+                  y = 0;
+               }
+               
+               offscreen = 1;
+               im = imlib_create_image_from_drawable(0, px, py, pw, ph, 1);
+               dest = imlib_create_image(w, h);
+               imlib_context_set_image(dest);
+               imlib_image_clear();
+               imlib_context_set_cliprect(0, 0, w, h);
+
+               dx = x % pw;
+               dy = y % ph;
+
+               for (sy = 0; sy < (h + dy); sy += ph)
+                  for (sx = 0; sx < (w + dx); sx += pw)
+                     imlib_blend_image_onto_image(im, 1, 0, 0, pw, ph, 
+                                                  sx - dx, sy - dy, pw, ph);
+                  
+               imlib_context_set_image(im);
+               imlib_free_image();
+               imlib_context_set_image(dest);
+            }
+
+            imlib_image_set_format("argb");
+            new = evas_object_image_add(evas);
+            evas_object_image_alpha_set(new, 0);
+            evas_object_image_size_set(new, w, h);
+            evas_object_image_data_copy_set(new, 
imlib_image_get_data_for_reading_only());
+            imlib_free_image();
+
+            evas_object_image_fill_set(new, 0, 0, w, h);
+            evas_object_resize(new, w, h);
+            evas_object_move(new, ox, oy);
+            evas_object_layer_set(new, -9999);
+            evas_object_image_data_update_add(new, 0, 0, w, h);
+            evas_object_show(new);
+         } /* if (pw && ph) */
+         else /* This could happen with E16: Try to get pixmap from multiple desktop? 
*/
+            fprintf(stderr, "Esmart_Trans Error: Got invalid pixmap from root window! 
Ignored.\n");
+      } /* if ((p = *((Ecore_X_Pixmap *) data))) */
+      else
+      {
+         free(data);
+         fprintf(stderr, "Esmart_Trans Error: Could not read root window pixmap 
property!\n");
+      }
+   } /* ecore_x_window_prop_property_get() */
+   else
+      fprintf(stderr, "Esmart_Trans Error: Could not obtain root pixmap atom.\n");
+
+   if (!new) /* Fallback if no root pixmap is found */
+   {
+      int r = 0, g = 0, b = 0;
+
+      new = evas_object_rectangle_add(evas);
+      evas_object_resize(new, w, h);
+      evas_object_move(new, 0, 0);
+      evas_object_layer_set(new, -9999);
+      
+      if (ecore_x_window_prop_property_get(root, rootcolor, 
ecore_x_atom_get("CARDINAL"),
+                                           32, &data, &ret))
+      {
+         unsigned long pixel = *((unsigned long *) data);
+         r = (pixel >> 16) & 0xff;
+         g = (pixel >> 8) & 0xff;
+         b = pixel & 0xff;
+         free (data);
+      }
+      else
+      {
+         fprintf(stderr, "Esmart_Trans Error: Cannot create transparency pixmap: no 
valid wallpaper and no background color set.\n");
+      }
+
+      evas_object_color_set(new, r, g, b, 255);
+      evas_object_show(new);
+   }
 
-    return new; 
+   return new;
 }
 
 /* keep a global copy of this, so it only has to be created once */




-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click
_______________________________________________
enlightenment-cvs mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to