X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=driver%2Flock.c;h=8a00b3ba154869df0ed8c0a25fb5d513ea0e4f51;hp=c87597832039ee11f32fb5f8ca0dfa1312f7b25b;hb=3210e7e80ee2b5a7d2049a5aaff9f17b9c93dcc9;hpb=cf665b135b41d4f42067f9d9a8111c9602777cc1 diff --git a/driver/lock.c b/driver/lock.c index c8759783..8a00b3ba 100644 --- a/driver/lock.c +++ b/driver/lock.c @@ -39,7 +39,7 @@ extern char *getenv(const char *name); extern int validate_user(char *name, char *password); static Bool -vms_passwd_valid_p(char *pw) +vms_passwd_valid_p(char *pw, Bool verbose_p) { return (validate_user (getenv("USER"), typed_passwd) == 1); } @@ -62,8 +62,10 @@ struct passwd_dialog_data { int i_beam; float ratio; + Position x, y; Dimension width; Dimension height; + Dimension border_width; char *heading_label; char *body_label; @@ -97,6 +99,8 @@ struct passwd_dialog_data { Dimension thermo_field_x, thermo_field_y; Dimension thermo_field_height; + + Pixmap save_under; }; @@ -104,7 +108,6 @@ void make_passwd_window (saver_info *si) { struct passwd *p = getpwuid (getuid ()); - int x, y, bw; XSetWindowAttributes attrs; unsigned long attrmask = 0; Screen *screen = si->default_screen->screen; @@ -298,23 +301,49 @@ make_passwd_window (saver_info *si) Dimension w = WidthOfScreen(screen); Dimension h = HeightOfScreen(screen); if (si->prefs.debug_p) w /= 2; - x = ((w + pw->width) / 2) - pw->width; - y = ((h + pw->height) / 2) - pw->height; - if (x < 0) x = 0; - if (y < 0) y = 0; + pw->x = ((w + pw->width) / 2) - pw->width; + pw->y = ((h + pw->height) / 2) - pw->height; + if (pw->x < 0) pw->x = 0; + if (pw->y < 0) pw->y = 0; } - bw = get_integer_resource ("passwd.borderWidth", "Dialog.BorderWidth"); + pw->border_width = get_integer_resource ("passwd.borderWidth", + "Dialog.BorderWidth"); si->passwd_dialog = XCreateWindow (si->dpy, RootWindowOfScreen(screen), - x, y, pw->width, pw->height, bw, + pw->x, pw->y, pw->width, pw->height, pw->border_width, DefaultDepthOfScreen (screen), InputOutput, DefaultVisualOfScreen(screen), attrmask, &attrs); XSetWindowBackground (si->dpy, si->passwd_dialog, pw->background); + + /* Before mapping the window, save the bits that are underneath the + rectangle the window will occlude. When we lower the window, we + restore these bits. This works, because the running screenhack + has already been sent SIGSTOP, so we know nothing else is drawing + right now! */ + { + XGCValues gcv; + GC gc; + pw->save_under = XCreatePixmap (si->dpy, + si->default_screen->screensaver_window, + pw->width + (pw->border_width*2) + 1, + pw->height + (pw->border_width*2) + 1, + si->default_screen->current_depth); + gcv.function = GXcopy; + gc = XCreateGC (si->dpy, pw->save_under, GCFunction, &gcv); + XCopyArea (si->dpy, si->default_screen->screensaver_window, + pw->save_under, gc, + pw->x - pw->border_width, pw->y - pw->border_width, + pw->width + (pw->border_width*2) + 1, + pw->height + (pw->border_width*2) + 1, + 0, 0); + XFreeGC (si->dpy, gc); + } + XMapRaised (si->dpy, si->passwd_dialog); XSync (si->dpy, False); @@ -603,6 +632,24 @@ destroy_passwd_window (saver_info *si) si->passwd_dialog = 0; } + if (pw->save_under) + { + XGCValues gcv; + GC gc; + gcv.function = GXcopy; + gc = XCreateGC (si->dpy, si->default_screen->screensaver_window, + GCFunction, &gcv); + XCopyArea (si->dpy, pw->save_under, + si->default_screen->screensaver_window, gc, + 0, 0, + pw->width + (pw->border_width*2) + 1, + pw->height + (pw->border_width*2) + 1, + pw->x - pw->border_width, pw->y - pw->border_width); + XFreePixmap (si->dpy, pw->save_under); + pw->save_under = 0; + XFreeGC (si->dpy, gc); + } + if (pw->heading_label) free (pw->heading_label); if (pw->body_label) free (pw->body_label); if (pw->user_label) free (pw->user_label); @@ -672,6 +719,7 @@ passwd_animate_timer (XtPointer closure, XtIntervalId *id) static void handle_passwd_key (saver_info *si, XKeyEvent *event) { + saver_preferences *p = &si->prefs; passwd_dialog_data *pw = si->pw_data; int pw_size = sizeof (pw->typed_passwd) - 1; char *typed_passwd = pw->typed_passwd; @@ -700,12 +748,18 @@ handle_passwd_key (saver_info *si, XKeyEvent *event) case '\012': case '\015': /* Enter */ if (pw->state != pw_read) ; /* already done? */ - else if (passwd_valid_p (typed_passwd)) - pw->state = pw_ok; else if (typed_passwd[0] == 0) pw->state = pw_null; else - pw->state = pw_fail; + { + update_passwd_window (si, "Checking...", pw->ratio); + XSync (si->dpy, False); + if (passwd_valid_p (typed_passwd, p->verbose_p)) + pw->state = pw_ok; + else + pw->state = pw_fail; + update_passwd_window (si, "", pw->ratio); + } break; default: @@ -806,6 +860,9 @@ passwd_event_loop (saver_info *si) } #endif /* HAVE_SYSLOG */ + if (si->pw_data->state == pw_fail) + XBell (si->dpy, False); + if (si->pw_data->state == pw_ok && si->unlock_failures != 0) { if (si->unlock_failures == 1) @@ -825,7 +882,6 @@ passwd_event_loop (saver_info *si) { si->pw_data->i_beam = 0; update_passwd_window (si, msg, 0.0); - XBell (si->dpy, False); XSync (si->dpy, False); sleep (1);