Release 1.6.0.
[xtoys] / xrepaint.c
CommitLineData
dd6d43a6
MW
1/* -*-c-*-
2 *
3 * Redraw the screen in case it's been trashed somehow
4 *
5 * (c) 2016 Straylight/Edgeware
6 */
7
8/*----- Licensing notice --------------------------------------------------*
9 *
10 * This file is part of the Edgeware X tools collection.
11 *
12 * X tools is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * X tools is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with X tools; if not, write to the Free Software Foundation,
24 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 */
26
27/*----- Header files ------------------------------------------------------*/
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32
33#include <sys/time.h>
34#include <sys/types.h>
35#include <unistd.h>
36
37#include <X11/Xlib.h>
38
39#include <mLib/mdwopt.h>
40#include <mLib/quis.h>
41#include <mLib/report.h>
42
43/*----- Global variables --------------------------------------------------*/
44
45static Display *dpy;
46
47/*----- Main code ---------------------------------------------------------*/
48
49static void version(FILE *fp)
50 { pquis(fp, "$ (xtoys version " VERSION ")\n"); }
51
52static void usage(FILE *fp)
53 { pquis(fp, "Usage: $ [-as] [-d display]\n"); }
54
55static void help(FILE *fp)
56{
57 version(fp);
58 fputc('\n', fp);
59 usage(stdout);
60 fputs("\n\
61Repaint the X display (or just one screen).\n\
62\n\
63Options:\n\
64\n\
65-h, --help Display this help text\n\
66-u, --usage Display a short usage summary\n\
67-v, --version Display the program's version number\n\
68\n\
69-a, --all Repaint all of the screens on the display\n\
70-d, --display=DISPLAY Choose X display to connect to\n\
71-s, --screen Only repaint the selected screen\n",
72 fp);
73}
74
75static void repaint(Screen *sc)
76{
77 /* Repaint the screen SC.
78 *
79 * Annoyingly, `XClearWindow' uses `ClipByChildren' semantics, and there's
80 * no way to change that. The best idea I can come up with is to drop
81 * another window in front and take it away again.
82 */
83
84 Window w;
85 XSetWindowAttributes attr;
86 XEvent ev;
87
88 attr.background_pixel = 0;
89 attr.event_mask = StructureNotifyMask | VisibilityChangeMask | ExposureMask | KeyPressMask | ButtonPressMask;
90 attr.override_redirect = True;
91 w = XCreateWindow(dpy, RootWindowOfScreen(sc),
92 0, 0, WidthOfScreen(sc), HeightOfScreen(sc),
93 0, CopyFromParent, InputOutput,
94 DefaultVisualOfScreen(sc),
95 CWBackPixel | CWEventMask | CWOverrideRedirect, &attr);
96 XMapWindow(dpy, w);
97 do XNextEvent(dpy, &ev);
98 while (ev.type != Expose && ev.type != KeyPress && ev.type != ButtonPress);
99}
100
101int main(int argc, char *argv[])
102{
103 const char *display = 0;
104 unsigned f = 0;
105 struct timeval tv;
106 int i;
107
108#define f_only 1u
109#define f_bogus 2u
110
111 /* Parse command line options. */
112 ego(argv[0]);
113 for (;;) {
114 static struct option opt[] = {
115 { "help", 0, 0, 'h' },
116 { "usage", 0, 0, 'u' },
117 { "version", 0, 0, 'v' },
118 { "all", 0, 0, 'a' },
119 { "display", OPTF_ARGREQ, 0, 'd' },
120 { "screen", 0, 0, 's' },
121 { 0, 0, 0, 0 }
122 };
123 int i = getopt_long(argc, argv, "huv" "ad:s", opt, 0);
124 if (i < 0) break;
125 switch (i) {
126 case 'h': help(stdout); exit(0); break;
127 case 'u': usage(stdout); exit(0); break;
128 case 'v': version(stdout); exit(0); break;
129 case 'a': f &= ~f_only; break;
130 case 'd': display = optarg; break;
131 case 's': f |= f_only; break;
132 default: f |= f_bogus; break;
133 }
134 }
135 if (optind < argc) f |= f_bogus;
136 if (f & f_bogus) { usage(stderr); exit(EXIT_FAILURE); }
137
138 /* Open the display. */
139 dpy = XOpenDisplay(display);
140 if (!dpy) { die(EXIT_FAILURE, "couldn't open display"); }
141
142 /* Do the repainting thing. */
143 if (f & f_only)
144 repaint(DefaultScreenOfDisplay(dpy));
145 else {
146 for (i = 0; i < ScreenCount(dpy); i++)
147 repaint(ScreenOfDisplay(dpy, i));
148 }
149
150 /* Wait for a bit. This is an awful hack. */
151 tv.tv_sec = 0; tv.tv_usec = 50*1000;
152 select(0, 0, 0, 0, &tv);
153
154 /* All done. */
155 return (0);
156}
157
158/*----- That's all, folks -------------------------------------------------*/