Mercurial > hg > xemacs-beta
annotate lwlib/xlwgauge.c @ 4522:fc7067b7f407
Backout last patch; forgot to specify file.
author | Stephen J. Turnbull <stephen@xemacs.org> |
---|---|
date | Wed, 29 Oct 2008 03:37:16 +0900 |
parents | 383ab474a241 |
children | 726060ee587c |
rev | line source |
---|---|
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 | |
4522
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
80 #define offset(field) XtOffsetOf(GaugeRec, field) |
424 | 81 static XtResource resources[] = { |
4522
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
82 {XtNvalue, XtCValue, XtRInt, sizeof(int), |
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
83 offset(gauge.value), XtRImmediate, (XtPointer)0}, |
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
84 {XtNminValue, XtCMinValue, XtRInt, sizeof(int), |
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
85 offset(gauge.v0), XtRImmediate, (XtPointer)0}, |
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
86 {XtNmaxValue, XtCMaxValue, XtRInt, sizeof(int), |
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
87 offset(gauge.v1), XtRImmediate, (XtPointer)100}, |
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
88 {XtNntics, XtCNTics, XtRInt, sizeof(int), |
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
89 offset(gauge.ntics), XtRImmediate, (XtPointer) 0}, |
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
90 {XtNnlabels, XtCNLabels, XtRInt, sizeof(int), |
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
91 offset(gauge.nlabels), XtRImmediate, (XtPointer) 0}, |
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
92 {XtNlabels, XtCLabels, XtRStringArray, sizeof(String *), |
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
93 offset(gauge.labels), XtRStringArray, NULL}, |
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
94 {XtNautoScaleUp, XtCAutoScaleUp, XtRBoolean, sizeof(Boolean), |
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
95 offset(gauge.autoScaleUp), XtRImmediate, FALSE}, |
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
96 {XtNautoScaleDown, XtCAutoScaleDown, XtRBoolean, sizeof(Boolean), |
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
97 offset(gauge.autoScaleDown), XtRImmediate, FALSE}, |
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
98 {XtNorientation, XtCOrientation, XtROrientation, sizeof(XtOrientation), |
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
99 offset(gauge.orientation), XtRImmediate, (XtPointer)XtorientHorizontal}, |
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
100 {XtNupdate, XtCInterval, XtRInt, sizeof(int), |
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
101 offset(gauge.update), XtRImmediate, (XtPointer)0}, |
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
102 {XtNgetValue, XtCCallback, XtRCallback, sizeof(XtPointer), |
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
103 offset(gauge.getValue), XtRImmediate, (XtPointer)NULL}, |
424 | 104 }; |
105 #undef offset | |
4522
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
106 |
424 | 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 *); | |
3968 | 135 static void GaugeMercury (Display *, Window, GC, GaugeWidget, int, int); |
424 | 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 { | |
4522
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
149 {"select", GaugeSelect}, |
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
150 {"paste", GaugePaste}, |
424 | 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, |
4522
fc7067b7f407
Backout last patch; forgot to specify file.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4521
diff
changeset
|
165 /* class_name */ "Gauge", |
424 | 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, | |
3055 | 243 Widget new_, |
2286 | 244 ArgList UNUSED (args), |
245 Cardinal *UNUSED (num_args)) | |
424 | 246 { |
3055 | 247 GaugeWidget gw = (GaugeWidget) new_; |
424 | 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 ) | |
3055 | 261 new_->core.width = w ; |
424 | 262 if( request->core.height == 0 ) |
3055 | 263 new_->core.height = h ; |
264 gw->core.widget_class->core_class.resize(new_) ; | |
424 | 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), |
3055 | 504 Widget new_, |
2286 | 505 ArgList UNUSED (args), |
506 Cardinal *UNUSED (num_args)) | |
424 | 507 { |
508 GaugeWidget oldgw = (GaugeWidget) old; | |
3055 | 509 GaugeWidget gw = (GaugeWidget) new_; |
424 | 510 Boolean was_resized = False; |
511 | |
512 if( gw->gauge.selected != None ) { | |
3055 | 513 XtDisownSelection(new_, gw->gauge.selected, CurrentTime) ; |
424 | 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 | |
3055 | 538 GaugeResize(new_) ; |
424 | 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 { | |
3055 | 551 XtReleaseGC(new_, gw->gauge.inverse_GC) ; |
424 | 552 gw->gauge.inverse_GC = Get_GC(gw, gw->core.background_pixel) ; |
553 } | |
554 | |
555 return was_resized || gw->gauge.value != oldgw->gauge.value || | |
3055 | 556 XtIsSensitive(old) != XtIsSensitive(new_); |
424 | 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 | |
3968 | 820 XawGaugeSetValue (Widget w, int value) |
424 | 821 { |
822 GaugeWidget gw = (GaugeWidget)w ; | |
823 int oldvalue ; | |
824 GC gc ; | |
825 | |
826 if( gw->gauge.selected != None ) { | |
827 XtDisownSelection(w, gw->gauge.selected, CurrentTime) ; | |
828 gw->gauge.selected = None ; | |
829 } | |
830 | |
831 if( !XtIsRealized(w) ) { | |
832 gw->gauge.value = value ; | |
833 return ; | |
834 } | |
835 | |
836 /* need to rescale? */ | |
647 | 837 if(( gw->gauge.autoScaleUp && (int) value > gw->gauge.v1) || |
838 (gw->gauge.autoScaleDown && (int) value < gw->gauge.v1/3 )) | |
424 | 839 { |
3374 | 840 XtVaSetValues(w, XtNvalue, value, NULL) ; |
424 | 841 return ; |
842 } | |
843 | |
844 oldvalue = gw->gauge.value ; | |
845 gw->gauge.value = value ; | |
846 | |
847 gc = XtIsSensitive(w) ? gw->label.normal_GC : gw->label.gray_GC ; | |
848 GaugeMercury(XtDisplay(w), XtWindow(w), gc, gw, oldvalue,value) ; | |
849 } | |
850 | |
851 | |
3968 | 852 int |
424 | 853 XawGaugeGetValue (Widget w) |
854 { | |
855 GaugeWidget gw = (GaugeWidget)w ; | |
856 return gw->gauge.value ; | |
857 } | |
858 | |
859 | |
860 | |
861 | |
862 /**************************************************************** | |
863 * | |
864 * Private Procedures | |
865 * | |
866 ****************************************************************/ | |
867 | |
868 /* draw the mercury over a specific region */ | |
869 | |
870 static void | |
871 GaugeMercury (Display *dpy, | |
872 Window win, | |
873 GC gc, | |
874 GaugeWidget gw, | |
3968 | 875 int val0, |
876 int val1) | |
424 | 877 { |
878 int v0 = gw->gauge.v0 ; | |
879 int v1 = gw->gauge.v1 ; | |
880 int vd = v1 - v0 ; | |
881 Dimension len ; /* length (width or height) of gauge */ | |
882 Position e0, e1 ; /* gauge ends */ | |
883 Position p0, p1 ; /* mercury ends */ | |
884 int y ; /* vertical (horizontal) position */ | |
885 Boolean undraw = FALSE ; | |
886 | |
887 len = gw->gauge.orientation == XtorientHorizontal ? | |
888 gw->core.width : gw->core.height ; | |
889 | |
890 e0 = gw->gauge.margin0 ; /* left (top) end */ | |
891 e1 = len - gw->gauge.margin1 -1 ; /* right (bottom) end */ | |
892 | |
893 if( vd <= 0 ) vd = 1 ; | |
894 | |
3968 | 895 if( val0 < v0 ) val0 = v0 ; |
896 else if( val0 > v1 ) val0 = v1 ; | |
897 if( val1 < v0 ) val1 = v0 ; | |
898 else if( val1 > v1 ) val1 = v1 ; | |
424 | 899 |
900 p0 = (val0-v0)*(e1-e0-1)/vd ; | |
901 p1 = (val1-v0)*(e1-e0-1)/vd ; | |
902 | |
903 if( p1 == p0 ) | |
904 return ; | |
905 | |
906 y = gw->gauge.gmargin ; | |
907 | |
908 if( p1 < p0 ) | |
909 { | |
910 Position tmp = p0 ; | |
911 p0 = p1 ; | |
912 p1 = tmp ; | |
913 gc = gw->label.normal_GC ; | |
914 XSetForeground(dpy,gc, gw->core.background_pixel) ; | |
915 undraw = TRUE ; | |
916 } | |
917 | |
918 if( gw->gauge.orientation == XtorientHorizontal ) | |
919 XFillRectangle(dpy,win,gc, e0+p0+1,y+1, p1-p0,GA_WID) ; | |
920 else | |
921 XFillRectangle(dpy,win,gc, y+1,e1-p1, GA_WID,p1-p0) ; | |
922 | |
923 if( undraw ) | |
924 XSetForeground(dpy,gc, gw->label.foreground) ; | |
925 } | |
926 | |
927 | |
928 | |
929 /* Search the labels, find the largest one. */ | |
930 /* TODO: handle vertical fonts? */ | |
931 | |
932 static void | |
933 MaxLabel (GaugeWidget gw, | |
934 Dimension *wid, /* max label width */ | |
935 Dimension *hgt, /* max label height */ | |
936 Dimension *w0, /* width of first label */ | |
937 Dimension *w1) /* width of last label */ | |
938 { | |
939 char lstr[80], *lbl ; | |
940 int w ; | |
941 XFontStruct *font = gw->label.font ; | |
942 int i ; | |
943 int lw = 0; | |
944 int v0 = gw->gauge.v0 ; | |
945 int dv = gw->gauge.v1 - v0 ; | |
946 int n = gw->gauge.nlabels ; | |
947 | |
948 if( n > 0 ) | |
949 { | |
950 if( --n <= 0 ) {n = 1 ; v0 += dv/2 ;} | |
951 | |
952 /* loop through all labels, figure out how much room they | |
953 * need. | |
954 */ | |
955 w = 0 ; | |
956 for(i=0; i<gw->gauge.nlabels; ++i) | |
957 { | |
958 if( gw->gauge.labels == NULL ) /* numeric labels */ | |
959 sprintf(lbl = lstr,"%d", v0 + i*dv/n) ; | |
960 else | |
961 lbl = gw->gauge.labels[i] ; | |
962 | |
963 if( lbl != NULL ) { | |
964 lw = XTextWidth(font, lbl, strlen(lbl)) ; | |
965 w = Max( w, lw ) ; | |
966 } | |
967 else | |
968 lw = 0 ; | |
969 | |
970 if( i == 0 && w0 != NULL ) *w0 = lw ; | |
971 } | |
972 if( w1 != NULL ) *w1 = lw ; | |
973 | |
974 *wid = w ; | |
975 *hgt = font->max_bounds.ascent + font->max_bounds.descent ; | |
976 } | |
977 else | |
978 *wid = *hgt = 0 ; | |
979 } | |
980 | |
981 | |
982 /* Determine the preferred size for this widget. choose 100x100 for | |
983 * debugging. | |
984 */ | |
985 | |
986 static void | |
987 GaugeSize (GaugeWidget gw, | |
988 Dimension *wid, | |
989 Dimension *hgt, | |
990 Dimension min_len) | |
991 { | |
992 int w,h ; /* width, height of gauge */ | |
993 int vmargin ; /* vertical margin */ | |
994 int hmargin ; /* horizontal margin */ | |
995 | |
996 hmargin = gw->label.internal_width ; | |
997 vmargin = gw->label.internal_height ; | |
998 | |
999 /* find total height (width) of contents */ | |
1000 | |
1001 | |
1002 /* find minimum size for undecorated gauge */ | |
1003 | |
1004 if( gw->gauge.orientation == XtorientHorizontal ) | |
1005 { | |
1006 w = min_len ; | |
1007 h = GA_WID+2 ; /* gauge itself + edges */ | |
1008 } | |
1009 else | |
1010 { | |
1011 w = GA_WID+2 ; | |
1012 h = min_len ; | |
1013 } | |
1014 | |
1015 if( gw->gauge.ntics > 0 ) | |
1016 { | |
1017 if( gw->gauge.orientation == XtorientHorizontal ) | |
1018 { | |
1019 w = Max(w, gw->gauge.ntics*3) ; | |
1020 h += vmargin + TIC_LEN ; | |
1021 } | |
1022 else | |
1023 { | |
1024 w += hmargin + TIC_LEN ; | |
1025 h = Max(h, gw->gauge.ntics*3) ; | |
1026 } | |
1027 } | |
1028 | |
1029 | |
1030 /* If labels are requested, this gets a little interesting. | |
1031 * We want the end labels centered on the ends of the gauge and | |
1032 * the centers of the labels evenly spaced. The labels at the ends | |
1033 * will not be the same width, meaning that the gauge itself need | |
1034 * not be centered in the widget. | |
1035 * | |
1036 * First, determine the spacing. This is the width of the widest | |
1037 * label, plus the internal margin. Total length of the gauge is | |
1038 * spacing * (nlabels-1). To this, we add half the width of the | |
1039 * left-most label and half the width of the right-most label | |
1040 * to get the entire desired width of the widget. | |
1041 */ | |
1042 if( gw->gauge.nlabels > 0 ) | |
1043 { | |
1044 Dimension lwm, lw0, lw1 ; /* width of max, left, right labels */ | |
1045 Dimension lh ; | |
1046 | |
1047 MaxLabel(gw,&lwm,&lh, &lw0,&lw1) ; | |
1048 | |
1049 if( gw->gauge.orientation == XtorientHorizontal ) | |
1050 { | |
1051 lwm = (lwm+hmargin) * (gw->gauge.nlabels-1) + (lw0+lw1)/2 ; | |
1052 w = Max(w, lwm) ; | |
1053 h += lh + vmargin ; | |
1054 } | |
1055 else | |
1056 { | |
1057 lh = lh*gw->gauge.nlabels + (gw->gauge.nlabels - 1)*vmargin ; | |
1058 h = Max(h, lh) ; | |
1059 w += lwm + hmargin ; | |
1060 } | |
1061 } | |
1062 | |
1063 w += hmargin*2 ; | |
1064 h += vmargin*2 ; | |
1065 | |
1066 *wid = w ; | |
1067 *hgt = h ; | |
1068 } | |
1069 | |
1070 | |
1071 | |
1072 static void | |
1073 AutoScale (GaugeWidget gw) | |
1074 { | |
1075 static int scales[3] = {1,2,5} ; | |
1076 int sptr = 0, smult=1 ; | |
1077 | |
1078 if( gw->gauge.autoScaleDown ) | |
1079 gw->gauge.v1 = 0 ; | |
1080 while( gw->gauge.value > gw->gauge.v1 ) | |
1081 { | |
1082 if( ++sptr > 2 ) { | |
1083 sptr = 0 ; | |
1084 smult *= 10 ; | |
1085 } | |
1086 gw->gauge.v1 = scales[sptr] * smult ; | |
1087 } | |
1088 } | |
1089 | |
1090 static void | |
1091 EnableUpdate (GaugeWidget gw) | |
1092 { | |
1093 gw->gauge.intervalId = | |
1094 XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)gw), | |
1095 gw->gauge.update * MS_PER_SEC, GaugeGetValue, | |
1096 (XtPointer)gw) ; | |
1097 } | |
1098 | |
1099 static void | |
1100 DisableUpdate (GaugeWidget gw) | |
1101 { | |
1102 XtRemoveTimeOut(gw->gauge.intervalId) ; | |
1103 } | |
1104 | |
1105 static void | |
1106 GaugeGetValue (XtPointer clientData, | |
2286 | 1107 XtIntervalId *UNUSED (intervalId)) |
424 | 1108 { |
1109 GaugeWidget gw = (GaugeWidget)clientData ; | |
3968 | 1110 int value ; |
424 | 1111 |
1112 if( gw->gauge.update > 0 ) | |
1113 EnableUpdate(gw) ; | |
1114 | |
1115 if( gw->gauge.getValue != NULL ) | |
1116 { | |
1117 XtCallCallbackList((Widget)gw, gw->gauge.getValue, (XtPointer)&value); | |
1118 XawGaugeSetValue((Widget)gw, value) ; | |
1119 } | |
1120 } | |
1121 | |
1122 | |
1123 static GC | |
1124 Get_GC (GaugeWidget gw, | |
1125 Pixel fg) | |
1126 { | |
1127 XGCValues values ; | |
1128 #define vmask GCForeground | |
1129 #define umask (GCBackground|GCSubwindowMode|GCGraphicsExposures|GCDashOffset\ | |
1130 |GCFont|GCDashList|GCArcMode) | |
1131 | |
1132 values.foreground = fg ; | |
1133 | |
1134 return XtAllocateGC((Widget)gw, 0, vmask, &values, 0L, umask) ; | |
1135 } |