-/* 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;
Pixel background;
Pixel button_foreground;
Pixel button_background;
- Pixel logo_foreground;
- Pixel logo_background;
Pixel shadow_top;
Pixel shadow_bottom;
Dimension prefs_button_x, prefs_button_y;
Dimension help_button_x, help_button_y;
+ Pixmap logo_pixmap;
+ int logo_npixels;
+ unsigned long *logo_pixels;
+
int pressed;
};
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));
sp->button_background = get_pixel_resource ("splash.Button.background",
"Dialog.Button.Background",
si->dpy, cmap);
- sp->logo_foreground = get_pixel_resource ("splash.logo.foreground",
- "Dialog.Logo.Foreground",
- si->dpy, cmap);
- sp->logo_background = get_pixel_resource ("splash.logo.background",
- "Dialog.Logo.Background",
- si->dpy, cmap);
sp->shadow_top = get_pixel_resource ("splash.topShadowColor",
"Dialog.Foreground",
si->dpy, cmap);
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");
attrmask, &attrs);
XSetWindowBackground (si->dpy, si->splash_dialog, sp->background);
+ sp->logo_pixmap = xscreensaver_logo (si->dpy, si->splash_dialog, cmap,
+ sp->background,
+ &sp->logo_pixels, &sp->logo_npixels,
+ 0, True);
+
XMapRaised (si->dpy, si->splash_dialog);
XSync (si->dpy, False);
XSync (si->dpy, False);
}
+
static void
draw_splash_window (saver_info *si)
{
sp->help_button_y = y1;
- /* the logo
+ /* The logo
*/
- XSetForeground (si->dpy, gc1, sp->logo_foreground);
- XSetForeground (si->dpy, gc2, sp->logo_background);
-
x1 = sp->shadow_width * 3;
y1 = sp->shadow_width * 3;
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));
+ if (sp->logo_pixmap)
+ {
+ Window root;
+ int x, y;
+ unsigned int w, h, bw, d;
+ XGetGeometry (si->dpy, sp->logo_pixmap, &root, &x, &y, &w, &h, &bw, &d);
+ XSetForeground (si->dpy, gc1, sp->foreground);
+ XSetBackground (si->dpy, gc1, sp->background);
+ if (d == 1)
+ XCopyPlane (si->dpy, sp->logo_pixmap, si->splash_dialog, gc1,
+ 0, 0, w, h,
+ x1 + ((x2 - (int)w) / 2),
+ y1 + ((y2 - (int)h) / 2),
+ 1);
+ else
+ XCopyArea (si->dpy, sp->logo_pixmap, si->splash_dialog, gc1,
+ 0, 0, w, h,
+ x1 + ((x2 - (int)w) / 2),
+ y1 + ((y2 - (int)h) / 2));
+ }
+ /* Solid border inside the logo box. */
+ XSetForeground (si->dpy, gc1, sp->foreground);
+ XDrawRectangle (si->dpy, si->splash_dialog, gc1, x1, y1, x2-1, y2-1);
/* The shadow around the logo
*/
XFreeColors (si->dpy, cmap, &sp->button_foreground, 1, 0L);
if (sp->button_background != black && sp->button_background != white)
XFreeColors (si->dpy, cmap, &sp->button_background, 1, 0L);
- if (sp->logo_foreground != black && sp->logo_foreground != white)
- XFreeColors (si->dpy, cmap, &sp->logo_foreground, 1, 0L);
- if (sp->logo_background != black && sp->logo_background != white)
- XFreeColors (si->dpy, cmap, &sp->logo_background, 1, 0L);
if (sp->shadow_top != black && sp->shadow_top != white)
XFreeColors (si->dpy, cmap, &sp->shadow_top, 1, 0L);
if (sp->shadow_bottom != black && sp->shadow_bottom != white)
XFreeColors (si->dpy, cmap, &sp->shadow_bottom, 1, 0L);
+ if (sp->logo_pixmap)
+ XFreePixmap (si->dpy, sp->logo_pixmap);
+ if (sp->logo_npixels && sp->logo_pixels)
+ XFreeColors (si->dpy, cmap, sp->logo_pixels, sp->logo_npixels, 0L);
+ if (sp->logo_pixels)
+ free (sp->logo_pixels);
+
memset (sp, 0, sizeof(*sp));
free (sp);
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);
+}