diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 15:54:53 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 15:54:53 +0000 |
commit | 7fa20e0899cf53cbb6d386d0688127df8b6fb0c7 (patch) | |
tree | 2a47ff68a964eb21a7cb24420e7d3183bfa9720f |
R6.6 is the Xorg base-lineXORG-MAIN
-rw-r--r-- | Clock.c | 882 | ||||
-rw-r--r-- | Clock.h | 110 | ||||
-rw-r--r-- | ClockP.h | 118 | ||||
-rw-r--r-- | XClock.ad | 1 | ||||
-rw-r--r-- | clmask.bit | 27 | ||||
-rw-r--r-- | clock.bit | 29 | ||||
-rw-r--r-- | xclock.c | 175 | ||||
-rw-r--r-- | xclock.man | 165 |
8 files changed, 1507 insertions, 0 deletions
@@ -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 <X11/Xlib.h> +#include <X11/StringDefs.h> +#include <X11/IntrinsicP.h> +#include "ClockP.h" +#include <X11/Xosdefs.h> + +#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 <time.h> +#define Time_t time_t +#endif + +#ifdef XKB +#include <X11/extensions/XKBbells.h> +#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); + +} @@ -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 <X11/Xmu/Converters.h> + +/* 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 <X11/Xos.h> /* Needed for struct tm. */ +#include "Clock.h" +#include <X11/Xaw/SimpleP.h> + +#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 <X11/Xatom.h> +#include <X11/Intrinsic.h> +#include <X11/StringDefs.h> +#include <X11/Shell.h> +#include "Clock.h" +#include <X11/Xaw/Cardinals.h> +#include "clock.bit" +#include "clmask.bit" + +#ifdef XKB +#include <X11/extensions/XKBbells.h> +#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 <pixels>] [-digital]\n", call); + (void) printf (" [-fg <color>] [-bg <color>] [-hd <color>]\n"); + (void) printf (" [-hl <color>] [-bd <color>]\n"); + (void) printf (" [-fn <font_name>] [-help] [-padding <pixels>]\n"); + (void) printf (" [-rv] [-update <seconds>] [-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 ("<Message>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 +<XRoot>/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) + |