mikew@wyse.wyse.com (Mike Wexler) (03/11/89)
Submitted-by: jik@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@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@Athena.MIT.EDU X jik@pit-manager.MIT.EDU X BITnet: s20020@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, ¶m, &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, ¶m, &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