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