From 7fa20e0899cf53cbb6d386d0688127df8b6fb0c7 Mon Sep 17 00:00:00 2001 From: Kaleb Keithley Date: Fri, 14 Nov 2003 15:54:53 +0000 Subject: R6.6 is the Xorg base-line --- Clock.c | 882 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Clock.h | 110 ++++++++ ClockP.h | 118 +++++++++ XClock.ad | 1 + clmask.bit | 27 ++ clock.bit | 29 ++ xclock.c | 175 ++++++++++++ xclock.man | 165 ++++++++++++ 8 files changed, 1507 insertions(+) create mode 100644 Clock.c create mode 100644 Clock.h create mode 100644 ClockP.h create mode 100644 XClock.ad create mode 100644 clmask.bit create mode 100644 clock.bit create mode 100644 xclock.c create mode 100644 xclock.man diff --git a/Clock.c b/Clock.c new file mode 100644 index 0000000..1a01b1b --- /dev/null +++ b/Clock.c @@ -0,0 +1,882 @@ +/* $Xorg: Clock.c,v 1.4 2001/02/09 02:05:39 xorgcvs Exp $ */ + +/*********************************************************** + +Copyright 1987, 1988, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#include +#include +#include +#include "ClockP.h" +#include + +#if defined(__STDC__) && !defined(AIXV3) /* AIX is broken */ +#define Const const +#else +#define Const /**/ +#endif + +#ifdef X_NOT_STDC_ENV +extern struct tm *localtime(); +#define Time_t long +extern Time_t time (); +#else +#include +#define Time_t time_t +#endif + +#ifdef XKB +#include +#endif + +static void clock_tic(), DrawHand(), DrawSecond(), SetSeg(), DrawClockFace(); +static erase_hands(), round(); + +/* Private Definitions */ + +#define VERTICES_IN_HANDS 6 /* to draw triangle */ +#define PI 3.14159265358979 +#define TWOPI (2. * PI) + +#define SECOND_HAND_FRACT 90 +#define MINUTE_HAND_FRACT 70 +#define HOUR_HAND_FRACT 40 +#define HAND_WIDTH_FRACT 7 +#define SECOND_WIDTH_FRACT 5 +#define SECOND_HAND_TIME 30 + +#define ANALOG_SIZE_DEFAULT 164 + +#define max(a, b) ((a) > (b) ? (a) : (b)) +#define min(a, b) ((a) < (b) ? (a) : (b)) +#define abs(a) ((a) < 0 ? -(a) : (a)) + + +/* Initialization of defaults */ + +#define offset(field) XtOffsetOf(ClockRec, clock.field) +#define goffset(field) XtOffsetOf(WidgetRec, core.field) + +static XtResource resources[] = { + {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension), + goffset(width), XtRImmediate, (XtPointer) 0}, + {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension), + goffset(height), XtRImmediate, (XtPointer) 0}, + {XtNupdate, XtCInterval, XtRInt, sizeof(int), + offset(update), XtRImmediate, (XtPointer) 60 }, + {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), + offset(fgpixel), XtRString, XtDefaultForeground}, + {XtNhand, XtCForeground, XtRPixel, sizeof(Pixel), + offset(Hdpixel), XtRString, XtDefaultForeground}, + {XtNhighlight, XtCForeground, XtRPixel, sizeof(Pixel), + offset(Hipixel), XtRString, XtDefaultForeground}, + {XtNanalog, XtCBoolean, XtRBoolean, sizeof(Boolean), + offset(analog), XtRImmediate, (XtPointer) TRUE}, + {XtNchime, XtCBoolean, XtRBoolean, sizeof(Boolean), + offset(chime), XtRImmediate, (XtPointer) FALSE }, + {XtNpadding, XtCMargin, XtRInt, sizeof(int), + offset(padding), XtRImmediate, (XtPointer) 8}, + {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), + offset(font), XtRString, XtDefaultFont}, + {XtNbackingStore, XtCBackingStore, XtRBackingStore, sizeof (int), + offset (backing_store), XtRString, "default"}, +}; + +#undef offset +#undef goffset + +static void ClassInitialize(); +static void Initialize(), Realize(), Destroy(), Resize(), Redisplay(); +static Boolean SetValues(); + +ClockClassRec clockClassRec = { + { /* core fields */ + /* superclass */ (WidgetClass) &simpleClassRec, + /* class_name */ "Clock", + /* widget_size */ sizeof(ClockRec), + /* class_initialize */ ClassInitialize, + /* class_part_initialize */ NULL, + /* class_inited */ FALSE, + /* initialize */ Initialize, + /* initialize_hook */ NULL, + /* realize */ Realize, + /* actions */ NULL, + /* num_actions */ 0, + /* resources */ resources, + /* resource_count */ XtNumber(resources), + /* xrm_class */ NULLQUARK, + /* 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 */ NULL, + /* query_geometry */ XtInheritQueryGeometry, + /* display_accelerator */ XtInheritDisplayAccelerator, + /* extension */ NULL + }, + { /* simple fields */ + /* change_sensitive */ XtInheritChangeSensitive + }, + { /* clock fields */ + /* ignore */ 0 + } +}; + +WidgetClass clockWidgetClass = (WidgetClass) &clockClassRec; + +/**************************************************************** + * + * Private Procedures + * + ****************************************************************/ + +static void ClassInitialize() +{ + XtAddConverter( XtRString, XtRBackingStore, XmuCvtStringToBackingStore, + NULL, 0 ); +} + +/* ARGSUSED */ +static void Initialize (request, new, args, num_args) + Widget request, new; + ArgList args; + Cardinal *num_args; +{ + ClockWidget w = (ClockWidget)new; + XtGCMask valuemask; + XGCValues myXGCV; + int min_height, min_width; + + valuemask = GCForeground | GCBackground | GCFont | GCLineWidth; + if (w->clock.font != NULL) + myXGCV.font = w->clock.font->fid; + else + valuemask &= ~GCFont; /* use server default font */ + + min_width = min_height = ANALOG_SIZE_DEFAULT; + if(!w->clock.analog) { + char *str; + struct tm tm; + Time_t time_value; + + (void) time(&time_value); + tm = *localtime(&time_value); + str = asctime(&tm); + if (w->clock.font == NULL) + w->clock.font = XQueryFont( XtDisplay(w), + XGContextFromGC( + DefaultGCOfScreen(XtScreen(w))) ); + min_width = XTextWidth(w->clock.font, str, strlen(str)) + + 2 * w->clock.padding; + min_height = w->clock.font->ascent + + w->clock.font->descent + 2 * w->clock.padding; + } + if (w->core.width == 0) + w->core.width = min_width; + if (w->core.height == 0) + w->core.height = min_height; + + myXGCV.foreground = w->clock.fgpixel; + myXGCV.background = w->core.background_pixel; + if (w->clock.font != NULL) + myXGCV.font = w->clock.font->fid; + else + valuemask &= ~GCFont; /* use server default font */ + myXGCV.line_width = 0; + w->clock.myGC = XtGetGC((Widget)w, valuemask, &myXGCV); + + valuemask = GCForeground | GCLineWidth ; + myXGCV.foreground = w->core.background_pixel; + w->clock.EraseGC = XtGetGC((Widget)w, valuemask, &myXGCV); + + myXGCV.foreground = w->clock.Hipixel; + w->clock.HighGC = XtGetGC((Widget)w, valuemask, &myXGCV); + + valuemask = GCForeground; + myXGCV.foreground = w->clock.Hdpixel; + w->clock.HandGC = XtGetGC((Widget)w, valuemask, &myXGCV); + + if (w->clock.update <= 0) + w->clock.update = 60; /* make invalid update's use a default */ + w->clock.show_second_hand = (w->clock.update <= SECOND_HAND_TIME); + w->clock.numseg = 0; + w->clock.interval_id = 0; +} + +static void Realize (gw, valueMask, attrs) + Widget gw; + XtValueMask *valueMask; + XSetWindowAttributes *attrs; +{ + ClockWidget w = (ClockWidget) gw; +#ifdef notdef + *valueMask |= CWBitGravity; + attrs->bit_gravity = ForgetGravity; +#endif + switch (w->clock.backing_store) { + case Always: + case NotUseful: + case WhenMapped: + *valueMask |=CWBackingStore; + attrs->backing_store = w->clock.backing_store; + break; + } + (*clockWidgetClass->core_class.superclass->core_class.realize) + (gw, valueMask, attrs); + Resize(gw); +} + +static void Destroy (gw) + Widget gw; +{ + ClockWidget w = (ClockWidget) gw; + if (w->clock.interval_id) XtRemoveTimeOut (w->clock.interval_id); + XtReleaseGC (gw, w->clock.myGC); + XtReleaseGC (gw, w->clock.HighGC); + XtReleaseGC (gw, w->clock.HandGC); + XtReleaseGC (gw, w->clock.EraseGC); +} + +static void Resize (gw) + Widget gw; +{ + ClockWidget w = (ClockWidget) gw; + /* don't do this computation if window hasn't been realized yet. */ + if (XtIsRealized(gw) && w->clock.analog) { + /* need signed value since Dimension is unsigned */ + int radius = ((int) min(w->core.width, w->core.height) - (int) (2 * w->clock.padding)) / 2; + w->clock.radius = (Dimension) max (radius, 1); + + w->clock.second_hand_length = (int)(SECOND_HAND_FRACT * w->clock.radius) / 100; + w->clock.minute_hand_length = (int)(MINUTE_HAND_FRACT * w->clock.radius) / 100; + w->clock.hour_hand_length = (int)(HOUR_HAND_FRACT * w->clock.radius) / 100; + w->clock.hand_width = (int)(HAND_WIDTH_FRACT * w->clock.radius) / 100; + w->clock.second_hand_width = (int)(SECOND_WIDTH_FRACT * w->clock.radius) / 100; + + w->clock.centerX = w->core.width / 2; + w->clock.centerY = w->core.height / 2; + } +} + +/* ARGSUSED */ +static void Redisplay (gw, event, region) + Widget gw; + XEvent *event; /* unused */ + Region region; /* unused */ +{ + ClockWidget w = (ClockWidget) gw; + if (w->clock.analog) { + if (w->clock.numseg != 0) + erase_hands (w, (struct tm *) 0); + DrawClockFace(w); + } else { + w->clock.prev_time_string[0] = '\0'; + } + clock_tic((XtPointer)w, (XtIntervalId)0); +} + +/* ARGSUSED */ +static void clock_tic(client_data, id) + XtPointer client_data; + XtIntervalId *id; +{ + ClockWidget w = (ClockWidget)client_data; + struct tm tm; + Time_t time_value; + char *time_ptr; + register Display *dpy = XtDisplay(w); + register Window win = XtWindow(w); + + if (id || !w->clock.interval_id) + w->clock.interval_id = + XtAppAddTimeOut( XtWidgetToApplicationContext( (Widget) w), + w->clock.update*1000, clock_tic, (XtPointer)w ); + (void) time(&time_value); + tm = *localtime(&time_value); + /* + * Beep on the half hour; double-beep on the hour. + */ + if (w->clock.chime == TRUE) { + if (w->clock.beeped && (tm.tm_min != 30) && + (tm.tm_min != 0)) + w->clock.beeped = FALSE; + if (((tm.tm_min == 30) || (tm.tm_min == 0)) + && (!w->clock.beeped)) { + w->clock.beeped = TRUE; +#ifdef XKB + if (tm.tm_min==0) { + XkbStdBell(dpy,win,50,XkbBI_ClockChimeHour); + XkbStdBell(dpy,win,50,XkbBI_RepeatingLastBell); + } + else { + XkbStdBell(dpy,win,50,XkbBI_ClockChimeHalf); + } +#else + XBell(dpy, 50); + if (tm.tm_min == 0) + XBell(dpy, 50); +#endif + } + } + if( w->clock.analog == FALSE ) { + int clear_from; + int i, len, prev_len; + + time_ptr = asctime(&tm); + len = strlen (time_ptr); + if (time_ptr[len - 1] == '\n') time_ptr[--len] = '\0'; + prev_len = strlen (w->clock.prev_time_string); + for (i = 0; ((i < len) && (i < prev_len) && + (w->clock.prev_time_string[i] == time_ptr[i])); i++); + strcpy (w->clock.prev_time_string+i, time_ptr+i); + + XDrawImageString (dpy, win, w->clock.myGC, + (2+w->clock.padding + + XTextWidth (w->clock.font, time_ptr, i)), + 2+w->clock.font->ascent+w->clock.padding, + time_ptr + i, len - i); + /* + * Clear any left over bits + */ + clear_from = XTextWidth (w->clock.font, time_ptr, len) + + 2 + w->clock.padding; + if (clear_from < (int)w->core.width) + XFillRectangle (dpy, win, w->clock.EraseGC, + clear_from, 0, w->core.width - clear_from, w->core.height); + } else { + /* + * The second (or minute) hand is sec (or min) + * sixtieths around the clock face. The hour hand is + * (hour + min/60) twelfths of the way around the + * clock-face. The derivation is left as an excercise + * for the reader. + */ + + /* + * 12 hour clock. + */ + if(tm.tm_hour >= 12) + tm.tm_hour -= 12; + + erase_hands (w, &tm); + + if (w->clock.numseg == 0 || + tm.tm_min != w->clock.otm.tm_min || + tm.tm_hour != w->clock.otm.tm_hour) { + w->clock.segbuffptr = w->clock.segbuff; + w->clock.numseg = 0; + /* + * Calculate the hour hand, fill it in with its + * color and then outline it. Next, do the same + * with the minute hand. This is a cheap hidden + * line algorithm. + */ + DrawHand(w, + w->clock.minute_hand_length, w->clock.hand_width, + tm.tm_min * 12 + ); + if(w->clock.Hdpixel != w->core.background_pixel) + XFillPolygon( dpy, + win, w->clock.HandGC, + w->clock.segbuff, VERTICES_IN_HANDS, + Convex, CoordModeOrigin + ); + XDrawLines( dpy, + win, w->clock.HighGC, + w->clock.segbuff, VERTICES_IN_HANDS, + CoordModeOrigin); + w->clock.hour = w->clock.segbuffptr; + DrawHand(w, + w->clock.hour_hand_length, w->clock.hand_width, + tm.tm_hour * 60 + tm.tm_min + ); + if(w->clock.Hdpixel != w->core.background_pixel) { + XFillPolygon(dpy, + win, w->clock.HandGC, + w->clock.hour, + VERTICES_IN_HANDS, + Convex, CoordModeOrigin + ); + } + XDrawLines( dpy, + win, w->clock.HighGC, + w->clock.hour, VERTICES_IN_HANDS, + CoordModeOrigin ); + + w->clock.sec = w->clock.segbuffptr; + } + if (w->clock.show_second_hand == TRUE) { + w->clock.segbuffptr = w->clock.sec; + DrawSecond(w, + w->clock.second_hand_length - 2, + w->clock.second_hand_width, + w->clock.minute_hand_length + 2, + tm.tm_sec * 12 + ); + if(w->clock.Hdpixel != w->core.background_pixel) + XFillPolygon( dpy, + win, w->clock.HandGC, + w->clock.sec, + VERTICES_IN_HANDS -2, + Convex, CoordModeOrigin + ); + XDrawLines( dpy, + win, w->clock.HighGC, + w->clock.sec, + VERTICES_IN_HANDS-1, + CoordModeOrigin + ); + + } + w->clock.otm = tm; + } +} + +static erase_hands (w, tm) +ClockWidget w; +struct tm *tm; +{ + /* + * Erase old hands. + */ + if(w->clock.numseg > 0) { + Display *dpy; + Window win; + + dpy = XtDisplay (w); + win = XtWindow (w); + if (w->clock.show_second_hand == TRUE) { + XDrawLines(dpy, win, + w->clock.EraseGC, + w->clock.sec, + VERTICES_IN_HANDS-1, + CoordModeOrigin); + if(w->clock.Hdpixel != w->core.background_pixel) { + XFillPolygon(dpy, + win, w->clock.EraseGC, + w->clock.sec, + VERTICES_IN_HANDS-2, + Convex, CoordModeOrigin + ); + } + } + if(!tm || tm->tm_min != w->clock.otm.tm_min || + tm->tm_hour != w->clock.otm.tm_hour) + { + XDrawLines( dpy, win, + w->clock.EraseGC, + w->clock.segbuff, + VERTICES_IN_HANDS, + CoordModeOrigin); + XDrawLines( dpy, win, + w->clock.EraseGC, + w->clock.hour, + VERTICES_IN_HANDS, + CoordModeOrigin); + if(w->clock.Hdpixel != w->core.background_pixel) { + XFillPolygon( dpy, win, + w->clock.EraseGC, + w->clock.segbuff, VERTICES_IN_HANDS, + Convex, CoordModeOrigin); + XFillPolygon( dpy, win, + w->clock.EraseGC, + w->clock.hour, + VERTICES_IN_HANDS, + Convex, CoordModeOrigin); + } + } + } +} + +static float Const Sines[] = { +.000000, .008727, .017452, .026177, .034899, .043619, .052336, .061049, +.069756, .078459, .087156, .095846, .104528, .113203, .121869, .130526, +.139173, .147809, .156434, .165048, .173648, .182236, .190809, .199368, +.207912, .216440, .224951, .233445, .241922, .250380, .258819, .267238, +.275637, .284015, .292372, .300706, .309017, .317305, .325568, .333807, +.342020, .350207, .358368, .366501, .374607, .382683, .390731, .398749, +.406737, .414693, .422618, .430511, .438371, .446198, .453990, .461749, +.469472, .477159, .484810, .492424, .500000, .507538, .515038, .522499, +.529919, .537300, .544639, .551937, .559193, .566406, .573576, .580703, +.587785, .594823, .601815, .608761, .615661, .622515, .629320, .636078, +.642788, .649448, .656059, .662620, .669131, .675590, .681998, .688355, +.694658, .700909, .707107 +}; + +static float Const Cosines[] = { +1.00000, .999962, .999848, .999657, .999391, .999048, .998630, .998135, +.997564, .996917, .996195, .995396, .994522, .993572, .992546, .991445, +.990268, .989016, .987688, .986286, .984808, .983255, .981627, .979925, +.978148, .976296, .974370, .972370, .970296, .968148, .965926, .963630, +.961262, .958820, .956305, .953717, .951057, .948324, .945519, .942641, +.939693, .936672, .933580, .930418, .927184, .923880, .920505, .917060, +.913545, .909961, .906308, .902585, .898794, .894934, .891007, .887011, +.882948, .878817, .874620, .870356, .866025, .861629, .857167, .852640, +.848048, .843391, .838671, .833886, .829038, .824126, .819152, .814116, +.809017, .803857, .798636, .793353, .788011, .782608, .777146, .771625, +.766044, .760406, .754710, .748956, .743145, .737277, .731354, .725374, +.719340, .713250, .707107 +}; + +static void ClockAngle(tick_units, sinp, cosp) + int tick_units; + double *sinp, *cosp; +{ + int reduced, upper; + + reduced = tick_units % 90; + upper = tick_units / 90; + if (upper & 1) + reduced = 90 - reduced; + if ((upper + 1) & 2) { + *sinp = Cosines[reduced]; + *cosp = Sines[reduced]; + } else { + *sinp = Sines[reduced]; + *cosp = Cosines[reduced]; + } + if (upper >= 2 && upper < 6) + *cosp = -*cosp; + if (upper >= 4) + *sinp = -*sinp; +} + +/* + * DrawLine - Draws a line. + * + * blank_length is the distance from the center which the line begins. + * length is the maximum length of the hand. + * Tick_units is a number between zero and 12*60 indicating + * how far around the circle (clockwise) from high noon. + * + * The blank_length feature is because I wanted to draw tick-marks around the + * circle (for seconds). The obvious means of drawing lines from the center + * to the perimeter, then erasing all but the outside most pixels doesn't + * work because of round-off error (sigh). + */ +static void DrawLine(w, blank_length, length, tick_units) +ClockWidget w; +Dimension blank_length; +Dimension length; +int tick_units; +{ + double dblank_length = (double)blank_length, dlength = (double)length; + double cosangle, sinangle; + int cx = w->clock.centerX, cy = w->clock.centerY, x1, y1, x2, y2; + + /* + * Angles are measured from 12 o'clock, clockwise increasing. + * Since in X, +x is to the right and +y is downward: + * + * x = x0 + r * sin(theta) + * y = y0 - r * cos(theta) + * + */ + ClockAngle(tick_units, &sinangle, &cosangle); + + /* break this out so that stupid compilers can cope */ + x1 = cx + (int)(dblank_length * sinangle); + y1 = cy - (int)(dblank_length * cosangle); + x2 = cx + (int)(dlength * sinangle); + y2 = cy - (int)(dlength * cosangle); + SetSeg(w, x1, y1, x2, y2); +} + +/* + * DrawHand - Draws a hand. + * + * length is the maximum length of the hand. + * width is the half-width of the hand. + * Tick_units is a number between zero and 12*60 indicating + * how far around the circle (clockwise) from high noon. + * + */ +static void DrawHand(w, length, width, tick_units) +ClockWidget w; +Dimension length, width; +int tick_units; +{ + + double cosangle, sinangle; + register double ws, wc; + Position x, y, x1, y1, x2, y2; + + /* + * Angles are measured from 12 o'clock, clockwise increasing. + * Since in X, +x is to the right and +y is downward: + * + * x = x0 + r * sin(theta) + * y = y0 - r * cos(theta) + * + */ + ClockAngle(tick_units, &sinangle, &cosangle); + /* + * Order of points when drawing the hand. + * + * 1,4 + * / \ + * / \ + * / \ + * 2 ------- 3 + */ + wc = width * cosangle; + ws = width * sinangle; + SetSeg(w, + x = w->clock.centerX + round(length * sinangle), + y = w->clock.centerY - round(length * cosangle), + x1 = w->clock.centerX - round(ws + wc), + y1 = w->clock.centerY + round(wc - ws)); /* 1 ---- 2 */ + /* 2 */ + SetSeg(w, x1, y1, + x2 = w->clock.centerX - round(ws - wc), + y2 = w->clock.centerY + round(wc + ws)); /* 2 ----- 3 */ + + SetSeg(w, x2, y2, x, y); /* 3 ----- 1(4) */ +} + +/* + * DrawSecond - Draws the second hand (diamond). + * + * length is the maximum length of the hand. + * width is the half-width of the hand. + * offset is direct distance from center to tail end. + * Tick_units is a number between zero and 12*60 indicating + * how far around the circle (clockwise) from high noon. + * + */ +static void DrawSecond(w, length, width, offset, tick_units) +ClockWidget w; +Dimension length, width, offset; +int tick_units; +{ + + double cosangle, sinangle; + register double ms, mc, ws, wc; + register int mid; + Position x, y; + + /* + * Angles are measured from 12 o'clock, clockwise increasing. + * Since in X, +x is to the right and +y is downward: + * + * x = x0 + r * sin(theta) + * y = y0 - r * cos(theta) + * + */ + ClockAngle(tick_units, &sinangle, &cosangle); + /* + * Order of points when drawing the hand. + * + * 1,5 + * / \ + * / \ + * / \ + * 2< >4 + * \ / + * \ / + * \ / + * - 3 + * | + * | + * offset + * | + * | + * - + center + */ + + mid = (int) (length + offset) / 2; + mc = mid * cosangle; + ms = mid * sinangle; + wc = width * cosangle; + ws = width * sinangle; + /*1 ---- 2 */ + SetSeg(w, + x = w->clock.centerX + round(length * sinangle), + y = w->clock.centerY - round(length * cosangle), + w->clock.centerX + round(ms - wc), + w->clock.centerY - round(mc + ws) ); + SetSeg(w, w->clock.centerX + round(offset *sinangle), + w->clock.centerY - round(offset * cosangle), /* 2-----3 */ + w->clock.centerX + round(ms + wc), + w->clock.centerY - round(mc - ws)); + w->clock.segbuffptr->x = x; + w->clock.segbuffptr++->y = y; + w->clock.numseg ++; +} + +static void SetSeg(w, x1, y1, x2, y2) +ClockWidget w; +int x1, y1, x2, y2; +{ + w->clock.segbuffptr->x = x1; + w->clock.segbuffptr++->y = y1; + w->clock.segbuffptr->x = x2; + w->clock.segbuffptr++->y = y2; + w->clock.numseg += 2; +} + +/* + * Draw the clock face (every fifth tick-mark is longer + * than the others). + */ +static void DrawClockFace(w) +ClockWidget w; +{ + register int i; + register int delta = (int)(w->clock.radius - w->clock.second_hand_length) / 3; + + w->clock.segbuffptr = w->clock.segbuff; + w->clock.numseg = 0; + for (i = 0; i < 60; i++) + DrawLine(w, ( (i % 5) == 0 ? + w->clock.second_hand_length : + (w->clock.radius - delta) ), + w->clock.radius, i * 12); + /* + * Go ahead and draw it. + */ + XDrawSegments(XtDisplay(w), XtWindow(w), + w->clock.myGC, (XSegment *) &(w->clock.segbuff[0]), + w->clock.numseg/2); + + w->clock.segbuffptr = w->clock.segbuff; + w->clock.numseg = 0; +} + +static int round(x) +double x; +{ + return(x >= 0.0 ? (int)(x + .5) : (int)(x - .5)); +} + +/* ARGSUSED */ +static Boolean SetValues (gcurrent, grequest, gnew, args, num_args) + Widget gcurrent, grequest, gnew; + ArgList args; + Cardinal *num_args; +{ + ClockWidget current = (ClockWidget) gcurrent; + ClockWidget new = (ClockWidget) gnew; + Boolean redisplay = FALSE; + XtGCMask valuemask; + XGCValues myXGCV; + + /* first check for changes to clock-specific resources. We'll accept all + the changes, but may need to do some computations first. */ + + if (new->clock.update != current->clock.update) { + if (current->clock.interval_id) + XtRemoveTimeOut (current->clock.interval_id); + if (XtIsRealized( (Widget) new)) + new->clock.interval_id = XtAppAddTimeOut( + XtWidgetToApplicationContext(gnew), + new->clock.update*1000, + clock_tic, (XtPointer)gnew); + + new->clock.show_second_hand =(new->clock.update <= SECOND_HAND_TIME); + } + + if (new->clock.padding != current->clock.padding) + redisplay = TRUE; + + if (new->clock.analog != current->clock.analog) + redisplay = TRUE; + + if (new->clock.font != current->clock.font) + redisplay = TRUE; + + if ((new->clock.fgpixel != current->clock.fgpixel) + || (new->core.background_pixel != current->core.background_pixel)) { + valuemask = GCForeground | GCBackground | GCFont | GCLineWidth; + myXGCV.foreground = new->clock.fgpixel; + myXGCV.background = new->core.background_pixel; + myXGCV.font = new->clock.font->fid; + myXGCV.line_width = 0; + XtReleaseGC (gcurrent, current->clock.myGC); + new->clock.myGC = XtGetGC(gcurrent, valuemask, &myXGCV); + redisplay = TRUE; + } + + if (new->clock.Hipixel != current->clock.Hipixel) { + valuemask = GCForeground | GCLineWidth; + myXGCV.foreground = new->clock.Hipixel; + myXGCV.font = new->clock.font->fid; + myXGCV.line_width = 0; + XtReleaseGC (gcurrent, current->clock.HighGC); + new->clock.HighGC = XtGetGC((Widget)gcurrent, valuemask, &myXGCV); + redisplay = TRUE; + } + + if (new->clock.Hdpixel != current->clock.Hdpixel) { + valuemask = GCForeground; + myXGCV.foreground = new->clock.Hdpixel; + XtReleaseGC (gcurrent, current->clock.HandGC); + new->clock.HandGC = XtGetGC((Widget)gcurrent, valuemask, &myXGCV); + redisplay = TRUE; + } + + if (new->core.background_pixel != current->core.background_pixel) { + valuemask = GCForeground | GCLineWidth; + myXGCV.foreground = new->core.background_pixel; + myXGCV.line_width = 0; + XtReleaseGC (gcurrent, current->clock.EraseGC); + new->clock.EraseGC = XtGetGC((Widget)gcurrent, valuemask, &myXGCV); + redisplay = TRUE; + } + + return (redisplay); + +} diff --git a/Clock.h b/Clock.h new file mode 100644 index 0000000..a244370 --- /dev/null +++ b/Clock.h @@ -0,0 +1,110 @@ +/* +* $Xorg: Clock.h,v 1.4 2001/02/09 02:05:39 xorgcvs Exp $ +*/ + + +/*********************************************************** + +Copyright 1987, 1988, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawClock_h +#define _XawClock_h + +/*********************************************************************** + * + * Clock Widget + * + ***********************************************************************/ + +#include + +/* Parameters: + + Name Class RepType Default Value + ---- ----- ------- ------------- + analog Boolean Boolean True + background Background Pixel white + backingStore BackingStore BackingStore default + border BorderColor Pixel Black + borderWidth BorderWidth Dimension 1 + chime Boolean Boolean False + destroyCallback Callback Pointer NULL + font Font XFontStruct* fixed + foreground Foreground Pixel black + hand Foreground Pixel black + height Height Dimension 164 + highlight Foreground Pixel black + mappedWhenManaged MappedWhenManaged Boolean True + padding Margin int 8 + update Interval int 60 (seconds) + width Width Dimension 164 + x Position Position 0 + y Position Position 0 + +*/ + +/* Resource names used to the clock widget */ + + /* color of hands */ +#define XtNhand "hands" + + + /* Boolean: digital if FALSE */ +#define XtNanalog "analog" + + /* Boolean: */ +#define XtNchime "chime" + + /* Int: amount of space around outside of clock */ +#define XtNpadding "padding" + +typedef struct _ClockRec *ClockWidget; /* completely defined in ClockPrivate.h */ +typedef struct _ClockClassRec *ClockWidgetClass; /* completely defined in ClockPrivate.h */ + +extern WidgetClass clockWidgetClass; + +#endif /* _XawClock_h */ +/* DON'T ADD STUFF AFTER THIS #endif */ diff --git a/ClockP.h b/ClockP.h new file mode 100644 index 0000000..3f677e1 --- /dev/null +++ b/ClockP.h @@ -0,0 +1,118 @@ +/* +* $Xorg: ClockP.h,v 1.4 2001/02/09 02:05:39 xorgcvs Exp $ +*/ + + +/*********************************************************** + +Copyright 1987, 1988, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawClockP_h +#define _XawClockP_h + +#include /* Needed for struct tm. */ +#include "Clock.h" +#include + +#define SEG_BUFF_SIZE 128 +#define ASCII_TIME_BUFLEN 32 /* big enough for 26 plus slop */ + +/* New fields for the clock widget instance record */ +typedef struct { + Pixel fgpixel; /* color index for text */ + Pixel Hipixel; /* color index for Highlighting */ + Pixel Hdpixel; /* color index for hands */ + XFontStruct *font; /* font for text */ + GC myGC; /* pointer to GraphicsContext */ + GC EraseGC; /* eraser GC */ + GC HandGC; /* Hand GC */ + GC HighGC; /* Highlighting GC */ +/* start of graph stuff */ + int update; /* update frequence */ + Dimension radius; /* radius factor */ + int backing_store; /* backing store type */ + Boolean chime; + Boolean beeped; + Boolean analog; + Boolean show_second_hand; + Dimension second_hand_length; + Dimension minute_hand_length; + Dimension hour_hand_length; + Dimension hand_width; + Dimension second_hand_width; + Position centerX; + Position centerY; + int numseg; + int padding; + XPoint segbuff[SEG_BUFF_SIZE]; + XPoint *segbuffptr; + XPoint *hour, *sec; + struct tm otm ; + XtIntervalId interval_id; + char prev_time_string[ASCII_TIME_BUFLEN]; + } ClockPart; + +/* Full instance record declaration */ +typedef struct _ClockRec { + CorePart core; + SimplePart simple; + ClockPart clock; + } ClockRec; + +/* New fields for the Clock widget class record */ +typedef struct {int dummy;} ClockClassPart; + +/* Full class record declaration. */ +typedef struct _ClockClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + ClockClassPart clock_class; + } ClockClassRec; + +/* Class pointer. */ +extern ClockClassRec clockClassRec; + +#endif /* _XawClockP_h */ diff --git a/XClock.ad b/XClock.ad new file mode 100644 index 0000000..971ae2d --- /dev/null +++ b/XClock.ad @@ -0,0 +1 @@ +XClock.input: false diff --git a/clmask.bit b/clmask.bit new file mode 100644 index 0000000..afeb014 --- /dev/null +++ b/clmask.bit @@ -0,0 +1,27 @@ +#define clock_mask_width 48 +#define clock_mask_height 48 +static unsigned char clock_mask_bits[] = { + 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, + 0x00, 0xe0, 0xff, 0xff, 0x03, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x07, 0x00, + 0x00, 0xf8, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x1f, 0x00, + 0x00, 0xfe, 0xff, 0xff, 0x3f, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x00, + 0x80, 0xff, 0xff, 0xff, 0xff, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x01, + 0xe0, 0xff, 0xff, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x03, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x07, + 0xf8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x0f, + 0xf8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0xfc, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0xfc, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xfc, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xfc, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0xfc, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x0f, + 0xf8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x07, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x03, + 0xe0, 0xff, 0xff, 0xff, 0xff, 0x01, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x01, + 0x80, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x00, + 0x00, 0xfe, 0xff, 0xff, 0x3f, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x1f, 0x00, + 0x00, 0xf8, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x07, 0x00, + 0x00, 0xe0, 0xff, 0xff, 0x03, 0x00, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00}; diff --git a/clock.bit b/clock.bit new file mode 100644 index 0000000..5e9ab18 --- /dev/null +++ b/clock.bit @@ -0,0 +1,29 @@ +#define clock_width 48 +#define clock_height 48 +#define clock_x_hot -1 +#define clock_y_hot -1 +static unsigned char clock_bits[] = { + 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, + 0x00, 0xe0, 0xff, 0xff, 0x03, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x07, 0x00, + 0x00, 0xf8, 0x87, 0xf1, 0x0f, 0x00, 0x00, 0xfc, 0x80, 0x81, 0x1f, 0x00, + 0x00, 0x3e, 0x80, 0x01, 0x3e, 0x00, 0x00, 0x9f, 0x01, 0xc0, 0x7c, 0x00, + 0x80, 0x8f, 0x01, 0xc0, 0xf8, 0x00, 0xc0, 0x07, 0x00, 0x00, 0xf0, 0x01, + 0xe0, 0x03, 0x00, 0x00, 0xe0, 0x03, 0xe0, 0x01, 0x00, 0x00, 0xc0, 0x03, + 0xf0, 0x00, 0x00, 0x40, 0x80, 0x07, 0xf0, 0x06, 0x00, 0xe0, 0xb0, 0x07, + 0x78, 0x06, 0x00, 0xf0, 0x30, 0x0f, 0x78, 0x00, 0x00, 0x78, 0x00, 0x0f, + 0x78, 0x00, 0x00, 0x3c, 0x00, 0x0f, 0x3c, 0x00, 0x00, 0x1e, 0x00, 0x1e, + 0x3c, 0x00, 0x00, 0x0f, 0x00, 0x1e, 0x3c, 0x00, 0x80, 0x07, 0x00, 0x1e, + 0x3c, 0x00, 0xc0, 0x03, 0x00, 0x7e, 0xfc, 0x01, 0xc0, 0x03, 0xc0, 0x7f, + 0xfc, 0x01, 0x80, 0x07, 0xc0, 0x7f, 0x3c, 0x00, 0x00, 0x0f, 0x00, 0x7e, + 0x3c, 0x00, 0x00, 0x1e, 0x00, 0x1e, 0x3c, 0x00, 0x00, 0x1c, 0x00, 0x1e, + 0x7c, 0x00, 0x00, 0x08, 0x00, 0x0f, 0x78, 0x00, 0x00, 0x00, 0x00, 0x0f, + 0x78, 0x06, 0x00, 0x00, 0x30, 0x0f, 0xf0, 0x06, 0x00, 0x00, 0xb0, 0x07, + 0xf0, 0x00, 0x00, 0x00, 0x80, 0x07, 0xe0, 0x01, 0x00, 0x00, 0xc0, 0x03, + 0xe0, 0x03, 0x00, 0x00, 0xe0, 0x01, 0xc0, 0x07, 0x00, 0x00, 0xf0, 0x01, + 0x80, 0x8f, 0x01, 0xc0, 0xf8, 0x00, 0x00, 0x9f, 0x01, 0xc0, 0x7c, 0x00, + 0x00, 0x3e, 0x80, 0x01, 0x3e, 0x00, 0x00, 0xfc, 0x80, 0x81, 0x1f, 0x00, + 0x00, 0xf8, 0x87, 0xf1, 0x0f, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x07, 0x00, + 0x00, 0xe0, 0xff, 0xff, 0x03, 0x00, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00}; diff --git a/xclock.c b/xclock.c new file mode 100644 index 0000000..8ac6723 --- /dev/null +++ b/xclock.c @@ -0,0 +1,175 @@ +/* $Xorg: xclock.c,v 1.4 2001/02/09 02:05:39 xorgcvs Exp $ */ + +/* + * xclock -- Hacked from Tony Della Fera's much hacked clock program. + */ + +/* +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + */ + +#include +#include +#include +#include +#include "Clock.h" +#include +#include "clock.bit" +#include "clmask.bit" + +#ifdef XKB +#include +#endif + +extern void exit(); + +/* Command line options table. Only resources are entered here...there is a + pass over the remaining options after XtParseCommand is let loose. */ + +static XrmOptionDescRec options[] = { +{"-chime", "*clock.chime", XrmoptionNoArg, "TRUE"}, +{"-hd", "*clock.hands", XrmoptionSepArg, NULL}, +{"-hands", "*clock.hands", XrmoptionSepArg, NULL}, +{"-hl", "*clock.highlight", XrmoptionSepArg, NULL}, +{"-highlight", "*clock.highlight", XrmoptionSepArg, NULL}, +{"-update", "*clock.update", XrmoptionSepArg, NULL}, +{"-padding", "*clock.padding", XrmoptionSepArg, NULL}, +{"-d", "*clock.analog", XrmoptionNoArg, "FALSE"}, +{"-digital", "*clock.analog", XrmoptionNoArg, "FALSE"}, +{"-analog", "*clock.analog", XrmoptionNoArg, "TRUE"}, +}; + +static void quit(); +static XtActionsRec xclock_actions[] = { + { "quit", quit }, +}; + +static Atom wm_delete_window; + +/* + * Report the syntax for calling xclock. + */ +Syntax(call) + char *call; +{ + (void) printf ("Usage: %s [-analog] [-bw ] [-digital]\n", call); + (void) printf (" [-fg ] [-bg ] [-hd ]\n"); + (void) printf (" [-hl ] [-bd ]\n"); + (void) printf (" [-fn ] [-help] [-padding ]\n"); + (void) printf (" [-rv] [-update ] [-display displayname]\n"); + (void) printf (" [-geometry geom]\n\n"); + exit(1); +} + +static void die(w, client_data, call_data) + Widget w; + XtPointer client_data; + XtPointer call_data; +{ + XCloseDisplay(XtDisplayOfObject(w)); + exit(0); +} + +static void quit (w, event, params, num_params) + Widget w; /* ApplicationShellWidget */ + XEvent *event; + String *params; + Cardinal *num_params; +{ + Arg arg; + + if (event->type == ClientMessage && + event->xclient.data.l[0] != wm_delete_window) { +#ifdef XKB + XkbStdBell(XtDisplay(w), XtWindow(w), 0, XkbBI_MinorError); +#else + XBell (XtDisplay(w), 0); +#endif + } else { + /* resign from the session */ + XtSetArg(arg, XtNjoinSession, False); + XtSetValues(w, &arg, ONE); + die(w, NULL, NULL); + } +} + +static void save(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + XtCheckpointToken token = (XtCheckpointToken) call_data; + /* we have nothing to save */ + token->save_success = True; +} + +void main(argc, argv) + int argc; + char **argv; +{ + Widget toplevel; + Arg arg; + Pixmap icon_pixmap = None; + XtAppContext app_con; + + toplevel = XtOpenApplication(&app_con, "XClock", + options, XtNumber(options), &argc, argv, NULL, + sessionShellWidgetClass, NULL, ZERO); + if (argc != 1) Syntax(argv[0]); + XtAddCallback(toplevel, XtNdieCallback, die, NULL); + XtAddCallback(toplevel, XtNsaveCallback, save, NULL); + + XtAppAddActions (app_con, xclock_actions, XtNumber(xclock_actions)); + + /* + * This is a hack so that wm_delete_window will do something useful + * in this single-window application. + */ + XtOverrideTranslations(toplevel, + XtParseTranslationTable ("WM_PROTOCOLS: quit()")); + + XtSetArg(arg, XtNiconPixmap, &icon_pixmap); + XtGetValues(toplevel, &arg, ONE); + if (icon_pixmap == None) { + arg.value = (XtArgVal)XCreateBitmapFromData(XtDisplay(toplevel), + XtScreen(toplevel)->root, + (char *)clock_bits, clock_width, clock_height); + XtSetValues (toplevel, &arg, ONE); + } + XtSetArg(arg, XtNiconMask, &icon_pixmap); + XtGetValues(toplevel, &arg, ONE); + if (icon_pixmap == None) { + arg.value = (XtArgVal)XCreateBitmapFromData(XtDisplay(toplevel), + XtScreen(toplevel)->root, + (char *)clock_mask_bits, clock_mask_width, + clock_mask_height); + XtSetValues (toplevel, &arg, ONE); + } + + XtCreateManagedWidget ("clock", clockWidgetClass, toplevel, NULL, ZERO); + XtRealizeWidget (toplevel); + wm_delete_window = XInternAtom (XtDisplay(toplevel), "WM_DELETE_WINDOW", + False); + (void) XSetWMProtocols (XtDisplay(toplevel), XtWindow(toplevel), + &wm_delete_window, 1); + XtAppMainLoop (app_con); +} diff --git a/xclock.man b/xclock.man new file mode 100644 index 0000000..0019d77 --- /dev/null +++ b/xclock.man @@ -0,0 +1,165 @@ +.\" $Xorg: xclock.man,v 1.4 2001/02/09 02:05:39 xorgcvs Exp $ +.\" Copyright 1988, 1994, 1998 The Open Group +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and its +.\" documentation for any purpose is hereby granted without fee, provided that +.\" the above copyright notice appear in all copies and that both that +.\" copyright notice and this permission notice appear in supporting +.\" documentation. +.\" +.\" The above copyright notice and this permission notice shall be included +.\" in all copies or substantial portions of the Software. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +.\" OTHER DEALINGS IN THE SOFTWARE. +.\" +.\" Except as contained in this notice, the name of The Open Group shall +.\" not be used in advertising or otherwise to promote the sale, use or +.\" other dealings in this Software without prior written authorization +.\" from The Open Group. +.TH XCLOCK 1 "Release 6.4" "X Version 11" +.SH NAME +xclock \- analog / digital clock for X +.SH SYNOPSIS +.ta 8n +\fBxclock\fP [ \fB\-help\fP ] [ \fB\-analog\fP ] [ \fB\-digital\fP ] +[ \fB\-chime\fP ] [ \fB\-hd\fP \fIcolor\fP ] +[ \fB\-hl\fP \fIcolor\fP ] [ \fB\-update\fP \fIseconds\fP ] +[ \fB\-padding\fP \fInumber\fP ] +.SH DESCRIPTION +The +.I xclock +program displays the time in analog or digital form. The time is continuously +updated at a frequency which may be specified by the user. +.SH OPTIONS +.I Xclock +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 \-analog +This option indicates that a conventional 12 hour clock face with tick marks +and hands should be used. This is the default. +.TP 8 +\fB\-digital\fP or \fB\-d\fP +This option indicates that a 24 hour digital clock should be used. +.TP 8 +.B \-chime +This option indicates that the clock should chime +once on the half hour and twice on the hour. +.TP 8 +\fB\-hands\fP \fIcolor\fP (or \fB\-hd\fP \fIcolor\fP) +This option specifies the color of the hands on an analog clock. The default +is \fIblack\fP. +.TP 8 +\fB\-highlight\fP \fIcolor\fP (or \fB\-hl\fP \fIcolor\fP) +This option specifies the color of the edges of the hands on an analog clock, +and is only useful on color displays. The default is \fIblack\fP. +.TP 8 +.B \-update \fIseconds\fP +This option specifies the frequency in seconds at which \fIxclock\fP +should update its display. If the clock is obscured and then exposed, +it will be updated immediately. A value of 30 seconds or less will enable a +second hand on an analog clock. The default is 60 seconds. +.TP 8 +.B \-padding \fInumber\fP +This option specifies the width in pixels of the padding +between the window border and clock text or picture. The default is 10 +on a digital clock and 8 on an analog clock. +.SH X DEFAULTS +This program uses the +.I Clock +widget. 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. The default for analog clocks is 164 +pixels; the default for digital clocks is whatever is needed to hold the +clock when displayed in the chosen font. +.TP 8 +.B height (\fPclass\fB Height) +Specifies the height of the clock. The default for analog clocks is 164 +pixels; the default for digital clocks is whatever is needed to hold the +clock when displayed in the chosen font. +.TP 8 +.B update (\fPclass\fB Interval) +Specifies the frequency in seconds at which the time should be redisplayed. +.TP 8 +.B foreground (\fPclass\fB Foreground) +Specifies the color for the tic marks. The default is depends on whether +\fIreverseVideo\fP is specified. If \fIreverseVideo\fP is specified +the default is \fIlwhite\fP, otherwise the default is \fIblack\fP. + +.TP 8 +.B hands (\fPclass\fB Foreground) +Specifies the color of the insides of the clock's hands. The default is +depends on whether +\fIreverseVideo\fP is specified. If \fIreverseVideo\fP is specified +the default is \fIlwhite\fP, otherwise the default is \fIblack\fP. +.TP 8 +.B highlight (\fPclass\fB Foreground) +Specifies the color used to highlight the clock's hands. The default is + depends on whether +\fIreverseVideo\fP is specified. If \fIreverseVideo\fP is specified +the default is \fIlwhite\fP, otherwise the default is \fIblack\fP. +.TP 8 +.B analog (\fPclass\fB Boolean) +Specifies whether or not an analog clock should be used instead of a digital +one. The default is True. +.TP 8 +.B chime (\fPclass\fB Boolean) +Specifies whether or not a bell should be rung on the hour and half hour. +.TP 8 +.B padding (\fPclass\fB Margin) +Specifies the amount of internal padding in pixels to be used. The default is +8. +.TP 8 +.B font (\fPclass\fB Font) +Specifies the font to be used for the digital clock. Note that variable width +fonts currently will not always display correctly. +.SH WIDGETS +In order to specify resources, it is useful to know the hierarchy of +the widgets which compose \fIxclock\fR. In the notation below, +indentation indicates hierarchical structure. The widget class name +is given first, followed by the widget instance name. +.sp +.nf +.TA .5i +.ta .5i +XClock xclock + Clock clock +.fi +.sp +.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 FILES +/lib/X11/app-defaults/XClock - specifies required resources +.SH "SEE ALSO" +X(1), xrdb(1), time(3C) +.SH BUGS +.I Xclock +believes the system clock. +.PP +When in digital mode, the string should be centered automatically. +.SH AUTHORS +Tony Della Fera (MIT-Athena, DEC) +.br +Dave Mankins (MIT-Athena, BBN) +.br +Ed Moy (UC Berkeley) + -- cgit v1.2.3