http://x.cybermirror.org/R5contrib/xscreensaver-1.21.tar.Z
[xscreensaver] / driver / lock.c
index 92137aa821a70ec9077d19dbf29cdb3d5dfb5fee..4bf6a92fe3f72a1907b9c619ce766c93ed8d8716 100644 (file)
@@ -5,7 +5,7 @@
  * the above copyright notice appear in all copies and that both that
  * copyright notice and this permission notice appear in supporting
  * documentation.  No representations are made about the suitability of this
- * software for any purpose.  It is provided "as is" without express or
+ * software for any purpose.  It is provided "as is" without express or 
  * implied warranty.
  */
 
@@ -34,9 +34,9 @@
 
 #include "xscreensaver.h"
 
-Time passwd_timeout;
 #ifndef NO_LOCKING
 
+Time passwd_timeout;
 
 extern char *screensaver_version;
 extern char *progname;
@@ -54,14 +54,11 @@ extern Widget passwd_cancel;
 
 extern create_passwd_dialog ();
 
-static enum
-{
-  pw_read, pw_ok, pw_fail, pw_cancel, pw_time
-} passwd_state;
-static char typed_passwd[1024];
+static enum { pw_read, pw_ok, pw_fail, pw_cancel, pw_time } passwd_state;
+static char typed_passwd [1024];
 
-static char root_passwd[255];
-static char user_passwd[255];
+static char root_passwd [255];
+static char user_passwd [255];
 
 #ifdef HAVE_SHADOW
 # define PWTYPE struct spwd *
@@ -79,44 +76,51 @@ lock_init ()
   Bool ok = True;
   char *u;
   PWTYPE p = GETPW ("root");
-
   if (p && p->PWSLOT && p->PWSLOT[0] != '*')
     strcpy (root_passwd, p->PWSLOT);
   else
-  {
-    fprintf (stderr, "%s: couldn't get root's password\n", progname);
-    strcpy (root_passwd, "*");
-  }
+    {
+      fprintf (stderr, "%s: couldn't get root's password\n", progname);
+      strcpy (root_passwd, "*");
+    }
 
   /* It has been reported that getlogin() returns the wrong user id on some
      very old SGI systems... */
-  u = (char *) getlogin ();
+  u = getlogin ();
   if (u)
     p = GETPW (u);
   else
-  {
-    /* getlogin() fails if not attached to a terminal;
+    {
+      /* getlogin() fails if not attached to a terminal;
         in that case, use getpwuid(). */
-    p = getpwuid (getuid ());
-    u = p->pw_name;
-  }
+      struct passwd *p2 = getpwuid (getuid ());
+      u = p2->pw_name;
+#ifdef HAVE_SHADOW
+      p = GETPW (u);
+#else
+      p = p2;
+#endif
+    }
 
-  if (p && p->PWSLOT && p->PWSLOT[0] != '*')
+  if (p && p->PWSLOT &&
+      /* p->PWSLOT[0] != '*' */                /* sensible */
+      (strlen (p->PWSLOT) > 4)         /* solaris */
+      )
     strcpy (user_passwd, p->PWSLOT);
   else
-  {
-    fprintf (stderr, "%s: couldn't get password of \"%s\"\n", progname, u);
-    strcpy (user_passwd, "*");
-    ok = False;
-  }
+    {
+      fprintf (stderr, "%s: couldn't get password of \"%s\"\n", progname, u);
+      strcpy (user_passwd, "*");
+      ok = False;
+    }
   return ok;
 }
+
+
 \f
-#ifdef XmVersion
-# if (XmVersion >= 1002)       /* The `destroy' bug apears to be fixed as   */
-#  define DESTROY_WORKS                /* of Motif 1.2.1, but the `verify-callback' */
-# endif                                /* bug is still present. */
-#endif
+#if (XmVersion >= 1002)         /* The `destroy' bug apears to be fixed as   */
+# define DESTROY_WORKS  /* of Motif 1.2.1, but the `verify-callback' */
+#endif                  /* bug is still present. */
 
 static void
 passwd_cancel_cb (button, client_data, call_data)
@@ -131,13 +135,11 @@ passwd_done_cb (button, client_data, call_data)
      Widget button;
      XtPointer client_data, call_data;
 {
-  if (passwd_state != pw_read)
-    return;                    /* already done */
-
+  if (passwd_state != pw_read) return; /* already done */
   if (!strcmp ((char *) crypt (typed_passwd, user_passwd), user_passwd))
     passwd_state = pw_ok;
   /* do not allow root to have empty passwd */
-  else if (typed_passwd[0] &&
+  else if (typed_passwd [0] &&
           !strcmp ((char *) crypt (typed_passwd, root_passwd), root_passwd))
     passwd_state = pw_ok;
   else
@@ -146,7 +148,7 @@ passwd_done_cb (button, client_data, call_data)
 
 #ifdef VERIFY_CALLBACK_WORKS
 
-/* ####  It looks to me like adding any modifyVerify callback causes
+  /* ####  It looks to me like adding any modifyVerify callback causes
      ####  Motif 1.1.4 to free the the TextF_Value() twice.  I can't see
      ####  the bug in the Motif source, but Purify complains, even if
      ####  check_passwd_cb() is a no-op.
@@ -156,7 +158,7 @@ passwd_done_cb (button, client_data, call_data)
      ####  Probably this block is the text field's text.
    */
 
-static void
+static void 
 check_passwd_cb (button, client_data, call_data)
      Widget button;
      XtPointer client_data, call_data;
@@ -166,40 +168,37 @@ check_passwd_cb (button, client_data, call_data)
   if (passwd_state != pw_read)
     return;
   else if (vcb->reason == XmCR_ACTIVATE)
-  {
-    passwd_done_cb (0, 0, 0);
-  }
+    {
+      passwd_done_cb (0, 0, 0);
+    }
   else if (vcb->text->length > 1)      /* don't allow "paste" operations */
-  {
-    vcb->doit = False;
-  }
+    {
+      vcb->doit = False;
+    }
   else if (vcb->text->ptr != 0)
-  {
-    int i;
-
-    strncat (typed_passwd, vcb->text->ptr, vcb->text->length);
-    typed_passwd[vcb->endPos + vcb->text->length] = 0;
-    for (i = 0; i < vcb->text->length; i++)
-      vcb->text->ptr[i] = '*';
-  }
+    {
+      int i;
+      strncat (typed_passwd, vcb->text->ptr, vcb->text->length);
+      typed_passwd [vcb->endPos + vcb->text->length] = 0;
+      for (i = 0; i < vcb->text->length; i++)
+       vcb->text->ptr [i] = '*';
+    }
 }
 
 #else /* !VERIFY_CALLBACK_WORKS */
 
-static void keypress ();
-static void backspace ();
-static void kill_line ();
-static void done ();
+static void keypress();
+static void backspace();
+static void kill_line();
+static void done();
 
-static XtActionsRec actions[] =
-{
-  {"keypress", keypress},
-  {"backspace", backspace},
-  {"kill_line", kill_line},
-  {"done", done}
-};
+static XtActionsRec actions[] = {{"keypress",  keypress},
+                                {"backspace", backspace},
+                                {"kill_line", kill_line},
+                                {"done",      done}
+                               };
 
-#if 0                          /* oh fuck, why doesn't this work? */
+#if 0 /* oh fuck, why doesn't this work? */
 static char translations[] = "\
 <Key>BackSpace:                backspace()\n\
 <Key>Delete:           backspace()\n\
@@ -210,10 +209,8 @@ Ctrl<Key>J:                done()\n\
 Ctrl<Key>M:            done()\n\
 <Key>:                 keypress()\n\
 ";
-
 #else
 static char translations[] = "<Key>:keypress()";
-
 #endif
 
 static void
@@ -224,49 +221,23 @@ keypress (w, event, argv, argc)
      Cardinal *argc;
 {
   int i, j;
-  char s[sizeof (typed_passwd)];
+  char s [sizeof (typed_passwd)];
   int size = XLookupString ((XKeyEvent *) event, s, sizeof (s), 0, 0);
-
-  if (size != 1)
-    return;
+  if (size != 1) return;
 
   /* hack because I can't get translations to dance to my tune... */
-  if (*s == '\010')
-  {
-    backspace (w, event, argv, argc);
-    return;
-  }
-  if (*s == '\177')
-  {
-    backspace (w, event, argv, argc);
-    return;
-  }
-  if (*s == '\025')
-  {
-    kill_line (w, event, argv, argc);
-    return;
-  }
-  if (*s == '\030')
-  {
-    kill_line (w, event, argv, argc);
-    return;
-  }
-  if (*s == '\012')
-  {
-    done (w, event, argv, argc);
-    return;
-  }
-  if (*s == '\015')
-  {
-    done (w, event, argv, argc);
-    return;
-  }
+  if (*s == '\010') { backspace (w, event, argv, argc); return; }
+  if (*s == '\177') { backspace (w, event, argv, argc); return; }
+  if (*s == '\025') { kill_line (w, event, argv, argc); return; }
+  if (*s == '\030') { kill_line (w, event, argv, argc); return; }
+  if (*s == '\012') { done (w, event, argv, argc); return; }
+  if (*s == '\015') { done (w, event, argv, argc); return; }
 
   i = j = strlen (typed_passwd);
-  typed_passwd[i] = *s;
-  s[++i] = 0;
+  typed_passwd [i] = *s;
+  s [++i] = 0;
   while (i--)
-    s[i] = '*';
+    s [i] = '*';
   XmTextFieldSetString (passwd_text, s);
   XmTextFieldSetInsertionPosition (passwd_text, j + 1);
 }
@@ -278,16 +249,15 @@ backspace (w, event, argv, argc)
      String *argv;
      Cardinal *argc;
 {
-  char s[sizeof (typed_passwd)];
+  char s [sizeof (typed_passwd)];
   int i = strlen (typed_passwd);
   int j = i;
-
   if (i == 0)
     return;
-  typed_passwd[--i] = 0;
-  s[i] = 0;
+  typed_passwd [--i] = 0;
+  s [i] = 0;
   while (i--)
-    s[i] = '*';
+    s [i] = '*';
   XmTextFieldSetString (passwd_text, s);
   XmTextFieldSetInsertionPosition (passwd_text, j + 1);
 }
@@ -321,14 +291,12 @@ format_into_label (widget, string)
      char *string;
 {
   char *label;
-  char buf[255];
+  char buf [255];
   XmString xm_label = 0;
   XmString new_xm_label;
   Arg av[10];
   int ac = 0;
-
-  XtSetArg (av[ac], XmNlabelString, &xm_label);
-  ac++;
+  XtSetArg (av [ac], XmNlabelString, &xm_label); ac++;
   XtGetValues (widget, av, ac);
   XmStringGetLtoR (xm_label, XmSTRING_DEFAULT_CHARSET, &label);
   if (!strcmp (label, XtName (widget)))
@@ -337,8 +305,7 @@ format_into_label (widget, string)
     sprintf (buf, label, string);
   new_xm_label = XmStringCreate (buf, XmSTRING_DEFAULT_CHARSET);
   ac = 0;
-  XtSetArg (av[ac], XmNlabelString, new_xm_label);
-  ac++;
+  XtSetArg (av [ac], XmNlabelString, new_xm_label); ac++;
   XtSetValues (widget, av, ac);
   XmStringFree (new_xm_label);
   XtFree (label);
@@ -346,7 +313,6 @@ format_into_label (widget, string)
 
 #if __STDC__
 extern void skull (Display *, Window, GC, GC, int, int, int, int);
-
 #endif
 
 static void
@@ -357,7 +323,7 @@ roger (button, client_data, call_data)
   Display *dpy = XtDisplay (button);
   Screen *screen = XtScreen (button);
   Window window = XtWindow (button);
-  Arg av[10];
+  Arg av [10];
   int ac = 0;
   XGCValues gcv;
   Colormap cmap;
@@ -365,21 +331,15 @@ roger (button, client_data, call_data)
   unsigned int fg, bg;
   int x, y, size;
   XWindowAttributes xgwa;
-
   XGetWindowAttributes (dpy, window, &xgwa);
   cmap = xgwa.colormap;
-  if (xgwa.width > xgwa.height)
-    size = xgwa.height;
-  else
-    size = xgwa.width;
-  if (size > 40)
-    size -= 30;
+  if (xgwa.width > xgwa.height) size = xgwa.height;
+  else size = xgwa.width;
+  if (size > 40) size -= 30;
   x = (xgwa.width - size) / 2;
   y = (xgwa.height - size) / 2;
-  XtSetArg (av[ac], XmNforeground, &fg);
-  ac++;
-  XtSetArg (av[ac], XmNbackground, &bg);
-  ac++;
+  XtSetArg (av [ac], XmNforeground, &fg); ac++;
+  XtSetArg (av [ac], XmNbackground, &bg); ac++;
   XtGetValues (button, av, ac);
   /* if it's black on white, swap it cause it looks better (hack hack) */
   if (fg == BlackPixelOfScreen (screen) && bg == WhitePixelOfScreen (screen))
@@ -399,7 +359,6 @@ make_passwd_dialog (parent)
      Widget parent;
 {
   struct passwd *pw;
-
   create_passwd_dialog (parent);
 
   XtAddCallback (passwd_done, XmNactivateCallback, passwd_done_cb, 0);
@@ -414,11 +373,20 @@ make_passwd_dialog (parent)
   XtOverrideTranslations (passwd_text, XtParseTranslationTable (translations));
 #endif
 
+#if (XmVersion >= 1002)
+  /* The focus stuff changed around; this didn't exist in 1.1.5. */
+  XtVaSetValues (passwd_form, XmNinitialFocus, passwd_text, 0);
+#endif
+
+  /* Another random thing necessary in 1.2.1 but not 1.1.5... */
+  XtVaSetValues (roger_label, XmNborderWidth, 2, 0);
+
   pw = getpwuid (getuid ());
   format_into_label (passwd_label3, (pw->pw_name ? pw->pw_name : "???"));
   format_into_label (passwd_label1, screensaver_version);
 }
 
+
 extern void idle_timer ();
 
 static int passwd_idle_timer_tick;
@@ -437,48 +405,41 @@ passwd_idle_timer (junk1, junk2)
 
   idle_timer (junk1, junk2);
 
-  if (passwd_idle_timer_tick == max)   /* first time */
-  {
-    Arg av[10];
-    int ac = 0;
-    XGCValues gcv;
-    unsigned long fg, bg;
-
-    XtSetArg (av[ac], XmNheight, &d);
-    ac++;
-    XtGetValues (passwd_done, av, ac);
-    ac = 0;
-    XtSetArg (av[ac], XmNwidth, &x);
-    ac++;
-    XtSetArg (av[ac], XmNheight, &y);
-    ac++;
-    XtSetArg (av[ac], XmNforeground, &fg);
-    ac++;
-    XtSetArg (av[ac], XmNbackground, &bg);
-    ac++;
-    XtGetValues (passwd_form, av, ac);
-    x -= d;
-    y -= d;
-    d -= 4;
-    gcv.foreground = fg;
-    if (gc)
-      XFreeGC (dpy, gc);
-    gc = XCreateGC (dpy, window, GCForeground, &gcv);
-    s = 360 * 64 / (passwd_idle_timer_tick - 1);
-    ss = 90 * 64;
-    XFillArc (dpy, window, gc, x, y, d, d, 0, 360 * 64);
-    XSetForeground (dpy, gc, bg);
-    x += 1;
-    y += 1;
-    d -= 2;
-  }
+  if (passwd_idle_timer_tick == max)  /* first time */
+    {
+      Arg av [10];
+      int ac = 0;
+      XGCValues gcv;
+      unsigned long fg, bg;
+      XtSetArg (av [ac], XmNheight, &d); ac++;
+      XtGetValues (passwd_done, av, ac);
+      ac = 0;
+      XtSetArg (av [ac], XmNwidth, &x); ac++;
+      XtSetArg (av [ac], XmNheight, &y); ac++;
+      XtSetArg (av [ac], XmNforeground, &fg); ac++;
+      XtSetArg (av [ac], XmNbackground, &bg); ac++;
+      XtGetValues (passwd_form, av, ac);
+      x -= d;
+      y -= d;
+      d -= 4;
+      gcv.foreground = fg;
+      if (gc) XFreeGC (dpy, gc);
+      gc = XCreateGC (dpy, window, GCForeground, &gcv);
+      s = 360*64 / (passwd_idle_timer_tick - 1);
+      ss = 90*64;
+      XFillArc (dpy, window, gc, x, y, d, d, 0, 360*64);
+      XSetForeground (dpy, gc, bg);
+      x += 1;
+      y += 1;
+      d -= 2;
+    }
 
   if (--passwd_idle_timer_tick)
-  {
-    id = XtAppAddTimeOut (app, 1000, (XtTimerCallbackProc) passwd_idle_timer, 0);
-    XFillArc (dpy, window, gc, x, y, d, d, ss, s);
-    ss += s;
-  }
+    {
+      id = XtAppAddTimeOut (app, 1000, passwd_idle_timer, 0);
+      XFillArc (dpy, window, gc, x, y, d, d, ss, s);
+      ss += s;
+    }
 }
 
 extern void pop_up_dialog_box ();
@@ -491,8 +452,7 @@ pop_passwd_dialog (parent)
   Display *dpy = XtDisplay (passwd_dialog);
   Window focus;
   int revert_to;
-
-  typed_passwd[0] = 0;
+  typed_passwd [0] = 0;
   passwd_state = pw_read;
   XmTextFieldSetString (passwd_text, "");
 
@@ -506,72 +466,65 @@ pop_passwd_dialog (parent)
   if (XtWindow (passwd_form))
     XMapRaised (dpy, XtWindow (passwd_dialog));
 #endif
-  pop_up_dialog_box (passwd_dialog, passwd_form, 2);
 
+  pop_up_dialog_box (passwd_dialog, passwd_form, 2);
   XtManageChild (passwd_form);
-  XSetInputFocus (dpy, XtWindow (passwd_dialog), revert_to, CurrentTime);
 
-  /* #### This doesn't work in 1.2.1... Check return code... */
-  XmProcessTraversal (passwd_text, 0);
+#if (XmVersion < 1002)
+  /* The focus stuff changed around; this causes problems in 1.2.1
+     but is necessary in 1.1.5. */
+  XmProcessTraversal (passwd_text, XmTRAVERSE_CURRENT);
+#endif
 
   passwd_idle_timer_tick = passwd_timeout / 1000;
-  id = XtAppAddTimeOut (app, 1000, (XtTimerCallbackProc) passwd_idle_timer, 0);
+  id = XtAppAddTimeOut (app, 1000, passwd_idle_timer, 0);
 
-  XGrabServer (dpy);           /* ############ DANGER! */
 
-  while (passwd_state == pw_read)
-  {
-    XEvent event;
+  XGrabServer (dpy);                           /* ############ DANGER! */
 
-    XtAppNextEvent (app, &event);
-    /* wait for timer event */
-    if (event.xany.type == 0 && passwd_idle_timer_tick == 0)
-      passwd_state = pw_time;
-    XtDispatchEvent (&event);
-  }
+  while (passwd_state == pw_read)
+    {
+      XEvent event;
+      XtAppNextEvent (app, &event);
+      /* wait for timer event */
+      if (event.xany.type == 0 && passwd_idle_timer_tick == 0)
+       passwd_state = pw_time;
+      XtDispatchEvent (&event);
+    }
   XUngrabServer (dpy);
-  XSync (dpy, False);          /* ###### (danger over) */
+  XSync (dpy, False);                          /* ###### (danger over) */
 
   if (passwd_state != pw_time)
     XtRemoveTimeOut (id);
 
   if (passwd_state != pw_ok)
-  {
-    char *lose;
-
-    switch (passwd_state)
     {
-    case pw_time:
-      lose = "Timed out!";
-      break;
-    case pw_fail:
-      lose = "Sorry!";
-      break;
-    case pw_cancel:
-      lose = 0;
-      break;
-    default:
-      abort ();
+      char *lose;
+      switch (passwd_state)
+       {
+       case pw_time: lose = "Timed out!"; break;
+       case pw_fail: lose = "Sorry!"; break;
+       case pw_cancel: lose = 0; break;
+       default: abort ();
+       }
+      XmProcessTraversal (passwd_cancel, 0); /* turn off I-beam */
+      if (lose)
+       {
+         XmTextFieldSetString (passwd_text, lose);
+         XmTextFieldSetInsertionPosition (passwd_text, strlen (lose) + 1);
+         passwd_idle_timer_tick = 1;
+         id = XtAppAddTimeOut (app, 3000, passwd_idle_timer, 0);
+         while (1)
+           {
+             XEvent event;
+             XtAppNextEvent (app, &event);
+             if (event.xany.type == 0 &&       /* wait for timer event */
+                 passwd_idle_timer_tick == 0)
+               break;
+             XtDispatchEvent (&event);
+           }
+       }
     }
-    XmProcessTraversal (passwd_cancel, 0);     /* turn off I-beam */
-    if (lose)
-    {
-      XmTextFieldSetString (passwd_text, lose);
-      XmTextFieldSetInsertionPosition (passwd_text, strlen (lose) + 1);
-      passwd_idle_timer_tick = 1;
-      id = XtAppAddTimeOut (app, 3000, (XtTimerCallbackProc) passwd_idle_timer, 0);
-      while (1)
-      {
-       XEvent event;
-
-       XtAppNextEvent (app, &event);
-       if (event.xany.type == 0 &&     /* wait for timer event */
-           passwd_idle_timer_tick == 0)
-         break;
-       XtDispatchEvent (&event);
-      }
-    }
-  }
   memset (typed_passwd, 0, sizeof (typed_passwd));
   XmTextFieldSetString (passwd_text, "");
   XtSetKeyboardFocus (parent, None);
@@ -584,7 +537,6 @@ pop_passwd_dialog (parent)
 #endif
   {
     int (*old_handler) ();
-
     old_handler = XSetErrorHandler (BadWindow_ehandler);
     /* I don't understand why this doesn't refocus on the old selected
        window when MWM is running in click-to-type mode.  The value of
@@ -602,16 +554,15 @@ unlock_p (parent)
      Widget parent;
 {
   static Bool initted = False;
-
-  if (!initted)
-  {
+  if (! initted)
+    {
 #ifndef VERIFY_CALLBACK_WORKS
-    XtAppAddActions (app, actions, XtNumber (actions));
+      XtAppAddActions (app, actions, XtNumber (actions));
 #endif
-    passwd_dialog = 0;
-    initted = True;
-  }
-  if (!passwd_dialog)
+      passwd_dialog = 0;
+      initted = True;
+    }
+  if (! passwd_dialog)
     make_passwd_dialog (parent);
   return pop_passwd_dialog (parent);
 }