gtk+3: fix dependencies for new gnome/accessibility/at-spi2-core
[oi-userland.git] / components / x11 / libXaw5 / src / StripChart.c
blob33d947ec953a6fcf8bcff8684537529876d9b5ca
1 /* $XConsortium: StripChart.c,v 1.25 94/04/17 20:12:56 kaleb Exp $ */
3 /***********************************************************
5 Copyright (c) 1987, 1988, 1994 X Consortium
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 Except as contained in this notice, the name of the X Consortium shall not be
25 used in advertising or otherwise to promote the sale, use or other dealings
26 in this Software without prior written authorization from the X Consortium.
29 Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
31 All Rights Reserved
33 Permission to use, copy, modify, and distribute this software and its
34 documentation for any purpose and without fee is hereby granted,
35 provided that the above copyright notice appear in all copies and that
36 both that copyright notice and this permission notice appear in
37 supporting documentation, and that the name of Digital not be
38 used in advertising or publicity pertaining to distribution of the
39 software without specific, written prior permission.
41 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
42 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
43 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
44 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
45 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
46 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
47 SOFTWARE.
49 ******************************************************************/
51 #include <stdio.h>
52 #include <X11/IntrinsicP.h>
53 #include <X11/StringDefs.h>
54 #include <X11/Xaw/XawInit.h>
55 #include <X11/Xaw/StripCharP.h>
56 #include <X11/Xfuncs.h>
58 #define MS_PER_SEC 1000
60 /* Private Data */
62 #define offset(field) XtOffsetOf(StripChartRec, field)
64 static XtResource resources[] = {
65 {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension),
66 offset(core.width), XtRImmediate, (XtPointer) 120},
67 {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension),
68 offset(core.height), XtRImmediate, (XtPointer) 120},
69 {XtNupdate, XtCInterval, XtRInt, sizeof(int),
70 offset(strip_chart.update), XtRImmediate, (XtPointer) 10},
71 {XtNminScale, XtCScale, XtRInt, sizeof(int),
72 offset(strip_chart.min_scale), XtRImmediate, (XtPointer) 1},
73 {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
74 offset(strip_chart.fgpixel), XtRString, XtDefaultForeground},
75 {XtNhighlight, XtCForeground, XtRPixel, sizeof(Pixel),
76 offset(strip_chart.hipixel), XtRString, XtDefaultForeground},
77 {XtNgetValue, XtCCallback, XtRCallback, sizeof(XtPointer),
78 offset(strip_chart.get_value), XtRImmediate, (XtPointer) NULL},
79 {XtNjumpScroll, XtCJumpScroll, XtRInt, sizeof(int),
80 offset(strip_chart.jump_val), XtRImmediate, (XtPointer) DEFAULT_JUMP},
83 #undef offset
85 static void Initialize(), Destroy(), Redisplay(), MoveChart(), SetPoints();
86 static Boolean SetValues();
87 static int repaint_window();
89 StripChartClassRec stripChartClassRec = {
90 { /* core fields */
91 /* superclass */ (WidgetClass) &simpleClassRec,
92 /* class_name */ "StripChart",
93 /* size */ sizeof(StripChartRec),
94 /* class_initialize */ XawInitializeWidgetSet,
95 /* class_part_initialize */ NULL,
96 /* class_inited */ FALSE,
97 /* initialize */ Initialize,
98 /* initialize_hook */ NULL,
99 /* realize */ XtInheritRealize,
100 /* actions */ NULL,
101 /* num_actions */ 0,
102 /* resources */ resources,
103 /* num_resources */ XtNumber(resources),
104 /* xrm_class */ NULLQUARK,
105 /* compress_motion */ TRUE,
106 /* compress_exposure */ XtExposeCompressMultiple |
107 XtExposeGraphicsExposeMerged,
108 /* compress_enterleave */ TRUE,
109 /* visible_interest */ FALSE,
110 /* destroy */ Destroy,
111 /* resize */ SetPoints,
112 /* expose */ Redisplay,
113 /* set_values */ SetValues,
114 /* set_values_hook */ NULL,
115 /* set_values_almost */ NULL,
116 /* get_values_hook */ NULL,
117 /* accept_focus */ NULL,
118 /* version */ XtVersion,
119 /* callback_private */ NULL,
120 /* tm_table */ NULL,
121 /* query_geometry */ XtInheritQueryGeometry,
122 /* display_accelerator */ XtInheritDisplayAccelerator,
123 /* extension */ NULL
125 { /* Simple class fields */
126 /* change_sensitive */ XtInheritChangeSensitive
130 WidgetClass stripChartWidgetClass = (WidgetClass) &stripChartClassRec;
132 /****************************************************************
134 * Private Procedures
136 ****************************************************************/
138 static void draw_it();
140 /* Function Name: CreateGC
141 * Description: Creates the GC's
142 * Arguments: w - the strip chart widget.
143 * which - which GC's to create.
144 * Returns: none
147 static void
148 CreateGC(w, which)
149 StripChartWidget w;
150 unsigned int which;
152 XGCValues myXGCV;
154 if (which & FOREGROUND) {
155 myXGCV.foreground = w->strip_chart.fgpixel;
156 w->strip_chart.fgGC = XtGetGC((Widget) w, GCForeground, &myXGCV);
159 if (which & HIGHLIGHT) {
160 myXGCV.foreground = w->strip_chart.hipixel;
161 w->strip_chart.hiGC = XtGetGC((Widget) w, GCForeground, &myXGCV);
165 /* Function Name: DestroyGC
166 * Description: Destroys the GC's
167 * Arguments: w - the strip chart widget.
168 * which - which GC's to destroy.
169 * Returns: none
172 static void
173 DestroyGC(w, which)
174 StripChartWidget w;
175 unsigned int which;
177 if (which & FOREGROUND)
178 XtReleaseGC((Widget) w, w->strip_chart.fgGC);
180 if (which & HIGHLIGHT)
181 XtReleaseGC((Widget) w, w->strip_chart.hiGC);
184 /* ARGSUSED */
185 static void Initialize (greq, gnew, args, num_args)
186 Widget greq, gnew;
187 ArgList args;
188 Cardinal *num_args;
190 StripChartWidget w = (StripChartWidget)gnew;
192 if (w->strip_chart.update > 0)
193 w->strip_chart.interval_id = XtAppAddTimeOut(
194 XtWidgetToApplicationContext(gnew),
195 w->strip_chart.update * MS_PER_SEC,
196 draw_it, (XtPointer) gnew);
197 CreateGC(w, (unsigned int) ALL_GCS);
199 w->strip_chart.scale = w->strip_chart.min_scale;
200 w->strip_chart.interval = 0;
201 w->strip_chart.max_value = 0.0;
202 w->strip_chart.points = NULL;
203 SetPoints(w);
206 static void Destroy (gw)
207 Widget gw;
209 StripChartWidget w = (StripChartWidget)gw;
211 if (w->strip_chart.update > 0)
212 XtRemoveTimeOut (w->strip_chart.interval_id);
213 if (w->strip_chart.points)
214 XtFree((char *) w->strip_chart.points);
215 DestroyGC(w, (unsigned int) ALL_GCS);
219 * NOTE: This function really needs to recieve graphics exposure
220 * events, but since this is not easily supported until R4 I am
221 * going to hold off until then.
224 /* ARGSUSED */
225 static void Redisplay(w, event, region)
226 Widget w;
227 XEvent *event;
228 Region region;
230 if (event->type == GraphicsExpose)
231 (void) repaint_window ((StripChartWidget)w, event->xgraphicsexpose.x,
232 event->xgraphicsexpose.width);
233 else
234 (void) repaint_window ((StripChartWidget)w, event->xexpose.x,
235 event->xexpose.width);
238 /* ARGSUSED */
239 static void
240 draw_it(client_data, id)
241 XtPointer client_data;
242 XtIntervalId *id; /* unused */
244 StripChartWidget w = (StripChartWidget)client_data;
245 double value;
247 if (w->strip_chart.update > 0)
248 w->strip_chart.interval_id =
249 XtAppAddTimeOut(XtWidgetToApplicationContext( (Widget) w),
250 w->strip_chart.update * MS_PER_SEC,draw_it,client_data);
252 if (w->strip_chart.interval >= (int)w->core.width)
253 MoveChart( (StripChartWidget) w, TRUE);
255 /* Get the value, stash the point and draw corresponding line. */
257 if (w->strip_chart.get_value == NULL)
258 return;
260 XtCallCallbacks( (Widget)w, XtNgetValue, (XtPointer)&value );
263 * Keep w->strip_chart.max_value up to date, and if this data
264 * point is off the graph, change the scale to make it fit.
267 if (value > w->strip_chart.max_value) {
268 w->strip_chart.max_value = value;
269 if (XtIsRealized((Widget)w) &&
270 w->strip_chart.max_value > w->strip_chart.scale) {
271 XClearWindow( XtDisplay (w), XtWindow (w));
272 w->strip_chart.interval = repaint_window(w, 0, (int) w->core.width);
276 w->strip_chart.valuedata[w->strip_chart.interval] = value;
277 if (XtIsRealized((Widget)w)) {
278 int y = (int) (w->core.height
279 - (int)(w->core.height * value) / w->strip_chart.scale);
281 XFillRectangle(XtDisplay(w), XtWindow(w), w->strip_chart.fgGC,
282 w->strip_chart.interval, y,
283 (unsigned int) 1, w->core.height - y);
285 * Fill in the graph lines we just painted over.
288 if (w->strip_chart.points != NULL) {
289 w->strip_chart.points[0].x = w->strip_chart.interval;
290 XDrawPoints(XtDisplay(w), XtWindow(w), w->strip_chart.hiGC,
291 w->strip_chart.points, w->strip_chart.scale - 1,
292 CoordModePrevious);
295 XFlush(XtDisplay(w)); /* Flush output buffers */
297 w->strip_chart.interval++; /* Next point */
298 } /* draw_it */
300 /* Blts data according to current size, then redraws the stripChart window.
301 * Next represents the number of valid points in data. Returns the (possibly)
302 * adjusted value of next. If next is 0, this routine draws an empty window
303 * (scale - 1 lines for graph). If next is less than the current window width,
304 * the returned value is identical to the initial value of next and data is
305 * unchanged. Otherwise keeps half a window's worth of data. If data is
306 * changed, then w->strip_chart.max_value is updated to reflect the
307 * largest data point.
310 static int
311 repaint_window(w, left, width)
312 StripChartWidget w;
313 int left, width;
315 int i, j;
316 int next = w->strip_chart.interval;
317 int scale = w->strip_chart.scale;
318 int scalewidth = 0;
320 /* Compute the minimum scale required to graph the data, but don't go
321 lower than min_scale. */
322 if (w->strip_chart.interval != 0 || scale <= (int)w->strip_chart.max_value)
323 scale = ((int) (w->strip_chart.max_value)) + 1;
324 if (scale < w->strip_chart.min_scale)
325 scale = w->strip_chart.min_scale;
327 if (scale != w->strip_chart.scale) {
328 w->strip_chart.scale = scale;
329 left = 0;
330 width = next;
331 scalewidth = w->core.width;
333 SetPoints(w);
335 if (XtIsRealized ((Widget) w))
336 XClearWindow (XtDisplay (w), XtWindow (w));
340 if (XtIsRealized((Widget)w)) {
341 Display *dpy = XtDisplay(w);
342 Window win = XtWindow(w);
344 width += left - 1;
345 if (!scalewidth) scalewidth = width;
347 if (next < ++width) width = next;
349 /* Draw data point lines. */
350 for (i = left; i < width; i++) {
351 int y = (int) (w->core.height -
352 (int)(w->core.height * w->strip_chart.valuedata[i]) /
353 w->strip_chart.scale);
355 XFillRectangle(dpy, win, w->strip_chart.fgGC,
356 i, y, (unsigned int) 1,
357 (unsigned int) (w->core.height - y));
360 /* Draw graph reference lines */
361 for (i = 1; i < w->strip_chart.scale; i++) {
362 j = i * ((int)w->core.height / w->strip_chart.scale);
363 XDrawLine(dpy, win, w->strip_chart.hiGC, left, j, scalewidth, j);
366 return(next);
369 /* Function Name: MoveChart
370 * Description: moves the chart over when it would run off the end.
371 * Arguments: w - the load widget.
372 * blit - blit the bits? (TRUE/FALSE).
373 * Returns: none.
376 static void
377 MoveChart(w, blit)
378 StripChartWidget w;
379 Boolean blit;
381 double old_max;
382 int left, i, j;
383 int next = w->strip_chart.interval;
385 if (!XtIsRealized((Widget) w)) return;
387 if (w->strip_chart.jump_val < 0) w->strip_chart.jump_val = DEFAULT_JUMP;
388 if (w->strip_chart.jump_val == DEFAULT_JUMP)
389 j = w->core.width >> 1; /* Half the window width. */
390 else {
391 j = w->core.width - w->strip_chart.jump_val;
392 if (j < 0) j = 0;
395 (void) memmove((char *)(w->strip_chart.valuedata),
396 (char *)(w->strip_chart.valuedata + next - j),
397 j * sizeof(double));
398 next = w->strip_chart.interval = j;
401 * Since we just lost some data, recompute the
402 * w->strip_chart.max_value.
405 old_max = w->strip_chart.max_value;
406 w->strip_chart.max_value = 0.0;
407 for (i = 0; i < next; i++) {
408 if (w->strip_chart.valuedata[i] > w->strip_chart.max_value)
409 w->strip_chart.max_value = w->strip_chart.valuedata[i];
412 if (!blit) return; /* we are done... */
414 if ( ((int) old_max) != ( (int) w->strip_chart.max_value) ) {
415 XClearWindow(XtDisplay(w), XtWindow(w));
416 repaint_window(w, 0, (int) w->core.width);
417 return;
420 XCopyArea(XtDisplay((Widget)w), XtWindow((Widget)w), XtWindow((Widget)w),
421 w->strip_chart.hiGC, (int) w->core.width - j, 0,
422 (unsigned int) j, (unsigned int) w->core.height,
423 0, 0);
425 XClearArea(XtDisplay((Widget)w), XtWindow((Widget)w),
426 (int) j, 0,
427 (unsigned int) w->core.width - j, (unsigned int)w->core.height,
428 FALSE);
430 /* Draw graph reference lines */
431 left = j;
432 for (i = 1; i < w->strip_chart.scale; i++) {
433 j = i * ((int)w->core.height / w->strip_chart.scale);
434 XDrawLine(XtDisplay((Widget) w), XtWindow( (Widget) w),
435 w->strip_chart.hiGC, left, j, (int)w->core.width, j);
437 return;
440 /* ARGSUSED */
441 static Boolean SetValues (current, request, new, args, num_args)
442 Widget current, request, new;
443 ArgList args;
444 Cardinal *num_args;
446 StripChartWidget old = (StripChartWidget)current;
447 StripChartWidget w = (StripChartWidget)new;
448 Boolean ret_val = FALSE;
449 unsigned int new_gc = NO_GCS;
451 if (w->strip_chart.update != old->strip_chart.update) {
452 if (old->strip_chart.update > 0)
453 XtRemoveTimeOut (old->strip_chart.interval_id);
454 if (w->strip_chart.update > 0)
455 w->strip_chart.interval_id =
456 XtAppAddTimeOut(XtWidgetToApplicationContext(new),
457 w->strip_chart.update * MS_PER_SEC,
458 draw_it, (XtPointer)w);
461 if ( w->strip_chart.min_scale > (int) ((w->strip_chart.max_value) + 1) )
462 ret_val = TRUE;
464 if ( w->strip_chart.fgpixel != old->strip_chart.fgpixel ) {
465 new_gc |= FOREGROUND;
466 ret_val = True;
469 if ( w->strip_chart.hipixel != old->strip_chart.hipixel ) {
470 new_gc |= HIGHLIGHT;
471 ret_val = True;
474 DestroyGC(old, new_gc);
475 CreateGC(w, new_gc);
477 return( ret_val );
480 /* Function Name: SetPoints
481 * Description: Sets up the polypoint that will be used to draw in
482 * the graph lines.
483 * Arguments: w - the StripChart widget.
484 * Returns: none.
487 #define HEIGHT ( (unsigned int) w->core.height)
489 static void
490 SetPoints(widget)
491 Widget widget;
493 StripChartWidget w = (StripChartWidget) widget;
494 XPoint * points;
495 Cardinal size;
496 int i;
498 if (w->strip_chart.scale <= 1) { /* no scale lines. */
499 XtFree ((char *) w->strip_chart.points);
500 w->strip_chart.points = NULL;
501 return;
504 size = sizeof(XPoint) * (w->strip_chart.scale - 1);
506 points = (XPoint *) XtRealloc( (XtPointer) w->strip_chart.points, size);
507 w->strip_chart.points = points;
509 /* Draw graph reference lines into clip mask */
511 for (i = 1; i < w->strip_chart.scale; i++) {
512 points[i - 1].x = 0;
513 points[i - 1].y = HEIGHT / w->strip_chart.scale;