3 * Redraw the screen in case it's been trashed somehow
5 * (c) 2016 Straylight/Edgeware
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of the Edgeware X tools collection.
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.
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.
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.
27 /*----- Header files ------------------------------------------------------*/
34 #include <sys/types.h>
39 #include <mLib/alloc.h>
40 #include <mLib/mdwopt.h>
41 #include <mLib/quis.h>
42 #include <mLib/report.h>
44 /*----- Global variables --------------------------------------------------*/
48 /*----- Main code ---------------------------------------------------------*/
50 static void version(FILE *fp
)
51 { pquis(fp
, "$ (xtoys version " VERSION
")\n"); }
53 static void usage(FILE *fp
)
54 { pquis(fp
, "Usage: $ [-as] [-d display]\n"); }
56 static void help(FILE *fp
)
62 Repaint the X display (or just one screen).\n\
66 -h, --help Display this help text\n\
67 -u, --usage Display a short usage summary\n\
68 -v, --version Display the program's version number\n\
70 -a, --all Repaint all of the screens on the display\n\
71 -d, --display=DISPLAY Choose X display to connect to\n\
72 -s, --screen Only repaint the selected screen\n",
76 static Window
cover_screen(Screen
*sc
)
78 /* Make, map, and return a window completely covering the screen SC. */
81 XSetWindowAttributes attr
;
83 attr
.background_pixel
= 0;
84 attr
.event_mask
= StructureNotifyMask
| VisibilityChangeMask
| ExposureMask
| KeyPressMask
| ButtonPressMask
;
85 attr
.override_redirect
= True
;
86 w
= XCreateWindow(dpy
, RootWindowOfScreen(sc
),
87 0, 0, WidthOfScreen(sc
), HeightOfScreen(sc
),
88 0, CopyFromParent
, InputOutput
,
89 DefaultVisualOfScreen(sc
),
90 CWBackPixel
| CWEventMask
| CWOverrideRedirect
, &attr
);
95 int main(int argc
, char *argv
[])
97 const char *display
= 0;
107 /* Parse command line options. */
110 static struct option opt
[] = {
111 { "help", 0, 0, 'h' },
112 { "usage", 0, 0, 'u' },
113 { "version", 0, 0, 'v' },
114 { "all", 0, 0, 'a' },
115 { "display", OPTF_ARGREQ
, 0, 'd' },
116 { "screen", 0, 0, 's' },
119 int i
= getopt_long(argc
, argv
, "huv" "ad:s", opt
, 0);
122 case 'h': help(stdout
); exit(0); break;
123 case 'u': usage(stdout
); exit(0); break;
124 case 'v': version(stdout
); exit(0); break;
125 case 'a': f
&= ~f_only
; break;
126 case 'd': display
= optarg
; break;
127 case 's': f
|= f_only
; break;
128 default: f
|= f_bogus
; break;
131 if (optind
< argc
) f
|= f_bogus
;
132 if (f
& f_bogus
) { usage(stderr
); exit(EXIT_FAILURE
); }
134 /* Open the display. */
135 dpy
= XOpenDisplay(display
);
136 if (!dpy
) { die(EXIT_FAILURE
, "couldn't open display"); }
138 /* Annoyingly, `XClearWindow' uses `ClipByChildren' semantics, and there's
139 * no way to change that. The best idea I can come up with is to drop
140 * windows over the top of each screen and take them away again. The
141 * latter part is easy because they'll disappear when we close the
144 * Start by making and mapping the windows.
146 n
= f
&f_only ?
1 : ScreenCount(dpy
);
147 win
= xmalloc(n
*sizeof(Window
));
149 win
[0] = cover_screen(DefaultScreenOfDisplay(dpy
));
150 else for (i
= 0; i
< n
; i
++)
151 win
[i
] = cover_screen(ScreenOfDisplay(dpy
, i
));
153 /* Now we wait until they're all obviously mapped. */
155 XNextEvent(dpy
, &ev
);
158 w
= ev
.xmap
.window
; goto window_visible
;
159 case VisibilityNotify
: case Expose
: case KeyPress
: case ButtonPress
:
160 w
= ev
.xany
.window
; goto window_visible
;
162 for (i
= 0; i
< n
; i
++)
163 if (w
== win
[i
]) { win
[i
] = win
[--n
]; break; }
168 /* Finally, we must wait for a bit longer. This is an awful hack. */
169 tv
.tv_sec
= 0; tv
.tv_usec
= 50*1000;
170 select(0, 0, 0, 0, &tv
);
177 /*----- That's all, folks -------------------------------------------------*/