Enlightenment CVS committal

Author  : kwo
Project : e16
Module  : e

Dir     : e16/e/src


Modified Files:
      Tag: branch-exp
        desktops.c ecompmgr.c events.c ewin-ops.c misc.c mod-desks.c 
        pager.c startup.c 


Log Message:
Rewrite composite manager (unfinished). Enable shadows.
===================================================================
RCS file: /cvsroot/enlightenment/e16/e/src/desktops.c,v
retrieving revision 1.95.2.23
retrieving revision 1.95.2.24
diff -u -3 -r1.95.2.23 -r1.95.2.24
--- desktops.c  23 Oct 2004 14:23:38 -0000      1.95.2.23
+++ desktops.c  25 Oct 2004 22:14:19 -0000      1.95.2.24
@@ -686,7 +686,7 @@
    if (desks.desk[desk].viewable)
       RefreshDesktop(desk);
 
-   ModulesSignal(ESIGNAL_BACKGROUND_CHANGE, bg);
+   ModulesSignal(ESIGNAL_BACKGROUND_CHANGE, (void *)desk);
 
    EDBUG_RETURN_;
 }
===================================================================
RCS file: /cvsroot/enlightenment/e16/e/src/Attic/ecompmgr.c,v
retrieving revision 1.1.2.3
retrieving revision 1.1.2.4
diff -u -3 -r1.1.2.3 -r1.1.2.4
--- ecompmgr.c  20 Oct 2004 21:04:06 -0000      1.1.2.3
+++ ecompmgr.c  25 Oct 2004 22:14:21 -0000      1.1.2.4
@@ -23,7 +23,7 @@
 
 /* >>> Original copyright notice begin <<< */
 /*
- * $Id: ecompmgr.c,v 1.1.2.1 2004/09/26 20:09:50 kwo Exp $
+ * $Id: xcompmgr.c,v 1.26 2004/08/14 21:39:51 keithp Exp $
  *
  * Copyright © 2003 Keith Packard
  *
@@ -81,14 +81,15 @@
 
 #define USE_MOSTLY_ROOT_EVENTS 1
 
-#define ENABLE_SHADOWS 0
+#define ENABLE_SHADOWS 1
 #define ENABLE_FADING  0
 
 #define ENABLE_DEBUG   1
 
 #if ENABLE_DEBUG
-#define EDBUG_TYPE_COMPMGR  160
-#define EDBUG_TYPE_COMPMGR2 161
+#define EDBUG_TYPE_COMPMGR  161
+#define EDBUG_TYPE_COMPMGR2 162
+#define EDBUG_TYPE_COMPMGR3 163
 #define D1printf(fmt...) if(EventDebug(EDBUG_TYPE_COMPMGR))Eprintf(fmt)
 #define D2printf(fmt...) if(EventDebug(EDBUG_TYPE_COMPMGR2))Eprintf(fmt)
 #else
@@ -97,7 +98,6 @@
 #endif /* ENABLE_DEBUG */
 
 #define DEBUG_EVENTS 0
-#define MONITOR_REPAINT 0
 
 #define set_ignore(dpy, seq)
 
@@ -113,6 +113,7 @@
    Pixmap              pixmap;
 #endif
    XWindowAttributes   a;
+   int                 rcx, rcy, rcw, rch;
 #if CAN_DO_USABLE
    Bool                usable; /* mapped and all damaged at one point */
    XRectangle          damage_bounds;  /* bounds of damage */
@@ -141,12 +142,28 @@
    struct _Win        *prev_trans;
 } Win;
 
+#if ENABLE_SHADOWS
+typedef enum _compMode
+{
+   CompSimple,                 /* looks like a regular X server */
+   CompServerShadows,          /* use window alpha for shadow; sharp, but precise */
+   CompClientShadows,          /* use window extents for shadow, blurred */
+} CompMode;
+#endif
+
 static struct
 {
-   char                enable;
-   char                autoredirect;
+   int                 mode;
+#if ENABLE_SHADOWS
+   int                 shadow;
+#endif
 } Conf_compmgr;
 
+#define ECOMPMGR_MODE_OFF      0
+#define ECOMPMGR_MODE_ROOT     1
+#define ECOMPMGR_MODE_WINDOW   2
+#define ECOMPMGR_MODE_AUTO     3
+
 static struct
 {
    char                active;
@@ -157,8 +174,8 @@
 static Picture      rootPicture;
 static Picture      rootBuffer;
 
-static Picture      rootTile = None;
 static XserverRegion allDamage;
+
 static Bool         clipChanged;
 
 #if HAS_NAME_WINDOW_PIXMAP
@@ -174,9 +191,209 @@
 
 #define TRANS_OPACITY  0.75
 
-static void         determine_mode(Display * dpy, Win * w);
+static void         restack_win(Win * w, Window new_above);
+static void         ECompMgrDamageMerge(XserverRegion damage, int destroy);
+
+static void
+ESelectInputAdd(Display * dpy, Window win, long mask)
+{
+   XWindowAttributes   xwa;
+
+   XGetWindowAttributes(dpy, win, &xwa);
+   xwa.your_event_mask |= mask;
+   XSelectInput(dpy, win, xwa.your_event_mask);
+}
+
+/*
+ * Regions
+ */
+
+static              XserverRegion
+ERegionCreate(int x, int y, int w, int h)
+{
+   XserverRegion       rgn;
+   XRectangle          rct;
+
+   rct.x = x;
+   rct.y = y;
+   rct.width = w;
+   rct.height = h;
+   rgn = XFixesCreateRegion(disp, &rct, 1);
+
+   return rgn;
+}
+
+static void
+ERegionShow(const char *txt, XserverRegion rgn)
+{
+   int                 i, nr;
+   XRectangle         *pr;
+
+   pr = XFixesFetchRegion(disp, rgn, &nr);
+   if (!pr)
+      return;
+
+   Eprintf("ERegionShow: %s %#lx:\n", txt, rgn);
+   for (i = 0; i < nr; i++)
+      Eprintf("%4d: %4d+%4d %4dx%4d\n", i, pr[i].x, pr[i].y, pr[i].width,
+             pr[i].height);
+
+   XFree(pr);
+}
+
+/*
+ * Pictures
+ */
+
+static              Picture
+EPictureCreateSolid(Bool argb, double a, double r, double g, double b)
+{
+   Display            *dpy = disp;
+   Pixmap              pmap;
+   Picture             pict;
+   XRenderPictFormat  *pictfmt;
+   XRenderPictureAttributes pa;
+   XRenderColor        c;
+
+   pmap = XCreatePixmap(dpy, VRoot.win, 1, 1, argb ? 32 : 8);
+   pictfmt = XRenderFindStandardFormat(dpy,
+                                      argb ? PictStandardARGB32 :
+                                      PictStandardA8);
+   pa.repeat = True;
+   pict = XRenderCreatePicture(dpy, pmap, pictfmt, CPRepeat, &pa);
+
+   c.alpha = a * 0xffff;
+   c.red = r * 0xffff;
+   c.green = g * 0xffff;
+   c.blue = b * 0xffff;
+   XRenderFillRectangle(dpy, PictOpSrc, pict, &c, 0, 0, 1, 1);
+
+   XFreePixmap(dpy, pmap);
+
+   return pict;
+}
+
+static              Picture
+EPictureCreateBuffer(Window win, int w, int h, int depth, Visual * vis)
+{
+   Display            *dpy = disp;
+   Picture             pict;
+   Pixmap              pmap;
+   XRenderPictFormat  *pictfmt;
+
+   pmap = XCreatePixmap(dpy, win, w, h, depth);
+   pictfmt = XRenderFindVisualFormat(dpy, vis);
+   pict = XRenderCreatePicture(dpy, pmap, pictfmt, 0, 0);
+   XFreePixmap(dpy, pmap);
+
+   return pict;
+}
+
+/*
+ * Desktops (move to desktops.c?)
+ */
+typedef struct
+{
+   Picture             bgpict; /* The background picture */
+} EcmDeskInfo;
+
+static EcmDeskInfo  desks[32];
+
+static              Picture
+DeskBackgroundPictureGet(int desk)
+{
+   Picture             pict;
+   Pixmap              pmap;
+   Bool                fill;
+   XRenderPictFormat  *pictfmt;
+   XRenderPictureAttributes pa;
+
+   pict = desks[desk].bgpict;
+   if (pict != None)
+      return pict;
+
+   fill = False;
+   pmap = BackgroundGetPixmap(DeskGetBackground(desk));
+   D1printf("DeskBackgroundPictureGet: Desk %d: using pixmap %#lx\n", desk,
+           pmap);
+   if (!pmap)
+     {
+       pmap = XCreatePixmap(disp, VRoot.win, 1, 1, VRoot.depth);
+       fill = True;
+     }
+
+   pa.repeat = True;
+   pictfmt = XRenderFindVisualFormat(disp, VRoot.vis);
+   pict = XRenderCreatePicture(disp, pmap, pictfmt, CPRepeat, &pa);
+
+   if (fill)
+     {
+       /* FIXME - use desk bg color */
+       XRenderColor        c;
+
+       c.red = c.green = c.blue = 0x8080;
+       c.alpha = 0xffff;
+       XRenderFillRectangle(disp, PictOpSrc, pict, &c, 0, 0, 1, 1);
+     }
+
+#if xHAS_NAME_WINDOW_PIXMAP    /* Do this? */
+   if (hasNamePixmap)
+     {
+       pmap = XCompositeNameWindowPixmap(dpy, id);
+       desks[desk].bgpmap = pmap;
+     }
+#endif
+
+   /* New background, all must be repainted */
+   ECompMgrDamageMerge(ERegionCreate(0, 0, VRoot.w, VRoot.h), 1);
+
+   desks[desk].bgpict = pict;
+}
+
+static void
+DeskBackgroundPictureFree(int desk)
+{
+   Picture             pict;
+
+   pict = desks[desk].bgpict;
+   if (pict == None)
+      return;
+
+   XClearArea(disp, DeskGetWin(desk), 0, 0, 0, 0, True);
+   XRenderFreePicture(disp, pict);
+
+   desks[desk].bgpict = None;
+}
+
+/*
+ * Root (?)
+ */
+
+static void
+ECompMgrDamageMerge(XserverRegion damage, int destroy)
+{
+   if (allDamage)
+     {
+       if (EventDebug(EDBUG_TYPE_COMPMGR3))
+          ERegionShow("ECompMgrDamageMerge add:", damage);
+
+       XFixesUnionRegion(disp, allDamage, allDamage, damage);
+       if (destroy)
+          XFixesDestroyRegion(disp, damage);
+     }
+   else if (!destroy)
+     {
+       allDamage = XFixesCreateRegion(disp, 0, 0);
+       XFixesCopyRegion(disp, allDamage, damage);
+     }
+   else
+     {
+       allDamage = damage;
+     }
 
-Bool                autoRedirect = False;
+   if (EventDebug(EDBUG_TYPE_COMPMGR3))
+      ERegionShow("ECompMgrDamageMerge all:", allDamage);
+}
 
 #if ENABLE_FADING
 
@@ -278,11 +495,8 @@
       f->step = -fade_step;
    f->callback = callback;
    f->gone = gone;
-   w->opacity = f->cur * OPAQUE;
-#if 0
-   printf("set_fade start %g step %g\n", f->cur, f->step);
-#endif
-   determine_mode(dpy, w);
+
+   ECompMgrWinChangeOpacity(w, f->cur * OPAQUE);
 }
 
 static int
@@ -324,10 +538,7 @@
           f->cur = 1;
        else if (f->cur < 0)
           f->cur = 0;
-#if 0
-       printf("opacity now %g\n", f->cur);
-#endif
-       w->opacity = f->cur * OPAQUE;
+
        if (f->step > 0)
          {
             if (f->cur >= 1)
@@ -338,7 +549,8 @@
             if (f->cur <= 0)
                dequeue_fade(dpy, f);
          }
-       determine_mode(dpy, w);
+
+       ECompMgrWinChangeOpacity(w, f->cur * OPAQUE);
      }
    fade_time = now + fade_delta;
 }
@@ -365,15 +577,6 @@
 #define SHADOWS                1
 #define SHARP_SHADOW   0
 
-typedef enum _compMode
-{
-   CompSimple,                 /* looks like a regular X server */
-   CompServerShadows,          /* use window alpha for shadow; sharp, but precise */
-   CompClientShadows,          /* use window extents for shadow, blurred */
-} CompMode;
-
-CompMode            compMode = CompSimple;
-
 int                 shadowRadius = 12;
 
 static double
@@ -585,6 +788,7 @@
    shadowImage = make_shadow(dpy, opacity, width, height);
    if (!shadowImage)
       return None;
+
    shadowPixmap = XCreatePixmap(dpy, VRoot.win,
                                shadowImage->width, shadowImage->height, 8);
    shadowPicture = XRenderCreatePicture(dpy, shadowPixmap,
@@ -600,100 +804,15 @@
    XFreeGC(dpy, gc);
    XDestroyImage(shadowImage);
    XFreePixmap(dpy, shadowPixmap);
+
    return shadowPicture;
 }
 
 #endif /* ENABLE_SHADOWS */
 
-static void
-ESelectInputAdd(Display * dpy, Window win, long mask)
-{
-   XWindowAttributes   xwa;
-
-   XGetWindowAttributes(dpy, win, &xwa);
-   xwa.your_event_mask |= mask;
-   XSelectInput(dpy, win, xwa.your_event_mask);
-}
-
-static              Picture
-solid_picture(Display * dpy, Bool argb, double a, double r, double g, double b)
-{
-   Pixmap              pixmap;
-   Picture             picture;
-   XRenderPictureAttributes pa;
-   XRenderColor        c;
-
-   pixmap = XCreatePixmap(dpy, VRoot.win, 1, 1, argb ? 32 : 8);
-   pa.repeat = True;
-   picture = XRenderCreatePicture(dpy, pixmap,
-                                 XRenderFindStandardFormat(dpy,
-                                                           argb ?
-                                                           PictStandardARGB32 :
-                                                           PictStandardA8),
-                                 CPRepeat, &pa);
-   c.alpha = a * 0xffff;
-   c.red = r * 0xffff;
-   c.green = g * 0xffff;
-   c.blue = b * 0xffff;
-   XRenderFillRectangle(dpy, PictOpSrc, picture, &c, 0, 0, 1, 1);
-   XFreePixmap(dpy, pixmap);
-   return picture;
-}
-
-static void
-ECompMgrRootInit(int init)
-{
-   Picture             picture;
-   Pixmap              pixmap;
-   Bool                fill;
-   XRenderPictFormat  *pictfmt;
-   XRenderPictureAttributes pa;
-
-   if (rootTile)
-     {
-       XClearArea(disp, VRoot.win, 0, 0, 0, 0, True);
-       XRenderFreePicture(disp, rootTile);
-       rootTile = None;
-       if (!init)
-          return;
-     }
-
-   fill = False;
-   pixmap = BackgroundGetPixmap(DeskGetBackground(0));
-   if (!pixmap)
-     {
-       pixmap = XCreatePixmap(disp, VRoot.win, 1, 1, VRoot.depth);
-       fill = True;
-     }
-
-   pa.repeat = True;
-   pictfmt = XRenderFindVisualFormat(disp, VRoot.vis);
-   picture = XRenderCreatePicture(disp, pixmap, pictfmt, CPRepeat, &pa);
-
-   if (fill)
-     {
-       /* FIXME - use bg color */
-       XRenderColor        c;
-
-       c.red = c.green = c.blue = 0x8080;
-       c.alpha = 0xffff;
-       XRenderFillRectangle(disp, PictOpSrc, picture, &c, 0, 0, 1, 1);
-     }
-
-   rootTile = picture;
-}
-
-static void
-paint_root(Display * dpy)
-{
-   if (!rootTile)
-      ECompMgrRootInit(1);
-
-   D1printf("paint_root rootTile=%#lx\n", rootTile);
-   XRenderComposite(dpy, PictOpSrc,
-                   rootTile, None, rootBuffer,
-                   0, 0, 0, 0, 0, 0, VRoot.w, VRoot.h);
-}
+/*
+ * Window ops
+ */
 
 static              XserverRegion
 win_extents(Display * dpy, Win * w)
@@ -706,59 +825,61 @@
    r.height = w->a.height + w->a.border_width * 2;
 
 #if ENABLE_SHADOWS
-   if (compMode != CompSimple)
+   if (Conf_compmgr.shadow != CompSimple &&
+       (Conf_compmgr.shadow == CompServerShadows || w->mode != WINDOW_ARGB))
      {
-       if (compMode == CompServerShadows || w->mode != WINDOW_ARGB)
-         {
-            XRectangle          sr;
+       XRectangle          sr;
 
-            if (compMode == CompServerShadows)
-              {
-                 w->shadow_dx = 2;
-                 w->shadow_dy = 7;
-                 w->shadow_width = w->a.width;
-                 w->shadow_height = w->a.height;
-              }
-            else
-              {
-                 w->shadow_dx = SHADOW_OFFSET_X;
-                 w->shadow_dy = SHADOW_OFFSET_Y;
-                 if (!w->shadow)
-                   {
-                      double              opacity = SHADOW_OPACITY;
-
-                      if (w->mode == WINDOW_TRANS)
-                         opacity = opacity * TRANS_OPACITY;
-                      w->shadow = shadow_picture(dpy, opacity,
-                                                 w->a.width +
-                                                 w->a.border_width * 2,
-                                                 w->a.height +
-                                                 w->a.border_width * 2,
-                                                 &w->shadow_width,
-                                                 &w->shadow_height);
-                   }
-              }
-            sr.x = w->a.x + w->shadow_dx;
-            sr.y = w->a.y + w->shadow_dy;
-            sr.width = w->shadow_width;
-            sr.height = w->shadow_height;
-            if (sr.x < r.x)
-              {
-                 r.width = (r.x + r.width) - sr.x;
-                 r.x = sr.x;
-              }
-            if (sr.y < r.y)
+       if (Conf_compmgr.shadow == CompServerShadows)
+         {
+            w->shadow_dx = 2;
+            w->shadow_dy = 7;
+            w->shadow_width = w->a.width;
+            w->shadow_height = w->a.height;
+         }
+       else
+         {
+            w->shadow_dx = SHADOW_OFFSET_X;
+            w->shadow_dy = SHADOW_OFFSET_Y;
+            if (!w->shadow)
               {
-                 r.height = (r.y + r.height) - sr.y;
-                 r.y = sr.y;
+                 double              opacity = SHADOW_OPACITY;
+
+                 if (w->mode == WINDOW_TRANS)
+                    opacity = opacity * TRANS_OPACITY;
+                 w->shadow = shadow_picture(dpy, opacity,
+                                            w->a.width +
+                                            w->a.border_width * 2,
+                                            w->a.height +
+                                            w->a.border_width * 2,
+                                            &w->shadow_width,
+                                            &w->shadow_height);
               }
-            if (sr.x + sr.width > r.x + r.width)
-               r.width = sr.x + sr.width - r.x;
-            if (sr.y + sr.height > r.y + r.height)
-               r.height = sr.y + sr.height - r.y;
          }
+       sr.x = w->a.x + w->shadow_dx;
+       sr.y = w->a.y + w->shadow_dy;
+       sr.width = w->shadow_width;
+       sr.height = w->shadow_height;
+       if (sr.x < r.x)
+         {
+            r.width = (r.x + r.width) - sr.x;
+            r.x = sr.x;
+         }
+       if (sr.y < r.y)
+         {
+            r.height = (r.y + r.height) - sr.y;
+            r.y = sr.y;
+         }
+       if (sr.x + sr.width > r.x + r.width)
+          r.width = sr.x + sr.width - r.x;
+       if (sr.y + sr.height > r.y + r.height)
+          r.height = sr.y + sr.height - r.y;
      }
 #endif
+
+   D2printf("win_extents %#lx %d %d %d %d\n", w->id, r.x, r.y, r.width,
+           r.height);
+
    return XFixesCreateRegion(dpy, &r, 1);
 }
 
@@ -767,287 +888,115 @@
 {
    XserverRegion       border;
 
-   /*
-    * if window doesn't exist anymore,  this will generate an error
-    * as well as not generate a region.  Perhaps a better XFixes
-    * architecture would be to have a request that copies instead
-    * of creates, that way you'd just end up with an empty region
-    * instead of an invalid XID.
-    */
    set_ignore(dpy, NextRequest(dpy));
    border = XFixesCreateRegionFromWindow(dpy, w->id, WindowRegionBounding);
+
    /* translate this */
    set_ignore(dpy, NextRequest(dpy));
    XFixesTranslateRegion(dpy, border,
                         w->a.x + w->a.border_width,
                         w->a.y + w->a.border_width);
+
+   D2printf("border_size %#lx: %d %d\n",
+           w->id, w->a.x + w->a.border_width, w->a.y + w->a.border_width);
+
    return border;
 }
 
+/* pixmap picture borderSize shadowPict borderClip - alphaPict */
 static void
-paint_all(Display * dpy, XserverRegion region)
+ECompMgrWinInvalidateSize(ECmWinInfo * w)
 {
-   Win                *w;
-   Win                *t = 0;
-   XRenderPictFormat  *pictfmt;
+   Display            *dpy = disp;
 
-   D2printf("paint_all %#lx\n", region);
-   if (!region)
+#if HAS_NAME_WINDOW_PIXMAP
+   if (w->pixmap != None)
      {
-       XRectangle          r;
-
-       r.x = 0;
-       r.y = 0;
-       r.width = VRoot.w;
-       r.height = VRoot.h;
-       region = XFixesCreateRegion(dpy, &r, 1);
+       XFreePixmap(dpy, w->pixmap);
+       w->pixmap = None;
      }
+#endif
 
-#if MONITOR_REPAINT
-   rootBuffer = rootPicture;
-#else
-   if (!rootBuffer)
+   if (w->picture != None)
      {
-       Pixmap              rootPixmap;
-
-       rootPixmap =
-          XCreatePixmap(dpy, VRoot.win, VRoot.w, VRoot.h, VRoot.depth);
+       set_ignore(dpy, NextRequest(dpy));
+       XRenderFreePicture(dpy, w->picture);
+       w->picture = None;
+     }
 
-       pictfmt = XRenderFindVisualFormat(disp, VRoot.vis);
-       rootBuffer = XRenderCreatePicture(dpy, rootPixmap, pictfmt, 0, 0);
-       XFreePixmap(dpy, rootPixmap);
+   if (w->borderSize != None)
+     {
+       set_ignore(dpy, NextRequest(dpy));
+       XFixesDestroyRegion(dpy, w->borderSize);
+       w->borderSize = None;
      }
-#endif
 
-   XFixesSetPictureClipRegion(dpy, rootPicture, 0, 0, region);
-#if MONITOR_REPAINT
-   XRenderComposite(dpy, PictOpSrc, blackPicture, None, rootPicture,
-                   0, 0, 0, 0, 0, 0, VRoot.w, VRoot.h);
+#if ENABLE_SHADOWS
+   if (w->shadowPict != None)
+     {
+       XRenderFreePicture(dpy, w->shadow);
+       w->shadow = None;
+     }
 #endif
 
-   for (w = list; w; w = w->next)
+   if (w->borderClip != None)
      {
-#if CAN_DO_USABLE
-       if (!w->usable)
-          continue;
-#endif
-       /* never painted, ignore it */
-       if (!w->damaged)
-          continue;
-
-       if (!w->picture)
-         {
-            XRenderPictureAttributes pa;
-            XRenderPictFormat  *format;
-            Drawable            draw = w->id;
-
-#if HAS_NAME_WINDOW_PIXMAP
-            if (hasNamePixmap && !w->pixmap)
-               w->pixmap = XCompositeNameWindowPixmap(dpy, w->id);
-            if (w->pixmap)
-               draw = w->pixmap;
-#endif
-            format = XRenderFindVisualFormat(dpy, w->a.visual);
-            pa.subwindow_mode = IncludeInferiors;
-            w->picture = XRenderCreatePicture(dpy, draw,
-                                              format, CPSubwindowMode, &pa);
-         }
-
-       D2printf("paint %#lx %d %#lx\n", w->id, w->mode, w->picture);
-       if (clipChanged)
-         {
-            if (w->borderSize)
-              {
-                 set_ignore(dpy, NextRequest(dpy));
-                 XFixesDestroyRegion(dpy, w->borderSize);
-                 w->borderSize = None;
-              }
-            if (w->extents)
-              {
-                 XFixesDestroyRegion(dpy, w->extents);
-                 w->extents = None;
-              }
-            if (w->borderClip)
-              {
-                 XFixesDestroyRegion(dpy, w->borderClip);
-                 w->borderClip = None;
-              }
-         }
-
-       if (!w->borderSize)
-          w->borderSize = border_size(dpy, w);
-
-       if (!w->extents)
-          w->extents = win_extents(dpy, w);
-
-       if (w->mode == WINDOW_SOLID)
-         {
-            int                 x, y, wid, hei;
-
-#if HAS_NAME_WINDOW_PIXMAP
-            x = w->a.x;
-            y = w->a.y;
-            wid = w->a.width + w->a.border_width * 2;
-            hei = w->a.height + w->a.border_width * 2;
-#else
-            x = w->a.x + w->a.border_width;
-            y = w->a.y + w->a.border_width;
-            wid = w->a.width;
-            hei = w->a.height;
-#endif
-            XFixesSetPictureClipRegion(dpy, rootBuffer, 0, 0, region);
-            set_ignore(dpy, NextRequest(dpy));
-            XFixesSubtractRegion(dpy, region, region, w->borderSize);
-            set_ignore(dpy, NextRequest(dpy));
-            XRenderComposite(dpy, PictOpSrc, w->picture, None, rootBuffer,
-                             0, 0, 0, 0, x, y, wid, hei);
-         }
-
-       if (!w->borderClip)
-         {
-            w->borderClip = XFixesCreateRegion(dpy, 0, 0);
-            XFixesCopyRegion(dpy, w->borderClip, region);
-         }
-       w->prev_trans = t;
-       t = w;
-     }
-
-   XFixesSetPictureClipRegion(dpy, rootBuffer, 0, 0, region);
-   paint_root(dpy);
-   for (w = t; w; w = w->prev_trans)
-     {
-       XFixesSetPictureClipRegion(dpy, rootBuffer, 0, 0, w->borderClip);
-#if ENABLE_SHADOWS
-       switch (compMode)
-         {
-         case CompSimple:
-            break;
-         case CompServerShadows:
-            set_ignore(dpy, NextRequest(dpy));
-            if (w->opacity != OPAQUE && !w->shadowPict)
-               w->shadowPict = solid_picture(dpy, True,
-                                             (double)w->opacity / OPAQUE * 0.3,
-                                             0, 0, 0);
-            XRenderComposite(dpy, PictOpOver,
-                             w->shadowPict ? w->shadowPict : transBlackPicture,
-                             w->picture, rootBuffer,
-                             0, 0, 0, 0,
-                             w->a.x + w->shadow_dx,
-                             w->a.y + w->shadow_dy,
-                             w->shadow_width, w->shadow_height);
-            break;
-         case CompClientShadows:
-            if (w->shadow)
-              {
-                 XRenderComposite(dpy, PictOpOver, blackPicture, w->shadow,
-                                  rootBuffer, 0, 0, 0, 0,
-                                  w->a.x + w->shadow_dx, w->a.y + w->shadow_dy,
-                                  w->shadow_width, w->shadow_height);
-              }
-            break;
-         }
-#endif
-       if (w->opacity != OPAQUE && !w->alphaPict)
-          w->alphaPict = solid_picture(dpy, False,
-                                       (double)w->opacity / OPAQUE, 0, 0, 0);
-       if (w->mode == WINDOW_TRANS)
-         {
-            int                 x, y, wid, hei;
-
-#if HAS_NAME_WINDOW_PIXMAP
-            x = w->a.x;
-            y = w->a.y;
-            wid = w->a.width + w->a.border_width * 2;
-            hei = w->a.height + w->a.border_width * 2;
-#else
-            x = w->a.x + w->a.border_width;
-            y = w->a.y + w->a.border_width;
-            wid = w->a.width;
-            hei = w->a.height;
-#endif
-            set_ignore(dpy, NextRequest(dpy));
-            XRenderComposite(dpy, PictOpOver, w->picture, w->alphaPict,
-                             rootBuffer, 0, 0, 0, 0, x, y, wid, hei);
-         }
-       else if (w->mode == WINDOW_ARGB)
-         {
-            int                 x, y, wid, hei;
-
-#if HAS_NAME_WINDOW_PIXMAP
-            x = w->a.x;
-            y = w->a.y;
-            wid = w->a.width + w->a.border_width * 2;
-            hei = w->a.height + w->a.border_width * 2;
-#else
-            x = w->a.x + w->a.border_width;
-            y = w->a.y + w->a.border_width;
-            wid = w->a.width;
-            hei = w->a.height;
-#endif
-            set_ignore(dpy, NextRequest(dpy));
-            XRenderComposite(dpy, PictOpOver, w->picture, w->alphaPict,
-                             rootBuffer, 0, 0, 0, 0, x, y, wid, hei);
-         }
        XFixesDestroyRegion(dpy, w->borderClip);
        w->borderClip = None;
      }
-   XFixesDestroyRegion(dpy, region);
-   if (rootBuffer != rootPicture)
-     {
-       XFixesSetPictureClipRegion(dpy, rootBuffer, 0, 0, None);
-       XRenderComposite(dpy, PictOpSrc, rootBuffer, None, rootPicture,
-                        0, 0, 0, 0, 0, 0, VRoot.w, VRoot.h);
-     }
 }
 
 static void
-add_damage(Display * dpy, XserverRegion damage)
+ECompMgrWinInvalidateOpacity(Win * w)
 {
-   D2printf("add_damage %#lx %#lx\n", allDamage, damage);
-   if (allDamage)
+   Display            *dpy = disp;
+
+   if (w->alphaPict != None)
      {
-       XFixesUnionRegion(dpy, allDamage, allDamage, damage);
-       XFixesDestroyRegion(dpy, damage);
+       XRenderFreePicture(dpy, w->alphaPict);
+       w->alphaPict = None;
      }
-   else
-      allDamage = damage;
+#if ENABLE_SHADOWS
+   if (w->shadowPict != None)
+     {
+       XRenderFreePicture(dpy, w->shadowPict);
+       w->shadowPict = None;
+     }
+#endif
 }
 
 static void
-repair_win(Display * dpy, Win * w)
+ECompMgrWinChangeOpacity(ECmWinInfo * w, unsigned int opacity)
 {
-   XserverRegion       parts;
+   Display            *dpy = disp;
+   int                 mode;
+   XRenderPictFormat  *pictfmt;
 
-   D2printf("repair_win %#lx damaged=%d\n", w->id, w->damaged);
-   if (!w->damaged)
-     {
-       parts = win_extents(dpy, w);
-       set_ignore(dpy, NextRequest(dpy));
-       XDamageSubtract(dpy, w->damage, None, None);
-     }
+   if (w->opacity == opacity)
+      return;
+
+   w->opacity = opacity;
+
+   D1printf("ECompMgrWinChangeOpacity: %#lx opacity=%#x\n", w->id, w->opacity);
+
+   /* Invalidate stuff changed by opacity */
+   ECompMgrWinInvalidateOpacity(w);
+
+   if (w->a.class == InputOnly)
+      pictfmt = NULL;
    else
-     {
-       parts = XFixesCreateRegion(dpy, 0, 0);
-       set_ignore(dpy, NextRequest(dpy));
-       XDamageSubtract(dpy, w->damage, None, parts);
-       XFixesTranslateRegion(dpy, parts,
-                             w->a.x + w->a.border_width,
-                             w->a.y + w->a.border_width);
-#if ENABLE_SHADOWS
-       if (compMode == CompServerShadows)
-         {
-            XserverRegion       o;
+      pictfmt = XRenderFindVisualFormat(dpy, w->a.visual);
 
-            o = XFixesCreateRegion(dpy, 0, 0);
-            XFixesCopyRegion(dpy, o, parts);
-            XFixesTranslateRegion(dpy, o, w->shadow_dx, w->shadow_dy);
-            XFixesUnionRegion(dpy, parts, parts, o);
-            XFixesDestroyRegion(dpy, o);
-         }
-#endif
-     }
-   add_damage(dpy, parts);
-   w->damaged = 1;
+   if (pictfmt && pictfmt->type == PictTypeDirect && pictfmt->direct.alphaMask)
+      mode = WINDOW_ARGB;
+   else if (w->opacity != OPAQUE)
+      mode = WINDOW_TRANS;
+   else
+      mode = WINDOW_SOLID;
+   w->mode = mode;
+
+   if (w->extents != None)
+      ECompMgrDamageMerge(w->extents, 0);
 }
 
 static void
@@ -1064,61 +1013,29 @@
    w->damage_bounds.width = w->damage_bounds.height = 0;
 #endif
    w->damaged = 0;
+
+   if (w->extents)
+     {
+       XFixesDestroyRegion(disp, w->extents);
+     }
+   w->extents = win_extents(disp, w);
 }
 
 static void
-finish_unmap_win(Display * dpy, Win * w)
+finish_unmap_win(Display * dpy __UNUSED__, Win * w)
 {
    w->damaged = 0;
+
 #if CAN_DO_USABLE
    w->usable = False;
 #endif
-   if (w->extents != None)
-     {
-       add_damage(dpy, w->extents);    /* destroys region */
-       w->extents = None;
-     }
-
-#if HAS_NAME_WINDOW_PIXMAP
-   if (w->pixmap)
-     {
-       XFreePixmap(dpy, w->pixmap);
-       w->pixmap = None;
-     }
-#endif
-
-   if (w->picture)
-     {
-       set_ignore(dpy, NextRequest(dpy));
-       XRenderFreePicture(dpy, w->picture);
-       w->picture = None;
-     }
-
-   /* don't care about properties anymore */
-   set_ignore(dpy, NextRequest(dpy));
-#if 0                          /* Not if integrated - and why bother at all? */
-   XSelectInput(dpy, w->id, 0);
-#endif
 
-   if (w->borderSize)
-     {
-       set_ignore(dpy, NextRequest(dpy));
-       XFixesDestroyRegion(dpy, w->borderSize);
-       w->borderSize = None;
-     }
+   ECompMgrWinInvalidateSize(w);
 
-#if ENABLE_SHADOWS
-   if (w->shadow)
-     {
-       XRenderFreePicture(dpy, w->shadow);
-       w->shadow = None;
-     }
-#endif
-
-   if (w->borderClip)
+   if (w->extents != None)
      {
-       XFixesDestroyRegion(dpy, w->borderClip);
-       w->borderClip = None;
+       ECompMgrDamageMerge(w->extents, 1);
+       w->extents = None;
      }
 
    clipChanged = True;
@@ -1139,6 +1056,9 @@
 {
    if (!w)
       return;
+
+   D1printf("ECompMgrWinUnmap %#lx\n", w->id);
+
 #if ENABLE_FADING
 #if HAS_NAME_WINDOW_PIXMAP
    if (w->pixmap && do_fade && fadeWindows)
@@ -1154,16 +1074,16 @@
    otherwise the value
  */
 static unsigned int
-get_opacity_prop(Display * dpy, Win * w, unsigned int def)
+get_opacity_prop(Win * w, unsigned int def)
 {
    Atom                actual;
-   int                 format;
+   int                 pictfmt;
    unsigned long       n, left;
    unsigned char      *data;
 
    data = NULL;
-   XGetWindowProperty(dpy, w->id, _NET_WM_WINDOW_OPACITY, 0L, 1L, False,
-                     XA_CARDINAL, &actual, &format, &n, &left, &data);
+   XGetWindowProperty(disp, w->id, _NET_WM_WINDOW_OPACITY, 0L, 1L, False,
+                     XA_CARDINAL, &actual, &pictfmt, &n, &left, &data);
    if (data)
      {
        unsigned int        i;
@@ -1174,64 +1094,6 @@
    return def;
 }
 
-/* determine mode for window all in one place.
-   Future might check for menu flag and other cool things
-*/
-
-static void
-determine_mode(Display * dpy, Win * w)
-{
-   int                 mode;
-   XRenderPictFormat  *format;
-
-   /* if trans prop == -1 fall back on  previous tests */
-
-   if (w->alphaPict)
-     {
-       XRenderFreePicture(dpy, w->alphaPict);
-       w->alphaPict = None;
-     }
-#if ENABLE_SHADOWS
-   if (w->shadowPict)
-     {
-       XRenderFreePicture(dpy, w->shadowPict);
-       w->shadowPict = None;
-     }
-#endif
-
-   if (w->a.class == InputOnly)
-     {
-       format = 0;
-     }
-   else
-     {
-       format = XRenderFindVisualFormat(dpy, w->a.visual);
-     }
-
-   if (format && format->type == PictTypeDirect && format->direct.alphaMask)
-     {
-       mode = WINDOW_ARGB;
-     }
-   else if (w->opacity != OPAQUE)
-     {
-       mode = WINDOW_TRANS;
-     }
-   else
-     {
-       mode = WINDOW_SOLID;
-     }
-   w->mode = mode;
-
-   if (w->extents)
-     {
-       XserverRegion       damage;
-
-       damage = XFixesCreateRegion(dpy, 0, 0);
-       XFixesCopyRegion(dpy, damage, w->extents);
-       add_damage(dpy, damage);
-     }
-}
-
 static ECmWinInfo  *
 ECompMgrWinNew(Window id, Window prev)
 {
@@ -1278,6 +1140,7 @@
        new->damage_sequence = NextRequest(dpy);
        new->damage = XDamageCreate(dpy, id, XDamageReportNonEmpty);
      }
+
    new->alphaPict = None;
    new->borderSize = None;
    new->extents = None;
@@ -1296,8 +1159,8 @@
 
    /* moved mode setting to one place */
    ESelectInputAdd(dpy, id, PropertyChangeMask);
-   new->opacity = get_opacity_prop(dpy, new, OPAQUE);
-   determine_mode(dpy, new);
+   new->opacity = 0xdeadbeef;
+   ECompMgrWinChangeOpacity(new, get_opacity_prop(new, OPAQUE));
 
    new->next = *p;
    *p = new;
@@ -1308,59 +1171,6 @@
 }
 
 static void
-restack_win(Win * w, Window new_above)
-{
-   Window              old_above;
-
-   D2printf("restack_win %#lx\n", w->id);
-
-   if (w->next)
-      old_above = w->next->id;
-   else
-      old_above = None;
-   if (old_above != new_above)
-     {
-       Win               **prev;
-
-       /* unhook */
-       for (prev = &list; *prev; prev = &(*prev)->next)
-          if ((*prev) == w)
-             break;
-       *prev = w->next;
-
-       /* rehook */
-       for (prev = &list; *prev; prev = &(*prev)->next)
-         {
-            if ((*prev)->id == new_above)
-               break;
-         }
-       w->next = *prev;
-       *prev = w;
-     }
-}
-
-static void
-ECompMgrRootConfigure(void *prm __UNUSED__, XEvent * ev)
-{
-   Display            *dpy = disp;
-
-   D1printf("ECompMgrRootConfigure root\n");
-   if (ev->xconfigure.window == VRoot.win)
-     {
-       if (rootBuffer)
-         {
-            XRenderFreePicture(dpy, rootBuffer);
-            rootBuffer = None;
-         }
-#if 0                          /* Should be handled elsewhere */
-       VRoot.w = ev->xconfigure.width;
-       VRoot.h = ev->xconfigure.height;
-#endif
-     }
-   return;
-}
-
-static void
 ECompMgrWinConfigure(ECmWinInfo * w, XEvent * ev)
 {
    Display            *dpy = disp;
@@ -1369,8 +1179,9 @@
    if (!w)
       return;
 
-   D1printf("ECompMgrWinConfigure %#lx\n", w->id);
+   D1printf("ECompMgrWinConfigure %#lx %#lx\n", w->id, w->extents);
 
+   /* Invalidate old window region */
 #if CAN_DO_USABLE
    if (w->usable)
 #endif
@@ -1378,7 +1189,10 @@
        damage = XFixesCreateRegion(dpy, 0, 0);
        if (w->extents != None)
           XFixesCopyRegion(dpy, damage, w->extents);
+       if (EventDebug(EDBUG_TYPE_COMPMGR3))
+          ERegionShow("ECompMgrWinConfigure old-extents:", damage);
      }
+
    w->a.x = ev->xconfigure.x;
    w->a.y = ev->xconfigure.y;
    if (w->a.width != ev->xconfigure.width ||
@@ -1404,20 +1218,32 @@
          }
 #endif
      }
+
    w->a.width = ev->xconfigure.width;
    w->a.height = ev->xconfigure.height;
    w->a.border_width = ev->xconfigure.border_width;
    w->a.override_redirect = ev->xconfigure.override_redirect;
    restack_win(w, ev->xconfigure.above);
 
-   if (damage)
-     {
-       XserverRegion       extents = win_extents(dpy, w);
+#if HAS_NAME_WINDOW_PIXMAP
+   w->rcx = w->a.x;
+   w->rcy = w->a.y;
+   w->rcw = w->a.width + w->a.border_width * 2;
+   w->rch = w->w->a.height + w->a.border_width * 2;
+#else
+   w->rcx = w->a.x + w->a.border_width;
+   w->rcy = w->a.y + w->a.border_width;
+   w->rcw = w->a.width;
+   w->rch = w->a.height;
+#endif
+
+   /* Find new window region */
+   w->extents = win_extents(dpy, w);
+
+   /* Invalidate new window region */
+   XFixesUnionRegion(dpy, damage, damage, w->extents);
+   ECompMgrDamageMerge(damage, 1);
 
-       XFixesUnionRegion(dpy, damage, damage, extents);
-       XFixesDestroyRegion(dpy, extents);
-       add_damage(dpy, damage);
-     }
    clipChanged = True;
 }
 
@@ -1433,10 +1259,21 @@
    else
       new_above = None;
    restack_win(w, new_above);
+
    clipChanged = True;
 }
 
 static void
+ECompMgrWinInvalidateAll(Win * w)
+{
+   /* Free pixmap, picture, borderSize, shadowPict, borderClip */
+   ECompMgrWinInvalidateSize(w);
+
+   /* Free alphaPict, shadowPict */
+   ECompMgrWinInvalidateOpacity(w);
+}
+
+static void
 finish_destroy_win(Display * dpy, Window id, Bool gone)
 {
    Win               **prev, *w;
@@ -1450,39 +1287,26 @@
           finish_unmap_win(dpy, w);
 
        *prev = w->next;
+       goto cleanup;
+     }
 
-       if (w->picture)
-         {
-            set_ignore(dpy, NextRequest(dpy));
-            XRenderFreePicture(dpy, w->picture);
-         }
-
-       if (w->alphaPict)
-         {
-            XRenderFreePicture(dpy, w->alphaPict);
-            w->alphaPict = None;
-         }
+   /* No match */
+   return;
 
-#if ENABLE_SHADOWS
-       if (w->shadowPict)
-         {
-            XRenderFreePicture(dpy, w->shadowPict);
-            w->shadowPict = None;
-         }
-#endif
+ cleanup:
 
-       if (w->damage != None)
-         {
-            set_ignore(dpy, NextRequest(dpy));
-            XDamageDestroy(dpy, w->damage);
-         }
+   ECompMgrWinInvalidateAll(w);
+
+   if (w->damage != None)
+     {
+       set_ignore(dpy, NextRequest(dpy));
+       XDamageDestroy(dpy, w->damage);
+     }
 
 #if ENABLE_FADING
-       cleanup_fade(dpy, w);
+   cleanup_fade(dpy, w);
 #endif
-       free(w);
-       break;
-     }
+   free(w);
 }
 
 #if ENABLE_FADING
@@ -1523,6 +1347,7 @@
 {
    Display            *dpy = disp;
    XDamageNotifyEvent *de = (XDamageNotifyEvent *) ev;
+   XserverRegion       parts;
 
    if (!w)
       return;
@@ -1582,18 +1407,46 @@
             w->usable = True;
          }
      }
-   if (w->usable)
+   if (!w->usable)
+      return;
 #else
    de = NULL;
 #endif
-   repair_win(dpy, w);
+
+   if (!w->damaged)
+     {
+       parts = win_extents(dpy, w);
+       set_ignore(dpy, NextRequest(dpy));
+       XDamageSubtract(dpy, w->damage, None, None);
+     }
+   else
+     {
+       parts = XFixesCreateRegion(dpy, 0, 0);
+       set_ignore(dpy, NextRequest(dpy));
+       XDamageSubtract(dpy, w->damage, None, parts);
+       XFixesTranslateRegion(dpy, parts,
+                             w->a.x + w->a.border_width,
+                             w->a.y + w->a.border_width);
+#if ENABLE_SHADOWS
+       if (Conf_compmgr.shadow == CompServerShadows)
+         {
+            XserverRegion       o;
+
+            o = XFixesCreateRegion(dpy, 0, 0);
+            XFixesCopyRegion(dpy, o, parts);
+            XFixesTranslateRegion(dpy, o, w->shadow_dx, w->shadow_dy);
+            XFixesUnionRegion(dpy, parts, parts, o);
+            XFixesDestroyRegion(dpy, o);
+         }
+#endif
+     }
+   ECompMgrDamageMerge(parts, 1);
+   w->damaged = 1;
 }
 
 static void
 ECompMgrWinProperty(Win * w, XEvent * ev)
 {
-   Display            *dpy = disp;
-
    if (!w)
       return;
 
@@ -1603,9 +1456,254 @@
        /* reset mode and redraw window */
        D1printf("ECompMgrWinProperty %#lx\n", w->id);
 
-       w->opacity = get_opacity_prop(dpy, w, OPAQUE);
-       determine_mode(dpy, w);
+       ECompMgrWinChangeOpacity(w, get_opacity_prop(w, OPAQUE));
+     }
+}
+
+static void
+restack_win(Win * w, Window new_above)
+{
+   Window              old_above;
+
+   D2printf("restack_win %#lx\n", w->id);
+
+   if (w->next)
+      old_above = w->next->id;
+   else
+      old_above = None;
+
+   if (old_above != new_above)
+     {
+       Win               **prev;
+
+       /* unhook */
+       for (prev = &list; *prev; prev = &(*prev)->next)
+          if ((*prev) == w)
+             break;
+       *prev = w->next;
+
+       /* rehook */
+       for (prev = &list; *prev; prev = &(*prev)->next)
+         {
+            if ((*prev)->id == new_above)
+               break;
+         }
+       w->next = *prev;
+       *prev = w;
+     }
+}
+
+/* Ensure that the blend mask is up to date */
+static void
+ECompMgrCheckAlphaMask(Win * w)
+{
+   if (w->opacity != OPAQUE && !w->alphaPict)
+      w->alphaPict = EPictureCreateSolid(False, (double)w->opacity / OPAQUE,
+                                        0, 0, 0);
+}
+
+static void
+ECompMgrRepaint(Display * dpy, XserverRegion region)
+{
+   Win                *w, *t;
+   Picture             pict, pbuf;
+   XRenderPictFormat  *pictfmt;
+
+   D2printf("ECompMgrRepaint rootBuffer=%#lx rootPicture=%#lx\n",
+           rootBuffer, rootPicture);
+   if (EventDebug(EDBUG_TYPE_COMPMGR3))
+      ERegionShow("Paint", region);
+
+   if (!rootBuffer)
+      rootBuffer = EPictureCreateBuffer(VRoot.win, VRoot.w, VRoot.h,
+                                       VRoot.depth, VRoot.vis);
+   pbuf = rootBuffer;
+
+   /* Reverse link the list(?) */
+   for (w = list, t = NULL; w; w = w->next)
+     {
+       w->prev_trans = t;
+       t = w;
+     }
+
+   XFixesSetPictureClipRegion(dpy, pbuf, 0, 0, region);
+
+   /* Draw desktop background picture */
+   pict = DeskBackgroundPictureGet(0);
+   D1printf("paint_root desk picture=%#lx\n", pict);
+   XRenderComposite(dpy, PictOpSrc, pict, None, pbuf,
+                   0, 0, 0, 0, 0, 0, VRoot.w, VRoot.h);
+
+   for (w = t; w; w = w->prev_trans)
+     {
+#if CAN_DO_USABLE
+       if (!w->usable)
+          continue;
+#endif
+       if (!w->damaged)
+          continue;
+
+       if (!w->picture)
+         {
+            XRenderPictureAttributes pa;
+
+            Drawable            draw = w->id;
+
+#if HAS_NAME_WINDOW_PIXMAP
+            if (hasNamePixmap && !w->pixmap)
+               w->pixmap = XCompositeNameWindowPixmap(dpy, w->id);
+            if (w->pixmap)
+               draw = w->pixmap;
+#endif
+            pictfmt = XRenderFindVisualFormat(dpy, w->a.visual);
+            pa.subwindow_mode = IncludeInferiors;
+            w->picture = XRenderCreatePicture(dpy, draw,
+                                              pictfmt, CPSubwindowMode, &pa);
+         }
+
+       D2printf("paint %#lx %d %#lx\n", w->id, w->mode, w->picture);
+#if 0                          /* FIXME - Why? */
+       if (clipChanged)
+         {
+            if (w->borderSize)
+              {
+                 set_ignore(dpy, NextRequest(dpy));
+                 XFixesDestroyRegion(dpy, w->borderSize);
+                 w->borderSize = None;
+              }
+            if (w->extents)
+              {
+                 XFixesDestroyRegion(dpy, w->extents);
+                 w->extents = None;
+              }
+            if (w->borderClip)
+              {
+                 XFixesDestroyRegion(dpy, w->borderClip);
+                 w->borderClip = None;
+              }
+         }
+#endif
+
+       /* Region of shaped window in screen coordinates */
+       if (!w->borderSize)
+          w->borderSize = border_size(dpy, w);
+       if (EventDebug(EDBUG_TYPE_COMPMGR3))
+          ERegionShow("Window borderSize", w->borderSize);
+
+       /* Region of window in screen coordinates */
+       if (!w->extents)
+          w->extents = win_extents(dpy, w);
+       if (EventDebug(EDBUG_TYPE_COMPMGR3))
+          ERegionShow("Window extents", w->extents);
+
+#if 0
+       if (w->mode == WINDOW_SOLID)
+         {
+            XFixesSetPictureClipRegion(dpy, rootBuffer, 0, 0, region);
+            set_ignore(dpy, NextRequest(dpy));
+            XFixesSubtractRegion(dpy, region, region, w->borderSize);
+            set_ignore(dpy, NextRequest(dpy));
+            XRenderComposite(dpy, PictOpSrc, w->picture, None, rootBuffer,
+                             0, 0, 0, 0, w->rcx, w->rcy, w->rcw, w->rch);
+         }
+#endif
+
+#if 1
+       if (!w->borderClip)
+         {
+            w->borderClip = XFixesCreateRegion(dpy, 0, 0);
+            XFixesCopyRegion(dpy, w->borderClip, region);
+         }
+#endif
+       XFixesSetPictureClipRegion(dpy, pbuf, 0, 0, w->borderClip);
+#if ENABLE_SHADOWS
+       switch (Conf_compmgr.shadow)
+         {
+         case CompSimple:
+            break;
+         case CompServerShadows:
+            set_ignore(dpy, NextRequest(dpy));
+            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 CompClientShadows:
+            if (w->shadow)
+              {
+                 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;
+         }
+#endif
+
+       switch (w->mode)
+         {
+         default:
+         case WINDOW_SOLID:
+#if 0
+            XFixesSetPictureClipRegion(dpy, pbuf, 0, 0, region);
+            set_ignore(dpy, NextRequest(dpy));
+            XFixesSubtractRegion(dpy, region, region, w->borderSize);
+#endif
+            set_ignore(dpy, NextRequest(dpy));
+            XRenderComposite(dpy, PictOpSrc, w->picture, None, pbuf,
+                             0, 0, 0, 0, w->rcx, w->rcy, w->rcw, w->rch);
+         case WINDOW_TRANS:
+            ECompMgrCheckAlphaMask(w);
+            set_ignore(dpy, NextRequest(dpy));
+            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);
+            set_ignore(dpy, NextRequest(dpy));
+            XRenderComposite(dpy, PictOpOver, w->picture, w->alphaPict,
+                             pbuf, 0, 0, 0, 0, w->rcx, w->rcy, w->rcw, w->rch);
+            break;
+            break;
+         }
+       XFixesDestroyRegion(dpy, w->borderClip);
+       w->borderClip = None;
+     }
+
+   XFixesDestroyRegion(dpy, region);
+
+   if (pbuf != rootPicture)
+     {
+       XFixesSetPictureClipRegion(dpy, pbuf, 0, 0, None);
+       XRenderComposite(dpy, PictOpSrc, pbuf, None, rootPicture,
+                        0, 0, 0, 0, 0, 0, VRoot.w, VRoot.h);
+     }
+}
+
+static void
+ECompMgrRootConfigure(void *prm __UNUSED__, XEvent * ev)
+{
+   Display            *dpy = disp;
+
+   D1printf("ECompMgrRootConfigure root\n");
+   if (ev->xconfigure.window == VRoot.win)
+     {
+       if (rootBuffer)
+         {
+            XRenderFreePicture(dpy, rootBuffer);
+            rootBuffer = None;
+         }
+#if 0                          /* Should be handled elsewhere */
+       VRoot.w = ev->xconfigure.width;
+       VRoot.h = ev->xconfigure.height;
+#endif
      }
+   return;
 }
 
 static void
@@ -1648,7 +1746,7 @@
 
        region = XFixesCreateRegion(dpy, expose_rects, n_expose);
 
-       add_damage(dpy, region);
+       ECompMgrDamageMerge(region, 1);
        n_expose = 0;
      }
 }
@@ -1656,19 +1754,27 @@
 static void
 ECompMgrIdle(void)
 {
-   static int          paint;
-
-   if (!allDamage || autoRedirect)
+   /* Do we get here on auto? */
+   if (!allDamage /* || Conf_compmgr.mode == ECOMPMGR_MODE_AUTO */ )
       return;
 
-   paint_all(disp, allDamage);
-   paint++;
+   ECompMgrRepaint(disp, allDamage);
+
    XSync(disp, False);
+
    allDamage = None;
    clipChanged = False;
 }
 
-#if BUILD_ECOMPMGR || USE_MOSTLY_ROOT_EVENTS
+static void
+ECompMgrDeskChanged(int desk)
+{
+   D1printf("ECompMgrDeskChanged: desk=%d\n", desk);
+
+   DeskBackgroundPictureFree(desk);
+}
+
+#if USE_MOSTLY_ROOT_EVENTS
 
 static Win         *
 find_win(Window id)
@@ -1689,12 +1795,12 @@
    XRenderPictFormat  *pictfmt;
    XRenderPictureAttributes pa;
 
-   if (!Conf_compmgr.enable || Mode_compmgr.active)
+   if (Conf_compmgr.mode == ECOMPMGR_MODE_OFF || Mode_compmgr.active)
       return;
    Mode_compmgr.active = 1;
 
 #if ENABLE_SHADOWS
-   if (compMode == CompClientShadows)
+   if (Conf_compmgr.shadow == CompClientShadows)
       gaussianMap = make_gaussian_map(disp, shadowRadius);
 #endif
 
@@ -1704,9 +1810,9 @@
       XRenderCreatePicture(disp, VRoot.win, pictfmt, CPSubwindowMode, &pa);
 
 #if ENABLE_SHADOWS
-   blackPicture = solid_picture(disp, True, 1, 0, 0, 0);
-   if (compMode == CompServerShadows)
-      transBlackPicture = solid_picture(disp, True, 0.3, 0, 0, 0);
+   blackPicture = EPictureCreateSolid(True, 1, 0, 0, 0);
+   if (Conf_compmgr.shadow == CompServerShadows)
+      transBlackPicture = EPictureCreateSolid(True, 0.3, 0, 0, 0);
 #endif
 
    allDamage = None;
@@ -1714,20 +1820,26 @@
 
    XGrabServer(disp);
 
-   if (autoRedirect)
-      XCompositeRedirectSubwindows(disp, VRoot.win, CompositeRedirectAutomatic);
-   else
+   switch (Conf_compmgr.mode)
      {
+     case ECOMPMGR_MODE_AUTO:
+       XCompositeRedirectSubwindows(disp, VRoot.win,
+                                    CompositeRedirectAutomatic);
+       break;
+     case ECOMPMGR_MODE_ROOT:
        XCompositeRedirectSubwindows(disp, VRoot.win, CompositeRedirectManual);
        ESelectInputAdd(disp, VRoot.win,
                        SubstructureNotifyMask |
                        ExposureMask | StructureNotifyMask |
                        PropertyChangeMask);
+       break;
+     case ECOMPMGR_MODE_WINDOW:
+       break;
      }
 
-#if BUILD_ECOMPMGR || USE_MOSTLY_ROOT_EVENTS
+#if USE_MOSTLY_ROOT_EVENTS
    /* Build initial list of children */
-   if (!autoRedirect)
+   if (Conf_compmgr.mode != ECOMPMGR_MODE_AUTO)
      {
        Window              root_return, parent_return;
        Window             *children;
@@ -1744,8 +1856,8 @@
 
    XUngrabServer(disp);
 
-   if (!autoRedirect)
-      paint_all(disp, None);
+   if (Conf_compmgr.mode != ECOMPMGR_MODE_AUTO)
+      ECompMgrRepaint(disp, ERegionCreate(0, 0, VRoot.w, VRoot.h));
 }
 
 static void
@@ -1763,9 +1875,7 @@
       XRenderFreePicture(disp, rootBuffer);
    rootBuffer = None;
 
-   if (rootTile)
-      XRenderFreePicture(disp, rootTile);
-   rootTile = None;
+   DeskBackgroundPictureFree(0);
 
    while (list)
       ECompMgrWinDel(list, False, False);
@@ -1773,10 +1883,10 @@
    XCompositeRedirectSubwindows(disp, VRoot.win, CompositeRedirectAutomatic);
 }
 
-#if BUILD_ECOMPMGR || USE_MOSTLY_ROOT_EVENTS
+#if USE_MOSTLY_ROOT_EVENTS
 #define _GET_WIN(a) find_win(a)
 #else
-#define _GET_WIN(a) ((Win*)((EWin*)prm)->cmhook);
+#define _GET_WIN(a) ((Win*)((EWin*)prm)->cmhook)
 #endif
 
 static void
@@ -1805,13 +1915,7 @@
        ECompMgrWinProperty(_GET_WIN(ev->xproperty.window), ev);
        break;
 
-#if BUILD_ECOMPMGR
-     default:
-       if (ev->type != damage_event + XDamageNotify)
-          break;
-#else
      case EX_EVENT_DAMAGE_NOTIFY:
-#endif
        ECompMgrWinDamage(_GET_WIN(((XDamageNotifyEvent *) ev)->drawable), ev);
        break;
      }
@@ -1830,23 +1934,25 @@
      case CreateNotify:
       case_CreateNotify:
        ECompMgrWinNew(ev->xcreatewindow.window, 0);
-#if !BUILD_ECOMPMGR
        EventCallbackRegister(ev->xcreatewindow.window, 0,
                              ECompMgrHandleWindowEvent, NULL);
-#endif
        break;
      case DestroyNotify:
        ECompMgrWinDel(_GET_WIN(ev->xdestroywindow.window), True, True);
+       EventCallbackUnregister(ev->xcreatewindow.window, 0,
+                               ECompMgrHandleWindowEvent, NULL);
        break;
 
      case ReparentNotify:
        if (ev->xreparent.parent == VRoot.win)
           goto case_CreateNotify;
        ECompMgrWinDel(_GET_WIN(ev->xreparent.window), False, True);
+       EventCallbackUnregister(ev->xcreatewindow.window, 0,
+                               ECompMgrHandleWindowEvent, NULL);
        break;
 
      case ConfigureNotify:
-       if (ev->xreparent.parent == VRoot.win)
+       if (ev->xconfigure.window == VRoot.win)
           ECompMgrRootConfigure(prm, ev);
        else
           ECompMgrWinConfigure(_GET_WIN(ev->xconfigure.window), ev);
@@ -1862,6 +1968,11 @@
      case CirculateNotify:
        ECompMgrWinCirculate(_GET_WIN(ev->xcirculate.window), ev);
        break;
+#else
+     case ConfigureNotify:
+       if (ev->xconfigure.window == VRoot.win)
+          ECompMgrRootConfigure(prm, ev);
+       break;
 #endif
 
      case Expose:
@@ -1877,13 +1988,11 @@
 
    if (!XDamageQueryExtension(disp, &events, &errors))
      {
-       Conf_compmgr.enable = 0;
+       Conf_compmgr.mode = ECOMPMGR_MODE_OFF;
        return;
      }
 
-   autoRedirect = Conf_compmgr.autoredirect;
-
-   D1printf("ECompMgrInit: enable=%d\n", Conf_compmgr.enable);
+   D1printf("ECompMgrInit: mode=%d\n", Conf_compmgr.mode);
 }
 
 static void
@@ -1891,11 +2000,9 @@
 {
 #if !USE_MOSTLY_ROOT_EVENTS
    EWin               *ewin;
-#else
-   prm = NULL;                 /* Avoid compiler warning */
 #endif
 
-   if (!Conf_compmgr.enable)
+   if (Conf_compmgr.mode == ECOMPMGR_MODE_OFF)
       return;
 
    switch (sig)
@@ -1907,7 +2014,7 @@
        break;
 
      case ESIGNAL_BACKGROUND_CHANGE:
-       ECompMgrRootInit(0);
+       ECompMgrDeskChanged((int)prm);
        break;
 
      case ESIGNAL_IDLE:
@@ -1917,8 +2024,9 @@
 #if !USE_MOSTLY_ROOT_EVENTS
      case ESIGNAL_EWIN_CREATE:
        ewin = (EWin *) prm;
-       ewin->cmhook = ECompMgrWinNew(ewin->win, None);
-       EventCallbackRegister(ewin->win, 0, ECompMgrHandleWindowEvent, ewin);
+       ewin->cmhook = ECompMgrWinNew(EoGetWin(ewin), None);
+       EventCallbackRegister(EoGetWin(ewin), 0, ECompMgrHandleWindowEvent,
+                             ewin);
        break;
 
      case ESIGNAL_EWIN_DESTROY:
@@ -1974,8 +2082,8 @@
 #define N_IPC_FUNCS (sizeof(CompMgrIpcArray)/sizeof(IpcItem))
 
 static const CfgItem CompMgrCfgItems[] = {
-   CFG_ITEM_BOOL(Conf_compmgr, enable, 0),
-   CFG_ITEM_BOOL(Conf_compmgr, autoredirect, 0),
+   CFG_ITEM_INT(Conf_compmgr, mode, 0),
+   CFG_ITEM_INT(Conf_compmgr, shadow, 0),
 };
 #define N_CFG_ITEMS (sizeof(CompMgrCfgItems)/sizeof(CfgItem))
 
===================================================================
RCS file: /cvsroot/enlightenment/e16/e/src/events.c,v
retrieving revision 1.69.2.14
retrieving revision 1.69.2.15
diff -u -3 -r1.69.2.14 -r1.69.2.15
--- events.c    20 Oct 2004 21:04:07 -0000      1.69.2.14
+++ events.c    25 Oct 2004 22:14:21 -0000      1.69.2.15
@@ -542,6 +542,7 @@
          case UnmapNotify:
          case MapNotify:
          case ConfigureNotify:
+         case Expose:
          case EX_EVENT_DAMAGE_NOTIFY:
             if (EventDebug(EDBUG_TYPE_EVENTS))
                Eprintf("CheckEvent %d type=%d\n", i, evq[i].type);
===================================================================
RCS file: /cvsroot/enlightenment/e16/e/src/Attic/ewin-ops.c,v
retrieving revision 1.1.2.15
retrieving revision 1.1.2.16
diff -u -3 -r1.1.2.15 -r1.1.2.16
--- ewin-ops.c  20 Oct 2004 21:04:07 -0000      1.1.2.15
+++ ewin-ops.c  25 Oct 2004 22:14:22 -0000      1.1.2.16
@@ -253,8 +253,10 @@
    EMoveResizeWindow(disp, EoGetWin(ewin), EoGetX(ewin), EoGetY(ewin),
                     EoGetW(ewin), EoGetH(ewin));
 
-   if ((Mode.mode != MODE_MOVE_PENDING && Mode.mode != MODE_MOVE)
+#if 0                          /* FIXME - Make configurable? */
+   if (Conf.(Mode.mode != MODE_MOVE_PENDING && Mode.mode != MODE_MOVE)
        || (Mode.have_place_grab))
+#endif
       ICCCM_Configure(ewin);
 
    EwinBorderCalcSizes(ewin);
===================================================================
RCS file: /cvsroot/enlightenment/e16/e/src/misc.c,v
retrieving revision 1.58.2.5
retrieving revision 1.58.2.6
diff -u -3 -r1.58.2.5 -r1.58.2.6
--- misc.c      17 Oct 2004 22:28:11 -0000      1.58.2.5
+++ misc.c      25 Oct 2004 22:14:22 -0000      1.58.2.6
@@ -138,8 +138,8 @@
 #endif
    etl_k = etl_k1 + tm * etl_fac;
 
-   CheckEvent();
    ecore_x_sync();
+   CheckEvent();
 
    return etl_k;
 }
===================================================================
RCS file: /cvsroot/enlightenment/e16/e/src/Attic/mod-desks.c,v
retrieving revision 1.1.2.11
retrieving revision 1.1.2.12
diff -u -3 -r1.1.2.11 -r1.1.2.12
--- mod-desks.c 20 Oct 2004 21:04:10 -0000      1.1.2.11
+++ mod-desks.c 25 Oct 2004 22:14:23 -0000      1.1.2.12
@@ -42,6 +42,7 @@
        DeskSetViewable(0, 1);
        RefreshDesktop(0);
 
+#if !USE_COMPOSITE             /* FIXME - Disable for now */
        /* toss down the dragbar and related */
        InitDesktopControls();
 
@@ -49,6 +50,7 @@
        ShowDesktopButtons();
 
        ShowDesktopControls();
+#endif
        break;
      }
 }
===================================================================
RCS file: /cvsroot/enlightenment/e16/e/src/pager.c,v
retrieving revision 1.103.2.19
retrieving revision 1.103.2.20
diff -u -3 -r1.103.2.19 -r1.103.2.20
--- pager.c     20 Oct 2004 21:04:10 -0000      1.103.2.19
+++ pager.c     25 Oct 2004 22:14:23 -0000      1.103.2.20
@@ -2188,7 +2188,6 @@
 {
    static int          pdesk = -1;     /* Last desk */
    int                 desk;
-   Background         *bg;
 
    switch (sig)
      {
@@ -2238,18 +2237,14 @@
        pdesk = desk;
        break;
      case ESIGNAL_BACKGROUND_CHANGE:
-       bg = (Background *) prm;
-       for (desk = 0; desk < Conf.desks.num; desk++)
-          if (DeskGetBackground(desk) == bg)
-            {
-               if (desk == DesksGetCurrent())
-                 {
-                    RedrawPagersForDesktop(desk, 2);
-                    ForceUpdatePagersForDesktop(desk);
-                 }
-               else
-                  RedrawPagersForDesktop(desk, 1);
-            }
+       desk = (int)prm;
+       if (desk == DesksGetCurrent())
+         {
+            RedrawPagersForDesktop(desk, 2);
+            ForceUpdatePagersForDesktop(desk);
+         }
+       else
+          RedrawPagersForDesktop(desk, 1);
        break;
      case ESIGNAL_DESK_CHANGE:
        ForceUpdatePagersForDesktop((int)prm);
===================================================================
RCS file: /cvsroot/enlightenment/e16/e/src/startup.c,v
retrieving revision 1.44.2.7
retrieving revision 1.44.2.8
diff -u -3 -r1.44.2.7 -r1.44.2.8
--- startup.c   17 Sep 2004 16:13:43 -0000      1.44.2.7
+++ startup.c   25 Oct 2004 22:14:23 -0000      1.44.2.8
@@ -35,6 +35,10 @@
    static ImageClass  *ic = NULL;
    char                pq;
 
+#if USE_COMPOSITE              /* FIXME - Disable for now */
+   return;
+#endif
+
    if (start)
      {
        bg_sideways = FindItem("STARTUP_BACKGROUND_SIDEWAYS", 0,




-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl
_______________________________________________
enlightenment-cvs mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to