Rename gussianMap to gaussianMap (who the heck is gus?) Allow for other
names for the root pixmap Handle non-zero border widths better (need Composite change to display them though). Add MONITOR_UPDATE mode that eliminates double buffering and blanks the screen to make sequence of update operations visible. Leave damage object around to catch map damage right. Add CirculateNotify support.
This commit is contained in:
parent
c676d32456
commit
df3dc087f8
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
||||||
|
2003-11-23 Keith Packard <keithp@keithp.com>
|
||||||
|
|
||||||
|
* xcompmgr.c: (make_shadow), (root_tile), (win_extents),
|
||||||
|
(border_size), (paint_all), (repair_win), (map_win), (unmap_win),
|
||||||
|
(add_win), (restack_win), (configure_win), (circulate_win),
|
||||||
|
(destroy_win), (ev_serial), (ev_name), (ev_window), (main):
|
||||||
|
|
||||||
|
Rename gussianMap to gaussianMap (who the heck is gus?)
|
||||||
|
Allow for other names for the root pixmap
|
||||||
|
Handle non-zero border widths better (need Composite change
|
||||||
|
to display them though).
|
||||||
|
Add MONITOR_UPDATE mode that eliminates double buffering and
|
||||||
|
blanks the screen to make sequence of update operations visible.
|
||||||
|
Leave damage object around to catch map damage right.
|
||||||
|
Add CirculateNotify support.
|
||||||
|
|
||||||
2003-11-23 Eric Anholt <anholt@FreeBSD.org>
|
2003-11-23 Eric Anholt <anholt@FreeBSD.org>
|
||||||
|
|
||||||
* xcompmgr.c: (border_size), (paint_all), (add_damage),
|
* xcompmgr.c: (border_size), (paint_all), (add_damage),
|
||||||
|
|
337
xcompmgr.c
337
xcompmgr.c
|
@ -39,8 +39,8 @@ typedef struct _win {
|
||||||
struct _win *next;
|
struct _win *next;
|
||||||
Window id;
|
Window id;
|
||||||
XWindowAttributes a;
|
XWindowAttributes a;
|
||||||
int damaged;
|
|
||||||
int mode;
|
int mode;
|
||||||
|
int damaged;
|
||||||
Damage damage;
|
Damage damage;
|
||||||
Picture picture;
|
Picture picture;
|
||||||
XserverRegion borderSize;
|
XserverRegion borderSize;
|
||||||
|
@ -51,6 +51,8 @@ typedef struct _win {
|
||||||
int shadow_width;
|
int shadow_width;
|
||||||
int shadow_height;
|
int shadow_height;
|
||||||
|
|
||||||
|
unsigned long damage_sequence; /* sequence when damage was created */
|
||||||
|
|
||||||
/* for drawing translucent windows */
|
/* for drawing translucent windows */
|
||||||
XserverRegion borderClip;
|
XserverRegion borderClip;
|
||||||
struct _win *prev_trans;
|
struct _win *prev_trans;
|
||||||
|
@ -72,9 +74,7 @@ Picture blackPicture;
|
||||||
Picture rootTile;
|
Picture rootTile;
|
||||||
XserverRegion allDamage;
|
XserverRegion allDamage;
|
||||||
int root_height, root_width;
|
int root_height, root_width;
|
||||||
conv *gussianMap;
|
conv *gaussianMap;
|
||||||
|
|
||||||
#define BACKGROUND_PROP "_XROOTPMAP_ID"
|
|
||||||
|
|
||||||
#define WINDOW_SOLID 0
|
#define WINDOW_SOLID 0
|
||||||
#define WINDOW_TRANS 1
|
#define WINDOW_TRANS 1
|
||||||
|
@ -86,6 +86,8 @@ conv *gussianMap;
|
||||||
#define SHADOW_OFFSET_X (-SHADOW_RADIUS)
|
#define SHADOW_OFFSET_X (-SHADOW_RADIUS)
|
||||||
#define SHADOW_OFFSET_Y (-SHADOW_RADIUS)
|
#define SHADOW_OFFSET_Y (-SHADOW_RADIUS)
|
||||||
|
|
||||||
|
#define DEBUG 0
|
||||||
|
#define MONITOR_REPAINT 0
|
||||||
|
|
||||||
static double
|
static double
|
||||||
gaussian (double r, double x, double y)
|
gaussian (double r, double x, double y)
|
||||||
|
@ -199,7 +201,7 @@ make_shadow (Display *dpy, double opacity, int width, int height)
|
||||||
{
|
{
|
||||||
XImage *ximage;
|
XImage *ximage;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
int gsize = gussianMap->size;
|
int gsize = gaussianMap->size;
|
||||||
int ylimit, xlimit;
|
int ylimit, xlimit;
|
||||||
int swidth = width + gsize;
|
int swidth = width + gsize;
|
||||||
int sheight = height + gsize;
|
int sheight = height + gsize;
|
||||||
|
@ -232,7 +234,7 @@ make_shadow (Display *dpy, double opacity, int width, int height)
|
||||||
for (y = 0; y < ylimit; y++)
|
for (y = 0; y < ylimit; y++)
|
||||||
for (x = 0; x < xlimit; x++)
|
for (x = 0; x < xlimit; x++)
|
||||||
{
|
{
|
||||||
d = sum_gaussian (gussianMap, opacity, x - center, y - center, width, height);
|
d = sum_gaussian (gaussianMap, opacity, x - center, y - center, width, height);
|
||||||
data[y * swidth + x] = d;
|
data[y * swidth + x] = d;
|
||||||
data[(sheight - y - 1) * swidth + x] = d;
|
data[(sheight - y - 1) * swidth + x] = d;
|
||||||
data[(sheight - y - 1) * swidth + (swidth - x - 1)] = d;
|
data[(sheight - y - 1) * swidth + (swidth - x - 1)] = d;
|
||||||
|
@ -244,7 +246,7 @@ make_shadow (Display *dpy, double opacity, int width, int height)
|
||||||
*/
|
*/
|
||||||
for (y = 0; y < ylimit; y++)
|
for (y = 0; y < ylimit; y++)
|
||||||
{
|
{
|
||||||
d = sum_gaussian (gussianMap, opacity, center, y - center, width, height);
|
d = sum_gaussian (gaussianMap, opacity, center, y - center, width, height);
|
||||||
for (x = gsize; x < swidth - gsize; x++)
|
for (x = gsize; x < swidth - gsize; x++)
|
||||||
{
|
{
|
||||||
data[y * swidth + x] = d;
|
data[y * swidth + x] = d;
|
||||||
|
@ -258,7 +260,7 @@ make_shadow (Display *dpy, double opacity, int width, int height)
|
||||||
|
|
||||||
for (x = 0; x < xlimit; x++)
|
for (x = 0; x < xlimit; x++)
|
||||||
{
|
{
|
||||||
d = sum_gaussian (gussianMap, opacity, x - center, center, width, height);
|
d = sum_gaussian (gaussianMap, opacity, x - center, center, width, height);
|
||||||
for (y = gsize; y < sheight - gsize; y++)
|
for (y = gsize; y < sheight - gsize; y++)
|
||||||
{
|
{
|
||||||
data[y * swidth + x] = d;
|
data[y * swidth + x] = d;
|
||||||
|
@ -270,7 +272,7 @@ make_shadow (Display *dpy, double opacity, int width, int height)
|
||||||
* center
|
* center
|
||||||
*/
|
*/
|
||||||
|
|
||||||
d = sum_gaussian (gussianMap, opacity, center, center, width, height);
|
d = sum_gaussian (gaussianMap, opacity, center, center, width, height);
|
||||||
for (y = ylimit; y < sheight - ylimit; y++)
|
for (y = ylimit; y < sheight - ylimit; y++)
|
||||||
for (x = xlimit; x < swidth - xlimit; x++)
|
for (x = xlimit; x < swidth - xlimit; x++)
|
||||||
data[y * swidth + x] = d;
|
data[y * swidth + x] = d;
|
||||||
|
@ -313,6 +315,12 @@ find_win (Display *dpy, Window id)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *backgroundProps[] = {
|
||||||
|
"_XROOTPMAP_ID",
|
||||||
|
"_XSETROOT_ID",
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
static Picture
|
static Picture
|
||||||
root_tile (Display *dpy)
|
root_tile (Display *dpy)
|
||||||
{
|
{
|
||||||
|
@ -325,17 +333,22 @@ root_tile (Display *dpy)
|
||||||
unsigned char *prop;
|
unsigned char *prop;
|
||||||
Bool fill;
|
Bool fill;
|
||||||
XRenderPictureAttributes pa;
|
XRenderPictureAttributes pa;
|
||||||
|
int p;
|
||||||
|
|
||||||
if (XGetWindowProperty (dpy, root, XInternAtom (dpy, BACKGROUND_PROP, False),
|
for (p = 0; backgroundProps[p]; p++)
|
||||||
0, 4, False, AnyPropertyType,
|
|
||||||
&actual_type, &actual_format, &nitems, &bytes_after, &prop) == Success &&
|
|
||||||
actual_type == XInternAtom (dpy, "PIXMAP", False) && actual_format == 32 && nitems == 1)
|
|
||||||
{
|
{
|
||||||
memcpy (&pixmap, prop, 4);
|
if (XGetWindowProperty (dpy, root, XInternAtom (dpy, backgroundProps[p], False),
|
||||||
XFree (prop);
|
0, 4, False, AnyPropertyType,
|
||||||
fill = False;
|
&actual_type, &actual_format, &nitems, &bytes_after, &prop) == Success &&
|
||||||
|
actual_type == XInternAtom (dpy, "PIXMAP", False) && actual_format == 32 && nitems == 1)
|
||||||
|
{
|
||||||
|
memcpy (&pixmap, prop, 4);
|
||||||
|
XFree (prop);
|
||||||
|
fill = False;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
if (!backgroundProps[p])
|
||||||
{
|
{
|
||||||
pixmap = XCreatePixmap (dpy, root, 1, 1, DefaultDepth (dpy, scr));
|
pixmap = XCreatePixmap (dpy, root, 1, 1, DefaultDepth (dpy, scr));
|
||||||
fill = True;
|
fill = True;
|
||||||
|
@ -373,30 +386,44 @@ win_extents (Display *dpy, win *w)
|
||||||
{
|
{
|
||||||
XRectangle r;
|
XRectangle r;
|
||||||
|
|
||||||
if (w->mode == WINDOW_ARGB)
|
r.x = w->a.x;
|
||||||
{
|
r.y = w->a.y;
|
||||||
r.x = w->a.x;
|
r.width = w->a.width + w->a.border_width * 2;
|
||||||
r.y = w->a.y;
|
r.height = w->a.height + w->a.border_width * 2;
|
||||||
r.width = w->a.width + w->a.border_width * 2;
|
if (w->mode != WINDOW_ARGB)
|
||||||
r.height = w->a.height + w->a.border_width * 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
XRectangle sr;
|
||||||
|
|
||||||
if (!w->shadow)
|
if (!w->shadow)
|
||||||
{
|
{
|
||||||
double opacity = SHADOW_OPACITY;
|
double opacity = SHADOW_OPACITY;
|
||||||
if (w->mode == WINDOW_TRANS)
|
if (w->mode == WINDOW_TRANS)
|
||||||
opacity = opacity * TRANS_OPACITY;
|
opacity = opacity * TRANS_OPACITY;
|
||||||
w->shadow = shadow_picture (dpy, opacity,
|
w->shadow = shadow_picture (dpy, opacity,
|
||||||
w->a.width, w->a.height,
|
w->a.width + w->a.border_width * 2,
|
||||||
|
w->a.height + w->a.border_width * 2,
|
||||||
&w->shadow_width, &w->shadow_height);
|
&w->shadow_width, &w->shadow_height);
|
||||||
w->shadow_dx = SHADOW_OFFSET_X;
|
w->shadow_dx = SHADOW_OFFSET_X;
|
||||||
w->shadow_dy = SHADOW_OFFSET_Y;
|
w->shadow_dy = SHADOW_OFFSET_Y;
|
||||||
}
|
}
|
||||||
r.x = w->a.x + w->a.border_width + w->shadow_dx;
|
sr.x = w->a.x + w->shadow_dx;
|
||||||
r.y = w->a.y + w->a.border_width + w->shadow_dy;
|
sr.y = w->a.y + w->shadow_dy;
|
||||||
r.width = w->shadow_width;
|
sr.width = w->shadow_width;
|
||||||
r.height = w->shadow_height;
|
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.width > r.width)
|
||||||
|
r.width = sr.width;
|
||||||
|
if (sr.height > r.height)
|
||||||
|
r.height = sr.height;
|
||||||
}
|
}
|
||||||
return XFixesCreateRegion (dpy, &r, 1);
|
return XFixesCreateRegion (dpy, &r, 1);
|
||||||
}
|
}
|
||||||
|
@ -406,7 +433,10 @@ border_size (Display *dpy, win *w)
|
||||||
{
|
{
|
||||||
XserverRegion border;
|
XserverRegion border;
|
||||||
border = XFixesCreateRegionFromWindow (dpy, w->id, WindowRegionBounding);
|
border = XFixesCreateRegionFromWindow (dpy, w->id, WindowRegionBounding);
|
||||||
XFixesTranslateRegion (dpy, border, w->a.x, w->a.y);
|
/* translate this */
|
||||||
|
XFixesTranslateRegion (dpy, border,
|
||||||
|
w->a.x + w->a.border_width,
|
||||||
|
w->a.y + w->a.border_width);
|
||||||
return border;
|
return border;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,6 +455,9 @@ paint_all (Display *dpy, XserverRegion region)
|
||||||
r.height = root_height;
|
r.height = root_height;
|
||||||
region = XFixesCreateRegion (dpy, &r, 1);
|
region = XFixesCreateRegion (dpy, &r, 1);
|
||||||
}
|
}
|
||||||
|
#if MONITOR_REPAINT
|
||||||
|
rootBuffer = rootPicture;
|
||||||
|
#else
|
||||||
if (!rootBuffer)
|
if (!rootBuffer)
|
||||||
{
|
{
|
||||||
Pixmap rootPixmap = XCreatePixmap (dpy, root, root_width, root_height,
|
Pixmap rootPixmap = XCreatePixmap (dpy, root, root_width, root_height,
|
||||||
|
@ -435,14 +468,27 @@ paint_all (Display *dpy, XserverRegion region)
|
||||||
0, 0);
|
0, 0);
|
||||||
XFreePixmap (dpy, rootPixmap);
|
XFreePixmap (dpy, rootPixmap);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
XFixesSetPictureClipRegion (dpy, rootPicture, 0, 0, region);
|
XFixesSetPictureClipRegion (dpy, rootPicture, 0, 0, region);
|
||||||
|
#if MONITOR_REPAINT
|
||||||
|
XRenderComposite (dpy, PictOpSrc, blackPicture, None, rootPicture,
|
||||||
|
0, 0, 0, 0, 0, 0, root_width, root_height);
|
||||||
|
#endif
|
||||||
|
#if DEBUG
|
||||||
|
printf ("paint:");
|
||||||
|
#endif
|
||||||
for (w = list; w; w = w->next)
|
for (w = list; w; w = w->next)
|
||||||
{
|
{
|
||||||
if (w->a.map_state != IsViewable)
|
if (w->a.map_state != IsViewable)
|
||||||
continue;
|
continue;
|
||||||
|
/* never painted, ignore it */
|
||||||
|
if (!w->damaged)
|
||||||
|
continue;
|
||||||
if (!w->picture)
|
if (!w->picture)
|
||||||
continue;
|
continue;
|
||||||
|
#if DEBUG
|
||||||
|
printf (" 0x%x", w->id);
|
||||||
|
#endif
|
||||||
if (w->borderSize)
|
if (w->borderSize)
|
||||||
XFixesDestroyRegion (dpy, w->borderSize);
|
XFixesDestroyRegion (dpy, w->borderSize);
|
||||||
w->borderSize = border_size (dpy, w);
|
w->borderSize = border_size (dpy, w);
|
||||||
|
@ -465,6 +511,9 @@ paint_all (Display *dpy, XserverRegion region)
|
||||||
w->prev_trans = t;
|
w->prev_trans = t;
|
||||||
t = w;
|
t = w;
|
||||||
}
|
}
|
||||||
|
#if DEBUG
|
||||||
|
printf ("\n");
|
||||||
|
#endif
|
||||||
XFixesSetPictureClipRegion (dpy, rootBuffer, 0, 0, region);
|
XFixesSetPictureClipRegion (dpy, rootBuffer, 0, 0, region);
|
||||||
paint_root (dpy);
|
paint_root (dpy);
|
||||||
for (w = t; w; w = w->prev_trans)
|
for (w = t; w; w = w->prev_trans)
|
||||||
|
@ -474,8 +523,8 @@ paint_all (Display *dpy, XserverRegion region)
|
||||||
{
|
{
|
||||||
XRenderComposite (dpy, PictOpOver, blackPicture, w->shadow, rootBuffer,
|
XRenderComposite (dpy, PictOpOver, blackPicture, w->shadow, rootBuffer,
|
||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
w->a.x + w->a.border_width + w->shadow_dx,
|
w->a.x + w->shadow_dx,
|
||||||
w->a.y + w->a.border_width + w->shadow_dy,
|
w->a.y + w->shadow_dy,
|
||||||
w->shadow_width, w->shadow_height);
|
w->shadow_width, w->shadow_height);
|
||||||
}
|
}
|
||||||
if (w->mode == WINDOW_TRANS)
|
if (w->mode == WINDOW_TRANS)
|
||||||
|
@ -496,9 +545,12 @@ paint_all (Display *dpy, XserverRegion region)
|
||||||
w->borderClip = None;
|
w->borderClip = None;
|
||||||
}
|
}
|
||||||
XFixesDestroyRegion (dpy, region);
|
XFixesDestroyRegion (dpy, region);
|
||||||
XFixesSetPictureClipRegion (dpy, rootBuffer, 0, 0, None);
|
if (rootBuffer != rootPicture)
|
||||||
XRenderComposite (dpy, PictOpSrc, rootBuffer, None, rootPicture,
|
{
|
||||||
0, 0, 0, 0, 0, 0, root_width, root_height);
|
XFixesSetPictureClipRegion (dpy, rootBuffer, 0, 0, None);
|
||||||
|
XRenderComposite (dpy, PictOpSrc, rootBuffer, None, rootPicture,
|
||||||
|
0, 0, 0, 0, 0, 0, root_width, root_height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -521,28 +573,32 @@ repair_win (Display *dpy, Window id)
|
||||||
|
|
||||||
if (!w)
|
if (!w)
|
||||||
return;
|
return;
|
||||||
/* printf ("repair 0x%x\n", w->id); */
|
if (!w->damaged)
|
||||||
parts = XFixesCreateRegion (dpy, 0, 0);
|
{
|
||||||
XDamageSubtract (dpy, w->damage, None, parts);
|
parts = win_extents (dpy, w);
|
||||||
XFixesTranslateRegion (dpy, parts, w->a.x, w->a.y);
|
XDamageSubtract (dpy, w->damage, None, None);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parts = XFixesCreateRegion (dpy, 0, 0);
|
||||||
|
XDamageSubtract (dpy, w->damage, None, parts);
|
||||||
|
XFixesTranslateRegion (dpy, parts,
|
||||||
|
w->a.x + w->a.border_width,
|
||||||
|
w->a.y + w->a.border_width);
|
||||||
|
}
|
||||||
add_damage (dpy, parts);
|
add_damage (dpy, parts);
|
||||||
|
w->damaged = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
map_win (Display *dpy, Window id)
|
map_win (Display *dpy, Window id, unsigned long sequence)
|
||||||
{
|
{
|
||||||
win *w = find_win (dpy, id);
|
win *w = find_win (dpy, id);
|
||||||
XserverRegion region;
|
|
||||||
|
|
||||||
if (!w)
|
if (!w)
|
||||||
return;
|
return;
|
||||||
w->a.map_state = IsViewable;
|
w->a.map_state = IsViewable;
|
||||||
if (w->picture)
|
w->damaged = 0;
|
||||||
{
|
|
||||||
w->damage = XDamageCreate (dpy, id, XDamageReportNonEmpty);
|
|
||||||
region = win_extents (dpy, w);
|
|
||||||
add_damage (dpy, region);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -553,11 +609,7 @@ unmap_win (Display *dpy, Window id)
|
||||||
if (!w)
|
if (!w)
|
||||||
return;
|
return;
|
||||||
w->a.map_state = IsUnmapped;
|
w->a.map_state = IsUnmapped;
|
||||||
if (w->damage != None)
|
w->damaged = 0;
|
||||||
{
|
|
||||||
XDamageDestroy (dpy, w->damage);
|
|
||||||
w->damage = None;
|
|
||||||
}
|
|
||||||
if (w->extents != None)
|
if (w->extents != None)
|
||||||
{
|
{
|
||||||
add_damage (dpy, w->extents); /* destroys region */
|
add_damage (dpy, w->extents); /* destroys region */
|
||||||
|
@ -589,6 +641,7 @@ add_win (Display *dpy, Window id, Window prev)
|
||||||
free (new);
|
free (new);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
new->damage = None;
|
||||||
new->damaged = 0;
|
new->damaged = 0;
|
||||||
new->damage = None;
|
new->damage = None;
|
||||||
pa.subwindow_mode = IncludeInferiors;
|
pa.subwindow_mode = IncludeInferiors;
|
||||||
|
@ -596,6 +649,7 @@ add_win (Display *dpy, Window id, Window prev)
|
||||||
{
|
{
|
||||||
new->picture = 0;
|
new->picture = 0;
|
||||||
format = 0;
|
format = 0;
|
||||||
|
new->damage_sequence = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -604,9 +658,15 @@ add_win (Display *dpy, Window id, Window prev)
|
||||||
format,
|
format,
|
||||||
CPSubwindowMode,
|
CPSubwindowMode,
|
||||||
&pa);
|
&pa);
|
||||||
|
new->damage_sequence = NextRequest (dpy);
|
||||||
|
new->damage = XDamageCreate (dpy, id, XDamageReportNonEmpty);
|
||||||
}
|
}
|
||||||
|
|
||||||
new->shadow = None;
|
new->shadow = None;
|
||||||
|
new->shadow_dx = 0;
|
||||||
|
new->shadow_dy = 0;
|
||||||
|
new->shadow_width = 0;
|
||||||
|
new->shadow_height = 0;
|
||||||
new->borderSize = None;
|
new->borderSize = None;
|
||||||
new->extents = None;
|
new->extents = None;
|
||||||
if (format && format->type == PictTypeDirect && format->direct.alphaMask)
|
if (format && format->type == PictTypeDirect && format->direct.alphaMask)
|
||||||
|
@ -618,7 +678,37 @@ add_win (Display *dpy, Window id, Window prev)
|
||||||
new->next = *p;
|
new->next = *p;
|
||||||
*p = new;
|
*p = new;
|
||||||
if (new->a.map_state == IsViewable)
|
if (new->a.map_state == IsViewable)
|
||||||
map_win (dpy, id);
|
map_win (dpy, id, new->damage_sequence - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
restack_win (Display *dpy, win *w, Window new_above)
|
||||||
|
{
|
||||||
|
Window old_above;
|
||||||
|
|
||||||
|
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
|
static void
|
||||||
|
@ -660,29 +750,7 @@ configure_win (Display *dpy, XConfigureEvent *ce)
|
||||||
w->a.height = ce->height;
|
w->a.height = ce->height;
|
||||||
w->a.border_width = ce->border_width;
|
w->a.border_width = ce->border_width;
|
||||||
w->a.override_redirect = ce->override_redirect;
|
w->a.override_redirect = ce->override_redirect;
|
||||||
if (w->next)
|
restack_win (dpy, w, ce->above);
|
||||||
above = w->next->id;
|
|
||||||
else
|
|
||||||
above = None;
|
|
||||||
if (above != ce->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 == ce->above)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
w->next = *prev;
|
|
||||||
*prev = w;
|
|
||||||
}
|
|
||||||
if (damage)
|
if (damage)
|
||||||
{
|
{
|
||||||
XserverRegion extents = win_extents (dpy, w);
|
XserverRegion extents = win_extents (dpy, w);
|
||||||
|
@ -692,6 +760,19 @@ configure_win (Display *dpy, XConfigureEvent *ce)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
circulate_win (Display *dpy, XCirculateEvent *ce)
|
||||||
|
{
|
||||||
|
win *w = find_win (dpy, ce->window);
|
||||||
|
Window new_above;
|
||||||
|
|
||||||
|
if (ce->place == PlaceOnTop)
|
||||||
|
new_above = list->id;
|
||||||
|
else
|
||||||
|
new_above = None;
|
||||||
|
restack_win (dpy, w, new_above);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
destroy_win (Display *dpy, Window id, Bool gone)
|
destroy_win (Display *dpy, Window id, Bool gone)
|
||||||
{
|
{
|
||||||
|
@ -701,12 +782,12 @@ destroy_win (Display *dpy, Window id, Bool gone)
|
||||||
if (w->id == id)
|
if (w->id == id)
|
||||||
{
|
{
|
||||||
if (!gone)
|
if (!gone)
|
||||||
{
|
|
||||||
unmap_win (dpy, id);
|
unmap_win (dpy, id);
|
||||||
if (w->picture)
|
|
||||||
XRenderFreePicture (dpy, w->picture);
|
|
||||||
}
|
|
||||||
*prev = w->next;
|
*prev = w->next;
|
||||||
|
if (w->picture)
|
||||||
|
XRenderFreePicture (dpy, w->picture);
|
||||||
|
if (w->damage != None)
|
||||||
|
XDamageDestroy (dpy, w->damage);
|
||||||
free (w);
|
free (w);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -768,8 +849,64 @@ time_in_millis (void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define INTERVAL 0
|
||||||
|
|
||||||
|
static int
|
||||||
|
ev_serial (XEvent *ev)
|
||||||
|
{
|
||||||
|
if (ev->type & 0x7f != KeymapNotify)
|
||||||
|
return ev->xany.serial;
|
||||||
|
return NextRequest (ev->xany.display);
|
||||||
|
}
|
||||||
|
|
||||||
|
int damage_event, damage_error;
|
||||||
|
|
||||||
|
static char *
|
||||||
|
ev_name (XEvent *ev)
|
||||||
|
{
|
||||||
|
static char buf[128];
|
||||||
|
switch (ev->type & 0x7f) {
|
||||||
|
case Expose:
|
||||||
|
return "Expose";
|
||||||
|
case MapNotify:
|
||||||
|
return "Map";
|
||||||
|
case UnmapNotify:
|
||||||
|
return "Unmap";
|
||||||
|
case ReparentNotify:
|
||||||
|
return "Reparent";
|
||||||
|
case CirculateNotify:
|
||||||
|
return "Circulate";
|
||||||
|
default:
|
||||||
|
if (ev->type == damage_event + XDamageNotify)
|
||||||
|
return "Damage";
|
||||||
|
sprintf (buf, "Event %d", ev->type);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Window
|
||||||
|
ev_window (XEvent *ev)
|
||||||
|
{
|
||||||
|
switch (ev->type) {
|
||||||
|
case Expose:
|
||||||
|
return ev->xexpose.window;
|
||||||
|
case MapNotify:
|
||||||
|
return ev->xmap.window;
|
||||||
|
case UnmapNotify:
|
||||||
|
return ev->xunmap.window;
|
||||||
|
case ReparentNotify:
|
||||||
|
return ev->xreparent.window;
|
||||||
|
case CirculateNotify:
|
||||||
|
return ev->xcirculate.window;
|
||||||
|
default:
|
||||||
|
if (ev->type == damage_event + XDamageNotify)
|
||||||
|
return ((XDamageNotifyEvent *) ev)->drawable;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (void)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
XEvent ev;
|
XEvent ev;
|
||||||
int event_base, error_base;
|
int event_base, error_base;
|
||||||
|
@ -779,13 +916,17 @@ main (void)
|
||||||
Pixmap blackPixmap;
|
Pixmap blackPixmap;
|
||||||
unsigned int nchildren;
|
unsigned int nchildren;
|
||||||
int i;
|
int i;
|
||||||
int damage_event, damage_error;
|
|
||||||
int xfixes_event, xfixes_error;
|
int xfixes_event, xfixes_error;
|
||||||
XRenderPictureAttributes pa;
|
XRenderPictureAttributes pa;
|
||||||
XRenderColor c;
|
XRenderColor c;
|
||||||
XRectangle *expose_rects = 0;
|
XRectangle *expose_rects = 0;
|
||||||
int size_expose = 0;
|
int size_expose = 0;
|
||||||
int n_expose = 0;
|
int n_expose = 0;
|
||||||
|
struct pollfd ufd;
|
||||||
|
int n;
|
||||||
|
int last_update;
|
||||||
|
int now;
|
||||||
|
int p;
|
||||||
#if INTERVAL
|
#if INTERVAL
|
||||||
int timeout;
|
int timeout;
|
||||||
#endif
|
#endif
|
||||||
|
@ -801,7 +942,7 @@ main (void)
|
||||||
root = RootWindow (dpy, scr);
|
root = RootWindow (dpy, scr);
|
||||||
pa.subwindow_mode = IncludeInferiors;
|
pa.subwindow_mode = IncludeInferiors;
|
||||||
|
|
||||||
gussianMap = make_gaussian_map(dpy, SHADOW_RADIUS);
|
gaussianMap = make_gaussian_map(dpy, SHADOW_RADIUS);
|
||||||
|
|
||||||
transPixmap = XCreatePixmap (dpy, root, 1, 1, 8);
|
transPixmap = XCreatePixmap (dpy, root, 1, 1, 8);
|
||||||
pa.repeat = True;
|
pa.repeat = True;
|
||||||
|
@ -874,7 +1015,10 @@ main (void)
|
||||||
if (!busy_start)
|
if (!busy_start)
|
||||||
busy_start = time_in_millis();
|
busy_start = time_in_millis();
|
||||||
#endif
|
#endif
|
||||||
/* printf ("event %d\n", ev.type); */
|
#if DEBUG
|
||||||
|
printf ("event %10.10s serial 0x%08x window 0x%08x\n",
|
||||||
|
ev_name(&ev), ev_serial (&ev), ev_window (&ev));
|
||||||
|
#endif
|
||||||
switch (ev.type) {
|
switch (ev.type) {
|
||||||
case CreateNotify:
|
case CreateNotify:
|
||||||
add_win (dpy, ev.xcreatewindow.window, 0);
|
add_win (dpy, ev.xcreatewindow.window, 0);
|
||||||
|
@ -886,7 +1030,7 @@ main (void)
|
||||||
destroy_win (dpy, ev.xdestroywindow.window, True);
|
destroy_win (dpy, ev.xdestroywindow.window, True);
|
||||||
break;
|
break;
|
||||||
case MapNotify:
|
case MapNotify:
|
||||||
map_win (dpy, ev.xmap.window);
|
map_win (dpy, ev.xmap.window, ev.xmap.serial);
|
||||||
break;
|
break;
|
||||||
case UnmapNotify:
|
case UnmapNotify:
|
||||||
unmap_win (dpy, ev.xunmap.window);
|
unmap_win (dpy, ev.xunmap.window);
|
||||||
|
@ -897,6 +1041,9 @@ main (void)
|
||||||
else
|
else
|
||||||
destroy_win (dpy, ev.xreparent.window, False);
|
destroy_win (dpy, ev.xreparent.window, False);
|
||||||
break;
|
break;
|
||||||
|
case CirculateNotify:
|
||||||
|
circulate_win (dpy, &ev.xcirculate);
|
||||||
|
break;
|
||||||
case Expose:
|
case Expose:
|
||||||
if (ev.xexpose.window == root)
|
if (ev.xexpose.window == root)
|
||||||
{
|
{
|
||||||
|
@ -929,13 +1076,17 @@ main (void)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PropertyNotify:
|
case PropertyNotify:
|
||||||
if (ev.xproperty.atom == XInternAtom (dpy, BACKGROUND_PROP, False))
|
for (p = 0; backgroundProps[p]; p++)
|
||||||
{
|
{
|
||||||
if (rootTile)
|
if (ev.xproperty.atom == XInternAtom (dpy, backgroundProps[p], False))
|
||||||
{
|
{
|
||||||
XClearArea (dpy, root, 0, 0, 0, 0, True);
|
if (rootTile)
|
||||||
XRenderFreePicture (dpy, rootTile);
|
{
|
||||||
rootTile = None;
|
XClearArea (dpy, root, 0, 0, 0, 0, True);
|
||||||
|
XRenderFreePicture (dpy, rootTile);
|
||||||
|
rootTile = None;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -944,7 +1095,7 @@ main (void)
|
||||||
damage_win (dpy, (XDamageNotifyEvent *) &ev);
|
damage_win (dpy, (XDamageNotifyEvent *) &ev);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (XEventsQueued (dpy, QueuedAfterReading));
|
} while (QLength (dpy));
|
||||||
#if INTERVAL
|
#if INTERVAL
|
||||||
now = time_in_millis ();
|
now = time_in_millis ();
|
||||||
/* printf ("\t\tbusy %d\n", now - busy_start); */
|
/* printf ("\t\tbusy %d\n", now - busy_start); */
|
||||||
|
|
Loading…
Reference in New Issue