--- xcompmgr-1.1.5/xcompmgr.c 2009-10-20 00:44:23.000000000 +0200 +++ xcompmgr-local/xcompmgr.c 2010-03-16 12:27:35.521699742 +0100 @@ -43,6 +43,7 @@ #include #include #include +#include #if COMPOSITE_MAJOR > 0 || COMPOSITE_MINOR >= 2 #define HAS_NAME_WINDOW_PIXMAP 1 @@ -82,6 +83,8 @@ unsigned int opacity; Atom windowType; unsigned long damage_sequence; /* sequence when damage was created */ + Bool shaped; + XRectangle shape_bounds; /* for drawing translucent windows */ XserverRegion borderClip; @@ -125,6 +128,7 @@ static int damage_event, damage_error; static int composite_event, composite_error; static int render_event, render_error; +static int xshape_event, xshape_error; static Bool synchronize; static int composite_opcode; @@ -1023,6 +1027,7 @@ { w->borderClip = XFixesCreateRegion (dpy, NULL, 0); XFixesCopyRegion (dpy, w->borderClip, region); + XFixesIntersectRegion(dpy, w->borderClip, w->borderClip, w->borderSize); } w->prev_trans = t; t = w; @@ -1441,6 +1446,11 @@ free (new); return; } + new->shaped = False; + new->shape_bounds.x = new->a.x; + new->shape_bounds.y = new->a.y; + new->shape_bounds.width = new->a.width; + new->shape_bounds.height = new->a.height; new->damaged = 0; #if CAN_DO_USABLE new->usable = False; @@ -1458,6 +1468,7 @@ { new->damage_sequence = NextRequest (dpy); new->damage = XDamageCreate (dpy, id, XDamageReportNonEmpty); + XShapeSelectInput (dpy, id, ShapeNotifyMask); } new->alphaPict = None; new->shadowPict = None; @@ -1539,6 +1550,8 @@ if (w->extents != None) XFixesCopyRegion (dpy, damage, w->extents); } + w->shape_bounds.x -= w->a.x; + w->shape_bounds.y -= w->a.y; w->a.x = ce->x; w->a.y = ce->y; if (w->a.width != ce->width || w->a.height != ce->height) @@ -1573,6 +1586,14 @@ XFixesDestroyRegion (dpy, extents); add_damage (dpy, damage); } + w->shape_bounds.x += w->a.x; + w->shape_bounds.y += w->a.y; + if (!w->shaped) + { + w->shape_bounds.width = w->a.width; + w->shape_bounds.height = w->a.height; + } + clipChanged = True; } @@ -1737,6 +1758,76 @@ repair_win (dpy, w); } +static const char * +shape_kind(int kind) +{ + static char buf[128]; + + switch(kind){ + case ShapeBounding: + return "ShapeBounding"; + case ShapeClip: + return "ShapeClip"; + case ShapeInput: + return "ShapeInput"; + default: + sprintf (buf, "Shape %d", kind); + return buf; + } +} + +static void +shape_win (Display *dpy, XShapeEvent *se) +{ + win *w = find_win (dpy, se->window); + + if (!w) + return; + + if (se->kind == ShapeClip || se->kind == ShapeBounding) + { + XserverRegion region0; + XserverRegion region1; + +#if 0 + printf("win 0x%lx %s:%s %ux%u+%d+%d\n", + (unsigned long) se->window, + shape_kind(se->kind), + (se->shaped == True) ? "true" : "false", + se->width, se->height, + se->x, se->y); +#endif + + clipChanged = True; + + region0 = XFixesCreateRegion (dpy, &w->shape_bounds, 1); + + if (se->shaped == True) + { + w->shaped = True; + w->shape_bounds.x = w->a.x + se->x; + w->shape_bounds.y = w->a.y + se->y; + w->shape_bounds.width = se->width; + w->shape_bounds.height = se->height; + } + else + { + w->shaped = False; + w->shape_bounds.x = w->a.x; + w->shape_bounds.y = w->a.y; + w->shape_bounds.width = w->a.width; + w->shape_bounds.height = w->a.height; + } + + region1 = XFixesCreateRegion (dpy, &w->shape_bounds, 1); + XFixesUnionRegion (dpy, region0, region0, region1); + XFixesDestroyRegion (dpy, region1); + + /* ask for repaint of the old and new region */ + paint_all (dpy, region0); + } +} + static int error (Display *dpy, XErrorEvent *ev) { @@ -1823,7 +1914,13 @@ return "Circulate"; default: if (ev->type == damage_event + XDamageNotify) + { return "Damage"; + } + else if (ev->type == xshape_event + ShapeNotify) + { + return "Shape"; + } sprintf (buf, "Event %d", ev->type); return buf; } @@ -1845,7 +1942,13 @@ return ev->xcirculate.window; default: if (ev->type == damage_event + XDamageNotify) + { return ((XDamageNotifyEvent *) ev)->drawable; + } + else if (ev->type == xshape_event + ShapeNotify) + { + return ((XShapeEvent *) ev)->window; + } return 0; } } @@ -2047,6 +2150,11 @@ fprintf (stderr, "No XFixes extension\n"); exit (1); } + if (!XShapeQueryExtension (dpy, &xshape_event, &xshape_error)) + { + fprintf (stderr, "No XShape extension\n"); + exit (1); + } if (!register_cm()) { @@ -2097,6 +2205,7 @@ ExposureMask| StructureNotifyMask| PropertyChangeMask); + XShapeSelectInput (dpy, root, ShapeNotifyMask); XQueryTree (dpy, root, &root_return, &parent_return, &children, &nchildren); for (i = 0; i < nchildren; i++) add_win (dpy, children[i], i ? children[i-1] : None); @@ -2225,7 +2334,13 @@ break; default: if (ev.type == damage_event + XDamageNotify) - damage_win (dpy, (XDamageNotifyEvent *) &ev); + { + damage_win (dpy, (XDamageNotifyEvent *) &ev); + } + else if (ev.type == xshape_event + ShapeNotify) + { + shape_win (dpy, (XShapeEvent *) &ev); + } break; } } while (QLength (dpy));