home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
x
/
volume10
/
xchrom
/
part01
/
Xchrom.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-12-07
|
12KB
|
391 lines
/*
* Xchrom.c -- a CHROMACHRON clock widget. implementation module.
* Copyright (c) Olaf Heimburger 1990
* Last edited: Tue Nov 6 11:16:24 1990 by olafh (Olaf Heimburger) on GECKO
*/
#include <stdio.h>
#include <math.h>
#include <X11/IntrinsicP.h>
#include <X11/Xos.h>
#include <X11/StringDefs.h>
#include "XchromP.h"
static void Initialize (), Resize (), Realize (), Destroy (),
Redisplay (), Timeout (), GetGC (), GetColorGC (), ShowTime ();
static Boolean SetValues ();
static Dimension winWidth = MINWIDTH;
static Dimension winHeight = MINHEIGHT;
static int sOffset = STARTCORNER;
static int mOffset = MASKOFFSET;
static int tOffset = 0; /* believe system clock */
static int sliceAngles[NUMFIELDS] = {
75, /* twelve */
45, /* one */
15, /* two */
345, /* three */
315, /* four */
285, /* five */
255, /* six */
225, /* seven */
195, /* eight */
165, /* nine */
135, /* ten */
105, /* eleven */
};
static XtResource resources[] = {
{ XtNwidth, XtCWidth, XtRDimension, sizeof (Dimension),
XtOffset (Widget, core.width), XtRDimension, (caddr_t)&winWidth },
{ XtNheight, XtCHeight, XtRDimension, sizeof (Dimension),
XtOffset (Widget, core.height), XtRDimension, (caddr_t)&winHeight },
{ XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel),
XtOffset (XchromWidget, xchrom.foreground), XtRString,
XtDefaultForeground},
{ XtNstartOffset, XtCStartOffset, XtRInt, sizeof (int),
XtOffset (XchromWidget, xchrom.startOffset), XtRInt,
(caddr_t)&sOffset},
{ XtNmaskOffset, XtCMaskOffset, XtRInt, sizeof (int),
XtOffset (XchromWidget, xchrom.maskOffset), XtRInt, (caddr_t)&mOffset},
{ XtNtimeOffset, XtCTimeOffset, XtRInt, sizeof (int),
XtOffset (XchromWidget, xchrom.timeOffset), XtRInt, (caddr_t)&tOffset},
{ XtNtwelveOClock, XtCTwelveOClock, XtRPixel, sizeof (Pixel),
XtOffset (XchromWidget, xchrom.color[0]), XtRString, "Yellow"},
{ XtNoneOClock, XtCOneOClock, XtRPixel, sizeof (Pixel),
XtOffset (XchromWidget, xchrom.color[1]), XtRString, "Orange"},
{ XtNtwoOClock, XtCTwoOClock, XtRPixel, sizeof (Pixel),
XtOffset (XchromWidget, xchrom.color[2]), XtRString, "Pink"},
{ XtNthreeOClock, XtCThreeOClock, XtRPixel, sizeof (Pixel),
XtOffset (XchromWidget, xchrom.color[3]), XtRString, "Red"},
{ XtNfourOClock, XtCFourOClock, XtRPixel, sizeof (Pixel),
XtOffset (XchromWidget, xchrom.color[4]), XtRString, "LightPink"},
{ XtNfiveOClock, XtCFiveOClock, XtRPixel, sizeof (Pixel),
XtOffset (XchromWidget, xchrom.color[5]), XtRString, "Violet"},
{ XtNsixOClock, XtCSixOClock, XtRPixel, sizeof (Pixel),
XtOffset (XchromWidget, xchrom.color[6]), XtRString, "RoyalBlue"},
{ XtNsevenOClock, XtCSevenOClock, XtRPixel, sizeof (Pixel),
XtOffset (XchromWidget, xchrom.color[7]), XtRString, "DarkGreen"},
{ XtNeightOClock, XtCEightOClock, XtRPixel, sizeof (Pixel),
XtOffset (XchromWidget, xchrom.color[8]), XtRString, "Turquoise"},
{ XtNnineOClock, XtCNineOClock, XtRPixel, sizeof (Pixel),
XtOffset (XchromWidget, xchrom.color[9]), XtRString, "Brown"},
{ XtNtenOClock, XtCTenOClock, XtRPixel, sizeof (Pixel),
XtOffset (XchromWidget, xchrom.color[10]), XtRString, "LightYellow"},
{ XtNelevenOClock, XtCElevenOClock, XtRPixel, sizeof (Pixel),
XtOffset (XchromWidget, xchrom.color[11]), XtRString, "Wheat"},
};
XchromClassRec xchromClassRec = {
{ /* core fields */
/* superclass */ &widgetClassRec,
/* class_name */ "Xchrom",
/* widget_size */ sizeof (XchromRec),
/* class_initialize */ NULL,
/* 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 */ NULL,
/* compress_motion */ TRUE,
/* compress_exposure */ TRUE,
/* compress_enterleave */ TRUE,
/* visible_interest */ FALSE,
/* destroy */ Destroy,
/* resize */ Resize,
/* expose */ Redisplay,
/* set_values */ SetValues,
/* set_values_hook */ NULL,
/* set_values_almost */ XtInheritSetValuesAlmost,
/* get_values_hook */ NULL,
/* accept_focus */ NULL,
/* version */ XtVersion,
/* callback_private */ NULL,
/* tm_table */ NULL,
/* query_geometry */ NULL,
}
};
WidgetClass xchromWidgetClass = (WidgetClass) &xchromClassRec;
/* ARGSUSED */
static void Initialize (request, new)
XchromWidget request;
XchromWidget new;
{
if (new) {
int i;
new->xchrom.intervalId = None;
new->xchrom.wdwPixmap = new->xchrom.colorPixmap = None;
/*
* initialize the color table
*/
for (i = 0; i < NUMFIELDS; ++i) {
GetColorGC (new, i);
}
/*
* Initialize the angles for the slices.
*/
for (i = 0; i < NUMFIELDS; ++i) {
new->xchrom.slices[i].angle1 = (short)(sliceAngles[i] * XARCMAGIC);
new->xchrom.slices[i].angle2 = (short)(SLICEANGLE * XARCMAGIC);
}
new->xchrom.slices[SLICEMASK].angle1 = STARTDEGREES * XARCMAGIC;
new->xchrom.slices[SLICEMASK].angle2 = MASKDEGREES * XARCMAGIC;
new->xchrom.slices[SLICEMASK].x =
new->xchrom.slices[SLICEMASK].y =
new->xchrom.startOffset + new->xchrom.maskOffset;
new->xchrom.minOffset = new->xchrom.timeOffset % 60;
new->xchrom.hourOffset = new->xchrom.timeOffset / 60;
}
GetGC (new);
}
static void GetColorGC (w, i)
XchromWidget w;
int i;
{
if (w && i >= 0 && i < NUMFIELDS) {
XGCValues gcv;
XtGCMask mask = GCForeground | GCBackground | GCFunction;
gcv.background = WhitePixel (XtDisplay (w),
DefaultScreen (XtDisplay (w)));
gcv.function = GXcopy;
gcv.foreground = w->xchrom.color[i];
w->xchrom.colors[i] = XtGetGC ((Widget)w, mask, &gcv);
}
}
static void GetGC (w)
XchromWidget w;
{
if (w) {
XGCValues gcv;
XtGCMask mask = GCForeground | GCBackground | GCFunction;
gcv.background = w->core.background_pixel;
gcv.foreground = w->xchrom.foreground;
gcv.function = GXcopy;
w->xchrom.colors[BACKCOLOR] = XtGetGC ((Widget)w, mask, &gcv);
}
}
static void CreatePixmaps (w)
XchromWidget w;
{
if (w) {
/*
* Create the pixmap's and clear 'em.
*/
Display *dpy = XtDisplay (w);
Window win = XtWindow (w);
GC tmpGC;
XGCValues gcv;
XtGCMask mask = GCForeground | GCBackground | GCFunction;
if (w->xchrom.colorPixmap != None) {
XFreePixmap (dpy, w->xchrom.colorPixmap);
}
if (w->xchrom.wdwPixmap != None) {
XFreePixmap (dpy, w->xchrom.wdwPixmap);
}
gcv.foreground = WhitePixel (dpy, DefaultScreen (dpy));
gcv.background = BlackPixel (dpy, DefaultScreen (dpy));
gcv.function = GXcopy;
tmpGC = XtGetGC (w, mask, &gcv);
w->xchrom.colorPixmap =
XCreatePixmap (dpy, win, w->xchrom.arcSize, w->xchrom.arcSize,
DefaultDepth (dpy, DefaultScreen (dpy)));
XFillRectangle (dpy, w->xchrom.colorPixmap, tmpGC, 0, 0,
w->xchrom.arcSize, w->xchrom.arcSize);
w->xchrom.wdwPixmap =
XCreatePixmap (dpy, win, w->core.width, w->core.height,
DefaultDepth (dpy, DefaultScreen (dpy)));
XFillRectangle (dpy, w->xchrom.wdwPixmap, tmpGC, 0, 0, w->core.width,
w->core.height);
XtReleaseGC (w, tmpGC);
}
}
static void Realize (w, valueMask, attrs)
Widget w;
XtValueMask *valueMask;
XSetWindowAttributes *attrs;
{
*valueMask |= CWBitGravity;
attrs->bit_gravity = ForgetGravity;
XtCreateWindow(w, InputOutput, (Visual*)CopyFromParent, *valueMask,
attrs);
Resize(w);
}
static void Destroy (w)
XchromWidget w;
{
int n;
if (w->xchrom.intervalId) {
XtRemoveTimeOut (w->xchrom.intervalId);
}
for (n = 0; n < NUMFIELDS + 1; ++n) {
XtReleaseGC (w, w->xchrom.colors[n]);
}
if (w->xchrom.colorPixmap) {
XFreePixmap (XtDisplay (w), w->xchrom.colorPixmap);
}
if (w->xchrom.wdwPixmap) {
XFreePixmap (XtDisplay (w), w->xchrom.wdwPixmap);
}
}
/* ARGSUSED */
static void Resize (w)
XchromWidget w;
{
if (XtIsRealized (w)) {
Display *dpy = XtDisplay (w);
int width = w->core.width;
int height = w->core.height;
/*
* Get the minimum size of the square
*/
w->xchrom.squareSize =
((width > height) ? height : width) - (w->xchrom.startOffset * 2);
if (w->xchrom.squareSize > 0) {
XRectangle rect;
int i = 0;
int halfSize = w->xchrom.squareSize / 2;
w->xchrom.arcSize =
((int)sqrt ((float)((halfSize * halfSize)
+ (halfSize * halfSize))) * 2) + 3;
w->xchrom.offset =
(int)((w->xchrom.arcSize - w->xchrom.squareSize) / 2);
CreatePixmaps (w);
/*
* Fill the color pixmap
*/
for (i = 0; i < NUMFIELDS; ++i) {
w->xchrom.slices[i].x = w->xchrom.slices[i].y = 0;
w->xchrom.slices[i].width = w->xchrom.slices[i].height =
w->xchrom.arcSize;
XFillArcs (dpy, w->xchrom.colorPixmap, w->xchrom.colors[i],
&w->xchrom.slices[i], 1);
}
/*
* Fill the background
*/
rect.x = 0;
rect.y = 0;
rect.width = width;
rect.height = height;
XFillRectangles (dpy, w->xchrom.wdwPixmap,
w->xchrom.colors[BACKCOLOR], &rect, 1);
/*
* Set the slice mask size.
*/
w->xchrom.slices[SLICEMASK].width =
w->xchrom.slices[SLICEMASK].height =
w->xchrom.squareSize - (w->xchrom.maskOffset * 2);
}
}
}
/* ARGSUSED */
static void Redisplay (w)
XchromWidget w;
{
if (XtIsRealized (w)) {
long t = time (0);
if (w->xchrom.intervalId != None) {
XtRemoveTimeOut (w->xchrom.intervalId);
w->xchrom.intervalId = NULL;
}
ShowTime (w);
w->xchrom.intervalId =
XtAddTimeOut ((unsigned long)(60 - (t % 60)) * 1000, Timeout, w);
}
}
static void ShowTime (w)
XchromWidget w;
{
long t = time (0);
register struct tm *lTime = localtime (&t);
/*
* Clear the previous slice mask.
*/
XCopyArea (XtDisplay (w), w->xchrom.colorPixmap, w->xchrom.wdwPixmap,
w->xchrom.colors[BACKCOLOR], w->xchrom.offset, w->xchrom.offset,
w->xchrom.squareSize, w->xchrom.squareSize,
w->xchrom.startOffset, w->xchrom.startOffset);
/*
* Calculate current position of slice mask
*/
if (lTime) {
int min = lTime->tm_min + w->xchrom.minOffset;
int hour = (lTime->tm_hour + w->xchrom.hourOffset) % NUMFIELDS;
if (w->xchrom.savedHour != hour || w->xchrom.savedMin != min) {
w->xchrom.slices[SLICEMASK].angle1 =
(sliceAngles[hour] + SLICEANGLE) * XARCMAGIC;
/*
* Display every minute. (0.5 degrees per minute)
*/
w->xchrom.slices[SLICEMASK].angle1 -= (min) * (int)(XARCMAGIC / 2);
w->xchrom.savedHour = hour;
w->xchrom.savedMin = min;
}
}
/*
* Draw slice mask.
*/
XFillArcs (XtDisplay (w), w->xchrom.wdwPixmap, w->xchrom.colors[BACKCOLOR],
&w->xchrom.slices[SLICEMASK], 1);
/*
* Finally, show the result.
*/
XCopyArea (XtDisplay (w), w->xchrom.wdwPixmap, XtWindow (w),
w->xchrom.colors[BACKCOLOR], 0, 0, w->core.width,
w->core.height, 0, 0);
XFlush (XtDisplay (w));
}
static void Timeout (w, id)
XchromWidget w;
XtIntervalId *id;
{
ShowTime (w);
w->xchrom.intervalId = XtAddTimeOut (60000, Timeout, w);
}
/* ARGSUSED */
static Boolean SetValues (current, request, new)
XchromWidget current, request, new;
{
Boolean redraw = False;
int i;
if (new->xchrom.foreground != current->xchrom.foreground
|| new->core.background_pixel != current->core.background_pixel) {
XtReleaseGC (current, current->xchrom.colors[BACKCOLOR]);
GetGC (new);
redraw = True;
}
for (i = 0; i < NUMFIELDS; ++i) {
if (new->xchrom.color[i] != current->xchrom.color[i]) {
printf ("color %d changed\n", i);
XtReleaseGC (current, current->xchrom.colors[i]);
GetColorGC (new, i);
redraw = True;
}
}
if (redraw) {
Resize (new); /* pixmaps need to be redrawn */
}
return redraw;
}