+ if (!ssi || !ssi->screen)
+ return; /* WTF? Trying to splash while no screens connected? */
+
+ cmap = DefaultColormapOfScreen (ssi->screen);
+
+ sp = (splash_dialog_data *) calloc (1, sizeof(*sp));
+ sp->prompt_screen = ssi;
+
+ sp->heading_label = get_string_resource (si->dpy,
+ "splash.heading.label",
+ "Dialog.Label.Label");
+ sp->body_label = get_string_resource (si->dpy,
+ "splash.body.label",
+ "Dialog.Label.Label");
+ sp->body2_label = get_string_resource (si->dpy,
+ "splash.body2.label",
+ "Dialog.Label.Label");
+ sp->demo_label = get_string_resource (si->dpy,
+ "splash.demo.label",
+ "Dialog.Button.Label");
+#ifdef PREFS_BUTTON
+ sp->prefs_label = get_string_resource (si->dpy,
+ "splash.prefs.label",
+ "Dialog.Button.Label");
+#endif /* PREFS_BUTTON */
+ sp->help_label = get_string_resource (si->dpy,
+ "splash.help.label",
+ "Dialog.Button.Label");
+
+
+
+ if (whine)
+ {
+ sp->body3_label = strdup("WARNING: This version is very old!");
+ sp->body4_label = strdup("Please upgrade!");
+ }
+
+ if (!sp->heading_label)
+ sp->heading_label = strdup("ERROR: REESOURCES NOT INSTALLED CORRECTLY");
+ if (!sp->body_label)
+ sp->body_label = strdup("ERROR: REESOURCES NOT INSTALLED CORRECTLY");
+ 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. */
+ {
+ char *s = (char *) malloc (strlen(sp->heading_label) + 20);
+ sprintf(s, sp->heading_label, si->version);
+ free (sp->heading_label);
+ sp->heading_label = s;
+ }
+
+ f = get_string_resource (si->dpy, "splash.headingFont", "Dialog.Font");
+ sp->heading_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
+ if (!sp->heading_font) sp->heading_font = XLoadQueryFont (si->dpy, "fixed");
+ if (f) free (f);
+
+ f = get_string_resource(si->dpy, "splash.bodyFont", "Dialog.Font");
+ sp->body_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
+ if (!sp->body_font) sp->body_font = XLoadQueryFont (si->dpy, "fixed");
+ if (f) free (f);
+
+ f = get_string_resource(si->dpy, "splash.buttonFont", "Dialog.Font");
+ sp->button_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
+ if (!sp->button_font) sp->button_font = XLoadQueryFont (si->dpy, "fixed");
+ if (f) free (f);
+
+ sp->foreground = get_pixel_resource (si->dpy, cmap,
+ "splash.foreground",
+ "Dialog.Foreground");
+ sp->background = get_pixel_resource (si->dpy, cmap,
+ "splash.background",
+ "Dialog.Background");
+ sp->border = get_pixel_resource (si->dpy, cmap,
+ "splash.borderColor",
+ "Dialog.borderColor");
+
+ if (sp->foreground == sp->background)
+ {
+ /* Make sure the error messages show up. */
+ sp->foreground = BlackPixelOfScreen (ssi->screen);
+ sp->background = WhitePixelOfScreen (ssi->screen);
+ }
+
+ sp->button_foreground = get_pixel_resource (si->dpy, cmap,
+ "splash.Button.foreground",
+ "Dialog.Button.Foreground");
+ sp->button_background = get_pixel_resource (si->dpy, cmap,
+ "splash.Button.background",
+ "Dialog.Button.Background");
+ sp->shadow_top = get_pixel_resource (si->dpy, cmap,
+ "splash.topShadowColor",
+ "Dialog.Foreground");
+ sp->shadow_bottom = get_pixel_resource (si->dpy, cmap,
+ "splash.bottomShadowColor",
+ "Dialog.Background");
+
+ sp->logo_width = get_integer_resource (si->dpy,
+ "splash.logo.width",
+ "Dialog.Logo.Width");
+ sp->logo_height = get_integer_resource (si->dpy,
+ "splash.logo.height",
+ "Dialog.Logo.Height");
+ sp->internal_border = get_integer_resource (si->dpy,
+ "splash.internalBorderWidth",
+ "Dialog.InternalBorderWidth");
+ sp->shadow_width = get_integer_resource (si->dpy,
+ "splash.shadowThickness",
+ "Dialog.ShadowThickness");
+
+ if (sp->logo_width == 0) sp->logo_width = 150;
+ if (sp->logo_height == 0) sp->logo_height = 150;
+ if (sp->internal_border == 0) sp->internal_border = 15;
+ if (sp->shadow_width == 0) sp->shadow_width = 4;
+
+ {
+ int direction, ascent, descent;
+ XCharStruct overall;
+
+ sp->width = 0;
+ sp->height = 0;
+
+ /* Measure the heading_label. */
+ XTextExtents (sp->heading_font,
+ sp->heading_label, strlen(sp->heading_label),
+ &direction, &ascent, &descent, &overall);
+ if (overall.width > sp->width) sp->width = overall.width;
+ sp->height += ascent + descent;
+
+ /* Measure the body_label. */
+ XTextExtents (sp->body_font,
+ sp->body_label, strlen(sp->body_label),
+ &direction, &ascent, &descent, &overall);
+ if (overall.width > sp->width) sp->width = overall.width;
+ sp->height += ascent + descent;
+
+ /* Measure the body2_label. */
+ XTextExtents (sp->body_font,
+ sp->body2_label, strlen(sp->body2_label),
+ &direction, &ascent, &descent, &overall);
+ if (overall.width > sp->width) sp->width = overall.width;
+ sp->height += ascent + descent;
+
+ /* Measure the optional body3_label. */
+ if (sp->body3_label)
+ {
+ XTextExtents (sp->heading_font,
+ sp->body3_label, strlen(sp->body3_label),
+ &direction, &ascent, &descent, &overall);
+ if (overall.width > sp->width) sp->width = overall.width;
+ XTextExtents (sp->heading_font,
+ sp->body4_label, strlen(sp->body4_label),
+ &direction, &ascent, &descent, &overall);
+ if (overall.width > sp->width) sp->width = overall.width;
+ sp->height += (ascent + descent) * 5;
+ }
+
+ {
+ Dimension w2 = 0, w3 = 0, w4 = 0;
+ Dimension h2 = 0, h3 = 0, h4 = 0;
+
+ /* Measure the Demo button. */
+ XTextExtents (sp->button_font,
+ sp->demo_label, strlen(sp->demo_label),
+ &direction, &ascent, &descent, &overall);
+ 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,
+ sp->help_label, strlen(sp->help_label),
+ &direction, &ascent, &descent, &overall);
+ w4 = overall.width;
+ h4 = ascent + descent;
+
+ 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 */
+
+ if (w2 > sp->width) sp->width = w2;
+ sp->height += h2;
+ }
+
+ sp->width += (sp->internal_border * 2);
+ sp->height += (sp->internal_border * 3);
+
+ if (sp->logo_height > sp->height)
+ sp->height = sp->logo_height;
+ else if (sp->height > sp->logo_height)
+ sp->logo_height = sp->height;
+
+ sp->logo_width = sp->logo_height;
+
+ sp->width += sp->logo_width;
+ }
+
+ attrmask |= CWOverrideRedirect; attrs.override_redirect = True;
+ attrmask |= CWEventMask;
+ attrs.event_mask = (ExposureMask | ButtonPressMask | ButtonReleaseMask);
+
+ {
+ int sx = 0, sy = 0, w, h;
+ 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;
+ }
+ }
+
+ x = ssi->x;
+ y = ssi->y;
+ w = ssi->width;
+ h = ssi->height;
+ if (si->prefs.debug_p) w /= 2;
+ 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 (si->dpy,
+ "splash.borderWidth",
+ "Dialog.BorderWidth");
+
+ si->splash_dialog =
+ XCreateWindow (si->dpy,
+ RootWindowOfScreen(ssi->screen),
+ x, y, sp->width, sp->height, bw,
+ DefaultDepthOfScreen (ssi->screen), InputOutput,
+ DefaultVisualOfScreen(ssi->screen),
+ attrmask, &attrs);
+ XSetWindowBackground (si->dpy, si->splash_dialog, sp->background);
+ XSetWindowBorder (si->dpy, si->splash_dialog, sp->border);
+
+
+ sp->logo_pixmap = xscreensaver_logo (ssi->screen,
+ /* same visual as si->splash_dialog */
+ DefaultVisualOfScreen (ssi->screen),
+ si->splash_dialog, cmap,
+ sp->background,
+ &sp->logo_pixels, &sp->logo_npixels,
+ &sp->logo_clipmask, True);
+
+ XMapRaised (si->dpy, si->splash_dialog);
+ XSync (si->dpy, False);
+
+ si->sp_data = sp;
+
+ sp->timer = XtAppAddTimeOut (si->app, si->prefs.splash_duration,
+ unsplash_timer, (XtPointer) si);
+
+ draw_splash_window (si);
+ XSync (si->dpy, False);