-/* xscreensaver, Copyright (c) 1991-1998 Jamie Zawinski <jwz@netscape.com>
+/* xscreensaver, Copyright (c) 1991-2001 Jamie Zawinski <jwz@netscape.com>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
}
-static void
-send_self_clientmessage (saver_info *si, Atom command)
-{
- Display *dpy = si->dpy;
- Window window = si->default_screen->screensaver_window;
- XEvent event;
- event.xany.type = ClientMessage;
- event.xclient.display = si->dpy;
- event.xclient.window = window;
- event.xclient.message_type = XA_SCREENSAVER;
- event.xclient.format = 32;
- memset (&event.xclient.data, 0, sizeof(event.xclient.data));
- event.xclient.data.l[0] = (long) command;
- if (! XSendEvent (dpy, window, False, 0L, &event))
- fprintf (stderr, "%s: XSendEvent(dpy, 0x%x ...) failed.\n",
- progname, (unsigned int) window);
-}
-
-
-static void
-get_help (saver_info *si)
-{
- saver_preferences *p = &si->prefs;
-
- if (!p->help_url || !*p->help_url)
- fprintf (stderr, "%s: no Help URL has been specified.\n", blurb());
- else if (!p->load_url_command || !*p->load_url_command)
- fprintf (stderr, "%s: no URL-loading command has been specified.\n",
- blurb());
- else
- {
- char *buf = (char *) malloc (strlen(p->load_url_command) +
- (strlen(p->help_url) * 2) + 10);
- sprintf (buf, p->load_url_command, p->help_url, p->help_url);
- system (buf);
- }
-}
-
static void update_splash_window (saver_info *si);
static void draw_splash_window (saver_info *si);
static void destroy_splash_window (saver_info *si);
static void unsplash_timer (XtPointer closure, XtIntervalId *id);
+static void do_demo (saver_info *si);
+static void do_prefs (saver_info *si);
+static void do_help (saver_info *si);
+
struct splash_dialog_data {
XtIntervalId timer;
if (si->sp_data)
return;
- if (si->prefs.splash_duration <= 0)
+ if (!si->prefs.splash_p ||
+ si->prefs.splash_duration <= 0)
return;
sp = (splash_dialog_data *) calloc (1, sizeof(*sp));
attrs.event_mask = (ExposureMask | ButtonPressMask | ButtonReleaseMask);
{
- Dimension w = WidthOfScreen(screen);
- Dimension h = HeightOfScreen(screen);
+ int sx, sy, w, h;
+ get_screen_viewport (si->default_screen, &sx, &sy, &w, &h, False);
if (si->prefs.debug_p) w /= 2;
- x = ((w + sp->width) / 2) - sp->width;
- y = ((h + sp->height) / 2) - sp->height;
- if (x < 0) x = 0;
- if (y < 0) y = 0;
+ x = sx + (((w + sp->width) / 2) - sp->width);
+ y = sy + (((h + sp->height) / 2) - sp->height);
+ if (x < sx) x = sx;
+ if (y < sy) y = sy;
}
bw = get_integer_resource ("splash.borderWidth", "Dialog.BorderWidth");
XSync (si->dpy, False);
}
+void
+draw_logo (saver_info *si, Window win, int x, int y, int w, int h,
+ Bool first_time_p)
+{
+ Colormap cmap = DefaultColormapOfScreen (si->default_screen->screen);
+ Pixmap logo_map = XCreatePixmap (si->dpy, win, w, h,
+ si->default_screen->current_depth);
+ XGCValues gcv;
+ GC gc = XCreateGC (si->dpy, win, 0, &gcv);
+ xscreensaver_logo (si->dpy, logo_map, cmap, !first_time_p);
+ XCopyArea (si->dpy, logo_map, win, gc, 0, 0, w, h, x, y);
+ XFreeGC (si->dpy, gc);
+ XFreePixmap (si->dpy, logo_map);
+}
+
+
static void
draw_splash_window (saver_info *si)
{
x2 = sp->logo_width - (sp->shadow_width * 6);
y2 = sp->logo_height - (sp->shadow_width * 6);
- XFillRectangle (si->dpy, si->splash_dialog, gc2, x1, y1, x2, y2);
- skull (si->dpy, si->splash_dialog, gc1, gc2,
- x1 + sp->shadow_width, y1 + sp->shadow_width,
- x2 - (sp->shadow_width * 2), y2 - (sp->shadow_width * 2));
+ draw_logo (si, si->splash_dialog, x1, y1, x2, y2, True);
/* The shadow around the logo
destroy_splash_window (si);
switch (which)
{
- case 1: send_self_clientmessage (si, XA_DEMO); break;
- case 2: send_self_clientmessage (si, XA_PREFS); break;
- case 3: get_help (si); break;
+ case 1: do_demo (si); break;
+ case 2: do_prefs (si); break;
+ case 3: do_help (si); break;
default: abort();
}
}
if (si && si->sp_data)
destroy_splash_window (si);
}
+
+\f
+/* Button callbacks */
+
+#ifdef VMS
+# define pid_t int
+# define fork vfork
+#endif /* VMS */
+
+static void
+fork_and_exec (saver_info *si, const char *command, const char *desc)
+{
+ saver_preferences *p = &si->prefs;
+ pid_t forked;
+ char buf [512];
+ char *av[5];
+ int ac;
+
+ if (!command || !*command)
+ {
+ fprintf (stderr, "%s: no %s command has been specified.\n",
+ blurb(), desc);
+ return;
+ }
+
+ switch ((int) (forked = fork ()))
+ {
+ case -1:
+ sprintf (buf, "%s: couldn't fork", blurb());
+ perror (buf);
+ break;
+
+ case 0:
+ close (ConnectionNumber (si->dpy)); /* close display fd */
+ hack_subproc_environment (si->default_screen); /* set $DISPLAY */
+ ac = 0;
+ av [ac++] = (char *) p->shell;
+ av [ac++] = (char *) "-c";
+ av [ac++] = (char *) command;
+ av [ac] = 0;
+ execvp (av[0], av); /* shouldn't return. */
+
+ sprintf (buf, "%s: execvp(\"%s\", \"%s\", \"%s\") failed",
+ blurb(), av[0], av[1], av[2]);
+ perror (buf);
+ fflush (stderr);
+ fflush (stdout);
+ exit (1); /* Note that this only exits a child fork. */
+ break;
+
+ default:
+ /* parent fork. */
+ break;
+ }
+}
+
+
+static void
+do_demo (saver_info *si)
+{
+ saver_preferences *p = &si->prefs;
+ fork_and_exec (si, p->demo_command, "demo-mode");
+}
+
+static void
+do_prefs (saver_info *si)
+{
+ saver_preferences *p = &si->prefs;
+ fork_and_exec (si, p->prefs_command, "preferences");
+}
+
+static void
+do_help (saver_info *si)
+{
+ saver_preferences *p = &si->prefs;
+ char *help_command;
+
+ if (!p->help_url || !*p->help_url)
+ {
+ fprintf (stderr, "%s: no Help URL has been specified.\n", blurb());
+ return;
+ }
+
+ help_command = (char *) malloc (strlen (p->load_url_command) +
+ (strlen (p->help_url) * 2) + 10);
+ sprintf (help_command, p->load_url_command, p->help_url, p->help_url);
+ fork_and_exec (si, help_command, "URL-loading");
+ free (help_command);
+}