From: caro Date: Mon, 8 Jun 2009 06:34:20 +0000 (+0000) Subject: Add Region API to ecore_x (Xlib using Region and XCB using pixman). X-Git-Tag: 2.0_alpha~194^2~1448 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ddc50f0a86a7550949502b7401aae81c687056e0;p=framework%2Fuifw%2Fecore.git Add Region API to ecore_x (Xlib using Region and XCB using pixman). This allow to use the same code in ecore_evas for Xlib and XCB git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/ecore@40959 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- diff --git a/src/lib/ecore_evas/ecore_evas_private.h b/src/lib/ecore_evas/ecore_evas_private.h index a02e2c2..f2c9e6f 100644 --- a/src/lib/ecore_evas/ecore_evas_private.h +++ b/src/lib/ecore_evas/ecore_evas_private.h @@ -164,11 +164,7 @@ struct _Ecore_Evas_Engine Ecore_X_Pixmap pmap; Ecore_X_Pixmap mask; Ecore_X_GC gc; -#ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB -# warning [XCB] No Region code -#else - Region damages; -#endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */ + Ecore_X_XRegion *damages; int px, py, pw, ph; unsigned char direct_resize : 1; unsigned char using_bg_pixmap : 1; diff --git a/src/lib/ecore_evas/ecore_evas_x.c b/src/lib/ecore_evas/ecore_evas_x.c index cfc4d57..7fe922c 100644 --- a/src/lib/ecore_evas/ecore_evas_x.c +++ b/src/lib/ecore_evas/ecore_evas_x.c @@ -176,47 +176,44 @@ _ecore_evas_x_render(Ecore_Evas *ee) } else { -#ifdef HAVE_ECORE_X_XCB -#warning [XCB] No Region code -#else EINA_LIST_FOREACH(updates, l, r) { - XRectangle xr; - Region tmpr; + Ecore_X_Rectangle rect; + Ecore_X_XRegion *tmpr; if (!ee->engine.x.damages) - ee->engine.x.damages = XCreateRegion(); - tmpr = XCreateRegion(); + ee->engine.x.damages = ecore_x_xregion_new(); + tmpr = ecore_x_xregion_new(); if (ee->rotation == 0) { - xr.x = r->x; - xr.y = r->y; - xr.width = r->w; - xr.height = r->h; + rect.x = r->x; + rect.y = r->y; + rect.width = r->w; + rect.height = r->h; } else if (ee->rotation == 90) { - xr.x = r->y; - xr.y = ee->h - r->x - r->w; - xr.width = r->h; - xr.height = r->w; + rect.x = r->y; + rect.y = ee->h - r->x - r->w; + rect.width = r->h; + rect.height = r->w; } else if (ee->rotation == 180) { - xr.x = ee->w - r->x - r->w; - xr.y = ee->h - r->y - r->h; - xr.width = r->w; - xr.height = r->h; + rect.x = ee->w - r->x - r->w; + rect.y = ee->h - r->y - r->h; + rect.width = r->w; + rect.height = r->h; } else if (ee->rotation == 270) { - xr.x = ee->w - r->y - r->h; - xr.y = r->x; - xr.width = r->h; - xr.height = r->w; + rect.x = ee->w - r->y - r->h; + rect.y = r->x; + rect.width = r->h; + rect.height = r->w; } - XUnionRectWithRegion(&xr, ee->engine.x.damages, tmpr); - XDestroyRegion(ee->engine.x.damages); + ecore_x_xregion_union_rect(tmpr, ee->engine.x.damages, &rect); + ecore_x_xregion_free(ee->engine.x.damages); ee->engine.x.damages = tmpr; } if (ee->engine.x.damages) @@ -256,7 +253,7 @@ _ecore_evas_x_render(Ecore_Evas *ee) ECORE_X_EVENT_MASK_WINDOW_PROPERTY | ECORE_X_EVENT_MASK_WINDOW_COLORMAP ); - XSetRegion(ecore_x_display_get(), ee->engine.x.gc, ee->engine.x.damages); + ecore_x_xregion_set(ee->engine.x.damages, ee->engine.x.gc); /* debug rendering */ /* XSetForeground(ecore_x_display_get(), ee->engine.x.gc, rand()); @@ -268,10 +265,9 @@ _ecore_evas_x_render(Ecore_Evas *ee) */ ecore_x_pixmap_paste(ee->engine.x.pmap, ee->prop.window, ee->engine.x.gc, 0, 0, ee->w, ee->h, 0, 0); - XDestroyRegion(ee->engine.x.damages); - ee->engine.x.damages = 0; + ecore_x_xregion_free(ee->engine.x.damages); + ee->engine.x.damages = NULL; } -#endif /* HAVE_ECORE_X_XCB */ if (updates) { evas_render_updates_free(updates); @@ -663,37 +659,33 @@ _ecore_evas_x_event_window_damage(void *data __UNUSED__, int type __UNUSED__, vo // printf("EXPOSE %p [%i] %i %i %ix%i\n", ee, ee->prop.avoid_damage, e->x, e->y, e->w, e->h); if (ee->prop.avoid_damage) { -#ifdef HAVE_ECORE_X_XCB -# warning [XCB] No Region code -#else - XRectangle xr; - Region tmpr; - - if (!ee->engine.x.damages) ee->engine.x.damages = XCreateRegion(); - tmpr = XCreateRegion(); - xr.x = e->x; - xr.y = e->y; - xr.width = e->w; - xr.height = e->h; - XUnionRectWithRegion(&xr, ee->engine.x.damages, tmpr); - XDestroyRegion(ee->engine.x.damages); + Ecore_X_Rectangle rect; + Ecore_X_XRegion *tmpr; + + if (!ee->engine.x.damages) ee->engine.x.damages = ecore_x_xregion_new(); + tmpr = ecore_x_xregion_new(); + rect.x = e->x; + rect.y = e->y; + rect.width = e->w; + rect.height = e->h; + ecore_x_xregion_union_rect(tmpr, ee->engine.x.damages, &rect); + ecore_x_xregion_free(ee->engine.x.damages); ee->engine.x.damages = tmpr; /* no - this breaks things badly. disable. Ecore_X_Rectangle != XRectangle - see * the typedefs in x's headers and ecore_x's. also same with Region - it's a pointer in x - not an X ID Ecore_X_Rectangle rect; - Ecore_X_Region tmpr; + Ecore_X_XRegion *tmpr; - if (!ee->engine.x.damages) ee->engine.x.damages = XCreateRegion(); - tmpr = XCreateRegion(); + if (!ee->engine.x.damages) ee->engine.x.damages = ecore_x_xregion_new(); + tmpr = ecore_x_xregion_new(); rect.x = e->x; rect.y = e->y; rect.width = e->w; rect.height = e->h; - XUnionRectWithRegion(&rect, ee->engine.x.damages, tmpr); - XDestroyRegion(ee->engine.x.damages); + ecore_x_xregion_union_rect(tmpr, ee->engine.x.damages, &rect); + ecore_x_xregion_free(ee->engine.x.damages); ee->engine.x.damages = tmpr; */ -#endif /* ! HAVE_ECORE_X_XCB */ } else { @@ -1064,19 +1056,11 @@ _ecore_evas_x_free(Ecore_Evas *ee) if (ee->engine.x.pmap) ecore_x_pixmap_free(ee->engine.x.pmap); if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask); if (ee->engine.x.gc) ecore_x_gc_free(ee->engine.x.gc); -#ifdef HAVE_ECORE_X_XCB -# warning [XCB] No Region code -#else - if (ee->engine.x.damages) XDestroyRegion(ee->engine.x.damages); -#endif /* ! HAVE_ECORE_X_XCB */ + if (ee->engine.x.damages) ecore_x_xregion_free(ee->engine.x.damages); ee->engine.x.pmap = 0; ee->engine.x.mask = 0; ee->engine.x.gc = 0; -#ifdef HAVE_ECORE_X_XCB -#warning [XCB] No Region code -#else - ee->engine.x.damages = 0; -#endif /* ! HAVE_ECORE_X_XCB */ + ee->engine.x.damages = NULL; ecore_event_window_unregister(ee->prop.window); while (ee->engine.x.win_extra) { diff --git a/src/lib/ecore_x/Ecore_X.h b/src/lib/ecore_x/Ecore_X.h index 87fd8c0..1500b18 100644 --- a/src/lib/ecore_x/Ecore_X.h +++ b/src/lib/ecore_x/Ecore_X.h @@ -66,6 +66,7 @@ typedef void Ecore_X_Connection; typedef void Ecore_X_Screen; typedef Ecore_X_ID Ecore_X_Sync_Counter; typedef Ecore_X_ID Ecore_X_Sync_Alarm; +typedef void Ecore_X_XRegion; typedef Ecore_X_ID Ecore_X_Randr_Output; typedef Ecore_X_ID Ecore_X_Randr_Crtc; @@ -1616,6 +1617,19 @@ EAPI void ecore_x_pointer_xy_get_prefetch(Ecore_X_Window window); EAPI void ecore_x_pointer_xy_get_fetch(void); EAPI void ecore_x_pointer_xy_get(Ecore_X_Window win, int *x, int *y); +/* ecore_x_region.c */ +EAPI Ecore_X_XRegion *ecore_x_xregion_new(); +EAPI void ecore_x_xregion_free(Ecore_X_XRegion *region); +EAPI int ecore_x_xregion_set(Ecore_X_XRegion *region, Ecore_X_GC gc); +EAPI void ecore_x_xregion_translate(Ecore_X_XRegion *region, int x, int y); +EAPI int ecore_x_xregion_intersect(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2); +EAPI int ecore_x_xregion_union(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2); +EAPI int ecore_x_xregion_union_rect(Ecore_X_XRegion *dst, Ecore_X_XRegion *src, Ecore_X_Rectangle *rect); +EAPI int ecore_x_xregion_subtract(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2); +EAPI int ecore_x_xregion_is_empty(Ecore_X_XRegion *region); +EAPI int ecore_x_xregion_point_contain(Ecore_X_XRegion *region, int x, int y); +EAPI int ecore_x_xregion_rect_contain(Ecore_X_XRegion *region, Ecore_X_Rectangle *rect); + /* ecore_x_sync.c */ EAPI Ecore_X_Sync_Alarm ecore_x_sync_alarm_new(Ecore_X_Sync_Counter counter); EAPI int ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm); diff --git a/src/lib/ecore_x/xcb/Makefile.am b/src/lib/ecore_x/xcb/Makefile.am index 5e46fb2..a9c110a 100644 --- a/src/lib/ecore_x/xcb/Makefile.am +++ b/src/lib/ecore_x/xcb/Makefile.am @@ -47,6 +47,7 @@ ecore_xcb_mwm.c \ ecore_xcb_netwm.c \ ecore_xcb_pixmap.c \ ecore_xcb_randr.c \ +ecore_xcb_region.c \ ecore_xcb_reply.c \ ecore_xcb_screensaver.c \ ecore_xcb_selection.c \ diff --git a/src/lib/ecore_x/xcb/ecore_xcb_region.c b/src/lib/ecore_x/xcb/ecore_xcb_region.c new file mode 100644 index 0000000..ec2847c --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_region.c @@ -0,0 +1,170 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "ecore_x_private.h" + + +/* + * [x] XCreateRegion + * [ ] XPolygonRegion + * [x] XSetRegion + * [x] XDestroyRegion + * + * [x] XOffsetRegion + * [ ] XShrinkRegion + * + * [ ] XClipBox + * [x] XIntersectRegion + * [x] XUnionRegion + * [x] XUnionRectWithRegion + * [x] XSubtractRegion + * [ ] XXorRegion + * + * [x] XEmptyRegion + * [x] XEqualRegion + * + * [x] XPointInRegion + * [x] XRectInRegion + */ + +EAPI Ecore_X_XRegion * +ecore_x_xregion_new() +{ + pixman_region16_t *region; + + region = (pixman_region16_t *)malloc (sizeof (pixman_region16_t)); + if (!region) + return NULL; + + pixman_region_init(region); + + return (Ecore_X_XRegion *)region; +} + +EAPI void +ecore_x_xregion_free(Ecore_X_XRegion *region) +{ + if (!region) + return; + + pixman_region_fini(region); + free(region); +} + +EAPI int +ecore_x_xregion_set(Ecore_X_XRegion *region, Ecore_X_GC gc) +{ + xcb_rectangle_t *rects; + pixman_box16_t *boxes; + int num; + + if (!region) + return 0; + + boxes = pixman_region_rectangles ((pixman_region16_t *)region, &num); + + if (!boxes || (num == 0)) + return 0; + + rects = (xcb_rectangle_t *)malloc(sizeof(xcb_rectangle_t) * num); + if (!rects) + return 0; + + for (i = 0; i < num; i++) + { + rects[i].x = boxes[i].x1; + rects[i].y = boxes[i].y1; + rects[i].width = boxes[i].x2 - boxes[i].x1 + 1; + rects[i].height = boxes[i].y2 - boxes[i].y1 + 1; + } + + xcb_set_clip_rectangles(_ecore_x_connection, + XCB_CLIP_ORDERING_YX_BANDED, + gc, + 0, 0, + num, + rects); + return 1; +} + +EAPI void +ecore_x_xregion_translate(Ecore_X_XRegion *region, int x, int y) +{ + if (!region) + return; + + pixman_region_translate((pixman_region16_t *)region, x, y); +} + +EAPI int +ecore_x_xregion_intersect(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2) +{ + return pixman_region_intersect((pixman_region16_t *)dst, (pixman_region16_t *)r1, (pixman_region16_t *)r2); +} + +EAPI int +ecore_x_xregion_union(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2) +{ + return pixman_region_union((pixman_region16_t *)dst, (pixman_region16_t *)r1, (pixman_region16_t *)r2); +} + +EAPI int +ecore_x_xregion_union_rect(Ecore_X_XRegion *dst, Ecore_X_XRegion *src, Ecore_X_Rectangle *rect) +{ + return pixman_region_union_rect((pixman_region16_t *)dst, (pixman_region16_t *)src, + rect->x, rect->y, rect->width, rect->height); +} + +EAPI int +ecore_x_xregion_subtract(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2) +{ + return pixman_region_subtract((pixman_region16_t *)dst, (pixman_region16_t *)rm, (pixman_region16_t *)rs); +} + +EAPI int +ecore_x_xregion_is_empty(Ecore_X_XRegion *region) +{ + if (!region) + return 1; + + return !pixman_region_not_empty((pixman_region16_t *)region); +} + +EAPI int +ecore_x_xregion_is_empty(Ecore_X_XRegion *r1, Ecore_X_XRegion *r2) +{ + if (!r1 || !r2) + return 0; + + return pixman_region_equal((pixman_region16_t *)r1, (pixman_region16_t *)r2); +} + +EAPI int +ecore_x_xregion_point_contain(Ecore_X_XRegion *region, int x, int y) +{ + if (!region) + return 0; + + return pixman_region_contains_point((pixman_region16_t *)region, x, y); +} + +EAPI int +ecore_x_xregion_rect_contain(Ecore_X_XRegion *region, Ecore_X_Rectangle *rect) +{ + pixman_box16_t box; + + if (!region || !rect) + return 0; + + box.x1 = rect->x; + box.y1 = rect->y; + box.x2 = rect->x + rect->width - 1; + box.y2 = rect->y + rect->height - 1; + + return pixman_region_contains_rectangle((pixman_region16_t *)region, &box); +} diff --git a/src/lib/ecore_x/xlib/Makefile.am b/src/lib/ecore_x/xlib/Makefile.am index e9cfbf3..da19a96 100644 --- a/src/lib/ecore_x/xlib/Makefile.am +++ b/src/lib/ecore_x/xlib/Makefile.am @@ -56,7 +56,8 @@ ecore_x_dpms.c \ ecore_x_drawable.c \ ecore_x_cursor.c \ ecore_x_test.c \ -ecore_x_atoms.c +ecore_x_atoms.c \ +ecore_x_region.c libecore_x_xlib_la_LIBADD = \ @Xcursor_libs@ \ diff --git a/src/lib/ecore_x/xlib/ecore_x_region.c b/src/lib/ecore_x/xlib/ecore_x_region.c new file mode 100644 index 0000000..69c7a8c --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_region.c @@ -0,0 +1,131 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "ecore_x_private.h" + + +/* + * [x] XCreateRegion + * [ ] XPolygonRegion + * [x] XSetRegion + * [x] XDestroyRegion + * + * [x] XOffsetRegion + * [ ] XShrinkRegion + * + * [ ] XClipBox + * [x] XIntersectRegion + * [x] XUnionRegion + * [x] XUnionRectWithRegion + * [x] XSubtractRegion + * [ ] XXorRegion + * + * [x] XEmptyRegion + * [x] XEqualRegion + * + * [x] XPointInRegion + * [x] XRectInRegion + */ + +EAPI Ecore_X_XRegion * +ecore_x_xregion_new() +{ + return (Ecore_X_XRegion *)XCreateRegion(); +} + +EAPI void +ecore_x_xregion_free(Ecore_X_XRegion *region) +{ + if (!region) + return; + + XDestroyRegion((Region)region); +} + +EAPI int +ecore_x_xregion_set(Ecore_X_XRegion *region, Ecore_X_GC gc) +{ + return XSetRegion(_ecore_x_disp, gc, (Region)region); +} + +EAPI void +ecore_x_xregion_translate(Ecore_X_XRegion *region, int x, int y) +{ + if (!region) + return; + + /* return value not used */ + XOffsetRegion((Region)region, x, y); +} + +EAPI int +ecore_x_xregion_intersect(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2) +{ + return XIntersectRegion((Region)r1, (Region)r2, (Region)dst); +} + +int +ecore_x_xregion_union(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2) +{ + return XUnionRegion((Region)r1, (Region)r2, (Region)dst); +} + +EAPI int +ecore_x_xregion_union_rect(Ecore_X_XRegion *dst, Ecore_X_XRegion *src, Ecore_X_Rectangle *rect) +{ + XRectangle xr; + + xr.x = rect->x; + xr.y = rect->y; + xr.width = rect->width; + xr.height = rect->height; + + return XUnionRectWithRegion(&xr, (Region)src, (Region)dst); +} + +EAPI int +ecore_x_xregion_subtract(Ecore_X_XRegion *dst, Ecore_X_XRegion *rm, Ecore_X_XRegion *rs) +{ + return XSubtractRegion((Region)rm, (Region)rs, (Region)dst); +} + +EAPI int +ecore_x_xregion_is_empty(Ecore_X_XRegion *region) +{ + if (!region) + return 1; + + return !XEmptyRegion((Region)region); +} + +EAPI int +ecore_x_xregion_is_equal(Ecore_X_XRegion *r1, Ecore_X_XRegion *r2) +{ + if (!r1 || !r2) + return 0; + + return XEqualRegion((Region)r1, (Region)r1); +} + +EAPI int +ecore_x_xregion_point_contain(Ecore_X_XRegion *region, int x, int y) +{ + if (!region) + return 0; + + return XPointInRegion((Region)region, x, y); +} + +EAPI int +ecore_x_xregion_rect_contain(Ecore_X_XRegion *region, Ecore_X_Rectangle *rect) +{ + if (!region || !rect) + return 0; + + return XRectInRegion((Region)region, rect->x, rect->y, rect->width, rect->height); +}