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,
|
|
244 ArgList args,
|
|
245 Cardinal *num_args)
|
|
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,
|
|
369 XEvent *event,
|
|
370 Region region)
|
|
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 hgt ; /* height (width) of widget */
|
|
380 int e0,e1 ; /* ends of the gauge */
|
|
381 int x ;
|
|
382 int y ; /* vertical (horizontal) position */
|
|
383 int i ;
|
|
384 int v0 = gw->gauge.v0 ;
|
|
385 int v1 = gw->gauge.v1 ;
|
|
386 int value = gw->gauge.value ;
|
|
387
|
|
388 gc = XtIsSensitive(w) ? gw->label.normal_GC : gw->label.gray_GC ;
|
|
389
|
|
390
|
|
391 #ifdef _ThreeDP_h
|
|
392 gctop = gw->threeD.bot_shadow_GC ;
|
|
393 gcbot = gw->threeD.top_shadow_GC ;
|
|
394 #else
|
|
395 gctop = gcbot = gc ;
|
|
396 #endif
|
|
397
|
|
398 if( gw->gauge.orientation == XtorientHorizontal ) {
|
|
399 len = gw->core.width ;
|
|
400 hgt = gw->core.height ;
|
|
401 } else {
|
|
402 len = gw->core.height ;
|
|
403 hgt = gw->core.width ;
|
|
404 }
|
|
405
|
|
406 /* if the gauge is selected, signify by drawing the background
|
442
|
407 * in a contrasting color.
|
424
|
408 */
|
|
409
|
|
410 if( gw->gauge.selected )
|
|
411 {
|
|
412 XFillRectangle(dpy,win, gc, 0,0, w->core.width,w->core.height) ;
|
|
413 gc = gw->gauge.inverse_GC ;
|
|
414 }
|
|
415
|
|
416 e0 = gw->gauge.margin0 ; /* left (top) end */
|
|
417 e1 = len - gw->gauge.margin1 -1 ; /* right (bottom) end */
|
|
418
|
|
419 /* Draw the Gauge itself */
|
|
420
|
|
421 y = gw->gauge.gmargin ;
|
|
422
|
|
423 if( gw->gauge.orientation == XtorientHorizontal ) /* horizontal */
|
|
424 {
|
|
425 XDrawLine(dpy,win,gctop, e0+1,y, e1-1,y) ;
|
|
426 XDrawLine(dpy,win,gctop, e0,y+1, e0,y+GA_WID) ;
|
|
427 XDrawLine(dpy,win,gcbot, e0+1, y+GA_WID+1, e1-1, y+GA_WID+1) ;
|
|
428 XDrawLine(dpy,win,gcbot, e1,y+1, e1,y+GA_WID) ;
|
|
429 }
|
|
430 else /* vertical */
|
|
431 {
|
|
432 XDrawLine(dpy,win,gctop, y,e0+1, y,e1-1) ;
|
|
433 XDrawLine(dpy,win,gctop, y+1,e0, y+GA_WID,e0) ;
|
|
434 XDrawLine(dpy,win,gcbot, y+GA_WID+1,e0+1, y+GA_WID+1, e1-1) ;
|
|
435 XDrawLine(dpy,win,gcbot, y+1,e1, y+GA_WID,e1) ;
|
|
436 }
|
|
437
|
|
438
|
|
439 /* draw the mercury */
|
|
440
|
|
441 GaugeMercury(dpy, win, gc, gw, 0,value) ;
|
|
442
|
|
443
|
|
444 if( gw->gauge.ntics > 1 )
|
|
445 {
|
|
446 y = gw->gauge.tmargin ;
|
|
447 for(i=0; i<gw->gauge.ntics; ++i)
|
|
448 {
|
|
449 x = e0 + i*(e1-e0-1)/(gw->gauge.ntics-1) ;
|
|
450 if( gw->gauge.orientation == XtorientHorizontal ) {
|
|
451 XDrawLine(dpy,win,gcbot, x,y+1, x,y+TIC_LEN-2) ;
|
|
452 XDrawLine(dpy,win,gcbot, x,y, x+1,y) ;
|
|
453 XDrawLine(dpy,win,gctop, x+1,y+1, x+1,y+TIC_LEN-2) ;
|
|
454 XDrawLine(dpy,win,gctop, x,y+TIC_LEN-1, x+1,y+TIC_LEN-1) ;
|
|
455 }
|
|
456 else {
|
|
457 XDrawLine(dpy,win,gcbot, y+1,x, y+TIC_LEN-2,x) ;
|
|
458 XDrawLine(dpy,win,gcbot, y,x, y,x+1) ;
|
|
459 XDrawLine(dpy,win,gctop, y+1,x+1, y+TIC_LEN-2,x+1) ;
|
|
460 XDrawLine(dpy,win,gctop, y+TIC_LEN-1,x, y+TIC_LEN-1,x+1) ;
|
|
461 }
|
|
462 }
|
|
463 }
|
|
464
|
|
465 /* draw labels */
|
|
466 if( gw->gauge.nlabels > 1 )
|
|
467 {
|
|
468 char label[20], *s = label ;
|
442
|
469 int xlen, wd,h =0 ;
|
424
|
470
|
|
471 if( gw->gauge.orientation == XtorientHorizontal )
|
|
472 y = gw->gauge.lmargin + gw->label.font->max_bounds.ascent - 1 ;
|
|
473 else {
|
|
474 y = gw->gauge.lmargin ;
|
|
475 h = gw->label.font->max_bounds.ascent / 2 ;
|
|
476 }
|
|
477
|
|
478 for(i=0; i<gw->gauge.nlabels; ++i)
|
|
479 {
|
|
480 if( gw->gauge.labels == NULL )
|
|
481 sprintf(label, "%d", v0+i*(v1 - v0)/(gw->gauge.nlabels - 1)) ;
|
|
482 else
|
|
483 s = gw->gauge.labels[i] ;
|
|
484 if( s != NULL ) {
|
|
485 x = e0 + i*(e1-e0-1)/(gw->gauge.nlabels-1) ;
|
442
|
486 xlen = strlen(s) ;
|
424
|
487 if( gw->gauge.orientation == XtorientHorizontal ) {
|
442
|
488 wd = XTextWidth(gw->label.font, s, xlen) ;
|
|
489 XDrawString(dpy,win,gc, x-wd/2,y, s,xlen) ;
|
424
|
490 }
|
|
491 else {
|
442
|
492 XDrawString(dpy,win,gc, y,x+h, s,xlen) ;
|
424
|
493 }
|
|
494 }
|
|
495 }
|
|
496 }
|
|
497 }
|
|
498
|
|
499
|
|
500 /*
|
|
501 * Set specified arguments into widget
|
|
502 */
|
|
503
|
|
504 static Boolean
|
|
505 GaugeSetValues (Widget old,
|
|
506 Widget request,
|
|
507 Widget new,
|
|
508 ArgList args,
|
|
509 Cardinal *num_args)
|
|
510 {
|
|
511 GaugeWidget oldgw = (GaugeWidget) old;
|
|
512 GaugeWidget gw = (GaugeWidget) new;
|
|
513 Boolean was_resized = False;
|
|
514
|
|
515 if( gw->gauge.selected != None ) {
|
|
516 XtDisownSelection(new, gw->gauge.selected, CurrentTime) ;
|
|
517 gw->gauge.selected = None ;
|
|
518 }
|
|
519
|
|
520 /* Changes to v0,v1,labels, ntics, nlabels require resize & redraw. */
|
|
521 /* Change to value requires redraw and possible resize if autoscale */
|
|
522
|
|
523 was_resized =
|
|
524 gw->gauge.v0 != oldgw->gauge.v0 ||
|
|
525 gw->gauge.v1 != oldgw->gauge.v1 ||
|
|
526 gw->gauge.ntics != oldgw->gauge.ntics ||
|
|
527 gw->gauge.nlabels != oldgw->gauge.nlabels ||
|
|
528 gw->gauge.labels != oldgw->gauge.labels ;
|
|
529
|
|
530 if( (gw->gauge.autoScaleUp && gw->gauge.value > gw->gauge.v1) ||
|
|
531 (gw->gauge.autoScaleDown && gw->gauge.value < gw->gauge.v1/3 ))
|
|
532 {
|
|
533 AutoScale(gw) ;
|
|
534 was_resized = TRUE ;
|
|
535 }
|
|
536
|
|
537 if( was_resized ) {
|
|
538 if( gw->label.resize )
|
|
539 GaugeSize(gw, &gw->core.width, &gw->core.height, DEF_LEN) ;
|
|
540 else
|
|
541 GaugeResize(new) ;
|
|
542 }
|
442
|
543
|
424
|
544 if( gw->gauge.update != oldgw->gauge.update )
|
|
545 {
|
|
546 if( gw->gauge.update > 0 )
|
|
547 EnableUpdate(gw) ;
|
|
548 else
|
|
549 DisableUpdate(gw) ;
|
|
550 }
|
|
551
|
|
552 if( gw->core.background_pixel != oldgw->core.background_pixel )
|
|
553 {
|
|
554 XtReleaseGC(new, gw->gauge.inverse_GC) ;
|
|
555 gw->gauge.inverse_GC = Get_GC(gw, gw->core.background_pixel) ;
|
|
556 }
|
|
557
|
|
558 return was_resized || gw->gauge.value != oldgw->gauge.value ||
|
|
559 XtIsSensitive(old) != XtIsSensitive(new);
|
|
560 }
|
|
561
|
|
562
|
|
563 static XtGeometryResult
|
|
564 GaugeQueryGeometry (Widget w,
|
|
565 XtWidgetGeometry *intended,
|
|
566 XtWidgetGeometry *preferred)
|
|
567 {
|
|
568 register GaugeWidget gw = (GaugeWidget)w;
|
|
569
|
|
570 if( intended->width == w->core.width &&
|
|
571 intended->height == w->core.height )
|
|
572 return XtGeometryNo ;
|
|
573
|
|
574 preferred->request_mode = CWWidth | CWHeight;
|
|
575 GaugeSize(gw, &preferred->width, &preferred->height, DEF_LEN) ;
|
|
576
|
|
577 if( (!(intended->request_mode & CWWidth) ||
|
|
578 intended->width >= preferred->width) &&
|
|
579 (!(intended->request_mode & CWHeight) ||
|
|
580 intended->height >= preferred->height) )
|
|
581 return XtGeometryYes;
|
|
582 else
|
|
583 return XtGeometryAlmost;
|
|
584 }
|
|
585
|
|
586
|
|
587
|
|
588
|
|
589 /****************************************************************
|
|
590 *
|
|
591 * Action Procedures
|
|
592 *
|
|
593 ****************************************************************/
|
|
594
|
|
595 static void
|
|
596 GaugeSelect (Widget w,
|
|
597 XEvent *event,
|
|
598 String *params,
|
|
599 Cardinal *num_params)
|
|
600 {
|
|
601 GaugeWidget gw = (GaugeWidget)w ;
|
|
602 Atom seln = XA_PRIMARY ;
|
|
603
|
|
604 if( gw->gauge.selected != None ) {
|
|
605 XtDisownSelection(w, gw->gauge.selected, CurrentTime) ;
|
|
606 gw->gauge.selected = None ;
|
|
607 }
|
|
608
|
|
609 if( *num_params > 0 ) {
|
|
610 seln = XInternAtom(XtDisplay(w), params[0], False) ;
|
|
611 printf("atom %s is %ld\n", params[0], seln) ;
|
|
612 }
|
|
613
|
|
614 if( ! XtOwnSelection(w, seln, event->xbutton.time, GaugeConvert,
|
|
615 GaugeLoseSel, GaugeDoneSel) )
|
|
616 {
|
|
617 /* in real code, this error message would be replaced by
|
|
618 * something more elegant, or at least deleted
|
|
619 */
|
|
620
|
|
621 fprintf(stderr, "Gauge failed to get selection, try again\n") ;
|
|
622 }
|
|
623 else
|
|
624 {
|
|
625 gw->gauge.selected = TRUE ;
|
|
626 gw->gauge.selstr = (String)XtMalloc(4*sizeof(int)) ;
|
|
627 sprintf(gw->gauge.selstr, "%d", gw->gauge.value) ;
|
|
628 GaugeExpose(w,0,0) ;
|
|
629 }
|
|
630 }
|
|
631
|
|
632
|
|
633 static Boolean
|
|
634 GaugeConvert (Widget w,
|
|
635 Atom *selection, /* usually XA_PRIMARY */
|
|
636 Atom *target, /* requested target */
|
|
637 Atom *type, /* returned type */
|
|
638 XtPointer *value, /* returned value */
|
458
|
639 unsigned long *length, /* returned length */
|
424
|
640 int *format) /* returned format */
|
|
641 {
|
|
642 GaugeWidget gw = (GaugeWidget)w ;
|
|
643 XSelectionRequestEvent *req ;
|
|
644
|
|
645 printf( "requesting selection %s:%s\n",
|
|
646 XGetAtomName(XtDisplay(w),*selection),
|
|
647 XGetAtomName(XtDisplay(w),*target));
|
|
648
|
|
649 #ifdef HAVE_XMU
|
|
650 if( *target == XA_TARGETS(XtDisplay(w)) )
|
|
651 {
|
2271
|
652 XPointer stdTargets;
|
|
653 Atom *rval ;
|
458
|
654 unsigned long stdLength ;
|
424
|
655
|
|
656 /* XmuConvertStandardSelection can handle this. This function
|
|
657 * will return a list of standard targets. We prepend TEXT,
|
|
658 * STRING and INTEGER to the list and return it.
|
|
659 */
|
|
660
|
|
661 req = XtGetSelectionRequest(w, *selection, NULL) ;
|
|
662 XmuConvertStandardSelection(w, req->time, selection, target,
|
2271
|
663 type, &stdTargets, &stdLength, format) ;
|
424
|
664
|
|
665 *type = XA_ATOM ; /* TODO: needed? */
|
|
666 *length = stdLength + 3 ;
|
|
667 rval = (Atom *) XtMalloc(sizeof(Atom)*(stdLength+3)) ;
|
|
668 *value = (XtPointer) rval ;
|
|
669 *rval++ = XA_INTEGER ;
|
|
670 *rval++ = XA_STRING ;
|
|
671 *rval++ = XA_TEXT(XtDisplay(w)) ;
|
2271
|
672 memcpy(rval, stdTargets, stdLength*sizeof(Atom)) ;
|
424
|
673 XtFree((char*) stdTargets) ;
|
|
674 *format = 8*sizeof(Atom) ; /* TODO: needed? */
|
|
675 return True ;
|
|
676 }
|
|
677
|
442
|
678 else
|
424
|
679 #endif
|
|
680 if( *target == XA_INTEGER )
|
|
681 {
|
|
682 *type = XA_INTEGER ;
|
|
683 *length = 1 ;
|
|
684 *value = (XtPointer) &gw->gauge.value ;
|
|
685 *format = 8*sizeof(int) ;
|
|
686 return True ;
|
|
687 }
|
|
688
|
442
|
689 else if( *target == XA_STRING
|
424
|
690 #ifdef HAVE_XMU
|
442
|
691 ||
|
|
692 *target == XA_TEXT(XtDisplay(w))
|
424
|
693 #endif
|
|
694 )
|
|
695 {
|
|
696 *type = *target ;
|
|
697 *length = strlen(gw->gauge.selstr)*sizeof(char) ;
|
|
698 *value = (XtPointer) gw->gauge.selstr ;
|
|
699 *format = 8 ;
|
|
700 return True ;
|
|
701 }
|
|
702
|
|
703 else
|
|
704 {
|
|
705 /* anything else, we just give it to XmuConvertStandardSelection() */
|
|
706 #ifdef HAVE_XMU
|
|
707 req = XtGetSelectionRequest(w, *selection, NULL) ;
|
|
708 if( XmuConvertStandardSelection(w, req->time, selection, target,
|
|
709 type, (XPointer *) value, length, format) )
|
|
710 return True ;
|
442
|
711 else
|
424
|
712 #endif
|
|
713 {
|
|
714 printf(
|
|
715 "Gauge: requestor is requesting unsupported selection %s:%s\n",
|
|
716 XGetAtomName(XtDisplay(w),*selection),
|
|
717 XGetAtomName(XtDisplay(w),*target));
|
|
718 return False ;
|
|
719 }
|
|
720 }
|
|
721 }
|
|
722
|
|
723
|
|
724
|
|
725 static void
|
|
726 GaugeLoseSel (Widget w,
|
|
727 Atom *selection) /* usually XA_PRIMARY */
|
|
728 {
|
|
729 GaugeWidget gw = (GaugeWidget)w ;
|
|
730 Display *dpy = XtDisplay(w) ;
|
|
731 Window win = XtWindow(w) ;
|
|
732
|
|
733 if( gw->gauge.selstr != NULL ) {
|
|
734 XtFree(gw->gauge.selstr) ;
|
|
735 gw->gauge.selstr = NULL ;
|
|
736 }
|
|
737
|
|
738 gw->gauge.selected = False ;
|
|
739 XClearWindow(dpy,win) ;
|
|
740 GaugeExpose(w,0,0) ;
|
|
741 }
|
|
742
|
|
743
|
|
744 static void
|
|
745 GaugeDoneSel (Widget w,
|
|
746 Atom *selection, /* usually XA_PRIMARY */
|
|
747 Atom *target) /* requested target */
|
|
748 {
|
|
749 /* selection done, anything to do? */
|
|
750 }
|
|
751
|
|
752
|
|
753 static void
|
|
754 GaugePaste (Widget w,
|
|
755 XEvent *event,
|
|
756 String *params,
|
|
757 Cardinal *num_params)
|
|
758 {
|
|
759 Atom seln = XA_PRIMARY ;
|
|
760
|
|
761 if( *num_params > 0 ) {
|
|
762 seln = XInternAtom(XtDisplay(w), params[0], False) ;
|
|
763 printf("atom %s is %ld\n", params[0], seln) ;
|
|
764 }
|
|
765
|
|
766 /* try for integer value first */
|
|
767 XtGetSelectionValue(w, seln, XA_INTEGER,
|
|
768 GaugeGetSelCB, (XtPointer)XA_INTEGER,
|
|
769 event->xbutton.time) ;
|
|
770 }
|
|
771
|
|
772 static void
|
|
773 GaugeGetSelCB (Widget w,
|
|
774 XtPointer client,
|
|
775 Atom *selection,
|
|
776 Atom *type,
|
|
777 XtPointer value,
|
458
|
778 unsigned long *length,
|
424
|
779 int *format)
|
|
780 {
|
|
781 Display *dpy = XtDisplay(w) ;
|
|
782 Atom target = (Atom)client ;
|
|
783 int *iptr ;
|
|
784 char *cptr ;
|
|
785
|
|
786 if( *type == XA_INTEGER ) {
|
|
787 iptr = (int *)value ;
|
|
788 XawGaugeSetValue(w, *iptr) ;
|
|
789 }
|
|
790
|
442
|
791 else if( *type == XA_STRING
|
424
|
792 #ifdef HAVE_XMU
|
|
793 ||
|
442
|
794 *type == XA_TEXT(dpy)
|
424
|
795 #endif
|
442
|
796 )
|
424
|
797 {
|
|
798 cptr = (char *)value ;
|
|
799 XawGaugeSetValue(w, atoi(cptr)) ;
|
|
800 }
|
|
801
|
|
802 /* failed, try string */
|
|
803 else if( *type == None && target == XA_INTEGER )
|
|
804 XtGetSelectionValue(w, *selection, XA_STRING,
|
|
805 GaugeGetSelCB, (XtPointer)XA_STRING,
|
|
806 CurrentTime) ;
|
|
807 }
|
|
808
|
|
809
|
|
810
|
|
811 /****************************************************************
|
|
812 *
|
|
813 * Public Procedures
|
|
814 *
|
|
815 ****************************************************************/
|
|
816
|
|
817
|
|
818 /* Change gauge value. Only undraw or draw what needs to be
|
|
819 * changed.
|
|
820 */
|
|
821
|
|
822 void
|
|
823 XawGaugeSetValue (Widget w,
|
|
824 Cardinal value)
|
|
825 {
|
|
826 GaugeWidget gw = (GaugeWidget)w ;
|
|
827 int oldvalue ;
|
|
828 GC gc ;
|
|
829
|
|
830 if( gw->gauge.selected != None ) {
|
|
831 XtDisownSelection(w, gw->gauge.selected, CurrentTime) ;
|
|
832 gw->gauge.selected = None ;
|
|
833 }
|
|
834
|
|
835 if( !XtIsRealized(w) ) {
|
|
836 gw->gauge.value = value ;
|
|
837 return ;
|
|
838 }
|
|
839
|
|
840 /* need to rescale? */
|
647
|
841 if(( gw->gauge.autoScaleUp && (int) value > gw->gauge.v1) ||
|
|
842 (gw->gauge.autoScaleDown && (int) value < gw->gauge.v1/3 ))
|
424
|
843 {
|
|
844 XtVaSetValues(w, XtNvalue, value, 0) ;
|
|
845 return ;
|
|
846 }
|
|
847
|
|
848 oldvalue = gw->gauge.value ;
|
|
849 gw->gauge.value = value ;
|
|
850
|
|
851 gc = XtIsSensitive(w) ? gw->label.normal_GC : gw->label.gray_GC ;
|
|
852 GaugeMercury(XtDisplay(w), XtWindow(w), gc, gw, oldvalue,value) ;
|
|
853 }
|
|
854
|
|
855
|
|
856 Cardinal
|
|
857 XawGaugeGetValue (Widget w)
|
|
858 {
|
|
859 GaugeWidget gw = (GaugeWidget)w ;
|
|
860 return gw->gauge.value ;
|
|
861 }
|
|
862
|
|
863
|
|
864
|
|
865
|
|
866 /****************************************************************
|
|
867 *
|
|
868 * Private Procedures
|
|
869 *
|
|
870 ****************************************************************/
|
|
871
|
|
872 /* draw the mercury over a specific region */
|
|
873
|
|
874 static void
|
|
875 GaugeMercury (Display *dpy,
|
|
876 Window win,
|
|
877 GC gc,
|
|
878 GaugeWidget gw,
|
|
879 Cardinal val0,
|
|
880 Cardinal val1)
|
|
881 {
|
|
882 int v0 = gw->gauge.v0 ;
|
|
883 int v1 = gw->gauge.v1 ;
|
|
884 int vd = v1 - v0 ;
|
|
885 Dimension len ; /* length (width or height) of gauge */
|
|
886 Position e0, e1 ; /* gauge ends */
|
|
887 Position p0, p1 ; /* mercury ends */
|
|
888 int y ; /* vertical (horizontal) position */
|
|
889 Boolean undraw = FALSE ;
|
|
890
|
|
891 len = gw->gauge.orientation == XtorientHorizontal ?
|
|
892 gw->core.width : gw->core.height ;
|
|
893
|
|
894 e0 = gw->gauge.margin0 ; /* left (top) end */
|
|
895 e1 = len - gw->gauge.margin1 -1 ; /* right (bottom) end */
|
|
896
|
|
897 if( vd <= 0 ) vd = 1 ;
|
|
898
|
647
|
899 if( (int) val0 < v0 ) val0 = v0 ;
|
|
900 else if( (int) val0 > v1 ) val0 = v1 ;
|
|
901 if( (int) val1 < v0 ) val1 = v0 ;
|
|
902 else if( (int) val1 > v1 ) val1 = v1 ;
|
424
|
903
|
|
904 p0 = (val0-v0)*(e1-e0-1)/vd ;
|
|
905 p1 = (val1-v0)*(e1-e0-1)/vd ;
|
|
906
|
|
907 if( p1 == p0 )
|
|
908 return ;
|
|
909
|
|
910 y = gw->gauge.gmargin ;
|
|
911
|
|
912 if( p1 < p0 )
|
|
913 {
|
|
914 Position tmp = p0 ;
|
|
915 p0 = p1 ;
|
|
916 p1 = tmp ;
|
|
917 gc = gw->label.normal_GC ;
|
|
918 XSetForeground(dpy,gc, gw->core.background_pixel) ;
|
|
919 undraw = TRUE ;
|
|
920 }
|
|
921
|
|
922 if( gw->gauge.orientation == XtorientHorizontal )
|
|
923 XFillRectangle(dpy,win,gc, e0+p0+1,y+1, p1-p0,GA_WID) ;
|
|
924 else
|
|
925 XFillRectangle(dpy,win,gc, y+1,e1-p1, GA_WID,p1-p0) ;
|
|
926
|
|
927 if( undraw )
|
|
928 XSetForeground(dpy,gc, gw->label.foreground) ;
|
|
929 }
|
|
930
|
|
931
|
|
932
|
|
933 /* Search the labels, find the largest one. */
|
|
934 /* TODO: handle vertical fonts? */
|
|
935
|
|
936 static void
|
|
937 MaxLabel (GaugeWidget gw,
|
|
938 Dimension *wid, /* max label width */
|
|
939 Dimension *hgt, /* max label height */
|
|
940 Dimension *w0, /* width of first label */
|
|
941 Dimension *w1) /* width of last label */
|
|
942 {
|
|
943 char lstr[80], *lbl ;
|
|
944 int w ;
|
|
945 XFontStruct *font = gw->label.font ;
|
|
946 int i ;
|
|
947 int lw = 0;
|
|
948 int v0 = gw->gauge.v0 ;
|
|
949 int dv = gw->gauge.v1 - v0 ;
|
|
950 int n = gw->gauge.nlabels ;
|
|
951
|
|
952 if( n > 0 )
|
|
953 {
|
|
954 if( --n <= 0 ) {n = 1 ; v0 += dv/2 ;}
|
|
955
|
|
956 /* loop through all labels, figure out how much room they
|
|
957 * need.
|
|
958 */
|
|
959 w = 0 ;
|
|
960 for(i=0; i<gw->gauge.nlabels; ++i)
|
|
961 {
|
|
962 if( gw->gauge.labels == NULL ) /* numeric labels */
|
|
963 sprintf(lbl = lstr,"%d", v0 + i*dv/n) ;
|
|
964 else
|
|
965 lbl = gw->gauge.labels[i] ;
|
|
966
|
|
967 if( lbl != NULL ) {
|
|
968 lw = XTextWidth(font, lbl, strlen(lbl)) ;
|
|
969 w = Max( w, lw ) ;
|
|
970 }
|
|
971 else
|
|
972 lw = 0 ;
|
|
973
|
|
974 if( i == 0 && w0 != NULL ) *w0 = lw ;
|
|
975 }
|
|
976 if( w1 != NULL ) *w1 = lw ;
|
|
977
|
|
978 *wid = w ;
|
|
979 *hgt = font->max_bounds.ascent + font->max_bounds.descent ;
|
|
980 }
|
|
981 else
|
|
982 *wid = *hgt = 0 ;
|
|
983 }
|
|
984
|
|
985
|
|
986 /* Determine the preferred size for this widget. choose 100x100 for
|
|
987 * debugging.
|
|
988 */
|
|
989
|
|
990 static void
|
|
991 GaugeSize (GaugeWidget gw,
|
|
992 Dimension *wid,
|
|
993 Dimension *hgt,
|
|
994 Dimension min_len)
|
|
995 {
|
|
996 int w,h ; /* width, height of gauge */
|
|
997 int vmargin ; /* vertical margin */
|
|
998 int hmargin ; /* horizontal margin */
|
|
999
|
|
1000 hmargin = gw->label.internal_width ;
|
|
1001 vmargin = gw->label.internal_height ;
|
|
1002
|
|
1003 /* find total height (width) of contents */
|
|
1004
|
|
1005
|
|
1006 /* find minimum size for undecorated gauge */
|
|
1007
|
|
1008 if( gw->gauge.orientation == XtorientHorizontal )
|
|
1009 {
|
|
1010 w = min_len ;
|
|
1011 h = GA_WID+2 ; /* gauge itself + edges */
|
|
1012 }
|
|
1013 else
|
|
1014 {
|
|
1015 w = GA_WID+2 ;
|
|
1016 h = min_len ;
|
|
1017 }
|
|
1018
|
|
1019 if( gw->gauge.ntics > 0 )
|
|
1020 {
|
|
1021 if( gw->gauge.orientation == XtorientHorizontal )
|
|
1022 {
|
|
1023 w = Max(w, gw->gauge.ntics*3) ;
|
|
1024 h += vmargin + TIC_LEN ;
|
|
1025 }
|
|
1026 else
|
|
1027 {
|
|
1028 w += hmargin + TIC_LEN ;
|
|
1029 h = Max(h, gw->gauge.ntics*3) ;
|
|
1030 }
|
|
1031 }
|
|
1032
|
|
1033
|
|
1034 /* If labels are requested, this gets a little interesting.
|
|
1035 * We want the end labels centered on the ends of the gauge and
|
|
1036 * the centers of the labels evenly spaced. The labels at the ends
|
|
1037 * will not be the same width, meaning that the gauge itself need
|
|
1038 * not be centered in the widget.
|
|
1039 *
|
|
1040 * First, determine the spacing. This is the width of the widest
|
|
1041 * label, plus the internal margin. Total length of the gauge is
|
|
1042 * spacing * (nlabels-1). To this, we add half the width of the
|
|
1043 * left-most label and half the width of the right-most label
|
|
1044 * to get the entire desired width of the widget.
|
|
1045 */
|
|
1046 if( gw->gauge.nlabels > 0 )
|
|
1047 {
|
|
1048 Dimension lwm, lw0, lw1 ; /* width of max, left, right labels */
|
|
1049 Dimension lh ;
|
|
1050
|
|
1051 MaxLabel(gw,&lwm,&lh, &lw0,&lw1) ;
|
|
1052
|
|
1053 if( gw->gauge.orientation == XtorientHorizontal )
|
|
1054 {
|
|
1055 lwm = (lwm+hmargin) * (gw->gauge.nlabels-1) + (lw0+lw1)/2 ;
|
|
1056 w = Max(w, lwm) ;
|
|
1057 h += lh + vmargin ;
|
|
1058 }
|
|
1059 else
|
|
1060 {
|
|
1061 lh = lh*gw->gauge.nlabels + (gw->gauge.nlabels - 1)*vmargin ;
|
|
1062 h = Max(h, lh) ;
|
|
1063 w += lwm + hmargin ;
|
|
1064 }
|
|
1065 }
|
|
1066
|
|
1067 w += hmargin*2 ;
|
|
1068 h += vmargin*2 ;
|
|
1069
|
|
1070 *wid = w ;
|
|
1071 *hgt = h ;
|
|
1072 }
|
|
1073
|
|
1074
|
|
1075
|
|
1076 static void
|
|
1077 AutoScale (GaugeWidget gw)
|
|
1078 {
|
|
1079 static int scales[3] = {1,2,5} ;
|
|
1080 int sptr = 0, smult=1 ;
|
|
1081
|
|
1082 if( gw->gauge.autoScaleDown )
|
|
1083 gw->gauge.v1 = 0 ;
|
|
1084 while( gw->gauge.value > gw->gauge.v1 )
|
|
1085 {
|
|
1086 if( ++sptr > 2 ) {
|
|
1087 sptr = 0 ;
|
|
1088 smult *= 10 ;
|
|
1089 }
|
|
1090 gw->gauge.v1 = scales[sptr] * smult ;
|
|
1091 }
|
|
1092 }
|
|
1093
|
|
1094 static void
|
|
1095 EnableUpdate (GaugeWidget gw)
|
|
1096 {
|
|
1097 gw->gauge.intervalId =
|
|
1098 XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)gw),
|
|
1099 gw->gauge.update * MS_PER_SEC, GaugeGetValue,
|
|
1100 (XtPointer)gw) ;
|
|
1101 }
|
|
1102
|
|
1103 static void
|
|
1104 DisableUpdate (GaugeWidget gw)
|
|
1105 {
|
|
1106 XtRemoveTimeOut(gw->gauge.intervalId) ;
|
|
1107 }
|
|
1108
|
|
1109 static void
|
|
1110 GaugeGetValue (XtPointer clientData,
|
|
1111 XtIntervalId *intervalId)
|
|
1112 {
|
|
1113 GaugeWidget gw = (GaugeWidget)clientData ;
|
|
1114 Cardinal value ;
|
|
1115
|
|
1116 if( gw->gauge.update > 0 )
|
|
1117 EnableUpdate(gw) ;
|
|
1118
|
|
1119 if( gw->gauge.getValue != NULL )
|
|
1120 {
|
|
1121 XtCallCallbackList((Widget)gw, gw->gauge.getValue, (XtPointer)&value);
|
|
1122 XawGaugeSetValue((Widget)gw, value) ;
|
|
1123 }
|
|
1124 }
|
|
1125
|
|
1126
|
|
1127 static GC
|
|
1128 Get_GC (GaugeWidget gw,
|
|
1129 Pixel fg)
|
|
1130 {
|
|
1131 XGCValues values ;
|
|
1132 #define vmask GCForeground
|
|
1133 #define umask (GCBackground|GCSubwindowMode|GCGraphicsExposures|GCDashOffset\
|
|
1134 |GCFont|GCDashList|GCArcMode)
|
|
1135
|
|
1136 values.foreground = fg ;
|
|
1137
|
|
1138 return XtAllocateGC((Widget)gw, 0, vmask, &values, 0L, umask) ;
|
|
1139 }
|