Add Region API to ecore_x (Xlib using Region and XCB using pixman).
authorcaro <caro@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 8 Jun 2009 06:34:20 +0000 (06:34 +0000)
committercaro <caro@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 8 Jun 2009 06:34:20 +0000 (06:34 +0000)
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

src/lib/ecore_evas/ecore_evas_private.h
src/lib/ecore_evas/ecore_evas_x.c
src/lib/ecore_x/Ecore_X.h
src/lib/ecore_x/xcb/Makefile.am
src/lib/ecore_x/xcb/ecore_xcb_region.c [new file with mode: 0644]
src/lib/ecore_x/xlib/Makefile.am
src/lib/ecore_x/xlib/ecore_x_region.c [new file with mode: 0644]

index a02e2c2..f2c9e6f 100644 (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;
index cfc4d57..7fe922c 100644 (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);
+       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)
      {
index 87fd8c0..1500b18 100644 (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);
index 5e46fb2..a9c110a 100644 (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 \
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 (file)
index 0000000..ec2847c
--- /dev/null
@@ -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);
+}
index e9cfbf3..da19a96 100644 (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@ \
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 (file)
index 0000000..69c7a8c
--- /dev/null
@@ -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);
+}