Make composite manager mode run-time selectable with command line option:

-s: server-side shadows (sharp, but follows window alpha)
-c: client-side shadows (blurred, but uses window extents only)
-n: no shadows (this is the default mode)
This commit is contained in:
Keith Packard 2004-06-27 05:08:33 +00:00
parent def454cc5a
commit 9616aa5ba6
2 changed files with 140 additions and 84 deletions

View File

@ -1,3 +1,13 @@
2004-06-26 Keith Packard <keithp@keithp.com>
* xcompmgr.c: (win_extents), (paint_all), (repair_win),
(unmap_win), (usage), (main):
Make composite manager mode run-time selectable with
command line option:
-s: server-side shadows (sharp, but follows window alpha)
-c: client-side shadows (blurred, but uses window extents only)
-n: no shadows (this is the default mode)
2004-06-26 Keith Packard <keithp@keithp.com> 2004-06-26 Keith Packard <keithp@keithp.com>
* xcompmgr.c: (make_gaussian_map), (make_shadow), (shadow_picture), * xcompmgr.c: (make_gaussian_map), (make_shadow), (shadow_picture),

View File

@ -35,6 +35,7 @@
#include <sys/poll.h> #include <sys/poll.h>
#include <sys/time.h> #include <sys/time.h>
#include <time.h> #include <time.h>
#include <unistd.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
@ -122,11 +123,19 @@ conv *gaussianMap;
#define SHADOWS 1 #define SHADOWS 1
#define SHARP_SHADOW 0 #define SHARP_SHADOW 0
#if SHADOWS typedef enum _compMode {
#define SHADOW_RADIUS 12 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;
#define SHADOW_OPACITY 0.75 #define SHADOW_OPACITY 0.75
#define SHADOW_OFFSET_X (-SHADOW_RADIUS * 5 / 4) #define SHADOW_OFFSET_X (-shadowRadius * 5 / 4)
#define SHADOW_OFFSET_Y (-SHADOW_RADIUS * 5 / 4) #define SHADOW_OFFSET_Y (-shadowRadius * 5 / 4)
static double static double
gaussian (double r, double x, double y) gaussian (double r, double x, double y)
@ -358,8 +367,6 @@ shadow_picture (Display *dpy, double opacity, int width, int height, int *wp, in
return shadowPicture; return shadowPicture;
} }
#endif /* SHADOWS */
Picture Picture
solid_picture (Display *dpy, Bool argb, double a, double r, double g, double b) solid_picture (Display *dpy, Bool argb, double a, double r, double g, double b)
{ {
@ -507,52 +514,54 @@ win_extents (Display *dpy, win *w)
r.y = w->a.y; r.y = w->a.y;
r.width = w->a.width + w->a.border_width * 2; r.width = w->a.width + w->a.border_width * 2;
r.height = w->a.height + w->a.border_width * 2; r.height = w->a.height + w->a.border_width * 2;
#if SHADOWS if (compMode != CompSimple)
#if !SHARP_SHADOW
if (w->mode != WINDOW_ARGB)
#endif
{ {
XRectangle sr; if (compMode == CompServerShadows || w->mode != WINDOW_ARGB)
#if SHARP_SHADOW
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; XRectangle sr;
if (w->mode == WINDOW_TRANS)
opacity = opacity * TRANS_OPACITY; if (compMode == CompServerShadows)
w->shadow = shadow_picture (dpy, opacity, {
w->a.width + w->a.border_width * 2, w->shadow_dx = 2;
w->a.height + w->a.border_width * 2, w->shadow_dy = 7;
&w->shadow_width, &w->shadow_height); 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)
{
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
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
return XFixesCreateRegion (dpy, &r, 1); return XFixesCreateRegion (dpy, &r, 1);
} }
@ -679,31 +688,34 @@ paint_all (Display *dpy, XserverRegion region)
for (w = t; w; w = w->prev_trans) for (w = t; w; w = w->prev_trans)
{ {
XFixesSetPictureClipRegion (dpy, rootBuffer, 0, 0, w->borderClip); XFixesSetPictureClipRegion (dpy, rootBuffer, 0, 0, w->borderClip);
#if SHADOWS switch (compMode) {
#if SHARP_SHADOW case CompSimple:
set_ignore (dpy, NextRequest (dpy)); break;
if (w->opacity != OPAQUE && !w->shadowPict) case CompServerShadows:
w->shadowPict = solid_picture (dpy, True, set_ignore (dpy, NextRequest (dpy));
(double) w->opacity / OPAQUE * 0.3, if (w->opacity != OPAQUE && !w->shadowPict)
0, 0, 0); w->shadowPict = solid_picture (dpy, True,
XRenderComposite (dpy, PictOpOver, (double) w->opacity / OPAQUE * 0.3,
w->shadowPict ? w->shadowPict : transBlackPicture, 0, 0, 0);
w->picture, rootBuffer, XRenderComposite (dpy, PictOpOver,
0, 0, 0, 0, w->shadowPict ? w->shadowPict : transBlackPicture,
w->a.x + w->shadow_dx, w->picture, rootBuffer,
w->a.y + w->shadow_dy,
w->shadow_width, w->shadow_height);
#else
if (w->shadow)
{
XRenderComposite (dpy, PictOpOver, blackPicture, w->shadow, rootBuffer,
0, 0, 0, 0, 0, 0, 0, 0,
w->a.x + w->shadow_dx, w->a.x + w->shadow_dx,
w->a.y + w->shadow_dy, w->a.y + w->shadow_dy,
w->shadow_width, w->shadow_height); 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
#endif /* SHADOWS */
if (w->opacity != OPAQUE) if (w->opacity != OPAQUE)
w->alphaPict = solid_picture (dpy, False, w->alphaPict = solid_picture (dpy, False,
(double) w->opacity / OPAQUE, 0, 0, 0); (double) w->opacity / OPAQUE, 0, 0, 0);
@ -774,15 +786,14 @@ repair_win (Display *dpy, Window id)
XFixesTranslateRegion (dpy, parts, XFixesTranslateRegion (dpy, parts,
w->a.x + w->a.border_width, w->a.x + w->a.border_width,
w->a.y + w->a.border_width); w->a.y + w->a.border_width);
#if SHADOWS if (compMode == CompServerShadows)
#if SHARP_SHADOW {
o = XFixesCreateRegion (dpy, 0, 0); o = XFixesCreateRegion (dpy, 0, 0);
XFixesCopyRegion (dpy, o, parts); XFixesCopyRegion (dpy, o, parts);
XFixesTranslateRegion (dpy, o, w->shadow_dx, w->shadow_dy); XFixesTranslateRegion (dpy, o, w->shadow_dx, w->shadow_dy);
XFixesUnionRegion (dpy, parts, parts, o); XFixesUnionRegion (dpy, parts, parts, o);
XFixesDestroyRegion (dpy, o); XFixesDestroyRegion (dpy, o);
#endif }
#endif
} }
add_damage (dpy, parts); add_damage (dpy, parts);
w->damaged = 1; w->damaged = 1;
@ -848,7 +859,11 @@ unmap_win (Display *dpy, Window id)
w->pixmap = 0; w->pixmap = 0;
} }
if (w->picture) if (w->picture)
{
set_ignore (dpy, NextRequest (dpy));
XRenderFreePicture (dpy, w->picture); XRenderFreePicture (dpy, w->picture);
w->picture = None;
}
/* don't care about properties anymore */ /* don't care about properties anymore */
set_ignore (dpy, NextRequest (dpy)); set_ignore (dpy, NextRequest (dpy));
@ -1261,6 +1276,13 @@ ev_window (XEvent *ev)
} }
} }
void
usage (char *program)
{
fprintf (stderr, "usage: %s [-d display] [-n] [-s] [-c]\n", program);
exit (1);
}
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
@ -1282,8 +1304,31 @@ main (int argc, char **argv)
int now; int now;
int p; int p;
int composite_major, composite_minor; int composite_major, composite_minor;
char *display = 0;
int o;
dpy = XOpenDisplay (0); while ((o = getopt (argc, argv, "d:scn")) != -1)
{
switch (o) {
case 'd':
display = optarg;
break;
case 's':
compMode = CompServerShadows;
break;
case 'c':
compMode = CompClientShadows;
break;
case 'n':
compMode = CompSimple;
break;
default:
usage (argv[0]);
break;
}
}
dpy = XOpenDisplay (display);
if (!dpy) if (!dpy)
{ {
fprintf (stderr, "Can't open display\n"); fprintf (stderr, "Can't open display\n");
@ -1308,6 +1353,9 @@ main (int argc, char **argv)
} }
XCompositeQueryVersion (dpy, &composite_major, &composite_minor); XCompositeQueryVersion (dpy, &composite_major, &composite_minor);
#if 0 #if 0
/*
* Don't use this yet; we don't have set semantics for new pixmaps
*/
if (composite_major > 0 || composite_minor >= 2) if (composite_major > 0 || composite_minor >= 2)
hasNamePixmap = True; hasNamePixmap = True;
#endif #endif
@ -1327,9 +1375,8 @@ main (int argc, char **argv)
pa.subwindow_mode = IncludeInferiors; pa.subwindow_mode = IncludeInferiors;
#if SHADOWS && !SHARP_SHADOW if (compMode == CompClientShadows)
gaussianMap = make_gaussian_map(dpy, SHADOW_RADIUS); gaussianMap = make_gaussian_map(dpy, shadowRadius);
#endif
root_width = DisplayWidth (dpy, scr); root_width = DisplayWidth (dpy, scr);
root_height = DisplayHeight (dpy, scr); root_height = DisplayHeight (dpy, scr);
@ -1340,9 +1387,8 @@ main (int argc, char **argv)
CPSubwindowMode, CPSubwindowMode,
&pa); &pa);
blackPicture = solid_picture (dpy, True, 1, 0, 0, 0); blackPicture = solid_picture (dpy, True, 1, 0, 0, 0);
#if SHADOWS && SHARP_SHADOW if (compMode == CompServerShadows)
transBlackPicture = solid_picture (dpy, True, 0.3, 0, 0, 0); transBlackPicture = solid_picture (dpy, True, 0.3, 0, 0, 0);
#endif
allDamage = None; allDamage = None;
clipChanged = True; clipChanged = True;
XGrabServer (dpy); XGrabServer (dpy);