X-Git-Url: https://git.distorted.org.uk/~mdw/xtoys/blobdiff_plain/dd6d43a6e256a061ecf9a5fcb43c5e45cc69f3fe..c3d5f88d49ba3dbb7c2f44d5861206f273dd2924:/xrepaint.c diff --git a/xrepaint.c b/xrepaint.c index 166e238..23c81e0 100644 --- a/xrepaint.c +++ b/xrepaint.c @@ -36,6 +36,7 @@ #include +#include #include #include #include @@ -72,21 +73,17 @@ Options:\n\ fp); } -static void repaint(Screen *sc) +static Window cover_screen(Screen *sc) { - /* Repaint the screen SC. - * - * Annoyingly, `XClearWindow' uses `ClipByChildren' semantics, and there's - * no way to change that. The best idea I can come up with is to drop - * another window in front and take it away again. - */ + /* Make, map, and return a window completely covering the screen SC. */ Window w; XSetWindowAttributes attr; - XEvent ev; attr.background_pixel = 0; - attr.event_mask = StructureNotifyMask | VisibilityChangeMask | ExposureMask | KeyPressMask | ButtonPressMask; + attr.event_mask = + StructureNotifyMask | VisibilityChangeMask | ExposureMask | + KeyPressMask | ButtonPressMask; attr.override_redirect = True; w = XCreateWindow(dpy, RootWindowOfScreen(sc), 0, 0, WidthOfScreen(sc), HeightOfScreen(sc), @@ -94,8 +91,7 @@ static void repaint(Screen *sc) DefaultVisualOfScreen(sc), CWBackPixel | CWEventMask | CWOverrideRedirect, &attr); XMapWindow(dpy, w); - do XNextEvent(dpy, &ev); - while (ev.type != Expose && ev.type != KeyPress && ev.type != ButtonPress); + return (w); } int main(int argc, char *argv[]) @@ -103,7 +99,9 @@ int main(int argc, char *argv[]) const char *display = 0; unsigned f = 0; struct timeval tv; - int i; + XEvent ev; + Window *win, w; + int i, n; #define f_only 1u #define f_bogus 2u @@ -139,19 +137,42 @@ int main(int argc, char *argv[]) dpy = XOpenDisplay(display); if (!dpy) { die(EXIT_FAILURE, "couldn't open display"); } - /* Do the repainting thing. */ - if (f & f_only) - repaint(DefaultScreenOfDisplay(dpy)); - else { - for (i = 0; i < ScreenCount(dpy); i++) - repaint(ScreenOfDisplay(dpy, i)); + /* Annoyingly, `XClearWindow' uses `ClipByChildren' semantics, and there's + * no way to change that. The best idea I can come up with is to drop + * windows over the top of each screen and take them away again. The + * latter part is easy because they'll disappear when we close the + * display. + * + * Start by making and mapping the windows. + */ + n = f&f_only ? 1 : ScreenCount(dpy); + win = xmalloc(n*sizeof(Window)); + if (f&f_only) + win[0] = cover_screen(DefaultScreenOfDisplay(dpy)); + else for (i = 0; i < n; i++) + win[i] = cover_screen(ScreenOfDisplay(dpy, i)); + + /* Now we wait until they're all obviously mapped. */ + while (n) { + XNextEvent(dpy, &ev); + switch (ev.type) { + case MapNotify: + w = ev.xmap.window; goto window_visible; + case VisibilityNotify: case Expose: case KeyPress: case ButtonPress: + w = ev.xany.window; goto window_visible; + window_visible: + for (i = 0; i < n; i++) + if (w == win[i]) { win[i] = win[--n]; break; } + break; + } } - /* Wait for a bit. This is an awful hack. */ + /* Finally, we must wait for a bit longer. This is an awful hack. */ tv.tv_sec = 0; tv.tv_usec = 50*1000; select(0, 0, 0, 0, &tv); /* All done. */ + XCloseDisplay(dpy); return (0); }