summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Clock-color.ad6
-rw-r--r--Clock.c590
-rw-r--r--Clock.h75
-rw-r--r--ClockP.h87
-rw-r--r--oclmask.bit14
-rw-r--r--oclock.bit14
-rw-r--r--oclock.c171
-rw-r--r--oclock.man101
-rw-r--r--transform.c142
-rw-r--r--transform.h56
10 files changed, 1256 insertions, 0 deletions
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 <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xmu/Converters.h>
+#include "ClockP.h"
+#include <X11/Xos.h>
+#include <stdio.h>
+#include <math.h>
+#include <X11/extensions/shape.h>
+
+#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
+
+#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 <math.h> */
+# 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 <X11/CoreP.h>
+#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 <X11/Intrinsic.h>
+#include <X11/Xatom.h>
+#include <X11/StringDefs.h>
+#include <X11/Shell.h>
+#include <X11/Xmu/Editres.h>
+#include "Clock.h"
+#include <stdio.h>
+
+#ifdef XKB
+#include <X11/extensions/XKBbells.h>
+#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 ("<Message>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:
+<XRoot>/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 <X11/Xlib.h>
+# 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)