diff options
author | Daniel Stenberg <daniel@haxx.se> | 2002-04-27 23:48:49 +0000 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2002-04-27 23:48:49 +0000 |
commit | 3caa3c08717ad745b49da01bf70a4c0da195ac14 (patch) | |
tree | 486f9d59673e537cd100957c8748b351e0a64ce4 /uisimulator/x11/screenhack.c | |
parent | c1543511b342162b2b537485c6646186037d8845 (diff) | |
download | rockbox-3caa3c08717ad745b49da01bf70a4c0da195ac14.tar.gz rockbox-3caa3c08717ad745b49da01bf70a4c0da195ac14.zip |
moved X11-specific files into a separate subdir to keep root clean for
target files
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@282 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'uisimulator/x11/screenhack.c')
-rw-r--r-- | uisimulator/x11/screenhack.c | 576 |
1 files changed, 576 insertions, 0 deletions
diff --git a/uisimulator/x11/screenhack.c b/uisimulator/x11/screenhack.c new file mode 100644 index 0000000000..f4f5aaa348 --- /dev/null +++ b/uisimulator/x11/screenhack.c | |||
@@ -0,0 +1,576 @@ | |||
1 | /* xscreensaver, Copyright (c) 1992, 1995, 1997, 1998 | ||
2 | * Jamie Zawinski <jwz@jwz.org> | ||
3 | * | ||
4 | * Permission to use, copy, modify, distribute, and sell this software and its | ||
5 | * documentation for any purpose is hereby granted without fee, provided that | ||
6 | * the above copyright notice appear in all copies and that both that | ||
7 | * copyright notice and this permission notice appear in supporting | ||
8 | * documentation. No representations are made about the suitability of this | ||
9 | * software for any purpose. It is provided "as is" without express or | ||
10 | * implied warranty. | ||
11 | * | ||
12 | * And remember: X Windows is to graphics hacking as roman numerals are to | ||
13 | * the square root of pi. | ||
14 | */ | ||
15 | |||
16 | /* This file contains simple code to open a window or draw on the root. | ||
17 | The idea being that, when writing a graphics hack, you can just link | ||
18 | with this .o to get all of the uninteresting junk out of the way. | ||
19 | |||
20 | - create a procedure `screenhack(dpy, window)' | ||
21 | |||
22 | - create a variable `char *progclass' which names this program's | ||
23 | resource class. | ||
24 | |||
25 | - create a variable `char defaults []' for the default resources, and | ||
26 | null-terminate it. | ||
27 | |||
28 | - create a variable `XrmOptionDescRec options[]' for the command-line, | ||
29 | and null-terminate it. | ||
30 | |||
31 | And that's it... | ||
32 | */ | ||
33 | |||
34 | #include <stdio.h> | ||
35 | #include <X11/Intrinsic.h> | ||
36 | #include <X11/IntrinsicP.h> | ||
37 | #include <X11/CoreP.h> | ||
38 | #include <X11/Shell.h> | ||
39 | #include <X11/StringDefs.h> | ||
40 | #include <X11/Xutil.h> | ||
41 | #include <X11/keysym.h> | ||
42 | |||
43 | #ifdef __sgi | ||
44 | # include <X11/SGIScheme.h> /* for SgiUseSchemes() */ | ||
45 | #endif /* __sgi */ | ||
46 | |||
47 | #ifdef HAVE_XMU | ||
48 | # ifndef VMS | ||
49 | # include <X11/Xmu/Error.h> | ||
50 | # else /* VMS */ | ||
51 | # include <Xmu/Error.h> | ||
52 | # endif | ||
53 | #else | ||
54 | # include "xmu.h" | ||
55 | #endif | ||
56 | #include "screenhack.h" | ||
57 | #include "version.h" | ||
58 | #include "vroot.h" | ||
59 | |||
60 | #ifndef isupper | ||
61 | # define isupper(c) ((c) >= 'A' && (c) <= 'Z') | ||
62 | #endif | ||
63 | #ifndef _tolower | ||
64 | # define _tolower(c) ((c) - 'A' + 'a') | ||
65 | #endif | ||
66 | |||
67 | |||
68 | char *progname; | ||
69 | XrmDatabase db; | ||
70 | XtAppContext app; | ||
71 | Bool mono_p; | ||
72 | |||
73 | static XrmOptionDescRec default_options [] = { | ||
74 | { "-root", ".root", XrmoptionNoArg, "True" }, | ||
75 | { "-window", ".root", XrmoptionNoArg, "False" }, | ||
76 | { "-mono", ".mono", XrmoptionNoArg, "True" }, | ||
77 | { "-install", ".installColormap", XrmoptionNoArg, "True" }, | ||
78 | { "-noinstall",".installColormap", XrmoptionNoArg, "False" }, | ||
79 | { "-visual", ".visualID", XrmoptionSepArg, 0 }, | ||
80 | { "-window-id", ".windowID", XrmoptionSepArg, 0 }, | ||
81 | { 0, 0, 0, 0 } | ||
82 | }; | ||
83 | |||
84 | static char *default_defaults[] = { | ||
85 | ".root: false", | ||
86 | "*geometry: 200x100", /* this should be .geometry, but nooooo... */ | ||
87 | "*mono: false", | ||
88 | "*installColormap: false", | ||
89 | "*visualID: default", | ||
90 | "*windowID: ", | ||
91 | 0 | ||
92 | }; | ||
93 | |||
94 | extern Display* dpy; | ||
95 | |||
96 | static XrmOptionDescRec *merged_options; | ||
97 | static int merged_options_size; | ||
98 | static char **merged_defaults; | ||
99 | |||
100 | static void | ||
101 | merge_options (void) | ||
102 | { | ||
103 | int def_opts_size, opts_size; | ||
104 | int def_defaults_size, defaults_size; | ||
105 | |||
106 | for (def_opts_size = 0; default_options[def_opts_size].option; | ||
107 | def_opts_size++) | ||
108 | ; | ||
109 | for (opts_size = 0; options[opts_size].option; opts_size++) | ||
110 | ; | ||
111 | |||
112 | merged_options_size = def_opts_size + opts_size; | ||
113 | merged_options = (XrmOptionDescRec *) | ||
114 | malloc ((merged_options_size + 1) * sizeof(*default_options)); | ||
115 | memcpy (merged_options, default_options, | ||
116 | (def_opts_size * sizeof(*default_options))); | ||
117 | memcpy (merged_options + def_opts_size, options, | ||
118 | ((opts_size + 1) * sizeof(*default_options))); | ||
119 | |||
120 | for (def_defaults_size = 0; default_defaults[def_defaults_size]; | ||
121 | def_defaults_size++) | ||
122 | ; | ||
123 | for (defaults_size = 0; defaults[defaults_size]; defaults_size++) | ||
124 | ; | ||
125 | merged_defaults = (char **) | ||
126 | malloc ((def_defaults_size + defaults_size + 1) * sizeof (*defaults));; | ||
127 | memcpy (merged_defaults, default_defaults, | ||
128 | def_defaults_size * sizeof(*defaults)); | ||
129 | memcpy (merged_defaults + def_defaults_size, defaults, | ||
130 | (defaults_size + 1) * sizeof(*defaults)); | ||
131 | |||
132 | /* This totally sucks. Xt should behave like this by default. | ||
133 | If the string in `defaults' looks like ".foo", change that | ||
134 | to "Progclass.foo". | ||
135 | */ | ||
136 | { | ||
137 | char **s; | ||
138 | for (s = merged_defaults; *s; s++) | ||
139 | if (**s == '.') | ||
140 | { | ||
141 | const char *oldr = *s; | ||
142 | char *newr = (char *) malloc(strlen(oldr) + strlen(progclass) + 3); | ||
143 | strcpy (newr, progclass); | ||
144 | strcat (newr, oldr); | ||
145 | *s = newr; | ||
146 | } | ||
147 | } | ||
148 | } | ||
149 | |||
150 | |||
151 | /* Make the X errors print out the name of this program, so we have some | ||
152 | clue which one has a bug when they die under the screensaver. | ||
153 | */ | ||
154 | |||
155 | static int | ||
156 | screenhack_ehandler (Display *dpy, XErrorEvent *error) | ||
157 | { | ||
158 | fprintf (stderr, "\nX error in %s:\n", progname); | ||
159 | if (XmuPrintDefaultErrorMessage (dpy, error, stderr)) | ||
160 | exit (-1); | ||
161 | else | ||
162 | fprintf (stderr, " (nonfatal.)\n"); | ||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | static Bool | ||
167 | MapNotify_event_p (Display *dpy, XEvent *event, XPointer window) | ||
168 | { | ||
169 | return (event->xany.type == MapNotify && | ||
170 | event->xvisibility.window == (Window) window); | ||
171 | } | ||
172 | |||
173 | |||
174 | #ifdef XLOCKMORE | ||
175 | extern void pre_merge_options (void); | ||
176 | #endif | ||
177 | |||
178 | |||
179 | static Atom XA_WM_PROTOCOLS, XA_WM_DELETE_WINDOW; | ||
180 | |||
181 | /* Dead-trivial event handling: exits if "q" or "ESC" are typed. | ||
182 | Exit if the WM_PROTOCOLS WM_DELETE_WINDOW ClientMessage is received. | ||
183 | */ | ||
184 | int | ||
185 | screenhack_handle_event (Display *dpy, XEvent *event) | ||
186 | { | ||
187 | int key=0; | ||
188 | switch (event->xany.type) | ||
189 | { | ||
190 | case KeyPress: | ||
191 | { | ||
192 | KeySym keysym; | ||
193 | unsigned char c = 0; | ||
194 | XLookupString (&event->xkey, &c, 1, &keysym, 0); | ||
195 | if (! (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)) | ||
196 | XBell (dpy, 0); /* beep for non-chord keys */ | ||
197 | key = keysym; | ||
198 | fprintf(stderr, "KEY PRESSED: %c (%02x)\n", c, c); | ||
199 | } | ||
200 | break; | ||
201 | case ResizeRequest: | ||
202 | screen_resized(event->xresizerequest.width, event->xresizerequest.height); | ||
203 | screen_redraw(); | ||
204 | fprintf(stderr, "WINDOW RESIZED to width %d height %d\n", | ||
205 | event->xresizerequest.width, event->xresizerequest.height); | ||
206 | break; | ||
207 | default: | ||
208 | fprintf(stderr, "EVENT: %d (see /usr/include/X11/X.h)\n", | ||
209 | event->xany.type); | ||
210 | break; | ||
211 | case Expose: | ||
212 | screen_redraw(); | ||
213 | fprintf(stderr, "EXPOSE: x: %d y: %d width: %d height: %d\n", | ||
214 | event->xexpose.x, event->xexpose.y, | ||
215 | event->xexpose.width, event->xexpose.height); | ||
216 | break; | ||
217 | case ButtonPress: | ||
218 | fprintf(stderr, "BUTTON PRESSED\n"); | ||
219 | break; | ||
220 | case ClientMessage: | ||
221 | { | ||
222 | if (event->xclient.message_type != XA_WM_PROTOCOLS) | ||
223 | { | ||
224 | char *s = XGetAtomName(dpy, event->xclient.message_type); | ||
225 | if (!s) s = "(null)"; | ||
226 | fprintf (stderr, "%s: unknown ClientMessage %s received!\n", | ||
227 | progname, s); | ||
228 | } | ||
229 | else if (event->xclient.data.l[0] != XA_WM_DELETE_WINDOW) | ||
230 | { | ||
231 | char *s1 = XGetAtomName(dpy, event->xclient.message_type); | ||
232 | char *s2 = XGetAtomName(dpy, event->xclient.data.l[0]); | ||
233 | if (!s1) s1 = "(null)"; | ||
234 | if (!s2) s2 = "(null)"; | ||
235 | fprintf (stderr, "%s: unknown ClientMessage %s[%s] received!\n", | ||
236 | progname, s1, s2); | ||
237 | } | ||
238 | else | ||
239 | { | ||
240 | exit (0); | ||
241 | } | ||
242 | } | ||
243 | break; | ||
244 | } | ||
245 | return key; | ||
246 | } | ||
247 | |||
248 | |||
249 | int | ||
250 | screenhack_handle_events (void) | ||
251 | { | ||
252 | int key=0; | ||
253 | while (XPending (dpy)) | ||
254 | { | ||
255 | XEvent event; | ||
256 | XNextEvent (dpy, &event); | ||
257 | key=screenhack_handle_event (dpy, &event); | ||
258 | } | ||
259 | return key; | ||
260 | } | ||
261 | |||
262 | |||
263 | static Visual * | ||
264 | pick_visual (Screen *screen) | ||
265 | { | ||
266 | #ifdef USE_GL | ||
267 | /* If we're linking against GL (that is, this is the version of screenhack.o | ||
268 | that the GL hacks will use, which is different from the one that the | ||
269 | non-GL hacks will use) then try to pick the "best" visual by interrogating | ||
270 | the GL library instead of by asking Xlib. GL knows better. | ||
271 | */ | ||
272 | Visual *v = 0; | ||
273 | char *string = get_string_resource ("visualID", "VisualID"); | ||
274 | char *s; | ||
275 | |||
276 | if (string) | ||
277 | for (s = string; *s; s++) | ||
278 | if (isupper (*s)) *s = _tolower (*s); | ||
279 | |||
280 | if (!string || !*string || | ||
281 | !strcmp (string, "gl") || | ||
282 | !strcmp (string, "best") || | ||
283 | !strcmp (string, "color") || | ||
284 | !strcmp (string, "default")) | ||
285 | v = get_gl_visual (screen); /* from ../utils/visual-gl.c */ | ||
286 | |||
287 | if (string) | ||
288 | free (string); | ||
289 | if (v) | ||
290 | return v; | ||
291 | #endif /* USE_GL */ | ||
292 | |||
293 | return get_visual_resource (screen, "visualID", "VisualID", False); | ||
294 | } | ||
295 | |||
296 | |||
297 | /* Notice when the user has requested a different visual or colormap | ||
298 | on a pre-existing window (e.g., "-root -visual truecolor" or | ||
299 | "-window-id 0x2c00001 -install") and complain, since when drawing | ||
300 | on an existing window, we have no choice about these things. | ||
301 | */ | ||
302 | static void | ||
303 | visual_warning (Screen *screen, Window window, Visual *visual, Colormap cmap, | ||
304 | Bool window_p) | ||
305 | { | ||
306 | char *visual_string = get_string_resource ("visualID", "VisualID"); | ||
307 | Visual *desired_visual = pick_visual (screen); | ||
308 | char win[100]; | ||
309 | char why[100]; | ||
310 | |||
311 | if (window == RootWindowOfScreen (screen)) | ||
312 | strcpy (win, "root window"); | ||
313 | else | ||
314 | sprintf (win, "window 0x%x", (unsigned long) window); | ||
315 | |||
316 | if (window_p) | ||
317 | sprintf (why, "-window-id 0x%x", (unsigned long) window); | ||
318 | else | ||
319 | strcpy (why, "-root"); | ||
320 | |||
321 | if (visual_string && *visual_string) | ||
322 | { | ||
323 | char *s; | ||
324 | for (s = visual_string; *s; s++) | ||
325 | if (isupper (*s)) *s = _tolower (*s); | ||
326 | |||
327 | if (!strcmp (visual_string, "default") || | ||
328 | !strcmp (visual_string, "default") || | ||
329 | !strcmp (visual_string, "best")) | ||
330 | /* don't warn about these, just silently DWIM. */ | ||
331 | ; | ||
332 | else if (visual != desired_visual) | ||
333 | { | ||
334 | fprintf (stderr, "%s: ignoring `-visual %s' because of `%s'.\n", | ||
335 | progname, visual_string, why); | ||
336 | fprintf (stderr, "%s: using %s's visual 0x%x.\n", | ||
337 | progname, win, XVisualIDFromVisual (visual)); | ||
338 | } | ||
339 | free (visual_string); | ||
340 | } | ||
341 | |||
342 | if (visual == DefaultVisualOfScreen (screen) && | ||
343 | has_writable_cells (screen, visual) && | ||
344 | get_boolean_resource ("installColormap", "InstallColormap")) | ||
345 | { | ||
346 | fprintf (stderr, "%s: ignoring `-install' because of `%s'.\n", | ||
347 | progname, why); | ||
348 | fprintf (stderr, "%s: using %s's colormap 0x%x.\n", | ||
349 | progname, win, (unsigned long) cmap); | ||
350 | } | ||
351 | } | ||
352 | |||
353 | |||
354 | int | ||
355 | main (int argc, char **argv) | ||
356 | { | ||
357 | Widget toplevel; | ||
358 | Display *dpy; | ||
359 | Window window; | ||
360 | Screen *screen; | ||
361 | Visual *visual; | ||
362 | Colormap cmap; | ||
363 | Bool root_p; | ||
364 | Window on_window = 0; | ||
365 | XEvent event; | ||
366 | Boolean dont_clear /*, dont_map */; | ||
367 | char version[255]; | ||
368 | |||
369 | #ifdef XLOCKMORE | ||
370 | pre_merge_options (); | ||
371 | #endif | ||
372 | merge_options (); | ||
373 | |||
374 | #ifdef __sgi | ||
375 | /* We have to do this on SGI to prevent the background color from being | ||
376 | overridden by the current desktop color scheme (we'd like our backgrounds | ||
377 | to be black, thanks.) This should be the same as setting the | ||
378 | "*useSchemes: none" resource, but it's not -- if that resource is | ||
379 | present in the `default_defaults' above, it doesn't work, though it | ||
380 | does work when passed as an -xrm arg on the command line. So screw it, | ||
381 | turn them off from C instead. | ||
382 | */ | ||
383 | SgiUseSchemes ("none"); | ||
384 | #endif /* __sgi */ | ||
385 | |||
386 | toplevel = XtAppInitialize (&app, progclass, merged_options, | ||
387 | merged_options_size, &argc, argv, | ||
388 | merged_defaults, 0, 0); | ||
389 | dpy = XtDisplay (toplevel); | ||
390 | screen = XtScreen (toplevel); | ||
391 | db = XtDatabase (dpy); | ||
392 | |||
393 | XtGetApplicationNameAndClass (dpy, &progname, &progclass); | ||
394 | |||
395 | /* half-assed way of avoiding buffer-overrun attacks. */ | ||
396 | if (strlen (progname) >= 100) progname[100] = 0; | ||
397 | |||
398 | XSetErrorHandler (screenhack_ehandler); | ||
399 | |||
400 | XA_WM_PROTOCOLS = XInternAtom (dpy, "WM_PROTOCOLS", False); | ||
401 | XA_WM_DELETE_WINDOW = XInternAtom (dpy, "WM_DELETE_WINDOW", False); | ||
402 | |||
403 | |||
404 | if (argc > 1) | ||
405 | { | ||
406 | const char *s; | ||
407 | int i; | ||
408 | int x = 18; | ||
409 | int end = 78; | ||
410 | Bool help_p = !strcmp(argv[1], "-help"); | ||
411 | fprintf (stderr, "%s\n", version); | ||
412 | for (s = progclass; *s; s++) fprintf(stderr, " "); | ||
413 | fprintf (stderr, " eXcellent GUI\n\n"); | ||
414 | |||
415 | if (!help_p) | ||
416 | fprintf(stderr, "Unrecognised option: %s\n", argv[1]); | ||
417 | fprintf (stderr, "Options include: "); | ||
418 | for (i = 0; i < merged_options_size; i++) | ||
419 | { | ||
420 | char *sw = merged_options [i].option; | ||
421 | Bool argp = (merged_options [i].argKind == XrmoptionSepArg); | ||
422 | int size = strlen (sw) + (argp ? 6 : 0) + 2; | ||
423 | if (x + size >= end) | ||
424 | { | ||
425 | fprintf (stderr, "\n\t\t "); | ||
426 | x = 18; | ||
427 | } | ||
428 | x += size; | ||
429 | fprintf (stderr, "%s", sw); | ||
430 | if (argp) fprintf (stderr, " <arg>"); | ||
431 | if (i != merged_options_size - 1) fprintf (stderr, ", "); | ||
432 | } | ||
433 | fprintf (stderr, ".\n"); | ||
434 | exit (help_p ? 0 : 1); | ||
435 | } | ||
436 | |||
437 | dont_clear = get_boolean_resource ("dontClearRoot", "Boolean"); | ||
438 | /*dont_map = get_boolean_resource ("dontMapWindow", "Boolean"); */ | ||
439 | mono_p = get_boolean_resource ("mono", "Boolean"); | ||
440 | if (CellsOfScreen (DefaultScreenOfDisplay (dpy)) <= 2) | ||
441 | mono_p = True; | ||
442 | |||
443 | root_p = get_boolean_resource ("root", "Boolean"); | ||
444 | |||
445 | { | ||
446 | char *s = get_string_resource ("windowID", "WindowID"); | ||
447 | if (s && *s) | ||
448 | on_window = get_integer_resource ("windowID", "WindowID"); | ||
449 | if (s) free (s); | ||
450 | } | ||
451 | |||
452 | if (on_window) | ||
453 | { | ||
454 | XWindowAttributes xgwa; | ||
455 | window = (Window) on_window; | ||
456 | XtDestroyWidget (toplevel); | ||
457 | XGetWindowAttributes (dpy, window, &xgwa); | ||
458 | cmap = xgwa.colormap; | ||
459 | visual = xgwa.visual; | ||
460 | visual_warning (screen, window, visual, cmap, True); | ||
461 | } | ||
462 | else if (root_p) | ||
463 | { | ||
464 | XWindowAttributes xgwa; | ||
465 | window = RootWindowOfScreen (XtScreen (toplevel)); | ||
466 | XtDestroyWidget (toplevel); | ||
467 | XGetWindowAttributes (dpy, window, &xgwa); | ||
468 | cmap = xgwa.colormap; | ||
469 | visual = xgwa.visual; | ||
470 | visual_warning (screen, window, visual, cmap, False); | ||
471 | } | ||
472 | else | ||
473 | { | ||
474 | Boolean def_visual_p; | ||
475 | visual = pick_visual (screen); | ||
476 | |||
477 | if (toplevel->core.width <= 0) | ||
478 | toplevel->core.width = 600; | ||
479 | if (toplevel->core.height <= 0) | ||
480 | toplevel->core.height = 480; | ||
481 | |||
482 | def_visual_p = (visual == DefaultVisualOfScreen (screen)); | ||
483 | |||
484 | if (!def_visual_p) | ||
485 | { | ||
486 | unsigned int bg, bd; | ||
487 | Widget new; | ||
488 | |||
489 | cmap = XCreateColormap (dpy, RootWindowOfScreen(screen), | ||
490 | visual, AllocNone); | ||
491 | bg = get_pixel_resource ("background", "Background", dpy, cmap); | ||
492 | bd = get_pixel_resource ("borderColor", "Foreground", dpy, cmap); | ||
493 | |||
494 | new = XtVaAppCreateShell (progname, progclass, | ||
495 | topLevelShellWidgetClass, dpy, | ||
496 | XtNmappedWhenManaged, False, | ||
497 | XtNvisual, visual, | ||
498 | XtNdepth, visual_depth (screen, visual), | ||
499 | XtNwidth, toplevel->core.width, | ||
500 | XtNheight, toplevel->core.height, | ||
501 | XtNcolormap, cmap, | ||
502 | XtNbackground, (Pixel) bg, | ||
503 | XtNborderColor, (Pixel) bd, | ||
504 | XtNinput, True, /* for WM_HINTS */ | ||
505 | 0); | ||
506 | XtDestroyWidget (toplevel); | ||
507 | toplevel = new; | ||
508 | XtRealizeWidget (toplevel); | ||
509 | window = XtWindow (toplevel); | ||
510 | } | ||
511 | else | ||
512 | { | ||
513 | XtVaSetValues (toplevel, | ||
514 | XtNmappedWhenManaged, False, | ||
515 | XtNinput, True, /* for WM_HINTS */ | ||
516 | 0); | ||
517 | XtRealizeWidget (toplevel); | ||
518 | window = XtWindow (toplevel); | ||
519 | |||
520 | if (get_boolean_resource ("installColormap", "InstallColormap")) | ||
521 | { | ||
522 | cmap = XCreateColormap (dpy, window, | ||
523 | DefaultVisualOfScreen (XtScreen (toplevel)), | ||
524 | AllocNone); | ||
525 | XSetWindowColormap (dpy, window, cmap); | ||
526 | } | ||
527 | else | ||
528 | { | ||
529 | cmap = DefaultColormap (dpy, DefaultScreen (dpy)); | ||
530 | } | ||
531 | } | ||
532 | |||
533 | /* | ||
534 | if (dont_map) | ||
535 | { | ||
536 | XtVaSetValues (toplevel, XtNmappedWhenManaged, False, 0); | ||
537 | XtRealizeWidget (toplevel); | ||
538 | } | ||
539 | else | ||
540 | */ | ||
541 | { | ||
542 | XtPopup (toplevel, XtGrabNone); | ||
543 | } | ||
544 | |||
545 | XtVaSetValues(toplevel, XtNtitle, version, 0); | ||
546 | |||
547 | /* For screenhack_handle_events(): select KeyPress, and | ||
548 | announce that we accept WM_DELETE_WINDOW. */ | ||
549 | { | ||
550 | XWindowAttributes xgwa; | ||
551 | XGetWindowAttributes (dpy, window, &xgwa); | ||
552 | XSelectInput (dpy, window, | ||
553 | xgwa.your_event_mask | KeyPressMask | ButtonPressMask | ResizeRedirectMask | ExposureMask); | ||
554 | XChangeProperty (dpy, window, XA_WM_PROTOCOLS, XA_ATOM, 32, | ||
555 | PropModeReplace, | ||
556 | (unsigned char *) &XA_WM_DELETE_WINDOW, 1); | ||
557 | } | ||
558 | } | ||
559 | |||
560 | if (!dont_clear) | ||
561 | { | ||
562 | XSetWindowBackground (dpy, window, | ||
563 | get_pixel_resource ("background", "Background", | ||
564 | dpy, cmap)); | ||
565 | XClearWindow (dpy, window); | ||
566 | } | ||
567 | |||
568 | if (!root_p && !on_window) | ||
569 | /* wait for it to be mapped */ | ||
570 | XIfEvent (dpy, &event, MapNotify_event_p, (XPointer) window); | ||
571 | |||
572 | XSync (dpy, False); | ||
573 | |||
574 | screenhack (dpy, window); /* doesn't return */ | ||
575 | return 0; | ||
576 | } | ||