mikew@wyse.wyse.com (Mike Wexler) (09/16/88)
Submitted-by: dheller@cory (Dan Heller) Posting-number: Volume 1, Issue 44 Archive-name: dclock/part01 Here's the latest dclock with patchlevel.h and everything. #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # README # dclock.man # Makefile # Dclock.c # Dclock.h # DclockP.h # Patchlevel.h # dclock.c # This archive created: Wed Sep 14 23:36:04 1988 export PATH; PATH=/bin:/usr/bin:$PATH echo shar: "extracting 'README'" '(391 characters)' if test -f 'README' then echo shar: "will not over-write existing file 'README'" else cat << \!Funky!Stuff! > 'README' To compile, just run make and watch it go. When the program is running and the mouse is in the window, you can type the following keys: r -- toggle reverse video s -- toggle seconds display b -- toggle the bell to ring on half hours j -- toggle jump or smooth scrolling This code was written by Dan Heller <island!argv@sun.com> for use by those who find it useful :-) !Funky!Stuff! fi # end of overwriting check echo shar: "extracting 'dclock.man'" '(5033 characters)' if test -f 'dclock.man' then echo shar: "will not over-write existing file 'dclock.man'" else cat << \!Funky!Stuff! > 'dclock.man' .TH DCLOCK 1 "1 March 1988" "X Version 11" .SH NAME dclock - digital clock for X .SH SYNOPSIS .B dclock [-\fItoolkitoption\fP ...] [-option ...] .SH DESCRIPTION The .I dclock program displays the time in digital format only. The time is updated on a per second basis or on a per minute basis. This program is nothing more than a wrapper around the dclock widget not associated with the Athena Widget Set. .sp When the clock is running, the user may change attributes by typing: .in +2 .nf \fBr\fP\ \ Toggles \fBReverse Video\fP. \fBs\fP\ \ Toggles the \fBseconds\fP display. \fBb\fP\ \ Toggles the \fBbell\fP attribute (see below). \fBj\fP\ \ Toggles the \fBjump/scroll\fP attribute (see below). .in -2 .fi .SH OPTIONS .I Dclock accepts all of the standard X Toolkit command line options along with the additional options listed below: .TP 8 .B \-help This option indicates that a brief summary of the allowed options should be printed on the standard error. .TP 8 .B \-bell This option indicates that the beel will beep once on the half hour and twice on the hour. .TP 8 .B \-scroll .br .B \-noscroll When the time changes, the digits scroll from the previous digit to the next digit. Since this is on by default, the -noscroll option can turn it off. .TP 8 .B \-date "format" The date is printed under the time in the specified font. The string displayed is in the "format" argument. If the string contains a formatting character (%), then the next character is examined and a value is inserted into the string. Example: .sp .ti +2 dclock -date "Today is %W" .sp The date string will print "Today is Friday" if the weekday name happens to be friday. The formatting characters that are understood are: .in +2 .nf %W Full weekday name %w Three-char weekday name (Sun, Mon, Tue...) %M Full month name %m Three-char abbreviation for that month (Jan, Feb, Mar...) %d The date (numerical day number of the month) %Y Full year (4 digits) %y 2-digit year number .fi .in -2 .TP 8 .B \-seconds This option will update the clock every second and display the time including the seconds. .TP 8 .B \-bg \fIcolor\fP This option specifies the color to use for the background of the window. The default is ``white.'' .TP 8 .B \-bd \fIcolor\fP This option specifies the color to use for the border of the window. The default is ``black.'' .TP 8 .B \-bw \fInumber\fP This option specifies the width in pixels of the border surrounding the window. .TP 8 .B \-fg \fIcolor\fP This option specifies the color to use for displaying text. The default is ``black''. .TP 8 .B \-fn \fIfont\fP This option specifies the font to be used for displaying normal text. The default is ``Fixed.'' .TP 8 .B \-rv This option indicates that reverse video should be simulated by swapping the foreground and background colors. .TP 8 .B \-geometry \fIgeometry\fP This option specifies the prefered size and position of the clock window. .TP 8 .B \-display \fIhost\fP:\fIdisplay\fP This option specifies the X server to contact. .TP 8 .B \-xrm \fIresourcestring\fP This option specifies a resource string to be used. This is especially useful for setting resources that do not have separate command line options. .SH X DEFAULTS It understands all of the core resource names and classes as well as: .PP .TP 8 .B width (\fPclass\fB Width) Specifies the width of the clock. .TP 8 .B height (\fPclass\fB Height) Specifies the height of the clock. .TP 8 .B foreground (\fPclass\fB Foreground) Specifies the color for the tic marks. Using the class specifies the color for all things that normally would appear in the foreground color. The default is ``black'' since the core default for background is ``white.'' .TP 8 .B bell (\fPclass\fB Boolean) Specifies whether or not a bell should be rung on the hour and half hour. .TP 8 .B font (\fPclass\fB Font) Specifies the font to be used for the date. .TP 8 .B reverseVideo (\fPclass\fB ReverseVideo) Specifies that the foreground and background colors should be reversed. .TP 8 .B scroll (\fPclass\fB Boolean) Specifies whether the digits should scroll or not. .TP 8 .B seconds (\fPclass\fB Boolean) Specifies whether the seconds should be displayed or not. .TP 8 .B bell (\fPclass\fB Boolean) Specifies whether the bell should sound on the half hour and on the hour. .SH ENVIRONMENT .PP .TP 8 .B DISPLAY to get the default host and display number. .TP 8 .B XENVIRONMENT to get the name of a resource file that overrides the global resources stored in the RESOURCE_MANAGER property. .SH "SEE ALSO" X(1), xrdb(1), time(3C). .SH BUGS .I Dclock believes the system clock. .PP Scrolling from 9 to 10 O'Clock seems weird, but chances are you won't notice it. .PP If the window is too small, the seconds are tough to read. This should be recognized by the program and should display seconds using a font rather than the bitmaps used by the clock itself. .PP Color has been untested. .SH COPYRIGHT Copyright (c) 1988, Dan Heller. .SH AUTHOR .nf Dan Heller -- <island!argv@sun.com> or <dheller@cory.berkeley.edu> .fi !Funky!Stuff! fi # end of overwriting check echo shar: "extracting 'Makefile'" '(310 characters)' if test -f 'Makefile' then echo shar: "will not over-write existing file 'Makefile'" else cat << \!Funky!Stuff! > 'Makefile' # Please read the accompanying README file before running Make SRCS= Dclock.c dclock.c OBJS= Dclock.o dclock.o CFLAGS= -O LDFLAGS= -s LIBS= -lXaw -lXt -lX dclock: ${OBJS} cc ${LDFLAGS} ${OBJS} ${LIBS} -o dclock clean: ; rm ${OBJS} core dclock shar: ; shar README Makefile dclock.man ${SRCS} > dclock.shar !Funky!Stuff! fi # end of overwriting check echo shar: "extracting 'Dclock.c'" '(18921 characters)' if test -f 'Dclock.c' then echo shar: "will not over-write existing file 'Dclock.c'" else cat << \!Funky!Stuff! > 'Dclock.c' /* * Dclock.c -- a digital clock widget. * Author: Dan Heller <island!argv@sun.com> */ #include <stdio.h> #include <X11/IntrinsicP.h> #include <X11/Xos.h> #include <X11/StringDefs.h> #include "DclockP.h" static void Initialize(), Resize(), Realize(), Destroy(), Redisplay(), timeout(), toggle_bell(), toggle_reverse_video(), toggle_scroll(), toggle_seconds(), show_dialog_box(), GetGC(), make_number(), show_time(), show_date(), scroll_time(); #define BORDER 5 #define CLOCK_WIDTH 256 #define CLOCK_HEIGHT 80 #define when break;case #define otherwise break;default static Boolean SetValues(); static int winwidth = CLOCK_WIDTH; static int winheight = CLOCK_HEIGHT; static Boolean false = False; static Boolean true = True; static double x_ratio, y_ratio; static Pixmap old_pix[4]; static struct tm before; extern int exit(); static char defaultTranslations[] = "<Key>b: toggle-bell() \n\ <Key>j: toggle-scroll() \n\ <Key>r: toggle-reverse-video() \n\ <Key>s: toggle-seconds() \n\ <Btn3Down>: dialog-box()"; static XtActionsRec actionsList[] = { { "toggle-bell", toggle_bell }, { "toggle-scroll", toggle_scroll }, { "toggle-reverse-video", toggle_reverse_video }, { "toggle-seconds", toggle_seconds }, { "dialog-box", show_dialog_box }, }; static XtResource resources[] = { { XtNwidth, XtCWidth, XtRInt, sizeof(int), XtOffset(Widget,core.width), XtRInt, (caddr_t)&winwidth }, { XtNheight, XtCHeight, XtRInt, sizeof(int), XtOffset(Widget,core.height), XtRInt, (caddr_t)&winheight }, { XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), XtOffset(DclockWidget,dclock.foreground), XtRString, "Black"}, { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean), XtOffset(DclockWidget,dclock.reverse), XtRBoolean, (caddr_t)&false}, { XtNscroll, XtCBoolean, XtRBoolean, sizeof (Boolean), XtOffset(DclockWidget,dclock.scroll), XtRBoolean, (caddr_t)&true}, { XtNbell, XtCBoolean, XtRBoolean, sizeof (Boolean), XtOffset(DclockWidget,dclock.bell), XtRBoolean, (caddr_t)&false}, { XtNseconds, XtCBoolean, XtRBoolean, sizeof (Boolean), XtOffset(DclockWidget,dclock.seconds), XtRBoolean, (caddr_t)&false}, { XtNdate, XtCString, XtRString, sizeof (String), XtOffset(DclockWidget,dclock.date_fmt), XtRString, NULL}, { XtNfont, XtCFont, XtRFontStruct, sizeof (XFontStruct *), XtOffset(DclockWidget,dclock.font), XtRString, "Fixed"}, }; DclockClassRec dclockClassRec = { { /* core fields */ /* superclass */ &widgetClassRec, /* class_name */ "Dclock", /* widget_size */ sizeof(DclockRec), /* class_initialize */ NULL, /* class_part_initialize */ NULL, /* class_inited */ FALSE, /* initialize */ Initialize, /* initialize_hook */ NULL, /* realize */ Realize, /* actions */ actionsList, /* num_actions */ XtNumber(actionsList), /* resources */ resources, /* resource_count */ XtNumber(resources), /* xrm_class */ NULL, /* compress_motion */ TRUE, /* compress_exposure */ TRUE, /* compress_enterleave */ TRUE, /* visible_interest */ FALSE, /* destroy */ Destroy, /* resize */ Resize, /* expose */ Redisplay, /* set_values */ SetValues, /* set_values_hook */ NULL, /* set_values_almost */ XtInheritSetValuesAlmost, /* get_values_hook */ NULL, /* accept_focus */ NULL, /* version */ XtVersion, /* callback_private */ NULL, /* tm_table */ defaultTranslations, /* query_geometry */ NULL, } }; WidgetClass dclockWidgetClass = (WidgetClass) &dclockClassRec; /* ARGSUSED */ static void Initialize (request, new) DclockWidget request; DclockWidget new; { GetGC(new); } static void GetGC(w) DclockWidget w; { XGCValues xgcv; XtGCMask gc_mask = GCFont | GCForeground | GCBackground; #ifdef NOT_NOW if (w->dclock.reverse) { Pixel fg = w->dclock.foreground; Pixel bg = w->core.background_pixel; if (w->core.border_pixel == fg) w->core.border_pixel = bg; w->dclock.foreground = bg; w->core.background_pixel = fg; xgcv.function = GXcopyInverted; gc_mask |= GCFunction; } else xgcv.function = GXcopy; gc_mask |= GCFunction; #endif /* NOT_NOW */ xgcv.font = w->dclock.font->fid; xgcv.foreground = BlackPixel(XtDisplay(w), DefaultScreen(XtDisplay(w))); xgcv.background = WhitePixel(XtDisplay(w), DefaultScreen(XtDisplay(w))); /* xgcv.foreground = w->dclock.foreground; xgcv.background = w->core.background_pixel; */ w->dclock.foreGC = XtGetGC ((Widget) w, gc_mask, &xgcv); xgcv.foreground = w->core.background_pixel; xgcv.background = w->dclock.foreground; w->dclock.backGC = XtGetGC ((Widget) w, gc_mask, &xgcv); } static void Realize (w, valueMask, attrs) Widget w; XtValueMask *valueMask; XSetWindowAttributes *attrs; { *valueMask |= CWBitGravity; attrs->bit_gravity = ForgetGravity; XtCreateWindow (w, InputOutput, (Visual *) CopyFromParent, *valueMask, attrs); Resize(w); } static void Destroy (w) DclockWidget w; { int n; XtRemoveTimeOut(w->dclock.interval_id); XtDestroyGC (w->dclock.foreGC); XtDestroyGC (w->dclock.backGC); for (n = 0; n < 10; n++) { XFreePixmap(XtDisplay(w), w->dclock.digits[n]); XFreePixmap(XtDisplay(w), w->dclock.tiny_digits[n]); } if (w->dclock.colon[0]) XFreePixmap(XtDisplay(w), w->dclock.colon[0]); if (w->dclock.colon[1]) XFreePixmap(XtDisplay(w), w->dclock.colon[1]); } /* ARGSUSED */ static void Resize (w) DclockWidget w; { int i, digit_w, digit_h; Pixmap pix; GC gc; if (!XtIsRealized(w)) return; winwidth = w->core.width; winheight = w->core.height; x_ratio = (double)winwidth / CLOCK_WIDTH; y_ratio = (double)winheight / CLOCK_HEIGHT; if (w->dclock.date_fmt) /* make win temporarily shorter so digits will fit on top of date */ winheight -= w->dclock.font->ascent + w->dclock.font->descent; digit_w = winwidth/(4 - !w->dclock.seconds) - (int)(x_ratio*BORDER*5); digit_h = winheight - (int)(y_ratio * BORDER*2); w->dclock.digit_w = digit_w; w->dclock.digit_h = digit_h; gc = w->dclock.reverse? w->dclock.backGC : w->dclock.foreGC; for (i = 0; i < 10; i++) { /* Make the big digit */ if (w->dclock.digits[i]) XFreePixmap(XtDisplay(w), w->dclock.digits[i]); w->dclock.digits[i] = XCreatePixmap(XtDisplay(w), XtWindow(w), digit_w, digit_h, 1); make_number(w, w->dclock.digits[i], gc, i, digit_w, digit_h); /* make smaller version of this digit for use by "seconds" */ if (w->dclock.tiny_digits[i]) XFreePixmap(XtDisplay(w), w->dclock.tiny_digits[i]); w->dclock.tiny_digits[i] = XCreatePixmap(XtDisplay(w), XtWindow(w), digit_w/2,digit_h/2,1); make_number(w, w->dclock.tiny_digits[i], gc, i, digit_w/2, digit_h/2); } /* The colon[0] area is blank */ if (w->dclock.colon[0]) XFreePixmap(XtDisplay(w), w->dclock.colon[0]); w->dclock.colon[0] = XCreatePixmap(XtDisplay(w), XtWindow(w), digit_w, digit_h, 1); if (w->dclock.reverse) XFillRectangle(XtDisplay(w), w->dclock.colon[0], w->dclock.foreGC, 0, 0, digit_w,digit_h); else XFillRectangle(XtDisplay(w), w->dclock.colon[0], w->dclock.backGC, 0, 0, digit_w,digit_h); /* colon[1] area has two squares */ if (w->dclock.colon[1]) XFreePixmap(XtDisplay(w), w->dclock.colon[1]); w->dclock.colon[1] = XCreatePixmap(XtDisplay(w), XtWindow(w), (int)(30*x_ratio), digit_h, 1); if (w->dclock.reverse) /* black background with white squres */ XFillRectangle(XtDisplay(w), w->dclock.colon[1], w->dclock.foreGC, 0, 0, (int)(30*x_ratio), digit_h); else XFillRectangle(XtDisplay(w), w->dclock.colon[1], w->dclock.backGC, 0, 0, (int)(30*x_ratio), digit_h); XFillArc(XtDisplay(w), w->dclock.colon[1], gc, (int)(15*x_ratio), digit_h/3, digit_w/7, digit_w/7, 0, 360 * 64); XFillArc(XtDisplay(w), w->dclock.colon[1], gc, (int)(15*x_ratio), (2*digit_h)/3, digit_w/7, digit_w/7, 0, 360 * 64); /* to optimize scrolling information (see scroll_time()) */ old_pix[0] = w->dclock.digits[0]; old_pix[1] = old_pix[2] = old_pix[3] = 0; if (w->dclock.date_fmt) /* restore size */ winheight += w->dclock.font->ascent + w->dclock.font->descent; } /* Defines to draw the (simulated) LED bars for each light in the digit */ #define TOP (pts[0].x = 2, pts[0].y = pts[1].y = 0, pts[1].x = w-2, \ pts[3].x = 2+6*x_ratio, pts[3].y = pts[2].y = 6*y_ratio, \ pts[2].x = w - pts[3].x, \ XFillPolygon(dpy, pix, gc, pts, 4, Convex, CoordModeOrigin)); #define MIDDLE (pts[0].x = 2, pts[0].y = h/2 - 1, \ pts[1].x = 6*x_ratio, pts[1].y = h/2 - 3*y_ratio, \ pts[2].x = w-pts[1].x, pts[2].y = pts[1].y, \ pts[3].x = w-2, pts[3].y = h/2 - 1, \ pts[4].x = pts[2].x, pts[4].y = h/2 + 3*y_ratio, \ pts[5].x = pts[1].x, pts[5].y = pts[4].y, \ XFillPolygon(dpy, pix, gc, pts, 6, Convex, CoordModeOrigin)); #define BOTTOM (pts[0].x = 2, pts[0].y = pts[1].y = h, pts[1].x = w-2, \ pts[3].x = 6*x_ratio, pts[3].y = pts[2].y = h - 6*y_ratio, \ pts[2].x = w - pts[3].x, \ XFillPolygon(dpy, pix, gc, pts, 4, Convex, CoordModeOrigin)); #define T_LEFT (pts[0].x = pts[1].x = 0, pts[0].y = 2, pts[1].y = h/2-2, \ pts[2].x = pts[3].x = 6*x_ratio, \ pts[2].y = h/2 - 5*y_ratio, pts[3].y = 8*y_ratio, \ XFillPolygon(dpy, pix, gc, pts, 4, Convex, CoordModeOrigin)); #define B_LEFT (pts[0].x = pts[1].x = 0, pts[0].y = h/2, pts[1].y = h, \ pts[2].x = pts[3].x = 6*x_ratio, \ pts[3].y = h/2 + 5*y_ratio, pts[2].y = h - 8*y_ratio, \ XFillPolygon(dpy, pix, gc, pts, 4, Convex, CoordModeOrigin)); #define T_RIGHT (pts[0].x = pts[1].x = w, pts[0].y = 2, pts[1].y = h/2-2, \ pts[2].x = pts[3].x = w-6*x_ratio, \ pts[2].y = h/2 - 5*y_ratio, pts[3].y = 8*y_ratio, \ XFillPolygon(dpy, pix, gc, pts, 4, Convex, CoordModeOrigin)); #define B_RIGHT (pts[0].x = pts[1].x = w, pts[0].y = h/2, pts[1].y = h, \ pts[2].x = pts[3].x = w-6*x_ratio, \ pts[3].y = h/2 + 5*y_ratio, pts[2].y = h - 8*y_ratio, \ XFillPolygon(dpy, pix, gc, pts, 4, Convex, CoordModeOrigin)); static void make_number(dw, pix, gc, n, w, h) DclockWidget dw; Pixmap pix; GC gc; int n, w, h; { XPoint pts[6]; Display *dpy = XtDisplay(dw); if (dw->dclock.reverse) XFillRectangle(dpy, pix, dw->dclock.foreGC, 0, 0, w, h); else XFillRectangle(dpy, pix, dw->dclock.backGC, 0, 0, w, h); switch(n) { when 0: TOP T_RIGHT B_RIGHT BOTTOM B_LEFT T_LEFT when 1: T_RIGHT B_RIGHT when 2: TOP T_RIGHT MIDDLE B_LEFT BOTTOM when 3: TOP T_RIGHT MIDDLE B_RIGHT BOTTOM when 4: T_LEFT MIDDLE T_RIGHT B_RIGHT when 5: TOP T_LEFT MIDDLE B_RIGHT BOTTOM when 6: T_LEFT B_LEFT MIDDLE BOTTOM B_RIGHT when 7: TOP T_RIGHT B_RIGHT when 8: T_LEFT B_LEFT MIDDLE TOP BOTTOM T_RIGHT B_RIGHT when 9: TOP T_LEFT T_RIGHT MIDDLE B_RIGHT otherwise: MIDDLE } } /* ARGSUSED */ static void Redisplay (w) DclockWidget w; { Boolean save_scroll = w->dclock.scroll; long t; if (!XtIsRealized(w)) return; if (w->dclock.interval_id) XtRemoveTimeOut(w->dclock.interval_id); if (w->dclock.reverse) XFillRectangle(XtDisplay(w), XtWindow(w), w->dclock.foreGC, 0, 0, w->core.width, w->core.height); else XClearWindow(XtDisplay(w), XtWindow(w)); before.tm_min = before.tm_hour = before.tm_wday = -1; old_pix[0] = w->dclock.digits[0]; old_pix[1] = old_pix[2] = old_pix[3] = 0; w->dclock.scroll = FALSE; show_time(w); w->dclock.scroll = save_scroll; if (w->dclock.seconds) w->dclock.interval_id = XtAddTimeOut(1000, timeout, w); else { t = time(0); w->dclock.interval_id = XtAddTimeOut((unsigned long)(60 - (t % 60)) * 1000, timeout, w); } } static void show_time(w) DclockWidget w; { char buf[11]; long t = time(0); register struct tm *l_time = localtime(&t); int digit_w = w->dclock.digit_w; int digit_h = w->dclock.digit_h; Display *dpy = XtDisplay(w); Window win = XtWindow(w); GC gc = w->dclock.reverse ? w->dclock.backGC : w->dclock.foreGC; (void) sprintf(buf, "%02d%02d", (l_time->tm_hour) ? ((l_time->tm_hour <= 12)? l_time->tm_hour: l_time->tm_hour-12): 12, l_time->tm_min); if (l_time->tm_min != before.tm_min || l_time->tm_hour != before.tm_hour) scroll_time(w, buf); if (w->dclock.seconds) { XCopyArea(dpy, w->dclock.tiny_digits[l_time->tm_sec/10], win, gc, 0, 0, digit_w/2, digit_h/2, winwidth - 2*(digit_w/2 + (int)(BORDER*x_ratio)), (int)(BORDER*y_ratio)); XCopyArea(dpy, w->dclock.tiny_digits[l_time->tm_sec%10], win, gc, 0, 0, digit_w/2, digit_h/2, winwidth - digit_w/2 - (int)(BORDER*x_ratio), (int)(BORDER*y_ratio)); } XCopyArea(dpy, w->dclock.colon[(!w->dclock.seconds || l_time->tm_sec & 1)], win, gc, 0, 0, (int)(30*x_ratio), digit_h, (int)(-digit_w*.75 + 2*BORDER*x_ratio) + 2*digit_w, (int)(BORDER*y_ratio)); if (w->dclock.date_fmt && before.tm_wday != l_time->tm_wday) show_date(w, l_time); if (w->dclock.bell && (!w->dclock.seconds || l_time->tm_sec == 0) && (l_time->tm_min == 0 || l_time->tm_min == 30)) { XBell(dpy, 50); if (l_time->tm_min == 0) XBell(dpy, 50); } before = *l_time; } static void scroll_time(w, p) DclockWidget w; register char *p; { int scroll_me[4], J = winheight - BORDER*2*y_ratio + 1; register int i, j, incr; int digit_w = w->dclock.digit_w; int digit_h = w->dclock.digit_h; Display *dpy = XtDisplay(w); Window win = XtWindow(w); GC gc = w->dclock.reverse? w->dclock.backGC : w->dclock.foreGC; Pixmap tmp[4]; if (w->dclock.date_fmt) J -= w->dclock.font->ascent + w->dclock.font->descent; if ((incr = J / 30) < 1) incr = 1; #define x ((int)(-digit_w*.75 + ((i+1)*BORDER + (i>1)*30)*x_ratio) + i*digit_w) #define y (int)(BORDER * y_ratio) for (i = 0; i < 4; i++) /* if pixrects don't match, scroll it */ scroll_me[i] = ((tmp[i] = w->dclock.digits[*p++ - '0']) != old_pix[i]); if (w->dclock.scroll && (scroll_me[0] || scroll_me[1] || scroll_me[2] || scroll_me[3])) for (j = 0; j <= J; j += incr) for (i = 0; i < 4; i++) if (scroll_me[i]) { if (old_pix[i]) XCopyArea(dpy, old_pix[i], win, gc, 0, j, digit_w, digit_h - j, x, y); if (i || tmp[i] == w->dclock.digits[1]) XCopyArea(dpy, tmp[i], win, gc, 0, 0, digit_w, j, x, y + digit_h - j); else XCopyArea(dpy, w->dclock.colon[0], win, gc, 0, 0, x+5, y + digit_h - j, digit_w, j); } for (i = 0; i < 4; i++) if (i || tmp[0] == w->dclock.digits[1]) XCopyArea(dpy, tmp[i], win, gc, 0,0, digit_w, digit_h, x,y); else XCopyArea(dpy, w->dclock.colon[0], win, gc, 0,0, digit_w,digit_h, x+5,y); #undef x #undef y for (i = 0; i < 4; i++) old_pix[i] = tmp[i]; } static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; static char *Months[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; static char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; static char *Days[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; static void show_date(w, now) DclockWidget w; struct tm *now; { char datestr[128]; register char *datep = datestr, *p; int x; if (!w->dclock.date_fmt) return; #if 0 if (set_alarm) sprintf(datestr, "Alarm is %s.", alarm_time.tm_sec < 0? "off" : "on"); else #endif /* 0 */ { for (p = w->dclock.date_fmt; *p; p++) { if (*p != '%') *datep++ = *p; else switch (*++p) { when 'M': datep += strlen(strcpy(datep, Months[now->tm_mon])); when 'm': datep += strlen(strcpy(datep, months[now->tm_mon])); when 'W': datep += strlen(strcpy(datep, Days[now->tm_wday])); when 'w': datep += strlen(strcpy(datep, days[now->tm_wday])); when 'd': if (now->tm_mday >= 10) *datep++ = (now->tm_mday / 10 + '0'); *datep++ = now->tm_mday % 10 + '0'; when 'Y': *datep++ = '1', *datep++ = '9'; /* fall thru */ case 'y': *datep++ = now->tm_year / 10 + '0'; *datep++ = now->tm_year % 10 + '0'; when '%': *datep++ = *p; otherwise: ; /* nothing */ } } *datep = 0; } x = (w->core.width - XTextWidth(w->dclock.font, datestr, datep-datestr))/2; if (x < 2) x = 2; /* remove what was there in case the whole thing isn't overwritten */ if (w->dclock.reverse) XFillRectangle(XtDisplay(w), XtWindow(w), w->dclock.foreGC, 0, winheight - (w->dclock.font->ascent + w->dclock.font->descent), winwidth, w->dclock.font->ascent + w->dclock.font->descent); else XClearArea(XtDisplay(w), XtWindow(w), 0, winheight - (w->dclock.font->ascent + w->dclock.font->descent), winwidth, w->dclock.font->ascent + w->dclock.font->descent, False); XDrawString(XtDisplay(w), XtWindow(w), w->dclock.reverse? w->dclock.backGC : w->dclock.foreGC, x, winheight - BORDER, datestr, (int)(datep - datestr)); } static void timeout(w, id) DclockWidget w; XtIntervalId *id; { show_time(w); w->dclock.interval_id = XtAddTimeOut(w->dclock.seconds? 1000 : 60000, timeout, w); } /* ARGSUSED */ static Boolean SetValues (current, request, new) DclockWidget current, request, new; { Boolean do_redraw = False; if (new->dclock.foreground != current->dclock.foreground || new->core.background_pixel != current->core.background_pixel || new->dclock.reverse != current->dclock.reverse) { XtDestroyGC (current->dclock.foreGC); XtDestroyGC (current->dclock.backGC); GetGC(new); Resize(new); /* pixmaps need to be redrawn */ do_redraw = True; } if (new->dclock.seconds != current->dclock.seconds) { XtRemoveTimeOut(current->dclock.interval_id); Resize(new); do_redraw = True; } if (new->dclock.date_fmt != current->dclock.date_fmt) { do_redraw = True; before.tm_wday = -1; } return do_redraw; } static void toggle_bell(w) DclockWidget w; { if (w->dclock.bell = !w->dclock.bell) XBell(XtDisplay(w), 50); } static void toggle_scroll(w) DclockWidget w; { w->dclock.scroll = !w->dclock.scroll; } static void toggle_reverse_video(w) DclockWidget w; { Arg arg; XtSetArg(arg, XtNreverseVideo, !w->dclock.reverse); XtSetValues(w, &arg, 1); } static void toggle_seconds(w) DclockWidget w; { Arg arg; XtSetArg(arg, XtNseconds, !w->dclock.seconds); XtSetValues(w, &arg, 1); } static void show_dialog_box(w) Widget w; { XBell(XtDisplay(w), 50); } !Funky!Stuff! fi # end of overwriting check echo shar: "extracting 'Dclock.h'" '(1430 characters)' if test -f 'Dclock.h' then echo shar: "will not over-write existing file 'Dclock.h'" else cat << \!Funky!Stuff! > 'Dclock.h' /* * Dclock.c -- a digital clock widget. * Author: Dan Heller <island!argv@sun.com> */ #ifndef _XtDclock_h #define _XtDclock_h /* Parameters: Name Class RepType Default Value ---- ----- ------- ------------- background Background pixel White bell Boolean Boolean False border BorderColor pixel Black borderWidth BorderWidth int 1 date String String NULL destroyCallback Callback Pointer NULL foreground Foreground Pixel Black height Height int 80 mappedWhenManaged MappedWhenManaged Boolean True reverseVideo ReverseVideo Boolean False seconds Boolean Boolean False scroll Boolean Boolean True x Position int 0 y Position int 0 */ #define XtNseconds "seconds" #define XtNbell "bell" #define XtNscroll "scroll" #define XtNdate "date" typedef struct _DclockRec *DclockWidget; typedef struct _DclockClassRec *DclockWidgetClass; extern WidgetClass dclockWidgetClass; #endif _XtDclock_h !Funky!Stuff! fi # end of overwriting check echo shar: "extracting 'DclockP.h'" '(882 characters)' if test -f 'DclockP.h' then echo shar: "will not over-write existing file 'DclockP.h'" else cat << \!Funky!Stuff! > 'DclockP.h' /* * Dclock.c -- a digital clock widget. * Author: Dan Heller <island!argv@sun.com> */ #ifndef _XtDclockP_h #define _XtDclockP_h #include <X11/CoreP.h> #include "Dclock.h" typedef struct { Pixel foreground; Boolean reverse; Boolean scroll; Boolean seconds; Boolean bell; String date_fmt; XFontStruct *font; /* non-resources (e.g. user can't set) */ XtIntervalId interval_id; GC foreGC, backGC; int digit_w, digit_h; Pixmap digits[10]; Pixmap tiny_digits[10]; Pixmap colon[2]; } DclockPart; typedef struct _DclockRec { CorePart core; DclockPart dclock; } DclockRec; typedef struct {int dummy;} DclockClassPart; typedef struct _DclockClassRec { CoreClassPart core_class; DclockClassPart dclock_class; } DclockClassRec; extern DclockClassRec dclockClassRec; #endif _XtDclockP_h !Funky!Stuff! fi # end of overwriting check echo shar: "extracting 'Patchlevel.h'" '(21 characters)' if test -f 'Patchlevel.h' then echo shar: "will not over-write existing file 'Patchlevel.h'" else cat << \!Funky!Stuff! > 'Patchlevel.h' #define PATCHLEVEL 0 !Funky!Stuff! fi # end of overwriting check echo shar: "extracting 'dclock.c'" '(2421 characters)' if test -f 'dclock.c' then echo shar: "will not over-write existing file 'dclock.c'" else cat << \!Funky!Stuff! > 'dclock.c' /* * dclock -- program to demonstrate how to use the digital-clock widget. * To specify a date, the date format is a string of characters. If a * character in the string is a %-sign, the next character is examined * and a value is inserted into the string. Example: * dclock -date "Today is %W" * The date string will print "Today is" and then the %W will be replaced * by the current weekday name. The parameters are: * %W full weekday name * %w three-char weekday name (sun, mon, tue, wed...) * %M full month name * %m three-char abbreviation for that month (jan, feb, mar...) * %d The date (numerical number of the month) * %Y full year (4 digits) * %y 2-digit year number * * To specify seconds to be displayed, use "-seconds" or use the resource * manager: *Dclock.seconds: on */ #include <stdio.h> #include <X11/Intrinsic.h> #include "Dclock.h" static XrmOptionDescRec options[] = { {"-date", "*Dclock.date", XrmoptionSepArg, NULL }, {"-seconds", "*Dclock.seconds", XrmoptionNoArg, "TRUE" }, {"-bell", "*Dclock.bell", XrmoptionNoArg, "TRUE" }, {"-scroll", "*Dclock.scroll", XrmoptionNoArg, "TRUE" }, {"-noscroll","*Dclock.scroll", XrmoptionNoArg, "FALSE" }, }; static void Usage(name) String name; { static char *help_message[] = { "where options include:", " -bg color background color", " -fg color foreground color", " -fn font font name", " -rv reverse video", " -geometry geom size of mailbox", " -display host:dpy X server to contact", " -seconds [on/off] display seconds", " -bell [on/off] ring bell each half hour", " -scroll [on/off] turn off scrolling", " -date \"date format\" show the date in specified format", NULL }; char **cpp; fprintf(stderr, "usage: %s [-options ...]\n", name); for (cpp = help_message; *cpp; cpp++) fprintf(stderr, "%s\n", *cpp); exit(1); } main(argc, argv) char *argv[]; { Widget toplevel; char *name, *rindex(); if (name = rindex(argv[0], '/')) name++; else name = argv[0]; toplevel = XtInitialize(name, "DClock", options, XtNumber(options), &argc,argv); if (argc != 1) Usage(name); XtCreateManagedWidget("dclock", dclockWidgetClass, toplevel, NULL, 0); XtRealizeWidget(toplevel); XtMainLoop(); } !Funky!Stuff! fi # end of overwriting check exit 0 # End of shell archive -- Mike Wexler(wyse!mikew) Phone: (408)433-1000 x1330