1 /* xscreensaver, Copyright (c) 1991-1998 Jamie Zawinski <jwz@netscape.com>
3 * Permission to use, copy, modify, distribute, and sell this software and its
4 * documentation for any purpose is hereby granted without fee, provided that
5 * the above copyright notice appear in all copies and that both that
6 * copyright notice and this permission notice appear in supporting
7 * documentation. No representations are made about the suitability of this
8 * software for any purpose. It is provided "as is" without express or
16 #include <X11/Intrinsic.h>
17 #include <X11/StringDefs.h>
22 #else /* HAVE_ATHENA */
23 # include <X11/Shell.h>
24 # include <X11/Xaw/Form.h>
25 # include <X11/Xaw/Box.h>
26 # include <X11/Xaw/Command.h>
27 # include <X11/Xaw/Dialog.h>
28 #endif /* HAVE_ATHENA */
30 #include "xscreensaver.h"
36 extern void skull (Display *, Window, GC, GC, int, int, int, int);
39 roger (Widget button, XtPointer client_data, XtPointer call_data)
41 Display *dpy = XtDisplay (button);
42 Screen *screen = XtScreen (button);
43 Window window = XtWindow (button);
51 XWindowAttributes xgwa;
52 XGetWindowAttributes (dpy, window, &xgwa);
54 if (xgwa.width > xgwa.height) size = xgwa.height;
55 else size = xgwa.width;
56 if (size > 40) size -= 30;
57 x = (xgwa.width - size) / 2;
58 y = (xgwa.height - size) / 2;
59 XtSetArg (av [ac], XtNforeground, &fg); ac++;
60 XtSetArg (av [ac], XtNbackground, &bg); ac++;
61 XtGetValues (button, av, ac);
62 /* if it's black on white, swap it cause it looks better (hack hack) */
63 if (fg == BlackPixelOfScreen (screen) && bg == WhitePixelOfScreen (screen))
64 fg = WhitePixelOfScreen (screen), bg = BlackPixelOfScreen (screen);
66 erase_gc = XCreateGC (dpy, window, GCForeground, &gcv);
68 draw_gc = XCreateGC (dpy, window, GCForeground, &gcv);
69 XFillRectangle (dpy, window, erase_gc, 0, 0, xgwa.width, xgwa.height);
70 skull (dpy, window, draw_gc, erase_gc, x, y, size, size);
71 XFreeGC (dpy, draw_gc);
72 XFreeGC (dpy, erase_gc);
76 static Widget splash_shell;
77 extern Widget splash_dialog;
78 extern Widget splash_form;
79 extern Widget splash_roger_label;
80 extern Widget splash_label1;
81 extern Widget splash_label3;
82 extern Widget splash_demo;
83 extern Widget splash_prefs;
84 extern Widget splash_help;
87 splash_sink(saver_info *si)
89 if (si->splash_dialog)
91 XtDestroyWidget(si->splash_dialog);
92 XtDestroyWidget(splash_shell);
93 si->splash_dialog = 0;
99 splash_sink_timer (XtPointer closure, XtIntervalId *id)
101 saver_info *si = (saver_info *) closure;
107 send_self_clientmessage (saver_info *si, Atom command)
109 Display *dpy = si->dpy;
110 Window window = si->default_screen->screensaver_window;
112 event.xany.type = ClientMessage;
113 event.xclient.display = si->dpy;
114 event.xclient.window = window;
115 event.xclient.message_type = XA_SCREENSAVER;
116 event.xclient.format = 32;
117 event.xclient.data.l[0] = (long) command;
118 if (! XSendEvent (dpy, window, False, 0L, &event))
119 fprintf (stderr, "%s: XSendEvent(dpy, 0x%x ...) failed.\n",
120 progname, (unsigned int) window);
124 splash_demo_cb (Widget button, XtPointer client_data, XtPointer call_data)
126 saver_info *si = (saver_info *) client_data;
128 send_self_clientmessage (si, XA_DEMO);
132 splash_prefs_cb (Widget button, XtPointer client_data, XtPointer call_data)
134 saver_info *si = (saver_info *) client_data;
136 send_self_clientmessage (si, XA_PREFS);
140 splash_help_cb (Widget button, XtPointer client_data, XtPointer call_data)
142 saver_info *si = (saver_info *) client_data;
143 saver_preferences *p = &si->prefs;
147 if (!p->help_url || !*p->help_url)
148 fprintf(stderr, "%s: no Help URL has been specified.\n");
149 else if (!p->load_url_command || !*p->load_url_command)
150 fprintf(stderr, "%s: no URL-loading command has been specified.\n");
153 char *buf = (char *) malloc (strlen(p->load_url_command) +
154 (strlen(p->help_url) * 2) + 10);
155 sprintf(buf, p->load_url_command, p->help_url, p->help_url);
161 make_splash_dialog (saver_info *si)
163 saver_screen_info *ssi = si->default_screen;
164 Visual *v = DefaultVisualOfScreen(ssi->screen);
166 /* The splash dialog must always be created on the default visual and
167 with the default colormap, so that it shows up in the right colors
168 when viewed along with the rest of the desktop. The other xscreensaver
169 dialogs don't have this constraint, since they are only seen when the
170 blackout window is also exposed.
172 To accomplish this, we need our own ApplicationShell, since the shell
173 in si->default_screen->toplevel_shell might have a non-default visual.
175 splash_shell = XtVaAppCreateShell (progname, progclass,
176 applicationShellWidgetClass,
178 XtNscreen, ssi->screen,
180 XtNdepth, visual_depth(ssi->screen, v),
183 create_splash_dialog (splash_shell, v,
184 DefaultColormapOfScreen (ssi->screen));
185 si->splash_dialog = splash_dialog; /* gaaah... */
188 XawDialogAddButton(splash_form,"demo", splash_demo_cb, si);
189 XawDialogAddButton(splash_form,"prefs", splash_prefs_cb, si);
190 XawDialogAddButton(splash_form,"help", splash_help_cb, si);
191 splash_demo = XtNameToWidget(splash_form,"demo");
192 splash_prefs = XtNameToWidget(splash_form,"prefs");
193 splash_help = XtNameToWidget(splash_form,"help");
195 /* Lose the label on the inner dialog. */
197 Widget w = XtNameToWidget(splash_form, "label");
198 if (w) XtUnmanageChild(w);
201 #else /* HAVE_MOTIF */
202 /* Another random thing necessary in 1.2.1 but not 1.1.5... */
203 XtVaSetValues (splash_roger_label, XmNborderWidth, 1, 0);
205 XtAddCallback (splash_demo, XmNactivateCallback, splash_demo_cb, si);
206 XtAddCallback (splash_prefs, XmNactivateCallback, splash_prefs_cb, si);
207 XtAddCallback (splash_help, XmNactivateCallback, splash_help_cb, si);
208 XtAddCallback (splash_roger_label, XmNexposeCallback, roger, si);
210 #endif /* HAVE_MOTIF */
212 format_into_label (splash_label1, si->version);
214 XtRealizeWidget(splash_dialog);
218 pop_splash_dialog (saver_info *si)
220 XtIntervalId splash_sink_id;
222 if (si->prefs.splash_duration <= 0)
225 if (! si->splash_dialog)
226 make_splash_dialog (si);
229 splash_form = splash_dialog; /* kludge */
232 pop_up_dialog_box (splash_dialog, splash_form,
233 /* for debugging -- don't ask */
234 (si->prefs.debug_p ? 69 : 0) +
236 XtManageChild (splash_form);
239 if (splash_roger_label)
240 roger (splash_roger_label, 0, 0);
241 #endif /* HAVE_ATHENA */
243 splash_sink_id = XtAppAddTimeOut (si->app, si->prefs.splash_duration,
244 splash_sink_timer, (XtPointer) si);