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>
|
2003-11-09 Keith Packard <keithp@keithp.com>
|
||||||
|
|
||||||
* xcompmgr.c: (root_tile), (paint_root):
|
* 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 <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#include <X11/extensions/Xcomposite.h>
|
#include <X11/extensions/Xcomposite.h>
|
||||||
|
@ -34,9 +59,11 @@ Display *dpy;
|
||||||
int scr;
|
int scr;
|
||||||
Window root;
|
Window root;
|
||||||
Picture rootPicture;
|
Picture rootPicture;
|
||||||
|
Picture rootBuffer;
|
||||||
Picture transPicture;
|
Picture transPicture;
|
||||||
Picture rootTile;
|
Picture rootTile;
|
||||||
XserverRegion allDamage;
|
XserverRegion allDamage;
|
||||||
|
int root_height, root_width;
|
||||||
|
|
||||||
#define WINDOW_PLAIN 0
|
#define WINDOW_PLAIN 0
|
||||||
#define WINDOW_DROP 1
|
#define WINDOW_DROP 1
|
||||||
|
@ -336,8 +363,8 @@ paint_root (Display *dpy)
|
||||||
rootTile = root_tile (dpy);
|
rootTile = root_tile (dpy);
|
||||||
|
|
||||||
XRenderComposite (dpy, PictOpSrc,
|
XRenderComposite (dpy, PictOpSrc,
|
||||||
rootTile, None, rootPicture,
|
rootTile, None, rootBuffer,
|
||||||
0, 0, 0, 0, 0, 0, 32767, 32767);
|
0, 0, 0, 0, 0, 0, root_width, root_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
XserverRegion
|
XserverRegion
|
||||||
|
@ -379,12 +406,35 @@ paint_all (Display *dpy, XserverRegion region)
|
||||||
win *w;
|
win *w;
|
||||||
win *t = 0;
|
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)
|
for (w = list; w; w = w->next)
|
||||||
{
|
{
|
||||||
Picture mask;
|
Picture mask;
|
||||||
|
|
||||||
if (w->a.map_state != IsViewable)
|
if (w->a.map_state != IsViewable)
|
||||||
continue;
|
continue;
|
||||||
|
if (!w->picture)
|
||||||
|
continue;
|
||||||
|
|
||||||
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);
|
||||||
|
@ -393,9 +443,9 @@ paint_all (Display *dpy, XserverRegion region)
|
||||||
w->extents = win_extents (dpy, w);
|
w->extents = win_extents (dpy, w);
|
||||||
if (w->mode != WINDOW_TRANS)
|
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);
|
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,
|
0, 0, 0, 0,
|
||||||
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,
|
||||||
|
@ -407,21 +457,21 @@ paint_all (Display *dpy, XserverRegion region)
|
||||||
w->prev_trans = t;
|
w->prev_trans = t;
|
||||||
t = w;
|
t = w;
|
||||||
}
|
}
|
||||||
XFixesSetPictureClipRegion (dpy, rootPicture, 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)
|
||||||
{
|
{
|
||||||
XFixesSetPictureClipRegion (dpy, rootPicture, 0, 0, w->borderClip);
|
XFixesSetPictureClipRegion (dpy, rootBuffer, 0, 0, w->borderClip);
|
||||||
if (w->shadow)
|
if (w->shadow)
|
||||||
{
|
{
|
||||||
XRenderComposite (dpy, PictOpOver, w->shadow, None, rootPicture,
|
XRenderComposite (dpy, PictOpOver, w->shadow, None, rootBuffer,
|
||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
w->a.x + w->a.border_width + w->shadow_dx,
|
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->shadow_dy,
|
||||||
w->shadow_width, w->shadow_height);
|
w->shadow_width, w->shadow_height);
|
||||||
}
|
}
|
||||||
if (w->mode == WINDOW_TRANS)
|
if (w->mode == WINDOW_TRANS)
|
||||||
XRenderComposite (dpy, PictOpOver, w->picture, transPicture, rootPicture,
|
XRenderComposite (dpy, PictOpOver, w->picture, transPicture, rootBuffer,
|
||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
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,
|
||||||
|
@ -431,6 +481,9 @@ paint_all (Display *dpy, XserverRegion region)
|
||||||
w->borderClip = None;
|
w->borderClip = None;
|
||||||
}
|
}
|
||||||
XFixesDestroyRegion (dpy, region);
|
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
|
void
|
||||||
|
@ -470,9 +523,12 @@ map_win (Display *dpy, Window id)
|
||||||
if (!w)
|
if (!w)
|
||||||
return;
|
return;
|
||||||
w->a.map_state = IsViewable;
|
w->a.map_state = IsViewable;
|
||||||
w->damage = XDamageCreate (dpy, id, XDamageReportNonEmpty);
|
if (w->picture)
|
||||||
region = win_extents (dpy, w);
|
{
|
||||||
add_damage (dpy, region);
|
w->damage = XDamageCreate (dpy, id, XDamageReportNonEmpty);
|
||||||
|
region = win_extents (dpy, w);
|
||||||
|
add_damage (dpy, region);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -522,11 +578,16 @@ add_win (Display *dpy, Window id, Window prev)
|
||||||
new->damaged = 0;
|
new->damaged = 0;
|
||||||
new->damage = None;
|
new->damage = None;
|
||||||
pa.subwindow_mode = IncludeInferiors;
|
pa.subwindow_mode = IncludeInferiors;
|
||||||
new->picture = XRenderCreatePicture (dpy, id,
|
if (new->a.class == InputOnly)
|
||||||
XRenderFindVisualFormat (dpy,
|
new->picture = 0;
|
||||||
new->a.visual),
|
else
|
||||||
CPSubwindowMode,
|
{
|
||||||
&pa);
|
new->picture = XRenderCreatePicture (dpy, id,
|
||||||
|
XRenderFindVisualFormat (dpy,
|
||||||
|
new->a.visual),
|
||||||
|
CPSubwindowMode,
|
||||||
|
&pa);
|
||||||
|
}
|
||||||
|
|
||||||
new->shadow = None;
|
new->shadow = None;
|
||||||
new->borderSize = None;
|
new->borderSize = None;
|
||||||
|
@ -549,7 +610,19 @@ configure_win (Display *dpy, XConfigureEvent *ce)
|
||||||
XserverRegion damage = None;
|
XserverRegion damage = None;
|
||||||
|
|
||||||
if (!w)
|
if (!w)
|
||||||
|
{
|
||||||
|
if (ce->window == root)
|
||||||
|
{
|
||||||
|
if (rootBuffer)
|
||||||
|
{
|
||||||
|
XRenderFreePicture (dpy, rootBuffer);
|
||||||
|
rootBuffer = None;
|
||||||
|
}
|
||||||
|
root_width = ce->width;
|
||||||
|
root_height = ce->height;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if (w->a.map_state == IsViewable)
|
if (w->a.map_state == IsViewable)
|
||||||
{
|
{
|
||||||
damage = XFixesCreateRegion (dpy, 0, 0);
|
damage = XFixesCreateRegion (dpy, 0, 0);
|
||||||
|
@ -610,7 +683,8 @@ destroy_win (Display *dpy, Window id, Bool gone)
|
||||||
if (!gone)
|
if (!gone)
|
||||||
{
|
{
|
||||||
unmap_win (dpy, id);
|
unmap_win (dpy, id);
|
||||||
XRenderFreePicture (dpy, w->picture);
|
if (w->picture)
|
||||||
|
XRenderFreePicture (dpy, w->picture);
|
||||||
}
|
}
|
||||||
*prev = w->next;
|
*prev = w->next;
|
||||||
free (w);
|
free (w);
|
||||||
|
@ -673,6 +747,8 @@ main ()
|
||||||
GC gc;
|
GC gc;
|
||||||
int size_expose = 0;
|
int size_expose = 0;
|
||||||
int n_expose = 0;
|
int n_expose = 0;
|
||||||
|
struct pollfd ufd;
|
||||||
|
int n;
|
||||||
|
|
||||||
dpy = XOpenDisplay (0);
|
dpy = XOpenDisplay (0);
|
||||||
if (!dpy)
|
if (!dpy)
|
||||||
|
@ -680,6 +756,7 @@ main ()
|
||||||
fprintf (stderr, "Can't open display\n");
|
fprintf (stderr, "Can't open display\n");
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
XSynchronize (dpy, True);
|
||||||
XSetErrorHandler (error);
|
XSetErrorHandler (error);
|
||||||
scr = DefaultScreen (dpy);
|
scr = DefaultScreen (dpy);
|
||||||
root = RootWindow (dpy, scr);
|
root = RootWindow (dpy, scr);
|
||||||
|
@ -694,6 +771,9 @@ main ()
|
||||||
c.alpha = 0xc0c0;
|
c.alpha = 0xc0c0;
|
||||||
XRenderFillRectangle (dpy, PictOpSrc, transPicture, &c, 0, 0, 1, 1);
|
XRenderFillRectangle (dpy, PictOpSrc, transPicture, &c, 0, 0, 1, 1);
|
||||||
|
|
||||||
|
root_width = DisplayWidth (dpy, scr);
|
||||||
|
root_height = DisplayHeight (dpy, scr);
|
||||||
|
|
||||||
rootPicture = XRenderCreatePicture (dpy, root,
|
rootPicture = XRenderCreatePicture (dpy, root,
|
||||||
XRenderFindVisualFormat (dpy,
|
XRenderFindVisualFormat (dpy,
|
||||||
DefaultVisual (dpy, scr)),
|
DefaultVisual (dpy, scr)),
|
||||||
|
@ -704,21 +784,24 @@ main ()
|
||||||
fprintf (stderr, "No composite extension\n");
|
fprintf (stderr, "No composite extension\n");
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
printf ("Composite error %d\n", error_base);
|
||||||
if (!XDamageQueryExtension (dpy, &damage_event, &damage_error))
|
if (!XDamageQueryExtension (dpy, &damage_event, &damage_error))
|
||||||
{
|
{
|
||||||
fprintf (stderr, "No damage extension\n");
|
fprintf (stderr, "No damage extension\n");
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
printf ("Damage error %d\n", damage_error);
|
||||||
if (!XFixesQueryExtension (dpy, &xfixes_event, &xfixes_error))
|
if (!XFixesQueryExtension (dpy, &xfixes_event, &xfixes_error))
|
||||||
{
|
{
|
||||||
fprintf (stderr, "No XFixes extension\n");
|
fprintf (stderr, "No XFixes extension\n");
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
printf ("XFixes error %d\n", xfixes_error);
|
||||||
allDamage = None;
|
allDamage = None;
|
||||||
XGrabServer (dpy);
|
XGrabServer (dpy);
|
||||||
XCompositeRedirectSubwindows (dpy, root, CompositeRedirectManual);
|
XCompositeRedirectSubwindows (dpy, root, CompositeRedirectManual);
|
||||||
paint_root (dpy);
|
paint_all (dpy, None);
|
||||||
XSelectInput (dpy, root, SubstructureNotifyMask|ExposureMask);
|
XSelectInput (dpy, root, SubstructureNotifyMask|ExposureMask|StructureNotifyMask);
|
||||||
XQueryTree (dpy, root, &root_return, &parent_return, &children, &nchildren);
|
XQueryTree (dpy, root, &root_return, &parent_return, &children, &nchildren);
|
||||||
for (i = 0; i < nchildren; i++)
|
for (i = 0; i < nchildren; i++)
|
||||||
add_win (dpy, children[i], i ? children[i-1] : None);
|
add_win (dpy, children[i], i ? children[i-1] : None);
|
||||||
|
@ -789,6 +872,11 @@ main ()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (XEventsQueued (dpy, QueuedAfterReading));
|
} 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)
|
if (allDamage)
|
||||||
{
|
{
|
||||||
paint_all (dpy, allDamage);
|
paint_all (dpy, allDamage);
|
||||||
|
|
Loading…
Reference in New Issue