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