442
|
1 /* Gauge Widget for XEmacs.
|
424
|
2 Copyright (C) 1999 Edward A. Falk
|
|
3
|
|
4 This file is part of XEmacs.
|
|
5
|
|
6 XEmacs is free software; you can redistribute it and/or modify it
|
|
7 under the terms of the GNU General Public License as published by the
|
|
8 Free Software Foundation; either version 2, or (at your option) any
|
|
9 later version.
|
|
10
|
|
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
|
|
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
14 for more details.
|
|
15
|
|
16 You should have received a copy of the GNU General Public License
|
|
17 along with XEmacs; see the file COPYING. If not, write to
|
|
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
19 Boston, MA 02111-1307, USA. */
|
|
20
|
|
21 /* Synched up with: Gauge.c 1.2 */
|
|
22
|
|
23 /*
|
|
24 * Gauge.c - Gauge widget
|
|
25 *
|
|
26 * Author: Edward A. Falk
|
|
27 * falk@falconer.vip.best.com
|
442
|
28 *
|
424
|
29 * Date: July 9, 1997
|
|
30 *
|
|
31 * Note: for fun and demonstration purposes, I have added selection
|
|
32 * capabilities to this widget. If you select the widget, you create
|
|
33 * a primary selection containing the current value of the widget in
|
|
34 * both integer and string form. If you copy into the widget, the
|
|
35 * primary selection is converted to an integer value and the gauge is
|
|
36 * set to that value.
|
|
37 */
|
|
38
|
|
39 /* TODO: display time instead of value
|
|
40 */
|
|
41
|
|
42 #define DEF_LEN 50 /* default width (or height for vertical gauge) */
|
|
43 #define MIN_LEN 10 /* minimum reasonable width (height) */
|
|
44 #define TIC_LEN 6 /* length of tic marks */
|
|
45 #define GA_WID 3 /* width of gauge */
|
|
46 #define MS_PER_SEC 1000
|
|
47
|
|
48 #include <config.h>
|
|
49 #include <stdlib.h>
|
|
50 #include <stdio.h>
|
|
51 #include <ctype.h>
|
|
52 #include <X11/IntrinsicP.h>
|
|
53 #include <X11/Xatom.h>
|
|
54 #include <X11/StringDefs.h>
|
442
|
55 #include ATHENA_XawInit_h_
|
424
|
56 #include "xlwgaugeP.h"
|
|
57 #include "../src/xmu.h"
|
|
58 #ifdef HAVE_XMU
|
|
59 #include <X11/Xmu/Atoms.h>
|
|
60 #include <X11/Xmu/Drawing.h>
|
|
61 #include <X11/Xmu/StdSel.h>
|
|
62 #endif
|
|
63
|
|
64
|
|
65 /****************************************************************
|
|
66 *
|
|
67 * Gauge resources
|
|
68 *
|
|
69 ****************************************************************/
|
|
70
|
|
71
|
|
72 static char defaultTranslations[] =
|
|
73 "<Btn1Up>: select()\n\
|
|
74 <Key>F1: select(CLIPBOARD)\n\
|
|
75 <Btn2Up>: paste()\n\
|
|
76 <Key>F2: paste(CLIPBOARD)" ;
|
|
77
|
|
78
|
|
79
|
|
80 #define offset(field) XtOffsetOf(GaugeRec, field)
|
|
81 static XtResource resources[] = {
|
|
82 {XtNvalue, XtCValue, XtRInt, sizeof(int),
|
|
83 offset(gauge.value), XtRImmediate, (XtPointer)0},
|
|
84 {XtNminValue, XtCMinValue, XtRInt, sizeof(int),
|
|
85 offset(gauge.v0), XtRImmediate, (XtPointer)0},
|
|
86 {XtNmaxValue, XtCMaxValue, XtRInt, sizeof(int),
|
|
87 offset(gauge.v1), XtRImmediate, (XtPointer)100},
|
|
88 {XtNntics, XtCNTics, XtRInt, sizeof(int),
|
|
89 offset(gauge.ntics), XtRImmediate, (XtPointer) 0},
|
|
90 {XtNnlabels, XtCNLabels, XtRInt, sizeof(int),
|
|
91 offset(gauge.nlabels), XtRImmediate, (XtPointer) 0},
|
|
92 {XtNlabels, XtCLabels, XtRStringArray, sizeof(String *),
|
|
93 offset(gauge.labels), XtRStringArray, NULL},
|
|
94 {XtNautoScaleUp, XtCAutoScaleUp, XtRBoolean, sizeof(Boolean),
|
|
95 offset(gauge.autoScaleUp), XtRImmediate, FALSE},
|
|
96 {XtNautoScaleDown, XtCAutoScaleDown, XtRBoolean, sizeof(Boolean),
|
|
97 offset(gauge.autoScaleDown), XtRImmediate, FALSE},
|
|
98 {XtNorientation, XtCOrientation, XtROrientation, sizeof(XtOrientation),
|
|
99 offset(gauge.orientation), XtRImmediate, (XtPointer)XtorientHorizontal},
|
|
100 {XtNupdate, XtCInterval, XtRInt, sizeof(int),
|
|
101 offset(gauge.update), XtRImmediate, (XtPointer)0},
|
|
102 {XtNgetValue, XtCCallback, XtRCallback, sizeof(XtPointer),
|
|
103 offset(gauge.getValue), XtRImmediate, (XtPointer)NULL},
|
|
104 };
|
|
105 #undef offset
|
|
106
|
|
107
|
|
108
|
|
109 /* member functions */
|
|
110
|
|
111 static void GaugeClassInit (void);
|
|
112 static void GaugeInit (Widget, Widget, ArgList, Cardinal *);
|
|
113 static void GaugeDestroy (Widget);
|
|
114 static void GaugeResize (Widget);
|
|
115 static void GaugeExpose (Widget, XEvent *, Region);
|
|
116 static Boolean GaugeSetValues (Widget, Widget, Widget, ArgList, Cardinal *);
|
|
117 static XtGeometryResult GaugeQueryGeometry (Widget, XtWidgetGeometry *,
|
|
118 XtWidgetGeometry *);
|
|
119
|
|
120 /* action procs */
|
|
121
|
|
122 static void GaugeSelect (Widget, XEvent *, String *, Cardinal *);
|
|
123 static void GaugePaste (Widget, XEvent *, String *, Cardinal *);
|
|
124
|
|
125 /* internal privates */
|
|
126
|
|
127 static void GaugeSize (GaugeWidget, Dimension *, Dimension *, Dimension);
|
|
128 static void MaxLabel (GaugeWidget, Dimension *, Dimension *,
|
|
129 Dimension *, Dimension *);
|
|
130 static void AutoScale (GaugeWidget);
|
|
131 static void EnableUpdate (GaugeWidget);
|
|
132 static void DisableUpdate (GaugeWidget);
|
|
133
|
|
134 static void GaugeGetValue (XtPointer, XtIntervalId *);
|
|
135 static void GaugeMercury (Display *, Window, GC, GaugeWidget, Cardinal, Cardinal);
|
|
136
|
|
137 static Boolean GaugeConvert (Widget, Atom *, Atom *, Atom *,
|
458
|
138 XtPointer *, unsigned long *, int *);
|
424
|
139 static void GaugeLoseSel (Widget, Atom *);
|
|
140 static void GaugeDoneSel (Widget, Atom *, Atom *);
|
|
141 static void GaugeGetSelCB (Widget, XtPointer, Atom *, Atom *,
|
458
|
142 XtPointer, unsigned long *, int *);
|
424
|
143
|
|
144 static GC Get_GC (GaugeWidget, Pixel);
|
|
145
|
|
146
|
|
147 static XtActionsRec actionsList[] =
|
|
148 {
|
|
149 {"select", GaugeSelect},
|
|
150 {"paste", GaugePaste},
|
|
151 } ;
|
|
152
|
|
153
|
|
154
|
|
155 /****************************************************************
|
|
156 *
|
|
157 * Full class record constant
|
|
158 *
|
|
159 ****************************************************************/
|
|
160
|
|
161 GaugeClassRec gaugeClassRec = {
|
|
162 {
|
442
|
163 /* core_class fields */
|
424
|
164 /* superclass */ (WidgetClass) &labelClassRec,
|
|
165 /* class_name */ "Gauge",
|
|
166 /* widget_size */ sizeof(GaugeRec),
|
|
167 /* class_initialize */ GaugeClassInit,
|
|
168 /* class_part_initialize */ NULL,
|
|
169 /* class_inited */ FALSE,
|
|
170 /* initialize */ GaugeInit,
|
|
171 /* initialize_hook */ NULL,
|
|
172 /* realize */ XtInheritRealize, /* TODO? */
|
|
173 /* actions */ actionsList,
|
|
174 /* num_actions */ XtNumber(actionsList),
|
|
175 /* resources */ resources,
|
|
176 /* num_resources */ XtNumber(resources),
|
|
177 /* xrm_class */ NULLQUARK,
|
|
178 /* compress_motion */ TRUE,
|
|
179 /* compress_exposure */ TRUE,
|
|
180 /* compress_enterleave */ TRUE,
|
|
181 /* visible_interest */ FALSE,
|
|
182 /* destroy */ GaugeDestroy,
|
|
183 /* resize */ GaugeResize,
|
|
184 /* expose */ GaugeExpose,
|
|
185 /* set_values */ GaugeSetValues,
|
|
186 /* set_values_hook */ NULL,
|
|
187 /* set_values_almost */ XtInheritSetValuesAlmost,
|
|
188 /* get_values_hook */ NULL,
|
|
189 /* accept_focus */ NULL,
|
|
190 /* version */ XtVersion,
|
|
191 /* callback_private */ NULL,
|
|
192 /* tm_table */ defaultTranslations,
|
|
193 /* query_geometry */ GaugeQueryGeometry,
|
|
194 /* display_accelerator */ XtInheritDisplayAccelerator,
|
|
195 /* extension */ NULL
|
|
196 },
|
|
197 /* Simple class fields initialization */
|
|
198 {
|
|
199 /* change_sensitive */ XtInheritChangeSensitive
|
|
200 },
|
|
201 #ifdef _ThreeDP_h
|
|
202 /* ThreeD class fields initialization */
|
|
203 {
|
|
204 XtInheritXaw3dShadowDraw /* shadowdraw */
|
|
205 },
|
|
206 #endif
|
|
207 /* Label class fields initialization */
|
|
208 {
|
|
209 /* ignore */ 0
|
|
210 },
|
|
211 /* Gauge class fields initialization */
|
|
212 {
|
|
213 /* extension */ NULL
|
|
214 },
|
|
215 };
|
|
216
|
|
217 WidgetClass gaugeWidgetClass = (WidgetClass)&gaugeClassRec;
|
|
218
|
|
219
|
|
220
|
|
221
|
|
222 /****************************************************************
|
|
223 *
|
|
224 * Member Procedures
|
|
225 *
|
|
226 ****************************************************************/
|
|
227
|
|
228 static void
|
|
229 GaugeClassInit (void)
|
|
230 {
|
|
231 XawInitializeWidgetSet();
|
|
232 #ifdef HAVE_XMU
|
|
233 XtAddConverter(XtRString, XtROrientation, XmuCvtStringToOrientation,
|
|
234 NULL, 0) ;
|
|
235 #endif
|
|
236 }
|
|
237
|
|
238
|
|
239
|
|
240 /* ARGSUSED */
|
|
241 static void
|
|
242 GaugeInit (Widget request,
|
|
243 Widget new,
|
2286
|
244 ArgList UNUSED (args),
|
|
245 Cardinal *UNUSED (num_args))
|
424
|
246 {
|
|
247 GaugeWidget gw = (GaugeWidget) new;
|
|
248
|
|
249 if( gw->gauge.v0 == 0 && gw->gauge.v1 == 0 ) {
|
|
250 gw->gauge.autoScaleUp = gw->gauge.autoScaleDown = TRUE ;
|
|
251 AutoScale(gw) ;
|
|
252 }
|
|
253
|
|
254 /* If size not explicitly set, set it to our preferred size now. */
|
|
255
|
|
256 if( request->core.width == 0 || request->core.height == 0 )
|
|
257 {
|
|
258 Dimension w,h ;
|
|
259 GaugeSize(gw, &w,&h, DEF_LEN) ;
|
|
260 if( request->core.width == 0 )
|
|
261 new->core.width = w ;
|
|
262 if( request->core.height == 0 )
|
|
263 new->core.height = h ;
|
|
264 gw->core.widget_class->core_class.resize(new) ;
|
|
265 }
|
|
266
|
|
267 gw->gauge.selected = None ;
|
|
268 gw->gauge.selstr = NULL ;
|
|
269
|
|
270 if( gw->gauge.update > 0 )
|
|
271 EnableUpdate(gw) ;
|
|
272
|
|
273 gw->gauge.inverse_GC = Get_GC(gw, gw->core.background_pixel) ;
|
|
274 }
|
|
275
|
|
276 static void
|
|
277 GaugeDestroy (Widget w)
|
|
278 {
|
|
279 GaugeWidget gw = (GaugeWidget)w;
|
|
280
|
|
281 if( gw->gauge.selstr != NULL )
|
|
282 XtFree(gw->gauge.selstr) ;
|
|
283
|
|
284 if( gw->gauge.selected != None )
|
|
285 XtDisownSelection(w, gw->gauge.selected, CurrentTime) ;
|
|
286
|
|
287 XtReleaseGC(w, gw->gauge.inverse_GC) ;
|
|
288
|
|
289 if( gw->gauge.update > 0 )
|
|
290 DisableUpdate(gw) ;
|
|
291 }
|
|
292
|
|
293
|
|
294 /* React to size change from manager. Label widget will compute some
|
|
295 * internal stuff, but we need to override.
|
|
296 */
|
|
297
|
|
298 static void
|
|
299 GaugeResize (Widget w)
|
|
300 {
|
|
301 GaugeWidget gw = (GaugeWidget)w;
|
|
302 int size ; /* height (width) of gauge */
|
|
303 int vmargin ; /* vertical (horizontal) margin */
|
|
304 int hmargin ; /* horizontal (vertical) margin */
|
|
305
|
|
306 vmargin = gw->gauge.orientation == XtorientHorizontal ?
|
|
307 gw->label.internal_height : gw->label.internal_width ;
|
|
308 hmargin = gw->gauge.orientation == XtorientHorizontal ?
|
|
309 gw->label.internal_width : gw->label.internal_height ;
|
|
310
|
|
311 /* TODO: need to call parent resize proc? I don't think so since
|
|
312 * we're recomputing everything from scratch anyway.
|
|
313 */
|
|
314
|
|
315 /* find total height (width) of contents */
|
|
316
|
|
317 size = GA_WID+2 ; /* gauge itself + edges */
|
|
318
|
|
319 if( gw->gauge.ntics > 1 ) /* tic marks */
|
|
320 size += vmargin + TIC_LEN ;
|
|
321
|
|
322 if( gw->gauge.nlabels > 1 )
|
|
323 {
|
|
324 Dimension lwm, lw0, lw1 ; /* width of max, left, right labels */
|
|
325 Dimension lh ;
|
|
326
|
|
327 MaxLabel(gw,&lwm,&lh, &lw0,&lw1) ;
|
|
328
|
|
329 if( gw->gauge.orientation == XtorientHorizontal )
|
|
330 {
|
|
331 gw->gauge.margin0 = lw0 / 2 ;
|
|
332 gw->gauge.margin1 = lw1 / 2 ;
|
|
333 size += lh + vmargin ;
|
|
334 }
|
|
335 else
|
|
336 {
|
442
|
337 gw->gauge.margin0 =
|
424
|
338 gw->gauge.margin1 = lh / 2 ;
|
|
339 size += lwm + vmargin ;
|
|
340 }
|
|
341 }
|
|
342 else
|
|
343 gw->gauge.margin0 = gw->gauge.margin1 = 0 ;
|
|
344
|
|
345 gw->gauge.margin0 += hmargin ;
|
|
346 gw->gauge.margin1 += hmargin ;
|
|
347
|
|
348 /* Now distribute height (width) over components */
|
|
349
|
|
350 if( gw->gauge.orientation == XtorientHorizontal )
|
|
351 gw->gauge.gmargin = (gw->core.height-size)/2 ;
|
|
352 else
|
|
353 gw->gauge.gmargin = (gw->core.width-size)/2 ;
|
|
354
|
|
355 gw->gauge.tmargin = gw->gauge.gmargin + GA_WID+2 + vmargin ;
|
|
356 if( gw->gauge.ntics > 1 )
|
|
357 gw->gauge.lmargin = gw->gauge.tmargin + TIC_LEN + vmargin ;
|
|
358 else
|
|
359 gw->gauge.lmargin = gw->gauge.tmargin ;
|
|
360 }
|
|
361
|
|
362 /*
|
|
363 * Repaint the widget window
|
|
364 */
|
|
365
|
|
366 /* ARGSUSED */
|
|
367 static void
|
|
368 GaugeExpose (Widget w,
|
2286
|
369 XEvent *UNUSED (event),
|
|
370 Region UNUSED (region))
|
424
|
371 {
|
|
372 GaugeWidget gw = (GaugeWidget) w;
|
|
373 register Display *dpy = XtDisplay(w) ;
|
|
374 register Window win = XtWindow(w) ;
|
|
375 GC gc; /* foreground, background */
|
|
376 GC gctop, gcbot ; /* dark, light shadows */
|
|
377
|
|
378 int len ; /* length (width or height) of widget */
|
|
379 int e0,e1 ; /* ends of the gauge */
|
|
380 int x ;
|
|
381 int y ; /* vertical (horizontal) position */
|
|
382 int i ;
|
|
383 int v0 = gw->gauge.v0 ;
|
|
384 int v1 = gw->gauge.v1 ;
|
|
385 int value = gw->gauge.value ;
|
|
386
|
|
387 gc = XtIsSensitive(w) ? gw->label.normal_GC : gw->label.gray_GC ;
|
|
388
|
|
389
|
|
390 #ifdef _ThreeDP_h
|
|
391 gctop = gw->threeD.bot_shadow_GC ;
|
|
392 gcbot = gw->threeD.top_shadow_GC ;
|
|
393 #else
|
|
394 gctop = gcbot = gc ;
|
|
395 #endif
|
|
396
|
|
397 if( gw->gauge.orientation == XtorientHorizontal ) {
|
|
398 len = gw->core.width ;
|
|
399 } else {
|
|
400 len = gw->core.height ;
|
|
401 }
|
|
402
|
|
403 /* if the gauge is selected, signify by drawing the background
|
442
|
404 * in a contrasting color.
|
424
|
405 */
|
|
406
|
|
407 if( gw->gauge.selected )
|
|
408 {
|
|
409 XFillRectangle(dpy,win, gc, 0,0, w->core.width,w->core.height) ;
|
|
410 gc = gw->gauge.inverse_GC ;
|
|
411 }
|
|
412
|
|
413 e0 = gw->gauge.margin0 ; /* left (top) end */
|
|
414 e1 = len - gw->gauge.margin1 -1 ; /* right (bottom) end */
|
|
415
|
|
416 /* Draw the Gauge itself */
|
|
417
|
|
418 y = gw->gauge.gmargin ;
|
|
419
|
|
420 if( gw->gauge.orientation == XtorientHorizontal ) /* horizontal */
|
|
421 {
|
|
422 XDrawLine(dpy,win,gctop, e0+1,y, e1-1,y) ;
|
|
423 XDrawLine(dpy,win,gctop, e0,y+1, e0,y+GA_WID) ;
|
|
424 XDrawLine(dpy,win,gcbot, e0+1, y+GA_WID+1, e1-1, y+GA_WID+1) ;
|
|
425 XDrawLine(dpy,win,gcbot, e1,y+1, e1,y+GA_WID) ;
|
|
426 }
|
|
427 else /* vertical */
|
|
428 {
|
|
429 XDrawLine(dpy,win,gctop, y,e0+1, y,e1-1) ;
|
|
430 XDrawLine(dpy,win,gctop, y+1,e0, y+GA_WID,e0) ;
|
|
431 XDrawLine(dpy,win,gcbot, y+GA_WID+1,e0+1, y+GA_WID+1, e1-1) ;
|
|
432 XDrawLine(dpy,win,gcbot, y+1,e1, y+GA_WID,e1) ;
|
|
433 }
|
|
434
|
|
435
|
|
436 /* draw the mercury */
|
|
437
|
|
438 GaugeMercury(dpy, win, gc, gw, 0,value) ;
|
|
439
|
|
440
|
|
441 if( gw->gauge.ntics > 1 )
|
|
442 {
|
|
443 y = gw->gauge.tmargin ;
|
|
444 for(i=0; i<gw->gauge.ntics; ++i)
|
|
445 {
|
|
446 x = e0 + i*(e1-e0-1)/(gw->gauge.ntics-1) ;
|
|
447 if( gw->gauge.orientation == XtorientHorizontal ) {
|
|
448 XDrawLine(dpy,win,gcbot, x,y+1, x,y+TIC_LEN-2) ;
|
|
449 XDrawLine(dpy,win,gcbot, x,y, x+1,y) ;
|
|
450 XDrawLine(dpy,win,gctop, x+1,y+1, x+1,y+TIC_LEN-2) ;
|
|
451 XDrawLine(dpy,win,gctop, x,y+TIC_LEN-1, x+1,y+TIC_LEN-1) ;
|
|
452 }
|
|
453 else {
|
|
454 XDrawLine(dpy,win,gcbot, y+1,x, y+TIC_LEN-2,x) ;
|
|
455 XDrawLine(dpy,win,gcbot, y,x, y,x+1) ;
|
|
456 XDrawLine(dpy,win,gctop, y+1,x+1, y+TIC_LEN-2,x+1) ;
|
|
457 XDrawLine(dpy,win,gctop, y+TIC_LEN-1,x, y+TIC_LEN-1,x+1) ;
|
|
458 }
|
|
459 }
|
|
460 }
|
|
461
|
|
462 /* draw labels */
|
|
463 if( gw->gauge.nlabels > 1 )
|
|
464 {
|
|
465 char label[20], *s = label ;
|
442
|
466 int xlen, wd,h =0 ;
|
424
|
467
|
|
468 if( gw->gauge.orientation == XtorientHorizontal )
|
|
469 y = gw->gauge.lmargin + gw->label.font->max_bounds.ascent - 1 ;
|
|
470 else {
|
|
471 y = gw->gauge.lmargin ;
|
|
472 h = gw->label.font->max_bounds.ascent / 2 ;
|
|
473 }
|
|
474
|
|
475 for(i=0; i<gw->gauge.nlabels; ++i)
|
|
476 {
|
|
477 if( gw->gauge.labels == NULL )
|
|
478 sprintf(label, "%d", v0+i*(v1 - v0)/(gw->gauge.nlabels - 1)) ;
|
|
479 else
|
|
480 s = gw->gauge.labels[i] ;
|
|
481 if( s != NULL ) {
|
|
482 x = e0 + i*(e1-e0-1)/(gw->gauge.nlabels-1) ;
|
442
|
483 xlen = strlen(s) ;
|
424
|
484 if( gw->gauge.orientation == XtorientHorizontal ) {
|
442
|
485 wd = XTextWidth(gw->label.font, s, xlen) ;
|
|
486 XDrawString(dpy,win,gc, x-wd/2,y, s,xlen) ;
|
424
|
487 }
|
|
488 else {
|
442
|
489 XDrawString(dpy,win,gc, y,x+h, s,xlen) ;
|
424
|
490 }
|
|
491 }
|
|
492 }
|
|
493 }
|
|
494 }
|
|
495
|
|
496
|
|
497 /*
|
|
498 * Set specified arguments into widget
|
|
499 */
|
|
500
|
|
501 static Boolean
|
|
502 GaugeSetValues (Widget old,
|
2286
|
503 Widget UNUSED (request),
|
424
|
504 Widget new,
|
2286
|
505 ArgList UNUSED (args),
|
|
506 Cardinal *UNUSED (num_args))
|
424
|
507 {
|
|
508 GaugeWidget oldgw = (GaugeWidget) old;
|
|
509 GaugeWidget gw = (GaugeWidget) new;
|
|
510 Boolean was_resized = False;
|
|
511
|
|
512 if( gw->gauge.selected != None ) {
|
|
513 XtDisownSelection(new, gw->gauge.selected, CurrentTime) ;
|
|
514 gw->gauge.selected = None ;
|
|
515 }
|
|
516
|
|
517 /* Changes to v0,v1,labels, ntics, nlabels require resize & redraw. */
|
|
518 /* Change to value requires redraw and possible resize if autoscale */
|
|
519
|
|
520 was_resized =
|
|
521 gw->gauge.v0 != oldgw->gauge.v0 ||
|
|
522 gw->gauge.v1 != oldgw->gauge.v1 ||
|
|
523 gw->gauge.ntics != oldgw->gauge.ntics ||
|
|
524 gw->gauge.nlabels != oldgw->gauge.nlabels ||
|
|
525 gw->gauge.labels != oldgw->gauge.labels ;
|
|
526
|
|
527 if( (gw->gauge.autoScaleUp && gw->gauge.value > gw->gauge.v1) ||
|
|
528 (gw->gauge.autoScaleDown && gw->gauge.value < gw->gauge.v1/3 ))
|
|
529 {
|
|
530 AutoScale(gw) ;
|
|
531 was_resized = TRUE ;
|
|
532 }
|
|
533
|
|
534 if( was_resized ) {
|
|
535 if( gw->label.resize )
|
|
536 GaugeSize(gw, &gw->core.width, &gw->core.height, DEF_LEN) ;
|
|
537 else
|
|
538 GaugeResize(new) ;
|
|
539 }
|
442
|
540
|
424
|
541 if( gw->gauge.update != oldgw->gauge.update )
|
|
542 {
|
|
543 if( gw->gauge.update > 0 )
|
|
544 EnableUpdate(gw) ;
|
|
545 else
|
|
546 DisableUpdate(gw) ;
|
|
547 }
|
|
548
|
|
549 if( gw->core.background_pixel != oldgw->core.background_pixel )
|
|
550 {
|
|
551 XtReleaseGC(new, gw->gauge.inverse_GC) ;
|
|
552 gw->gauge.inverse_GC = Get_GC(gw, gw->core.background_pixel) ;
|
|
553 }
|
|
554
|
|
555 return was_resized || gw->gauge.value != oldgw->gauge.value ||
|
|
556 XtIsSensitive(old) != XtIsSensitive(new);
|
|
557 }
|
|
558
|
|
559
|
|
560 static XtGeometryResult
|
|
561 GaugeQueryGeometry (Widget w,
|
|
562 XtWidgetGeometry *intended,
|
|
563 XtWidgetGeometry *preferred)
|
|
564 {
|
|
565 register GaugeWidget gw = (GaugeWidget)w;
|
|
566
|
|
567 if( intended->width == w->core.width &&
|
|
568 intended->height == w->core.height )
|
|
569 return XtGeometryNo ;
|
|
570
|
|
571 preferred->request_mode = CWWidth | CWHeight;
|
|
572 GaugeSize(gw, &preferred->width, &preferred->height, DEF_LEN) ;
|
|
573
|
|
574 if( (!(intended->request_mode & CWWidth) ||
|
|
575 intended->width >= preferred->width) &&
|
|
576 (!(intended->request_mode & CWHeight) ||
|
|
577 intended->height >= preferred->height) )
|
|
578 return XtGeometryYes;
|
|
579 else
|
|
580 return XtGeometryAlmost;
|
|
581 }
|
|
582
|
|
583
|
|
584
|
|
585
|
|
586 /****************************************************************
|
|
587 *
|
|
588 * Action Procedures
|
|
589 *
|
|
590 ****************************************************************/
|
|
591
|
|
592 static void
|
|
593 GaugeSelect (Widget w,
|
|
594 XEvent *event,
|
|
595 String *params,
|
|
596 Cardinal *num_params)
|
|
597 {
|
|
598 GaugeWidget gw = (GaugeWidget)w ;
|
|
599 Atom seln = XA_PRIMARY ;
|
|
600
|
|
601 if( gw->gauge.selected != None ) {
|
|
602 XtDisownSelection(w, gw->gauge.selected, CurrentTime) ;
|
|
603 gw->gauge.selected = None ;
|
|
604 }
|
|
605
|
|
606 if( *num_params > 0 ) {
|
|
607 seln = XInternAtom(XtDisplay(w), params[0], False) ;
|
|
608 printf("atom %s is %ld\n", params[0], seln) ;
|
|
609 }
|
|
610
|
|
611 if( ! XtOwnSelection(w, seln, event->xbutton.time, GaugeConvert,
|
|
612 GaugeLoseSel, GaugeDoneSel) )
|
|
613 {
|
|
614 /* in real code, this error message would be replaced by
|
|
615 * something more elegant, or at least deleted
|
|
616 */
|
|
617
|
|
618 fprintf(stderr, "Gauge failed to get selection, try again\n") ;
|
|
619 }
|
|
620 else
|
|
621 {
|
|
622 gw->gauge.selected = TRUE ;
|
|
623 gw->gauge.selstr = (String)XtMalloc(4*sizeof(int)) ;
|
|
624 sprintf(gw->gauge.selstr, "%d", gw->gauge.value) ;
|
|
625 GaugeExpose(w,0,0) ;
|
|
626 }
|
|
627 }
|
|
628
|
|
629
|
|
630 static Boolean
|
|
631 GaugeConvert (Widget w,
|
|
632 Atom *selection, /* usually XA_PRIMARY */
|
|
633 Atom *target, /* requested target */
|
|
634 Atom *type, /* returned type */
|
|
635 XtPointer *value, /* returned value */
|
458
|
636 unsigned long *length, /* returned length */
|
424
|
637 int *format) /* returned format */
|
|
638 {
|
|
639 GaugeWidget gw = (GaugeWidget)w ;
|
|
640 XSelectionRequestEvent *req ;
|
|
641
|
|
642 printf( "requesting selection %s:%s\n",
|
|
643 XGetAtomName(XtDisplay(w),*selection),
|
|
644 XGetAtomName(XtDisplay(w),*target));
|
|
645
|
|
646 #ifdef HAVE_XMU
|
|
647 if( *target == XA_TARGETS(XtDisplay(w)) )
|
|
648 {
|
2271
|
649 XPointer stdTargets;
|
|
650 Atom *rval ;
|
458
|
651 unsigned long stdLength ;
|
424
|
652
|
|
653 /* XmuConvertStandardSelection can handle this. This function
|
|
654 * will return a list of standard targets. We prepend TEXT,
|
|
655 * STRING and INTEGER to the list and return it.
|
|
656 */
|
|
657
|
|
658 req = XtGetSelectionRequest(w, *selection, NULL) ;
|
|
659 XmuConvertStandardSelection(w, req->time, selection, target,
|
2271
|
660 type, &stdTargets, &stdLength, format) ;
|
424
|
661
|
|
662 *type = XA_ATOM ; /* TODO: needed? */
|
|
663 *length = stdLength + 3 ;
|
|
664 rval = (Atom *) XtMalloc(sizeof(Atom)*(stdLength+3)) ;
|
|
665 *value = (XtPointer) rval ;
|
|
666 *rval++ = XA_INTEGER ;
|
|
667 *rval++ = XA_STRING ;
|
|
668 *rval++ = XA_TEXT(XtDisplay(w)) ;
|
2271
|
669 memcpy(rval, stdTargets, stdLength*sizeof(Atom)) ;
|
424
|
670 XtFree((char*) stdTargets) ;
|
|
671 *format = 8*sizeof(Atom) ; /* TODO: needed? */
|
|
672 return True ;
|
|
673 }
|
|
674
|
442
|
675 else
|
424
|
676 #endif
|
|
677 if( *target == XA_INTEGER )
|
|
678 {
|
|
679 *type = XA_INTEGER ;
|
|
680 *length = 1 ;
|
|
681 *value = (XtPointer) &gw->gauge.value ;
|
|
682 *format = 8*sizeof(int) ;
|
|
683 return True ;
|
|
684 }
|
|
685
|
442
|
686 else if( *target == XA_STRING
|
424
|
687 #ifdef HAVE_XMU
|
442
|
688 ||
|
|
689 *target == XA_TEXT(XtDisplay(w))
|
424
|
690 #endif
|
|
691 )
|
|
692 {
|
|
693 *type = *target ;
|
|
694 *length = strlen(gw->gauge.selstr)*sizeof(char) ;
|
|
695 *value = (XtPointer) gw->gauge.selstr ;
|
|
696 *format = 8 ;
|
|
697 return True ;
|
|
698 }
|
|
699
|
|
700 else
|
|
701 {
|
|
702 /* anything else, we just give it to XmuConvertStandardSelection() */
|
|
703 #ifdef HAVE_XMU
|
|
704 req = XtGetSelectionRequest(w, *selection, NULL) ;
|
|
705 if( XmuConvertStandardSelection(w, req->time, selection, target,
|
|
706 type, (XPointer *) value, length, format) )
|
|
707 return True ;
|
442
|
708 else
|
424
|
709 #endif
|
|
710 {
|
|
711 printf(
|
|
712 "Gauge: requestor is requesting unsupported selection %s:%s\n",
|
|
713 XGetAtomName(XtDisplay(w),*selection),
|
|
714 XGetAtomName(XtDisplay(w),*target));
|
|
715 return False ;
|
|
716 }
|
|
717 }
|
|
718 }
|
|
719
|
|
720
|
|
721
|
|
722 static void
|
|
723 GaugeLoseSel (Widget w,
|
2286
|
724 Atom *UNUSED (selection)) /* usually XA_PRIMARY */
|
424
|
725 {
|
|
726 GaugeWidget gw = (GaugeWidget)w ;
|
|
727 Display *dpy = XtDisplay(w) ;
|
|
728 Window win = XtWindow(w) ;
|
|
729
|
|
730 if( gw->gauge.selstr != NULL ) {
|
|
731 XtFree(gw->gauge.selstr) ;
|
|
732 gw->gauge.selstr = NULL ;
|
|
733 }
|
|
734
|
|
735 gw->gauge.selected = False ;
|
|
736 XClearWindow(dpy,win) ;
|
|
737 GaugeExpose(w,0,0) ;
|
|
738 }
|
|
739
|
|
740
|
|
741 static void
|
2286
|
742 GaugeDoneSel (Widget UNUSED (w),
|
|
743 Atom *UNUSED (selection), /* usually XA_PRIMARY */
|
|
744 Atom *UNUSED (target)) /* requested target */
|
424
|
745 {
|
|
746 /* selection done, anything to do? */
|
|
747 }
|
|
748
|
|
749
|
|
750 static void
|
|
751 GaugePaste (Widget w,
|
|
752 XEvent *event,
|
|
753 String *params,
|
|
754 Cardinal *num_params)
|
|
755 {
|
|
756 Atom seln = XA_PRIMARY ;
|
|
757
|
|
758 if( *num_params > 0 ) {
|
|
759 seln = XInternAtom(XtDisplay(w), params[0], False) ;
|
|
760 printf("atom %s is %ld\n", params[0], seln) ;
|
|
761 }
|
|
762
|
|
763 /* try for integer value first */
|
|
764 XtGetSelectionValue(w, seln, XA_INTEGER,
|
|
765 GaugeGetSelCB, (XtPointer)XA_INTEGER,
|
|
766 event->xbutton.time) ;
|
|
767 }
|
|
768
|
|
769 static void
|
|
770 GaugeGetSelCB (Widget w,
|
|
771 XtPointer client,
|
|
772 Atom *selection,
|
|
773 Atom *type,
|
|
774 XtPointer value,
|
2286
|
775 unsigned long *UNUSED (length),
|
|
776 int *UNUSED (format))
|
424
|
777 {
|
|
778 Display *dpy = XtDisplay(w) ;
|
|
779 Atom target = (Atom)client ;
|
|
780 int *iptr ;
|
|
781 char *cptr ;
|
|
782
|
|
783 if( *type == XA_INTEGER ) {
|
|
784 iptr = (int *)value ;
|
|
785 XawGaugeSetValue(w, *iptr) ;
|
|
786 }
|
|
787
|
442
|
788 else if( *type == XA_STRING
|
424
|
789 #ifdef HAVE_XMU
|
|
790 ||
|
442
|
791 *type == XA_TEXT(dpy)
|
424
|
792 #endif
|
442
|
793 )
|
424
|
794 {
|
|
795 cptr = (char *)value ;
|
|
796 XawGaugeSetValue(w, atoi(cptr)) ;
|
|
797 }
|
|
798
|
|
799 /* failed, try string */
|
|
800 else if( *type == None && target == XA_INTEGER )
|
|
801 XtGetSelectionValue(w, *selection, XA_STRING,
|
|
802 GaugeGetSelCB, (XtPointer)XA_STRING,
|
|
803 CurrentTime) ;
|
|
804 }
|
|
805
|
|
806
|
|
807
|
|
808 /****************************************************************
|
|
809 *
|
|
810 * Public Procedures
|
|
811 *
|
|
812 ****************************************************************/
|
|
813
|
|
814
|
|
815 /* Change gauge value. Only undraw or draw what needs to be
|
|
816 * changed.
|
|
817 */
|
|
818
|
|
819 void
|
|
820 XawGaugeSetValue (Widget w,
|
|
821 Cardinal value)
|
|
822 {
|
|
823 GaugeWidget gw = (GaugeWidget)w ;
|
|
824 int oldvalue ;
|
|
825 GC gc ;
|
|
826
|
|
827 if( gw->gauge.selected != None ) {
|
|
828 XtDisownSelection(w, gw->gauge.selected, CurrentTime) ;
|
|
829 gw->gauge.selected = None ;
|
|
830 }
|
|
831
|
|
832 if( !XtIsRealized(w) ) {
|
|
833 gw->gauge.value = value ;
|
|
834 return ;
|
|
835 }
|
|
836
|
|
837 /* need to rescale? */
|
647
|
838 if(( gw->gauge.autoScaleUp && (int) value > gw->gauge.v1) ||
|
|
839 (gw->gauge.autoScaleDown && (int) value < gw->gauge.v1/3 ))
|
424
|
840 {
|
|
841 XtVaSetValues(w, XtNvalue, value, 0) ;
|
|
842 return ;
|
|
843 }
|
|
844
|
|
845 oldvalue = gw->gauge.value ;
|
|
846 gw->gauge.value = value ;
|
|
847
|
|
848 gc = XtIsSensitive(w) ? gw->label.normal_GC : gw->label.gray_GC ;
|
|
849 GaugeMercury(XtDisplay(w), XtWindow(w), gc, gw, oldvalue,value) ;
|
|
850 }
|
|
851
|
|
852
|
|
853 Cardinal
|
|
854 XawGaugeGetValue (Widget w)
|
|
855 {
|
|
856 GaugeWidget gw = (GaugeWidget)w ;
|
|
857 return gw->gauge.value ;
|
|
858 }
|
|
859
|
|
860
|
|
861
|
|
862
|
|
863 /****************************************************************
|
|
864 *
|
|
865 * Private Procedures
|
|
866 *
|
|
867 ****************************************************************/
|
|
868
|
|
869 /* draw the mercury over a specific region */
|
|
870
|
|
871 static void
|
|
872 GaugeMercury (Display *dpy,
|
|
873 Window win,
|
|
874 GC gc,
|
|
875 GaugeWidget gw,
|
|
876 Cardinal val0,
|
|
877 Cardinal val1)
|
|
878 {
|
|
879 int v0 = gw->gauge.v0 ;
|
|
880 int v1 = gw->gauge.v1 ;
|
|
881 int vd = v1 - v0 ;
|
|
882 Dimension len ; /* length (width or height) of gauge */
|
|
883 Position e0, e1 ; /* gauge ends */
|
|
884 Position p0, p1 ; /* mercury ends */
|
|
885 int y ; /* vertical (horizontal) position */
|
|
886 Boolean undraw = FALSE ;
|
|
887
|
|
888 len = gw->gauge.orientation == XtorientHorizontal ?
|
|
889 gw->core.width : gw->core.height ;
|
|
890
|
|
891 e0 = gw->gauge.margin0 ; /* left (top) end */
|
|
892 e1 = len - gw->gauge.margin1 -1 ; /* right (bottom) end */
|
|
893
|
|
894 if( vd <= 0 ) vd = 1 ;
|
|
895
|
647
|
896 if( (int) val0 < v0 ) val0 = v0 ;
|
|
897 else if( (int) val0 > v1 ) val0 = v1 ;
|
|
898 if( (int) val1 < v0 ) val1 = v0 ;
|
|
899 else if( (int) val1 > v1 ) val1 = v1 ;
|
424
|
900
|
|
901 p0 = (val0-v0)*(e1-e0-1)/vd ;
|
|
902 p1 = (val1-v0)*(e1-e0-1)/vd ;
|
|
903
|
|
904 if( p1 == p0 )
|
|
905 return ;
|
|
906
|
|
907 y = gw->gauge.gmargin ;
|
|
908
|
|
909 if( p1 < p0 )
|
|
910 {
|
|
911 Position tmp = p0 ;
|
|
912 p0 = p1 ;
|
|
913 p1 = tmp ;
|
|
914 gc = gw->label.normal_GC ;
|
|
915 XSetForeground(dpy,gc, gw->core.background_pixel) ;
|
|
916 undraw = TRUE ;
|
|
917 }
|
|
918
|
|
919 if( gw->gauge.orientation == XtorientHorizontal )
|
|
920 XFillRectangle(dpy,win,gc, e0+p0+1,y+1, p1-p0,GA_WID) ;
|
|
921 else
|
|
922 XFillRectangle(dpy,win,gc, y+1,e1-p1, GA_WID,p1-p0) ;
|
|
923
|
|
924 if( undraw )
|
|
925 XSetForeground(dpy,gc, gw->label.foreground) ;
|
|
926 }
|
|
927
|
|
928
|
|
929
|
|
930 /* Search the labels, find the largest one. */
|
|
931 /* TODO: handle vertical fonts? */
|
|
932
|
|
933 static void
|
|
934 MaxLabel (GaugeWidget gw,
|
|
935 Dimension *wid, /* max label width */
|
|
936 Dimension *hgt, /* max label height */
|
|
937 Dimension *w0, /* width of first label */
|
|
938 Dimension *w1) /* width of last label */
|
|
939 {
|
|
940 char lstr[80], *lbl ;
|
|
941 int w ;
|
|
942 XFontStruct *font = gw->label.font ;
|
|
943 int i ;
|
|
944 int lw = 0;
|
|
945 int v0 = gw->gauge.v0 ;
|
|
946 int dv = gw->gauge.v1 - v0 ;
|
|
947 int n = gw->gauge.nlabels ;
|
|
948
|
|
949 if( n > 0 )
|
|
950 {
|
|
951 if( --n <= 0 ) {n = 1 ; v0 += dv/2 ;}
|
|
952
|
|
953 /* loop through all labels, figure out how much room they
|
|
954 * need.
|
|
955 */
|
|
956 w = 0 ;
|
|
957 for(i=0; i<gw->gauge.nlabels; ++i)
|
|
958 {
|
|
959 if( gw->gauge.labels == NULL ) /* numeric labels */
|
|
960 sprintf(lbl = lstr,"%d", v0 + i*dv/n) ;
|
|
961 else
|
|
962 lbl = gw->gauge.labels[i] ;
|
|
963
|
|
964 if( lbl != NULL ) {
|
|
965 lw = XTextWidth(font, lbl, strlen(lbl)) ;
|
|
966 w = Max( w, lw ) ;
|
|
967 }
|
|
968 else
|
|
969 lw = 0 ;
|
|
970
|
|
971 if( i == 0 && w0 != NULL ) *w0 = lw ;
|
|
972 }
|
|
973 if( w1 != NULL ) *w1 = lw ;
|
|
974
|
|
975 *wid = w ;
|
|
976 *hgt = font->max_bounds.ascent + font->max_bounds.descent ;
|
|
977 }
|
|
978 else
|
|
979 *wid = *hgt = 0 ;
|
|
980 }
|
|
981
|
|
982
|
|
983 /* Determine the preferred size for this widget. choose 100x100 for
|
|
984 * debugging.
|
|
985 */
|
|
986
|
|
987 static void
|
|
988 GaugeSize (GaugeWidget gw,
|
|
989 Dimension *wid,
|
|
990 Dimension *hgt,
|
|
991 Dimension min_len)
|
|
992 {
|
|
993 int w,h ; /* width, height of gauge */
|
|
994 int vmargin ; /* vertical margin */
|
|
995 int hmargin ; /* horizontal margin */
|
|
996
|
|
997 hmargin = gw->label.internal_width ;
|
|
998 vmargin = gw->label.internal_height ;
|
|
999
|
|
1000 /* find total height (width) of contents */
|
|
1001
|
|
1002
|
|
1003 /* find minimum size for undecorated gauge */
|
|
1004
|
|
1005 if( gw->gauge.orientation == XtorientHorizontal )
|
|
1006 {
|
|
1007 w = min_len ;
|
|
1008 h = GA_WID+2 ; /* gauge itself + edges */
|
|
1009 }
|
|
1010 else
|
|
1011 {
|
|
1012 w = GA_WID+2 ;
|
|
1013 h = min_len ;
|
|
1014 }
|
|
1015
|
|
1016 if( gw->gauge.ntics > 0 )
|
|
1017 {
|
|
1018 if( gw->gauge.orientation == XtorientHorizontal )
|
|
1019 {
|
|
1020 w = Max(w, gw->gauge.ntics*3) ;
|
|
1021 h += vmargin + TIC_LEN ;
|
|
1022 }
|
|
1023 else
|
|
1024 {
|
|
1025 w += hmargin + TIC_LEN ;
|
|
1026 h = Max(h, gw->gauge.ntics*3) ;
|
|
1027 }
|
|
1028 }
|
|
1029
|
|
1030
|
|
1031 /* If labels are requested, this gets a little interesting.
|
|
1032 * We want the end labels centered on the ends of the gauge and
|
|
1033 * the centers of the labels evenly spaced. The labels at the ends
|
|
1034 * will not be the same width, meaning that the gauge itself need
|
|
1035 * not be centered in the widget.
|
|
1036 *
|
|
1037 * First, determine the spacing. This is the width of the widest
|
|
1038 * label, plus the internal margin. Total length of the gauge is
|
|
1039 * spacing * (nlabels-1). To this, we add half the width of the
|
|
1040 * left-most label and half the width of the right-most label
|
|
1041 * to get the entire desired width of the widget.
|
|
1042 */
|
|
1043 if( gw->gauge.nlabels > 0 )
|
|
1044 {
|
|
1045 Dimension lwm, lw0, lw1 ; /* width of max, left, right labels */
|
|
1046 Dimension lh ;
|
|
1047
|
|
1048 MaxLabel(gw,&lwm,&lh, &lw0,&lw1) ;
|
|
1049
|
|
1050 if( gw->gauge.orientation == XtorientHorizontal )
|
|
1051 {
|
|
1052 lwm = (lwm+hmargin) * (gw->gauge.nlabels-1) + (lw0+lw1)/2 ;
|
|
1053 w = Max(w, lwm) ;
|
|
1054 h += lh + vmargin ;
|
|
1055 }
|
|
1056 else
|
|
1057 {
|
|
1058 lh = lh*gw->gauge.nlabels + (gw->gauge.nlabels - 1)*vmargin ;
|
|
1059 h = Max(h, lh) ;
|
|
1060 w += lwm + hmargin ;
|
|
1061 }
|
|
1062 }
|
|
1063
|
|
1064 w += hmargin*2 ;
|
|
1065 h += vmargin*2 ;
|
|
1066
|
|
1067 *wid = w ;
|
|
1068 *hgt = h ;
|
|
1069 }
|
|
1070
|
|
1071
|
|
1072
|
|
1073 static void
|
|
1074 AutoScale (GaugeWidget gw)
|
|
1075 {
|
|
1076 static int scales[3] = {1,2,5} ;
|
|
1077 int sptr = 0, smult=1 ;
|
|
1078
|
|
1079 if( gw->gauge.autoScaleDown )
|
|
1080 gw->gauge.v1 = 0 ;
|
|
1081 while( gw->gauge.value > gw->gauge.v1 )
|
|
1082 {
|
|
1083 if( ++sptr > 2 ) {
|
|
1084 sptr = 0 ;
|
|
1085 smult *= 10 ;
|
|
1086 }
|
|
1087 gw->gauge.v1 = scales[sptr] * smult ;
|
|
1088 }
|
|
1089 }
|
|
1090
|
|
1091 static void
|
|
1092 EnableUpdate (GaugeWidget gw)
|
|
1093 {
|
|
1094 gw->gauge.intervalId =
|
|
1095 XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)gw),
|
|
1096 gw->gauge.update * MS_PER_SEC, GaugeGetValue,
|
|
1097 (XtPointer)gw) ;
|
|
1098 }
|
|
1099
|
|
1100 static void
|
|
1101 DisableUpdate (GaugeWidget gw)
|
|
1102 {
|
|
1103 XtRemoveTimeOut(gw->gauge.intervalId) ;
|
|
1104 }
|
|
1105
|
|
1106 static void
|
|
1107 GaugeGetValue (XtPointer clientData,
|
2286
|
1108 XtIntervalId *UNUSED (intervalId))
|
424
|
1109 {
|
|
1110 GaugeWidget gw = (GaugeWidget)clientData ;
|
|
1111 Cardinal value ;
|
|
1112
|
|
1113 if( gw->gauge.update > 0 )
|
|
1114 EnableUpdate(gw) ;
|
|
1115
|
|
1116 if( gw->gauge.getValue != NULL )
|
|
1117 {
|
|
1118 XtCallCallbackList((Widget)gw, gw->gauge.getValue, (XtPointer)&value);
|
|
1119 XawGaugeSetValue((Widget)gw, value) ;
|
|
1120 }
|
|
1121 }
|
|
1122
|
|
1123
|
|
1124 static GC
|
|
1125 Get_GC (GaugeWidget gw,
|
|
1126 Pixel fg)
|
|
1127 {
|
|
1128 XGCValues values ;
|
|
1129 #define vmask GCForeground
|
|
1130 #define umask (GCBackground|GCSubwindowMode|GCGraphicsExposures|GCDashOffset\
|
|
1131 |GCFont|GCDashList|GCArcMode)
|
|
1132
|
|
1133 values.foreground = fg ;
|
|
1134
|
|
1135 return XtAllocateGC((Widget)gw, 0, vmask, &values, 0L, umask) ;
|
|
1136 }
|