struct _win *prev_trans;
} win;
-win *list;
+typedef struct _conv {
+ int size;
+ double *data;
+} conv;
+win *list;
Display *dpy;
int scr;
Window root;
Picture rootPicture;
Picture rootBuffer;
Picture transPicture;
+Picture blackPicture;
Picture rootTile;
XserverRegion allDamage;
int root_height, root_width;
+conv *gussianMap;
#define BACKGROUND_PROP "_XROOTPMAP_ID"
-#define WINDOW_PLAIN 0
-#define WINDOW_DROP 1
-#define WINDOW_TRANS 2
+
+#define WINDOW_SOLID 0
+#define WINDOW_TRANS 1
+#define WINDOW_ARGB 2
+
#define TRANS_OPACITY 0.75
#define SHADOW_RADIUS 15
#define SHADOW_OPACITY 0.75
exp ((- (x * x + y * y)) / (2 * r * r)));
}
-typedef struct _conv {
- int size;
- double *data;
-} conv;
conv *
make_gaussian_map (Display *dpy, double r)
t += g;
c->data[y * size + x] = g;
}
- printf ("gaussian total %f\n", t);
+/* printf ("gaussian total %f\n", t); */
for (y = 0; y < size; y++)
for (x = 0; x < size; x++)
{
* center +-----+-------------------+-----+
*/
-unsigned int
+unsigned char
sum_gaussian (conv *map, double opacity, int x, int y, int width, int height)
{
int fx, fy;
if (v > 1)
v = 1;
- return ((unsigned int) (v * opacity * 255.0)) << 24;
+ return ((unsigned int) (v * opacity * 255.0));
}
XImage *
-make_shadow (Display *dpy, double opacity, double r, int width, int height)
+make_shadow (Display *dpy, double opacity, int width, int height)
{
- conv *map = make_gaussian_map (dpy, r);
XImage *ximage;
- double *gdata = map->data;
- unsigned int *data;
- int gsize = map->size;
+ double *gdata = gussianMap->data;
+ unsigned char *data;
+ int gsize = gussianMap->size;
int ylimit, xlimit;
int swidth = width + gsize;
int sheight = height + gsize;
int x, y;
int fx, fy;
int sx, sy;
- unsigned int d;
+ unsigned char d;
double v;
unsigned char c;
- data = malloc (swidth * sheight * sizeof (int));
+ data = malloc (swidth * sheight * sizeof (unsigned char));
ximage = XCreateImage (dpy,
DefaultVisual(dpy, DefaultScreen(dpy)),
- 32,
+ 8,
ZPixmap,
0,
(char *) data,
- swidth, sheight, 32, swidth * sizeof (int));
+ swidth, sheight, 8, swidth * sizeof (unsigned char));
/*
* Build the gaussian in sections
*/
for (y = 0; y < ylimit; y++)
for (x = 0; x < xlimit; x++)
{
- d = sum_gaussian (map, opacity, x - center, y - center, width, height);
+ d = sum_gaussian (gussianMap, opacity, x - center, y - center, width, height);
data[y * swidth + x] = d;
data[(sheight - y - 1) * swidth + x] = d;
data[(sheight - y - 1) * swidth + (swidth - x - 1)] = d;
*/
for (y = 0; y < ylimit; y++)
{
- d = sum_gaussian (map, opacity, center, y - center, width, height);
+ d = sum_gaussian (gussianMap, opacity, center, y - center, width, height);
for (x = gsize; x < swidth - gsize; x++)
{
data[y * swidth + x] = d;
for (x = 0; x < xlimit; x++)
{
- d = sum_gaussian (map, opacity, x - center, center, width, height);
+ d = sum_gaussian (gussianMap, opacity, x - center, center, width, height);
for (y = gsize; y < sheight - gsize; y++)
{
data[y * swidth + x] = d;
* center
*/
- d = sum_gaussian (map, opacity, center, center, width, height);
+ d = sum_gaussian (gussianMap, opacity, center, center, width, height);
for (y = ylimit; y < sheight - ylimit; y++)
for (x = xlimit; x < swidth - xlimit; x++)
data[y * swidth + x] = d;
- free (map);
return ximage;
}
Picture
-shadow_picture (Display *dpy, double opacity, double r, int width, int height, int *wp, int *hp)
+shadow_picture (Display *dpy, double opacity, int width, int height, int *wp, int *hp)
{
- XImage *shadowImage = make_shadow (dpy, opacity, r, width, height);
+ XImage *shadowImage = make_shadow (dpy, opacity, width, height);
Pixmap shadowPixmap = XCreatePixmap (dpy, root,
shadowImage->width,
shadowImage->height,
- 32);
+ 8);
Picture shadowPicture = XRenderCreatePicture (dpy, shadowPixmap,
- XRenderFindStandardFormat (dpy, PictStandardARGB32),
+ XRenderFindStandardFormat (dpy, PictStandardA8),
0, 0);
GC gc = XCreateGC (dpy, shadowPixmap, 0, 0);
{
XRectangle r;
- if (!w->shadow)
+ if (w->mode == WINDOW_ARGB)
{
- double opacity = SHADOW_OPACITY;
- if (w->mode == WINDOW_TRANS)
- opacity = opacity * TRANS_OPACITY;
- w->shadow = shadow_picture (dpy, opacity, SHADOW_RADIUS,
- w->a.width, w->a.height,
- &w->shadow_width, &w->shadow_height);
- w->shadow_dx = SHADOW_OFFSET_X;
- w->shadow_dy = SHADOW_OFFSET_Y;
+ r.x = w->a.x;
+ r.y = w->a.y;
+ r.width = w->a.width + w->a.border_width * 2;
+ r.height = w->a.height + w->a.border_width * 2;
+ }
+ else
+ {
+ 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.height,
+ &w->shadow_width, &w->shadow_height);
+ w->shadow_dx = SHADOW_OFFSET_X;
+ w->shadow_dy = SHADOW_OFFSET_Y;
+ }
+ r.x = w->a.x + w->a.border_width + w->shadow_dx;
+ r.y = w->a.y + w->a.border_width + w->shadow_dy;
+ r.width = w->shadow_width;
+ r.height = w->shadow_height;
}
- r.x = w->a.x + w->a.border_width + w->shadow_dx;
- r.y = w->a.y + w->a.border_width + w->shadow_dy;
- r.width = w->shadow_width;
- r.height = w->shadow_height;
return XFixesCreateRegion (dpy, &r, 1);
}
if (w->extents)
XFixesDestroyRegion (dpy, w->extents);
w->extents = win_extents (dpy, w);
- if (w->mode != WINDOW_TRANS)
+ if (w->mode == WINDOW_SOLID)
{
XFixesSetPictureClipRegion (dpy, rootBuffer, 0, 0, region);
XFixesSubtractRegion (dpy, region, region, 0, 0, w->borderSize, 0, 0);
XFixesSetPictureClipRegion (dpy, rootBuffer, 0, 0, w->borderClip);
if (w->shadow)
{
- XRenderComposite (dpy, PictOpOver, w->shadow, None, rootBuffer,
+ XRenderComposite (dpy, PictOpOver, blackPicture, w->shadow, rootBuffer,
0, 0, 0, 0,
w->a.x + w->a.border_width + w->shadow_dx,
w->a.y + w->a.border_width + w->shadow_dy,
w->a.y + w->a.border_width,
w->a.width,
w->a.height);
+ else if (w->mode == WINDOW_ARGB)
+ XRenderComposite (dpy, PictOpOver, w->picture, None, rootBuffer,
+ 0, 0, 0, 0,
+ w->a.x + w->a.border_width,
+ w->a.y + w->a.border_width,
+ w->a.width,
+ w->a.height);
XFixesDestroyRegion (dpy, w->borderClip);
w->borderClip = None;
}
void
add_win (Display *dpy, Window id, Window prev)
{
- win *new = malloc (sizeof (win));
- win **p;
- XWindowAttributes a;
- XRenderPictureAttributes pa;
+ win *new = malloc (sizeof (win));
+ win **p;
+ XWindowAttributes a;
+ XRenderPictureAttributes pa;
+ XRenderPictFormat *format;
if (!new)
return;
new->damage = None;
pa.subwindow_mode = IncludeInferiors;
if (new->a.class == InputOnly)
+ {
new->picture = 0;
+ format = 0;
+ }
else
{
+ format = XRenderFindVisualFormat (dpy, new->a.visual);
new->picture = XRenderCreatePicture (dpy, id,
- XRenderFindVisualFormat (dpy,
- new->a.visual),
+ format,
CPSubwindowMode,
&pa);
}
new->shadow = None;
new->borderSize = None;
new->extents = None;
- if (new->a.override_redirect)
+ if (format && format->type == PictTypeDirect && format->direct.alphaMask)
+ new->mode = WINDOW_ARGB;
+ else if (new->a.override_redirect)
new->mode = WINDOW_TRANS;
else
- new->mode = WINDOW_DROP;
+ new->mode = WINDOW_SOLID;
new->next = *p;
*p = new;
if (new->a.map_state == IsViewable)
return(tp.tv_sec * 1000) + (tp.tv_usec / 1000);
}
-#define INTERVAL 30
+#define INTERVAL 0
main ()
{
Window root_return, parent_return;
Window *children;
Pixmap transPixmap;
+ Pixmap blackPixmap;
unsigned int nchildren;
int i;
int damage_event, damage_error;
int n;
int last_update;
int now;
+#if INTERVAL
int timeout;
+#endif
dpy = XOpenDisplay (0);
if (!dpy)
scr = DefaultScreen (dpy);
root = RootWindow (dpy, scr);
pa.subwindow_mode = IncludeInferiors;
+
+ gussianMap = make_gaussian_map(dpy, SHADOW_RADIUS);
+
transPixmap = XCreatePixmap (dpy, root, 1, 1, 8);
pa.repeat = True;
transPicture = XRenderCreatePicture (dpy, transPixmap,
DefaultVisual (dpy, scr)),
CPSubwindowMode,
&pa);
+ blackPixmap = XCreatePixmap (dpy, root, 1, 1, 32);
+ pa.repeat = True;
+ blackPicture = XRenderCreatePicture (dpy, blackPixmap,
+ XRenderFindStandardFormat (dpy, PictStandardARGB32),
+ CPRepeat,
+ &pa);
+ c.red = c.green = c.blue = 0;
+ c.alpha = 0xffff;
+ XRenderFillRectangle (dpy, PictOpSrc, blackPicture, &c, 0, 0, 1, 1);
if (!XCompositeQueryExtension (dpy, &event_base, &error_base))
{
fprintf (stderr, "No composite extension\n");
allDamage = None;
XGrabServer (dpy);
XCompositeRedirectSubwindows (dpy, root, CompositeRedirectManual);
- paint_all (dpy, None);
XSelectInput (dpy, root,
SubstructureNotifyMask|
ExposureMask|
add_win (dpy, children[i], i ? children[i-1] : None);
XFree (children);
XUngrabServer (dpy);
+ paint_all (dpy, None);
+#if INTERVAL
last_update = time_in_millis ();
+#endif
for (;;)
{
+#if INTERVAL
+ int busy_start = 0;
+#endif
/* dump_wins (); */
do {
XNextEvent (dpy, &ev);
+#if INTERVAL
+ if (!busy_start)
+ busy_start = time_in_millis();
+#endif
/* printf ("event %d\n", ev.type); */
switch (ev.type) {
case CreateNotify:
break;
}
} while (XEventsQueued (dpy, QueuedAfterReading));
+#if INTERVAL
now = time_in_millis ();
+/* printf ("\t\tbusy %d\n", now - busy_start); */
timeout = INTERVAL - (now - last_update);
if (timeout > 0)
{
if (n > 0 && (ufd.revents & POLLIN) && XEventsQueued (dpy, QueuedAfterReading))
continue;
}
- last_update = time_in_millis();
+#endif
if (allDamage)
{
+#if INTERVAL
+ int old_update = last_update;
+ last_update = time_in_millis();
+/* printf ("delta %d\n", last_update - old_update); */
+#endif
paint_all (dpy, allDamage);
allDamage = None;
}