Add name window pixmap support
This commit is contained in:
parent
4b34993c83
commit
018fc12ad4
|
@ -1,3 +1,10 @@
|
|||
2004-08-13 Keith Packard <keithp@keithp.com>
|
||||
|
||||
* xcompmgr.c: (paint_all), (repair_win), (map_win),
|
||||
(finish_unmap_win), (add_win), (configure_win), (damage_win),
|
||||
(error), (main):
|
||||
Add name window pixmap support
|
||||
|
||||
2004-07-08 Ely Levy <elylevy-xserver@cs.huji.ac.il>
|
||||
|
||||
reviewed by: Keith Packard
|
||||
|
|
163
xcompmgr.c
163
xcompmgr.c
|
@ -47,6 +47,8 @@
|
|||
#define HAS_NAME_WINDOW_PIXMAP 1
|
||||
#endif
|
||||
|
||||
#define CAN_DO_USABLE 0
|
||||
|
||||
typedef struct _ignore {
|
||||
struct _ignore *next;
|
||||
unsigned long sequence;
|
||||
|
@ -59,6 +61,10 @@ typedef struct _win {
|
|||
Pixmap pixmap;
|
||||
#endif
|
||||
XWindowAttributes a;
|
||||
#if CAN_DO_USABLE
|
||||
Bool usable; /* mapped and all damaged at one point */
|
||||
XRectangle damage_bounds; /* bounds of damage */
|
||||
#endif
|
||||
int mode;
|
||||
int damaged;
|
||||
Damage damage;
|
||||
|
@ -117,6 +123,8 @@ int xfixes_event, xfixes_error;
|
|||
int damage_event, damage_error;
|
||||
int composite_event, composite_error;
|
||||
int render_event, render_error;
|
||||
Bool synchronize;
|
||||
int composite_opcode;
|
||||
|
||||
/* find these once and be done with it */
|
||||
Atom opacityAtom;
|
||||
|
@ -795,8 +803,10 @@ paint_all (Display *dpy, XserverRegion region)
|
|||
#endif
|
||||
for (w = list; w; w = w->next)
|
||||
{
|
||||
if (w->a.map_state != IsViewable)
|
||||
#if CAN_DO_USABLE
|
||||
if (!w->usable)
|
||||
continue;
|
||||
#endif
|
||||
/* never painted, ignore it */
|
||||
if (!w->damaged)
|
||||
continue;
|
||||
|
@ -847,16 +857,25 @@ paint_all (Display *dpy, XserverRegion region)
|
|||
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,
|
||||
w->a.x + w->a.border_width,
|
||||
w->a.y + w->a.border_width,
|
||||
w->a.width,
|
||||
w->a.height);
|
||||
x, y, wid, hei);
|
||||
}
|
||||
if (!w->borderClip)
|
||||
{
|
||||
|
@ -908,23 +927,41 @@ paint_all (Display *dpy, XserverRegion region)
|
|||
(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,
|
||||
w->a.x + w->a.border_width,
|
||||
w->a.y + w->a.border_width,
|
||||
w->a.width,
|
||||
w->a.height);
|
||||
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,
|
||||
w->a.x + w->a.border_width,
|
||||
w->a.y + w->a.border_width,
|
||||
w->a.width,
|
||||
w->a.height);
|
||||
x, y, wid, hei);
|
||||
}
|
||||
XFixesDestroyRegion (dpy, w->borderClip);
|
||||
w->borderClip = None;
|
||||
|
@ -951,13 +988,10 @@ add_damage (Display *dpy, XserverRegion damage)
|
|||
}
|
||||
|
||||
static void
|
||||
repair_win (Display *dpy, Window id)
|
||||
repair_win (Display *dpy, win *w)
|
||||
{
|
||||
win *w = find_win (dpy, id);
|
||||
XserverRegion parts;
|
||||
|
||||
if (!w)
|
||||
return;
|
||||
if (!w->damaged)
|
||||
{
|
||||
parts = win_extents (dpy, w);
|
||||
|
@ -996,20 +1030,20 @@ map_win (Display *dpy, Window id, unsigned long sequence, Bool fade)
|
|||
return;
|
||||
w->a.map_state = IsViewable;
|
||||
|
||||
/* make sure we know if property was changed */
|
||||
XSelectInput(dpy, id, PropertyChangeMask);
|
||||
|
||||
#if CAN_DO_USABLE
|
||||
w->damage_bounds.x = w->damage_bounds.y = 0;
|
||||
w->damage_bounds.width = w->damage_bounds.height = 0;
|
||||
#endif
|
||||
w->damaged = 0;
|
||||
clipChanged = True;
|
||||
if (fade && fadeWindows)
|
||||
set_fade (dpy, w, True, 0, False);
|
||||
}
|
||||
|
||||
static void
|
||||
finish_unmap_win (Display *dpy, win *w)
|
||||
{
|
||||
w->a.map_state = IsUnmapped;
|
||||
w->damaged = 0;
|
||||
#if CAN_DO_USABLE
|
||||
w->usable = False;
|
||||
#endif
|
||||
if (w->extents != None)
|
||||
{
|
||||
add_damage (dpy, w->extents); /* destroys region */
|
||||
|
@ -1181,6 +1215,9 @@ add_win (Display *dpy, Window id, Window prev)
|
|||
return;
|
||||
}
|
||||
new->damaged = 0;
|
||||
#if CAN_DO_USABLE
|
||||
new->usable = False;
|
||||
#endif
|
||||
#if HAS_NAME_WINDOW_PIXMAP
|
||||
new->pixmap = None;
|
||||
#endif
|
||||
|
@ -1210,6 +1247,7 @@ add_win (Display *dpy, Window id, Window prev)
|
|||
new->prev_trans = 0;
|
||||
|
||||
/* moved mode setting to one place */
|
||||
XSelectInput(dpy, id, PropertyChangeMask);
|
||||
new->opacity = get_opacity_prop(dpy, new, OPAQUE);
|
||||
determine_mode (dpy, new);
|
||||
|
||||
|
@ -1270,7 +1308,9 @@ configure_win (Display *dpy, XConfigureEvent *ce)
|
|||
}
|
||||
return;
|
||||
}
|
||||
if (w->a.map_state == IsViewable)
|
||||
#if CAN_DO_USABLE
|
||||
if (w->usable)
|
||||
#endif
|
||||
{
|
||||
damage = XFixesCreateRegion (dpy, 0, 0);
|
||||
if (w->extents != None)
|
||||
|
@ -1409,7 +1449,59 @@ dump_wins (void)
|
|||
static void
|
||||
damage_win (Display *dpy, XDamageNotifyEvent *de)
|
||||
{
|
||||
repair_win (dpy, de->drawable);
|
||||
win *w = find_win (dpy, de->drawable);
|
||||
|
||||
if (!w)
|
||||
return;
|
||||
#if CAN_DO_USABLE
|
||||
if (!w->usable)
|
||||
{
|
||||
if (w->damage_bounds.width == 0 || w->damage_bounds.height == 0)
|
||||
{
|
||||
w->damage_bounds = de->area;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (de->area.x < w->damage_bounds.x)
|
||||
{
|
||||
w->damage_bounds.width += (w->damage_bounds.x - de->area.x);
|
||||
w->damage_bounds.x = de->area.x;
|
||||
}
|
||||
if (de->area.y < w->damage_bounds.y)
|
||||
{
|
||||
w->damage_bounds.height += (w->damage_bounds.y - de->area.y);
|
||||
w->damage_bounds.y = de->area.y;
|
||||
}
|
||||
if (de->area.x + de->area.width > w->damage_bounds.x + w->damage_bounds.width)
|
||||
w->damage_bounds.width = de->area.x + de->area.width - w->damage_bounds.x;
|
||||
if (de->area.y + de->area.height > w->damage_bounds.y + w->damage_bounds.height)
|
||||
w->damage_bounds.height = de->area.y + de->area.height - w->damage_bounds.y;
|
||||
}
|
||||
#if 0
|
||||
printf ("unusable damage %d, %d: %d x %d bounds %d, %d: %d x %d\n",
|
||||
de->area.x,
|
||||
de->area.y,
|
||||
de->area.width,
|
||||
de->area.height,
|
||||
w->damage_bounds.x,
|
||||
w->damage_bounds.y,
|
||||
w->damage_bounds.width,
|
||||
w->damage_bounds.height);
|
||||
#endif
|
||||
if (w->damage_bounds.x <= 0 &&
|
||||
w->damage_bounds.y <= 0 &&
|
||||
w->a.width <= w->damage_bounds.x + w->damage_bounds.width &&
|
||||
w->a.height <= w->damage_bounds.y + w->damage_bounds.height)
|
||||
{
|
||||
clipChanged = True;
|
||||
if (fadeWindows)
|
||||
set_fade (dpy, w, True, 0, False);
|
||||
w->usable = True;
|
||||
}
|
||||
}
|
||||
if (w->usable)
|
||||
#endif
|
||||
repair_win (dpy, w);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1421,6 +1513,12 @@ error (Display *dpy, XErrorEvent *ev)
|
|||
if (should_ignore (dpy, ev->serial))
|
||||
return 0;
|
||||
|
||||
if (ev->request_code == composite_opcode &&
|
||||
ev->minor_code == X_CompositeRedirectSubwindows)
|
||||
{
|
||||
fprintf (stderr, "Another composite manager is already running\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
o = ev->error_code - xfixes_error;
|
||||
switch (o) {
|
||||
|
@ -1542,7 +1640,7 @@ main (int argc, char **argv)
|
|||
char *display = 0;
|
||||
int o;
|
||||
|
||||
while ((o = getopt (argc, argv, "d:scnf")) != -1)
|
||||
while ((o = getopt (argc, argv, "d:scnfS")) != -1)
|
||||
{
|
||||
switch (o) {
|
||||
case 'd':
|
||||
|
@ -1560,6 +1658,9 @@ main (int argc, char **argv)
|
|||
case 'f':
|
||||
fadeWindows = True;
|
||||
break;
|
||||
case 'S':
|
||||
synchronize = True;
|
||||
break;
|
||||
default:
|
||||
usage (argv[0]);
|
||||
break;
|
||||
|
@ -1573,9 +1674,8 @@ main (int argc, char **argv)
|
|||
exit (1);
|
||||
}
|
||||
XSetErrorHandler (error);
|
||||
#if 0
|
||||
XSynchronize (dpy, 1);
|
||||
#endif
|
||||
if (synchronize)
|
||||
XSynchronize (dpy, 1);
|
||||
scr = DefaultScreen (dpy);
|
||||
root = RootWindow (dpy, scr);
|
||||
|
||||
|
@ -1584,7 +1684,8 @@ main (int argc, char **argv)
|
|||
fprintf (stderr, "No render extension\n");
|
||||
exit (1);
|
||||
}
|
||||
if (!XCompositeQueryExtension (dpy, &composite_event, &composite_error))
|
||||
if (!XQueryExtension (dpy, COMPOSITE_NAME, &composite_opcode,
|
||||
&composite_event, &composite_error))
|
||||
{
|
||||
fprintf (stderr, "No composite extension\n");
|
||||
exit (1);
|
||||
|
|
Loading…
Reference in New Issue