Mercurial > hg > xemacs-beta
annotate lwlib/xlwgauge.c @ 5904:ee27ca517e90
Revise print_symbol(), never calling is{float,ratio}_string().
src/ChangeLog addition:
2015-05-08 Aidan Kehoe <kehoea@parhasard.net>
* print.c (print_symbol):
Revise this. No longer call isfloat_string() and isratio_string()
on practically every symbol seen; check explicitly for the known
float format in this function, which turns out to be a more
limited and cheap job than you would think.
Also check for integer and ratio syntax in passing.
Use Vdigit_fixnum_map when working out whether a given character
is a digit.
* lisp.h:
Make Vdigit_fixnum_map available generally.
tests/ChangeLog addition:
2015-05-08 Aidan Kehoe <kehoea@parhasard.net>
* automated/lisp-reader-tests.el:
Check read and print handling of symbols that look like
numbers. In passing, check the read and print handling of the
associated numbers.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Fri, 08 May 2015 14:33:46 +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 } |