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