From c4bc1693ae8bbc4bff3891b1d06b110025c23579 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-color.ad | 6 + Clock.c | 590 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Clock.h | 75 ++++++++ ClockP.h | 87 +++++++++ oclmask.bit | 14 ++ oclock.bit | 14 ++ oclock.c | 171 +++++++++++++++++ oclock.man | 101 ++++++++++ transform.c | 142 ++++++++++++++ transform.h | 56 ++++++ 10 files changed, 1256 insertions(+) create mode 100644 Clock-color.ad create mode 100644 Clock.c create mode 100644 Clock.h create mode 100644 ClockP.h create mode 100644 oclmask.bit create mode 100644 oclock.bit create mode 100644 oclock.c create mode 100644 oclock.man create mode 100644 transform.c create mode 100644 transform.h diff --git a/Clock-color.ad b/Clock-color.ad new file mode 100644 index 0000000..00e87f4 --- /dev/null +++ b/Clock-color.ad @@ -0,0 +1,6 @@ +! $Xorg: Clock-col.ad,v 1.3 2000/08/17 19:53:59 cpqbld Exp $ +Clock*Background: grey +Clock*BorderColor: light blue +Clock*hour: yellow +Clock*jewel: yellow +Clock*minute: yellow diff --git a/Clock.c b/Clock.c new file mode 100644 index 0000000..5791faa --- /dev/null +++ b/Clock.c @@ -0,0 +1,590 @@ +/* + * $Xorg: Clock.c,v 1.4 2001/02/09 02:05:33 xorgcvs Exp $ + * +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. + */ + +/* + * Clock.c + * + * a NeWS clone clock + */ + +#include +#include +#include +#include "ClockP.h" +#include +#include +#include +#include + +#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 + +#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) 120}, + {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension), + goffset(height), XtRImmediate, (XtPointer) 120}, + {XtNminute, XtCForeground, XtRPixel, sizeof (Pixel), + offset(minute), XtRString, XtDefaultForeground}, + {XtNhour, XtCForeground, XtRPixel, sizeof (Pixel), + offset(hour), XtRString, XtDefaultForeground}, + {XtNjewel, XtCForeground, XtRPixel, sizeof (Pixel), + offset(jewel), XtRString, XtDefaultForeground}, + {XtNbackingStore, XtCBackingStore, XtRBackingStore, sizeof (int), + offset (backing_store), XtRString, "default"}, + {XtNborderSize, XtCBorderSize, XtRFloat, sizeof (float), + offset (border_size), XtRString, "0.1"}, + {XtNjewelSize, XtCBorderSize, XtRFloat, sizeof (float), + offset (jewel_size), XtRString, "0.075"}, + {XtNshapeWindow, XtCShapeWindow, XtRBoolean, sizeof (Boolean), + offset (shape_window), XtRImmediate, (XtPointer) True}, + {XtNtransparent, XtCTransparent, XtRBoolean, sizeof (Boolean), + offset (transparent), XtRImmediate, (XtPointer) False}, +}; + +#undef offset +#undef goffset + +static void new_time(); + +static void Initialize(), Realize(), Destroy(), Redisplay(), Resize(); + +# define BORDER_SIZE(w) ((w)->clock.border_size) +# define WINDOW_WIDTH(w) (2.0 - BORDER_SIZE(w)*2) +# define WINDOW_HEIGHT(w) (2.0 - BORDER_SIZE(w)*2) +# define MINUTE_WIDTH(w) (0.05) +# define HOUR_WIDTH(w) (0.05) +# define JEWEL_SIZE(w) ((w)->clock.jewel_size) +# define MINUTE_LENGTH(w) (JEWEL_Y(w) - JEWEL_SIZE(w) / 2.0) +# define HOUR_LENGTH(w) (MINUTE_LENGTH(w) * 0.6) +# define JEWEL_X(w) (0.0) +# define JEWEL_Y(w) (1.0 - (BORDER_SIZE(w) + JEWEL_SIZE(w))) + +static void ClassInitialize(); + +ClockClassRec clockClassRec = { + { /* core fields */ + /* superclass */ &widgetClassRec, + /* class_name */ "Clock", + /* 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, + /* num_resources */ 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 */ NULL, + /* set_values_hook */ NULL, + /* set_values_almost */ NULL, + /* get_values_hook */ NULL, + /* accept_focus */ NULL, + /* version */ XtVersion, + /* callback_private */ NULL, + /* tm_table */ NULL, + /* query_geometry */ XtInheritQueryGeometry, + } +}; + +static void ClassInitialize() +{ + XtAddConverter( XtRString, XtRBackingStore, XmuCvtStringToBackingStore, + NULL, 0 ); +} + +WidgetClass clockWidgetClass = (WidgetClass) &clockClassRec; + +/* ARGSUSED */ +static void Initialize (greq, gnew, args, num_args) + Widget greq, gnew; + ArgList args; + Cardinal *num_args; +{ + ClockWidget w = (ClockWidget)gnew; + XtGCMask valuemask; + XGCValues myXGCV; + int shape_event_base, shape_error_base; + + valuemask = GCForeground; + + if (w->clock.transparent) + { + ; + } + else + { + myXGCV.foreground = w->clock.minute; + w->clock.minuteGC = XtGetGC(gnew, valuemask, &myXGCV); + + myXGCV.foreground = w->clock.hour; + w->clock.hourGC = XtGetGC(gnew, valuemask, &myXGCV); + + myXGCV.foreground = w->clock.jewel; + w->clock.jewelGC = XtGetGC(gnew, valuemask, &myXGCV); + + myXGCV.foreground = w->core.background_pixel; + w->clock.eraseGC = XtGetGC(gnew, valuemask, &myXGCV); + } + + /* wait for Realize to add the timeout */ + w->clock.interval_id = 0; + + if (w->clock.shape_window && !XShapeQueryExtension (XtDisplay (w), + &shape_event_base, + &shape_error_base)) + w->clock.shape_window = False; + w->clock.shape_mask = 0; + w->clock.shapeGC = 0; + w->clock.shape_width = 0; + w->clock.shape_height = 0; + w->clock.polys_valid = 0; +} + +static void Resize (widget) + Widget widget; +{ + ClockWidget w = (ClockWidget) widget; + XGCValues xgcv; + Widget parent; + XWindowChanges xwc; + int face_width, face_height; + int x, y; + Pixmap shape_mask; + + if (!XtIsRealized((Widget) w)) + return; + + /* + * compute desired border size + */ + + SetTransform (&w->clock.maskt, + 0, w->core.width, + w->core.height, 0, + -1.0, 1.0, + -1.0, 1.0); + + face_width = abs (Xwidth (BORDER_SIZE(w), BORDER_SIZE(w), &w->clock.maskt)); + face_height = abs (Xheight (BORDER_SIZE(w), BORDER_SIZE(w), &w->clock.maskt)); + + /* + * shape the windows and borders + */ + + if (w->clock.shape_window) { + + SetTransform (&w->clock.t, + face_width, w->core.width - face_width, + w->core.height - face_height, face_height, + -WINDOW_WIDTH(w)/2, WINDOW_WIDTH(w)/2, + -WINDOW_HEIGHT(w)/2, WINDOW_HEIGHT(w)/2); + + /* + * allocate a pixmap to draw shapes in + */ + + if (w->clock.shape_mask && + (w->clock.shape_width != w->core.width || + w->clock.shape_height != w->core.height)) + { + XFreePixmap (XtDisplay (w), w->clock.shape_mask); + w->clock.shape_mask = None; + } + + if (!w->clock.shape_mask) + { + w->clock.shape_mask = XCreatePixmap (XtDisplay (w), XtWindow (w), + w->core.width, w->core.height, 1); + } + shape_mask = w->clock.shape_mask; + if (!w->clock.shapeGC) + w->clock.shapeGC = XCreateGC (XtDisplay (w), shape_mask, 0, &xgcv); + + /* erase the pixmap */ + XSetForeground (XtDisplay (w), w->clock.shapeGC, 0); + XFillRectangle (XtDisplay (w), shape_mask, w->clock.shapeGC, + 0, 0, w->core.width, w->core.height); + XSetForeground (XtDisplay (w), w->clock.shapeGC, 1); + + /* + * draw the bounding shape. Doing this first + * eliminates extra exposure events. + */ + + if (w->clock.border_size > 0.0 || !w->clock.transparent) + { + TFillArc (XtDisplay (w), shape_mask, + w->clock.shapeGC, &w->clock.maskt, + -1.0, -1.0, + 2.0, 2.0, + 0, 360 * 64); + } + + if (w->clock.transparent) + { + if (w->clock.border_size > 0.0) + { + XSetForeground (XtDisplay (w), w->clock.shapeGC, 0); + TFillArc (XtDisplay (w), shape_mask, + w->clock.shapeGC, &w->clock.t, + -WINDOW_WIDTH(w)/2, -WINDOW_HEIGHT(w)/2, + WINDOW_WIDTH(w), WINDOW_HEIGHT(w), + 0, 360 * 64); + XSetForeground (XtDisplay (w), w->clock.shapeGC, 1); + } + paint_jewel (w, shape_mask, w->clock.shapeGC); + paint_hands (w, shape_mask, w->clock.shapeGC, w->clock.shapeGC); + } + /* + * Find the highest enclosing widget and shape it + */ + + x = 0; + y = 0; + for (parent = (Widget) w; XtParent (parent); parent = XtParent (parent)) { + x = x + parent->core.x + parent->core.border_width; + y = y + parent->core.y + parent->core.border_width; + } + + XShapeCombineMask (XtDisplay (parent), XtWindow (parent), ShapeBounding, + x, y, shape_mask, ShapeSet); + + /* erase the pixmap */ + XSetForeground (XtDisplay (w), w->clock.shapeGC, 0); + XFillRectangle (XtDisplay (w), shape_mask, w->clock.shapeGC, + 0, 0, w->core.width, w->core.height); + XSetForeground (XtDisplay (w), w->clock.shapeGC, 1); + + /* + * draw the clip shape + */ + + if (w->clock.transparent) + { + paint_jewel (w, shape_mask, w->clock.shapeGC); + paint_hands (w, shape_mask, w->clock.shapeGC, w->clock.shapeGC); + } + else + { + TFillArc (XtDisplay (w), shape_mask, + w->clock.shapeGC, &w->clock.t, + -WINDOW_WIDTH(w)/2, -WINDOW_HEIGHT(w)/2, + WINDOW_WIDTH(w), WINDOW_HEIGHT(w), + 0, 360 * 64); + } + + XShapeCombineMask (XtDisplay (w), XtWindow (w), ShapeClip, + 0, 0, shape_mask, ShapeSet); + + } else + { + /* + * reconfigure the widget to split the availible + * space between the window and the border + */ + + if (face_width > face_height) + xwc.border_width = face_height; + else + xwc.border_width = face_width; + xwc.width = w->core.width - xwc.border_width * 2; + xwc.height = w->core.height - xwc.border_width * 2; + XConfigureWindow (XtDisplay (w), XtWindow (w), + CWWidth|CWHeight|CWBorderWidth, + &xwc); + + SetTransform (&w->clock.t, + 0, xwc.width, + xwc.height, 0, + -WINDOW_WIDTH(w)/2, WINDOW_WIDTH(w)/2, + -WINDOW_HEIGHT(w)/2, WINDOW_HEIGHT(w)/2); + } +} + +static void Realize (gw, valueMask, attrs) + Widget gw; + XtValueMask *valueMask; + XSetWindowAttributes *attrs; +{ + ClockWidget w = (ClockWidget)gw; + + if (w->clock.backing_store != Always + WhenMapped + NotUseful) { + attrs->backing_store = w->clock.backing_store; + *valueMask |= CWBackingStore; + } + if (w->clock.transparent) + { + attrs->background_pixel = w->clock.minute; + *valueMask |= CWBackPixel; + *valueMask &= ~CWBackPixmap; + } + XtCreateWindow( gw, (unsigned)InputOutput, (Visual *)CopyFromParent, + *valueMask, attrs ); + if (!w->clock.transparent) + Resize (w); + new_time ((XtPointer) gw, 0); +} + +static void Destroy (gw) + Widget gw; +{ + ClockWidget w = (ClockWidget)gw; + if (w->clock.interval_id) XtRemoveTimeOut (w->clock.interval_id); + if (! w->clock.transparent) { + XtReleaseGC(gw, w->clock.minuteGC); + XtReleaseGC(gw, w->clock.hourGC); + XtReleaseGC(gw, w->clock.jewelGC); + XtReleaseGC(gw, w->clock.eraseGC); + } + if (w->clock.shapeGC) + XFreeGC(XtDisplay(gw), w->clock.shapeGC); + if (w->clock.shape_mask) + XFreePixmap (XtDisplay (w), w->clock.shape_mask); +} + +/* ARGSUSED */ +static void Redisplay(gw, event, region) + Widget gw; + XEvent *event; + Region region; +{ + ClockWidget w; + + w = (ClockWidget) gw; + if (!w->clock.transparent) + { + paint_jewel (w, XtWindow (w), w->clock.jewelGC); + paint_hands (w, XtWindow (w), w->clock.minuteGC, w->clock.hourGC); + } +} + +/* + * routines to draw the hands and jewel + */ + +#ifndef PI /* may be found in */ +# define PI (3.14159265358979323846) +#endif + +/* + * converts a number from 0..1 representing a clockwise radial distance + * from the 12 oclock position to a radian measure of the counter-clockwise + * distance from the 3 oclock position + */ + +static double +clock_to_angle (clock) +double clock; +{ + if (clock >= .75) + clock -= 1.0; + return -2.0 * PI * clock + PI / 2.0; +} + +/* ARGSUSED */ +static void new_time (client_data, id) + XtPointer client_data; + XtIntervalId *id; /* unused */ +{ + ClockWidget w = (ClockWidget)client_data; + Time_t now; + struct tm *tm; + + if (!w->clock.transparent) + if (w->clock.polys_valid) { + paint_hands (w, XtWindow (w), w->clock.eraseGC, w->clock.eraseGC); + check_jewel (w, XtWindow (w), w->clock.jewelGC); + } + (void) time (&now); + tm = localtime (&now); + if (tm->tm_hour >= 12) + tm->tm_hour -= 12; + w->clock.hour_angle = clock_to_angle ((((double) tm->tm_hour) + + ((double) tm->tm_min) / 60.0) / 12.0); + w->clock.minute_angle = + clock_to_angle (((double) tm->tm_min) / 60.0); + /* + * add the timeout before painting the hands, that may + * take a while and we'd like the clock to keep up + * with time changes. + */ + w->clock.interval_id = + XtAppAddTimeOut (XtWidgetToApplicationContext((Widget) w), + (60 - tm->tm_sec) * 1000, new_time, client_data); + compute_hands (w); + if (w->clock.transparent) + Resize (w); + else + paint_hands (w, XtWindow (w), w->clock.minuteGC, w->clock.hourGC); +} /* new_time */ + +paint_jewel (w, d, gc) +ClockWidget w; +Drawable d; +GC gc; +{ + if (JEWEL_SIZE(w) > 0.0) + { + TFillArc (XtDisplay (w), d, gc, &w->clock.t, + JEWEL_X(w) - JEWEL_SIZE(w) / 2.0, + JEWEL_Y(w) - JEWEL_SIZE(w) / 2.0, + JEWEL_SIZE(w), JEWEL_SIZE(w), 0, 360 * 64); + } +} + +#define sqr(x) ((x)*(x)) + +/* + * check to see if the polygon intersects the circular jewel + */ + +check_jewel_poly (w, poly) +ClockWidget w; +TPoint poly[POLY_SIZE]; +{ + double a2, b2, c2, d2; + double x, y, size; + int i; + + if (JEWEL_SIZE(w) > 0.0) + { + x = JEWEL_X(w); + y = JEWEL_Y(w); + size = JEWEL_SIZE(w); + /* + * check each side of the polygon to see if the + * distance from the line to the center of the + * circular jewel is less than the radius. + */ + for (i = 0; i < POLY_SIZE-1; i++) { + a2 = sqr (poly[i].x - x) + sqr (poly[i].y - y); + b2 = sqr (poly[i+1].x - x) + sqr (poly[i+1].y - y); + c2 = sqr (poly[i].x - poly[i+1].x) + sqr (poly[i].y - poly[i+1].y); + d2 = a2 + b2 - c2; + if (d2 <= sqr (size) && + a2 <= 2 * c2 && b2 <= 2 * c2 || + a2 <= sqr (size) || + b2 <= sqr (size)) + return 1; + } + } + return 0; +} + +check_jewel (w, d, gc) +ClockWidget w; +Drawable d; +GC gc; +{ + if (!w->clock.polys_valid || JEWEL_SIZE(w) <= 0.0) + return; + if ((MINUTE_LENGTH(w) >= (JEWEL_Y(w) - JEWEL_SIZE(w)/2.0) && + check_jewel_poly (w, w->clock.minute_poly)) || + (HOUR_LENGTH(w) >= (JEWEL_Y(w) - JEWEL_SIZE(w)/2.0) && + check_jewel_poly (w, w->clock.minute_poly))) + { + paint_jewel (w, d, gc); + } +} + +/* + * A hand is a rectangle with a triangular cap at the far end. + * This is represented with a five sided polygon. + */ + +compute_hand (w, a, l, width, poly) +ClockWidget w; +double a, l, width; +TPoint poly[POLY_SIZE]; +{ + double c, s; + + c = cos(a); + s = sin(a); + poly[0].x = c * l; + poly[0].y = s * l; + poly[1].x = (l - width) * c - s * width; + poly[1].y = (l - width) * s + c * width; + poly[2].x = (-width) * c - s * width; + poly[2].y = (-width) * s + c * width; + poly[3].x = (-width) * c + s * width; + poly[3].y = (-width) * s - c * width; + poly[4].x = (l - width) * c + s * width; + poly[4].y = (l - width) * s - c * width; + poly[5].x = poly[0].x; + poly[5].y = poly[0].y; +} + +compute_hands (w) +ClockWidget w; +{ + compute_hand (w, w->clock.minute_angle, + MINUTE_LENGTH(w), MINUTE_WIDTH(w), w->clock.minute_poly); + compute_hand (w, w->clock.hour_angle, + HOUR_LENGTH(w), HOUR_WIDTH(w), w->clock.hour_poly); + w->clock.polys_valid = 1; +} + +paint_hand (w, d, gc, poly) +ClockWidget w; +Drawable d; +GC gc; +TPoint poly[POLY_SIZE]; +{ + TFillPolygon (XtDisplay (w), d, gc, &w->clock.t, poly, POLY_SIZE, + Convex, CoordModeOrigin); +} + +paint_hands (w, d, minute_gc, hour_gc) +ClockWidget w; +Drawable d; +GC minute_gc, hour_gc; +{ + if (w->clock.polys_valid) { + paint_hand (w, d, hour_gc, w->clock.hour_poly); + paint_hand (w, d, minute_gc, w->clock.minute_poly); + } +} diff --git a/Clock.h b/Clock.h new file mode 100644 index 0000000..6015931 --- /dev/null +++ b/Clock.h @@ -0,0 +1,75 @@ +/* $Xorg: Clock.h,v 1.4 2001/02/09 02:05:33 xorgcvs Exp $ */ +/* + +Copyright 1993, 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. + +*/ + +#ifndef _XtClock_h +#define _XtClock_h + +/*********************************************************************** + * + * Clock Widget + * + ***********************************************************************/ + +/* Parameters: + + Name Class RepType Default Value + ---- ----- ------- ------------- + background Background pixel White + border BorderColor pixel Black + borderWidth BorderWidth int 1 + minute Foreground Pixel Black + hour Foreground Pixel Black + height Height int 120 + mappedWhenManaged MappedWhenManaged Boolean True + width Width int 120 + x Position int 0 + y Position int 0 + +*/ + +#define XtNminute "minute" +#define XtNhour "hour" +#define XtNjewel "jewel" + +#define XtNshapeWindow "shapeWindow" +#define XtCShapeWindow "ShapeWindow" +#define XtNtransparent "transparent" +#define XtCTransparent "Transparent" + +#define XtNjewelSize "jewelSize" +#define XtNborderSize "borderSize" +#define XtCBorderSize "BorderSize" + +typedef struct _ClockRec *ClockWidget; /* completely defined in ClockPrivate.h */ +typedef struct _ClockClassRec *ClockWidgetClass; /* completely defined in ClockPrivate.h */ + +extern WidgetClass clockWidgetClass; + +#endif /* _XtClock_h */ +/* DON'T ADD STUFF AFTER THIS #endif */ diff --git a/ClockP.h b/ClockP.h new file mode 100644 index 0000000..408dc4d --- /dev/null +++ b/ClockP.h @@ -0,0 +1,87 @@ +/* $Xorg: ClockP.h,v 1.4 2001/02/09 02:05:33 xorgcvs Exp $ */ +/* + +Copyright 1993, 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. + +*/ + + +#ifndef _ClockP_h +#define _ClockP_h + +#include "Clock.h" +#include +#include "transform.h" + +#define POLY_SIZE 6 + +/* New fields for the clock widget instance record */ +typedef struct { + Pixel minute; + Pixel hour; + Pixel jewel; + GC minuteGC; + GC hourGC; + GC jewelGC; + GC eraseGC; + GC shapeGC; /* pointer to GraphicsContext */ +/* start of graph stuff */ + int backing_store; /* backing store variety */ + Boolean shape_window; /* use SetWindowShapeMask */ + Boolean transparent; /* make window transparent */ + float border_size; + float jewel_size; + XtIntervalId interval_id; + Transform t; + Transform maskt; + Pixmap shape_mask; /* window shape */ + int shape_width; /* window width when shape last made */ + int shape_height; /* window height when shape last made */ + double hour_angle; /* hour hand position */ + double minute_angle; /* minute hand position */ + int polys_valid; /* polygons contain good data */ + TPoint minute_poly[POLY_SIZE]; /* polygon for minute hand */ + TPoint hour_poly[POLY_SIZE]; /* polygon for hour hand */ +} ClockPart; + +/* Full instance record declaration */ +typedef struct _ClockRec { + CorePart core; + 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; + ClockClassPart clock_class; +} ClockClassRec; + +/* Class pointer. */ +extern ClockClassRec clockClassRec; + +#endif /* _ClockP_h */ diff --git a/oclmask.bit b/oclmask.bit new file mode 100644 index 0000000..19fb3ca --- /dev/null +++ b/oclmask.bit @@ -0,0 +1,14 @@ +#define oclmask_width 32 +#define oclmask_height 32 +static unsigned char oclmask_bits[] = { + 0x00, 0xf0, 0x07, 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x80, 0xff, 0xff, 0x00, + 0xc0, 0xff, 0xff, 0x01, 0xe0, 0xff, 0xff, 0x03, 0xf0, 0xff, 0xff, 0x07, + 0xf8, 0xff, 0xff, 0x0f, 0xfc, 0xff, 0xff, 0x1f, 0xfc, 0xff, 0xff, 0x1f, + 0xfe, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0x3f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xfe, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0x3f, + 0xfe, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0x1f, 0xfc, 0xff, 0xff, 0x1f, + 0xf8, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x07, 0xe0, 0xff, 0xff, 0x03, + 0xc0, 0xff, 0xff, 0x01, 0x80, 0xff, 0xff, 0x00, 0x00, 0xfe, 0x3f, 0x00, + 0x00, 0xf0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/oclock.bit b/oclock.bit new file mode 100644 index 0000000..c264fe7 --- /dev/null +++ b/oclock.bit @@ -0,0 +1,14 @@ +#define oclock_width 32 +#define oclock_height 32 +static unsigned char oclock_bits[] = { + 0x00, 0xf0, 0x07, 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x80, 0x8f, 0xf8, 0x00, + 0xc0, 0xc1, 0xc1, 0x01, 0xe0, 0x80, 0x80, 0x03, 0x30, 0x00, 0x00, 0x06, + 0x18, 0x00, 0x00, 0x0c, 0x1c, 0x00, 0x00, 0x1c, 0x0c, 0x00, 0x70, 0x18, + 0x06, 0x00, 0x78, 0x30, 0x06, 0x00, 0x3c, 0x30, 0x06, 0x00, 0x1e, 0x30, + 0x03, 0x00, 0x0f, 0x60, 0x03, 0x80, 0x07, 0x60, 0x03, 0xc0, 0x03, 0x60, + 0x03, 0xc0, 0x01, 0x60, 0x03, 0xc0, 0x01, 0x60, 0x03, 0xc0, 0x01, 0x60, + 0x03, 0xc0, 0x01, 0x60, 0x06, 0xc0, 0x01, 0x30, 0x06, 0xc0, 0x01, 0x30, + 0x06, 0xc0, 0x01, 0x30, 0x0c, 0xc0, 0x01, 0x18, 0x1c, 0xc0, 0x01, 0x1c, + 0x18, 0xc0, 0x01, 0x0c, 0x30, 0xc0, 0x01, 0x06, 0xe0, 0xc0, 0x81, 0x03, + 0xc0, 0x81, 0xc0, 0x01, 0x80, 0x0f, 0xf8, 0x00, 0x00, 0xfe, 0x3f, 0x00, + 0x00, 0xf0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/oclock.c b/oclock.c new file mode 100644 index 0000000..32bc912 --- /dev/null +++ b/oclock.c @@ -0,0 +1,171 @@ +/* + * $Xorg: oclock.c,v 1.4 2001/02/09 02:05:33 xorgcvs Exp $ + * +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 +#include "Clock.h" +#include + +#ifdef XKB +#include +#endif + +#include "oclock.bit" +#include "oclmask.bit" + +extern void exit(); +static void quit(); + +static XtActionsRec actions[] = { + {"quit", quit} +}; + +static Atom wm_delete_window; + +static void die(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + XCloseDisplay(XtDisplay(w)); + exit(0); +} + +static void save(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + return; /* stateless */ +} + +/* Exit with message describing command line format */ + +void usage() +{ + fprintf(stderr, +"usage: oclock\n"); + fprintf (stderr, +" [-geometry [{width}][x{height}][{+-}{xoff}[{+-}{yoff}]]] [-display [{host}]:[{vs}]]\n"); + fprintf(stderr, +" [-fg {color}] [-bg {color}] [-bd {color}] [-bw {pixels}]\n"); + fprintf(stderr, +" [-minute {color}] [-hour {color}] [-jewel {color}]\n"); + fprintf(stderr, +" [-backing {backing-store}] [-shape] [-noshape] [-transparent]\n"); + exit(1); +} + +/* 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[] = { +{"-fg", "*Foreground", XrmoptionSepArg, NULL}, +{"-bg", "*Background", XrmoptionSepArg, NULL}, +{"-foreground", "*Foreground", XrmoptionSepArg, NULL}, +{"-background", "*Background", XrmoptionSepArg, NULL}, +{"-minute", "*clock.minute", XrmoptionSepArg, NULL}, +{"-hour", "*clock.hour", XrmoptionSepArg, NULL}, +{"-jewel", "*clock.jewel", XrmoptionSepArg, NULL}, +{"-backing", "*clock.backingStore", XrmoptionSepArg, NULL}, +{"-shape", "*clock.shapeWindow", XrmoptionNoArg, "TRUE"}, +{"-noshape", "*clock.shapeWindow", XrmoptionNoArg, "FALSE"}, +{"-transparent","*clock.transparent", XrmoptionNoArg, "TRUE"}, +}; + +void main(argc, argv) + int argc; + char **argv; +{ + XtAppContext xtcontext; + Widget toplevel; + Widget clock; + Arg arg[2]; + int i; + + toplevel = XtOpenApplication(&xtcontext, "Clock", + options, XtNumber(options), &argc, argv, NULL, + sessionShellWidgetClass, NULL, 0); + if (argc != 1) usage(); + XtAddCallback(toplevel, XtNsaveCallback, save, NULL); + XtAddCallback(toplevel, XtNdieCallback, die, NULL); + + XtAppAddActions + (xtcontext, actions, XtNumber(actions)); + XtOverrideTranslations + (toplevel, XtParseTranslationTable ("WM_PROTOCOLS: quit()")); + + i = 0; + XtSetArg (arg[i], XtNiconPixmap, + XCreateBitmapFromData (XtDisplay(toplevel), + XtScreen(toplevel)->root, + (char *)oclock_bits, + oclock_width, oclock_height)); + i++; + XtSetArg (arg[i], XtNiconMask, + XCreateBitmapFromData (XtDisplay(toplevel), + XtScreen(toplevel)->root, + (char *)oclmask_bits, + oclmask_width, oclmask_height)); + i++; + XtSetValues (toplevel, arg, i); + + clock=XtCreateManagedWidget("clock", clockWidgetClass, toplevel, NULL, 0); + XtRealizeWidget (toplevel); + + wm_delete_window = XInternAtom(XtDisplay(toplevel), "WM_DELETE_WINDOW", + False); + (void) XSetWMProtocols (XtDisplay(toplevel), XtWindow(toplevel), + &wm_delete_window, 1); + + XtAddEventHandler(toplevel, (EventMask) 0, TRUE, + _XEditResCheckMessages, NULL); + + XtAppMainLoop(xtcontext); +} + +static void quit(w, event, params, num_params) + Widget w; + 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_BadValue); +#else + XBell(XtDisplay(w), 0); +#endif + } else { + XtSetArg(arg, XtNjoinSession, False); + XtSetValues(w, &arg, (Cardinal)1); + die(w, NULL, NULL); + } +} diff --git a/oclock.man b/oclock.man new file mode 100644 index 0000000..41128e1 --- /dev/null +++ b/oclock.man @@ -0,0 +1,101 @@ +.\" $Xorg: oclock.man,v 1.4 2001/02/09 02:05:33 xorgcvs Exp $ +.\" 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. +.TH OCLOCK 1 "Release 6.4" "X Version 11" +.SH NAME +oclock \- round X clock +.SH SYNOPSIS +.B oclock +[\-option ... ] +.SH DESCRIPTION +.I Oclock +simply displays the current time on an analog display. +.SH OPTIONS +.TP 8 +.B \-fg \fIcolor\fB +choose a different color for the both hands and the jewel of the clock +.TP 8 +.B \-bg \fIcolor\fB +choose a different color for the background. +.TP 8 +.B \-jewel \fIcolor\fB +choose a different color for the jewel on the clock. +.TP 8 +.B \-minute \fIcolor\fB +choose a different color for the minute hand of the clock. +.TP 8 +.B \-hour \fIcolor\fB +choose a different color for the hour hand of the clock. +.TP 8 +.B \-backing \fI{ WhenMapped Always NotUseful }\fB +selects an appropriate level of backing store. +.TP 8 +.B \-geometry \fIgeometry\fB +define the initial window geometry; see \fIX(1)\fP. +.TP 8 +.B \-display \fIdisplay\fB +specify the display to use; see \fIX(1)\fP. +.TP 8 +.B \-bd \fIcolor\fB +choose a different color for the window border. +.TP 8 +.B \-bw \fIwidth\fB +choose a different width for the window border. As the Clock widget changes +its border around quite a bit, this is most usefully set to zero. +.TP 8 +.B \-shape +causes the clock to use the Shape extension to create an oval window. +This is the default unless the shapeWindow resource is set to false. +.TP 8 +.B \-noshape +causes the clock to not reshape itself and ancestors to exactly +fit the outline of the clock. +.TP 8 +.B \-transparent +causes the clock to consist only of the jewel, the hands, and the border. +.SH COLORS +If you would like your clock to be viewable in color, include the following +in the #ifdef COLOR section you read with xrdb: +.sp 1 +*customization: -color +.sp 1 +.br +This will cause oclock to pick up the colors in the app-defaults color +customization file: +/lib/X11/app-defaults/Clock-color. +Below are the default colors: +.sp 1 +Clock*Background: grey +.br +Clock*BorderColor: light blue +.br +Clock*hour: yellow +.br +Clock*jewel: yellow +.br +Clock*minute: yellow +.SH "SEE ALSO" +X(1), X Toolkit documentation +.SH AUTHOR +Keith Packard, MIT X Consortium diff --git a/transform.c b/transform.c new file mode 100644 index 0000000..60a717a --- /dev/null +++ b/transform.c @@ -0,0 +1,142 @@ +/* $Xorg: transform.c,v 1.4 2001/02/09 02:05:33 xorgcvs Exp $ */ +/* + +Copyright 1993, 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. + +*/ + + +/* + * transformed coordinate system objects for X + */ + +# include +# include "transform.h" + +static XPoint * +TranslatePoints (points, n_points, t, mode) +TPoint *points; +int n_points; +Transform *t; +int mode; +{ + XPoint *xpoints; + int i; + double xoff = 0.0, yoff = 0.0; + + xpoints = (XPoint *) malloc ((unsigned)n_points * sizeof (*xpoints)); + if (!xpoints) + return 0; + for (i = 0; i < n_points; i++) { + xpoints[i].x = Xx(points[i].x + xoff, points[i].y + yoff, t); + xpoints[i].y = Xy(points[i].x + xoff, points[i].y + yoff, t); + if (mode == CoordModePrevious) { + xoff += points[i].x; + yoff += points[i].y; + } + } + return xpoints; +} + +TFillPolygon (dpy, d, gc, t, points, n_points, shape, mode) +register Display *dpy; +Drawable d; +GC gc; +Transform *t; +TPoint *points; +int n_points; +int shape; +int mode; +{ + XPoint *xpoints; + + xpoints = TranslatePoints (points, n_points, t, mode); + if (xpoints) { + XFillPolygon (dpy, d, gc, xpoints, n_points, shape, + CoordModeOrigin); + free (xpoints); + } +} + +TDrawArc (dpy, d, gc, t, x, y, width, height, angle1, angle2) + register Display *dpy; + Drawable d; + GC gc; + Transform *t; + double x, y, width, height; + int angle1, angle2; +{ + int xx, xy, xw, xh; + + xx = Xx(x,y,t); + xy = Xy(x,y,t); + xw = Xwidth (width, height, t); + xh = Xheight (width, height, t); + if (xw < 0) { + xx += xw; + xw = -xw; + } + if (xh < 0) { + xy += xh; + xh = -xh; + } + XDrawArc (dpy, d, gc, xx, xy, xw, xh, angle1, angle2); +} + +TFillArc (dpy, d, gc, t, x, y, width, height, angle1, angle2) + register Display *dpy; + Drawable d; + GC gc; + Transform *t; + double x, y, width, height; + int angle1, angle2; +{ + int xx, xy, xw, xh; + + xx = Xx(x,y,t); + xy = Xy(x,y,t); + xw = Xwidth (width, height, t); + xh = Xheight (width, height, t); + if (xw < 0) { + xx += xw; + xw = -xw; + } + if (xh < 0) { + xy += xh; + xh = -xh; + } + XFillArc (dpy, d, gc, xx, xy, xw, xh, angle1, angle2); +} + +SetTransform (t, xx1, xx2, xy1, xy2, tx1, tx2, ty1, ty2) +Transform *t; +int xx1, xx2, xy1, xy2; +double tx1, tx2, ty1, ty2; +{ + t->mx = ((double) xx2 - xx1) / (tx2 - tx1); + t->bx = ((double) xx1) - t->mx * tx1; + t->my = ((double) xy2 - xy1) / (ty2 - ty1); + t->by = ((double) xy1) - t->my * ty1; +} diff --git a/transform.h b/transform.h new file mode 100644 index 0000000..6377979 --- /dev/null +++ b/transform.h @@ -0,0 +1,56 @@ +/* $Xorg: transform.h,v 1.4 2001/02/09 02:05:33 xorgcvs Exp $ */ +/* + +Copyright 1993, 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. + +*/ + + +/* + * header file for transformed coordinate system. No rotations + * supported, as elipses cannot be rotated in X. + */ + +typedef struct _transform { + double mx, bx; + double my, by; +} Transform; + +typedef struct _TPoint { + double x, y; +} TPoint; + +typedef struct _TRectangle { + double x, y, width, height; +} TRectangle; + +# define Xx(x,y,t) ((int)((t)->mx * (x) + (t)->bx + 0.5)) +# define Xy(x,y,t) ((int)((t)->my * (y) + (t)->by + 0.5)) +# define Xwidth(w,h,t) ((int)((t)->mx * (w) + 0.5)) +# define Xheight(w,h,t) ((int)((t)->my * (h) + 0.5)) +# define Tx(x,y,t) ((((double) (x)) - (t)->bx) / (t)->mx) +# define Ty(x,y,t) ((((double) (y)) - (t)->by) / (t)->my) +# define Twidth(w,h,t) (((double) (w)) / (t)->mx) +# define Theight(w,h,t) (((double) (h)) / (t)->my) -- cgit v1.2.3