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"
28 #endif /* HAVE_SYSLOG */
31 ERROR! You must not include vroot.h in this file.
38 extern char *getenv(const char *name);
39 extern int validate_user(char *name, char *password);
42 vms_passwd_valid_p(char *pw)
44 return (validate_user (getenv("USER"), typed_passwd) == 1);
46 # undef passwd_valid_p
47 # define passwd_valid_p vms_passwd_valid_p
53 #define MAX(a,b) ((a)>(b)?(a):(b))
55 enum passwd_state { pw_read, pw_ok, pw_null, pw_fail, pw_cancel, pw_time };
57 struct passwd_dialog_data {
59 enum passwd_state state;
60 char typed_passwd [80];
75 XFontStruct *heading_font;
76 XFontStruct *body_font;
77 XFontStruct *label_font;
78 XFontStruct *passwd_font;
82 Pixel passwd_foreground;
83 Pixel passwd_background;
84 Pixel logo_foreground;
85 Pixel logo_background;
90 Dimension logo_height;
91 Dimension thermo_width;
92 Dimension internal_border;
93 Dimension shadow_width;
95 Dimension passwd_field_x, passwd_field_y;
96 Dimension passwd_field_width, passwd_field_height;
98 Dimension thermo_field_x, thermo_field_y;
99 Dimension thermo_field_height;
104 make_passwd_window (saver_info *si)
106 struct passwd *p = getpwuid (getuid ());
108 XSetWindowAttributes attrs;
109 unsigned long attrmask = 0;
110 Screen *screen = si->default_screen->screen;
111 passwd_dialog_data *pw = (passwd_dialog_data *) calloc (1, sizeof(*pw));
112 Colormap cmap = DefaultColormapOfScreen (screen);
117 pw->heading_label = get_string_resource ("passwd.heading.label",
118 "Dialog.Label.Label");
119 pw->body_label = get_string_resource ("passwd.body.label",
120 "Dialog.Label.Label");
121 pw->user_label = get_string_resource ("passwd.user.label",
122 "Dialog.Label.Label");
123 pw->passwd_label = get_string_resource ("passwd.passwd.label",
124 "Dialog.Label.Label");
126 if (!pw->heading_label)
127 pw->heading_label = strdup("ERROR: REESOURCES NOT INSTALLED CORRECTLY");
129 pw->body_label = strdup("ERROR: REESOURCES NOT INSTALLED CORRECTLY");
130 if (!pw->user_label) pw->user_label = strdup("ERROR");
131 if (!pw->passwd_label) pw->passwd_label = strdup("ERROR");
133 /* Put the version number in the label. */
135 char *s = (char *) malloc (strlen(pw->heading_label) + 20);
136 sprintf(s, pw->heading_label, si->version);
137 free (pw->heading_label);
138 pw->heading_label = s;
141 pw->user_string = (p->pw_name ? p->pw_name : "???");
142 pw->passwd_string = strdup("");
144 f = get_string_resource ("passwd.headingFont", "Dialog.Font");
145 pw->heading_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
146 if (!pw->heading_font) pw->heading_font = XLoadQueryFont (si->dpy, "fixed");
149 f = get_string_resource("passwd.bodyFont", "Dialog.Font");
150 pw->body_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
151 if (!pw->body_font) pw->body_font = XLoadQueryFont (si->dpy, "fixed");
154 f = get_string_resource("passwd.labelFont", "Dialog.Font");
155 pw->label_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
156 if (!pw->label_font) pw->label_font = XLoadQueryFont (si->dpy, "fixed");
159 f = get_string_resource("passwd.passwdFont", "Dialog.Font");
160 pw->passwd_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
161 if (!pw->passwd_font) pw->passwd_font = XLoadQueryFont (si->dpy, "fixed");
164 pw->foreground = get_pixel_resource ("passwd.foreground",
167 pw->background = get_pixel_resource ("passwd.background",
171 if (pw->foreground == pw->background)
173 /* Make sure the error messages show up. */
174 pw->foreground = BlackPixelOfScreen (screen);
175 pw->background = WhitePixelOfScreen (screen);
178 pw->passwd_foreground = get_pixel_resource ("passwd.text.foreground",
179 "Dialog.Text.Foreground",
181 pw->passwd_background = get_pixel_resource ("passwd.text.background",
182 "Dialog.Text.Background",
184 pw->logo_foreground = get_pixel_resource ("passwd.logo.foreground",
185 "Dialog.Logo.Foreground",
187 pw->logo_background = get_pixel_resource ("passwd.logo.background",
188 "Dialog.Logo.Background",
190 pw->shadow_top = get_pixel_resource ("passwd.topShadowColor",
193 pw->shadow_bottom = get_pixel_resource ("passwd.bottomShadowColor",
197 pw->logo_width = get_integer_resource ("passwd.logo.width",
198 "Dialog.Logo.Width");
199 pw->logo_height = get_integer_resource ("passwd.logo.height",
200 "Dialog.Logo.Height");
201 pw->thermo_width = get_integer_resource ("passwd.thermometer.width",
202 "Dialog.Thermometer.Width");
203 pw->internal_border = get_integer_resource ("passwd.internalBorderWidth",
204 "Dialog.InternalBorderWidth");
205 pw->shadow_width = get_integer_resource ("passwd.shadowThickness",
206 "Dialog.ShadowThickness");
208 if (pw->logo_width == 0) pw->logo_width = 150;
209 if (pw->logo_height == 0) pw->logo_height = 150;
210 if (pw->internal_border == 0) pw->internal_border = 15;
211 if (pw->shadow_width == 0) pw->shadow_width = 4;
212 if (pw->thermo_width == 0) pw->thermo_width = pw->shadow_width;
215 int direction, ascent, descent;
221 /* Measure the heading_label. */
222 XTextExtents (pw->heading_font,
223 pw->heading_label, strlen(pw->heading_label),
224 &direction, &ascent, &descent, &overall);
225 if (overall.width > pw->width) pw->width = overall.width;
226 pw->height += ascent + descent;
228 /* Measure the body_label. */
229 XTextExtents (pw->body_font,
230 pw->body_label, strlen(pw->body_label),
231 &direction, &ascent, &descent, &overall);
232 if (overall.width > pw->width) pw->width = overall.width;
233 pw->height += ascent + descent;
236 Dimension w2 = 0, w3 = 0;
237 Dimension h2 = 0, h3 = 0;
238 const char *passwd_string = "MMMMMMMMMMMM";
240 /* Measure the user_label. */
241 XTextExtents (pw->label_font,
242 pw->user_label, strlen(pw->user_label),
243 &direction, &ascent, &descent, &overall);
244 if (overall.width > w2) w2 = overall.width;
245 h2 += ascent + descent;
247 /* Measure the passwd_label. */
248 XTextExtents (pw->label_font,
249 pw->passwd_label, strlen(pw->passwd_label),
250 &direction, &ascent, &descent, &overall);
251 if (overall.width > w2) w2 = overall.width;
252 h2 += ascent + descent;
254 /* Measure the user_string. */
255 XTextExtents (pw->passwd_font,
256 pw->user_string, strlen(pw->user_string),
257 &direction, &ascent, &descent, &overall);
258 overall.width += (pw->shadow_width * 4);
259 ascent += (pw->shadow_width * 4);
260 if (overall.width > w3) w3 = overall.width;
261 h3 += ascent + descent;
263 /* Measure the (maximally-sized, dummy) passwd_string. */
264 XTextExtents (pw->passwd_font,
265 passwd_string, strlen(passwd_string),
266 &direction, &ascent, &descent, &overall);
267 overall.width += (pw->shadow_width * 4);
268 ascent += (pw->shadow_width * 4);
269 if (overall.width > w3) w3 = overall.width;
270 h3 += ascent + descent;
272 w2 = w2 + w3 + (pw->shadow_width * 2);
275 if (w2 > pw->width) pw->width = w2;
279 pw->width += (pw->internal_border * 2);
280 pw->height += (pw->internal_border * 4);
282 pw->width += pw->thermo_width + (pw->shadow_width * 3);
284 if (pw->logo_height > pw->height)
285 pw->height = pw->logo_height;
286 else if (pw->height > pw->logo_height)
287 pw->logo_height = pw->height;
289 pw->logo_width = pw->logo_height;
291 pw->width += pw->logo_width;
294 attrmask |= CWOverrideRedirect; attrs.override_redirect = True;
295 attrmask |= CWEventMask; attrs.event_mask = ExposureMask|KeyPressMask;
298 Dimension w = WidthOfScreen(screen);
299 Dimension h = HeightOfScreen(screen);
300 if (si->prefs.debug_p) w /= 2;
301 x = ((w + pw->width) / 2) - pw->width;
302 y = ((h + pw->height) / 2) - pw->height;
307 bw = get_integer_resource ("passwd.borderWidth", "Dialog.BorderWidth");
310 XCreateWindow (si->dpy,
311 RootWindowOfScreen(screen),
312 x, y, pw->width, pw->height, bw,
313 DefaultDepthOfScreen (screen), InputOutput,
314 DefaultVisualOfScreen(screen),
316 XSetWindowBackground (si->dpy, si->passwd_dialog, pw->background);
318 XMapRaised (si->dpy, si->passwd_dialog);
319 XSync (si->dpy, False);
323 draw_passwd_window (si);
324 XSync (si->dpy, False);
329 draw_passwd_window (saver_info *si)
331 passwd_dialog_data *pw = si->pw_data;
335 int x1, x2, x3, y1, y2;
339 height = (pw->heading_font->ascent + pw->heading_font->descent +
340 pw->body_font->ascent + pw->body_font->descent +
341 (2 * MAX ((pw->label_font->ascent + pw->label_font->descent),
342 (pw->passwd_font->ascent + pw->passwd_font->descent +
343 (pw->shadow_width * 4)))));
344 spacing = ((pw->height - (2 * pw->shadow_width) -
345 pw->internal_border - height)) / 8;
346 if (spacing < 0) spacing = 0;
348 gcv.foreground = pw->foreground;
349 gc1 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground, &gcv);
350 gc2 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground, &gcv);
351 x1 = pw->logo_width + pw->thermo_width + (pw->shadow_width * 3);
352 x3 = pw->width - (pw->shadow_width * 2);
353 y1 = (pw->shadow_width * 2) + spacing + spacing;
357 XSetFont (si->dpy, gc1, pw->heading_font->fid);
358 sw = string_width (pw->heading_font, pw->heading_label);
359 x2 = (x1 + ((x3 - x1 - sw) / 2));
360 y1 += spacing + pw->heading_font->ascent + pw->heading_font->descent;
361 XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1,
362 pw->heading_label, strlen(pw->heading_label));
364 /* text below top heading
366 XSetFont (si->dpy, gc1, pw->body_font->fid);
367 y1 += spacing + pw->body_font->ascent + pw->body_font->descent;
368 sw = string_width (pw->body_font, pw->body_label);
369 x2 = (x1 + ((x3 - x1 - sw) / 2));
370 XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1,
371 pw->body_label, strlen(pw->body_label));
374 tb_height = (pw->passwd_font->ascent + pw->passwd_font->descent +
375 (pw->shadow_width * 4));
377 /* the "User:" prompt
381 XSetForeground (si->dpy, gc1, pw->foreground);
382 XSetFont (si->dpy, gc1, pw->label_font->fid);
383 y1 += (spacing + tb_height);
384 x2 = (x1 + pw->internal_border +
385 MAX(string_width (pw->label_font, pw->user_label),
386 string_width (pw->label_font, pw->passwd_label)));
387 XDrawString (si->dpy, si->passwd_dialog, gc1,
388 x2 - string_width (pw->label_font, pw->user_label),
390 pw->user_label, strlen(pw->user_label));
392 /* the "Password:" prompt
394 y1 += (spacing + tb_height);
395 XDrawString (si->dpy, si->passwd_dialog, gc1,
396 x2 - string_width (pw->label_font, pw->passwd_label),
398 pw->passwd_label, strlen(pw->passwd_label));
401 XSetForeground (si->dpy, gc2, pw->passwd_background);
403 /* the "user name" text field
406 XSetForeground (si->dpy, gc1, pw->passwd_foreground);
407 XSetFont (si->dpy, gc1, pw->passwd_font->fid);
408 y1 += (spacing + tb_height);
409 x2 += (pw->shadow_width * 4);
411 pw->passwd_field_width = x3 - x2 - pw->internal_border;
412 pw->passwd_field_height = (pw->passwd_font->ascent +
413 pw->passwd_font->descent +
416 XFillRectangle (si->dpy, si->passwd_dialog, gc2,
417 x2 - pw->shadow_width,
418 y1 - (pw->passwd_font->ascent + pw->passwd_font->descent),
419 pw->passwd_field_width, pw->passwd_field_height);
420 XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1,
421 pw->user_string, strlen(pw->user_string));
423 /* the "password" text field
425 y1 += (spacing + tb_height);
427 pw->passwd_field_x = x2 - pw->shadow_width;
428 pw->passwd_field_y = y1 - (pw->passwd_font->ascent +
429 pw->passwd_font->descent);
431 /* The shadow around the text fields
434 y1 += (spacing + (pw->shadow_width * 3));
435 x1 = x2 - (pw->shadow_width * 2);
436 x2 = pw->passwd_field_width + (pw->shadow_width * 2);
437 y2 = pw->passwd_field_height + (pw->shadow_width * 2);
439 draw_shaded_rectangle (si->dpy, si->passwd_dialog,
442 pw->shadow_bottom, pw->shadow_top);
444 y1 += (spacing + pw->passwd_font->ascent + pw->passwd_font->descent +
445 (pw->shadow_width * 4));
446 draw_shaded_rectangle (si->dpy, si->passwd_dialog,
449 pw->shadow_bottom, pw->shadow_top);
453 XSetForeground (si->dpy, gc1, pw->logo_foreground);
454 XSetForeground (si->dpy, gc2, pw->logo_background);
456 x1 = pw->shadow_width * 3;
457 y1 = pw->shadow_width * 3;
458 x2 = pw->logo_width - (pw->shadow_width * 6);
459 y2 = pw->logo_height - (pw->shadow_width * 6);
461 XFillRectangle (si->dpy, si->passwd_dialog, gc2, x1, y1, x2, y2);
462 skull (si->dpy, si->passwd_dialog, gc1, gc2,
463 x1 + pw->shadow_width, y1 + pw->shadow_width,
464 x2 - (pw->shadow_width * 2), y2 - (pw->shadow_width * 2));
468 pw->thermo_field_x = pw->logo_width + pw->shadow_width;
469 pw->thermo_field_y = pw->shadow_width * 3;
470 pw->thermo_field_height = pw->height - (pw->shadow_width * 6);
472 /* Solid border inside the logo box. */
473 XSetForeground (si->dpy, gc1, pw->foreground);
474 XDrawRectangle (si->dpy, si->passwd_dialog, gc1, x1, y1, x2-1, y2-1);
476 /* The shadow around the logo
478 draw_shaded_rectangle (si->dpy, si->passwd_dialog,
479 pw->shadow_width * 2,
480 pw->shadow_width * 2,
481 pw->logo_width - (pw->shadow_width * 4),
482 pw->logo_height - (pw->shadow_width * 4),
484 pw->shadow_bottom, pw->shadow_top);
486 /* The shadow around the thermometer
488 draw_shaded_rectangle (si->dpy, si->passwd_dialog,
490 pw->shadow_width * 2,
491 pw->thermo_width + (pw->shadow_width * 2),
492 pw->height - (pw->shadow_width * 4),
494 pw->shadow_bottom, pw->shadow_top);
496 /* Solid border inside the thermometer. */
497 XSetForeground (si->dpy, gc1, pw->foreground);
498 XDrawRectangle (si->dpy, si->passwd_dialog, gc1,
499 pw->logo_width + pw->shadow_width,
500 pw->shadow_width * 3,
501 pw->thermo_width - 1,
502 pw->height - (pw->shadow_width * 6) - 1);
504 /* The shadow around the whole window
506 draw_shaded_rectangle (si->dpy, si->passwd_dialog,
507 0, 0, pw->width, pw->height, pw->shadow_width,
508 pw->shadow_top, pw->shadow_bottom);
510 XFreeGC (si->dpy, gc1);
511 XFreeGC (si->dpy, gc2);
513 update_passwd_window (si, pw->passwd_string, pw->ratio);
518 update_passwd_window (saver_info *si, const char *printed_passwd, float ratio)
520 passwd_dialog_data *pw = si->pw_data;
526 gcv.foreground = pw->passwd_foreground;
527 gcv.font = pw->passwd_font->fid;
528 gc1 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground|GCFont, &gcv);
529 gcv.foreground = pw->passwd_background;
530 gc2 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground, &gcv);
534 char *s = strdup (printed_passwd);
535 if (pw->passwd_string) free (pw->passwd_string);
536 pw->passwd_string = s;
539 /* the "password" text field
541 XFillRectangle (si->dpy, si->passwd_dialog, gc2,
542 pw->passwd_field_x, pw->passwd_field_y,
543 pw->passwd_field_width, pw->passwd_field_height);
544 XDrawString (si->dpy, si->passwd_dialog, gc1,
545 pw->passwd_field_x + pw->shadow_width,
546 pw->passwd_field_y + (pw->passwd_font->ascent +
547 pw->passwd_font->descent),
548 pw->passwd_string, strlen(pw->passwd_string));
554 x = (pw->passwd_field_x + pw->shadow_width +
555 string_width (pw->passwd_font, pw->passwd_string));
556 y = pw->passwd_field_y + pw->shadow_width;
557 XDrawLine (si->dpy, si->passwd_dialog, gc1,
558 x, y, x, y + pw->passwd_font->ascent);
561 pw->i_beam = (pw->i_beam + 1) % 4;
566 y = pw->thermo_field_height * (1.0 - pw->ratio);
569 XFillRectangle (si->dpy, si->passwd_dialog, gc2,
570 pw->thermo_field_x + 1,
571 pw->thermo_field_y + 1,
574 XSetForeground (si->dpy, gc1, pw->logo_foreground);
575 XFillRectangle (si->dpy, si->passwd_dialog, gc1,
576 pw->thermo_field_x + 1,
577 pw->thermo_field_y + 1 + y,
579 MAX (0, pw->thermo_field_height - y - 2));
582 XFreeGC (si->dpy, gc1);
583 XFreeGC (si->dpy, gc2);
584 XSync (si->dpy, False);
589 destroy_passwd_window (saver_info *si)
591 passwd_dialog_data *pw = si->pw_data;
592 Screen *screen = si->default_screen->screen;
593 Colormap cmap = DefaultColormapOfScreen (screen);
594 Pixel black = BlackPixelOfScreen (screen);
595 Pixel white = WhitePixelOfScreen (screen);
598 XtRemoveTimeOut (pw->timer);
600 if (si->passwd_dialog)
602 XDestroyWindow (si->dpy, si->passwd_dialog);
603 si->passwd_dialog = 0;
606 if (pw->heading_label) free (pw->heading_label);
607 if (pw->body_label) free (pw->body_label);
608 if (pw->user_label) free (pw->user_label);
609 if (pw->passwd_label) free (pw->passwd_label);
611 if (pw->heading_font) XFreeFont (si->dpy, pw->heading_font);
612 if (pw->body_font) XFreeFont (si->dpy, pw->body_font);
613 if (pw->label_font) XFreeFont (si->dpy, pw->label_font);
614 if (pw->passwd_font) XFreeFont (si->dpy, pw->passwd_font);
616 if (pw->foreground != black && pw->foreground != white)
617 XFreeColors (si->dpy, cmap, &pw->foreground, 1, 0L);
618 if (pw->background != black && pw->background != white)
619 XFreeColors (si->dpy, cmap, &pw->background, 1, 0L);
620 if (pw->passwd_foreground != black && pw->passwd_foreground != white)
621 XFreeColors (si->dpy, cmap, &pw->passwd_foreground, 1, 0L);
622 if (pw->passwd_background != black && pw->passwd_background != white)
623 XFreeColors (si->dpy, cmap, &pw->passwd_background, 1, 0L);
624 if (pw->logo_foreground != black && pw->logo_foreground != white)
625 XFreeColors (si->dpy, cmap, &pw->logo_foreground, 1, 0L);
626 if (pw->logo_background != black && pw->logo_background != white)
627 XFreeColors (si->dpy, cmap, &pw->logo_background, 1, 0L);
628 if (pw->shadow_top != black && pw->shadow_top != white)
629 XFreeColors (si->dpy, cmap, &pw->shadow_top, 1, 0L);
630 if (pw->shadow_bottom != black && pw->shadow_bottom != white)
631 XFreeColors (si->dpy, cmap, &pw->shadow_bottom, 1, 0L);
633 memset (pw, 0, sizeof(*pw));
644 passwd_animate_timer (XtPointer closure, XtIntervalId *id)
646 saver_info *si = (saver_info *) closure;
648 passwd_dialog_data *pw = si->pw_data;
652 pw->ratio -= (1.0 / ((double) si->prefs.passwd_timeout / (double) tick));
656 if (pw->state == pw_read)
660 update_passwd_window (si, 0, pw->ratio);
662 if (pw->state == pw_read)
663 pw->timer = XtAppAddTimeOut (si->app, tick, passwd_animate_timer,
668 idle_timer ((XtPointer) si, id);
673 handle_passwd_key (saver_info *si, XKeyEvent *event)
675 passwd_dialog_data *pw = si->pw_data;
676 int pw_size = sizeof (pw->typed_passwd) - 1;
677 char *typed_passwd = pw->typed_passwd;
681 int size = XLookupString (event, s, 1, 0, 0);
683 if (size != 1) return;
689 case '\010': case '\177': /* Backspace */
693 typed_passwd [strlen(typed_passwd)-1] = 0;
696 case '\025': case '\030': /* Erase line */
697 memset (typed_passwd, 0, pw_size);
700 case '\012': case '\015': /* Enter */
701 if (pw->state != pw_read)
702 ; /* already done? */
703 else if (passwd_valid_p (typed_passwd))
705 else if (typed_passwd[0] == 0)
712 i = strlen (typed_passwd);
717 typed_passwd [i] = *s;
718 typed_passwd [i+1] = 0;
723 i = strlen(typed_passwd);
724 stars = (char *) malloc(i+1);
725 memset (stars, '*', i);
727 update_passwd_window (si, stars, pw->ratio);
733 passwd_event_loop (saver_info *si)
735 saver_preferences *p = &si->prefs;
738 passwd_animate_timer ((XtPointer) si, 0);
740 while (si->pw_data && si->pw_data->state == pw_read)
742 XtAppNextEvent (si->app, &event);
743 if (event.xany.window == si->passwd_dialog && event.xany.type == Expose)
744 draw_passwd_window (si);
745 else if (event.xany.type == KeyPress)
746 handle_passwd_key (si, &event.xkey);
748 XtDispatchEvent (&event);
751 switch (si->pw_data->state)
753 case pw_ok: msg = 0; break;
754 case pw_null: msg = ""; break;
755 case pw_time: msg = "Timed out!"; break;
756 default: msg = "Sorry!"; break;
759 if (si->pw_data->state == pw_fail)
760 si->unlock_failures++;
763 switch (si->pw_data->state)
766 fprintf (stderr, "%s: password correct.\n", blurb()); break;
768 fprintf (stderr, "%s: password incorrect!\n", blurb()); break;
771 fprintf (stderr, "%s: password entry cancelled.\n", blurb()); break;
773 fprintf (stderr, "%s: password entry timed out.\n", blurb()); break;
778 if (si->pw_data->state == pw_fail)
780 /* If they typed a password (as opposed to just hitting return) and
781 the password was invalid, log it.
783 struct passwd *pw = getpwuid (getuid ());
784 char *d = DisplayString (si->dpy);
785 char *u = (pw->pw_name ? pw->pw_name : "???");
793 # if defined(LOG_AUTHPRIV)
795 # elif defined(LOG_AUTH)
802 openlog (progname, opt, fac);
803 syslog (LOG_NOTICE, "FAILED LOGIN %d ON DISPLAY \"%s\", FOR \"%s\"",
804 si->unlock_failures, d, u);
807 #endif /* HAVE_SYSLOG */
809 if (si->pw_data->state == pw_ok && si->unlock_failures != 0)
811 if (si->unlock_failures == 1)
812 fprintf (real_stderr,
813 "%s: WARNING: 1 failed attempt to unlock the screen.\n",
816 fprintf (real_stderr,
817 "%s: WARNING: %d failed attempts to unlock the screen.\n",
818 blurb(), si->unlock_failures);
819 fflush (real_stderr);
821 si->unlock_failures = 0;
826 si->pw_data->i_beam = 0;
827 update_passwd_window (si, msg, 0.0);
828 XBell (si->dpy, False);
829 XSync (si->dpy, False);
832 /* Swallow all pending KeyPress/KeyRelease events. */
835 while (XCheckMaskEvent (si->dpy, KeyPressMask|KeyReleaseMask, &e))
843 unlock_p (saver_info *si)
845 saver_preferences *p = &si->prefs;
846 Screen *screen = si->default_screen->screen;
847 Colormap cmap = DefaultColormapOfScreen (screen);
851 fprintf (stderr, "%s: prompting for password.\n", blurb());
853 if (si->pw_data || si->passwd_dialog)
854 destroy_passwd_window (si);
856 make_passwd_window (si);
857 if (cmap) XInstallColormap (si->dpy, cmap);
859 passwd_event_loop (si);
861 status = (si->pw_data->state == pw_ok);
862 destroy_passwd_window (si);
864 cmap = si->default_screen->cmap;
865 if (cmap) XInstallColormap (si->dpy, cmap);
870 #endif /* !NO_LOCKING -- whole file */