-/* xscreensaver, Copyright (c) 1991-1998 Jamie Zawinski <jwz@netscape.com>
+/* xscreensaver, Copyright (c) 1991-2002 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 unsplash_timer (XtPointer closure, XtIntervalId *id);
static void do_demo (saver_info *si);
+#ifdef PREFS_BUTTON
static void do_prefs (saver_info *si);
+#endif /* PREFS_BUTTON */
static void do_help (saver_info *si);
struct splash_dialog_data {
+
+ saver_screen_info *prompt_screen;
XtIntervalId timer;
Dimension width;
char *body_label;
char *body2_label;
char *demo_label;
+#ifdef PREFS_BUTTON
char *prefs_label;
+#endif /* PREFS_BUTTON */
char *help_label;
XFontStruct *heading_font;
Pixel background;
Pixel button_foreground;
Pixel button_background;
- Pixel logo_foreground;
- Pixel logo_background;
Pixel shadow_top;
Pixel shadow_bottom;
Dimension button_width, button_height;
Dimension demo_button_x, demo_button_y;
+#ifdef PREFS_BUTTON
Dimension prefs_button_x, prefs_button_y;
+#endif /* PREFS_BUTTON */
Dimension help_button_x, help_button_y;
+ Pixmap logo_pixmap;
+ int logo_npixels;
+ unsigned long *logo_pixels;
+
int pressed;
};
XSetWindowAttributes attrs;
unsigned long attrmask = 0;
splash_dialog_data *sp;
- Screen *screen = si->default_screen->screen;
- Colormap cmap = DefaultColormapOfScreen (screen);
+ saver_screen_info *ssi;
+ Colormap cmap;
char *f;
if (si->sp_data)
return;
- if (si->prefs.splash_duration <= 0)
+ if (!si->prefs.splash_p ||
+ si->prefs.splash_duration <= 0)
return;
+ ssi = &si->screens[mouse_screen (si)];
+ cmap = DefaultColormapOfScreen (ssi->screen);
+
sp = (splash_dialog_data *) calloc (1, sizeof(*sp));
+ sp->prompt_screen = ssi;
sp->heading_label = get_string_resource ("splash.heading.label",
"Dialog.Label.Label");
"Dialog.Label.Label");
sp->demo_label = get_string_resource ("splash.demo.label",
"Dialog.Button.Label");
+#ifdef PREFS_BUTTON
sp->prefs_label = get_string_resource ("splash.prefs.label",
"Dialog.Button.Label");
+#endif /* PREFS_BUTTON */
sp->help_label = get_string_resource ("splash.help.label",
"Dialog.Button.Label");
if (!sp->body2_label)
sp->body2_label = strdup("ERROR: REESOURCES NOT INSTALLED CORRECTLY");
if (!sp->demo_label) sp->demo_label = strdup("ERROR");
+#ifdef PREFS_BUTTON
if (!sp->prefs_label) sp->prefs_label = strdup("ERROR");
+#endif /* PREFS_BUTTON */
if (!sp->help_label) sp->help_label = strdup("ERROR");
/* Put the version number in the label. */
if (sp->foreground == sp->background)
{
/* Make sure the error messages show up. */
- sp->foreground = BlackPixelOfScreen (screen);
- sp->background = WhitePixelOfScreen (screen);
+ sp->foreground = BlackPixelOfScreen (ssi->screen);
+ sp->background = WhitePixelOfScreen (ssi->screen);
}
sp->button_foreground = get_pixel_resource ("splash.Button.foreground",
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);
w2 = overall.width;
h2 = ascent + descent;
+#ifdef PREFS_BUTTON
/* Measure the Prefs button. */
XTextExtents (sp->button_font,
sp->prefs_label, strlen(sp->prefs_label),
&direction, &ascent, &descent, &overall);
w3 = overall.width;
h3 = ascent + descent;
+#else /* !PREFS_BUTTON */
+ w3 = 0;
+ h3 = 0;
+#endif /* !PREFS_BUTTON */
/* Measure the Help button. */
XTextExtents (sp->button_font,
w2 = MAX(w2, w3); w2 = MAX(w2, w4);
h2 = MAX(h2, h3); h2 = MAX(h2, h4);
+ /* Add some horizontal padding inside the buttons. */
+ w2 += ascent;
+
w2 += ((ascent + descent) / 2) + (sp->shadow_width * 2);
h2 += ((ascent + descent) / 2) + (sp->shadow_width * 2);
sp->button_width = w2;
sp->button_height = h2;
+#ifdef PREFS_BUTTON
w2 *= 3;
+#else /* !PREFS_BUTTON */
+ w2 *= 2;
+#endif /* !PREFS_BUTTON */
w2 += ((ascent + descent) * 2); /* for space between buttons */
{
int sx, sy, w, h;
- get_screen_viewport (si->default_screen, &sx, &sy, &w, &h, False);
+ int mouse_x = 0, mouse_y = 0;
+
+ {
+ Window pointer_root, pointer_child;
+ int root_x, root_y, win_x, win_y;
+ unsigned int mask;
+ if (XQueryPointer (si->dpy,
+ RootWindowOfScreen (ssi->screen),
+ &pointer_root, &pointer_child,
+ &root_x, &root_y, &win_x, &win_y, &mask))
+ {
+ mouse_x = root_x;
+ mouse_y = root_y;
+ }
+ }
+
+ get_screen_viewport (ssi, &sx, &sy, &w, &h, mouse_x, mouse_y, False);
if (si->prefs.debug_p) w /= 2;
x = sx + (((w + sp->width) / 2) - sp->width);
y = sy + (((h + sp->height) / 2) - sp->height);
si->splash_dialog =
XCreateWindow (si->dpy,
- RootWindowOfScreen(screen),
+ RootWindowOfScreen(ssi->screen),
x, y, sp->width, sp->height, bw,
- DefaultDepthOfScreen (screen), InputOutput,
- DefaultVisualOfScreen(screen),
+ DefaultDepthOfScreen (ssi->screen), InputOutput,
+ DefaultVisualOfScreen(ssi->screen),
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)
{
int x1, x2, x3, y1, y2;
int sw;
+#ifdef PREFS_BUTTON
+ int nbuttons = 3;
+#else /* !PREFS_BUTTON */
+ int nbuttons = 2;
+#endif /* !PREFS_BUTTON */
+
height = (sp->heading_font->ascent + sp->heading_font->descent +
sp->body_font->ascent + sp->body_font->descent +
sp->body_font->ascent + sp->body_font->descent +
/ 2)
+ sp->button_font->ascent);
hspacing = ((sp->width - x1 - (sp->shadow_width * 2) -
- sp->internal_border - (sp->button_width * 3))
+ sp->internal_border - (sp->button_width * nbuttons))
/ 2);
x2 = x1 + ((sp->button_width - string_width(sp->button_font, sp->demo_label))
sp->demo_button_x = x1;
sp->demo_button_y = y1;
+#ifdef PREFS_BUTTON
x1 += hspacing + sp->button_width;
x2 = x1 + ((sp->button_width - string_width(sp->button_font,sp->prefs_label))
/ 2);
sp->prefs_label, strlen(sp->prefs_label));
sp->prefs_button_x = x1;
sp->prefs_button_y = y1;
+#endif /* PREFS_BUTTON */
+#ifdef PREFS_BUTTON
x1 += hspacing + sp->button_width;
+#else /* !PREFS_BUTTON */
+ x1 = (sp->width - sp->button_width -
+ sp->internal_border - (sp->shadow_width * 2));
+#endif /* !PREFS_BUTTON */
+
x2 = x1 + ((sp->button_width - string_width(sp->button_font,sp->help_label))
/ 2);
XFillRectangle (si->dpy, si->splash_dialog, gc2, x1, y1,
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);
+ x1 = sp->shadow_width * 6;
+ y1 = sp->shadow_width * 6;
+ x2 = sp->logo_width - (sp->shadow_width * 12);
+ y2 = sp->logo_height - (sp->shadow_width * 12);
- 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. */
+#if 0
+ XSetForeground (si->dpy, gc1, sp->foreground);
+ XDrawRectangle (si->dpy, si->splash_dialog, gc1, x1, y1, x2-1, y2-1);
+#endif
/* The shadow around the logo
*/
draw_shaded_rectangle (si->dpy, si->splash_dialog,
- sp->shadow_width * 2,
- sp->shadow_width * 2,
- sp->logo_width - (sp->shadow_width * 4),
- sp->logo_height - (sp->shadow_width * 4),
+ sp->shadow_width * 4,
+ sp->shadow_width * 4,
+ sp->logo_width - (sp->shadow_width * 8),
+ sp->logo_height - (sp->shadow_width * 8),
sp->shadow_width,
sp->shadow_bottom, sp->shadow_top);
sp->button_width, sp->button_height, sp->shadow_width,
(pressed == 1 ? sp->shadow_bottom : sp->shadow_top),
(pressed == 1 ? sp->shadow_top : sp->shadow_bottom));
+#ifdef PREFS_BUTTON
draw_shaded_rectangle (si->dpy, si->splash_dialog,
sp->prefs_button_x, sp->prefs_button_y,
sp->button_width, sp->button_height, sp->shadow_width,
(pressed == 2 ? sp->shadow_bottom : sp->shadow_top),
(pressed == 2 ? sp->shadow_top : sp->shadow_bottom));
+#endif /* PREFS_BUTTON */
draw_shaded_rectangle (si->dpy, si->splash_dialog,
sp->help_button_x, sp->help_button_y,
sp->button_width, sp->button_height, sp->shadow_width,
destroy_splash_window (saver_info *si)
{
splash_dialog_data *sp = si->sp_data;
- Screen *screen = si->default_screen->screen;
- Colormap cmap = DefaultColormapOfScreen (screen);
- Pixel black = BlackPixelOfScreen (screen);
- Pixel white = WhitePixelOfScreen (screen);
+ saver_screen_info *ssi = sp->prompt_screen;
+ Colormap cmap = DefaultColormapOfScreen (ssi->screen);
+ Pixel black = BlackPixelOfScreen (ssi->screen);
+ Pixel white = WhitePixelOfScreen (ssi->screen);
if (sp->timer)
XtRemoveTimeOut (sp->timer);
if (sp->heading_label) free (sp->heading_label);
if (sp->body_label) free (sp->body_label);
+ if (sp->body2_label) free (sp->body2_label);
if (sp->demo_label) free (sp->demo_label);
+#ifdef PREFS_BUTTON
if (sp->prefs_label) free (sp->prefs_label);
+#endif /* PREFS_BUTTON */
if (sp->help_label) free (sp->help_label);
if (sp->heading_font) XFreeFont (si->dpy, sp->heading_font);
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_pixels)
+ {
+ if (sp->logo_npixels)
+ XFreeColors (si->dpy, cmap, sp->logo_pixels, sp->logo_npixels, 0L);
+ free (sp->logo_pixels);
+ sp->logo_pixels = 0;
+ sp->logo_npixels = 0;
+ }
+
memset (sp, 0, sizeof(*sp));
free (sp);
-
si->sp_data = 0;
}
event->xbutton.y < sp->demo_button_y + sp->button_height)
which = 1;
+#ifdef PREFS_BUTTON
else if (event->xbutton.x >= sp->prefs_button_x &&
event->xbutton.x < sp->prefs_button_x + sp->button_width &&
event->xbutton.y >= sp->prefs_button_y &&
event->xbutton.y < sp->prefs_button_y + sp->button_height)
which = 2;
+#endif /* PREFS_BUTTON */
else if (event->xbutton.x >= sp->help_button_x &&
event->xbutton.x < sp->help_button_x + sp->button_width &&
switch (which)
{
case 1: do_demo (si); break;
+#ifdef PREFS_BUTTON
case 2: do_prefs (si); break;
+#endif /* PREFS_BUTTON */
case 3: do_help (si); break;
default: abort();
}
}
+ else if (which == 0 && sp->pressed == 0)
+ {
+ /* click and release on the window but not in a button:
+ treat that as "dismiss the splash dialog." */
+ destroy_splash_window (si);
+ }
sp->pressed = 0;
update_splash_window (si);
}
fork_and_exec (si, p->demo_command, "demo-mode");
}
+#ifdef PREFS_BUTTON
static void
do_prefs (saver_info *si)
{
saver_preferences *p = &si->prefs;
fork_and_exec (si, p->prefs_command, "preferences");
}
+#endif /* PREFS_BUTTON */
static void
do_help (saver_info *si)