/*
 * $Source: /mit/jik/sipbsrc/src/xscreensaver/RCS/util.c,v $
 * $Author: jik $
 *
 * This file is part of xscreensaver.  It contains a whole bunch of
 * utility procedures.
 *
 * Author: Jonathan Kamens, MIT Project Athena and
 *                          MIT Student Information Processing Board
 *
 * Copyright (c) 1989 by Jonathan Kamens.  This code may be
 * distributed freely as long as this notice is kept intact in its
 * entirety and every effort is made to send all corrections and
 * improvements to the code back to the author.  Also, don't try to
 * make any money off of it or pretend that you wrote it.
 */

#ifndef lint
static char rcsid_util_c[] = "$Header: /mit/jik/sipbsrc/src/xscreensaver/RCS/util.c,v 1.14 1992/04/28 20:28:54 jik Exp $";
#endif

#include "xsaver.h"
#include <X11/Xaw/Form.h>
#include <pwd.h>
#include "globals.h"


extern char *getenv(), *malloc();

char *get_user();







/* Returns the width of the widget passed in as an argument */
Dimension widget_width(w)
Widget w;
{
     Arg arglist[1];
     Dimension width;
     
     XtSetArg(arglist[0], XtNwidth, &width);
     XtGetValues(w, arglist, 1);

     return(width);
}




char *widget_string(w)
Widget w;
{
     Arg arglist[1];
     String label;
     
     XtSetArg(arglist[0], XtNlabel, &label);
     XtGetValues(w, arglist, 1);

     return(label);
}





/* Returns a blank cursor */
Cursor blank_cursor()
{
     static Cursor blank = (Cursor) NULL;
     Pixmap foo;
     XColor baz;

     if (! blank) {
	  foo = XCreatePixmap(dpy, RootWindow(dpy, screen), 1, 1, 1);
	  baz.red = baz.blue = baz.green = 0;
	  blank = XCreatePixmapCursor(dpy, foo, foo, &baz, &baz, 1, 1);
     }
     return(blank);
}





char *user_string(str)
char *str;
{
     static char buf[100];
     static int initialized = 0;

     if (! initialized) {
	  sprintf(buf, str, get_user());
     }
     return(buf);
}


char *time_string(str, force)
ForceType force;
char *str;
{
     struct tm *local;
     static char buf[100];
     char new[100];
     int newf = 0;
     
     local = localtime(&xtimes.current);
     sprintf(new, str, local->tm_hour, local->tm_min);
     if (strcmp(new, buf)) {
	  strcpy(buf, new);
	  newf++;
     }
     if (newf || (force == Force))
	  return(buf);
     else
	  return ((char *) NULL);
}     



char *elapsed_string(str, force)
ForceType force;
char *str;
{
     static char buf[100];
     int hours, minutes;
     char new[100];
     int newf = 0;

     int elapsed_sec = xtimes.current - xtimes.start;
     hours = elapsed_sec / 3600;
     minutes = (elapsed_sec - 3600 * hours) / 60;
     sprintf(new, str, hours, minutes);
     if (strcmp(new, buf)) {
	  strcpy(buf, new);
	  newf++;
     }
     if (newf || (force == Force))
	  return(buf);
     else
	  return((char *) NULL);
}


char *timeout_string(str, force)
ForceType force;
char *str;
{
     static char buf[100];
     int hours, minutes;
     char new[100];
     int newf = 0;
     
     hours = defs.timeout / 60;
     minutes = defs.timeout - 60 * hours;
     sprintf(new, str, hours, (hours == 1 ? "hour" : "hours"), 
	     minutes, (minutes == 1 ? "minute" : "minutes"));
     if (strcmp(new, buf)) {
	  strcpy(buf, new);
	  newf++;
     }

     if (newf || (force == Force))
	  return(buf);
     else
	  return((char *) NULL);
}


char *timeleft_string(str, force)
ForceType force;
char *str;
{
     static char buf[100];
     int hours, minutes;
     int elapsed_sec = xtimes.current - xtimes.start;
     char new[100];
     int newf = 0;

     /* Note that the + 59 in both equations is so that the counter will
      * always display the minute it is counting down, instead of the
      * minute before it.  I use + 59 rather than + 60 because
      * otherwise, when the widget is first mapped it will display one
      * number above the timeout value.  This is the same reason we
      * add 1 to the value of the current time when we activate the clock.
      */
     hours = (defs.timeout * 60 - elapsed_sec + 59) / 3600;
     minutes = (defs.timeout * 60 - elapsed_sec + 59 - 3600 * hours) / 60;
     sprintf(new, str, hours, (hours == 1 ? "hour" : "hours"),
	     minutes, (minutes == 1 ? "minute" : "minutes"));
     if (strcmp(new, buf)) {
	  strcpy(buf, new);
	  newf++;
     }

     if (newf || (force == Force))
	  return(buf);
     else
	  return((char *) NULL);
}





char *get_user()
{
     static char user[MAXUSERNAME];
     struct passwd *pwent;
     static char *ptr = (char *) NULL;
     
     if (ptr)
	  return(ptr);

#if 0
     /*
      * I'm disabling this because on a system with shadow passwords,
      * if the user can get the program to use a different username by
      * changing the USER environment variable, than he/she can get
      * another user's encrypted password string by coredumping the
      * program after xscreensaver has read the encrypted password out
      * of the shadow password file.
      */
     ptr = getenv("USER");
#endif

     if (ptr) {
	  ptr = strcpy(user, ptr);
	  return(user);
     }

     pwent = getpwuid(getuid());

     if (pwent) {
	  ptr = strcpy(user, pwent->pw_name);
	  return(ptr);
     }

     *user = '\0';
     
     return(user);
}





char *my_malloc(n, msg)
int n;
char *msg;
{
     char *temp;

     temp = malloc(n);
     if (! temp) {
	  fprintf(stderr, "%s: error malloc'ing for %s\n", whoami, msg);
	  clean_up_and_die(1);
     }
     return(temp);
}

		  
