1 /* lock.c --- handling the password dialog for locking-mode.
2 * xscreensaver, Copyright (c) 1993-1998 Jamie Zawinski <jwz@jwz.org>
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation. No representations are made about the suitability of this
9 * software for any purpose. It is provided "as is" without express or
13 /* Athena locking code contributed by Jon A. Christopher <jac8782@tamu.edu> */
14 /* Copyright 1997, with the same permissions as above. */
20 #ifndef NO_LOCKING /* whole file */
22 #include <X11/Intrinsic.h>
23 #include "xscreensaver.h"
24 #include "resources.h"
27 ERROR! You must not include vroot.h in this file.
34 extern char *getenv(const char *name);
35 extern int validate_user(char *name, char *password);
38 vms_passwd_valid_p(char *pw)
40 return (validate_user (getenv("USER"), typed_passwd) == 1);
42 # undef passwd_valid_p
43 # define passwd_valid_p vms_passwd_valid_p
49 #define MAX(a,b) ((a)>(b)?(a):(b))
51 enum passwd_state { pw_read, pw_ok, pw_fail, pw_cancel, pw_time };
53 struct passwd_dialog_data {
55 enum passwd_state state;
56 char typed_passwd [80];
71 XFontStruct *heading_font;
72 XFontStruct *body_font;
73 XFontStruct *label_font;
74 XFontStruct *passwd_font;
78 Pixel passwd_foreground;
79 Pixel passwd_background;
80 Pixel logo_foreground;
81 Pixel logo_background;
86 Dimension logo_height;
87 Dimension thermo_width;
88 Dimension internal_border;
89 Dimension shadow_width;
91 Dimension passwd_field_x, passwd_field_y;
92 Dimension passwd_field_width, passwd_field_height;
94 Dimension thermo_field_x, thermo_field_y;
95 Dimension thermo_field_height;
100 make_passwd_window (saver_info *si)
102 struct passwd *p = getpwuid (getuid ());
104 XSetWindowAttributes attrs;
105 unsigned long attrmask = 0;
106 Screen *screen = si->default_screen->screen;
107 passwd_dialog_data *pw = (passwd_dialog_data *) calloc (1, sizeof(*pw));
108 Colormap cmap = DefaultColormapOfScreen (screen);
113 pw->heading_label = get_string_resource ("passwd.heading.label",
114 "Dialog.Label.Label");
115 pw->body_label = get_string_resource ("passwd.body.label",
116 "Dialog.Label.Label");
117 pw->user_label = get_string_resource ("passwd.user.label",
118 "Dialog.Label.Label");
119 pw->passwd_label = get_string_resource ("passwd.passwd.label",
120 "Dialog.Label.Label");
122 if (!pw->heading_label)
123 pw->heading_label = strdup("ERROR: REESOURCES NOT INSTALLED CORRECTLY");
125 pw->body_label = strdup("ERROR: REESOURCES NOT INSTALLED CORRECTLY");
126 if (!pw->user_label) pw->user_label = strdup("ERROR");
127 if (!pw->passwd_label) pw->passwd_label = strdup("ERROR");
129 /* Put the version number in the label. */
131 char *s = (char *) malloc (strlen(pw->heading_label) + 20);
132 sprintf(s, pw->heading_label, si->version);
133 free (pw->heading_label);
134 pw->heading_label = s;
137 pw->user_string = (p->pw_name ? p->pw_name : "???");
138 pw->passwd_string = strdup("");
140 f = get_string_resource ("passwd.headingFont", "Dialog.Font");
141 pw->heading_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
142 if (!pw->heading_font) pw->heading_font = XLoadQueryFont (si->dpy, "fixed");
145 f = get_string_resource("passwd.bodyFont", "Dialog.Font");
146 pw->body_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
147 if (!pw->body_font) pw->body_font = XLoadQueryFont (si->dpy, "fixed");
150 f = get_string_resource("passwd.labelFont", "Dialog.Font");
151 pw->label_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
152 if (!pw->label_font) pw->label_font = XLoadQueryFont (si->dpy, "fixed");
155 f = get_string_resource("passwd.passwdFont", "Dialog.Font");
156 pw->passwd_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
157 if (!pw->passwd_font) pw->passwd_font = XLoadQueryFont (si->dpy, "fixed");
160 pw->foreground = get_pixel_resource ("passwd.foreground",
163 pw->background = get_pixel_resource ("passwd.background",
167 if (pw->foreground == pw->background)
169 /* Make sure the error messages show up. */
170 pw->foreground = BlackPixelOfScreen (screen);
171 pw->background = WhitePixelOfScreen (screen);
174 pw->passwd_foreground = get_pixel_resource ("passwd.text.foreground",
175 "Dialog.Text.Foreground",
177 pw->passwd_background = get_pixel_resource ("passwd.text.background",
178 "Dialog.Text.Background",
180 pw->logo_foreground = get_pixel_resource ("passwd.logo.foreground",
181 "Dialog.Logo.Foreground",
183 pw->logo_background = get_pixel_resource ("passwd.logo.background",
184 "Dialog.Logo.Background",
186 pw->shadow_top = get_pixel_resource ("passwd.topShadowColor",
189 pw->shadow_bottom = get_pixel_resource ("passwd.bottomShadowColor",
193 pw->logo_width = get_integer_resource ("passwd.logo.width",
194 "Dialog.Logo.Width");
195 pw->logo_height = get_integer_resource ("passwd.logo.height",
196 "Dialog.Logo.Height");
197 pw->thermo_width = get_integer_resource ("passwd.thermometer.width",
198 "Dialog.Thermometer.Width");
199 pw->internal_border = get_integer_resource ("passwd.internalBorderWidth",
200 "Dialog.InternalBorderWidth");
201 pw->shadow_width = get_integer_resource ("passwd.shadowThickness",
202 "Dialog.ShadowThickness");
204 if (pw->logo_width == 0) pw->logo_width = 150;
205 if (pw->logo_height == 0) pw->logo_height = 150;
206 if (pw->internal_border == 0) pw->internal_border = 15;
207 if (pw->shadow_width == 0) pw->shadow_width = 4;
208 if (pw->thermo_width == 0) pw->thermo_width = pw->shadow_width;
211 int direction, ascent, descent;
217 /* Measure the heading_label. */
218 XTextExtents (pw->heading_font,
219 pw->heading_label, strlen(pw->heading_label),
220 &direction, &ascent, &descent, &overall);
221 if (overall.width > pw->width) pw->width = overall.width;
222 pw->height += ascent + descent;
224 /* Measure the body_label. */
225 XTextExtents (pw->body_font,
226 pw->body_label, strlen(pw->body_label),
227 &direction, &ascent, &descent, &overall);
228 if (overall.width > pw->width) pw->width = overall.width;
229 pw->height += ascent + descent;
232 Dimension w2 = 0, w3 = 0;
233 Dimension h2 = 0, h3 = 0;
234 const char *passwd_string = "MMMMMMMMMMMM";
236 /* Measure the user_label. */
237 XTextExtents (pw->label_font,
238 pw->user_label, strlen(pw->user_label),
239 &direction, &ascent, &descent, &overall);
240 if (overall.width > w2) w2 = overall.width;
241 h2 += ascent + descent;
243 /* Measure the passwd_label. */
244 XTextExtents (pw->label_font,
245 pw->passwd_label, strlen(pw->passwd_label),
246 &direction, &ascent, &descent, &overall);
247 if (overall.width > w2) w2 = overall.width;
248 h2 += ascent + descent;
250 /* Measure the user_string. */
251 XTextExtents (pw->passwd_font,
252 pw->user_string, strlen(pw->user_string),
253 &direction, &ascent, &descent, &overall);
254 overall.width += (pw->shadow_width * 4);
255 ascent += (pw->shadow_width * 4);
256 if (overall.width > w3) w3 = overall.width;
257 h3 += ascent + descent;
259 /* Measure the (maximally-sized, dummy) passwd_string. */
260 XTextExtents (pw->passwd_font,
261 passwd_string, strlen(passwd_string),
262 &direction, &ascent, &descent, &overall);
263 overall.width += (pw->shadow_width * 4);
264 ascent += (pw->shadow_width * 4);
265 if (overall.width > w3) w3 = overall.width;
266 h3 += ascent + descent;
268 w2 = w2 + w3 + (pw->shadow_width * 2);
271 if (w2 > pw->width) pw->width = w2;
275 pw->width += (pw->internal_border * 2);
276 pw->height += (pw->internal_border * 4);
278 pw->width += pw->thermo_width + (pw->shadow_width * 3);
280 if (pw->logo_height > pw->height)
281 pw->height = pw->logo_height;
282 else if (pw->height > pw->logo_height)
283 pw->logo_height = pw->height;
285 pw->logo_width = pw->logo_height;
287 pw->width += pw->logo_width;
290 attrmask |= CWOverrideRedirect; attrs.override_redirect = True;
291 attrmask |= CWEventMask; attrs.event_mask = ExposureMask|KeyPressMask;
294 Dimension w = WidthOfScreen(screen);
295 Dimension h = HeightOfScreen(screen);
296 if (si->prefs.debug_p) w /= 2;
297 x = ((w + pw->width) / 2) - pw->width;
298 y = ((h + pw->height) / 2) - pw->height;
303 bw = get_integer_resource ("passwd.borderWidth", "Dialog.BorderWidth");
306 XCreateWindow (si->dpy,
307 RootWindowOfScreen(screen),
308 x, y, pw->width, pw->height, bw,
309 DefaultDepthOfScreen (screen), InputOutput,
310 DefaultVisualOfScreen(screen),
312 XSetWindowBackground (si->dpy, si->passwd_dialog, pw->background);
314 XMapRaised (si->dpy, si->passwd_dialog);
315 XSync (si->dpy, False);
319 draw_passwd_window (si);
320 XSync (si->dpy, False);
325 draw_passwd_window (saver_info *si)
327 passwd_dialog_data *pw = si->pw_data;
331 int x1, x2, x3, y1, y2;
335 height = (pw->heading_font->ascent + pw->heading_font->descent +
336 pw->body_font->ascent + pw->body_font->descent +
337 (2 * MAX ((pw->label_font->ascent + pw->label_font->descent),
338 (pw->passwd_font->ascent + pw->passwd_font->descent +
339 (pw->shadow_width * 4)))));
340 spacing = ((pw->height - (2 * pw->shadow_width) -
341 pw->internal_border - height)) / 8;
342 if (spacing < 0) spacing = 0;
344 gcv.foreground = pw->foreground;
345 gc1 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground, &gcv);
346 gc2 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground, &gcv);
347 x1 = pw->logo_width + pw->thermo_width + (pw->shadow_width * 3);
348 x3 = pw->width - (pw->shadow_width * 2);
349 y1 = (pw->shadow_width * 2) + spacing + spacing;
353 XSetFont (si->dpy, gc1, pw->heading_font->fid);
354 sw = string_width (pw->heading_font, pw->heading_label);
355 x2 = (x1 + ((x3 - x1 - sw) / 2));
356 y1 += spacing + pw->heading_font->ascent + pw->heading_font->descent;
357 XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1,
358 pw->heading_label, strlen(pw->heading_label));
360 /* text below top heading
362 XSetFont (si->dpy, gc1, pw->body_font->fid);
363 y1 += spacing + pw->body_font->ascent + pw->body_font->descent;
364 sw = string_width (pw->body_font, pw->body_label);
365 x2 = (x1 + ((x3 - x1 - sw) / 2));
366 XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1,
367 pw->body_label, strlen(pw->body_label));
370 tb_height = (pw->passwd_font->ascent + pw->passwd_font->descent +
371 (pw->shadow_width * 4));
373 /* the "User:" prompt
377 XSetForeground (si->dpy, gc1, pw->foreground);
378 XSetFont (si->dpy, gc1, pw->label_font->fid);
379 y1 += (spacing + tb_height);
380 x2 = (x1 + pw->internal_border +
381 MAX(string_width (pw->label_font, pw->user_label),
382 string_width (pw->label_font, pw->passwd_label)));
383 XDrawString (si->dpy, si->passwd_dialog, gc1,
384 x2 - string_width (pw->label_font, pw->user_label),
386 pw->user_label, strlen(pw->user_label));
388 /* the "Password:" prompt
390 y1 += (spacing + tb_height);
391 XDrawString (si->dpy, si->passwd_dialog, gc1,
392 x2 - string_width (pw->label_font, pw->passwd_label),
394 pw->passwd_label, strlen(pw->passwd_label));
397 XSetForeground (si->dpy, gc2, pw->passwd_background);
399 /* the "user name" text field
402 XSetForeground (si->dpy, gc1, pw->passwd_foreground);
403 XSetFont (si->dpy, gc1, pw->passwd_font->fid);
404 y1 += (spacing + tb_height);
405 x2 += (pw->shadow_width * 4);
407 pw->passwd_field_width = x3 - x2 - pw->internal_border;
408 pw->passwd_field_height = (pw->passwd_font->ascent +
409 pw->passwd_font->descent +
412 XFillRectangle (si->dpy, si->passwd_dialog, gc2,
413 x2 - pw->shadow_width,
414 y1 - (pw->passwd_font->ascent + pw->passwd_font->descent),
415 pw->passwd_field_width, pw->passwd_field_height);
416 XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1,
417 pw->user_string, strlen(pw->user_string));
419 /* the "password" text field
421 y1 += (spacing + tb_height);
423 pw->passwd_field_x = x2 - pw->shadow_width;
424 pw->passwd_field_y = y1 - (pw->passwd_font->ascent +
425 pw->passwd_font->descent);
427 /* The shadow around the text fields
430 y1 += (spacing + (pw->shadow_width * 3));
431 x1 = x2 - (pw->shadow_width * 2);
432 x2 = pw->passwd_field_width + (pw->shadow_width * 2);
433 y2 = pw->passwd_field_height + (pw->shadow_width * 2);
435 draw_shaded_rectangle (si->dpy, si->passwd_dialog,
438 pw->shadow_bottom, pw->shadow_top);
440 y1 += (spacing + pw->passwd_font->ascent + pw->passwd_font->descent +
441 (pw->shadow_width * 4));
442 draw_shaded_rectangle (si->dpy, si->passwd_dialog,
445 pw->shadow_bottom, pw->shadow_top);
449 XSetForeground (si->dpy, gc1, pw->logo_foreground);
450 XSetForeground (si->dpy, gc2, pw->logo_background);
452 x1 = pw->shadow_width * 3;
453 y1 = pw->shadow_width * 3;
454 x2 = pw->logo_width - (pw->shadow_width * 6);
455 y2 = pw->logo_height - (pw->shadow_width * 6);
457 XFillRectangle (si->dpy, si->passwd_dialog, gc2, x1, y1, x2, y2);
458 skull (si->dpy, si->passwd_dialog, gc1, gc2,
459 x1 + pw->shadow_width, y1 + pw->shadow_width,
460 x2 - (pw->shadow_width * 2), y2 - (pw->shadow_width * 2));
464 pw->thermo_field_x = pw->logo_width + pw->shadow_width;
465 pw->thermo_field_y = pw->shadow_width * 3;
466 pw->thermo_field_height = pw->height - (pw->shadow_width * 6);
468 /* Solid border inside the logo box. */
469 XSetForeground (si->dpy, gc1, pw->foreground);
470 XDrawRectangle (si->dpy, si->passwd_dialog, gc1, x1, y1, x2-1, y2-1);
472 /* The shadow around the logo
474 draw_shaded_rectangle (si->dpy, si->passwd_dialog,
475 pw->shadow_width * 2,
476 pw->shadow_width * 2,
477 pw->logo_width - (pw->shadow_width * 4),
478 pw->logo_height - (pw->shadow_width * 4),
480 pw->shadow_bottom, pw->shadow_top);
482 /* The shadow around the thermometer
484 draw_shaded_rectangle (si->dpy, si->passwd_dialog,
486 pw->shadow_width * 2,
487 pw->thermo_width + (pw->shadow_width * 2),
488 pw->height - (pw->shadow_width * 4),
490 pw->shadow_bottom, pw->shadow_top);
492 /* Solid border inside the thermometer. */
493 XSetForeground (si->dpy, gc1, pw->foreground);
494 XDrawRectangle (si->dpy, si->passwd_dialog, gc1,
495 pw->logo_width + pw->shadow_width,
496 pw->shadow_width * 3,
497 pw->thermo_width - 1,
498 pw->height - (pw->shadow_width * 6) - 1);
500 /* The shadow around the whole window
502 draw_shaded_rectangle (si->dpy, si->passwd_dialog,
503 0, 0, pw->width, pw->height, pw->shadow_width,
504 pw->shadow_top, pw->shadow_bottom);
506 XFreeGC (si->dpy, gc1);
507 XFreeGC (si->dpy, gc2);
509 update_passwd_window (si, pw->passwd_string, pw->ratio);
514 update_passwd_window (saver_info *si, const char *printed_passwd, float ratio)
516 passwd_dialog_data *pw = si->pw_data;
522 gcv.foreground = pw->passwd_foreground;
523 gcv.font = pw->passwd_font->fid;
524 gc1 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground|GCFont, &gcv);
525 gcv.foreground = pw->passwd_background;
526 gc2 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground, &gcv);
530 char *s = strdup (printed_passwd);
531 if (pw->passwd_string) free (pw->passwd_string);
532 pw->passwd_string = s;
535 /* the "password" text field
537 XFillRectangle (si->dpy, si->passwd_dialog, gc2,
538 pw->passwd_field_x, pw->passwd_field_y,
539 pw->passwd_field_width, pw->passwd_field_height);
540 XDrawString (si->dpy, si->passwd_dialog, gc1,
541 pw->passwd_field_x + pw->shadow_width,
542 pw->passwd_field_y + (pw->passwd_font->ascent +
543 pw->passwd_font->descent),
544 pw->passwd_string, strlen(pw->passwd_string));
550 x = (pw->passwd_field_x + pw->shadow_width +
551 string_width (pw->passwd_font, pw->passwd_string));
552 y = pw->passwd_field_y + pw->shadow_width;
553 XDrawLine (si->dpy, si->passwd_dialog, gc1,
554 x, y, x, y + pw->passwd_font->ascent);
557 pw->i_beam = (pw->i_beam + 1) % 4;
562 y = pw->thermo_field_height * (1.0 - pw->ratio);
565 XFillRectangle (si->dpy, si->passwd_dialog, gc2,
566 pw->thermo_field_x + 1,
567 pw->thermo_field_y + 1,
570 XSetForeground (si->dpy, gc1, pw->logo_foreground);
571 XFillRectangle (si->dpy, si->passwd_dialog, gc1,
572 pw->thermo_field_x + 1,
573 pw->thermo_field_y + 1 + y,
575 MAX (0, pw->thermo_field_height - y - 2));
578 XFreeGC (si->dpy, gc1);
579 XFreeGC (si->dpy, gc2);
580 XSync (si->dpy, False);
585 destroy_passwd_window (saver_info *si)
587 passwd_dialog_data *pw = si->pw_data;
588 Screen *screen = si->default_screen->screen;
589 Colormap cmap = DefaultColormapOfScreen (screen);
590 Pixel black = BlackPixelOfScreen (screen);
591 Pixel white = WhitePixelOfScreen (screen);
594 XtRemoveTimeOut (pw->timer);
596 if (si->passwd_dialog)
598 XDestroyWindow (si->dpy, si->passwd_dialog);
599 si->passwd_dialog = 0;
602 if (pw->heading_label) free (pw->heading_label);
603 if (pw->body_label) free (pw->body_label);
604 if (pw->user_label) free (pw->user_label);
605 if (pw->passwd_label) free (pw->passwd_label);
607 if (pw->heading_font) XFreeFont (si->dpy, pw->heading_font);
608 if (pw->body_font) XFreeFont (si->dpy, pw->body_font);
609 if (pw->label_font) XFreeFont (si->dpy, pw->label_font);
610 if (pw->passwd_font) XFreeFont (si->dpy, pw->passwd_font);
612 if (pw->foreground != black && pw->foreground != white)
613 XFreeColors (si->dpy, cmap, &pw->foreground, 1, 0L);
614 if (pw->background != black && pw->background != white)
615 XFreeColors (si->dpy, cmap, &pw->background, 1, 0L);
616 if (pw->passwd_foreground != black && pw->passwd_foreground != white)
617 XFreeColors (si->dpy, cmap, &pw->passwd_foreground, 1, 0L);
618 if (pw->passwd_background != black && pw->passwd_background != white)
619 XFreeColors (si->dpy, cmap, &pw->passwd_background, 1, 0L);
620 if (pw->logo_foreground != black && pw->logo_foreground != white)
621 XFreeColors (si->dpy, cmap, &pw->logo_foreground, 1, 0L);
622 if (pw->logo_background != black && pw->logo_background != white)
623 XFreeColors (si->dpy, cmap, &pw->logo_background, 1, 0L);
624 if (pw->shadow_top != black && pw->shadow_top != white)
625 XFreeColors (si->dpy, cmap, &pw->shadow_top, 1, 0L);
626 if (pw->shadow_bottom != black && pw->shadow_bottom != white)
627 XFreeColors (si->dpy, cmap, &pw->shadow_bottom, 1, 0L);
629 memset (pw, 0, sizeof(*pw));
640 passwd_animate_timer (XtPointer closure, XtIntervalId *id)
642 saver_info *si = (saver_info *) closure;
644 passwd_dialog_data *pw = si->pw_data;
648 pw->ratio -= (1.0 / ((double) si->prefs.passwd_timeout / (double) tick));
652 if (pw->state == pw_read)
656 update_passwd_window (si, 0, pw->ratio);
658 if (pw->state == pw_read)
659 pw->timer = XtAppAddTimeOut (si->app, tick, passwd_animate_timer,
664 idle_timer ((XtPointer) si, id);
669 handle_passwd_key (saver_info *si, XKeyEvent *event)
671 passwd_dialog_data *pw = si->pw_data;
672 int pw_size = sizeof (pw->typed_passwd) - 1;
673 char *typed_passwd = pw->typed_passwd;
677 int size = XLookupString (event, s, 1, 0, 0);
679 if (size != 1) return;
685 case '\010': case '\177': /* Backspace */
689 typed_passwd [strlen(typed_passwd)-1] = 0;
692 case '\025': case '\030': /* Erase line */
693 memset (typed_passwd, 0, pw_size);
696 case '\012': case '\015': /* Enter */
697 if (pw->state != pw_read)
698 ; /* already done? */
699 else if (passwd_valid_p (typed_passwd))
706 i = strlen (typed_passwd);
711 typed_passwd [i] = *s;
712 typed_passwd [i+1] = 0;
717 i = strlen(typed_passwd);
718 stars = (char *) malloc(i+1);
719 memset (stars, '*', i);
721 update_passwd_window (si, stars, pw->ratio);
727 passwd_event_loop (saver_info *si)
731 passwd_animate_timer ((XtPointer) si, 0);
733 while (si->pw_data && si->pw_data->state == pw_read)
735 XtAppNextEvent (si->app, &event);
736 if (event.xany.window == si->passwd_dialog && event.xany.type == Expose)
737 draw_passwd_window (si);
738 else if (event.xany.type == KeyPress)
739 handle_passwd_key (si, &event.xkey);
741 XtDispatchEvent (&event);
744 switch (si->pw_data->state)
746 case pw_ok: msg = 0; break;
747 case pw_time: msg = "Timed out!"; break;
748 default: msg = "Sorry!"; break;
753 si->pw_data->i_beam = 0;
754 update_passwd_window (si, msg, 0.0);
755 XBell (si->dpy, False);
756 XSync (si->dpy, False);
759 /* Swallow all pending KeyPress/KeyRelease events. */
762 while (XCheckMaskEvent (si->dpy, KeyPressMask|KeyReleaseMask, &e))
769 unlock_p (saver_info *si)
771 Screen *screen = si->default_screen->screen;
772 Colormap cmap = DefaultColormapOfScreen (screen);
775 if (si->pw_data || si->passwd_dialog)
776 destroy_passwd_window (si);
778 make_passwd_window (si);
779 if (cmap) XInstallColormap (si->dpy, cmap);
781 passwd_event_loop (si);
783 status = (si->pw_data->state == pw_ok);
784 destroy_passwd_window (si);
786 cmap = si->default_screen->cmap;
787 if (cmap) XInstallColormap (si->dpy, cmap);
792 #endif /* !NO_LOCKING -- whole file */