[comp.windows.x] Yet another xclock

jw@pan.UUCP (Jamie Watson) (05/04/87)

The following is a heavily modified version of xclock.  It has the
following major changes:

- Analog and digital displays are combined in one program.  Analog is
  the initial display; digital is the icon form.

- The analog version shows the day and date on the clock face.

- An alarm feature has been added.

- A command line argument has been added to allow the alarm in this
  xclock to be used as a simple replacement for leave(1).

Of course, there is still a lot to be done.

- There is no support for color displays included.  Although I used
  large pieces from the V10R3 distribution tape, I started this one
  from scratch.  I have no color display at this time, so even if I
  had tried to incorporate support for color, I would have no idea if
  it worked or not.  Besides, I have to leave something for others to
  do, don't I?

- My environment is SysV.3 based.  In light of the fact that most X
  sites are still Berkelix based, I think I have left the source in a
  condition that will compile on bsd without extra command line flags;
  compiling on SYSV requires the -DSYSV flag.  Again, though, I can
  only test it on what I have.  If you find that it doesn't compile on
  bsd, it shouldn't be too hard to fix.

- The parsing of the alarm time from the command line or .Xdefaults
  file is simple-minded, to be kind.

- I would like to have a way to specify on the command line the format
  to be used in the digital date/time display.  I recall seeing a
  program in net.sources some time back that duplicated the function
  of the SysV date(1) command in this regard.  I thought I saved it,
  but of course now that I am looking for it I can't find it.  Oh
  well.

- You would think that after all I've been through with translating
  various tools and utilities, that I would be careful to make my own
  programs easy to translate into languages and formats other than
  English/American, wouldn't you?  Well, you'd be wrong. Sigh.

- Someone with some combination of more brains, more experience with
  X, and more dedication that me might be able to come up with a way
  to change fonts on the fly when the analog window is resized.  I
  really don't want to think that hard about it.

- There should be some way to calculate if the day/date windows are
  going to overwrite part of the clock border, based on the window
  size and the font selected.  However, I don't remember enough of my
  high school geometry to figure out how.  Besides, this is something
  that should be started automatically, from a menu of some kind, so
  once you find a combination of geometry and font you like, you don't
  have to fool with it anyway.  Diminishing return, and all that.

Some other implementation notes:

- I have seen the X.V10R4+ version of xclock; I don't like the hands
  on it, so I chose not to put them into this one.

- SysV has no select(2) call.  Some versions of X on SysV are being
  implemented with streams, so poll(2) can be used to accomplish the
  same basic function of reading input with timeout.  My version has
  neither of these, unfortunately, so I had to make a new plan.  I
  decided to use alarm and signal(ugh).  Ugly, old fashioned, blah,
  blah, blah, in the end it works.  For a good time, try using
  sigset(2) in the same program as sleep(3).  The V.3 programmer's
  manual says not to use signal(2) and sigset(2) in the same program;
  this makes it obvious why sleep(3) and sigset(2) cannot be used
  together.  Does Berklix have the same limitation?  I wonder how many
  other syscalls/functions use signal(2), and so will not work with a
  program that uses sigset(2)?

- There are a few other places where X on SysV requires things that
  aren't there (pty's, for example).  While I didn't have to worry
  about them in this particular program, I will in the future.  What
  are other people doing about this?

This was the first program I wrote/modified with X, so my objective
was primarily to learn as much as possible about programming with X.
If you think I have made some stupid decisions or mistakes in the
design or coding, feel free to let me know.  Constructive criticism
is (almost) always welcome.  If you don't like it, or it doesn't
work for you, feel free to write me, but I reserve the right to tell
you I just don't care.

jw

James Watson			...!mcvax!cernvax!paninfo!jw
Pansystem Informatics AG	Tel: [41] (1) 833.36.44
Bahnhofstrasse 50		Telex: 827 332. pi ch
8305 Dietlikon
Switzerland

#! /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 shell archive."
# Contents:  xclock.c xclock.cursor alarm.cursor slash.cursor bell.bm
#   Makefile xclock.1
# Wrapped by jw@pan on Mon May  4 14:08:29 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f xclock.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"xclock.c\"
else
echo shar: Extracting \"xclock.c\" \(14768 characters\)
sed "s/^X//" >xclock.c <<'END_OF_xclock.c'
X#ifdef SYSV
X#include <X/mitcopyright.h>
X#include <string.h>
X#include <time.h>
X#else
X#include <X/mit-copyright.h>
X#include <strings.h>
X#include <sys/time.h>
X#endif
X#include <stdio.h>
X#include <signal.h>
X#include <X/Xlib.h>
X#include "bell.bm"
X#include "xclock.cursor"
X#include "slash.cursor"
X#include "alarm.cursor"
X
Xextern char *getenv();
Xextern long time();
Xextern unsigned alarm(), sleep();
Xextern void exit();
X
X#define PI 3.141592
X#define TRUE 1
X#define FALSE 0
X#define DEF_INTERVAL 60
X#define MIN_ANL_SIZE 75
X#define DEF_FONT "6x10"
X#define DEF_GEOMETRY "=100x100-0+0"
X#define DEF_ANALOG_PAD 2
X#define DEF_DIGITAL_PAD 3
X#define DEF_BORDER_WIDTH 2
X
XWindow AnalogWindow, IconWindow, DateWindow, DayWindow, BellWindow;
XCursor ClockCursor, DateCursor, BellCursor;
XFont f;
XFontInfo fi;
X
Xchar *geometry, *FontName, *DspName = NULL;
Xint rv, DigitalPad, AnalogPad, BorderWidth;
Xunsigned interval;
X
X/*
X * Miscellany for use in drawing the analog clock.
X */
XVertex SegBuff[128];
XVertex *SegBuffPtr;
Xint NumSegs = 0;
Xint radius, XCenter, YCenter, sec_hand_len, min_hand_len, hour_hand_len;
X
Xint anl_width, anl_height;
Xint FgPixel = BlackPixel, BgPixel = WhitePixel;
Xshort alarm_on = FALSE, ringing = FALSE, auto_alarm_off,
X      Iconified = FALSE, AlarmSetMode = FALSE;
Xstatic struct {
X    int hour, min;
X} al_tm;
Xstruct tm *tm;
X
Xstatic char *MonthName[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
X			    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
Xstatic char *DayName[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
X
Xhandler () {
X    (void) signal (SIGALRM, handler);
X    ShowTime ();
X    (void) alarm (ringing ? 1 : interval);
X}
X
Xmain (argc, argv)
Xint argc;
Xchar **argv;
X{
X    ReadDefaults (*argv);
X    ParseOptions (argc, argv);
X    XWinSetup (*argv);
X    SegBuffPtr = SegBuff;
X    SetAnalogSize();
X    DrawClockFace(sec_hand_len, radius);
X    (void) signal (SIGALRM, handler);
X    ShowTime ();
X    (void) alarm (interval == 1 ? interval : 60 - tm->tm_sec);
X
X    while (1) {
X	XButtonEvent event;
X
X	XNextEvent (&event);
X	if (event.window == AnalogWindow) {
X	    XExposeEvent *wevent = (XExposeEvent *) &event;
X	    Iconified = FALSE;
X	    if (wevent->width != anl_width || wevent->height != anl_height) {
X		anl_width = wevent->width;
X		anl_height = wevent->height;
X		SetAnalogSize();
X	    }
X	    DrawClockFace(sec_hand_len, radius);
X	    ShowTime ();
X	}
X	else if (event.window == IconWindow && event.type == ExposeWindow) {
X	    Iconified = TRUE;
X	    ShowTime ();
X	}
X	else if (event.window == BellWindow)
X	    switch (event.type) {
X	    case ButtonPressed:
X		ringing = alarm_on = FALSE;
X		XUnmapWindow (BellWindow);
X		break;
X	    case ExposeWindow:
X		XBitmapBitsPut(BellWindow, 0, 0, bell_width, bell_height,
X		    bell_bits, FgPixel, BgPixel, 0, GXcopy, AllPlanes);
X		break;
X	    }
X	else if (event.type == EnterWindow) {
X	    XClear (DateWindow);
X	    AlarmSetMode = TRUE;
X	    set_alarm ();
X	    AlarmSetMode = FALSE;
X	    ShowDate ();
X	}
X    }
X}
X
X/*
X * Get the defaults
X */
XReadDefaults (pname)
Xchar *pname;
X{
X    char *def_value;
X
X    if ((def_value = XGetDefault (pname, "BodyFont")) != NULL)
X	FontName = def_value;
X    else FontName = DEF_FONT;
X    if ((def_value = XGetDefault (pname, "ReverseVideo")) != NULL &&
X		strcmp (def_value, "on") == 0)
X	rv = TRUE;
X    else rv = FALSE;
X    if ((def_value = XGetDefault (pname, "AnalogPad")) != NULL)
X	AnalogPad = atoi (def_value);
X    else AnalogPad = DEF_ANALOG_PAD;
X    if ((def_value = XGetDefault (pname, "DigitalPad")) != NULL)
X	DigitalPad = atoi (def_value);
X    else DigitalPad = DEF_DIGITAL_PAD;
X    if ((def_value = XGetDefault (pname, "BorderWidth")) != NULL)
X	BorderWidth = atoi (def_value);
X    else BorderWidth = DEF_BORDER_WIDTH;
X    if ((def_value = XGetDefault (pname, "Update")) != NULL)
X	interval = atoi (def_value);
X    else interval = DEF_INTERVAL;
X    if ((def_value = XGetDefault (pname, "AlarmTime")) != NULL)
X	AlarmTime (def_value);
X    if ((def_value = XGetDefault (pname, "ManualAlarm")) != NULL &&
X		strcmp (def_value, "on") == 0)
X	auto_alarm_off = FALSE;
X    else auto_alarm_off = TRUE;
X}
X
X/*
X * Parse command line options.
X */
XParseOptions (argc, argv)
Xint argc;
Xchar **argv;
X{
X    for (argv++; --argc; argv++) {
X	if (**argv == '=') {
X	    geometry = *argv;
X	    continue;
X	}
X	if (strchr (*argv, ':') != NULL) {
X	    DspName = *argv;
X	    continue;
X	}
X	if (strcmp (*argv, "-rv") == 0 || strcmp (*argv, "-reverse") == 0) {
X	    rv = TRUE;
X	    continue;
X	}
X        if (strcmp (*argv, "-ma") == 0 || strcmp (*argv, "-manualalarm") == 0) {
X	    auto_alarm_off = FALSE;
X	    continue;
X	}
X	if (**argv != '-' || argc == 1)
X	    continue;
X	if (strcmp (*argv, "-fn") == 0 || strcmp (*argv, "-font") == 0) {
X	    FontName = *++argv;
X	    argc--;
X	    continue;
X	}
X	if (strcmp (*argv, "-update") == 0 || strcmp (*argv, "-u") == 0) {
X	    interval = atoi (*++argv);
X	    argc--;
X	    continue;
X	}
X	if (strcmp (*argv, "-bw") == 0 || strcmp (*argv, "-border") == 0) {
X	    BorderWidth = atoi (*++argv);
X	    argc--;
X	    continue;
X	}
X	if (strcmp (*argv, "-ap") == 0 || strcmp (*argv, "-analogpad") == 0) {
X	    AnalogPad = atoi (*++argv);
X	    argc--;
X	    continue;
X	}
X	if (strcmp (*argv, "-dp") == 0 || strcmp (*argv, "-digitalpad") == 0) {
X	    DigitalPad = atoi (*++argv);
X	    argc--;
X	    continue;
X	}
X	if (strcmp (*argv, "-alarm") == 0) {
X	    AlarmTime (*++argv);
X	    argc--;
X	    continue;
X	}
X    }
X    if (rv) {
X	FgPixel = WhitePixel;
X	BgPixel = BlackPixel;
X    }
X    if (interval < 1)
X	interval = 1;
X}
X
XAlarmTime (argv)
Xchar *argv;
X{
X    al_tm.hour = atoi (argv);
X    al_tm.min = atoi (strchr (argv, ':') + 1);
X    alarm_on = TRUE;
X}
X
X/*
X * Set up all the various parts of the windowing system.
X */
XXWinSetup (pname)
Xchar *pname;
X{
X    OpaqueFrame frame;
X    WindowInfo winfo;
X    int IconWidth = interval == 1 ? 20 : 17;
X
X    if (XOpenDisplay(DspName) == NULL || (f = XGetFont (FontName)) == 0)
X	exit (1);
X    XQueryFont (f, &fi);
X    frame.bdrwidth = BorderWidth;
X    frame.border = rv ? WhitePixmap : BlackPixmap;
X    frame.background = rv ? BlackPixmap : WhitePixmap;
X    AnalogWindow = XCreate ("Xclock", pname, geometry, DEF_GEOMETRY, &frame,
X			MIN_ANL_SIZE, MIN_ANL_SIZE);
X    XQueryWindow (AnalogWindow, &winfo);
X    anl_width = winfo.width;
X    anl_height = winfo.height;
X    IconWindow = XCreateWindow (RootWindow, 0, 0,
X		fi.width * IconWidth + 2 * DigitalPad,
X		fi.height + 2 * DigitalPad, BorderWidth,
X		rv ? WhitePixmap : BlackPixmap,
X		rv ? BlackPixmap : WhitePixmap);
X    DayWindow = XCreateTransparency (AnalogWindow,
X		anl_width/2 - fi.width*3/2, anl_height/4 - fi.height/2,
X		fi.width*3, fi.height);
X    DateWindow = XCreateTransparency (AnalogWindow,
X		anl_width/2 - fi.width*6/2,
X		anl_height*3/4 - fi.height/2,
X		fi.width*6, fi.height);
X    BellWindow = XCreateWindow (AnalogWindow, 0, 0,
X					  bell_width, bell_height, 0,
X					  rv ? WhitePixmap : BlackPixmap,
X					  rv ? WhitePixmap : BlackPixmap);
X    XSetIconWindow(AnalogWindow,IconWindow);
X    ClockCursor = XCreateCursor (xclock_width, xclock_height, xclock_bits,
X	xclock_bits, xclock_x_hot, xclock_y_hot, FgPixel, BgPixel, GXcopy);
X    XDefineCursor (AnalogWindow, ClockCursor);
X    XDefineCursor (IconWindow, ClockCursor);
X    DateCursor = XCreateCursor (alarm_width, alarm_height, alarm_bits,
X	alarm_bits, alarm_x_hot, alarm_y_hot, BgPixel, FgPixel, GXcopy);
X    XDefineCursor (DateWindow, DateCursor);
X    BellCursor = XCreateCursor (slash_width, slash_height, slash_bits,
X	slash_bits, slash_x_hot, slash_y_hot, FgPixel, BgPixel, GXcopy);
X    XDefineCursor (BellWindow, BellCursor);
X    XMapWindow (AnalogWindow);
X    XMapWindow (DateWindow);
X    XMapWindow (DayWindow);
X    XSelectInput (AnalogWindow, ExposeWindow);
X    XSelectInput (IconWindow, ExposeWindow|ButtonPressed|ButtonReleased);
X    XSelectInput (DateWindow,
X			EnterWindow|LeaveWindow|ButtonPressed|ButtonReleased);
X    XSelectInput (BellWindow, ExposeWindow|ButtonPressed);
X    if (alarm_on == TRUE)
X	XMapWindow (BellWindow);
X}
X
X/*
X *  Draw the clock face (every fifth tick-mark is longer than the others).
X */
XDrawClockFace(second_hand, Radius)
Xint second_hand;
Xint Radius;
X{
X	register int i;
X	register int delta = (Radius - second_hand) / 3;
X	
X	XClear(AnalogWindow);
X	for (i = 0; i < 60; i++)
X		if ((i % 5) == 0)
X			DrawHand(second_hand, Radius, ((double) i)/60.);
X		else DrawHand((Radius - delta), Radius, ((double) i)/60.);
X	Sync(FgPixel);
X}
X
X/*
X * This routine synchronizes the segment buffer contents with the
X * VS100 screen.  In effect, it flushes the buffer contents to the
X * screen.
X */
XSync(color)
Xint color;
X{
X	/*
X	 * Call the X draw curve routine.
X	 */
X	XDraw(AnalogWindow, SegBuff, NumSegs, 1, 1, color, GXcopy, AllPlanes);
X
X	/*
X	 * Reset the segment buffer pointer and the segment counter.
X	 */
X	SegBuffPtr = SegBuff;
X	NumSegs = 0;
X}
X
X/*
X * DrawHand - Draws (or erases) a hand.  Fraction_of_a_circle is a
X * fraction between 0 and 1 (inclusive) indicating how far around the
X * circle (clockwise) high noon.
X *
X * Blank_length is the distance from the center which the hand begins
X * (logically 0, but I have the feature, I might as well use it).
X * length is the maximum length of the hand.
X *
X * The blank_length feature is because I wanted to draw tick-marks around the
X * circle (for seconds).  The obvious means of drawing lines from the center
X * to the perimeter, then erasing all but the outside most pixels doesn't
X * work because of round-off error (sigh).
X */
XDrawHand(blank_length, length, fraction_of_a_circle)
Xint blank_length, length;
Xdouble fraction_of_a_circle;
X{
X
X	extern double cos(), sin();
X	double angle;
X
X	/*
X	 *  A full circle is 2 PI radians.
X	 *  Angles are measured from 6 o'clock, not noon (or so it seems).
X	 *  Thus, when fraction_of_a_circle is 0, we want angle to be PI,
X	 *  and when fraction_of_a_circle is 1, we want angle to be 3 PI.
X	 *
X	 *  Also, angles increase counter-clockwise, not clockwise, so we
X	 *  throw in a factor of -1 so our clock doesn't run backwards.
X	 */
X	angle = (-2 * PI * fraction_of_a_circle) + PI;
X
X	/*
X	 * Add the move instruction to the segment buffer and increment
X	 * the "next" pointer.
X	 */
X	SegBuffPtr->x = XCenter + (int)((float)blank_length * sin(angle));
X	SegBuffPtr->y = YCenter + (int)((float)blank_length * cos(angle));
X	SegBuffPtr->flags = VertexDontDraw;
X	SegBuffPtr++;
X	NumSegs++;
X
X	/*
X	 * Add the new point to the buffer and increment the "next" pointer.
X	 */
X	SegBuffPtr->x = XCenter + (int)((float)length * sin(angle));
X	SegBuffPtr->y = YCenter + (int)((float)length * cos(angle));
X	SegBuffPtr->flags = VertexDrawLastPoint;
X	SegBuffPtr++;
X	NumSegs++;
X}
X
Xset_alarm () {
X    short minute_set, hour_set, buttons;
X    int i_ignore;
X    Window w_ignore;
X    XButtonEvent event;
X
X    XQueryMouseButtons (RootWindow, &i_ignore, &i_ignore, &w_ignore, &buttons);
X    if (buttons & LeftMask)
X	ActivateAlarm ();
X    hour_set = buttons & MiddleMask;
X    minute_set = buttons & RightMask;
X    ShowAlarmTime ();
X    do {
X	if (XPending() || (hour_set == minute_set)) {
X	    XNextEvent (&event);
X	    if (event.type == ButtonPressed || event.type == ButtonReleased)
X		switch (event.detail & ValueMask) {
X		case LeftButton:
X		    ActivateAlarm();
X		    break;
X		case MiddleButton:
X		    hour_set = (event.type == ButtonPressed);
X		    break;
X		case RightButton:
X		    minute_set = (event.type == ButtonPressed);
X		    break;
X		}
X	}
X
X	if (hour_set && minute_set)
X	    al_tm.min = al_tm.hour = 0;
X	else if (minute_set && ++al_tm.min > 59)
X	    al_tm.min = 0;
X	else if (hour_set && ++al_tm.hour > 23)
X	    al_tm.hour = 0;
X	ShowAlarmTime ();
X
X	if (!XPending() && (minute_set != hour_set)) {
X	    XFlush ();
X	    (void) sleep (1);
X	}
X
X    } while (event.type != LeaveWindow);
X}
X
XActivateAlarm () {
X    alarm_on = TRUE;
X    XMapWindow (BellWindow);
X    XBitmapBitsPut(BellWindow, 0, 0, bell_width, bell_height,
X		    bell_bits, FgPixel, BgPixel, 0, GXcopy, AllPlanes);
X}
X
XShowTime () {
X    long clock;
X
X    clock = time ((long *) 0);
X    tm = localtime (&clock);
X    if (Iconified)
X	ShowIcon ();
X    else ShowHands ();
X    if (ringing == TRUE) {
X	if (auto_alarm_off == TRUE && tm->tm_min != al_tm.min) {
X	    ringing = FALSE;
X	    XUnmapWindow (BellWindow);
X	}
X	else RingAlarm ();
X    }
X    else if (alarm_on && tm->tm_hour == al_tm.hour && tm->tm_min == al_tm.min)
X	ringing = TRUE;
X    XFlush ();
X}
X
XRingAlarm () {
X    if (tm->tm_sec & 1)
X	XBitmapBitsPut(BellWindow, 0, 0, bell_width, bell_height,
X		    bell_bits, FgPixel, BgPixel, 0, GXcopy, AllPlanes);
X    else XBitmapBitsPut(BellWindow, 0, 0, bell_width, bell_height,
X		    bell_bits, BgPixel, FgPixel, 0, GXcopy, AllPlanes);
X    XFeep (0);
X}
X
XShowHands () {
X    static struct tm old_time;
X
X    if (interval == 1)
X	DrawHand(1, sec_hand_len, ((double) old_time.tm_sec)/60.0);
X    if (old_time.tm_min != tm->tm_min) {
X	DrawHand(1, min_hand_len, ((double) old_time.tm_min)/60.0);
X	DrawHand(1, hour_hand_len, (((double)old_time.tm_hour) + 
X			(((double)old_time.tm_min)/60.0))/12.0);
X    }
X    Sync(BgPixel);
X    if (AlarmSetMode)
X	ShowAlarmTime ();
X    else ShowDate ();
X    ShowDay ();
X    old_time = *tm;
X    if (interval == 1)
X	DrawHand(1, sec_hand_len, ((double) tm->tm_sec)/60.0);
X    DrawHand(1, min_hand_len, ((double) tm->tm_min)/60.0);
X    DrawHand(1, hour_hand_len, (((double)tm->tm_hour) + 
X			(((double)tm->tm_min)/60.0))/12.0);
X    Sync(FgPixel);
X}
X
XShowIcon () {
X    char buf[21];
X
X    if (interval == 1)
X	(void) sprintf (buf, "%s, %d %s %2d:%.2d:%.2d",
X		DayName[tm->tm_wday], tm->tm_mday, MonthName[tm->tm_mon],
X		tm->tm_hour, tm->tm_min, tm->tm_sec);
X    else (void) sprintf (buf, "%s, %d %s %2d:%.2d",
X		DayName[tm->tm_wday], tm->tm_mday,
X		MonthName[tm->tm_mon], tm->tm_hour, tm->tm_min);
X    XText (IconWindow,DigitalPad,DigitalPad,buf,strlen(buf),f,FgPixel,BgPixel);
X}
X
XShowDate () {
X    char buf[7];
X
X    (void) sprintf (buf, "%2d %s", tm->tm_mday, MonthName[tm->tm_mon]);
X    XText (DateWindow, 0, 0, buf, 6, f, FgPixel, BgPixel);
X}
X
XShowDay () {
X    XText (DayWindow, 0, 0, DayName[tm->tm_wday], 3, f, FgPixel, BgPixel);
X}
X
XShowAlarmTime () {
X    char buf[6];
X
X    (void) sprintf (buf, "%2d:%.2d", al_tm.hour, al_tm.min);
X    if (Iconified)
X	XText (IconWindow, DigitalPad, DigitalPad, buf, 5, f, BgPixel, FgPixel);
X    else XText (DateWindow, 0, 0, buf, 5, f, BgPixel, FgPixel);
X}
X
XSetAnalogSize () {
X    int face_size;
X
X    XCenter = anl_width / 2;
X    YCenter = anl_height / 2;
X    face_size = anl_width > anl_height ? anl_height : anl_width;
X    radius = (face_size - AnalogPad) / 2;
X    sec_hand_len = 90 * radius / 100;
X    min_hand_len = 70 * radius / 100;
X    hour_hand_len = 40 * radius / 100;
X    XMoveWindow (DateWindow, anl_width/2 - fi.width*6/2,
X				anl_height*3/4 - fi.height/2);
X    XMoveWindow (DayWindow, anl_width/2 - fi.width*3/2,
X				anl_height/4 - fi.height/2);
X}
END_OF_xclock.c
if test 14768 -ne `wc -c <xclock.c`; then
    echo shar: \"xclock.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f xclock.cursor -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"xclock.cursor\"
else
echo shar: Extracting \"xclock.cursor\" \(267 characters\)
sed "s/^X//" >xclock.cursor <<'END_OF_xclock.cursor'
X#define xclock_width 16
X#define xclock_height 16
X#define xclock_x_hot 8
X#define xclock_y_hot 8
Xstatic short xclock_bits[] = {
X   0x0180, 0x0420, 0x1108, 0x2104,
X   0x0100, 0x4102, 0x0100, 0x8101,
X   0x80f1, 0x0000, 0x4002, 0x0000,
X   0x2004, 0x1008, 0x0420, 0x0180};
END_OF_xclock.cursor
if test 267 -ne `wc -c <xclock.cursor`; then
    echo shar: \"xclock.cursor\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f alarm.cursor -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"alarm.cursor\"
else
echo shar: Extracting \"alarm.cursor\" \(139 characters\)
sed "s/^X//" >alarm.cursor <<'END_OF_alarm.cursor'
X#define alarm_width 7
X#define alarm_height 2
X#define alarm_x_hot 3
X#define alarm_y_hot 0
Xstatic short alarm_bits[] = {
X   0x007f, 0x007f};
END_OF_alarm.cursor
if test 139 -ne `wc -c <alarm.cursor`; then
    echo shar: \"alarm.cursor\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f slash.cursor -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"slash.cursor\"
else
echo shar: Extracting \"slash.cursor\" \(227 characters\)
sed "s/^X//" >slash.cursor <<'END_OF_slash.cursor'
X#define slash_width 12
X#define slash_height 12
X#define slash_x_hot 5
X#define slash_y_hot 6
Xstatic short slash_bits[] = {
X   0x0000, 0x0200, 0x0700, 0x0380,
X   0x01c0, 0x00e0, 0x0070, 0x0038,
X   0x001c, 0x000e, 0x0004, 0x0000};
END_OF_slash.cursor
if test 227 -ne `wc -c <slash.cursor`; then
    echo shar: \"slash.cursor\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f bell.bm -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"bell.bm\"
else
echo shar: Extracting \"bell.bm\" \(215 characters\)
sed "s/^X//" >bell.bm <<'END_OF_bell.bm'
X#define bell_width 16
X#define bell_height 16
Xstatic short bell_bits[] = {
X   0x0000, 0x0000, 0x0180, 0x0240,
X   0x0420, 0x0420, 0x0810, 0x0810,
X   0x1008, 0x1008, 0x300c, 0x2004,
X   0x3ffc, 0x03c0, 0x0180, 0x0000};
END_OF_bell.bm
if test 215 -ne `wc -c <bell.bm`; then
    echo shar: \"bell.bm\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile\"
else
echo shar: Extracting \"Makefile\" \(124 characters\)
sed "s/^X//" >Makefile <<'END_OF_Makefile'
XCFLAGS = -DSYSV
X
Xxclock: xclock.o
X	cc -o xclock xclock.o -lX -lm
X
Xxclock.o: bell.bm xclock.cursor alarm.cursor slash.cursor
END_OF_Makefile
if test 124 -ne `wc -c <Makefile`; then
    echo shar: \"Makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f xclock.1 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"xclock.1\"
else
echo shar: Extracting \"xclock.1\" \(5362 characters\)
sed "s/^X//" >xclock.1 <<'END_OF_xclock.1'
X.TH XCLOCK 1 "18 August 1985" "X Version 10"
X.SH NAME
Xxclock - X Window System, analog / digital clock
X.SH SYNOPSIS
X.B xclock
X[ option ] ...
X.SH DESCRIPTION
X.I Xclock 
Xis the
X.I X
Xwindow system clock.
X.I Xclock
XContinuously  displays  the  current  time of day.  The initial display
Xis an analog clock; the icon form is a digital clock.  The clock includes
Xan alarm which can be set by positioning the mouse cursor in the date
Xwindow of the analog clock, or anywhere in the icon.  The mouse buttons
Xcan then be used to set/activate the alarm as follows:
X.PP
X.TP 10
X\- Pressing the middle mouse button advances the hours
X.PP
X.TP 10
X\- Pressing the right mouse button advances the minutes
X.PP
X.TP 10
X\- Pressing both the middle and right buttons together resets
Xthe alarm time to 0:00
X.PP
X.TP 10
X\- Pressing the left mouse button activates the alarm.
X.PP
XWhen the alarm is active, a bell shows in the upper left corner
Xof the analog clock.  When the alarm time arrives, the keyboard bell is
Xsounded (XFeep is called) once per second, and the bell symbol reverses
Xforeground and backgroud once per second.  By default, the alarm only
Xrings for one minute, but this can be changed via a command line
Xor .Xdefaults option.
X.SH ARGUMENTS
X.PP
X.TP 10
X.B \-bw \fIpixels\fP
XSpecify the width in pixels of the border around the
X.I xclock
Xwindow.
X.PP
X.TP 10
X.B \-fn \fIfont\fP
XThe specified
X.I font
Xwill be used as the output font for the day and date on the analog clock,
Xand for everything in the digital (icon) display.
XAny fixed width font may be used, the default is ``6x10''.
X.PP
X.TP 10
X.B \-analogpad \fIpixels\fP
XSpecify the width in pixels of the padding ``white space''
Xbetween the window border and the analog clock face.
XThe default padding is 2 pixels.
X.PP
X.TP 10
X.B \-digitalpad \fIpixels\fP
XSpecify the width in pixels of the padding ``white space''
Xbetween the window border and the digital clock characters.
XThe default padding is 3 pixels.
X.PP
X.TP 10
X.B \-manualalarm
XCause
X.I xclock
Xto leave the alarm ringing until it is manually stopped (by clicking
Xany mouse button on the bell symbol in the analog display).  By default
Xthe alarm will stop automatically after about 1 minute.
X.PP
X.TP 10
X.B \-alarm \fIhh:mm\fP
XSet the alarm for the specified time, and activate it.  Using this
Xcommand line option,
X.I xclock
Xcan in some cases be used as a replacement for
X.I leave
X(1).
X.PP
X.TP 10
X.B \-rv
XCause
X.I xclock
Xto produce all output in white-on-black instead of black-on-white.  This
Xis only useful on Black and White displays.
X.PP
X.TP 10
X.B \-update \fIseconds\fP
XSpecify the frequency in seconds with which
X.I xclock
Xupdates its display.  If the
X.I xclock
Xwindow is obscured and then exposed,
X.I xclock
Xwill override this setting  and  redisplay  immediately.   The  default
Xupdate  frequency  is  60  seconds.   The  specification  of an update
Xfrequency of 1 second enables the second hand in analog mode, and the
Xseconds display in the digital mode.
X.PP
X.TP 8
X.B =\fIgeometry\fP
XThe clock window is created with the specified
Xsize according to the geometry specification.
XSee \fIX(1)\fP for details.
XIn digital mode if you do not specify either height and width they are
Xdetermined  by  the font in use.  In analog mode if you do not specify
Xeither width or height they default to 75.  The  default  offset  for
Xany unspecified offset is -0.  All values are in pixels.
X.PP
X.TP 10
X.B \fIhost\fP:\fIdisplay\fP
XNormally,
X.I xclock
Xgets  the host and display number to use from the environment variable
X``DISPLAY''.  One can, however specify them explicitly.
XThe
X.I host
Xspecifies which machine to create the
X.I xclock
Xwindow on, and
Xthe
X.I display
Xargument specifies the display number.
XFor example,
X``mit-frobozz:1'' creates an
X.I xclock
Xon display one on the machine mit-frobozz.  If the host is omitted the
Xlocal  host  is  assumed.   If  the  display  is omitted, display 0 is
Xassumed, the ``:'' is necessary in either case.
X.SH X DEFAULTS
X.PP
X.PP
X.TP 8
X.B BorderWidth
XTo determine the border width.
X.PP
X.TP 8
X.B BodyFont
XTo determine digital clock display font.
X.PP
X.TP 8
X.B AnalogPad
XTo determine the internal padding value for the analog display.
X.PP
X.TP 8
X.B DigitalPad
XTo determine the internal padding value for the digital display.
X.PP
X.TP 8
X.B ReverseVideo
XIf ``on'', the clock should be white on black instead of black on white.
XThis is only useful on Black and White displays.
X.PP
X.TP 8
X.B Update
XTo determine the update rate.
X.PP
X.TP 8
X.B ManualAlarm
XTo disable automatic shutoff of the alarm.
X.PP
X.TP 8
X.B AlarmTime
XTo set and activate the alarm.
X.SH ENVIRONMENT
X.PP
X.TP 8
X.B DISPLAY
XTo get the default host and display number.
X.SH SEE ALSO
XX(1), xwm(1), X(1), time(3C), select(2)
X.SH AUTHORS
X.PP
XCopyright 1985, Massachusetts Institute of Technology.
X.PP
XTony Della Fera (MIT-Athena, DEC)
X.PP
XDave Mankins (MIT-Athena, BBN)
X.PP
XJames Watson, Pansystem Informatics, Zurich, Switzerland.
X.SH BUGS
X.I Xclock
Xbelieves the Unix clock.
X.PP
XThe parsing of the alarm time is extremely simple-minded.
X.PP
XIt would be nice if there were an option to control the format used
Xin the digital display; something like System V date(1) has.
X.PP
XThere is no attempt to adjust the size of the analog display based on
Xthe font used for day and date display.  It is therefore possible to
Xmake a real mess by specifying a large font and a small analog window.
END_OF_xclock.1
if test 5362 -ne `wc -c <xclock.1`; then
    echo shar: \"xclock.1\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0