Enlightenment CVS committal

Author  : kwo
Project : e16
Module  : e

Dir     : e16/e/src


Modified Files:
        ecompmgr.c 


Log Message:
Fix composite repaint, taking opaque window clipping into account.
===================================================================
RCS file: /cvsroot/enlightenment/e16/e/src/ecompmgr.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -3 -r1.4 -r1.5
--- ecompmgr.c  4 Jan 2005 19:20:09 -0000       1.4
+++ ecompmgr.c  11 Jan 2005 22:58:39 -0000      1.5
@@ -110,6 +110,8 @@
 
 struct _ecmwininfo
 {
+   EObj               *next;   /* Paint order */
+   EObj               *prev;   /* Paint order */
 #if HAS_NAME_WINDOW_PIXMAP
    Pixmap              pixmap;
 #endif
@@ -127,6 +129,7 @@
    Picture             alphaPict;
    XserverRegion       borderSize;
    XserverRegion       extents;
+   XserverRegion       clip;
 #if ENABLE_SHADOWS
    Picture             shadowPict;
    Picture             shadow;
@@ -138,9 +141,6 @@
    unsigned int        opacity;
 
    unsigned long       damage_sequence;        /* sequence when damage was 
created */
-
-   /* for drawing translucent windows */
-   XserverRegion       borderClip;
 };
 
 #if ENABLE_SHADOWS
@@ -170,6 +170,8 @@
 #if HAS_NAME_WINDOW_PIXMAP
    char                have_name_pixmap;
 #endif
+   EObj               *eo_first;
+   EObj               *eo_last;
 } Mode_compmgr;
 
 static Picture      rootPicture;
@@ -727,9 +729,10 @@
    unsigned char       d;
    int                 x_diff;
 
-   data = malloc(swidth * sheight * sizeof(unsigned char));
+   data = calloc(swidth * sheight, sizeof(unsigned char));
    if (!data)
-      return 0;
+      return NULL;
+
    ximage = XCreateImage(dpy, DefaultVisual(dpy, DefaultScreen(dpy)),
                         8, ZPixmap, 0,
                         (char *)data,
@@ -737,18 +740,21 @@
    if (!ximage)
      {
        free(data);
-       return 0;
+       return NULL;
      }
+
    /*
     * Build the gaussian in sections
     */
 
+#if 0                          /* Never used */
    /*
     * center (fill the complete data array)
     */
 
    d = sum_gaussian(gaussianMap, opacity, center, center, width, height);
    memset(data, d, sheight * swidth);
+#endif
 
    /*
     * corners
@@ -990,11 +996,13 @@
        w->alphaPict = None;
      }
 
-   if ((what & INV_SIZE) && w->borderClip != None)
+#if 0                          /* Recalculating clip every repaint for now. */
+   if ((what & INV_SIZE) && w->clip != None)
      {
-       XFixesDestroyRegion(dpy, w->borderClip);
-       w->borderClip = None;
+       XFixesDestroyRegion(dpy, w->clip);
+       w->clip = None;
      }
+#endif
 
 #if ENABLE_SHADOWS
    if ((what & (INV_SIZE | INV_OPACITY | INV_SHADOW)) && w->shadow != None)
@@ -1224,6 +1232,7 @@
    w->alphaPict = None;
    w->borderSize = None;
    w->extents = None;
+   w->clip = None;
 #if ENABLE_SHADOWS
    w->shadowPict = None;
    w->shadow = None;
@@ -1233,8 +1242,6 @@
    w->shadow_height = 0;
 #endif
 
-   w->borderClip = None;
-
 #if 0
    /* moved mode setting to one place */
    ESelectInputAdd(disp, eo->win,
@@ -1488,33 +1495,73 @@
 }
 
 static void
-ECompMgrRepaintObj(Picture pbuf, EObj * eo)
+ECompMgrRepaintDetermineOrder(void)
 {
-   Display            *dpy = disp;
+   EObj               *const *lst, *eo, *eo_prev, *eo_first;
+   int                 i, num;
    ECmWinInfo         *w;
 
-   /* Atm we first hook up when mapped */
-   /* Maybe do it at init/create? */
-   if (!eo->cmhook)
-      return;
-   w = eo->cmhook;
+#if 0
+   lst = EobjListStackGet(&num);
+#else
+   lst = EobjListStackGetForDesk(&num, 0 /*desk */ );
+#endif
 
-   if (!w->visible)
-      return;
+   /* Determine overall paint order, top to bottom */
+   eo_first = eo_prev = NULL;
+
+   for (i = 0; i < num; i++)
+     {
+       eo = lst[i];
+       if (!eo->cmhook)
+          continue;
+       w = eo->cmhook;
+
+       if (!w->visible)
+          continue;
 #if CAN_DO_USABLE
-   if (!w->usable)
-      return;
+       if (!w->usable)
+          continue;
 #endif
-   if (!w->damaged)
-      return;
-   if (!w->picture)
-      return;
+       if (!w->damaged)
+          continue;
+       if (!w->picture)
+          continue;
+
+       if (!eo_first)
+          eo_first = eo;
+       w->prev = eo_prev;
+       if (eo_prev)
+          ((ECmWinInfo *) (eo_prev->cmhook))->next = eo;
+       eo_prev = eo;
+
+#if 0
+       /*  FIXME - We should break when the repaint region (w->clip) becomes 
empty */
+       if (eo->type == EOBJ_TYPE_DESK && eo->x == 0 && eo->y == 0)
+          break;
+#endif
+     }
+   if (eo_prev)
+      ((ECmWinInfo *) (eo_prev->cmhook))->next = NULL;
+
+   Mode_compmgr.eo_first = eo_first;
+   Mode_compmgr.eo_last = eo_prev;
+}
+
+static void
+ECompMgrRepaintObj(Picture pbuf, XserverRegion region, EObj * eo, int mode)
+{
+   Display            *dpy = disp;
+   ECmWinInfo         *w;
+
+   w = eo->cmhook;
 
 #if 0
    ECompMgrWinSetPicts(eo);
 #endif
 
-   D2printf("ECompMgrRepaintObj %#lx %d %#lx\n", eo->win, w->mode, w->picture);
+   D2printf("ECompMgrRepaintObj %d %#lx %d %#lx\n", mode, eo->win, w->mode,
+           w->picture);
 
    /* Region of shaped window in screen coordinates */
    if (!w->borderSize)
@@ -1522,74 +1569,79 @@
    if (EventDebug(EDBUG_TYPE_COMPMGR3))
       ERegionShow("Window borderSize", w->borderSize);
 
-   /* Region of window in screen coordinates */
+   /* Region of window in screen coordinates, including shadows */
    if (!w->extents)
       w->extents = win_extents(dpy, eo);
    if (EventDebug(EDBUG_TYPE_COMPMGR3))
       ERegionShow("Window extents", w->extents);
 
-#if 0
-   if (!w->borderClip)
+   if (mode == 0)
      {
-       w->borderClip = XFixesCreateRegion(dpy, 0, 0);
-       XFixesCopyRegion(dpy, w->borderClip, region);
+       /* Painting opaque windows top down, updating clip regions. */
+
+       w->clip = XFixesCreateRegion(dpy, 0, 0);
+       XFixesCopyRegion(dpy, w->clip, region);
+
+       switch (w->mode)
+         {
+         case WINDOW_SOLID:
+            XFixesSetPictureClipRegion(dpy, pbuf, 0, 0, region);
+            XFixesSubtractRegion(dpy, region, region, w->borderSize);
+            XRenderComposite(dpy, PictOpSrc, w->picture, None, pbuf,
+                             0, 0, 0, 0, w->rcx, w->rcy, w->rcw, w->rch);
+            break;
+         }
      }
-   XFixesSetPictureClipRegion(dpy, pbuf, 0, 0, w->borderClip);
-#endif
+   else
+     {
+       /* Painting trans stuff bottom up. */
+
+       switch (w->mode)
+         {
+         case WINDOW_TRANS:
+         case WINDOW_ARGB:
+            XFixesSetPictureClipRegion(dpy, pbuf, 0, 0, w->clip);
+            ECompMgrCheckAlphaMask(w);
+            XRenderComposite(dpy, PictOpOver, w->picture, w->alphaPict, pbuf,
+                             0, 0, 0, 0, w->rcx, w->rcy, w->rcw, w->rch);
+            break;
+         }
 
 #if ENABLE_SHADOWS
-   switch (Conf_compmgr.shadow)
-     {
-     case ECM_SHADOWS_OFF:
-       break;
-     case ECM_SHADOWS_SHARP:
-       if (w->opacity != OPAQUE && !w->shadowPict)
-          w->shadowPict = EPictureCreateSolid(True,
-                                              (double)w->opacity /
-                                              OPAQUE * 0.3, 0, 0, 0);
-       XRenderComposite(dpy, PictOpOver,
-                        w->shadowPict ? w->shadowPict : transBlackPicture,
-                        w->picture, pbuf, 0, 0, 0, 0,
-                        w->a.x + w->shadow_dx, w->a.y + w->shadow_dy,
-                        w->shadow_width, w->shadow_height);
-       break;
-     case ECM_SHADOWS_BLURRED:
-       if (w->shadow)
+       switch (Conf_compmgr.shadow)
          {
-            XRenderComposite(dpy, PictOpOver, blackPicture, w->shadow,
-                             pbuf, 0, 0, 0, 0,
+         case ECM_SHADOWS_OFF:
+            break;
+         case ECM_SHADOWS_SHARP:
+            if (w->opacity != OPAQUE && !w->shadowPict)
+               w->shadowPict = EPictureCreateSolid(True,
+                                                   (double)w->opacity /
+                                                   OPAQUE * 0.3, 0, 0, 0);
+            XFixesSubtractRegion(dpy, w->clip, w->clip, w->borderSize);
+            XFixesSetPictureClipRegion(dpy, pbuf, 0, 0, w->clip);
+            XRenderComposite(dpy, PictOpOver,
+                             w->shadowPict ? w->shadowPict : transBlackPicture,
+                             w->picture, pbuf, 0, 0, 0, 0,
                              w->a.x + w->shadow_dx, w->a.y + w->shadow_dy,
                              w->shadow_width, w->shadow_height);
+            break;
+         case ECM_SHADOWS_BLURRED:
+            if (w->shadow)
+              {
+                 XFixesSubtractRegion(dpy, w->clip, w->clip, w->borderSize);
+                 XFixesSetPictureClipRegion(dpy, pbuf, 0, 0, w->clip);
+                 XRenderComposite(dpy, PictOpOver, blackPicture, w->shadow,
+                                  pbuf, 0, 0, 0, 0,
+                                  w->a.x + w->shadow_dx, w->a.y + w->shadow_dy,
+                                  w->shadow_width, w->shadow_height);
+              }
+            break;
          }
-       break;
-     }
 #endif
 
-   switch (w->mode)
-     {
-     default:
-     case WINDOW_SOLID:
-#if 0
-       XFixesSetPictureClipRegion(dpy, pbuf, 0, 0, region);
-       XFixesSubtractRegion(dpy, region, region, w->borderSize);
-#endif
-       XRenderComposite(dpy, PictOpSrc, w->picture, None, pbuf,
-                        0, 0, 0, 0, w->rcx, w->rcy, w->rcw, w->rch);
-     case WINDOW_TRANS:
-       ECompMgrCheckAlphaMask(w);
-       XRenderComposite(dpy, PictOpOver, w->picture, w->alphaPict, pbuf,
-                        0, 0, 0, 0, w->rcx, w->rcy, w->rcw, w->rch);
-       break;
-     case WINDOW_ARGB:
-       ECompMgrCheckAlphaMask(w);
-       XRenderComposite(dpy, PictOpOver, w->picture, w->alphaPict, pbuf,
-                        0, 0, 0, 0, w->rcx, w->rcy, w->rcw, w->rch);
-       break;
+       XFixesDestroyRegion(dpy, w->clip);
+       w->clip = None;
      }
-#if 0
-   XFixesDestroyRegion(dpy, w->borderClip);
-   w->borderClip = None;
-#endif
 }
 
 static void
@@ -1597,8 +1649,7 @@
 {
    Display            *dpy = disp;
    XserverRegion       region = allDamage;
-   EObj               *const *lst, *eo;
-   int                 i, num;
+   EObj               *eo;
    Picture             pict, pbuf;
 
    D2printf("ECompMgrRepaint rootBuffer=%#lx rootPicture=%#lx\n",
@@ -1611,26 +1662,24 @@
                                        VRoot.depth, VRoot.vis);
    pbuf = rootBuffer;
 
-   XFixesSetPictureClipRegion(dpy, pbuf, 0, 0, region);
-
    /* Draw desktop background picture */
    pict = DeskBackgroundPictureGet(0);
    D1printf("ECompMgrRepaint desk picture=%#lx\n", pict);
+   XFixesSetPictureClipRegion(dpy, pbuf, 0, 0, region);
    XRenderComposite(dpy, PictOpSrc, pict, None, pbuf,
                    0, 0, 0, 0, 0, 0, VRoot.w, VRoot.h);
 
-#if 1
-   lst = EobjListStackGetForDesk(&num, 0 /*desk */ );
-#else
-   lst = EobjListStackGet(&num);
-#endif
+   /* Do paint order list linking */
+   ECompMgrRepaintDetermineOrder();
 
-   /* Normal objects */
-   for (i = num - 1; i >= 0; i--)
-     {
-       eo = lst[i];
-       ECompMgrRepaintObj(pbuf, eo);
-     }
+   /* Paint opaque windows top down, adjusting clip regions */
+   for (eo = Mode_compmgr.eo_first; eo;
+       eo = ((ECmWinInfo *) (eo->cmhook))->next)
+      ECompMgrRepaintObj(pbuf, region, eo, 0);
+
+   /* Paint trans windows and shadows bottom up */
+   for (eo = Mode_compmgr.eo_last; eo; eo = ((ECmWinInfo *) 
(eo->cmhook))->prev)
+      ECompMgrRepaintObj(pbuf, None, eo, 1);
 
    if (pbuf != rootPicture)
      {




-------------------------------------------------------
The SF.Net email is sponsored by: Beat the post-holiday blues
Get a FREE limited edition SourceForge.net t-shirt from ThinkGeek.
It's fun and FREE -- well, almost....http://www.thinkgeek.com/sfshirt
_______________________________________________
enlightenment-cvs mailing list
enlightenment-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to