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


SVN revision: 40959
This commit is contained in:
Vincent Torri 2009-06-08 06:34:20 +00:00
parent 19ebe43a04
commit 20108eea57
7 changed files with 365 additions and 68 deletions

View File

@ -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;

View File

@ -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);
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;
/* 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_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;
*/
#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)
{

View File

@ -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);

View File

@ -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 \

View File

@ -0,0 +1,170 @@
/*
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#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);
}

View File

@ -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@ \

View File

@ -0,0 +1,131 @@
/*
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#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);
}