+ passwd_dialog_data *pw = si->pw_data;
+ XGCValues gcv;
+ GC gc1, gc2;
+ int spacing, height;
+ int x1, x2, x3, y1, y2;
+ int sw;
+ int tb_height;
+
+ /* Force redraw */
+ pw->passwd_changed_p = True;
+ pw->button_state_changed_p = True;
+
+ /* This height is the height of all the elements, not to be confused with
+ * the overall window height which is pw->height. It is used to compute
+ * the amount of spacing (padding) between elements. */
+ height = (pw->heading_font->ascent + pw->heading_font->descent +
+ pw->info_label->overall_height +
+ MAX (((pw->label_font->ascent + pw->label_font->descent) +
+ (pw->prompt_label ? pw->prompt_label->overall_height : 0)),
+ ((pw->passwd_font->ascent + pw->passwd_font->descent) +
+ (pw->shadow_width * 2)) * (pw->prompt_label ? 2 : 1)) +
+ pw->date_font->ascent + pw->date_font->descent);
+
+ if ((strlen(pw->uname_label)) && pw->show_uname_p)
+ height += (pw->uname_font->ascent + pw->uname_font->descent);
+
+ height += ((pw->button_font->ascent + pw->button_font->descent) * 2 +
+ 2 * pw->shadow_width);
+
+ spacing = ((pw->height - 2 * pw->shadow_width
+ - pw->internal_border - height)
+ / 10);
+
+ if (spacing < 0) spacing = 0;
+
+ gcv.foreground = pw->foreground;
+ gc1 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground, &gcv);
+ gc2 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground, &gcv);
+ x1 = pw->logo_width + pw->thermo_width + (pw->shadow_width * 3);
+ x3 = pw->width - (pw->shadow_width * 2);
+ y1 = (pw->shadow_width * 2) + spacing + spacing;
+
+ /* top heading
+ */
+ XSetFont (si->dpy, gc1, pw->heading_font->fid);
+ sw = string_width (pw->heading_font, pw->heading_label);
+ x2 = (x1 + ((x3 - x1 - sw) / 2));
+ y1 += spacing + pw->heading_font->ascent + pw->heading_font->descent;
+ XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1,
+ pw->heading_label, strlen(pw->heading_label));
+
+ /* uname below top heading
+ */
+ if ((strlen(pw->uname_label)) && pw->show_uname_p)
+ {
+ XSetFont (si->dpy, gc1, pw->uname_font->fid);
+ y1 += spacing + pw->uname_font->ascent + pw->uname_font->descent;
+ sw = string_width (pw->uname_font, pw->uname_label);
+ x2 = (x1 + ((x3 - x1 - sw) / 2));
+ XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1,
+ pw->uname_label, strlen(pw->uname_label));
+ }
+
+ /* the info_label (below uname)
+ */
+ x2 = (x1 + ((x3 - x1 - pw->info_label->overall_width) / 2));
+ y1 += spacing + pw->info_label->font_height / 2;
+ mlstring_draw(si->dpy, si->passwd_dialog, gc1, pw->info_label,
+ x2, y1);
+ y1 += pw->info_label->overall_height;
+
+
+ tb_height = (pw->passwd_font->ascent + pw->passwd_font->descent +
+ (pw->shadow_width * 4));
+
+ /* the "User:" prompt
+ */
+ y2 = y1;
+ XSetForeground (si->dpy, gc1, pw->foreground);
+ XSetFont (si->dpy, gc1, pw->label_font->fid);
+ y1 += (spacing + tb_height + pw->shadow_width);
+ x2 = (x1 + pw->internal_border +
+ MAX(string_width (pw->label_font, pw->user_label),
+ pw->prompt_label ? pw->prompt_label->overall_width : 0));
+ XDrawString (si->dpy, si->passwd_dialog, gc1,
+ x2 - string_width (pw->label_font, pw->user_label),
+ y1 - pw->passwd_font->descent,
+ pw->user_label, strlen(pw->user_label));
+
+ /* the prompt_label prompt
+ */
+ if (pw->prompt_label)
+ {
+ y1 += tb_height - pw->label_font->ascent + pw->shadow_width;
+ mlstring_draw(si->dpy, si->passwd_dialog, gc1, pw->prompt_label,
+ x2 - pw->prompt_label->overall_width, y1);
+ }
+
+ /* the "user name" text field
+ */
+ y1 = y2;
+ XSetForeground (si->dpy, gc1, pw->passwd_foreground);
+ XSetForeground (si->dpy, gc2, pw->passwd_background);
+ XSetFont (si->dpy, gc1, pw->passwd_font->fid);
+ y1 += (spacing + tb_height);
+ x2 += (pw->shadow_width * 4);
+
+ pw->passwd_field_width = x3 - x2 - pw->internal_border;
+ pw->passwd_field_height = (pw->passwd_font->ascent +
+ pw->passwd_font->descent +
+ pw->shadow_width);
+
+ XFillRectangle (si->dpy, si->passwd_dialog, gc2,
+ x2 - pw->shadow_width,
+ y1 - (pw->passwd_font->ascent + pw->passwd_font->descent),
+ pw->passwd_field_width, pw->passwd_field_height);
+ XDrawString (si->dpy, si->passwd_dialog, gc1,
+ x2,
+ y1 - pw->passwd_font->descent,
+ si->user, strlen(si->user));
+
+ /* the password/prompt text field
+ */
+ if (pw->prompt_label)
+ {
+ y1 += (spacing + pw->prompt_label->overall_height + pw->shadow_width*2);
+
+ pw->passwd_field_x = x2 - pw->shadow_width;
+ pw->passwd_field_y = y1 - (pw->passwd_font->ascent +
+ pw->passwd_font->descent);
+ }
+
+ /* The shadow around the text fields
+ */
+ y1 = y2;
+ y1 += (spacing + (pw->shadow_width * 3));
+ x1 = x2 - (pw->shadow_width * 2);
+ x2 = pw->passwd_field_width + (pw->shadow_width * 2);
+ y2 = pw->passwd_field_height + (pw->shadow_width * 2);
+
+ draw_shaded_rectangle (si->dpy, si->passwd_dialog,
+ x1, y1, x2, y2,
+ pw->shadow_width,
+ pw->shadow_bottom, pw->shadow_top);
+
+ if (pw->prompt_label)
+ {
+ y1 += (spacing + pw->prompt_label->overall_height + pw->shadow_width*2);
+ draw_shaded_rectangle (si->dpy, si->passwd_dialog,
+ x1, y1, x2, y2,
+ pw->shadow_width,
+ pw->shadow_bottom, pw->shadow_top);
+ }
+
+
+ /* The date, below the text fields
+ */
+ {
+ char buf[100];
+ time_t now = time ((time_t *) 0);
+ struct tm *tm = localtime (&now);
+ memset (buf, 0, sizeof(buf));
+ strftime (buf, sizeof(buf)-1, pw->date_label, tm);
+
+ XSetFont (si->dpy, gc1, pw->date_font->fid);
+ y1 += pw->shadow_width;
+ y1 += (spacing + tb_height);
+ y1 += spacing/2;
+ sw = string_width (pw->date_font, buf);
+ x2 = x1 + x2 - sw;
+ XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1, buf, strlen(buf));
+ }
+
+ /* Set up the GCs for the "New Login" and "Unlock" buttons.
+ */
+ XSetForeground(si->dpy, gc1, pw->button_foreground);
+ XSetForeground(si->dpy, gc2, pw->button_background);
+ XSetFont(si->dpy, gc1, pw->button_font->fid);
+
+ /* The "Unlock" button */
+ x2 = pw->width - pw->internal_border - (pw->shadow_width * 2);
+
+ /* right aligned button */
+ x1 = x2 - pw->unlock_button_width;
+
+ /* Add half the difference between y1 and the internal edge.
+ * It actually looks better if the internal border is ignored. */
+ y1 += ((pw->height - MAX (pw->unlock_button_height, pw->login_button_height)
+ - spacing - y1)
+ / 2);
+
+ pw->unlock_button_x = x1;
+ pw->unlock_button_y = y1;
+
+ /* The "New Login" button
+ */
+ if (pw->login_button_p)
+ {
+ /* Using the same GC as for the Unlock button */
+
+ sw = string_width (pw->button_font, pw->login_label);
+
+ /* left aligned button */
+ x1 = (pw->logo_width + pw->thermo_width + (pw->shadow_width * 3) +
+ pw->internal_border);
+
+ pw->login_button_x = x1;
+ pw->login_button_y = y1;
+ }
+
+ /* The logo
+ */
+ x1 = pw->shadow_width * 6;
+ y1 = pw->shadow_width * 6;
+ x2 = pw->logo_width - (pw->shadow_width * 12);
+ y2 = pw->logo_height - (pw->shadow_width * 12);
+
+ if (pw->logo_pixmap)
+ {
+ Window root;
+ int x, y;
+ unsigned int w, h, bw, d;
+ XGetGeometry (si->dpy, pw->logo_pixmap, &root, &x, &y, &w, &h, &bw, &d);
+ XSetForeground (si->dpy, gc1, pw->foreground);
+ XSetBackground (si->dpy, gc1, pw->background);
+ XSetClipMask (si->dpy, gc1, pw->logo_clipmask);
+ XSetClipOrigin (si->dpy, gc1,
+ x1 + ((x2 - (int)w) / 2),
+ y1 + ((y2 - (int)h) / 2));
+ if (d == 1)
+ XCopyPlane (si->dpy, pw->logo_pixmap, si->passwd_dialog, gc1,
+ 0, 0, w, h,
+ x1 + ((x2 - (int)w) / 2),
+ y1 + ((y2 - (int)h) / 2),
+ 1);
+ else
+ XCopyArea (si->dpy, pw->logo_pixmap, si->passwd_dialog, gc1,
+ 0, 0, w, h,
+ x1 + ((x2 - (int)w) / 2),
+ y1 + ((y2 - (int)h) / 2));
+ }
+
+ /* The thermometer
+ */
+ XSetForeground (si->dpy, gc1, pw->thermo_foreground);
+ XSetForeground (si->dpy, gc2, pw->thermo_background);
+
+ pw->thermo_field_x = pw->logo_width + pw->shadow_width;
+ pw->thermo_field_y = pw->shadow_width * 5;
+ pw->thermo_field_height = pw->height - (pw->shadow_width * 10);
+
+#if 0
+ /* Solid border inside the logo box. */
+ XSetForeground (si->dpy, gc1, pw->foreground);
+ XDrawRectangle (si->dpy, si->passwd_dialog, gc1, x1, y1, x2-1, y2-1);
+#endif
+
+ /* The shadow around the logo
+ */
+ draw_shaded_rectangle (si->dpy, si->passwd_dialog,
+ pw->shadow_width * 4,
+ pw->shadow_width * 4,
+ pw->logo_width - (pw->shadow_width * 8),
+ pw->logo_height - (pw->shadow_width * 8),
+ pw->shadow_width,
+ pw->shadow_bottom, pw->shadow_top);
+
+ /* The shadow around the thermometer
+ */
+ draw_shaded_rectangle (si->dpy, si->passwd_dialog,
+ pw->logo_width,
+ pw->shadow_width * 4,
+ pw->thermo_width + (pw->shadow_width * 2),
+ pw->height - (pw->shadow_width * 8),
+ pw->shadow_width,
+ pw->shadow_bottom, pw->shadow_top);
+
+#if 1
+ /* Solid border inside the thermometer. */
+ XSetForeground (si->dpy, gc1, pw->foreground);
+ XDrawRectangle (si->dpy, si->passwd_dialog, gc1,
+ pw->thermo_field_x, pw->thermo_field_y,
+ pw->thermo_width - 1, pw->thermo_field_height - 1);
+#endif
+
+ /* The shadow around the whole window
+ */
+ draw_shaded_rectangle (si->dpy, si->passwd_dialog,
+ 0, 0, pw->width, pw->height, pw->shadow_width,
+ pw->shadow_top, pw->shadow_bottom);
+
+ XFreeGC (si->dpy, gc1);
+ XFreeGC (si->dpy, gc2);
+
+ update_passwd_window (si, pw->passwd_string, pw->ratio);