v03i041: Yet another screen saver, Part01/03

Mike Wexler mikew at wyse.wyse.com
Sat Mar 11 04:39:55 AEST 1989


Submitted-by: jik at pit-manager.mit.edu (Jonathan I. Kamens)
Posting-number: Volume 3, Issue 41
Archive-name: xsaver/part01

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 3)."
# Contents:  README Imakefile List.c PATCHLEVEL savescreen.c
# Wrapped by mikew at wyse on Fri Mar 10 10:36:39 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(2250 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X# $Source: /u1/uus/src/xscreensaver/RCS/README,v $
X# $Author: jik $
X# $Header: README,v 1.4 89/02/26 03:47:32 jik Exp $
X#
X# Isn't RCS fun?
X#
X
XThis is the source code and all supplementary files for the
Xxscreensaver program.  You should be able to compile the code right
Xout of the box after modifying only the Makefile to fit your
Xparticular setup.  However, if you want the xscreensaver to have a
Xmandatory maximum timeout period, you'll need to #define the symbol
XMAXTIMEOUT in xscreensaver.h to contain a string which represents the
Xmaximum timeout in minutes, and you'll also need to #define TIMEOUT to
Xbe a string representing the default timeout length.
X
XIf you use some strange variant of unix that doesn't use 13-character
Xencrypted passwords, you'll need to change PASSWDLENGTH in
Xxscreensaver.h to reflect the correct length of an encrypted password
Xstring in the /etc/passwd file.
X
XIf you allow usernames longer than 15 characters, you'll need to
Xchange MAXUSERNAME.
X
XIf your C library uses putenv rather than setenv, you should define
Xsetenv to putenv.  It's undef'd in the stuff I ship out because my
Xlibrary uses setenv.
X
XYou probably shouldn't fiddle with anything else in xscreensaver.h
Xwithout taking a look at where the stuff is used first.
X
XYou MUST link xscreensaver against the most up-to-date X11R3 X toolkit
Xsources (fix8 from the X consortium, at the time I wrote this
Xparagraph), or it will not work.  In addition, you must apply the
Xpatch in the file toolkit_patch to your toolkit library sources and
Xrebuild them.  This file contains some patches that, while not yet
Xreleased by the X Consortium, fix bugs that prevent the xscreensaver
Xfrom working properly.  They will probably be released by the
XConsortium soon -- trust me, they were written by one of the toolkit's
Xauthors :-) (not me, mind you)
X
XAny questions, suggested improvements, bugs, bug-fixes, etc. should be
Xsent to Jonathan Kamens (that's me):
X	Internet: 	jik at Athena.MIT.EDU
X                        jik at pit-manager.MIT.EDU
X	BITnet:		s20020 at MITVMA
X	UUCP:		{where-ever}!{mit-eddie,bloom-beacon}!athena!jik
X
XHave fun, and make sure to send me your comments, suggestions and
Xfixes!
X
X	Jonathan Kamens
X	MIT Student Information Processing Board
X	MIT Project Athena
END_OF_FILE
if test 2250 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'Imakefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Imakefile'\"
else
echo shar: Extracting \"'Imakefile'\" \(1207 characters\)
sed "s/^X//" >'Imakefile' <<'END_OF_FILE'
XBITMAPDIR       =       /global/bitmaps
XICONBITMAP	=	SigmaPiBeta
XFLOATBITMAP	=	yinyang
XICONPIXMAP	=	SigmaPiBeta
XBITMAPS		=	$(ICONBITMAP) $(FLOATBITMAP) $(ICONPIXMAP)
XSYS_LIBRARIES   = $(XAWLIB) $(XTOOLLIB) $(XMULIB) $(XLIB) -lm
XLOCAL_LIBRARIES = 
XSRCS 		=	main.c scaling.c List.c password.c savescreen.c\
X			menuIcon.c PromptBox.c util.c
XOBJS		=	main.o scaling.o List.o password.o savescreen.o\
X			menuIcon.o PromptBox.o util.o
XTARGET=xsaver
X
XAllTarget($(TARGET) Xsaver.ad xsaver.man)
XComplexProgramTarget($(TARGET))
XNormalLintTarget($(SRCS))
XInstallManPage(xsaver.man,$(MANDIR))
XInstallAppDefaults(Xsaver)
XInstallMultiple($(BITMAPS),$(BITMAPDIR))
X
XXsaver.ad: Xsaver.sed
X	sed -e 's|$$BITMAPDIR|$(BITMAPDIR)|g'\
X		-e 's|$$ICONPIXMAP|$(ICONPIXMAP)|g'\
X		-e 's|$$ICONBITMAP|$(ICONBITMAP)|g'\
X		-e 's|$$FLOATBITMAP|$(FLOATBITMAP)|g'\
X		Xsaver.sed > $@
X
Xxsaver.man: xsaver.man.s
X	sed -e 's|$$TARGET|$(TARGET)|g'\
X		-e 's|$$APPDIR|$(APPDIR)|g'\
X		-e 's|$$APPTARGET|$(APPTARGET)|g'\
X		-e 's|$$BITMAPDIR|$(BITMAPDIR)|g'\
X		-e 's|$$ICONPIXMAP|$(ICONPIXMAP)|g'\
X		-e 's|$$ICONBITMAP|$(ICONBITMAP)|g'\
X		-e 's|$$FLOATBITMAP|$(FLOATBITMAP)|g'\
X		xsaver.man.s > xsaver.man
X		
Xclean::
X	rm -f xsaver.man Xsaver.ad $(OBJS)
END_OF_FILE
if test 1207 -ne `wc -c <'Imakefile'`; then
    echo shar: \"'Imakefile'\" unpacked with wrong size!
fi
# end of 'Imakefile'
fi
if test -f 'List.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'List.c'\"
else
echo shar: Extracting \"'List.c'\" \(28545 characters\)
sed "s/^X//" >'List.c' <<'END_OF_FILE'
X/*
X * $Source: /mit/sipbsrc/uus/src/xscreensaver/RCS/List.c,v $
X * $Author: jik $
X *
X * This file is part of xscreensaver.  It contains a slightly modified
X * version of the Project Athena list widget which allows the widget
X * to use motion events to set the list, thus allowing the list to act
X * as a menu whose highlighting follows the mouse.
X *
X * Author: Jonathan Kamens, MIT Project Athena and
X *                          MIT Student Information Processing Board
X *         (Well, not really, I just changed a few lines of code.  The
X *          real copyright and stuff is found below.)
X */
X
X#if ( !defined(lint) && !defined(SABER))
X  static char Xrcs_id[] = "$XConsortium: List.c,v 1.11 88/10/23 14:44:33 swick Exp $";
X  static char rcsid_module_c[] = "$oHeader: List.c,v 1.4 88/08/30 16:36:03 kit Exp $";
X  static char rcsid_List_c[] = "$Header: List.c,v 1.4 89/02/16 22:53:31 jik Exp $";
X#endif
X
X/*  This is the List widget, it is useful to display a list, without the
X *  overhead of having a widget for each item in the list.  It allows 
X *  the user to select an item in a list and notifies the application through
X *  a callback function.
X *
X *	Created: 	8/13/88
X *	By:		Chris D. Peterson
X *                      MIT - Project Athena
X *
X *      $Author: jik $
X *	
X */
X
X/***********************************************************
XCopyright 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
Xand the Massachusetts Institute of Technology, Cambridge, Massachusetts.
X
X                        All Rights Reserved
X
XPermission to use, copy, modify, and distribute this software and its 
Xdocumentation for any purpose and without fee is hereby granted, 
Xprovided that the above copyright notice appear in all copies and that
Xboth that copyright notice and this permission notice appear in 
Xsupporting documentation, and that the names of Digital or MIT not be
Xused in advertising or publicity pertaining to distribution of the
Xsoftware without specific, written prior permission.  
X
XDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
XDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
XSOFTWARE.
X
X******************************************************************/
X
X/*
X * List.c - List widget
X *
X */
X
X#include <X11/IntrinsicP.h>
X#include <stdio.h>
X#include <X11/Xos.h>
X#include <ctype.h>
X#include <X11/StringDefs.h>
X#include <X11/ListP.h>
X
Xchar * malloc();
X
X/* 
X * Default Translation table.
X */
X
Xstatic char defaultTranslations[] =  
X  "<Btn1Down>:   Set()\n\
X   <Btn1Up>:     Notify()";
X
X/****************************************************************
X *
X * Full class record constant
X *
X ****************************************************************/
X
X/* Private Data */
X
X#define offset(field) XtOffset(ListWidget, field)
X
Xstatic XtResource resources[] = {
X    {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
X	offset(list.foreground), XtRString, "XtDefaultForeground"},
X    {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
X       offset(simple.cursor), XtRString, "left_ptr"},
X    {XtNfont,  XtCFont, XtRFontStruct, sizeof(XFontStruct *),
X	offset(list.font),XtRString, "XtDefaultFont"},
X    {XtNlist, XtCList, XtRPointer, sizeof(char **),
X       offset(list.list), XtRString, NULL},
X    {XtNdefaultColumns, XtCColumns, XtRInt,  sizeof(int),
X	offset(list.default_cols), XtRImmediate, (caddr_t)2},
X    {XtNlongest, XtCLongest, XtRInt,  sizeof(int),
X	offset(list.longest), XtRImmediate, (caddr_t)0},
X    {XtNnumberStrings, XtCNumberStrings, XtRInt,  sizeof(int),
X	offset(list.nitems), XtRImmediate, (caddr_t)0},
X    {XtNpasteBuffer, XtCBoolean, XtRBoolean,  sizeof(Boolean),
X	offset(list.paste), XtRString, (caddr_t) "False"},
X    {XtNforceColumns, XtCColumns, XtRBoolean,  sizeof(Boolean),
X	offset(list.force_cols), XtRString, (caddr_t) "False"},
X    {XtNverticalList, XtCBoolean, XtRBoolean,  sizeof(Boolean),
X	offset(list.vertical_cols), XtRString, (caddr_t) "False"},
X    {XtNinternalWidth, XtCWidth, XtRDimension,  sizeof(Dimension),
X	offset(list.internal_width), XtRImmediate, (caddr_t)4},
X    {XtNinternalHeight, XtCHeight, XtRDimension, sizeof(Dimension),
X	offset(list.internal_height), XtRImmediate, (caddr_t)2},
X    {XtNcolumnSpacing, XtCSpacing, XtRDimension,  sizeof(Dimension),
X	offset(list.column_space), XtRImmediate, (caddr_t)6},
X    {XtNrowSpacing, XtCSpacing, XtRDimension,  sizeof(Dimension),
X	offset(list.row_space), XtRImmediate, (caddr_t)2},
X    {XtNcallback, XtCCallback, XtRCallback, sizeof(caddr_t),
X        offset(list.callback), XtRCallback, NULL},
X};
X
Xstatic void Initialize();
Xstatic void ChangeSize();
Xstatic void Resize();
Xstatic void Redisplay();
Xstatic Boolean Layout();
Xstatic XtGeometryResult PreferredGeom();
Xstatic Boolean SetValues();
Xstatic void Notify(), Set(), Unset();
Xstatic int old_highlighted_item = -1;
X
Xstatic XtActionsRec actions[] = {
X      {"Notify",         Notify},
X      {"Set",            Set},
X      {"Unset",          Unset},
X      {NULL,NULL}
X};
X
XListClassRec listClassRec = {
X  {
X/* core_class fields */	
X#define superclass		(&simpleClassRec)
X    /* superclass	  	*/	(WidgetClass) superclass,
X    /* class_name	  	*/	"List",
X    /* widget_size	  	*/	sizeof(ListRec),
X    /* class_initialize   	*/	NULL,
X    /* class_part_initialize	*/	NULL,
X    /* class_inited       	*/	FALSE,
X    /* initialize	  	*/	Initialize,
X    /* initialize_hook		*/	NULL,
X    /* realize		  	*/	XtInheritRealize,
X    /* actions		  	*/	actions,
X    /* num_actions	  	*/	XtNumber(actions),
X    /* resources	  	*/	resources,
X    /* num_resources	  	*/	XtNumber(resources),
X    /* xrm_class	  	*/	NULLQUARK,
X    /* compress_motion	  	*/	FALSE,
X    /* compress_exposure  	*/	FALSE,
X    /* compress_enterleave	*/	TRUE,
X    /* visible_interest	  	*/	FALSE,
X    /* destroy		  	*/	NULL,
X    /* resize		  	*/	Resize,
X    /* expose		  	*/	Redisplay,
X    /* set_values	  	*/	SetValues,
X    /* set_values_hook		*/	NULL,
X    /* set_values_almost	*/	XtInheritSetValuesAlmost,
X    /* get_values_hook		*/	NULL,
X    /* accept_focus	 	*/	NULL,
X    /* version			*/	XtVersion,
X    /* callback_private   	*/	NULL,
X    /* tm_table		   	*/	defaultTranslations,
X   /* query_geometry		*/      PreferredGeom,
X  }
X};
X
XWidgetClass listWidgetClass = (WidgetClass)&listClassRec;
X
X/****************************************************************
X *
X * Private Procedures
X *
X ****************************************************************/
X
Xstatic void GetGCs(w)
XWidget w;
X{
X    XGCValues	values;
X    ListWidget lw = (ListWidget) w;    
X
X    values.foreground	= lw->list.foreground;
X    values.font		= lw->list.font->fid;
X
X    lw->list.normgc = XtGetGC(w, (unsigned) GCForeground | GCFont,
X				 &values);
X
X    values.foreground	= lw->core.background_pixel;
X
X    lw->list.revgc = XtGetGC(w, (unsigned) GCForeground | GCFont,
X				 &values);
X
X    values.foreground = lw->list.foreground;
X    values.tile       = XtGrayPixmap(XtScreen(w));
X    values.fill_style = FillTiled;
X
X    lw->list.graygc = XtGetGC(w, (unsigned) GCForeground | GCFont |
X			      GCTile | GCFillStyle, &values);
X}
X
X/*	Function Name: ResetList
X *	Description: Resets the new list when important things change.
X *	Arguments: w - the widget.
X *                 changex, changey - allow the height or width to change?
X *	Returns: none.
X */
X
Xstatic void
XResetList(w, changex, changey)
XWidget w;
XBoolean changex, changey;
X{
X    ListWidget lw = (ListWidget) w;
X    int width = w->core.width;
X    int height = w->core.height;
X
X    if (lw->list.nitems == 0)	/* Get number of items. */
X        while (lw->list.list[lw->list.nitems] != NULL)
X	    lw->list.nitems++;
X
X    if (lw->list.longest == 0) { /* Get column width. */
X        int i, len, max;
X        for ( i = 0, max = 0; i < lw->list.nitems; i++) {
X	    len = XTextWidth(lw->list.font, lw->list.list[i],
X			     strlen(lw->list.list[i]));
X	    if (len > max)
X	        max = len;
X	}
X        lw->list.col_width = max;
X    }
X    else 
X        lw->list.col_width = lw->list.longest;
X    lw->list.col_width += lw->list.column_space;
X
X    if (Layout(w, changex, changey, &width, &height))
X      ChangeSize(w, width, height);
X}
X
X/*	Function Name: ChangeSize.
X *	Description: Laysout the widget.
X *	Arguments: w - the widget to try change the size of.
X *	Returns: none.
X */
X
Xstatic void
XChangeSize(w, width, height)
XWidget w;
Xint width, height;
X{
X    int w_ret, h_ret;
X
X    (void) Layout(w, FALSE, FALSE, &width, &height);
X
X    switch ( XtMakeResizeRequest(w, width, height, &w_ret, &h_ret) ) {
X    case XtGeometryYes:
X    case XtGeometryNo:
X        break;
X    case XtGeometryAlmost:
X        if (Layout(w, FALSE, FALSE, &width, &height)) {
X            XtWarning("Size Changed when it shouldn't have...");
X	    XtWarning("when initializing the List Widget");
X	}
X	(void) XtMakeResizeRequest(w, w_ret, h_ret, NULL, NULL);
X	break;
X    default:
X	XtWarning("Unknown geometry return in List Widget");
X	break;
X    }
X}
X
X/*	Function Name: Initialize
X *	Description: Function that initilizes the widget instance.
X *	Arguments: junk - NOT USED.
X *                 new  - the new widget.
X *	Returns: none
X */
X
X/* ARGSUSED */
Xstatic void 
XInitialize(junk, new)
XWidget junk, new;
X{
X    ListWidget lw = (ListWidget) new;
X
X/* 
X * Initialize all private resources.
X */
X
X    GetGCs(new);
X
X    /* Set row height. */
X    lw->list.row_height = lw->list.font->max_bounds.ascent
X			+ lw->list.font->max_bounds.descent
X			+ lw->list.row_space;
X
X    ResetList(new, (new->core.width == 0), (new->core.height == 0));
X
X/*
X * Default to the name of the widget as the entire list.
X */
X
X    if (lw->list.list == NULL) {
X      lw->list.list = &(lw->core.name);
X      lw->list.nitems = 1;
X    }
X
X    lw->list.is_highlighted = NO_HIGHLIGHT;
X    lw->list.highlight = NO_HIGHLIGHT;
X
X} /* Initialize */
X
X/*	Function Name: CvtToItem
X *	Description: Converts Xcoord to item number of item containing that
X *                   point.
X *	Arguments: w - the list widget.
X *                 xloc, yloc - x location, and y location.
X *	Returns: the item number.
X */
X
Xstatic int
XCvtToItem(w, xloc, yloc, item)
XWidget w;
Xint xloc, yloc;
Xint *item;
X{
X    int one, another;
X    ListWidget lw = (ListWidget) w;
X    int ret_val = OKAY;
X
X    if (lw->list.vertical_cols) {
X        one = lw->list.nrows * ((xloc - (int) lw->list.internal_width)
X	    / lw->list.col_width);
X        another = (yloc - (int) lw->list.internal_height) 
X	        / lw->list.row_height;
X	 /* If out of range, return minimum possible value. */
X	if (another >= lw->list.nrows) {
X	    another = lw->list.nrows - 1;
X	    ret_val = OUT_OF_RANGE;
X	}
X    }
X    else {
X        one = (lw->list.ncols * ((yloc - (int) lw->list.internal_height) 
X              / lw->list.row_height)) ;
X	/* If in right margin handle things right. */
X        another = (xloc - (int) lw->list.internal_width) / lw->list.col_width;
X	if (another >= lw->list.ncols) {
X	    another = lw->list.ncols - 1; 
X	    ret_val = OUT_OF_RANGE;
X	}
X    }  
X    if ((xloc < 0) || (yloc < 0))
X        ret_val = OUT_OF_RANGE;
X    if (one < 0) one = 0;
X    if (another < 0) another = 0;
X    *item = one + another;
X    if (*item >= lw->list.nitems) return(OUT_OF_RANGE);
X    return(ret_val);
X}
X
X/*	Function Name: FindCornerItems.
X *	Description: Find the corners of the rectangle in item space.
X *	Arguments: w - the list widget.
X *                 event - the event structure that has the rectangle it it.
X *                 ul_ret, lr_ret - the corners ** RETURNED **.
X *	Returns: none.
X */
X
XFindCornerItems(w, event, ul_ret, lr_ret)
XWidget w;
XXEvent * event;
Xint *ul_ret, *lr_ret;
X{
X    int xloc, yloc;
X
X    xloc = event->xexpose.x;
X    yloc = event->xexpose.y;
X    CvtToItem(w, xloc, yloc, ul_ret);
X    xloc += event->xexpose.width;
X    yloc += event->xexpose.height;
X    CvtToItem(w, xloc, yloc, lr_ret);
X}
X
X/*	Function Name: ItemInRectangle
X *	Description: returns TRUE if the item passed is in the given rectangle.
X *	Arguments: w - the list widget.
X *                 ul, lr - corners of the rectangle in item space.
X *                 item - item to check.
X *	Returns: TRUE if the item passed is in the given rectangle.
X */
X    
XItemInRectangle(w, ul, lr, item)
XWidget w;
Xint ul, lr, item;
X{
X    ListWidget lw = (ListWidget) w;
X    register int mod_item;
X    int things;
X    
X    if (item < ul || item > lr) 
X        return(FALSE);
X    if (lw->list.vertical_cols)
X        things = lw->list.nrows;
X    else
X        things = lw->list.ncols;
X
X    mod_item = item % things;
X    if ( (mod_item >= ul % things) && (mod_item <= lr % things ) )
X        return(TRUE);
X    return(FALSE);
X}
X
X/*	Function Name: HighlightBackground
X *	Description: paints the color of the background for the given item.
X *	Arguments: w - the widget.
X *                 x, y - ul corner of the area item occupies.
X *                 item - the item we are dealing with.
X *                 gc - the gc that is used to paint this rectangle
X *	Returns: 
X */
X
XHighlightBackground(w, x, y, item, gc)
XWidget w;
Xint x, y, item;
XGC gc;
X{
X    ListWidget lw = (ListWidget) w;
X    int hl_x, hl_y, width, height;
X
X    hl_x = x - lw->list.column_space/2;
X    width =lw->list.col_width + lw->list.column_space;
X    hl_y = y - lw->list.row_space/2;
X    height = lw->list.row_height + lw->list.row_space;
X
X    XFillRectangle(XtDisplay(w), XtWindow(w), gc, hl_x, hl_y, width, height);
X}
X
X/*	Function Name: PaintItemName
X *	Description: paints the name of the item in the appropriate location.
X *	Arguments: w - the list widget.
X *                 item - the item to draw.
X *	Returns: none.
X */
X
XPaintItemName(w, item)
XWidget w;
Xint item;
X{
X    char * str;
X    GC gc;
X    int x, y, str_y;
X    ListWidget lw = (ListWidget) w;
X   
X    if (lw->list.vertical_cols) {
X	x = lw->list.col_width * (item / lw->list.nrows)
X	  + lw->list.internal_width;
X        y = lw->list.row_height * (item % lw->list.nrows)
X	  + lw->list.internal_height;
X    }
X    else {
X        x = lw->list.col_width * (item % lw->list.ncols)
X	  + lw->list.internal_width;
X        y = lw->list.row_height * (item / lw->list.ncols)
X	  + lw->list.internal_height;
X    }
X
X    str_y = y + lw->list.font->max_bounds.ascent;
X
X    if (item == lw->list.is_highlighted) {
X        if (item == lw->list.highlight) {
X            gc = lw->list.revgc;
X	    HighlightBackground(w, x, y, item, lw->list.normgc);
X	}
X        else {
X	    if (XtIsSensitive(w)) 
X	        gc = lw->list.normgc;
X	    else
X	        gc = lw->list.graygc;
X	    HighlightBackground(w, x, y, item, lw->list.revgc);
X	    lw->list.is_highlighted = NO_HIGHLIGHT;
X        }
X    }
X    else {
X        if (item == lw->list.highlight) {
X            gc = lw->list.revgc;
X	    HighlightBackground(w, x, y, item, lw->list.normgc);
X	    lw->list.is_highlighted = item;
X	}
X	else {
X	    if (XtIsSensitive(w)) 
X	        gc = lw->list.normgc;
X	    else
X	        gc = lw->list.graygc;
X	}
X    }
X
X    str =  lw->list.list[item];	/* draw it */
X    XDrawString(XtDisplay(w), XtWindow(w), gc, x, str_y, str, strlen(str));
X}
X    
X/*	Function Name: Redisplay
X *	Description: Repaints the widget window on expose events.
X *	Arguments: w - the list widget.
X *                 event - the expose event for this repaint.
X *                 junk - NOT USED.
X *	Returns: 
X */
X
X/* ARGSUSED */
Xstatic void 
XRedisplay(w, event, junk)
XWidget w;
XXEvent *event;
XRegion junk;
X{
X    int item;			/* an item to work with. */
X    int ul_item, lr_item;       /* corners of items we need to paint. */
X    ListWidget lw = (ListWidget) w;
X
X    if (event == NULL) {	/* repaint all. */
X        ul_item = 0;
X	lr_item = lw->list.nrows * lw->list.ncols - 1;
X	XClearWindow(XtDisplay(w), XtWindow(w));
X    }
X    else
X        FindCornerItems(w, event, &ul_item, &lr_item);
X    
X    for (item = ul_item; (item <= lr_item && item < lw->list.nitems) ; item++)
X      if (ItemInRectangle(w, ul_item, lr_item, item))
X	PaintItemName(w, item);
X}
X
X/*	Function Name: PreferredGeom
X *	Description: This tells the parent what size we would like to be
X *                   given certain constraints.
X *	Arguments: w - the widget.
X *                 intended - what the parent intends to do with us.
X *                 requested - what we want to happen.
X *	Returns: none.
X */
X
Xstatic XtGeometryResult 
XPreferredGeom(w, intended, requested)
XWidget w;
XXtWidgetGeometry *intended, *requested;
X{
X    int width_req, height_req, new_width, new_height;
X    Boolean change;
X    
X    width_req = intended->request_mode & CWWidth;
X    height_req = intended->request_mode & CWHeight;
X    if (width_req)
X      new_width = intended->width;
X    else
X      new_width = w->core.width;
X
X    if (height_req)
X      new_height = intended->height;
X    else
X      new_height = w->core.height;
X
X    requested->request_mode = 0;
X    
X/*
X * We only care about our height and width.
X */
X
X    if ( !width_req && !height_req) {
X      return(XtGeometryYes);
X    }
X    
X    change = Layout(w, !width_req, !height_req, &new_width, &new_height);
X
X    requested->request_mode |= CWWidth;
X    requested->width = new_width;
X    requested->request_mode |= CWHeight;
X    requested->height = new_height;
X
X    if (change)
X        return(XtGeometryAlmost);
X    return(XtGeometryYes);
X}
X
X/*	Function Name: Resize
X *	Description: resizes the widget, by changing the number of rows and
X *                   columns.
X *	Arguments: w - the widget.
X *	Returns: none.
X */
X
Xstatic void
XResize(w)
XWidget w;
X{
X  int width, height;
X
X  width = w->core.width;
X  height = w->core.height;
X
X  if (Layout(w, FALSE, FALSE, &width, &height))
X    XtWarning(
X      "Size Changed when it shouldn't have in Resizing the List Widget");
X}
X
X/*	Function Name: Layout
X *	Description: lays out the item in the list.
X *	Arguments: w - the widget.
X *                 xfree, yfree - TRUE if we are free to resize the widget in
X *                                this direction.
X *                 width, height - the is the current width and height that 
X *                                 we are going to layout the list widget to,
X *                                 depending on xfree and yfree of course.
X *                               
X *	Returns: TRUE if width or height have been changed.
X */
X
Xstatic Boolean
XLayout(w, xfree, yfree, width, height)
XWidget w;
XBoolean xfree, yfree;
Xint *width, *height;
X{
X    ListWidget lw = (ListWidget) w;
X    Boolean change = FALSE;
X    
X/* 
X * If force columns is set then always use number of columns specified
X * by default_cols.
X */
X
X    if (lw->list.force_cols) {
X        lw->list.ncols = lw->list.default_cols;
X	if (lw->list.ncols <= 0) lw->list.ncols = 1;
X	/* 12/3 = 4 and 10/3 = 4, but 9/3 = 3 */
X	lw->list.nrows = ( ( lw->list.nitems - 1) / lw->list.ncols) + 1 ;
X	if (xfree) {		/* If allowed resize width. */
X	    *width = lw->list.ncols * lw->list.col_width 
X	           + 2 * lw->list.internal_width;
X	    change = TRUE;
X	}
X	if (yfree) {		/* If allowed resize height. */
X	    *height = (lw->list.nrows * lw->list.row_height)
X                    + 2 * lw->list.internal_height;
X	    change = TRUE;
X	}
X	return(change);
X    }
X
X/*
X * If both width and height are free to change the use default_cols
X * to determine the number columns and set new width and height to
X * just fit the window.
X */
X
X    if (xfree && yfree) {
X        lw->list.ncols = lw->list.default_cols;
X	if (lw->list.ncols <= 0) lw->list.ncols = 1;
X	lw->list.nrows = ( ( lw->list.nitems - 1) / lw->list.ncols) + 1 ;
X        *width = lw->list.ncols * lw->list.col_width
X	       + 2 * lw->list.internal_width;
X	*height = (lw->list.nrows * lw->list.row_height)
X                + 2 * lw->list.internal_height;
X	change = TRUE;
X    }
X/* 
X * If the width is fixed then use it to determine the number of columns.
X * If the height is free to move (width still fixed) then resize the height
X * of the widget to fit the current list exactly.
X */
X    else if (!xfree) {
X        lw->list.ncols = (*width - 2 * lw->list.internal_width)
X	               / lw->list.col_width;
X	if (lw->list.ncols <= 0) lw->list.ncols = 1;
X	lw->list.nrows = ( ( lw->list.nitems - 1) / lw->list.ncols) + 1 ;
X	if ( yfree ) {
X  	    *height = (lw->list.nrows * lw->list.row_height)
X		    + 2 * lw->list.internal_height;
X	    change = TRUE;
X	}
X    }
X/* 
X * The last case is xfree and !yfree we use the height to determine
X * the number of rows and then set the width to just fit the resulting
X * number of columns.
X */
X    else if (!yfree) {		/* xfree must be TRUE. */
X        lw->list.nrows = (*height - 2 * lw->list.internal_height) 
X	               / lw->list.row_height;
X	if (lw->list.nrows <= 0) lw->list.nrows = 1;
X	lw->list.ncols = (( lw->list.nitems - 1 ) / lw->list.nrows) + 1;
X	*width = lw->list.ncols * lw->list.col_width 
X	       + 2 * lw->list.internal_width;
X	change = TRUE;
X    }      
X    return(change);
X}
X
X/*	Function Name: Notify
X *	Description: Notifies the user that a button has been pressed, and
X *                   calles the callback, if the XtNpasteBuffer resource
X *                   is true then the name of the item is also put in the
X *                   X cut buffer ( buf (0) ).
X *	Arguments: w - the widget that the notify occured in.
X *                 event - event that caused this notification.
X *                 params, num_params - not used.
X *	Returns: none.
X */
X
X/* ARGSUSED */
Xstatic void
XNotify(w, event, params, num_params)
XWidget w;
XXEvent * event;
XString * params;
XCardinal *num_params;
X{
X    ListWidget lw = ( ListWidget ) w;
X    int item, item_len;
X    XtListReturnStruct ret_value;
X
X/* 
X * Find item and if out of range then unhighlight and return. 
X * 
X * If the current item is unhighlighted then the user has aborted the
X * notify, so unhighlight and return.
X */
X
X    if ( ((CvtToItem(w, event->xbutton.x, event->xbutton.y, &item))
X	  == OUT_OF_RANGE) || (lw->list.highlight != item) ) {
X        XtListUnhighlight(w);
X        return;
X    }
X
X    item_len = strlen(lw->list.list[item]);
X
X    if ( lw->list.paste )	/* if XtNpasteBuffer set then paste it. */
X        XStoreBytes(XtDisplay(w), lw->list.list[item], item_len);
X
X/* 
X * Call Callback function.
X */
X
X    ret_value.string = lw->list.list[item];
X    ret_value.index = item;
X    
X    XtCallCallbacks( w, XtNcallback, (caddr_t) &ret_value);
X}
X
X/*	Function Name: Unset
X *	Description: unhighlights the current element.
X *	Arguments: w - the widget that the event occured in.
X *                 event - not used.
X *                 params, num_params - not used.
X *	Returns: none.
X */
X
X/* ARGSUSED */
Xstatic void
XUnset(w, event, params, num_params)
XWidget w;
XXEvent * event;
XString * params;
XCardinal *num_params;
X{
X  old_highlighted_item = -1;  
X  XtListUnhighlight(w);
X}
X
X/*	Function Name: Set
X *	Description: Highlights the current element.
X *	Arguments: w - the widget that the event occured in.
X *                 event - event that caused this notification.
X *                 params, num_params - not used.
X *	Returns: none.
X */
X
X/* ARGSUSED */
Xstatic void
XSet(w, event, params, num_params)
XWidget w;
XXEvent * event;
XString * params;
XCardinal *num_params;
X{
X  int item;
X  ListWidget lw = (ListWidget) w;
X  
X/* Find item and if out of range then return. */
X
X  if ( (CvtToItem(w, event->xbutton.x, event->xbutton.y, &item))
X      == OUT_OF_RANGE)
X       return;
X  
X  if ((old_highlighted_item != item) ||
X      (lw->list.is_highlighted == NO_HIGHLIGHT)) {
X       
X    XtListUnhighlight(w);		/* Unhighlight current item. */
X
X    XtListHighlight(w, item);	/* Highlight new item. */
X    old_highlighted_item = item;
X  }
X}
X
X/*
X * Set specified arguments into widget
X */
X
X/* ARGSUSED */
Xstatic Boolean SetValues(current, request, new)
XWidget current, request, new;
X{
X    ListWidget cl = (ListWidget) current;
X    ListWidget rl = (ListWidget) request;
X    ListWidget nl = (ListWidget) new;
X    Boolean redraw = FALSE;
X
X    if ((cl->list.foreground != rl->list.foreground) ||
X	(cl->core.background_pixel != rl->core.background_pixel) ||
X	(cl->list.font != rl->list.font) ) {
X        XtDestroyGC(cl->list.normgc);
X        XtDestroyGC(cl->list.graygc);
X	XtDestroyGC(cl->list.revgc);
X        GetGCs(new);
X        redraw = TRUE;
X    }
X
X    /* Reset row height. */
X
X    if ((cl->list.row_space != rl->list.row_space) ||
X	(cl->list.font != rl->list.font)) 
X        nl->list.row_height = nl->list.font->max_bounds.ascent
X	                    + nl->list.font->max_bounds.descent
X			    + nl->list.row_space;
X    
X    if ((cl->core.width != rl->core.width)                     ||
X	(cl->core.height != rl->core.height)                   ||
X	(cl->list.internal_width != rl->list.internal_width)   ||
X	(cl->list.internal_height != rl->list.internal_height) ||
X	(cl->list.column_space != rl->list.column_space)       ||
X	(cl->list.row_space != rl->list.row_space)             ||
X	(cl->list.default_cols != rl->list.default_cols)       ||
X	(  (cl->list.force_cols != rl->list.force_cols) &&
X	   (rl->list.force_cols != rl->list.ncols) )           ||
X	(cl->list.vertical_cols != rl->list.vertical_cols)     ||
X	(cl->list.longest != rl->list.longest)                 ||
X	(cl->list.nitems != rl->list.nitems)                   ||
X	(cl->list.font != rl->list.font)                       ||
X	(cl->list.list != rl->list.list)                        ) {
X
X      ResetList(new, TRUE, TRUE);
X      redraw = TRUE;
X    }
X
X    if (cl->list.list != rl->list.list)
X      nl->list.highlight = NO_HIGHLIGHT;
X
X    if ((cl->core.sensitive != rl->core.sensitive) ||
X	(cl->core.ancestor_sensitive != rl->core.ancestor_sensitive)) {
X        nl->list.highlight = NO_HIGHLIGHT;
X	redraw = TRUE;
X    }
X    
X    if (!XtIsRealized(current))
X      return(FALSE);
X      
X    return(redraw);
X}
X
X/* Exported Functions */
X
X/*	Function Name: XtListChange.
X *	Description: Changes the list being used and shown.
X *	Arguments: w - the list widget.
X *                 list - the new list.
X *                 nitems - the number of items in the list.
X *                 longest - the length (in Pixels) of the longest element
X *                           in the list.
X *                 resize - if TRUE the the list widget will
X *                          try to resize itself.
X *	Returns: none.
X *      NOTE:      If nitems of longest are <= 0 then they will be calculated.
X *                 If nitems is <= 0 then the list needs to be NULL terminated.
X */
X
Xvoid
XXtListChange(w, list, nitems, longest, resize_it)
XWidget w;
Xchar ** list;
Xint nitems, longest;
XBoolean resize_it;
X{
X    ListWidget lw = (ListWidget) w;
X
X    lw->list.list = list;
X
X    if (nitems <= 0) nitems = 0;
X    lw->list.nitems = nitems;
X    if (longest <= 0) longest = 0;
X    lw->list.longest = longest;
X
X    ResetList(w, resize_it, resize_it);
X    lw->list.highlight = NO_HIGHLIGHT;
X    if ( XtIsRealized(w) )
X      Redisplay(w, NULL, NULL);
X}
X
X/*	Function Name: XtListUnhighlight
X *	Description: unlights the current highlighted element.
X *	Arguments: w - the widget.
X *	Returns: none.
X */
X
Xvoid
XXtListUnhighlight(w)
XWidget w;
X{
X    ListWidget lw = ( ListWidget ) w;
X
X    lw->list.highlight = NO_HIGHLIGHT;
X    if (lw->list.is_highlighted != NO_HIGHLIGHT)
X        PaintItemName(w, lw->list.is_highlighted); /* unhighlight this one. */
X}
X
X/*	Function Name: XtListHighlight
X *	Description: Highlights the given item.
X *	Arguments: w - the list widget.
X *                 item - the item to hightlight.
X *	Returns: none.
X */
X
Xvoid
XXtListHighlight(w, item)
XWidget w;
Xint item;
X{
X    ListWidget lw = ( ListWidget ) w;
X    
X    if (XtIsSensitive(w)) {
X        lw->list.highlight = item;
X        if (lw->list.is_highlighted != NO_HIGHLIGHT)
X            PaintItemName(w, lw->list.is_highlighted);  /* Unhighlight. */
X	PaintItemName(w, item); /* HIGHLIGHT this one. */ 
X    }
X}
X
X/*	Function Name: XtListShowCurrent
X *	Description: returns the currently highlighted object.
X *	Arguments: w - the list widget.
X *	Returns: the info about the currently highlighted object.
X */
X
XXtListReturnStruct *
XXtListShowCurrent(w)
XWidget w;
X{
X    ListWidget lw = ( ListWidget ) w;
X    XtListReturnStruct * ret_val;
X
X    ret_val = (XtListReturnStruct *) malloc (sizeof (XtListReturnStruct));
X    if (ret_val == NULL)
X      XtError("Could not allocate memory in XtListShowCurrent.");
X    
X    ret_val->index = lw->list.highlight;
X    if (ret_val->index == XT_LIST_NONE)
X      ret_val->string = "";
X    else
X      ret_val->string = lw->list.list[ ret_val->index ];
X
X    return(ret_val);
X}
X
END_OF_FILE
if test 28545 -ne `wc -c <'List.c'`; then
    echo shar: \"'List.c'\" unpacked with wrong size!
fi
# end of 'List.c'
fi
if test -f 'PATCHLEVEL' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'PATCHLEVEL'\"
else
echo shar: Extracting \"'PATCHLEVEL'\" \(2 characters\)
sed "s/^X//" >'PATCHLEVEL' <<'END_OF_FILE'
X4
END_OF_FILE
if test 2 -ne `wc -c <'PATCHLEVEL'`; then
    echo shar: \"'PATCHLEVEL'\" unpacked with wrong size!
fi
# end of 'PATCHLEVEL'
fi
if test -f 'savescreen.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'savescreen.c'\"
else
echo shar: Extracting \"'savescreen.c'\" \(18776 characters\)
sed "s/^X//" >'savescreen.c' <<'END_OF_FILE'
X/*
X * $Source: /mit/sipbsrc/uus/src/xscreensaver/RCS/savescreen.c,v $
X * $Author: jik $
X *
X * This file is part of xscreensaver.  It contains the code for the
X * actual locking/blanking of the screen, with the floating icon and
X * the handling of passwords.
X *
X * Author: Jonathan Kamens, MIT Project Athena and
X *                          MIT Student Information Processing Board
X *
X * Coyright (c) 1989 by Jonathan Kamens.  This code may be distributed
X * freely as long as this notice is kept intact in its entirety and
X * every effort is made to send all corrections and improvements to
X * the code back to the author.  Also, don't try to make any money off
X * of it or pretend that you wrote it.
X */
X
X#ifndef lint
X     static char rcsid_savescreen_c[] = "$Header: savescreen.c,v 1.18 89/02/28 06:55:18 jik Exp $";
X#endif
X
X#include <stdio.h>
X#include <X11/Xos.h>
X#include <signal.h>
X#include <X11/Intrinsic.h>
X#include <X11/StringDefs.h>
X#include <X11/Command.h>
X#include <X11/Shell.h>
X#include <X11/List.h>
X#include <X11/Form.h>
X#include "xsaver.h"
X#include "scaling.h"
X#include "globals.h"
X
X
Xextern char *time_string(), *elapsed_string(), *timeleft_string(),
X     *malloc();
Xextern Cursor blank_cursor();
Xextern Widget PasswordWindow(), PromptBox();
Xextern long random();
Xextern Boolean correct_password();
Xextern void XtMoveWidget();
X
Xstatic void build_root(), lock_command(), unlock_command(), build_float(),
X     MoveFloat(), ActivateFloat(), ActivateClock(), UpdateClock(),
X     ReallyLockScreen(), SaveScreen(), do_timeout(), PasswordTimeout(),
X     LockScreen(), UpdateFloat();
Xstatic int new_off(), maybe_new_off_opposite_sign();
Xstatic char **breakup();
X
Xvoid ActivateRoot(), RaiseRoot(), RemoveRoot(), GetPassword();
X
Xstatic WidgetandWidth time_w, elapsed_w, timeout_w, icon_w;
Xstatic int x_off = 0, y_off = 0;
Xstatic int delay;
XBoolean activated = False, getting_password = False;
Xstatic Dimension max_float_x, max_float_y;
Xstatic int lock_command_pid = 0;
Xstatic String lockedTransString = 
X     "<Key>:			GetPassword(Locked)\n\
X      <BtnDown>,<BtnUp>:	GetPassword(Locked)\n\
X      <Visible>:		RaiseRoot()\n";
Xstatic XtTranslations lockedTrans = (XtTranslations) NULL;
Xstatic Widget root_shell = (Widget) NULL, float_widget = (Widget) NULL;
X
X
X
X
X#define PASSWORD_TIMEOUT 30	/* time, in seconds, before a password */
X				/* prompt will time out */
X
X
X
X
X
X
Xstatic void build_root()
X{
X     Arg arglist[10];
X     int i = 0;
X     Cursor cursor;
X
X     if (! root_shell) {
X	  XtSetArg(arglist[i], XtNborderWidth, 0); 			i++;
X	  XtSetArg(arglist[i], XtNx, 0); 				i++;
X	  XtSetArg(arglist[i], XtNy, 0); 				i++;
X	  XtSetArg(arglist[i], XtNwidth, display_width);		i++;
X	  XtSetArg(arglist[i], XtNheight, display_height);		i++;
X	  if (defs.use_background) {
X	       XtSetArg(arglist[i], XtNbackgroundPixmap,
X			ParentRelative); 				i++;
X	  }
X	  root_shell = XtCreatePopupShell("rootShell",
X					  overrideShellWidgetClass,
X					  top_widget, arglist, i);
X     
X	  root_widget = XtCreateManagedWidget("root", widgetClass,
X					      root_shell, arglist, i);	i = 0;
X
X	  XtRealizeWidget(root_shell);
X
X	  /* Here lies the direct Xlib trickery your mother warned you */
X	  /* about when she taught you tou use Xtk. */
X	  cursor = blank_cursor();
X	  XDefineCursor(dpy, XtWindow(root_shell), cursor);
X	  XDefineCursor(dpy, XtWindow(root_widget), cursor);
X     }
X     
X     /* Setting the coordinates to 0, 0 appears not to work in some */
X     /* cases, in particular when people specify Geometry *class* in */
X     /* the resources, so we are going to reposition the window after */
X     /* we create it. */
X     XtMoveWidget(root_shell, 0, 0);
X}
X
X
X
X
X
X
X/* ARGSUSED */
Xvoid ActivateRoot()
X{
X     ActivateClock();
X
X     build_root();
X     build_float();
X
X     activated = True;
X     
X     XSetScreenSaver(dpy, 0, saver.interval, saver.prefer_blanking,
X		     saver.allow_exposures);
X     XtMapWidget(root_shell);
X     if (XGrabPointer(dpy, XtWindow(root_widget), True, ButtonPressMask,
X		      GrabModeAsync, GrabModeAsync, XtWindow(root_widget),
X		      blank_cursor(), CurrentTime) != GrabSuccess)
X	  fprintf(stderr, "%s: Error grabbing pointer!\n", whoami);
X     if (XGrabKeyboard(dpy, XtWindow(root_widget), False, GrabModeAsync,
X		       GrabModeAsync, CurrentTime) != GrabSuccess)
X	  fprintf(stderr, "%s: Error grabbing keyboard!\n", whoami);
X     XtSetKeyboardFocus(root_shell, root_widget);
X
X     if (lock_flag)
X	  LockScreen();
X     else
X	  SaveScreen();
X}
X
X
X
Xstatic void LockScreen()
X{
X     if (! lockedTrans)
X	  lockedTrans = XtParseTranslationTable(lockedTransString);
X     if (! (*defs.ekey || *defs.key)) {
X	  String str = "Initial";
X	  Cardinal num = 1;
X	  GetPassword(root_widget, (XEvent *) NULL, &str, &num);
X     }
X     else
X	  ReallyLockScreen();
X}
X
X
X
Xstatic void ReallyLockScreen()
X{
X     lock_command();
X     XtOverrideTranslations(root_widget, lockedTrans);
X     ActivateFloat();
X}     
X
X
Xstatic void SaveScreen()
X{
X     static String rootTranslations =
X	  "<Key>:		RemoveRoot()\n\
X           <BtnDown>,<BtnUp>:	RemoveRoot()\n\
X           <Visible>:		RaiseRoot()\n";
X     XtTranslations trans = (XtTranslations) NULL;
X
X     if (! trans)
X	  trans = XtParseTranslationTable(rootTranslations);
X     XtOverrideTranslations(root_widget, trans);
X     ActivateFloat();
X}
X
X
X
X
X
Xstatic void PasswordTimeout()
X{
X     if (getting_password) {
X	  char *str = "Timeout";
X	  Cardinal num = 1;
X	  GetPassword(root_shell, (XEvent *) NULL, &str, &num);
X     }
X}
X
X
X
X
X
X#define DOING_NOTHING 0
X#define GETTING_LOCKED_PASSWORD 3
X#define GETTING_FIRST_INITIAL_PASSWORD 1
X#define GETTING_SECOND_INITIAL_PASSWORD 2
X
X/* ARGSUSED */
Xvoid GetPassword(w, event, params, num_params)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *num_params;
X{
X     static char password[MAXPASSWORD];
X     static char *ptr;
X     static String gettingPasswordTranslations =
X	  "<Key>Return:		GetPassword(Done)\n\
X	   <Key>:		GetPassword(Reading)\n\
X           <Visible>:		RaiseRoot()\n";
X     static XtTranslations gettingPasswordTrans = (XtTranslations) NULL;
X     static Widget prompt;
X     static int state = DOING_NOTHING;
X     Arg arglist[2];
X     int i = 0;
X     
X     if (! gettingPasswordTrans)
X	  gettingPasswordTrans =
X	       XtParseTranslationTable(gettingPasswordTranslations);
X     if (**params == 'L') {
X	  ptr = password;
X	  state = GETTING_LOCKED_PASSWORD;
X	  getting_password = True;
X	  prompt = PasswordWindow(state);
X	  XtSetArg(arglist[i], XtNtranslations, gettingPasswordTrans);	i++;
X	  XtSetValues(root_shell, arglist, i);
X	  XtSetValues(root_widget, arglist, i);				i = 0;
X	  XtMapWidget(prompt);
X	  XtAddTimeOut(PASSWORD_TIMEOUT * 1000, PasswordTimeout, NULL);
X     }
X     else if (**params == 'I') {
X	  ptr = password;
X	  state = GETTING_FIRST_INITIAL_PASSWORD;
X	  getting_password = True;
X	  prompt = PasswordWindow(state);
X	  XtOverrideTranslations(root_widget, gettingPasswordTrans);
X	  XtMapWidget(prompt);
X	  XtAddTimeOut(PASSWORD_TIMEOUT * 1000, PasswordTimeout, NULL);
X     }
X     else if (**params == 'R') {
X	  XtAddTimeOut(PASSWORD_TIMEOUT * 1000, PasswordTimeout, NULL);
X	  if (ptr - password < MAXPASSWORD - 1) {
X	       char key_buf[5];
X	       int num_read;
X	       
X	       num_read = XLookupString(event, key_buf, 5,
X					(KeySym *) NULL,
X					(XComposeStatus *) NULL);
X	       if (num_read == 1) {
X		    *ptr = *key_buf;
X		    ptr++;
X	       }
X	  }
X     }
X     else if (**params == 'D') {
X	  XtUnmapWidget(prompt);
X	  XtDestroyWidget(prompt);
X	  *ptr = '\0';
X	  if (state == GETTING_LOCKED_PASSWORD) {
X	       getting_password = False;
X	       state = DOING_NOTHING;
X	       if (correct_password(password)) {
X		    RemoveRoot(root_shell, (XEvent *) NULL, (String *) NULL,
X			       (Cardinal *) NULL);
X		    bzero(password, strlen(password));
X	       }
X	       else {
X		    ReallyLockScreen();
X		    bzero(password, strlen(password));
X	       }
X	  }
X	  else if (state == GETTING_FIRST_INITIAL_PASSWORD) {
X	       ptr = password;
X	       if (*ptr) {
X		    state = GETTING_SECOND_INITIAL_PASSWORD;
X		    strcpy(defs.key, password);
X		    bzero(password, strlen(password));
X		    prompt = PasswordWindow(state);
X		    XtMapWidget(prompt);
X	       }
X	       else { /* User just hit return.  That's a no-no, so ask */
X		      /* for a password again */
X		    char *param = "Initial";
X		    Cardinal num = 1;
X
X		    XBell(dpy, 100);
X		    state = DOING_NOTHING;
X		    GetPassword(root_shell, (XEvent *) NULL, &param, &num);
X	       }
X	  }
X	  else if (state == GETTING_SECOND_INITIAL_PASSWORD) {
X	       if (! strcmp(password, defs.key)) {
X		    getting_password = False;
X		    install_password();
X		    bzero(password, strlen(password));
X		    ReallyLockScreen();
X	       }
X	       else {
X		    char *param = "Initial";
X		    Cardinal num = 1;
X
X		    bzero(password, strlen(password));
X		    bzero(defs.key, strlen(defs.key));
X		    state = DOING_NOTHING;
X		    GetPassword(root_shell, (XEvent *) NULL, &param, &num);
X	       }
X	  }
X     }
X     else if (**params == 'T') {
X	  XtUnmapWidget(prompt);
X	  XtDestroyWidget(prompt);
X	  getting_password = False;
X	  bzero(password, ptr - password);
X	  if (state == GETTING_LOCKED_PASSWORD)
X	       ReallyLockScreen();
X	  else if (state == GETTING_FIRST_INITIAL_PASSWORD)
X	       RemoveRoot((Widget) NULL, (XEvent *) NULL, (String *) NULL,
X			  (Cardinal *) NULL);
X	  else if (state == GETTING_SECOND_INITIAL_PASSWORD)
X	       RemoveRoot((Widget) NULL, (XEvent *) NULL, (String *) NULL,
X			  (Cardinal *) NULL);
X     }
X}
X     
X            
X
X
X
Xstatic void ActivateClock()
X{
X     struct timeval tim;
X
X     gettimeofday(&tim, (struct timezone *) NULL);
X     times.start = times.current = times.saver = tim.tv_sec;
X}     
X
X
X
X
X
X
Xstatic void UpdateClock()
X{
X     struct timeval tim;
X     gettimeofday(&tim, (struct timezone *) NULL);
X     times.current = tim.tv_sec;
X}
X
X
X
X
X
X
X
Xstatic void ActivateFloat()
X{
X     Arg arglist[5];
X     int i = 0;
X     Position x, y;
X     Dimension width, height, border;
X     
X     if (! x_off) {
X	  XtSetArg(arglist[i], XtNwidth, &width); 			i++;
X	  XtSetArg(arglist[i], XtNheight, &height); 			i++;
X	  XtSetArg(arglist[i], XtNborderWidth, &border); 		i++;
X	  XtGetValues(float_widget, arglist, i); 			i = 0;
X
X	  max_float_x = display_width - width - 2 * border;
X	  max_float_y = display_height - height - 2 * border;
X	  x = random() % max_float_x;
X	  y = random() % max_float_y;
X	  x_off = new_off();
X	  y_off = new_off();
X
X	  delay = calc_delay(x_off, y_off, defs.velocity);
X	  
X	  XtMoveWidget(float_widget, x, y);
X	  XtMapWidget(float_widget);
X     }
X     else
X	  UpdateFloat();
X	  
X     XtAddTimeOut(delay, MoveFloat, NULL);
X}
X
X
X
X     
X     
Xstatic void do_timeout()
X{
X     unlock_command();
X     exit(0);
X}
X
X
X
Xstatic void MoveFloat()
X{
X     Arg arglist[5];
X     int i = 0;
X     Position x, y;
X     int changed_off = 0;
X
X     if (getting_password || (! activated))
X	  return;
X     if (lock_flag && defs.timeout) {
X	  if ((times.current - times.start) >= defs.timeout * 60)
X	       do_timeout();
X     }
X     UpdateFloat();
X     XtSetArg(arglist[i], XtNx, &x); i++;
X     XtSetArg(arglist[i], XtNy, &y); i++;
X     XtGetValues(float_widget, arglist, i);
X     if (x + x_off > max_float_x) {
X	  changed_off += maybe_new_off_opposite_sign(&x_off);
X     }
X     else if (x + x_off < 0) {
X	  changed_off += maybe_new_off_opposite_sign(&x_off);
X     }
X     if (y + y_off > max_float_y) {
X	  changed_off += maybe_new_off_opposite_sign(&y_off);
X     }
X     else if (y + y_off < 0) {
X	  changed_off += maybe_new_off_opposite_sign(&y_off);
X     }
X     x += x_off; y += y_off;
X     if (changed_off)
X	  delay = calc_delay(x_off, y_off, defs.velocity);
X     XtMoveWidget(float_widget, x, y);
X     XtAddTimeOut(delay, MoveFloat, NULL);
X}
X
X
X
X
Xstatic void UpdateFloat()
X{
X     Arg arglist[5];
X     int i = 0;
X     Dimension width, new_width;
X     
X     XtSetArg(arglist[i], XtNwidth, &width);				i++;
X     XtGetValues(float_widget, arglist, i);				i = 0;
X     UpdateClock();
X     XtFormDoLayout(float_widget, False);
X     XtSetArg(arglist[i], XtNwidth, &icon_w.width);			i++;
X     XtGetValues(icon_w.widget, arglist, i);				i = 0;
X     if (defs.d_time) {
X	  char *tm = time_string(TIME_FORMAT, NoForce);
X	  if (tm) {
X	       XtSetArg(arglist[i], XtNlabel, tm); i++;
X	       XtSetValues(time_w.widget, arglist, i); i = 0;
X	       XtSetArg(arglist[i], XtNwidth, &time_w.width);		i++;
X	       XtGetValues(time_w.widget, arglist, i);			i = 0;
X	  }
X     }
X     if (defs.d_elapsed) {
X	  char *tm = elapsed_string(ELAPSED_FORMAT, NoForce);
X	  if (tm) {
X	       XtSetArg(arglist[i], XtNlabel, tm); i++;
X	       XtSetValues(elapsed_w.widget, arglist, i); i = 0;
X	       XtSetArg(arglist[i], XtNwidth, &elapsed_w.width);	i++;
X	       XtGetValues(elapsed_w.widget, arglist, i);		i = 0;
X	  }
X     }
X     if (defs.d_timeout && lock_flag && defs.timeout) {
X	  char *tm = timeleft_string(TIMELEFT_FORMAT, NoForce);
X	  if (tm) {
X	       XtSetArg(arglist[i], XtNlabel, tm); i++;
X	       XtSetValues(timeout_w.widget, arglist, i); i = 0;
X	       XtSetArg(arglist[i], XtNwidth, &timeout_w.width);	i++;
X	       XtGetValues(timeout_w.widget, arglist, i);		i = 0;
X	  }
X     }
X     XtFormDoLayout(float_widget, True);
X     XtSetArg(arglist[i], XtNwidth, &new_width);			i++;
X     XtGetValues(float_widget, arglist, i);				i = 0;
X     if (new_width != width) {
X	  XtFormDoLayout(float_widget, False);
X	  center(icon_w.widget, icon_w.width, new_width);
X	  if (defs.d_time)
X	       center(time_w.widget, time_w.width, new_width);
X	  if (defs.d_elapsed)
X	       center(elapsed_w.widget, elapsed_w.width, new_width);
X	  if (defs.d_timeout && lock_flag && defs.timeout)
X	       center(timeout_w.widget, timeout_w.width, new_width);
X	  XtFormDoLayout(float_widget, True);
X     }
X}     
X
X
X
X
Xstatic int maybe_new_off_opposite_sign(foo)
Xint *foo;
X{
X     int off = - *foo;
X     int changed = 0;
X     
X     if (! (random() % 4)) {
X	  off = random() % 5 + 1;
X	  off = (*foo < 0 ? off : - off);
X	  changed++;
X     }
X     *foo = off;
X     
X     return(changed);
X}
X
X
X
X
X
X
X
Xstatic int new_off()
X{
X     int foo;
X     
X     foo = random() % 11 - 5;
X     if (! foo)
X	  foo = (random() % 1 ? 1 : -1);
X     
X     return(foo);
X}
X
X
X
X
X
X
X
X
Xstatic void build_float()
X{
X     PromptLine lines[MAXPROMPT];
X     int i = 0, max_strlen = 0;
X     Widget *return_widgets;
X     static String float_name = "float";
X     static String msg_name = "message";
X
X     if (! float_widget) {
X	  
X	  /* The first one should pick up a bitmap from the defaults */
X	  lines[i] = default_line;
X	  lines[i].use_default = True;
X	  lines[i].name = float_name;
X	  lines[i].str = "floatIcon";					i++;
X	  if (defs.d_time) {
X	       lines[i] = default_line;
X	       lines[i].name = float_name;
X	       lines[i].str = time_string(TIME_FORMAT, Force);
X	       max_strlen = ((strlen(lines[i].str) > max_strlen) ?
X			     strlen(lines[i].str) : max_strlen);	i++;
X	  }
X	  if (defs.d_elapsed) {
X	       lines[i] = default_line;
X	       lines[i].name = float_name;
X	       lines[i].str = elapsed_string(ELAPSED_FORMAT, Force);
X	       max_strlen = ((strlen(lines[i].str) > max_strlen) ?
X			     strlen(lines[i].str) : max_strlen);	i++;
X	  }
X     
X	  if (defs.d_timeout && lock_flag && defs.timeout) {
X	       lines[i] = default_line;
X	       lines[i].name = float_name;
X	       lines[i].str = timeleft_string(TIMELEFT_FORMAT, Force);
X	       max_strlen = ((strlen(lines[i].str) > max_strlen) ?
X			     strlen(lines[i].str) : max_strlen);	i++;
X	  }
X	  if (*defs.lock_message) {
X	       int num_lines;
X	       char **msg_lines;
X	       int a;
X
X	       if (max_strlen < 25)
X		    max_strlen = 25;
X	       msg_lines = breakup(defs.lock_message, max_strlen, &num_lines);
X	       for (a = 0; (a < num_lines) && (i < MAXPROMPT); a++, i++) {
X		    lines[i] = default_line;
X		    if (a == 0)
X			 lines[i].spread = 10;
X		    lines[i].name = msg_name;
X		    lines[i].str = msg_lines[a];
X	       }
X	  }
X	  
X	  return_widgets = (Widget *) malloc(sizeof(Widget) * i);
X	  if (! return_widgets) {
X	       perror(whoami);
X	       exit(1);
X	  }
X	  float_widget = PromptBox(root_widget, "float", lines, i,
X				   return_widgets);			i = 0;
X	  icon_w.widget = return_widgets[i];				i++;
X	  if (defs.d_time) {
X	       time_w.widget = return_widgets[i];			i++;
X	  }
X	  if (defs.d_elapsed) {
X	       elapsed_w.widget = return_widgets[i];			i++;
X	  }
X	  if (defs.d_timeout && lock_flag && defs.timeout) {
X	       timeout_w.widget = return_widgets[i];			i++;
X	  }
X     }
X}
X     
X
X
X
X
Xstatic char **breakup(str, max, num)
XString str;
Xint max;
Xint *num;
X{
X     char **foo;
X     int lines = 0;
X     char *ptr, *ptr2;
X     char temp;
X     
X     foo = (char **) malloc(0);
X
X     ptr = str;
X     while (strlen(ptr) > max) {
X	  lines++;
X	  for (ptr2 = ptr + max; (ptr2 > ptr) && (*ptr2 != ' '); ptr2--);
X	  if (ptr2 == ptr) {
X	       temp = *(ptr + max);
X	       *(ptr + max) = '\0';
X	       ptr2 = ptr + max;
X	  }
X	  else {
X	       temp = 0;
X	       *ptr2 = '\0';
X	       ptr2++;
X	  }
X	  foo = (char **) realloc(foo, sizeof(char *) * lines);
X	  foo[lines - 1] = malloc(strlen(ptr) + 1);
X	  strcpy(foo[lines - 1], ptr);
X	  if (temp)
X	       *ptr2 = temp;
X	  ptr = ptr2;
X	  
X     }
X     if (*ptr) {
X	  lines++;
X	  foo = (char **) realloc(foo, sizeof(char *) * lines);
X	  foo[lines - 1] = malloc(strlen(ptr) + 1);
X	  strcpy(foo[lines - 1], ptr);
X     }
X     *num = lines;
X     return(foo);
X}
X
X
X
X
X/* ARGSUSED */
Xvoid RaiseRoot(w, event, params, num_params)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *num_params;
X{
X     XRaiseWindow(dpy, XtWindow(root_shell));
X}
X
X
X
X/* ARGSUSED */
Xvoid RemoveRoot(w, event, params, num_params)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *num_params;
X{
X
X     unlock_command();
X     XtUnmapWidget(root_shell);
X     XUngrabPointer(dpy, CurrentTime);
X     XUngrabKeyboard(dpy, CurrentTime);
X     XSetScreenSaver(dpy, saver.timeout, saver.interval, saver.prefer_blanking,
X		     saver.allow_exposures);
X     activated = False;
X}
X
X
X
X
Xstatic void lock_command()
X{
X     if ((! lock_command_pid) && (*defs.lock_command)) {
X	  if ((lock_command_pid = fork()) == -1) {
X	       fprintf(stderr, "%s: Error forking to execute lock command!",
X		       whoami);
X	       lock_command_pid = 0;
X	  }
X	  else if (! lock_command_pid) {
X	       setpgrp(getpid(), getpid());
X	       XtCloseDisplay(dpy);
X	       system(defs.lock_command);
X	       exit(0);
X	  }
X     }
X}
X
X
X
X
X
Xstatic void unlock_command()
X{
X     if (lock_command_pid) {
X	  killpg(lock_command_pid, SIGKILL);
X	  lock_command_pid = 0;
X     }
X     if (lock_flag && *defs.unlock_command) {
X	  int pid;
X
X	  if ((pid = fork()) == -1)
X	       fprintf(stderr,
X		       "%s: Error forking to execute unlock command.\n",
X		       whoami);
X	  else if (! pid) {
X	       XtCloseDisplay(dpy);
X	       system(defs.unlock_command);
X	       exit(0);
X	  }
X     }
X}
X
X
X
END_OF_FILE
if test 18776 -ne `wc -c <'savescreen.c'`; then
    echo shar: \"'savescreen.c'\" unpacked with wrong size!
fi
# end of 'savescreen.c'
fi
echo shar: End of archive 1 \(of 3\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mike Wexler(wyse!mikew)    Phone: (408)433-1000 x1330
Moderator of comp.sources.x



More information about the Comp.sources.x mailing list