[comp.sources.x] v04i042: dclock -- a digital clock, Part01/01

argv@island.uu.net (Dan Heller) (06/30/89)

Submitted-by: island!argv@sun.com (Dan Heller)
Posting-number: Volume 4, Issue 42
Archive-name: dclock/part01



This is something that I submitted to the R3 tape last year.  However,
it has had a number of changes such as:
    portable to R3
    colors are handled correctly
    24 hour military time format
    Alarm feature.
    Added an Imakefile. :-)
I have submitted updates to expo in the past, but this is the first
official posting since it's first appearance on the R3 tape.  Posting
the whole source took less room than posting patches.  The new alarm
clock feature is something I've had for a while, but never sent it out
to anyone.  See the readme, the man page, and the wrapper program for
how to use it.

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then feed it
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix@uunet.uu.net if you want that tool.
# If this archive is complete, you will see the following message at the end:
#		"End of shell archive."
# Contents:  README dclock.man Imakefile Makefile Dclock.c Dclock.h
#   DclockP.h dclock.c patchlevel.h
# Wrapped by argv@island on Thu Jun 29 20:01:33 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'\" \(1122 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XCopyright (c) Dan Heller <island!argv@sun.com> 1988
X
XTo compile, just run make and watch it go.
X
XWhen the program is running and the mouse is in the window, you can
Xtype the following keys:
X    
X    r -- toggle reverse video
X    s -- toggle seconds display
X    b -- toggle the bell to ring on half hours
X    j -- toggle jump or smooth scrolling
X    d -- toggle date string display
X    m -- toggle military (24hr) time format
X    a -- toggle the alarm clock
X    q -- quit
X
XTo set the alarm time, use the third mouse button and click on the
Xdigits till the time is set correctly.  Alarm time is set in 24-hour
Xformat to distringuish between am and pm.  If there is an asterisk
Xon the same line as the date, then the alarm is set.  Use the 'a' key
Xto set the alarm.
X
Xtypical uses:
X
X    # set alarm for noon
X    dclock -fg green -gb black -alarmTime 12:00 -alarm
X
X    # set date string and have bell go off on hour/half-hour intervals
X    dclock -date "Today is %W, %M %d" -fg yellow -bg brown -bell
X
X    # set date more simply, use 24-hour military time format and display secs
X    dclock -date "%w, %m %d" -miltime -seconds
END_OF_FILE
if test 1122 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'dclock.man' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dclock.man'\"
else
echo shar: Extracting \"'dclock.man'\" \(6264 characters\)
sed "s/^X//" >'dclock.man' <<'END_OF_FILE'
X.TH DCLOCK 1 "1 March 1988" "X Version 11"
X.SH NAME
Xdclock - digital clock for X
X.SH SYNOPSIS
X.B dclock
X[-\fItoolkitoption\fP ...] [-option ...]
X.SH DESCRIPTION
XThe
X.I dclock 
Xprogram displays the time in digital format only.  The time is
Xupdated on a per second basis or on a per minute basis.  This program is
Xnothing more than a wrapper around the dclock widget not associated with
Xany particular widget set.
X.sp
XWhen the clock is running, the user may change attributes by typing:
X.in +2
X.nf
X\fBr\fP\ \ Toggles \fBReverse Video\fP.
X\fBs\fP\ \ Toggles the \fBseconds\fP display.
X\fBb\fP\ \ Toggles the \fBbell\fP attribute.
X\fBj\fP\ \ Toggles the \fBjump/scroll\fP attribute.
X\fBd\fP\ \ Toggles the \fBdate\fP format.
X\fBm\fP\ \ Toggles the \fBmilitary time\fP format.
X\fBa\fP\ \ Toggles the \fBalarm clock\fP.
X\fBq\fP\ \ quit the program.
X.sp
X.fi
X.in -2
XThe third mouse button puts the clock in the mode where the alarm clock can
Xbe set.  The alarm must be set in 24-hour format to distringuish between
Xam and pm time.  Digits can be changed by selecting the digit with the
Xleft or middle mouse button.  The Left button advances the time while the
XMiddle button moves the time backwards.  Using the left or middle button
Xover the text at the bottom of the clock toggles the alarm from actually
Xbeing set (or, use the 'a' key).
X.SH OPTIONS
X.I Dclock
Xaccepts all of the standard X Toolkit command line options along with the 
Xadditional options listed below:
X.TP 8
X.B \-help
XThis option indicates that a brief summary of the allowed options should be
Xprinted on the standard error.
X.TP 8
X.B \-bell
XThis option indicates that the beel will beep
Xonce on the half hour and twice on the hour.
X.TP 8
X.B \-miltime
XThis option causes the clock to display the time in 24 hour (military)
Xtime format.
X.TP 8
X.B \-scroll
X.br
X.B \-noscroll
XWhen the time changes, the digits scroll from the previous digit to the
Xnext digit.  Since this is on by default, the -noscroll option can turn
Xit off.
X.TP 8
X.B \-date "format"
XThe date is printed under the time in the specified font.  The string
Xdisplayed is in the "format" argument.  If the string contains a formatting
Xcharacter (%), then the next character is examined and a value is inserted
Xinto the string.  Example:
X.TP 8
X.B \-alarm
X.br
X.TP 8
X.B \-noalarm
XThe alarm is turned on or off.  Alarm rings bell and toggles the
Xreverse video five times.
X.br
X.TP 8
X.B \-alarmTime HH:MM
XIf alarm is set, it goes off at time specified in 24-hour format.
X.br
X.sp
X.ti +2
Xdclock -date "Today is %W"
X.sp
XThe date string will print "Today is Friday" if the weekday name happens
Xto be friday.  The formatting characters that are understood are:
X.in +2
X.nf
X%W	Full weekday name
X%w	Three-char weekday name (Sun, Mon, Tue...)
X%M	Full month name
X%m      Three-char abbreviation for that month (Jan, Feb, Mar...)
X%d	The date (numerical day number of the month)
X%Y	Full year (4 digits)
X%y	2-digit year number
X.fi
X.in -2
X.TP 8
X.B \-seconds
XThis option will update the clock every second and display the time
Xincluding the seconds.
X.TP 8
X.B \-bg \fIcolor\fP
XThis option specifies the color to use for the background of the window.  
XThe default is ``white.''
X.TP 8
X.B \-bd \fIcolor\fP
XThis option specifies the color to use for the border of the window.
XThe default is ``black.''
X.TP 8
X.B \-bw \fInumber\fP
XThis option specifies the width in pixels of the border surrounding the window.
X.TP 8
X.B \-fg \fIcolor\fP
XThis option specifies the color to use for displaying text.  The default is 
X``black''.
X.TP 8
X.B \-fn \fIfont\fP
XThis option specifies the font to be used for displaying normal text.  The
Xdefault is ``Fixed.''
X.TP 8
X.B \-rv
XThis option indicates that reverse video should be simulated by swapping
Xthe foreground and background colors.
X.TP 8
X.B \-geometry \fIgeometry\fP
XThis option specifies the prefered size and position of the clock window.
X.TP 8
X.B \-display \fIhost\fP:\fIdisplay\fP
XThis option specifies the X server to contact.
X.TP 8
X.B \-xrm \fIresourcestring\fP
XThis option specifies a resource string to be used.  This is especially
Xuseful for setting resources that do not have separate command line options.
X.SH X DEFAULTS
XIt understands all of the core resource names and
Xclasses as well as:
X.PP
X.TP 8
X.B width (\fPclass\fB Width)
XSpecifies the width of the clock.
X.TP 8
X.B height (\fPclass\fB Height)
XSpecifies the height of the clock.
X.TP 8
X.B foreground (\fPclass\fB Foreground)
XSpecifies the color for the tic marks.  Using the class specifies the
Xcolor for all things that normally would appear in the foreground color.
XThe default is ``black'' since the core default for background is ``white.''
X.TP 8
X.B bell (\fPclass\fB Boolean)
XSpecifies whether or not a bell should be rung on the hour and half hour.
X.TP 8
X.B font (\fPclass\fB Font)
XSpecifies the font to be used for the date.
X.TP 8
X.B miltime (\fPclass\fB Boolean)
XSpecifies whether the military (24hr) time format should be used.
X.TP 8
X.B reverseVideo (\fPclass\fB ReverseVideo)
XSpecifies that the foreground and background colors should be reversed.
X.TP 8
X.B scroll (\fPclass\fB Boolean)
XSpecifies whether the digits should scroll or not.
X.TP 8
X.B seconds (\fPclass\fB Boolean)
XSpecifies whether the seconds should be displayed or not.
X.TP 8
X.B bell (\fPclass\fB Boolean)
XSpecifies whether the bell should sound on the half hour and on the hour.
X.TP 8
X.B alarm (\fPclass\fB Boolean)
XSpecifies whether the alarm should go off at the specified time (alarmTime).
X.TP 8
X.B alarmTime (\fPclass\fB String)
XSpecifies the time alarm goes off if alarm is set.
X.SH ENVIRONMENT
X.PP
X.TP 8
X.B DISPLAY
Xto get the default host and display number.
X.B XENVIRONMENT
Xto get the name of a resource file that overrides the global resources
Xstored in the RESOURCE_MANAGER property.
X.SH "SEE ALSO"
XX(1), xrdb(1), time(3C).
X.SH BUGS
X.I Dclock
Xbelieves the system clock.
X.PP
XScrolling from 9 to 10 O'Clock seems weird, but chances are you won't
Xnotice it.
X.PP
XIf the window is too small, the seconds are tough to read.  This should
Xbe recognized by the program and should display seconds using a font
Xrather than the bitmaps used by the clock itself.
X.SH COPYRIGHT
XCopyright (c) 1988, Dan Heller.
X.SH AUTHOR
X.nf
XDan Heller -- <island!argv@sun.com> or <dheller@cory.berkeley.edu>
X.fi
END_OF_FILE
if test 6264 -ne `wc -c <'dclock.man'`; then
    echo shar: \"'dclock.man'\" unpacked with wrong size!
fi
# end of 'dclock.man'
fi
if test -f 'Imakefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Imakefile'\"
else
echo shar: Extracting \"'Imakefile'\" \(119 characters\)
sed "s/^X//" >'Imakefile' <<'END_OF_FILE'
XLOCAL_LIBRARIES = $(XTOOLLIB) $(XLIB)
X
XSRCS = Dclock.c dclock.c
XOBJS = Dclock.o dclock.o
X
XComplexProgramTarget(dclock)
END_OF_FILE
if test 119 -ne `wc -c <'Imakefile'`; then
    echo shar: \"'Imakefile'\" unpacked with wrong size!
fi
# end of 'Imakefile'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(449 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X# Please read the accompanying README file before running Make
XSRCS= Dclock.c dclock.c
XOBJS= Dclock.o dclock.o
XHFILES= Dclock.h DclockP.h patchlevel.h
X
XCFLAGS= -O
XLDFLAGS= -g
XLIBS= -lXt -lX
X
Xdclock: ${OBJS}
X	cc ${LDFLAGS} ${OBJS} ${LIBS} -o dclock
X
Xclean: ; rm -f ${OBJS} core dclock
X
Xshar: ; shar README Makefile dclock.man ${HFILES} ${SRCS} > dclock.shar
X
Xtar: ; tar fcv - README Makefile dclock.man ${HFILES} ${SRCS} | \
X	compress > dclock.tar.Z
END_OF_FILE
if test 449 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'Dclock.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Dclock.c'\"
else
echo shar: Extracting \"'Dclock.c'\" \(25043 characters\)
sed "s/^X//" >'Dclock.c' <<'END_OF_FILE'
X/*
X * Dclock.c -- a digital clock widget.
X * Copyright (c) Dan Heller <island!argv@sun.com> 1988
X */
X#include <stdio.h>
X#include <X11/IntrinsicP.h>
X#include <X11/Xos.h>
X#include <X11/StringDefs.h>
X#include "DclockP.h"
X
Xstatic void
X    Initialize(), Resize(), Realize(), Destroy(),
X    Redisplay(), timeout(), toggle_bell(), toggle_reverse_video(), GetGC(),
X    toggle_scroll(), toggle_seconds(), toggle_military_time(), toggle_date(),
X    make_number(), set_alarm(), show_date(), scroll_time(),
X    toggle_alarm(), outline_digit();
X
X#define BORDER		5
X#define CLOCK_WIDTH	256
X#define CLOCK_HEIGHT	80
X#define DATE_FMT	"%W, %M %d"
X#define when		break;case
X#define otherwise	break;default
X
Xstatic Boolean SetValues(), show_time();
Xstatic Dimension winwidth = CLOCK_WIDTH;
Xstatic Dimension winheight = CLOCK_HEIGHT;
Xstatic Boolean false = False;
Xstatic Boolean true = True;
Xstatic double x_ratio, y_ratio;
Xstatic Pixmap old_pix[4];
Xstatic struct tm before;
Xstatic char *saved_date;
Xstatic cur_position;	/* outline current digit for setting alarm */
Xstatic struct { int hrs, mins; } Alarm;
X
Xstatic char defaultTranslations[] =
X    "<Key>b:		toggle-bell()		\n\
X     <Key>j:		toggle-scroll()		\n\
X     <Key>r:		toggle-reverse-video()	\n\
X     <Key>s:		toggle-seconds()	\n\
X     <Key>m:		toggle-military-time()	\n\
X     <Key>d:		toggle-date()		\n\
X     <Key>a:		toggle-alarm()		\n\
X     <BtnDown>:		set-alarm()";
X
Xstatic XtActionsRec actionsList[] = {
X    { "toggle-bell",		toggle_bell		},
X    { "toggle-scroll",		toggle_scroll		},
X    { "toggle-reverse-video",	toggle_reverse_video	},
X    { "toggle-seconds",		toggle_seconds		},
X    { "toggle-military-time",	toggle_military_time	},
X    { "toggle-date",		toggle_date		},
X    { "toggle-alarm",		toggle_alarm		},
X    { "set-alarm",		set_alarm		},
X};
X
Xstatic XtResource resources[] = {
X    { XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension),
X	XtOffset(Widget,core.width), XtRDimension, (caddr_t)&winwidth },
X    { XtNheight, XtCHeight, XtRDimension, sizeof(Dimension),
X	XtOffset(Widget,core.height), XtRDimension, (caddr_t)&winheight },
X    { XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
X        XtOffset(DclockWidget,dclock.foreground), XtRString, "Black"},
X    { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
X	XtOffset(DclockWidget,dclock.reverse), XtRBoolean, (caddr_t)&false},
X    { XtNscroll, XtCBoolean, XtRBoolean, sizeof (Boolean),
X	XtOffset(DclockWidget,dclock.scroll), XtRBoolean, (caddr_t)&true},
X    { XtNdisplayTime, XtCBoolean, XtRBoolean, sizeof (Boolean),
X	XtOffset(DclockWidget,dclock.display_time), XtRBoolean, (caddr_t)&true},
X    { XtNalarm, XtCBoolean, XtRBoolean, sizeof (Boolean),
X	XtOffset(DclockWidget,dclock.alarm), XtRBoolean, (caddr_t)&false},
X    { XtNalarmTime, XtCTime, XtRString, sizeof (char *),
X	XtOffset(DclockWidget,dclock.alarm_time), XtRString, "00:00" },
X    { XtNbell, XtCBoolean, XtRBoolean, sizeof (Boolean),
X	XtOffset(DclockWidget,dclock.bell), XtRBoolean, (caddr_t)&false},
X    { XtNseconds, XtCBoolean, XtRBoolean, sizeof (Boolean),
X	XtOffset(DclockWidget,dclock.seconds), XtRBoolean, (caddr_t)&false},
X    { XtNmilitaryTime, XtCBoolean, XtRBoolean, sizeof (Boolean),
X	XtOffset(DclockWidget,dclock.miltime), XtRBoolean, (caddr_t)&false},
X    { XtNdate, XtCString, XtRString, sizeof (String),
X	XtOffset(DclockWidget,dclock.date_fmt), XtRString, NULL},
X    { XtNfont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
X	XtOffset(DclockWidget,dclock.font), XtRString, "fixed"},
X};
X
XDclockClassRec dclockClassRec = {
X    { /* core fields */
X    /* superclass		*/	&widgetClassRec,
X    /* class_name		*/	"Dclock",
X    /* widget_size		*/	sizeof(DclockRec),
X    /* class_initialize		*/	NULL,
X    /* class_part_initialize	*/	NULL,
X    /* class_inited		*/	FALSE,
X    /* initialize		*/	Initialize,
X    /* initialize_hook		*/	NULL,
X    /* realize			*/	Realize,
X    /* actions			*/	actionsList,
X    /* num_actions		*/	XtNumber(actionsList),
X    /* resources		*/	resources,
X    /* resource_count		*/	XtNumber(resources),
X    /* xrm_class		*/	NULL,
X    /* compress_motion		*/	TRUE,
X    /* compress_exposure	*/	TRUE,
X    /* compress_enterleave	*/	TRUE,
X    /* visible_interest		*/	FALSE,
X    /* destroy			*/	Destroy,
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		*/	NULL,
X    }
X};
XWidgetClass dclockWidgetClass = (WidgetClass) &dclockClassRec;
X
X/* ARGSUSED */
Xstatic void
XInitialize (request, new)
XDclockWidget   request;
XDclockWidget   new;
X{
X    int n;
X
X    if (new->dclock.reverse)
X	new->dclock.foreground = !new->dclock.foreground;
X
X    if (new->dclock.alarm_time) {
X	if (sscanf(new->dclock.alarm_time, "%2d:%2d",
X		&Alarm.hrs, &Alarm.mins) != 2 || Alarm.hrs >= 24 ||
X		Alarm.mins >= 60) {
X	    XtWarning("Alarm Time is in incorrect format.");
X	    new->dclock.alarm_time = "00:00";
X	    Alarm.hrs = Alarm.mins = 0;
X	}
X	new->dclock.alarm_time =
X	    strcpy(XtMalloc(strlen(new->dclock.alarm_time)+1),
X				   new->dclock.alarm_time);
X    }
X
X    GetGC(new);
X
X    if (!new->dclock.date_fmt || !*new->dclock.date_fmt)
X	saved_date = DATE_FMT;
X    if (new->dclock.date_fmt && !*new->dclock.date_fmt)
X	new->dclock.date_fmt = NULL;
X
X    /* Shouldn't be necessary, but play it safe anyway */
X    for (n = 0; n < 10; n++)
X	new->dclock.digits[n] = new->dclock.tiny_digits[n] = 0;
X    new->dclock.colon[0] = new->dclock.colon[1] = 0;
X}
X
Xstatic void
XGetGC(w)
XDclockWidget w;
X{
X    XGCValues  	xgcv;
X    XtGCMask	gc_mask =
X		    GCGraphicsExposures | GCFont | GCForeground | GCBackground;
X
X    xgcv.font = w->dclock.font->fid;
X    xgcv.graphics_exposures = FALSE;
X
X    if (w->dclock.reverse) {
X	xgcv.foreground = w->core.background_pixel;
X	xgcv.background = w->dclock.foreground;
X    } else {
X	xgcv.foreground = w->dclock.foreground;
X	xgcv.background = w->core.background_pixel;
X    }
X
X    w->dclock.foreGC = XtGetGC ((Widget) w, gc_mask, &xgcv);
X
X    /* the background is the reverse of the foreground -- so reverse twice */
X    if (w->dclock.reverse) {
X	xgcv.foreground = w->dclock.foreground;
X	xgcv.background = w->core.background_pixel;
X    } else {
X	xgcv.foreground = w->core.background_pixel;
X	xgcv.background = w->dclock.foreground;
X    }
X    w->dclock.backGC = XtGetGC ((Widget) w, gc_mask, &xgcv);
X}
X
Xstatic void
XRealize (w, valueMask, attrs)
XWidget w;
XXtValueMask *valueMask;
XXSetWindowAttributes *attrs;
X{
X    *valueMask |= CWBitGravity;
X    attrs->bit_gravity = ForgetGravity;
X    XtCreateWindow(w, InputOutput, (Visual *)CopyFromParent, *valueMask, attrs);
X    Resize(w);
X}
X
Xstatic void
XDestroy (w)
XDclockWidget w;
X{
X    int n;
X
X    if (w->dclock.interval_id)
X	XtRemoveTimeOut(w->dclock.interval_id);
X    XtReleaseGC (w, w->dclock.foreGC);
X    XtReleaseGC (w, w->dclock.backGC);
X    for (n = 0; n < 10; n++) {
X	XFreePixmap(XtDisplay(w), w->dclock.digits[n]);
X	XFreePixmap(XtDisplay(w), w->dclock.tiny_digits[n]);
X    }
X    if (w->dclock.colon[0])
X	XFreePixmap(XtDisplay(w), w->dclock.colon[0]);
X    if (w->dclock.colon[1])
X	XFreePixmap(XtDisplay(w), w->dclock.colon[1]);
X}
X 
X/* ARGSUSED */
Xstatic void
XResize  (w)
XDclockWidget    w;
X{
X    int i, digit_w, digit_h;
X    Pixmap pix;
X    GC gc = w->dclock.foreGC;
X
X    if (!XtIsRealized(w))
X	return;
X
X    winwidth = w->core.width;
X    winheight = w->core.height;
X
X    x_ratio = (double)winwidth / CLOCK_WIDTH;
X    y_ratio = (double)winheight / CLOCK_HEIGHT;
X
X    if (w->dclock.date_fmt || !w->dclock.display_time)
X	/* make win temporarily shorter so digits will fit on top of date */
X	winheight -= w->dclock.font->ascent + w->dclock.font->descent;
X
X    digit_w = winwidth/(4 - !w->dclock.seconds) - (int)(x_ratio*BORDER*5);
X
X    if (w->dclock.miltime)
X	digit_w -= digit_w/5;
X    digit_h = winheight - (int)(y_ratio * BORDER*2);
X    w->dclock.digit_w = digit_w;
X    w->dclock.digit_h = digit_h;
X
X    for (i = 0; i < 10; i++) {
X	/* Make the big digit */
X	if (w->dclock.digits[i])
X	    XFreePixmap(XtDisplay(w), w->dclock.digits[i]);
X	w->dclock.digits[i] =
X	      XCreatePixmap(XtDisplay(w), XtWindow(w), digit_w, digit_h,
X			    DefaultDepthOfScreen(XtScreen(w)));
X	make_number(w, w->dclock.digits[i], gc, i, digit_w, digit_h);
X
X	/* make smaller version of this digit for use by "seconds" */
X	if (w->dclock.tiny_digits[i])
X	    XFreePixmap(XtDisplay(w), w->dclock.tiny_digits[i]);
X	w->dclock.tiny_digits[i] =
X	    XCreatePixmap(XtDisplay(w), XtWindow(w), digit_w/2, digit_h/2,
X			    DefaultDepthOfScreen(XtScreen(w)));
X	make_number(w, w->dclock.tiny_digits[i], gc, i, digit_w/2, digit_h/2);
X    }
X    /* The colon[0] area is blank */
X    if (w->dclock.colon[0])
X	XFreePixmap(XtDisplay(w), w->dclock.colon[0]);
X    w->dclock.colon[0] =
X	XCreatePixmap(XtDisplay(w), XtWindow(w), digit_w, digit_h,
X		      DefaultDepthOfScreen(XtScreen(w)));
X
X    XFillRectangle(XtDisplay(w), w->dclock.colon[0],
X	w->dclock.backGC, 0, 0, digit_w,digit_h);
X
X    /* colon[1] area has two squares */
X    if (w->dclock.colon[1])
X	XFreePixmap(XtDisplay(w), w->dclock.colon[1]);
X    w->dclock.colon[1] = XCreatePixmap(XtDisplay(w), XtWindow(w),
X	(int)(30*x_ratio), digit_h,
X	DefaultDepthOfScreen(XtScreen(w)));
X
X    XFillRectangle(XtDisplay(w), w->dclock.colon[1],
X	w->dclock.backGC, 0, 0, (int)(30*x_ratio), digit_h);
X
X    XFillArc(XtDisplay(w), w->dclock.colon[1], gc,
X	(int)(15*x_ratio), digit_h/3, digit_w/7, digit_w/7,
X	0, 360 * 64);
X    XFillArc(XtDisplay(w), w->dclock.colon[1], gc,
X	(int)(15*x_ratio), (2*digit_h)/3, digit_w/7, digit_w/7,
X	0, 360 * 64);
X
X    /* to optimize scrolling information (see scroll_time()) */
X    old_pix[0] = w->dclock.digits[0];
X    old_pix[1] = old_pix[2] = old_pix[3] = 0;
X
X    if (w->dclock.date_fmt || !w->dclock.display_time)
X	/* restore size */
X	winheight += w->dclock.font->ascent + w->dclock.font->descent;
X}
X
X/* Defines to draw the (simulated) LED bars for each light in the digit */
X#define TOP    (pts[0].x = 2, pts[0].y = pts[1].y = 0, pts[1].x = w-2, \
X                pts[3].x = 2+6*x_ratio, pts[3].y = pts[2].y = 6*y_ratio, \
X		pts[2].x = w - pts[3].x, \
X		XFillPolygon(dpy, pix, gc, pts, 4, Convex, CoordModeOrigin));
X
X#define MIDDLE (pts[0].x = 2, pts[0].y = h/2 - 1, \
X		pts[1].x = 6*x_ratio, pts[1].y = h/2 - 3*y_ratio, \
X                pts[2].x = w-pts[1].x, pts[2].y = pts[1].y, \
X                pts[3].x = w-2, pts[3].y = h/2 - 1, \
X		pts[4].x = pts[2].x, pts[4].y = h/2 + 3*y_ratio, \
X		pts[5].x = pts[1].x, pts[5].y = pts[4].y, \
X		XFillPolygon(dpy, pix, gc, pts, 6, Convex, CoordModeOrigin));
X
X#define BOTTOM (pts[0].x = 2, pts[0].y = pts[1].y = h, pts[1].x = w-2, \
X                pts[3].x = 6*x_ratio, pts[3].y = pts[2].y = h - 6*y_ratio, \
X		pts[2].x = w - pts[3].x, \
X		XFillPolygon(dpy, pix, gc, pts, 4, Convex, CoordModeOrigin));
X
X#define T_LEFT (pts[0].x = pts[1].x = 0, pts[0].y = 2, pts[1].y = h/2-2, \
X                pts[2].x = pts[3].x = 6*x_ratio, \
X		pts[2].y = h/2 - 5*y_ratio, pts[3].y = 8*y_ratio, \
X		XFillPolygon(dpy, pix, gc, pts, 4, Convex, CoordModeOrigin));
X
X#define B_LEFT (pts[0].x = pts[1].x = 0, pts[0].y = h/2, pts[1].y = h, \
X                pts[2].x = pts[3].x = 6*x_ratio, \
X		pts[3].y = h/2 + 5*y_ratio, pts[2].y = h - 8*y_ratio, \
X		XFillPolygon(dpy, pix, gc, pts, 4, Convex, CoordModeOrigin));
X
X#define T_RIGHT (pts[0].x = pts[1].x = w, pts[0].y = 2, pts[1].y = h/2-2, \
X                 pts[2].x = pts[3].x = w-6*x_ratio, \
X		 pts[2].y = h/2 - 5*y_ratio, pts[3].y = 8*y_ratio, \
X		 XFillPolygon(dpy, pix, gc, pts, 4, Convex, CoordModeOrigin));
X
X#define B_RIGHT (pts[0].x = pts[1].x = w, pts[0].y = h/2, pts[1].y = h, \
X                 pts[2].x = pts[3].x = w-6*x_ratio, \
X		 pts[3].y = h/2 + 5*y_ratio, pts[2].y = h - 8*y_ratio, \
X		 XFillPolygon(dpy, pix, gc, pts, 4, Convex, CoordModeOrigin));
X
Xstatic void
Xmake_number(dw, pix, gc, n, w, h)
XDclockWidget dw;
XPixmap pix;
XGC gc;
Xint n, w, h;
X{
X    XPoint pts[6];
X    Display *dpy = XtDisplay(dw);
X
X    XFillRectangle(dpy, pix, dw->dclock.backGC, 0, 0, w, h);
X    switch(n) {
X	when 0: TOP  T_RIGHT  B_RIGHT  BOTTOM  B_LEFT  T_LEFT
X	when 1: T_RIGHT  B_RIGHT
X	when 2: TOP  T_RIGHT  MIDDLE  B_LEFT  BOTTOM
X	when 3: TOP  T_RIGHT  MIDDLE  B_RIGHT  BOTTOM
X	when 4: T_LEFT  MIDDLE  T_RIGHT  B_RIGHT
X	when 5: TOP  T_LEFT  MIDDLE  B_RIGHT  BOTTOM
X	when 6: T_LEFT  B_LEFT  MIDDLE BOTTOM B_RIGHT
X	when 7: TOP  T_RIGHT  B_RIGHT
X	when 8: T_LEFT B_LEFT MIDDLE TOP BOTTOM T_RIGHT B_RIGHT
X	when 9: TOP T_LEFT T_RIGHT MIDDLE B_RIGHT
X	otherwise: MIDDLE
X    }
X}
X
X/* ARGSUSED */
Xstatic void
XRedisplay  (w)
XDclockWidget    w;
X{
X    Boolean save_scroll = w->dclock.scroll;
X    long t;
X
X    if (!XtIsRealized(w))
X	return;
X
X    if (w->dclock.interval_id) {
X	XtRemoveTimeOut(w->dclock.interval_id);
X	w->dclock.interval_id = NULL;
X    }
X    XFillRectangle(XtDisplay(w), XtWindow(w), w->dclock.backGC,
X	0, 0, w->core.width, w->core.height);
X    before.tm_min = before.tm_hour = before.tm_wday = -1;
X    old_pix[0] = w->dclock.digits[0];
X    old_pix[1] = old_pix[2] = old_pix[3] = 0;
X    w->dclock.scroll = FALSE;
X    (void) show_time(w);
X    w->dclock.scroll = save_scroll;
X    if (w->dclock.display_time)
X	if (w->dclock.seconds)
X	    w->dclock.interval_id = XtAddTimeOut(1000, timeout, w);
X	else {
X	    t = time(0);
X	    w->dclock.interval_id =
X		XtAddTimeOut((unsigned long)(60 - (t % 60)) * 1000, timeout, w);
X	}
X}
X
Xstatic Boolean
Xshow_time(w)
XDclockWidget w;
X{
X    char buf[11];
X    Boolean alarm_went_off = False;
X    long t = time(0);
X    register struct tm *l_time = localtime(&t);
X    int digit_w = w->dclock.digit_w;
X    int digit_h = w->dclock.digit_h;
X    Display *dpy = XtDisplay(w);
X    Window win = XtWindow(w);
X    GC gc = w->dclock.foreGC;
X
X    if (w->dclock.display_time == True) {
X	if (w->dclock.miltime)
X	    (void) sprintf(buf, "%02d%02d", l_time->tm_hour, l_time->tm_min);
X	else
X	    (void) sprintf(buf, "%02d%02d",
X		 (l_time->tm_hour) ? ((l_time->tm_hour <= 12) ?
X		      l_time->tm_hour : l_time->tm_hour - 12) : 12,
X		  l_time->tm_min);
X    } else
X	/* display the alarm time */
X	(void) sprintf(buf, "%02d%02d", Alarm.hrs, Alarm.mins);
X
X    XCopyArea(dpy,
X	w->dclock.colon[!w->dclock.seconds || l_time->tm_sec & 1],
X	win, gc, 0, 0, (int)(30*x_ratio), digit_h,
X	(int)(!w->dclock.miltime * -digit_w * .75 +
X		2*BORDER*x_ratio) + 2 * digit_w,
X	(int)(BORDER*y_ratio));
X
X    if (l_time->tm_min != before.tm_min || l_time->tm_hour != before.tm_hour)
X	scroll_time(w, buf);
X
X    if (w->dclock.seconds) {
X	XCopyArea(dpy, w->dclock.tiny_digits[l_time->tm_sec/10], win, gc,
X	    0, 0, digit_w/2, digit_h/2,
X	    winwidth - 2*(digit_w/2 + (int)(BORDER*x_ratio)),
X	    (int)(BORDER*y_ratio));
X	XCopyArea(dpy, w->dclock.tiny_digits[l_time->tm_sec%10], win, gc,
X	    0, 0, digit_w/2, digit_h/2,
X	    winwidth - digit_w/2 - (int)(BORDER*x_ratio),
X	    (int)(BORDER*y_ratio));
X    }
X
X    if (w->dclock.date_fmt && before.tm_wday != l_time->tm_wday)
X	show_date(w, l_time);
X
X    before = *l_time;
X
X    if (w->dclock.alarm && Alarm.hrs == l_time->tm_hour &&
X	Alarm.mins == l_time->tm_min &&
X	l_time->tm_sec < 5) {
X	XBell(dpy, 50);
X	XBell(dpy, 50);
X	toggle_reverse_video(w);
X	alarm_went_off = True;
X    } else
X	/* if alarm didn't go off, check for hour/half-hour bell */
X	if (w->dclock.bell && (!w->dclock.seconds || l_time->tm_sec == 0) &&
X	    (l_time->tm_min == 0 || l_time->tm_min == 30)) {
X	    XBell(dpy, 50);
X	    if (l_time->tm_min == 0)
X		XBell(dpy, 50);
X	}
X    return alarm_went_off;
X}
X
Xstatic void
Xscroll_time(w, p)
XDclockWidget w;
Xregister char *p;
X{
X    int scroll_me[4], J = winheight - BORDER*2*y_ratio + 1;
X    register int i, j, incr;
X    int digit_w = w->dclock.digit_w;
X    int digit_h = w->dclock.digit_h;
X    Display *dpy = XtDisplay(w);
X    Window win = XtWindow(w);
X    GC gc = w->dclock.foreGC;
X    Pixmap tmp[4];
X
X    if (w->dclock.date_fmt || !w->dclock.display_time)
X	J -= w->dclock.font->ascent + w->dclock.font->descent;
X
X    if ((incr = J / 30) < 1)
X	incr = 1;
X
X#define x ((int)(!w->dclock.miltime * -digit_w * .75 + ((i+1)*BORDER + \
X	(i>1)*30)*x_ratio) + i*digit_w)
X#define y (int)(BORDER * y_ratio)
X
X    for (i = 0; i < 4; i++)    /* if pixmaps don't match, scroll it */
X	scroll_me[i] = ((tmp[i] = w->dclock.digits[*p++ - '0']) != old_pix[i]);
X
X    if (w->dclock.scroll &&
X	(scroll_me[0] || scroll_me[1] || scroll_me[2] || scroll_me[3]))
X	for (j = 0; j <= J; j += incr)
X	    for (i = 0; i < 4; i++)
X		if (scroll_me[i]) {
X		    if (old_pix[i])
X			XCopyArea(dpy, old_pix[i], win, gc,
X			    0, j, digit_w, digit_h - j, x, y);
X		    if (i || tmp[i] == w->dclock.digits[1] || w->dclock.miltime)
X			XCopyArea(dpy, tmp[i], win, gc,
X			    0, 0, digit_w, j, x, y + digit_h - j);
X		    else
X			XCopyArea(dpy, w->dclock.colon[0], win, gc,
X			    0, 0, x+5, y + digit_h - j, digit_w, j);
X		}
X    for (i = 0; i < 4; i++) {
X	if (i || tmp[0] == w->dclock.digits[1] || w->dclock.miltime)
X	    XCopyArea(dpy, tmp[i], win, gc, 0,0, digit_w, digit_h, x,y);
X	else
X	    XCopyArea(dpy, w->dclock.colon[0], win, gc,
X		0,0, digit_w,digit_h, x+5,y);
X	if (!w->dclock.display_time && i == cur_position)
X	    outline_digit(w, cur_position, True);
X    }
X#undef x
X#undef y
X    for (i = 0; i < 4; i++)
X	old_pix[i] = tmp[i];
X}
X
Xstatic char *months[] = {
X    "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
X    "Aug", "Sep", "Oct", "Nov", "Dec"
X};
Xstatic char *Months[] = {
X    "January", "February", "March", "April", "May", "June", "July",
X    "August", "September", "October", "November", "December"
X};
Xstatic char *days[] = {
X    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
X};
Xstatic char *Days[] = {
X    "Sunday", "Monday", "Tuesday", "Wednesday",
X    "Thursday", "Friday", "Saturday", "Sunday"
X};
X
Xstatic void
Xshow_date(w, now)
XDclockWidget w;
Xstruct tm *now;
X{
X    char datestr[128];
X    register char *datep = datestr, *p;
X    int x;
X
X    if (!w->dclock.display_time)
X	datep += strlen(strcpy(datep, "Push HERE to Set/Unset Alarm"));
X    else for (p = w->dclock.date_fmt; p && *p; p++) {
X	if (*p != '%')
X	    *datep++ = *p;
X	else switch (*++p) {
X	    when 'M':
X		datep += strlen(strcpy(datep, Months[now->tm_mon]));
X	    when 'm':
X		datep += strlen(strcpy(datep, months[now->tm_mon]));
X	    when 'W':
X		datep += strlen(strcpy(datep, Days[now->tm_wday]));
X	    when 'w':
X		datep += strlen(strcpy(datep, days[now->tm_wday]));
X	    when 'd':
X		if (now->tm_mday >= 10)
X		    *datep++ = (now->tm_mday / 10 + '0');
X		*datep++ = now->tm_mday % 10 + '0';
X	    when 'Y':
X		*datep++ = '1', *datep++ = '9';
X		/* fall thru */
X	    case 'y':
X		*datep++ = now->tm_year / 10 + '0';
X		*datep++ = now->tm_year % 10 + '0';
X	    when '%':
X		*datep++ = *p;
X	    otherwise: ; /* nothing */
X	}
X    }
X    *datep = 0;
X
X    x = (w->core.width - XTextWidth(w->dclock.font, datestr, datep-datestr))/2;
X    if (x < 2)
X	x = 2;
X
X    /* remove what was there in case the whole thing isn't overwritten */
X    XFillRectangle(XtDisplay(w), XtWindow(w), w->dclock.backGC,
X	0, winheight - (w->dclock.font->ascent + w->dclock.font->descent),
X	winwidth, w->dclock.font->ascent + w->dclock.font->descent);
X
X    XDrawString(XtDisplay(w), XtWindow(w), w->dclock.foreGC,
X	x, winheight - BORDER, datestr, (int)(datep - datestr));
X
X    if (w->dclock.alarm)
X	XDrawString(XtDisplay(w), XtWindow(w), w->dclock.foreGC,
X	    20, winheight - BORDER, "*", 1);
X}
X
Xstatic void
Xtimeout(w, id)
XDclockWidget w;
XXtIntervalId *id;
X{
X    Boolean alarm_went_off = show_time(w);
X    w->dclock.interval_id =
X	XtAddTimeOut((alarm_went_off || w->dclock.seconds)? 1000 : 60000,
X			timeout, w);
X}
X
X/* ARGSUSED */
Xstatic Boolean
XSetValues (current, request, new)
XDclockWidget current, request, new;
X{
X    Boolean do_redraw = False;
X
X    if (current->dclock.display_time != new->dclock.display_time) {
X	before.tm_min = before.tm_hour = before.tm_wday = -1;
X	new->dclock.miltime = True; /* old state needs to be saved */
X	do_redraw = True;
X    }
X    if (current->dclock.alarm_time != new->dclock.alarm_time) {
X	if (sscanf(new->dclock.alarm_time, "%2d:%2d",
X		&Alarm.hrs, &Alarm.mins) != 2 || Alarm.hrs >= 24 ||
X		Alarm.mins >= 60) {
X	    XtWarning("Alarm Time is in incorrect format.");
X	    new->dclock.alarm_time = "00:00";
X	    Alarm.hrs = Alarm.mins = 0;
X	}
X	new->dclock.alarm_time =
X	    strcpy(XtMalloc(strlen(new->dclock.alarm_time)+1),
X				   new->dclock.alarm_time);
X	do_redraw = True;
X    }
X
X    if (new->dclock.foreground != current->dclock.foreground
X    ||  new->core.background_pixel != current->core.background_pixel
X    ||  new->dclock.reverse != current->dclock.reverse
X    ||  new->dclock.miltime != current->dclock.miltime) {
X	XtReleaseGC (current, current->dclock.foreGC);
X	XtReleaseGC (current, current->dclock.backGC);
X	GetGC(new);
X	Resize(new); /* pixmaps need to be redrawn */
X	do_redraw = True;
X    }
X    if (new->dclock.seconds != current->dclock.seconds) {
X	if (current->dclock.interval_id) {
X	    XtRemoveTimeOut(current->dclock.interval_id);
X	    current->dclock.interval_id = NULL;
X	}
X	Resize(new);
X	do_redraw = True;
X    }
X    if (new->dclock.date_fmt != current->dclock.date_fmt) {
X	do_redraw = True;
X	before.tm_wday = -1;
X    }
X    if (new->dclock.alarm != current->dclock.alarm)
X	do_redraw = True;
X
X    return do_redraw;
X}
X
Xstatic void
Xtoggle_date(w)
XDclockWidget w;
X{
X    char *tmp;
X
X    if (!w->dclock.display_time) {
X	XBell(XtDisplay(w), 50);
X	return;
X    }
X    tmp = w->dclock.date_fmt;
X    w->dclock.date_fmt = saved_date;
X    saved_date = tmp;
X    before.tm_wday = -1;
X    Resize(w);
X    Redisplay(w);
X}
X
Xstatic void
Xtoggle_bell(w)
XDclockWidget w;
X{
X    if (w->dclock.bell = !w->dclock.bell)
X	XBell(XtDisplay(w), 50);
X}
X
Xstatic void
Xtoggle_scroll(w)
XDclockWidget w;
X{
X    w->dclock.scroll = !w->dclock.scroll;
X}
X
Xstatic void
Xtoggle_reverse_video(w)
XDclockWidget w;
X{
X    Arg arg;
X
X    XtSetArg(arg, XtNreverseVideo, !w->dclock.reverse);
X    XtSetValues(w, &arg, 1);
X}
X
Xstatic void
Xtoggle_military_time(w)
XDclockWidget w;
X{
X    Arg arg;
X
X    if (!w->dclock.display_time) {
X	XBell(XtDisplay(w), 50);
X	return;
X    }
X    XtSetArg(arg, XtNmilitaryTime, !w->dclock.miltime);
X    XtSetValues(w, &arg, 1);
X}
X
Xstatic void
Xtoggle_seconds(w)
XDclockWidget w;
X{
X    Arg arg;
X
X    if (!w->dclock.display_time) {
X	XBell(XtDisplay(w), 50);
X	return;
X    }
X    XtSetArg(arg, XtNseconds, !w->dclock.seconds);
X    XtSetValues(w, &arg, 1);
X}
X
Xstatic void
Xtoggle_alarm(w)
XDclockWidget w;
X{
X    Arg arg;
X
X    XtSetArg(arg, XtNalarm, !w->dclock.alarm);
X    XtSetValues(w, &arg, 1);
X}
X
Xstatic void
Xset_alarm(w, event)
XDclockWidget w;
XXButtonEvent *event;
X{
X    static saved_secs, saved_miltime;
X
X    if (event->button == 3) {
X	if (!(w->dclock.display_time = !w->dclock.display_time)) {
X	    XtRemoveTimeOut(w->dclock.interval_id);
X	    saved_secs = w->dclock.seconds, w->dclock.seconds = False;
X	    saved_miltime = w->dclock.miltime, w->dclock.miltime = True;
X	    w->dclock.interval_id = NULL;
X	} else {
X	    w->dclock.seconds = saved_secs;
X	    w->dclock.miltime = saved_miltime;
X	}
X	Resize(w);
X	Redisplay(w);
X    } else if (!w->dclock.display_time &&
X	    (event->button == 1 || event->button == 2)) {
X	/* get the digit under the position (1-4) the mouse is over
X	 * and increment (possibly wrap around) to next digit.
X	 */
X	int i, x, y = (int)((BORDER/2)*y_ratio);
X	/* first check to see if user toggles the alarm */
X	if (event->y >=
X		winheight - (w->dclock.font->ascent + w->dclock.font->descent))
X	    toggle_alarm(w);
X	else for (i = 0; i < 4; i++) {
X	    x = (int)(((i+1)*BORDER + (i>1)*30)*x_ratio) + i*w->dclock.digit_w;
X	    x -= (int)(BORDER * x_ratio / 2);
X	    if (event->x < x + w->dclock.digit_w) {
X		if (cur_position == i) {
X		    int digit = w->dclock.alarm_time[i>1?i+1:i] - '0';
X		    int mod;
X		    switch (i) {
X			when 0:
X			    if (Alarm.hrs > 13 && digit == 1)
X				digit++;
X			    mod = 3;
X			    before.tm_hour = -1;
X			when 1 :
X			    mod = (Alarm.hrs < 20)? 10 : 4;
X			    before.tm_hour = -1;
X			when 2:
X			    mod = 6;
X			    before.tm_min = -1;
X			when 3 :
X			    mod = 10;
X			    before.tm_min = -1;
X		    }
X		    if (event->button == 1)
X			digit = (digit + 1) % mod;
X		    else if (--digit < 0)
X			digit = mod-1;
X		    w->dclock.alarm_time[i>1?i+1:i] = digit + '0';
X		    (void) sscanf(w->dclock.alarm_time, "%2d:%2d",
X			    &Alarm.hrs, &Alarm.mins);
X		    (void) show_time(w);
X		} else {
X		    outline_digit(w, cur_position, False);
X		    outline_digit(w, cur_position = i, True);
X		}
X		break;
X	    }
X	}
X    } else
X	XBell(XtDisplay(w), 50);
X}
X
Xstatic void
Xoutline_digit(w, i, draw_it)
XDclockWidget w;
Xint i;
XBoolean draw_it;
X{
X    int x, y = (int)((BORDER/2)*y_ratio);
X
X    x = (int)((i*BORDER + (i>1)*30)*x_ratio) + i*w->dclock.digit_w;
X    x -= (int)(BORDER * x_ratio / 2);
X
X    XDrawRectangle(XtDisplay(w), XtWindow(w),
X	draw_it? w->dclock.foreGC : w->dclock.backGC,
X	x+5, y,
X	w->dclock.digit_w + (int)(BORDER*x_ratio),
X	w->dclock.digit_h + (int)(BORDER*y_ratio));
X    x = (int)((cur_position*BORDER + (cur_position>1)*30)*x_ratio) +
X	cur_position * w->dclock.digit_w;
X}
END_OF_FILE
if test 25043 -ne `wc -c <'Dclock.c'`; then
    echo shar: \"'Dclock.c'\" unpacked with wrong size!
fi
# end of 'Dclock.c'
fi
if test -f 'Dclock.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Dclock.h'\"
else
echo shar: Extracting \"'Dclock.h'\" \(1760 characters\)
sed "s/^X//" >'Dclock.h' <<'END_OF_FILE'
X/*
X * Dclock.c -- a digital clock widget.
X * Copyright (c) Dan Heller <island!argv@sun.com> 1988
X */
X#ifndef _XtDclock_h
X#define _XtDclock_h
X
X/* Parameters:
X
X Name                Class              RepType         Default Value
X ----                -----              -------         -------------
X alarm		     Boolean		Boolean		False
X alarmTime	     Time		long		00:00:00
X displayTime	     Boolean		Boolean		True
X background          Background         pixel           White
X bell		     Boolean		Boolean		False
X border              BorderColor        pixel           Black      
X borderWidth         BorderWidth        int             1
X date		     String		String		NULL
X destroyCallback     Callback           Pointer         NULL
X foreground          Foreground         Pixel           Black 
X height              Height             int             80
X mappedWhenManaged   MappedWhenManaged  Boolean         True
X reverseVideo        ReverseVideo       Boolean         False
X seconds	     Boolean		Boolean		False
X scroll		     Boolean		Boolean		True
X time		     Time		long		current time
X x                   Position           int             0 
X y                   Position           int             0
X
X*/
X
X#ifndef XtRDimension
X#define XtRDimension	"dimension"
X#endif /* XtRDimension */
X
X#define XtRTime		"Time"
X#define XtCTime		"Time"
X
X#define XtNseconds	"seconds"
X#define XtNalarm	"alarm"
X#define XtNalarmTime	"alarmTime"
X#define XtNdisplayTime	"displayTime"
X#define XtNtime		"time"
X#define XtNbell		"bell"
X#define XtNscroll	"scroll"
X#define XtNdate		"date"
X#define XtNmilitaryTime	"militaryTime"
X
Xtypedef struct _DclockRec *DclockWidget;
Xtypedef struct _DclockClassRec *DclockWidgetClass;
X
Xextern WidgetClass dclockWidgetClass;
X
X#endif /* _XtDclock_h */
END_OF_FILE
if test 1760 -ne `wc -c <'Dclock.h'`; then
    echo shar: \"'Dclock.h'\" unpacked with wrong size!
fi
# end of 'Dclock.h'
fi
if test -f 'DclockP.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'DclockP.h'\"
else
echo shar: Extracting \"'DclockP.h'\" \(1096 characters\)
sed "s/^X//" >'DclockP.h' <<'END_OF_FILE'
X/*
X * Dclock.c -- a digital clock widget.
X * Copyright (c) Dan Heller <island!argv@sun.com> 1988
X */
X#ifndef _XtDclockP_h
X#define _XtDclockP_h
X
X#include <X11/CoreP.h>
X#include "Dclock.h"
X
Xtypedef struct {
X    Pixel      		foreground;
X    Boolean    		reverse;
X    Boolean		scroll;
X    Boolean		seconds;
X    Boolean		bell;
X    Boolean		miltime;
X    Boolean		display_time;	/* when false, display alarm time */
X    Boolean		alarm;		/* alarm goes off at alarm time */
X    String		alarm_time;	/* time alarm goes off "14:30:00" */
X    String		date_fmt;
X    XFontStruct		*font;
X
X    /* non-resources (e.g. user can't set) */
X    XtIntervalId	interval_id;
X    GC			foreGC, backGC;
X    int			digit_w, digit_h;
X    Pixmap		digits[10];
X    Pixmap		tiny_digits[10];
X    Pixmap		colon[2];
X} DclockPart;
X
Xtypedef struct _DclockRec {
X    CorePart	core;
X    DclockPart	dclock;
X} DclockRec;
X
Xtypedef struct {int dummy;} DclockClassPart;
X
Xtypedef struct _DclockClassRec {
X    CoreClassPart	core_class;
X    DclockClassPart	dclock_class;
X} DclockClassRec;
X
Xextern DclockClassRec dclockClassRec;
X
X#endif _XtDclockP_h
END_OF_FILE
if test 1096 -ne `wc -c <'DclockP.h'`; then
    echo shar: \"'DclockP.h'\" unpacked with wrong size!
fi
# end of 'DclockP.h'
fi
if test -f 'dclock.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dclock.c'\"
else
echo shar: Extracting \"'dclock.c'\" \(3221 characters\)
sed "s/^X//" >'dclock.c' <<'END_OF_FILE'
X/*
X * Copyright (c) Dan Heller <island!argv@sun.com> 1988
X * dclock -- program to demonstrate how to use the digital-clock widget.
X * To specify a date, the date format is a string of characters.  If a
X * character in the string is a %-sign, the next character is examined
X * and a value is inserted into the string.  Example:
X *    dclock -date "Today is %W"
X * The date string will print "Today is" and then the %W will be replaced
X * by the current weekday name.  The parameters are:
X *    %W	full weekday name
X *    %w	three-char weekday name (sun, mon, tue, wed...)
X *    %M	full month name
X *    %m        three-char abbreviation for that month (jan, feb, mar...)
X *    %d	The date (numerical number of the month)
X *    %Y	full year (4 digits)
X *    %y	2-digit year number
X *
X * To specify seconds to be displayed, use "-seconds" or use the resource
X * manager: *Dclock.seconds: on
X */
X#include <stdio.h>
X#include <X11/Intrinsic.h>
X#include "Dclock.h"
X
Xstatic XrmOptionDescRec options[] = {
X    {"-date",	 "*Dclock.date",	XrmoptionSepArg, NULL },
X    {"-seconds", "*Dclock.seconds",	XrmoptionNoArg, "TRUE" },
X    {"-miltime", "*Dclock.miltime",	XrmoptionNoArg, "TRUE" },
X    {"-bell",	 "*Dclock.bell",	XrmoptionNoArg, "TRUE" },
X    {"-scroll",  "*Dclock.scroll",	XrmoptionNoArg, "TRUE" },
X    {"-noscroll","*Dclock.scroll",	XrmoptionNoArg, "FALSE" },
X    {"-alarm",   "*Dclock.alarm",	XrmoptionNoArg, "TRUE" },
X    {"-noalarm",   "*Dclock.alarm",	XrmoptionNoArg, "FALSE" },
X    {"-alarmTime","*Dclock.alarmTime",	XrmoptionSepArg, NULL },
X};
X
Xstatic void
XUsage(name, args)
XString name, *args;
X{
X    static char *help_message[] = {
X	"where options include:",
X	"    -bg color                  background color",
X	"    -fg color                  foreground color",
X	"    -fn font			font name",
X	"    -geometry geom             size of mailbox",
X	"    -display host:dpy          X server to contact",
X	"    -seconds [on/off]		display seconds",
X	"    -miltime [on/off]		display time in 24 hour format",
X	"    -bell [on/off]		ring bell each half hour",
X	"    -scroll [on/off]		turn on/off scrolling of numbers",
X	"    -date \"date format\"	show the date in specified format",
X	"    -alarm [on/off]		turn on/off alarm",
X	"    -alarmTime hh:mm		Time alarm goes off",
X	NULL
X    };
X    char **cpp;
X
X    fprintf(stderr, "Invalid Args:");
X    while (*args)
X	fprintf(stderr, " \"%s\"", *args++);
X    fputc('\n', stderr);
X    fprintf(stderr, "usage: %s [-options ...]\n", name);
X    for (cpp = help_message; *cpp; cpp++)
X	fprintf(stderr, "%s\n", *cpp);
X    exit(1);
X}
X
Xstatic void
Xquit()
X{
X    exit(0);
X}
X
Xstatic XtActionsRec actionsList[] = {
X    { "quit",	quit },
X};
X
Xmain(argc, argv)
Xchar *argv[];
X{
X    Widget toplevel, clock_w;
X    char *name, *rindex();
X    Arg arg;
X
X    if (name = rindex(argv[0], '/'))
X	name++;
X    else
X	name = argv[0];
X
X    toplevel = XtInitialize(name, "DClock", options, XtNumber(options),
X			    &argc, argv);
X
X    if (argc != 1)
X	Usage(name, argv+1);
X
X    clock_w = XtCreateManagedWidget(name, dclockWidgetClass, toplevel, NULL, 0);
X    XtAddActions(actionsList, 1);
X    XtOverrideTranslations(clock_w, XtParseTranslationTable("<Key>q: quit()"));
X
X    XtRealizeWidget(toplevel);
X    XtMainLoop();
X}
END_OF_FILE
if test 3221 -ne `wc -c <'dclock.c'`; then
    echo shar: \"'dclock.c'\" unpacked with wrong size!
fi
# end of 'dclock.c'
fi
if test -f 'patchlevel.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'patchlevel.h'\"
else
echo shar: Extracting \"'patchlevel.h'\" \(21 characters\)
sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
X#define PATCHLEVEL 3
END_OF_FILE
if test 21 -ne `wc -c <'patchlevel.h'`; then
    echo shar: \"'patchlevel.h'\" unpacked with wrong size!
fi
# end of 'patchlevel.h'
fi
echo shar: End of shell archive.
exit 0