Double buffer updates. Check for InputOnly windows and ignore them
This commit is contained in:
parent
e142128dde
commit
6e99ed898c
|
@ -1,3 +1,11 @@
|
|||
2003-11-09 Keith Packard <keithp@keithp.com>
|
||||
|
||||
* xcompmgr.c: (paint_root), (paint_all), (map_win), (add_win),
|
||||
(configure_win), (destroy_win), (main):
|
||||
|
||||
Double buffer updates.
|
||||
Check for InputOnly windows and ignore them
|
||||
|
||||
2003-11-09 Keith Packard <keithp@keithp.com>
|
||||
|
||||
* xcompmgr.c: (root_tile), (paint_root):
|
||||
|
|
126
xcompmgr.c
126
xcompmgr.c
|
@ -1,6 +1,31 @@
|
|||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright © 2003 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <sys/poll.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
|
@ -34,9 +59,11 @@ Display *dpy;
|
|||
int scr;
|
||||
Window root;
|
||||
Picture rootPicture;
|
||||
Picture rootBuffer;
|
||||
Picture transPicture;
|
||||
Picture rootTile;
|
||||
XserverRegion allDamage;
|
||||
int root_height, root_width;
|
||||
|
||||
#define WINDOW_PLAIN 0
|
||||
#define WINDOW_DROP 1
|
||||
|
@ -336,8 +363,8 @@ paint_root (Display *dpy)
|
|||
rootTile = root_tile (dpy);
|
||||
|
||||
XRenderComposite (dpy, PictOpSrc,
|
||||
rootTile, None, rootPicture,
|
||||
0, 0, 0, 0, 0, 0, 32767, 32767);
|
||||
rootTile, None, rootBuffer,
|
||||
0, 0, 0, 0, 0, 0, root_width, root_height);
|
||||
}
|
||||
|
||||
XserverRegion
|
||||
|
@ -379,12 +406,35 @@ paint_all (Display *dpy, XserverRegion region)
|
|||
win *w;
|
||||
win *t = 0;
|
||||
|
||||
if (!region)
|
||||
{
|
||||
XRectangle r;
|
||||
r.x = 0;
|
||||
r.y = 0;
|
||||
r.width = root_width;
|
||||
r.height = root_height;
|
||||
region = XFixesCreateRegion (dpy, &r, 1);
|
||||
}
|
||||
if (!rootBuffer)
|
||||
{
|
||||
Pixmap rootPixmap = XCreatePixmap (dpy, root, root_width, root_height,
|
||||
DefaultDepth (dpy, scr));
|
||||
rootBuffer = XRenderCreatePicture (dpy, rootPixmap,
|
||||
XRenderFindVisualFormat (dpy,
|
||||
DefaultVisual (dpy, scr)),
|
||||
0, 0);
|
||||
XFreePixmap (dpy, rootPixmap);
|
||||
}
|
||||
XFixesSetPictureClipRegion (dpy, rootPicture, 0, 0, region);
|
||||
for (w = list; w; w = w->next)
|
||||
{
|
||||
Picture mask;
|
||||
|
||||
if (w->a.map_state != IsViewable)
|
||||
continue;
|
||||
if (!w->picture)
|
||||
continue;
|
||||
|
||||
if (w->borderSize)
|
||||
XFixesDestroyRegion (dpy, w->borderSize);
|
||||
w->borderSize = border_size (dpy, w);
|
||||
|
@ -393,9 +443,9 @@ paint_all (Display *dpy, XserverRegion region)
|
|||
w->extents = win_extents (dpy, w);
|
||||
if (w->mode != WINDOW_TRANS)
|
||||
{
|
||||
XFixesSetPictureClipRegion (dpy, rootPicture, 0, 0, region);
|
||||
XFixesSetPictureClipRegion (dpy, rootBuffer, 0, 0, region);
|
||||
XFixesSubtractRegion (dpy, region, region, 0, 0, w->borderSize, 0, 0);
|
||||
XRenderComposite (dpy, PictOpSrc, w->picture, None, rootPicture,
|
||||
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,
|
||||
|
@ -407,21 +457,21 @@ paint_all (Display *dpy, XserverRegion region)
|
|||
w->prev_trans = t;
|
||||
t = w;
|
||||
}
|
||||
XFixesSetPictureClipRegion (dpy, rootPicture, 0, 0, region);
|
||||
XFixesSetPictureClipRegion (dpy, rootBuffer, 0, 0, region);
|
||||
paint_root (dpy);
|
||||
for (w = t; w; w = w->prev_trans)
|
||||
{
|
||||
XFixesSetPictureClipRegion (dpy, rootPicture, 0, 0, w->borderClip);
|
||||
XFixesSetPictureClipRegion (dpy, rootBuffer, 0, 0, w->borderClip);
|
||||
if (w->shadow)
|
||||
{
|
||||
XRenderComposite (dpy, PictOpOver, w->shadow, None, rootPicture,
|
||||
XRenderComposite (dpy, PictOpOver, w->shadow, None, 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->shadow_width, w->shadow_height);
|
||||
}
|
||||
if (w->mode == WINDOW_TRANS)
|
||||
XRenderComposite (dpy, PictOpOver, w->picture, transPicture, rootPicture,
|
||||
XRenderComposite (dpy, PictOpOver, w->picture, transPicture, rootBuffer,
|
||||
0, 0, 0, 0,
|
||||
w->a.x + w->a.border_width,
|
||||
w->a.y + w->a.border_width,
|
||||
|
@ -431,6 +481,9 @@ paint_all (Display *dpy, XserverRegion region)
|
|||
w->borderClip = None;
|
||||
}
|
||||
XFixesDestroyRegion (dpy, region);
|
||||
XFixesSetPictureClipRegion (dpy, rootBuffer, 0, 0, None);
|
||||
XRenderComposite (dpy, PictOpSrc, rootBuffer, None, rootPicture,
|
||||
0, 0, 0, 0, 0, 0, root_width, root_height);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -470,9 +523,12 @@ map_win (Display *dpy, Window id)
|
|||
if (!w)
|
||||
return;
|
||||
w->a.map_state = IsViewable;
|
||||
w->damage = XDamageCreate (dpy, id, XDamageReportNonEmpty);
|
||||
region = win_extents (dpy, w);
|
||||
add_damage (dpy, region);
|
||||
if (w->picture)
|
||||
{
|
||||
w->damage = XDamageCreate (dpy, id, XDamageReportNonEmpty);
|
||||
region = win_extents (dpy, w);
|
||||
add_damage (dpy, region);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -522,11 +578,16 @@ add_win (Display *dpy, Window id, Window prev)
|
|||
new->damaged = 0;
|
||||
new->damage = None;
|
||||
pa.subwindow_mode = IncludeInferiors;
|
||||
new->picture = XRenderCreatePicture (dpy, id,
|
||||
XRenderFindVisualFormat (dpy,
|
||||
new->a.visual),
|
||||
CPSubwindowMode,
|
||||
&pa);
|
||||
if (new->a.class == InputOnly)
|
||||
new->picture = 0;
|
||||
else
|
||||
{
|
||||
new->picture = XRenderCreatePicture (dpy, id,
|
||||
XRenderFindVisualFormat (dpy,
|
||||
new->a.visual),
|
||||
CPSubwindowMode,
|
||||
&pa);
|
||||
}
|
||||
|
||||
new->shadow = None;
|
||||
new->borderSize = None;
|
||||
|
@ -549,7 +610,19 @@ configure_win (Display *dpy, XConfigureEvent *ce)
|
|||
XserverRegion damage = None;
|
||||
|
||||
if (!w)
|
||||
{
|
||||
if (ce->window == root)
|
||||
{
|
||||
if (rootBuffer)
|
||||
{
|
||||
XRenderFreePicture (dpy, rootBuffer);
|
||||
rootBuffer = None;
|
||||
}
|
||||
root_width = ce->width;
|
||||
root_height = ce->height;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (w->a.map_state == IsViewable)
|
||||
{
|
||||
damage = XFixesCreateRegion (dpy, 0, 0);
|
||||
|
@ -610,7 +683,8 @@ destroy_win (Display *dpy, Window id, Bool gone)
|
|||
if (!gone)
|
||||
{
|
||||
unmap_win (dpy, id);
|
||||
XRenderFreePicture (dpy, w->picture);
|
||||
if (w->picture)
|
||||
XRenderFreePicture (dpy, w->picture);
|
||||
}
|
||||
*prev = w->next;
|
||||
free (w);
|
||||
|
@ -673,6 +747,8 @@ main ()
|
|||
GC gc;
|
||||
int size_expose = 0;
|
||||
int n_expose = 0;
|
||||
struct pollfd ufd;
|
||||
int n;
|
||||
|
||||
dpy = XOpenDisplay (0);
|
||||
if (!dpy)
|
||||
|
@ -680,6 +756,7 @@ main ()
|
|||
fprintf (stderr, "Can't open display\n");
|
||||
exit (1);
|
||||
}
|
||||
XSynchronize (dpy, True);
|
||||
XSetErrorHandler (error);
|
||||
scr = DefaultScreen (dpy);
|
||||
root = RootWindow (dpy, scr);
|
||||
|
@ -694,6 +771,9 @@ main ()
|
|||
c.alpha = 0xc0c0;
|
||||
XRenderFillRectangle (dpy, PictOpSrc, transPicture, &c, 0, 0, 1, 1);
|
||||
|
||||
root_width = DisplayWidth (dpy, scr);
|
||||
root_height = DisplayHeight (dpy, scr);
|
||||
|
||||
rootPicture = XRenderCreatePicture (dpy, root,
|
||||
XRenderFindVisualFormat (dpy,
|
||||
DefaultVisual (dpy, scr)),
|
||||
|
@ -704,21 +784,24 @@ main ()
|
|||
fprintf (stderr, "No composite extension\n");
|
||||
exit (1);
|
||||
}
|
||||
printf ("Composite error %d\n", error_base);
|
||||
if (!XDamageQueryExtension (dpy, &damage_event, &damage_error))
|
||||
{
|
||||
fprintf (stderr, "No damage extension\n");
|
||||
exit (1);
|
||||
}
|
||||
printf ("Damage error %d\n", damage_error);
|
||||
if (!XFixesQueryExtension (dpy, &xfixes_event, &xfixes_error))
|
||||
{
|
||||
fprintf (stderr, "No XFixes extension\n");
|
||||
exit (1);
|
||||
}
|
||||
printf ("XFixes error %d\n", xfixes_error);
|
||||
allDamage = None;
|
||||
XGrabServer (dpy);
|
||||
XCompositeRedirectSubwindows (dpy, root, CompositeRedirectManual);
|
||||
paint_root (dpy);
|
||||
XSelectInput (dpy, root, SubstructureNotifyMask|ExposureMask);
|
||||
paint_all (dpy, None);
|
||||
XSelectInput (dpy, root, SubstructureNotifyMask|ExposureMask|StructureNotifyMask);
|
||||
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);
|
||||
|
@ -789,6 +872,11 @@ main ()
|
|||
break;
|
||||
}
|
||||
} while (XEventsQueued (dpy, QueuedAfterReading));
|
||||
ufd.fd = ConnectionNumber (dpy);
|
||||
ufd.events = POLLIN;
|
||||
n = poll (&ufd, 1, 30);
|
||||
if (n > 0 && (ufd.revents & POLLIN) && XEventsQueued (dpy, QueuedAfterReading))
|
||||
continue;
|
||||
if (allDamage)
|
||||
{
|
||||
paint_all (dpy, allDamage);
|
||||
|
|
Loading…
Reference in New Issue