12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /**---------------------------------------------------------------------
- ***
- *** file: Clock.c
- ***
- *** project: MotifPlus Widgets
- ***
- *** description: Source code for DtClock class.
- *** Portions adapted from the Xaw Clock widget.
- ***
- ***
- *** (c) Copyright 1990 by Hewlett-Packard Company.
- ***
- ***
- Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
- and the Massachusetts Institute of Technology, Cambridge, 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 names of Digital or MIT 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 Files
- */
- #include <stdio.h>
- #include <sys/stat.h>
- #include <time.h>
- #include <Xm/GadgetP.h>
- #include <Xm/ManagerP.h>
- #include "ClockP.h"
- #include <Dt/Control.h>
- /*-------------------------------------------------------------
- ** Public Interface
- **-------------------------------------------------------------
- */
- WidgetClass dtClockGadgetClass;
- /*-------------------------------------------------------------
- */
- #define SIZE_DEFAULT 32
- #define DELAY_DEFAULT 250
- #define VERTICES_IN_HANDS 6 /* to draw triangle */
- #define PI 3.14159265358979
- #define TWOPI (2. * PI)
- #define SMALL_TICK_FRACT 100
- #define SMALL_MINUTE_HAND_FRACT 95
- #define SMALL_HOUR_HAND_FRACT 68
- #define SMALL_HAND_WIDTH_FRACT 12
- #define TICK_FRACT 90
- #define MINUTE_HAND_FRACT 70
- #define HOUR_HAND_FRACT 40
- #define HAND_WIDTH_FRACT 7
- #define max(a,b) ((a) > (b) ? (a) : (b))
- #define min(a,b) ((a) < (b) ? (a) : (b))
- #define abs(a) ((a) < 0 ? - (a) : (a))
- #define G_Width(r) (r -> rectangle.width)
- #define G_Height(r) (r -> rectangle.height)
- #define M_BackgroundGC(m) (m -> manager.background_GC)
- #define G_X(r) (r -> rectangle.x)
- #define G_Y(r) (r -> rectangle.y)
- /* Is this still needed, or does <time.h> always declare time()? */
- extern time_t time ( time_t * );
- /******** Public Function Declarations ********/
- extern Widget DtCreateClock(
- Widget parent,
- String name,
- ArgList arglist,
- Cardinal argcount) ;
- /******** End Public Function Declarations ********/
- /******** Static Function Declarations ********/
- static void ClockTick(
- XtPointer client_data,
- XtIntervalId *id) ;
- static void DrawLine(
- DtClockGadget w,
- Dimension blank_length,
- Dimension length,
- double fraction_of_a_circle) ;
- static void DrawHand(
- DtClockGadget w,
- Dimension length,
- Dimension width,
- double fraction_of_a_circle) ;
- static void SetSegment(
- DtClockGadget w,
- int x1,
- int y1,
- int x2,
- int y2) ;
- static int round(
- double x) ;
- static void DrawClockFace(
- DtClockGadget g) ;
- static void Initialize(
- Widget request_w,
- Widget new_w) ;
- static void Destroy(
- Widget w) ;
- static void Resize(
- Widget widget) ;
- static void Draw(
- DtClockGadget g,
- Drawable drawable,
- Position x,
- Position y,
- Dimension w,
- Dimension h,
- Dimension h_t,
- Dimension s_t,
- unsigned char s_type,
- unsigned char fill_mode) ;
- static void UpdateGCs(
- DtClockGadget g) ;
- static void EraseHands ( DtClockGadget w, struct tm * tm );
- /******** End Static Function Declarations ********/
- /*-------------------------------------------------------------
- ** Resource List
- */
- #define R_Offset(field) \
- XtOffset (DtClockGadget, clock.field)
- static XtResource resources[] =
- {
- {
- XmNclockInterval,
- XmCInterval, XmRInt, sizeof (int),
- R_Offset (clock_interval), XmRImmediate, (XtPointer) 60
- },
- {
- XmNchime,
- XmCBoolean, XmRBoolean, sizeof (Boolean),
- R_Offset (chime), XmRImmediate, (XtPointer) FALSE
- },
- {
- XmNleftInset,
- XmCSpacing, XmRHorizontalDimension, sizeof (Dimension),
- R_Offset (left_inset), XmRImmediate, (caddr_t) 2
- },
- {
- XmNrightInset,
- XmCSpacing, XmRHorizontalDimension, sizeof (Dimension),
- R_Offset (right_inset), XmRImmediate, (caddr_t) 2
- },
- {
- XmNtopInset,
- XmCSpacing, XmRVerticalDimension, sizeof (Dimension),
- R_Offset (top_inset), XmRImmediate, (caddr_t) 2
- },
- {
- XmNbottomInset,
- XmCSpacing, XmRVerticalDimension, sizeof (Dimension),
- R_Offset (bottom_inset), XmRImmediate, (caddr_t) 2
- }
- };
- #undef R_Offset
- /*-------------------------------------------------------------
- ** Class Record
- */
- DtClockClassRec dtClockClassRec =
- {
- /* Core Part
- */
- {
- (WidgetClass) &dtControlClassRec, /* superclass */
- "Clock", /* class_name */
- sizeof (DtClockRec), /* widget_size */
- NULL, /* class_initialize */
- NULL, /* class_part_initialize*/
- False, /* class_inited */
- (XtInitProc) Initialize, /* initialize */
- NULL, /* initialize_hook */
- NULL, /* realize */
- NULL, /* actions */
- 0, /* num_actions */
- resources, /* resources */
- XtNumber (resources), /* num_resources */
- NULLQUARK, /* xrm_class */
- True, /* compress_motion */
- True, /* compress_exposure */
- True, /* compress_enterleave */
- False, /* visible_interest */
- Destroy, /* destroy */
- Resize, /* resize */
- XtInheritExpose, /* expose */
- NULL, /* set_values */
- NULL, /* set_values_hook */
- XtInheritSetValuesAlmost, /* set_values_almost */
- NULL, /* get_values_hook */
- NULL, /* accept_focus */
- XtVersion, /* version */
- NULL, /* callback private */
- NULL, /* tm_table */
- NULL, /* query_geometry */
- NULL, /* display_accelerator */
- NULL, /* extension */
- },
- /* XmGadget Part
- */
- {
- XmInheritBorderHighlight, /* border_highlight */
- XmInheritBorderUnhighlight, /* border_unhighlight */
- (XtActionProc) XmInheritArmAndActivate, /* arm_and_activate */
- (XmWidgetDispatchProc) XmInheritInputDispatch, /* input_dispatch */
- XmInheritVisualChange, /* visual_change */
- NULL, /* get_resources */
- 0, /* num_get_resources */
- XmInheritCachePart, /* class_cache_part */
- NULL, /* extension */
- },
- /* DtIcon Part
- */
- {
- DtInheritGetSize, /* get_size */
- DtInheritGetPositions, /* get_positions */
- (DrawProc) Draw, /* draw */
- DtInheritCallCallback, /* call_callback */
- (UpdateGCsProc) UpdateGCs, /* update_gcs */
- False, /* optimize_redraw */
- NULL, /* class_cache_part */
- NULL, /* extension */
- },
- /* DtClock Part
- */
- {
- NULL, /* class_cache_part */
- NULL, /* extension */
- },
- /* DtControl Part
- */
- {
- NULL, /* class_cache_part */
- NULL, /* extension */
- }
- };
- WidgetClass dtClockGadgetClass = (WidgetClass) &dtClockClassRec;
- /*-------------------------------------------------------------
- ** Private Functions
- **-------------------------------------------------------------
- */
- /*-------------------------------------------------------------
- ** ClockTick
- ** Clock timeout.
- */
- static void
- ClockTick(
- XtPointer client_data,
- XtIntervalId *id )
- {
- DtClockGadget w = (DtClockGadget)client_data;
- struct tm * localtime ();
- struct tm tm;
- time_t time_value;
- char * time_ptr;
- Display * dpy = XtDisplay (w);
- Window win = XtWindow (w);
- if (id || !w->clock.interval_id)
- w->clock.interval_id =
- XtAppAddTimeOut (
- XtWidgetToApplicationContext ((Widget) w),
- G_ClockInterval (w)*1000, ClockTick,
- (XtPointer)w );
- (void) time (&time_value);
- tm = *localtime (&time_value);
- if (! XtIsManaged ((Widget)w))
- {
- w->clock.otm = tm;
- return;
- }
- /* 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;
- XBell (dpy, 50);
- if (tm.tm_min == 0)
- XBell (dpy, 50);
- }
- }
- /* remove this when clipping added to gcs */
- if ((G_Width (w) <
- (Dimension)((G_ClockWidth (w) / 2) + w->clock.centerX)) ||
- (G_Height (w) <
- (Dimension)((G_ClockHeight (w) / 2) + w->clock.centerY)))
- return;
- /* 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.
- */
- if (tm.tm_hour > 12)
- tm.tm_hour -= 12;
- EraseHands (w, &tm);
- w->clock.segbuffptr = w->clock.segbuff;
- w->clock.numseg = 0;
- /* Calculate the hour hand, fill it in with its color.
- */
- DrawHand (w, w->clock.minute_hand_length, w->clock.hand_width,
- ((double) tm.tm_min)/60.0);
- XDrawLines (dpy, win, G_ClockHandGC (w), w->clock.segbuff,
- VERTICES_IN_HANDS, CoordModeOrigin);
- XFillPolygon (dpy, win, G_ClockHandGC (w), w->clock.segbuff,
- VERTICES_IN_HANDS, Convex, CoordModeOrigin);
- w->clock.hour = w->clock.segbuffptr;
- DrawHand (w, w->clock.hour_hand_length, w->clock.hand_width,
- ((((double)tm.tm_hour) +
- (((double)tm.tm_min)/60.0)) / 12.0));
- XFillPolygon (dpy, win, G_ClockHandGC (w), w->clock.hour,
- VERTICES_IN_HANDS, Convex, CoordModeOrigin);
- XDrawLines (dpy, win, G_ClockHandGC (w), w->clock.hour,
- VERTICES_IN_HANDS, CoordModeOrigin);
- w->clock.sec = w->clock.segbuffptr;
- w->clock.otm = tm;
- }
-
- /*-------------------------------------------------------------
- ** EraseHands
- ** Erase clock hands.
- */
- static void
- EraseHands (
- DtClockGadget w,
- struct tm * tm )
- {
- XmManagerWidget mgr = (XmManagerWidget) XtParent (w);
- Display * dpy = XtDisplay (w);
- Window win = XtWindow (w);
- unsigned char behavior = G_Behavior (w);
- GC gc;
- if (! XtIsManaged ((Widget)w) || w->clock.numseg <= 0)
- return;
- gc = G_ClockBackgroundGC (w);
- /* Erase old hands.
- */
- if (!tm || tm->tm_min != w->clock.otm.tm_min ||
- tm->tm_hour != w->clock.otm.tm_hour)
- {
- XDrawLines (dpy, win, gc, w->clock.segbuff,
- VERTICES_IN_HANDS, CoordModeOrigin);
- XDrawLines (dpy, win, gc, w->clock.hour,
- VERTICES_IN_HANDS, CoordModeOrigin);
- XFillPolygon (dpy, win, gc, w->clock.segbuff,
- VERTICES_IN_HANDS, Convex, CoordModeOrigin);
- XFillPolygon (dpy, win, gc, w->clock.hour,
- VERTICES_IN_HANDS, Convex, CoordModeOrigin);
- }
- }
- /*-------------------------------------------------------------
- ** DrawLine
- ** Draw a line.
- * blank_length is the distance from the center which the line begins.
- * length is the maximum length of the hand.
- * Fraction_of_a_circle is a fraction between 0 and 1 (inclusive) 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 (
- DtClockGadget w,
- Dimension blank_length,
- Dimension length,
- double fraction_of_a_circle )
- {
- double dblank_length = (double)blank_length, dlength = (double)length;
- double angle, cosangle, sinangle;
- double cos ();
- double sin ();
- int cx = w->clock.centerX, cy = w->clock.centerY, x1, y1, x2, y2;
- /*
- * A full circle is 2 PI radians.
- * 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)
- *
- */
- angle = TWOPI * fraction_of_a_circle;
- cosangle = cos (angle);
- sinangle = sin (angle);
- /* 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);
- SetSegment (w, x1, y1, x2, y2);
- }
- /*-------------------------------------------------------------
- ** DrawHand
- ** Draw a hand.
- *
- * length is the maximum length of the hand.
- * width is the half-width of the hand.
- * Fraction_of_a_circle is a fraction between 0 and 1 (inclusive) indicating
- * how far around the circle (clockwise) from high noon.
- *
- */
- static void
- DrawHand(
- DtClockGadget w,
- Dimension length,
- Dimension width,
- double fraction_of_a_circle )
- {
- double angle, cosangle, sinangle;
- double ws, wc;
- Position x, y, x1, y1, x2, y2;
- double cos ();
- double sin ();
- /* A full circle is 2 PI radians.
- * 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)
- */
- angle = TWOPI * fraction_of_a_circle;
- cosangle = cos (angle);
- sinangle = sin (angle);
- /* Order of points when drawing the hand.
- * 1,4
- * / \
- * / \
- * / \
- * 2 ------- 3
- */
- wc = width * cosangle;
- ws = width * sinangle;
- SetSegment (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 */
- SetSegment (w, x1, y1,
- x2 = w->clock.centerX - round (ws - wc),
- y2 = w->clock.centerY + round (wc + ws)); /* 2 ----- 3 */
- SetSegment (w, x2, y2, x, y); /* 3 ----- 1 (4) */
- }
- /*-------------------------------------------------------------
- ** SetSegment
- ** Set segment values.
- */
- static void
- SetSegment(
- DtClockGadget w,
- int x1,
- int y1,
- int x2,
- int y2 )
- {
- w->clock.segbuffptr->x = x1 + G_X (w);
- w->clock.segbuffptr++->y = y1 + G_Y (w);
- w->clock.segbuffptr->x = x2 + G_X (w);
- w->clock.segbuffptr++->y = y2 + G_Y (w);
- w->clock.numseg += 2;
- }
- /*-------------------------------------------------------------
- ** round
- ** round integer.
- */
- static int
- round(
- double x )
- {
- return (x >= 0.0 ? (int) (x + .5) : (int) (x - .5));
- }
- /*-------------------------------------------------------------
- ** DrawClockFace
- *
- * Draw the clock face (every fifth tick-mark is longer
- * than the others).
- */
- static void
- DrawClockFace(
- DtClockGadget g )
- {
- Boolean draw_minute_ticks =
- ((G_ClockWidth (g) > (Dimension) (2 * SIZE_DEFAULT)) &&
- (G_ClockHeight (g) > (Dimension) (2 * SIZE_DEFAULT)));
- int i;
- int delta =
- (int)(g->clock.radius - g->clock.tick_spacing) / 3;
- if (! XtIsManaged ((Widget)g))
- return;
- g->clock.segbuffptr = g->clock.segbuff;
- g->clock.numseg = 0;
- /* Set segments.
- */
- for (i = 0; i < 60; i++)
- {
- if (draw_minute_ticks)
- {
- if ((i % 5) == 0)
- DrawLine (g, g->clock.tick_spacing,
- g->clock.radius, ((double) i)/60.);
- else
- DrawLine (g, g->clock.radius - delta,
- g->clock.radius, ((double) i)/60.);
- }
- else
- if ((i % 15) == 0)
- DrawLine (g, g->clock.radius - 1,
- g->clock.radius, ((double) i)/60.);
- }
- /* Draw clock face.
- */
- XDrawSegments (XtDisplay (g), XtWindow (g), G_ClockHandGC (g),
- (XSegment *) & (g->clock.segbuff[0]),
- g->clock.numseg/2);
-
- g->clock.segbuffptr = g->clock.segbuff;
- g->clock.numseg = 0;
- }
- /*-------------------------------------------------------------
- ** Action Procs
- **-------------------------------------------------------------
- */
- /*-------------------------------------------------------------
- ** Core Procs
- **-------------------------------------------------------------
- */
- /*-------------------------------------------------------------
- ** Initialize
- ** Initialize a new gadget instance.
- */
- /* ARGSUSED */
- static void
- Initialize(
- Widget request_w,
- Widget new_w )
- {
- DtClockGadget request = (DtClockGadget) request_w,
- new = (DtClockGadget) new_w;
- Dimension w, h,
- h_t = G_HighlightThickness (new),
- s_t = G_ShadowThickness (new);
- XmManagerWidget mw = (XmManagerWidget) XtParent (new);
- EventMask mask;
- String name = NULL;
- /* Set width and height.
- */
- if ((G_Width (request) == 0) ||
- (G_Height (request) == 0))
- {
- G_ClockWidth (new) = SIZE_DEFAULT;
- G_ClockHeight (new) = SIZE_DEFAULT;
- G_GetSize ((DtIconGadget)new, &w, &h);
- if (G_Width (request) == 0)
- G_Width (new) = w;
- if (G_Height (request) == 0)
- G_Height (new) = h;
- }
- Resize ((Widget)new);
- if (G_ClockInterval (new) <= 0)
- G_ClockInterval (new) = 60; /* make invalid update's use a default */
- new->clock.interval_id = 0;
- new->clock.numseg = 0;
- }
- /*-------------------------------------------------------------
- ** Destroy
- ** Release resources allocated for gadget.
- */
- static void
- Destroy(
- Widget w )
- {
- DtClockGadget g = (DtClockGadget) w;
- XmManagerWidget mw = (XmManagerWidget) XtParent (g);
- if (g->clock.interval_id) XtRemoveTimeOut (g->clock.interval_id);
- XtReleaseGC ((Widget) mw, G_ClockHandGC (g));
- }
- /*-------------------------------------------------------------
- ** Resize
- ** Set positions of string and pixmap.
- */
- static void
- Resize(
- Widget widget )
- {
- DtClockGadget g = (DtClockGadget) widget;
- Position pix_x, pix_y, str_x, str_y;
- Dimension s_t = G_ShadowThickness (g),
- h_t = G_HighlightThickness (g),
- p_w = G_PixmapWidth (g),
- p_h = G_PixmapHeight (g),
- m_w = G_MarginWidth (g),
- m_h = G_MarginHeight (g),
- s_w = G_StringWidth (g),
- s_h = G_StringHeight (g),
- v_pad = 2 * (s_t + h_t + m_h),
- h_pad = 2 * (s_t + h_t + m_w),
- spacing = G_Spacing (g),
- w = G_Width (g),
- h = G_Height (g);
- int radius;
- G_ClockWidth (g) = p_w - G_LeftInset (g) - G_RightInset (g);
- G_ClockHeight (g) = p_h - G_TopInset (g) - G_BottomInset (g);
-
- G_ClockWidth (g) = min (G_ClockWidth (g), G_ClockHeight (g));
- G_ClockHeight (g) = G_ClockWidth (g);
- G_GetPositions ((DtIconGadget)g, w, h, h_t, s_t,
- &pix_x, &pix_y, &str_x, &str_y);
- /* Compute clock size factors.
- * (need signed radius value since Dimension is unsigned)
- */
- radius = ((int) min (G_ClockWidth (g), G_ClockHeight (g))/2);
- g->clock.radius = (Dimension) max (radius, 1);
- if (G_ClockWidth (g) < (Dimension)(SIZE_DEFAULT / 2))
- {
- g->clock.tick_spacing =
- ((Dimension)(TICK_FRACT * g->clock.radius)/100);
- g->clock.minute_hand_length =
- ((Dimension)(MINUTE_HAND_FRACT * g->clock.radius)/100);
- g->clock.hour_hand_length =
- ((Dimension)(HOUR_HAND_FRACT * g->clock.radius)/100);
- g->clock.hand_width =
- ((Dimension)(HAND_WIDTH_FRACT * g->clock.radius)/100);
- }
- else
- {
- g->clock.tick_spacing =
- ((Dimension)(SMALL_TICK_FRACT * g->clock.radius)/100);
- g->clock.minute_hand_length =
- ((Dimension)(SMALL_MINUTE_HAND_FRACT * g->clock.radius)/100);
- g->clock.hour_hand_length =
- ((Dimension)(SMALL_HOUR_HAND_FRACT * g->clock.radius)/100);
- g->clock.hand_width =
- ((Dimension)(SMALL_HAND_WIDTH_FRACT * g->clock.radius)/100);
- }
- /* Compute clock position factors.
- */
- g->clock.centerX = pix_x + (p_w / 2);
- g->clock.centerY = pix_y + (p_h / 2);
- }
- /*-------------------------------------------------------------
- ** SetValues
- **
- */
- #if 0
- /* ARGSUSED */
- static Boolean
- SetValues(
- Widget current_w,
- Widget request_w,
- Widget new_w )
- {
- DtClockGadget request = (DtClockGadget) request_w,
- current = (DtClockGadget) current_w,
- new = (DtClockGadget) new_w;
- Boolean redraw_flag = False;
- if (G_ClockInterval (new) != current->clock.update)
- {
- if (current->clock.interval_id)
- XtRemoveTimeOut (current->clock.interval_id);
- if (XtIsRealized (new))
- new->clock.interval_id =
- XtAppAddTimeOut (
- XtWidgetToApplicationContext (new_w),
- G_ClockInterval (new)*1000,
- (XtTimerCallbackProc) ClockTick,
- (XtPointer)new_w);
- }
- /* Update clock face and hand color.
- */
- if ((G_ClockBackground (new) != G_ClockBackground (current)) ||
- (G_ClockHandPixel (new) != G_ClockHandPixel (current)))
- {
- G_UpdateGCs ((DtIconGadget)new);
- redraw_flag = True;
- }
- /* Update size factors if no resize.
- */
- if ((G_Width (new) == G_Width (current) &&
- G_Height (new) == G_Height (current)) &&
- (G_MarginWidth (new) != G_MarginWidth (current) ||
- G_MarginHeight (new) != G_MarginHeight (current) ||
- G_Spacing (new) != G_Spacing (current) ||
- G_ShadowThickness (new) != G_ShadowThickness (current) ||
- G_HighlightThickness (new) != G_HighlightThickness (current)))
- Resize (new_w);
- return (redraw_flag);
- }
- #endif /* 0 */
- /*-------------------------------------------------------------
- ** Gadget Procs
- **-------------------------------------------------------------
- */
- /*-------------------------------------------------------------
- ** Icon Procs
- **-------------------------------------------------------------
- */
- /*-------------------------------------------------------------
- ** Draw
- ** Draw gadget to drawable.
- */
- static void
- Draw(
- DtClockGadget g,
- Drawable drawable,
- Position x,
- Position y,
- Dimension w,
- Dimension h,
- Dimension h_t,
- Dimension s_t,
- unsigned char s_type,
- unsigned char fill_mode )
- {
- XmManagerWidget mgr = (XmManagerWidget) XtParent (g);
- Display * d = XtDisplay (g);
- GC gc;
- XRectangle clip;
- Position p_x, p_y, s_x, s_y;
- unsigned char behavior = G_Behavior (g);
- Dimension m_w = G_MarginWidth (g);
- Dimension m_h = G_MarginHeight (g);
- Dimension h_pad = h_t + s_t + m_w;
- Dimension v_pad = h_t + s_t + m_h;
- Dimension width, height;
- Pixmap pix;
- Pixmap mask;
- Boolean bMono;
- bMono = ( ((G_Foreground (g) == BlackPixelOfScreen (XtScreen (g))) ||
- (G_Foreground (g) == WhitePixelOfScreen (XtScreen (g)))) &&
- ((G_Background (g) == BlackPixelOfScreen (XtScreen (g))) ||
- (G_Background (g) == WhitePixelOfScreen (XtScreen (g)))) );
- if ((G_Armed (g)) && (fill_mode != XmFILL_PARENT))
- gc = G_ArmedBackgroundGC (g);
- else
- gc = M_BackgroundGC (mgr);
- if ((fill_mode != XmFILL_NONE) && (fill_mode != XmFILL_TRANSPARENT))
- XFillRectangle (d, drawable, gc, x + h_t, y + h_t,
- w - 2 * h_t, h - 2 * h_t);
- G_GetPositions ((DtIconGadget)g, w, h, h_t, s_t, &p_x, &p_y, &s_x, &s_y);
- if (G_Pixmap (g))
- {
- width = ((Dimension)(p_x + s_t + h_t) >= G_Width (g))
- ? 0 : min (G_PixmapWidth (g),
- (Dimension)(G_Width (g) - p_x - s_t - h_t));
- height = ((Dimension)(p_y + s_t + h_t) >= G_Height (g))
- ? 0 : min (G_PixmapHeight (g),
- (Dimension)(G_Height (g) - p_y - s_t - h_t));
- /* Use normal image.
- */
- pix = G_Pixmap (g);
- mask = G_Mask (g);
- /* Update clip gc.
- */
- if (mask != XmUNSPECIFIED_PIXMAP)
- {
- gc = G_ClipGC (g);
- XSetClipMask (XtDisplay(g), gc, mask);
- XSetClipOrigin (XtDisplay(g), gc, x + p_x, y + p_y);
- }
- else
- gc = G_NormalGC (g);
-
- /* Paint pixmap.
- */
- if ((gc != NULL) && (pix != XmUNSPECIFIED_PIXMAP))
- XCopyArea (d, pix, drawable, gc, 0, 0,
- width, height, x + p_x, y + p_y);
- }
- /* Fill clock face region and draw clock.
- */
- if (g->clock.numseg != 0)
- EraseHands (g, (struct tm *) 0);
- ClockTick ((XtPointer)g, (XtIntervalId*)NULL);
- /* Draw shadow.
- */
- if ((behavior == XmICON_BUTTON || behavior == XmICON_DRAG) &&
- G_FillOnArm (g) && G_Armed (g))
- gc = G_ArmedGC (g);
- else if (behavior == XmICON_TOGGLE && G_FillOnArm (g) &&
- ((G_Armed (g) && !G_Set (g)) ||
- (!G_Armed (g) && G_Set (g))))
- gc = G_ArmedGC (g);
- else
- gc = G_NormalGC (g);
- /* Draw string.
- */
- if (G_String (g))
- {
- clip.x = x + h_t + s_x;
- clip.y = y + h_t + s_y;
- clip.width = G_Width (g) - (2 * (h_t + s_t));
- clip.height = G_Height (g) - (2 * (h_t + s_t));
- if (clip.width > 0 && clip.height > 0)
- {
- if (bMono)
- {
- if ((s_x - 2) >= (Position)(h_t + s_t))
- XFillRectangle (d, drawable,
- G_ArmedBackgroundGC (g),
- x + s_x - 2, y + s_y,
- 2, G_StringHeight (g));
- XmStringDrawImage (d, drawable, G_FontList (g),
- G_String (g), G_NormalGC (g),
- x + s_x, y + s_y,
- clip.width, XmALIGNMENT_BEGINNING,
- XmSTRING_DIRECTION_L_TO_R, &clip);
- if ((s_x + (Position)(G_StringWidth (g) + 2))
- <= (Position)(G_Width (g) - h_t - s_t))
- XFillRectangle (d, drawable,
- G_ArmedBackgroundGC (g),
- x + s_x + G_StringWidth (g),
- y + s_y, 2, G_StringHeight (g));
- }
- else
- {
- if (G_UseEmbossedText (g))
- XmStringDraw (d, drawable, G_FontList (g),
- G_String (g), G_BottomShadowGC (g),
- x + s_x + 1, y + s_y + 1,
- clip.width, XmALIGNMENT_BEGINNING,
- XmSTRING_DIRECTION_L_TO_R, &clip);
- XmStringDraw (d, drawable, G_FontList (g),
- G_String (g), G_NormalGC (g),
- x + s_x, y + s_y,
- clip.width, XmALIGNMENT_BEGINNING,
- XmSTRING_DIRECTION_L_TO_R, &clip);
- }
- }
- }
- }
- /*-------------------------------------------------------------
- ** UpdateGCs
- ** Get normal and background graphics contexts.
- ** Use standard mask to maximize caching opportunities.
- */
- static void
- UpdateGCs(
- DtClockGadget g )
- {
- XGCValues values;
- XtGCMask value_mask;
- XmManagerWidget mw = (XmManagerWidget) XtParent(g);
- XFontStruct * font;
- Boolean font_rtn;
- DtIconGadgetClass
- super = (DtIconGadgetClass) XtSuperclass (g);
- static Boolean first = True;
- /* Let superclass do most of the work.
- */
- (* C_UpdateGCs (super)) ((DtIconGadget)g);
- if (first)
- first = False;
- else if (G_ClockHandGC (g))
- XtReleaseGC ((Widget)mw, G_ClockHandGC (g));
- /* Get clock hand GC.
- */
- value_mask = GCForeground | GCFillStyle;
- if (XmeRenderTableGetDefaultFont (G_FontList (g), &font)) {
- value_mask |= GCFont;
- values.font = font->fid;
- }
- if (((G_PixmapForeground (g) == WhitePixelOfScreen (XtScreen (g))) &&
- (G_PixmapBackground (g) == BlackPixelOfScreen (XtScreen (g)))) ||
- ((G_PixmapForeground (g) == BlackPixelOfScreen (XtScreen (g))) &&
- (G_PixmapBackground (g) == WhitePixelOfScreen (XtScreen (g)))))
- values.foreground = G_PixmapBackground (g);
- else
- values.foreground = mw->manager.top_shadow_color;
- values.fill_style = FillSolid;
- G_ClockHandGC (g) = XtGetGC ((Widget) mw, value_mask, &values);
- /* Get clock background GC
- */
- value_mask |= GCBackground;
- if (((G_PixmapForeground (g) == WhitePixelOfScreen (XtScreen (g))) &&
- (G_PixmapBackground (g) == BlackPixelOfScreen (XtScreen (g)))) ||
- ((G_PixmapForeground (g) == BlackPixelOfScreen (XtScreen (g))) &&
- (G_PixmapBackground (g) == WhitePixelOfScreen (XtScreen (g)))))
- values.foreground = G_PixmapForeground (g);
- else
- values.foreground = G_ArmColor (g);
- values.background = G_PixmapBackground (g);
- G_ClockBackgroundGC (g) = XtGetGC ((Widget) mw, value_mask, &values);
- }
- /*-------------------------------------------------------------
- ** Public Entry Points
- **-------------------------------------------------------------
- */
- /*-------------------------------------------------------------
- ** DtCreateClock
- ** Create a new gadget instance.
- **-------------------------------------------------------------
- */
- Widget
- DtCreateClock(
- Widget parent,
- String name,
- ArgList arglist,
- Cardinal argcount )
- {
- return (XtCreateWidget (name, dtClockGadgetClass,
- parent, arglist, argcount));
- }
|