1 /* aqua.c
2 *
3 * Initial Implementation: 10/2007
4 * UPDATED - March 2008. Add AQSEC2 routine to support "imaging" routine
5 * UPDATED - May 2009. When using the "-DDOUBLE" option, need
6 * to make a distinction between real
7 * numbers and integers since the default
8 * byte size can be set independently
9 * for these. Add the option "-DINTEGER8"
10 * to handle the case where integers set
11 * to 8 bytes on a 32-bit machine.
12 * UPDATED - June 2014. With the new versions of the Mac OSX and
13 * Aquaterm, need to modify how real numbers
14 * are passed between the Fortran,
15 * aqua.c, and the Aquaterm library.
16 *
17 * The purpose of this library is to provide easy access from
18 * a Fortran 77 program to the AquaTerm library on MacOSX.
19 *
20 * Aquaterm provides a native Mac OSX terminal. This can be
21 * used as an alternative to using X11 under Mac OSX. The
22 * advantage of Aquaterm is that is does not require the user
23 * to have X11 installed (X11 installation is optional under
24 * Mac OSX). The Aquaterm terminal also has the "look" of the
25 * Mac OSX window system (the X11 windows do not).
26 *
27 * A few commets:
28 *
29 * 1) It is assumed that the Mac user has installed the
30 * underlying Aquaterm software (in particular, the
31 * Aquaterm library is a shared library that is expected
32 * to be in /usr/local/lib.
33 *
34 * 2) Although Aquaterm provides a Fortran-based "adapter",
35 * I am unable to take advantage of this. The Fortran
36 * adapter requires that the Fortran code be compiled to
37 * preserve case in names. This causes problems with
38 * Dataplot since I do not want to do this for some other
39 * routines that I am calling.
40 *
41 * 3) Aquaterm is a dynamic library. With Dataplot, I try
42 * to link libraries statically whenever possible.
43 *
44 * This seems to cause a conflict with the zlib compression
45 * library. Dataplot uses the GD library for PNG and JPEG
46 * graphics. GD in turn uses the jpeg, png, and zlib
47 * libraries. For the Mac OSX, I have built static versions
48 * of these libraries. However, Aquaterm seems to need
49 * a dynamic version of zlib.
50 *
51 * For these reasons, I have choosen to use the C-based version
52 * of Aquaterm. I have provided this subroutine as an intermediate
53 * wrapper between the Dataplot Fortran and the Aquaterm C-based
54 * library.
55 *
56 * Given my problem, I have not supported the full Aquaterm library.
57 * Instead, I have supported a basic set of calls to support a
58 * device driver for Aquaterm. This set of routines provides
59 * a wrapper layer between Fortran and the C based GD libraries.
60 * That is, these routines use only integer and real arguments with
61 * no C specific structures. This makes the calling sequence from
62 * Fortran easy.
63 *
64 * Although I wrote this wrapper with a specific application in
65 * mind, I believe it may well be useful for other Fortran
66 * codes. This code may be used and modified by anyone without
67 * restriction.
68 *
69 * A dummy version of this routine is maintained for non-Mac OSX
70 * systems. Since the dummy library is coded in Fortran, routine
71 * names will be limited to six characters.
72 *
73 * Note that calling C from Fortran is not standard. I have
74 * provided the following compiler defintions to enhance portability.
75 *
76 * 1) The default is to assume that the Fortran compiler appends an
77 * underscore to the routine name. Use -DNOUNDERSCORE if your
78 * compiler does not append the underscore.
79 * 2) The default is to assume that the Fortran compiler converts
80 * routine names to lower case. Use -DUPPERCASE if your
81 * Fortran compiler does not do this (e.g., the Cray).
82 * 3) Dataplot is compiled with options to make both single precision
83 * and double precision 64-bit. So real numbers will be passed
84 * as "double" but need to be converted to "float" when calling
85 * the Aquaterm routines.
86 * 4) Character strings are the most troublesome issue for
87 * portability. Passing character strings from Fortran to C
88 * is very compiler dependent. I have addressed this issue
89 * by passing character strings as arrays of ASCII Decimal
90 * Equivalents (ADE's). That is, the Fortran converts a
91 * character string to an array of the integer values where
92 * the integer is the ASCII collating sequence (i.e., A = 65,
93 * B = 66, etc.). The end of the string is denoted by setting
94 * the value to 0. This is easily accomplished on the Fortran
95 * side by using the ICHAR function. The C code here then
96 * calls an internal routine to covnert the integer array to
97 * a C string. Although a bit convoluted, this avoids a lot
98 * of messy portability issues.
99 *
100 *
101 * The following routines are included:
102 *
103 * aqinit - initialize Aquaterm
104 * aqend - close Aquaterm
105 * aqrend - render the current plot
106 * aqeras - start a new graph (close currently open one as well)
107 * aqdraw - draw a polyline
108 * aqmove - move to a point
109 * aqseco - set foreground color (based on color-map table)
110 * aqsec2 - set foreground color (based on RGB triplet)
111 * aqsepa - set line pattern
112 * aqpoin - draw a point (i.e., a pixel)
113 * aqcirc - draw a circle
114 * aqrgfl - solid fill of a region
115 * aqtxth - draw a horizontal character string
116 * aqtxtv - draw a vertical character string
117 * aqrelo - read mouse position
118 * i_to_s_4 - utility routine to convert array of ADE's to string
119 * array
120 *
121 */
122
123 /* Site dependent definitions (see comments above) */
124 /* Default is an underscore and lower case. The compiler specified
125 * definitions -DNOUNDERSCORE and -DUPPERCASE can be specified to
126 * override these defaults. */
127
128 #ifdef NOUNDERSCORE
129 #define APPEND_UNDERSCORE 0
130 #else
131 #define APPEND_UNDERSCORE 1
132 #endif
133 #ifdef UPPERCASE
134 #define SUBROUTINE_CASE 0
135 #else
136 #define SUBROUTINE_CASE 1
137 #endif
138
139 /* include files */
140
141 #include <stdio.h>
142 #include <stdlib.h>
143 #include <math.h>
144 #include <strings.h>
145 #include <aquaterm/aquaterm.h>
146
147 /* global definitions */
148
149 int decodeEvent(char *event, int *x, int *y);
150
151 /* flags for current attribute settings */
152 static int OPEN_FLAG_AQUA = 0; /* 0 - closed, 1 - open */
153
154 #if APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 1
155 void aqend_(), aqdraw_(), aqpoin_(), aqcirc_(), aqrgfl_();
156 void aqinit_(), aqeras_(), aqtxth_(), aqtxtv_();
157 void aqseco_(), aqsec2(), aqsepa_(), aqrend_(), aaqrelo_();
158 #elif APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 0
159 void AQEND_(), AQINIT_(), AQDRAW_(), AQPOIN_(), AQCIRC_(), AQRGFL_();
160 void AQINIT_(), AQERAS_(), AQTXTH_(), AQTXTV_();
161 void AQSECO_(), AQSEC2(), AQSEPA_(), AQREND_(), AQRELO_(),;
162 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 1
163 void aqend(), aqdraw(), aqpoin(), aqcirc(), aqrgfl();
164 void aqinit(), aqeras(), aqtxth(), aqtxtv(),gdtatt();
165 void aqseco(), aqsec2(), aqsepa(), aqrend(), aqrelo();
166 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 0
167 void AQEND(), AQDRAW(), AQPOIN(), AQCIRC(), AQRGFL();
168 void AQINIT(), AQERAS(), AQTXTH(), AQTXTV();
169 void AQSECO(), AQSEC2(), AQSEPA(), AQRELO();
170 #endif
171 void i_to_s_4();
172
173 /* AQINIT - routine to initialize Aquaterm.
174 *
175 */
176 #if APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 1
aqinit_(nplot,anumhp,anumvp,ired,igreen,iblue,maxclr)177 void aqinit_(nplot,anumhp,anumvp,ired,igreen,iblue,maxclr)
178 #elif APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 0
179 void AQINIT_(nplot,anumhp,anumvp,ired,igreen,iblue,maxclr)
180 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 1
181 void aqinit(nplot,anumhp,anumvp,ired,igreen,iblue,maxclr)
182 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 0
183 void AQINIT(nplot,anumhp,anumvp,ired,igreen,iblue,maxclr)
184 #endif
185 int ired[];
186 int igreen[];
187 int iblue[];
188 int *maxclr;
189 int *nplot, *anumhp, *anumvp;
190
191 {
192 int nplot_temp, anumhp_temp, anumvp_temp;
193 int maxclr_temp;
194 int ival1, ival2, ival3;
195 int i;
196 float val1, val2, val3;
197
198 maxclr_temp = *maxclr;
199 nplot_temp = *nplot;
200 anumhp_temp = *anumhp;
201 anumvp_temp = *anumvp;
202
203 if (OPEN_FLAG_AQUA == 0) { /* Device currently closed */
204 OPEN_FLAG_AQUA = 1;
205 aqtInit();
206 aqtOpenPlot(nplot_temp);
207 aqtSetPlotSize(anumhp_temp,anumvp_temp);
208 aqtSetPlotTitle("Dataplot Graphics Window");
209 for (i = 0; i < maxclr_temp; i++) {
210 ival1 = ired[i];
211 ival2 = igreen[i];
212 ival3 = iblue[i];
213 val1 = (float)(ival1)/255.0;
214 val2 = (float)(ival2)/255.0;
215 val3 = (float)(ival3)/255.0;
216 aqtSetColormapEntry(i,val1,val2,val3);
217 }
218 }
219 }
220
221 /* AQERAS - routine to clear the screen.
222 *
223 * 1) Check if a plot is currently open. If yes, write
224 * it to a file and destroy the current image.
225 * 2) Create a new image with the specified size specified
226 * in pixels. Note that orientation (landscape, portrait,
227 * is implicit in the pixel dimensions). Note that
228 * this routine does not modify the values.
229 * 3) Set all colors to be undefined and then set
230 * background and foreground colors.
231 *
232 * xpixels - width (in pixels) for graphics window
233 * ypixels - height (in pixels) for graphics window
234 * back_col - background color
235 * file name - file name (in integer ascii decimal equivalents)
236 *
237 */
238
239 #if APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 1
aqeras_(nplot,anumhp,anumvp,iback)240 void aqeras_(nplot, anumhp, anumvp, iback)
241 #elif APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 0
242 void AQERAS_(nplot, anumhp, anumvp, iback)
243 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 1
244 void aqeras(nplot, anumhp, anumvp, iback)
245 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 0
246 void AQERAS(nplot, anumhp, anumvp, iback)
247 #endif
248 int *nplot, *anumhp, *anumvp, *iback;
249 {
250
251 int nplot_temp, anumhp_temp, anumvp_temp, iback_temp;
252
253 nplot_temp = *nplot;
254 anumhp_temp = *anumhp;
255 anumvp_temp = *anumvp;
256 iback_temp = *iback;
257
258 /* Use "erase rectangle" method to clear screen */
259 if (OPEN_FLAG_AQUA > 0) {
260 /* aqtTakeBackgroundColorFromColormapEntry(iback_temp); */
261 /* aqtOpenPlot(nplot_temp); */
262 /* aqtSetPlotSize(anumhp_temp,anumvp_temp); */
263 /* aqtClearPlot(); */
264 /* aqtSetPlotTitle("Dataplot Graphics Window"); */
265
266 aqtTakeColorFromColormapEntry(iback_temp-1);
267 aqtEraseRect(0,0,anumhp_temp,anumvp_temp);
268 aqtAddFilledRect(0,0,anumhp_temp,anumvp_temp);
269
270 aqtSetFontname("Helvetica");
271 aqtSetFontsize(12.0);
272 }
273 }
274
275 /* AQEND - routine to end Aquaterm display and close the display
276 *
277 */
278 #if APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 1
aqend_()279 void aqend_()
280 #elif APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 0
281 void AQEND_()
282 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 1
283 void aqend()
284 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 0
285 void AQEND()
286 #endif
287
288 {
289 if (OPEN_FLAG_AQUA > 0) {
290 aqtClosePlot();
291 aqtTerminate();
292 OPEN_FLAG_AQUA = 0;
293 }
294 }
295
296 /* AQREND - routine to render current plot
297 *
298 */
299 #if APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 1
aqrend_()300 void aqrend_()
301 #elif APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 0
302 void AQREND_()
303 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 1
304 void aqrend()
305 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 0
306 void AQREND()
307 #endif
308
309 {
310 if (OPEN_FLAG_AQUA > 0) {
311 aqtRenderPlot();
312 }
313 }
314
315 /* AQDRAW - draw a polyline. The line attributes are set in
316 * other routines.
317 *
318 * xpts - contains the x coordinates
319 * ypts - contains the y coordinates
320 * npts - the number of points to plot
321 * icap - cap style: 1 = Butt
322 * 2 = Round
323 * 3 = Square
324 *
325 * Calling routine should send points in increments of
326 * 1,000.
327 */
328 #if APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 1
aqdraw_(xpts,ypts,npts,icap)329 void aqdraw_(xpts, ypts, npts, icap)
330 #elif APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 0
331 void AQDRAW_(xpts, ypts, npts, icap)
332 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 1
333 void aqdraw(xpts, ypts, npts)
334 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 0
335 void AQDRAW(xpts, ypts, npts)
336 #endif
337 double xpts[], ypts[];
338 int *npts;
339 int *icap;
340 {
341 int i;
342 int iindx;
343 int npts_temp;
344 int icap_temp;
345 int nlast;
346 float xpts_temp[1000];
347 float ypts_temp[1000];
348
349 npts_temp = *npts;
350 icap_temp = *icap;
351
352 if (OPEN_FLAG_AQUA > 0) {
353 if (icap_temp == 2) {
354 aqtSetLineCapStyle(AQTRoundLineCapStyle);
355 } else if (icap_temp == 3) {
356 aqtSetLineCapStyle(AQTSquareLineCapStyle);
357 } else {
358 aqtSetLineCapStyle(AQTButtLineCapStyle);
359 }
360
361 nlast = npts_temp;
362 if (nlast > 1000) nlast = 1000;
363 for (i = 0; i < nlast; i++) {
364 /* iindx=2*i; */
365 iindx=i;
366 xpts_temp[i] = xpts[iindx];
367 ypts_temp[i] = ypts[iindx];
368 }
369
370 if (npts_temp > 0) {
371 aqtAddPolyline(xpts_temp, ypts_temp, npts_temp);
372 }
373 }
374
375 }
376
377 /* AQMOVE - move to a point
378 *
379 * ax1 - contains the x coordinate
380 * ay1 - contains the y coordinate
381 *
382 */
383 #if APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 1
aqmove_(ax1,ay1)384 void aqmove_(ax1, ay1)
385 #elif APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 0
386 void AQMOVE_(ax1,a1)
387 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 1
388 void aqmove(ax1,ay1)
389 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 0
390 void AQMOVE(ax1,ay1)
391 #endif
392 double *ax1, *ay1;
393 {
394 float ax1_temp;
395 float ay1_temp;
396
397 ax1_temp = *ax1;
398 ay1_temp = *ay1;
399
400 aqtMoveTo(ax1_temp,ay1_temp);
401
402 }
403
404 /* AQSECO - set the color
405 *
406 * jcol - index for desired color
407 *
408 */
409 #if APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 1
aqseco_(jcol)410 void aqseco_(jcol)
411 #elif APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 0
412 void AQSECO_(jcol)
413 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 1
414 void aqseco(jcol)
415 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 0
416 void AQSECO(jcol)
417 #endif
418 int *jcol;
419 {
420 int jcol_temp;
421 float avalue;
422
423 jcol_temp = *jcol;
424
425 if (OPEN_FLAG_AQUA > 0) {
426 if (jcol_temp > 0) {
427 aqtTakeColorFromColormapEntry(jcol_temp-1);
428 } else {
429 avalue = -(float)jcol_temp/100.;
430 aqtSetColor(avalue,avalue,avalue);
431 }
432 }
433
434 }
435
436 /* AQSEC2 - set the color using RGB specification
437 *
438 * jred - index for red component
439 * jgreen - index for green component
440 * jblue - index for blue component
441 *
442 */
443 #if APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 1
aqsec2_(jred,jgreen,jblue)444 void aqsec2_(jred,jgreen,jblue)
445 #elif APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 0
446 void AQSEC2_(jred,jgreen,jblue)
447 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 1
448 void aqsec2(jred,jgreen,jblue)
449 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 0
450 void AQSEC2(jred,jgreen,jblue)
451 #endif
452 float *jred;
453 float *jgreen;
454 float *jblue;
455 {
456 float avalue1;
457 float avalue2;
458 float avalue3;
459
460 avalue1 = *jred;
461 avalue2 = *jgreen;
462 avalue3 = *jblue;
463
464 if (avalue1 < 0) {
465 avalue1 = 0.0;
466 }
467 if (avalue1 > 1) {
468 avalue1=1.0;
469 }
470 if (avalue2 < 0) {
471 avalue2 = 0.0;
472 }
473 if (avalue2 > 1) {
474 avalue2=1.0;
475 }
476 if (avalue3 < 0) {
477 avalue3 = 0.0;
478 }
479 if (avalue3 > 1) {
480 avalue3=1.0;
481 }
482
483 if (OPEN_FLAG_AQUA > 0) {
484 aqtSetColor(avalue1,avalue2,avalue3);
485 }
486
487 }
488
489 /* AQSEPA - set line attribute (color set in AQSECO):
490 *
491 * jpatt - the line pattern
492 * pthick - the line thickness (in points)
493 *
494 */
495 #if APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 1
aqsepa_(xpatt,npatt,pthick,iopt)496 void aqsepa_(xpatt,npatt,pthick,iopt)
497 #elif APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 0
498 void AQSEPA_(xpatt,npatt,pthick,iopt)
499 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 1
500 void aqsepa(xpatt,npatt,pthick,iopt)
501 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 0
502 void AQSEPA(xpatt,npatt,pthick,iopt)
503 #endif
504 double xpatt[];
505 double *pthick;
506 int *npatt;
507 int *iopt;
508 {
509 int npatt_temp;
510 int iopt_temp;
511 int iindx;
512 int i;
513 int nlast;
514 float pthick_temp;
515 float xpatt_temp[8];
516
517 pthick_temp = *pthick;
518 npatt_temp = *npatt;
519 iopt_temp = *iopt;
520
521 nlast = npatt_temp;
522 if (nlast > 7) nlast = 7;
523 for (i = 0; i < nlast; i++) {
524 /* iindx=2*i; */
525 iindx=i;
526 xpatt_temp[i] = xpatt[iindx];
527 }
528
529 if (OPEN_FLAG_AQUA > 0) {
530 if (iopt_temp == 1) {
531 if (npatt_temp <= 1) {
532 aqtSetLinestyleSolid();
533 } else {
534 aqtSetLinestylePattern(xpatt_temp,npatt_temp,0.0);
535 }
536 }
537 if (iopt_temp == 2) {
538 aqtSetLinewidth(pthick_temp);
539 }
540 }
541
542 }
543
544 /* AQSESI - set character size
545 *
546 * pheigh - the desired point size
547 *
548 */
549 #if APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 1
aqsesi_(pheigh)550 void aqsesi_(pheigh)
551 #elif APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 0
552 void AQSESI_(pheigh)
553 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 1
554 void aqsesi(pheigh)
555 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 0
556 void AQSESI(pheigh)
557 #endif
558 double *pheigh;
559 {
560 float pheigh_temp;
561
562 pheigh_temp = *pheigh;
563
564 if (OPEN_FLAG_AQUA > 0) {
565 aqtSetFontsize(pheigh_temp);
566 }
567
568 }
569
570 /* AQPOIN - draw a point.
571 *
572 * ix - contains the x coordinate
573 * iy - contains the y coordinate
574 * jcol - color to use in drawing the point
575 *
576 */
577 #if APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 1
aqpoin_(ix,iy,ired,igreen,iblue)578 void aqpoin_(ix, iy, ired, igreen, iblue)
579 #elif APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 0
580 void AQPOIN_(ix, iy, ired, igreen, iblue)
581 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 1
582 void aqpoin(ix, iy, ired, igreen, iblue)
583 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 0
584 void AQPOIN(ix, iy, ired, igreen, iblue)
585 #endif
586 int *ix, *iy;
587 int *ired, *igreen, *iblue;
588 {
589
590 unsigned char rgbImage[3] = {255, 255, 255};
591 int ixtemp;
592 int iytemp;
593 int ired_temp;
594 int igreen_temp;
595 int iblue_temp;
596
597 ixtemp = *ix;
598 iytemp = *iy;
599 ired_temp = *ired;
600 igreen_temp = *igreen;
601 iblue_temp = *iblue;
602
603 rgbImage[0] = ired_temp;
604 rgbImage[1] = igreen_temp;
605 rgbImage[2] = iblue_temp;
606
607 aqtAddImageWithBitmap(rgbImage,1,1,ixtemp,iytemp,4,4);
608
609 }
610
611 /* AQRECT - fill a rectangle.
612 *
613 * ix1 - start x position
614 * iy1 - start y position
615 * ix2 - length of x
616 * iy2 - length of y
617 * otherwise, a convex polygon)
618 *
619 */
620 #if APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 1
aqrect_(ix1,iy1,ix2,iy2)621 void aqrect_(ix1, iy1, ix2, iy2)
622 #elif APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 0
623 void AQRECT_(ix1, iy1, ix2, iy2)
624 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 1
625 void aqrect(ix1, iy1, ix2, iy2)
626 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 0
627 void AQRECT(ix1, iy1, ix2, iy2)
628 #endif
629 int *ix1;
630 int *iy1;
631 int *ix2;
632 int *iy2;
633 {
634 int ix1_temp;
635 int iy1_temp;
636 int ix2_temp;
637 int iy2_temp;
638
639 ix1_temp = *ix1;
640 iy1_temp = *iy1;
641 ix2_temp = *ix2;
642 iy2_temp = *iy2;
643
644 if (OPEN_FLAG_AQUA > 0) {
645 aqtAddFilledRect(ix1_temp, iy1_temp, ix2_temp, iy2_temp);
646 }
647
648 }
649
650 /* AQRGFL - fill a region. Rectangular regions will be filled differently
651 * non-rectangular regions. Dataplot only handles convex polygons,
652 * so set this (for faster performance). This routine only does
653 * solid fills. Hatch patterns must be drawn
654 * by the calling program (i.e., send the individual lines to
655 * the AQDRAW routine).
656 *
657 * xpts - contains the x coordinates
658 * ypts - contains the y coordinates
659 * npts - the number of points in the polygon (if 2, assume a rectangle,
660 * otherwise, a convex polygon)
661 *
662 */
663 #define MAX_REG_POINTS 100
664 #if APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 1
aqrgfl_(xpts,ypts,npts)665 void aqrgfl_(xpts, ypts, npts)
666 #elif APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 0
667 void AQRGFL_(xpts, ypts, npts)
668 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 1
669 void aqrgfl(xpts, ypts, npts)
670 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 0
671 void AQRGFL(xpts, ypts, npts)
672 #endif
673 double xpts[], ypts[];
674 int *npts;
675 {
676 int i;
677 int iindx;
678 int npts_temp;
679 int nlast;
680 float xpts_temp[MAX_REG_POINTS];
681 float ypts_temp[MAX_REG_POINTS];
682
683 npts_temp = *npts;
684 nlast = MAX_REG_POINTS;
685 if (nlast > MAX_REG_POINTS) nlast = MAX_REG_POINTS;
686 for (i = 0; i < nlast; i++) {
687 /* iindx=2*i; */
688 iindx=i;
689 xpts_temp[i] = xpts[iindx];
690 ypts_temp[i] = ypts[iindx];
691 }
692
693 if (OPEN_FLAG_AQUA > 0) {
694 aqtAddPolygon(xpts_temp, ypts_temp, npts_temp);
695 }
696
697 }
698
699 /* AQTXTH - draw a horizontal text string.
700 *
701 * string - text string to draw
702 * ixpos - x position
703 * iypos - y position
704 * ijusth - justification (horizontal)
705 * 0 - left justified
706 * 1 - center justified
707 * 2 - right justified
708 * ijustv - justiciation (vertical)
709 * 0 - center justified
710 * 1 - bottom justified
711 * 2 - top justified
712 * font - font name
713 * error - error flag
714 *
715 */
716 #if APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 1
aqtxth_(string,ixpos,iypos,ijusth,ijustv,font,error)717 void aqtxth_(string, ixpos, iypos, ijusth, ijustv, font, error)
718 #elif APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 0
719 void AQTXTH_(string, ixpos, iypos, ijusth, ijustv, font, error)
720 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 1
721 void aqtxth(string, ixpos, iypos, ijusth, ijustv, font, error)
722 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 0
723 void AQTXTH(string, ixpos, iypos, ijusth, ijustv, font, error)
724 #endif
725 int string[];
726 int font[];
727 int *ixpos;
728 int *iypos;
729 int *ijusth;
730 int *ijustv;
731 int *error;
732 {
733
734 int len; /* number of characters in string */
735 int len2; /* number of characters in string */
736 int string_width; /* width of string in pixels */
737 char string2[130]; /* converted string */
738 char font2[130]; /* font name */
739 int i;
740 int ixpos_temp;
741 int iypos_temp;
742 int ijusth_temp;
743 int ijustv_temp;
744 int error_temp;
745 float xpos;
746 float ypos;
747
748 ixpos_temp = *ixpos;
749 iypos_temp = *iypos;
750 ijusth_temp = *ijusth;
751 ijustv_temp = *ijustv;
752
753 i_to_s_4(string, string2, 130, &len);
754 i_to_s_4(font, font2, 130, &len2);
755
756 if (len2 > 1) {
757 aqtSetFontname(font2);
758 }
759
760 xpos = (float)ixpos_temp;
761 ypos = (float)iypos_temp;
762 if (ijusth_temp == 0 && ijustv_temp == 0) { /* Left-bottom */
763 aqtAddLabel(string2,xpos,ypos,0.0,(AQTAlignLeft | AQTAlignBottom));
764 } else if (ijusth_temp == 0 && ijustv_temp == 1) { /* Left-center */
765 aqtAddLabel(string2,xpos,ypos,0.0,(AQTAlignLeft | AQTAlignMiddle));
766 } else if (ijusth_temp == 0 && ijustv_temp == 2) { /* Left-Top */
767 aqtAddLabel(string2,xpos,ypos,0.0,(AQTAlignLeft | AQTAlignTop));
768 } else if (ijusth_temp == 1 && ijustv_temp == 0) { /* Center-bottom */
769 aqtAddLabel(string2,xpos,ypos,0.0,(AQTAlignCenter | AQTAlignBottom));
770 } else if (ijusth_temp == 1 && ijustv_temp == 1) { /* Center-Center */
771 aqtAddLabel(string2,xpos,ypos,0.0,(AQTAlignCenter | AQTAlignMiddle));
772 } else if (ijusth_temp == 1 && ijustv_temp == 2) { /* Center-Top */
773 aqtAddLabel(string2,xpos,ypos,0.0,(AQTAlignCenter | AQTAlignTop));
774 } else if (ijusth_temp == 2 && ijustv_temp == 0) { /* Right-bottom */
775 aqtAddLabel(string2,xpos,ypos,0.0,(AQTAlignRight | AQTAlignBottom));
776 } else if (ijusth_temp == 2 && ijustv_temp == 1) { /* Right-Center */
777 aqtAddLabel(string2,xpos,ypos,0.0,(AQTAlignRight | AQTAlignMiddle));
778 } else if (ijusth_temp == 2 && ijustv_temp == 2) { /* Right-Top */
779 aqtAddLabel(string2,xpos,ypos,0.0,(AQTAlignRight | AQTAlignTop));
780 } else {
781 aqtAddLabel(string2,xpos,ypos,0.0,(AQTAlignLeft | AQTAlignBottom));
782 }
783
784 }
785
786 /* AQTXTV - draw a vertical text string.
787 *
788 * string - text string to draw
789 * ixpos - x position
790 * iypos - y position
791 * ijusth - justification (horizontal)
792 * 0 - left justified
793 * 1 - center justified
794 * 2 - right justified
795 * ijustv - justiciation (vertical)
796 * 0 - center justified
797 * 1 - bottom justified
798 * 2 - top justified
799 * font - font name
800 * error - error flag
801 *
802 */
803 #if APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 1
aqtxtv_(string,ixpos,iypos,ijusth,ijustv,font,error)804 void aqtxtv_(string, ixpos, iypos, ijusth, ijustv, font, error)
805 #elif APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 0
806 void AQTXTV_(string, ixpos, iypos, ijusth, ijustv, font, error)
807 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 1
808 void aqtxtv(string, ixpos, iypos, ijusth, ijustv, font, error)
809 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 0
810 void AQTXTV(string, ixpos, iypos, ijusth, ijustv, font, error)
811 #endif
812 int string[];
813 int font[];
814 int *ixpos;
815 int *iypos;
816 int *ijusth;
817 int *ijustv;
818 int *error;
819 {
820
821 int len; /* number of characters in string */
822 int string_width; /* width of string in pixels */
823 char string2[130]; /* converted string */
824 char font2[130]; /* font name */
825 int i;
826 int ixpos_temp;
827 int iypos_temp;
828 int ijusth_temp;
829 int ijustv_temp;
830 int error_temp;
831 float xpos;
832 float ypos;
833
834 ixpos_temp = *ixpos;
835 iypos_temp = *iypos;
836 ijusth_temp = *ijusth;
837 ijustv_temp = *ijustv;
838
839 i_to_s_4(string, string2, 130, &len);
840 i_to_s_4(font, font2, 130, &len);
841
842 xpos = (float)ixpos_temp;
843 ypos = (float)iypos_temp;
844 if (ijusth_temp == 0 && ijustv_temp == 0) { /* Left-bottom */
845 aqtAddLabel(string2,xpos,ypos,90.0,(AQTAlignLeft | AQTAlignBottom));
846 } else if (ijusth_temp == 0 && ijustv_temp == 1) { /* Left-center */
847 aqtAddLabel(string2,xpos,ypos,90.0,(AQTAlignLeft | AQTAlignMiddle));
848 } else if (ijusth_temp == 0 && ijustv_temp == 2) { /* Left-Top */
849 aqtAddLabel(string2,xpos,ypos,90.0,(AQTAlignLeft | AQTAlignTop));
850 } else if (ijusth_temp == 1 && ijustv_temp == 0) { /* Center-bottom */
851 aqtAddLabel(string2,xpos,ypos,90.0,(AQTAlignCenter | AQTAlignBottom));
852 } else if (ijusth_temp == 1 && ijustv_temp == 1) { /* Center-Center */
853 aqtAddLabel(string2,xpos,ypos,90.0,(AQTAlignCenter | AQTAlignMiddle));
854 } else if (ijusth_temp == 1 && ijustv_temp == 2) { /* Center-Top */
855 aqtAddLabel(string2,xpos,ypos,90.0,(AQTAlignCenter | AQTAlignTop));
856 } else if (ijusth_temp == 2 && ijustv_temp == 0) { /* Right-bottom */
857 aqtAddLabel(string2,xpos,ypos,90.0,(AQTAlignRight | AQTAlignBottom));
858 } else if (ijusth_temp == 2 && ijustv_temp == 1) { /* Right-Center */
859 aqtAddLabel(string2,xpos,ypos,90.0,(AQTAlignRight | AQTAlignMiddle));
860 } else if (ijusth_temp == 2 && ijustv_temp == 2) { /* Right-Top */
861 aqtAddLabel(string2,xpos,ypos,90.0,(AQTAlignRight | AQTAlignTop));
862 } else {
863 aqtAddLabel(string2,xpos,ypos,90.0,(AQTAlignLeft | AQTAlignBottom));
864 }
865
866 }
867
868 /* AQRDLO - routine to read a position from the graphics window (used
869 * by the Dataplot cross-hair command). The mouse position at
870 * the next mouse click will be determined.
871 *
872 * This routine will wait until a mouse button is pressed.
873 *
874 * ixret - x coordinate of mouse position when button pressed
875 * iyret - y coordinate of mouse position when button pressed
876 * error - error flag
877 *
878 */
879 #if APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 1
aqrdlo_(ixret,iyret,error)880 void aqrdlo_(ixret, iyret, error)
881 #elif APPEND_UNDERSCORE == 1 && SUBROUTINE_CASE == 0
882 void AQRDLO_(ixret, iyret, error)
883 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 1
884 void aqrdlo(ixret, iyret, error)
885 #elif APPEND_UNDERSCORE == 0 && SUBROUTINE_CASE == 0
886 void AQRDLO(ixret, iyret, error)
887 #endif
888 int *ixret, *iyret, *error;
889 {
890 int running = 0;
891 char buffer[AQT_EVENTBUF_SIZE];
892 int x, y;
893
894
895 *ixret = -1;
896 *iyret = -1;
897 *error = 0;
898
899 running = 0;
900 while (running == 0) { /* loop until mouse click */
901
902 aqtSelectPlot(1);
903 aqtWaitNextEvent(buffer);
904 switch (decodeEvent(buffer, &x, &y)) {
905
906 case 0: /* Null Event */
907 *error = 1;
908 running = 1;
909 break;
910
911 case -1: /* Error */
912 *error = 1;
913 running = 1;
914 break;
915
916 case 1: /* Mouse Click */
917 *ixret = x;
918 *iyret = y;
919 running = 1;
920 break;
921
922 default:
923 *error = 1;
924 running = 1;
925 break;
926 } /* end switch */
927 } /* end while */
928
929 }
930
931 /* i_to_s_4 - utitlity routine to convert an integer array containing
932 * Ascii Decimal Equivalents to a character string array. The
933 * Fortran routines pass character type data as an array of
934 * ADE's, which this routine then converts to C's character
935 * type. Note that the input array is assumed to be correct
936 * (i.e., a value between 0 and 127) and no error checking is
937 * done on it.
938 *
939 * string1 - input array containing ADE's.
940 * string2 - output array in C character format.
941 * maxlen - maximum length for string2
942 * ilen - length of character string
943 *
944 */
i_to_s_4(string1,string2,maxlen,ilen)945 void i_to_s_4(string1, string2, maxlen, ilen)
946 int string1[], maxlen, *ilen;
947 char string2[];
948
949 {
950 int i;
951 int itemp;
952 i = 0;
953 while (string1[i] != 0 && i < (maxlen - 1) ) {
954 itemp = string1[i];
955 string2[i] = string1[i];
956 i++;
957 }
958 *ilen = i;
959 string2[i]='\0';
960 }
961
decodeEvent(char * event,int * x,int * y)962 int decodeEvent(char *event, int *x, int *y)
963 {
964 /* int x, y; */
965 char **ap, *argv[10];
966
967 /* Split arguments separated by a ':' */
968 for (ap = argv; (*ap = strsep(&event, ":")) != NULL;)
969 if (**ap != '\0')
970 if (++ap >= &argv[10])
971 break;
972
973 if (strcmp(argv[0], "42") >= 0) /* Check for server error */
974 return -1;
975
976 if (argv[0][0] != '1') /* Only check for mouse clicks */
977 return 0;
978
979 /* sscanf(argv[1], "{%d ,%d}", &x, &y); */ /* Decode Position */
980 return 1;
981 }
982
983