1 /*-----[--.----+----.----+----.-----------------------------------------*/
2
3 /* * * F E A P * * A Finite Element Analysis Program */
4
5 /*.... Copyright (c) 1984-2017: Regents of the University of California*/
6 /* All rights reserved */
7 /*----[--.----+----.----+----.-----------------------------------------]
8 * Modification log Date (dd-mm-year)
9 * 1. Add cinput() 23-10-2017
10 */
11 /*-----[--.----+----.----+----.-----------------------------------------*/
12 /* Purpose: FEAP driver for X windows Version 11, Release 6. */
13
14 /* Inputs: */
15
16 /* Outputs: */
17 /*-----[--.----+----.----+----.-----------------------------------------*/
18
19 /*********************************/
20 /* Driver configuration */
21 /* X11 DEVICE DRIVER */
22 /* Change 6-places for EACH */
23 /* Type of workstation Search */
24 /* for string FORTRAN to change */
25 /* Currently set: Underscore */
26 /* Version for: Underscore */
27 /* GCC, INTEL, SUN & DEC */
28 /* Version for: No Underscore */
29 /* HP and IBM */
30 /*********************************/
31
32 /* This driver supports the traditional GIN mode, i.e. point the cursor */
33 /* and strike a key! It also supports the use of the mouse buttons */
34 /* during GIN input. Below is the mouse button to "key" relationships. */
35
36 #define BUTTON1_KEY 'l'
37 #define BUTTON2_KEY 'm'
38 #define BUTTON3_KEY 'r'
39
40 /* This driver has the capability to store all the lines drawn into the */
41 /* X Window and to use these saved lines to refresh the screen. */
42 /* Using this feature and the routine "gdx11_refresh_window" should */
43 /* make using FEAP under X11 easier than before! */
44 /* If you don't want/need this feature or if you can't afford the */
45 /* memory usage, set MAX_SEG to 1, MAX_POINTS to something around 100 */
46
47 #define MAX_POINTS 1000 /* Maximum points in all polylines stored */
48 #define MAX_SEG 100 /* Maximum polylines stored */
49 #define MAX_TEXT 100 /* Maximum 80-character text string */
50
51 #define DEBUG 0 /* 0 == No debugging. */
52 /* 1 == Soft X11 errors */
53 /* 2 == Above plus caller bugs */
54 /* 3 == Above plus Driver tracing messages */
55 /* 4 == Above plus all tracing messages */
56
57 /****************************/
58 /* Non-FEAP include files */
59 /****************************/
60
61 #include <stdio.h> /* Unix standard I/O definitions */
62 #include <stdlib.h> /* Use "malloc", "calloc" and "free" */
63 #include <string.h>
64 #include <X11/Xlib.h>
65 #include <X11/Xutil.h>
66 #include <X11/cursorfont.h>
67
68 /* #include <sys/select.h> Use this include instead of next 3
69 on POSIX systems */
70 #include <sys/types.h>
71 #include <sys/time.h>
72 #include <unistd.h>
73
74 #include "digwin.h"
75 /*void jpgd(); */
76
77 /* Note: if you don't have the file "malloc.h", then use the following: */
78 /* extern char *malloc(); */
79 /* extern void free(); */
80
81 /**************************/
82 /* Gray scale definitions */
83 /**************************/
84
85 #define gray1_width 16
86 #define gray1_height 16
87 static char gray1_bits [] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
88 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
89 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
90 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
91
92 #define gray2_width 4
93 #define gray2_height 4
94 static char gray2_bits [] = {0x07, 0x0d, 0x07, 0x0d};
95
96 #define gray3_width 16
97 #define gray3_height 4
98 static char gray3_bits [] = {0x55, 0x55, 0xee, 0xee, 0x55, 0x55, 0xbb, 0xbb};
99
100 #define gray4_width 16
101 #define gray4_height 16
102 static char gray4_bits [] = {0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0x33, 0x33,
103 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0x33, 0x33,
104 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0x33, 0x33,
105 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0x33, 0x33};
106
107 #define gray5_width 2
108 #define gray5_height 2
109 static char gray5_bits [] = {0x01, 0x02};
110
111 #define gray6_width 16
112 #define gray6_height 16
113 static char gray6_bits [] = {0x55, 0x55, 0x88, 0x88, 0x55, 0x55, 0x22, 0x22,
114 0x55, 0x55, 0x88, 0x88, 0x55, 0x55, 0x22, 0x22,
115 0x55, 0x55, 0x88, 0x88, 0x55, 0x55, 0x22, 0x22,
116 0x55, 0x55, 0x88, 0x88, 0x55, 0x55, 0x22, 0x22};
117
118 #define gray7_width 4
119 #define gray7_height 4
120 static char gray7_bits [] = {0x08, 0x02, 0x08, 0x02};
121
122 #define gray8_width 16
123 #define gray8_height 16
124 static char gray8_bits [] = {0x11, 0x11, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
125 0x11, 0x11, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
126 0x11, 0x11, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
127 0x11, 0x11, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00};
128
129 #define STROKE_DEVICE 0
130 #define RASTER_DEVICE 1
131 #define DVST_DEVICE 2
132 #define PLOTTER_DEVICE 3
133
134 #define CAN_DRAW_IN_BACKGROUND 4
135 #define HARDCOPY_DEVICE 8
136 #define SHARED_DEVICE 16
137 #define HLS_SETABLE_COLORS 32
138 #define RGB_SETABLE_COLORS 64
139 #define CAN_DO_GIN 128
140 #define CAN_DRAW_FILLED_POLYGONS 256
141 #define CONVEX_POLYGONS_ONLY 512
142 #define CAN_DO_LOCATOR_INPUT 1024
143
144 /***************************/
145 /* Some global definitions */
146 /***************************/
147
148 #define MAX_OPCODE 16 /* number of op-code values */
149
150 #define DEFAULT_X 485 /* X Window Location on Screen */
151 #define DEFAULT_Y 165 /* Y Window Location on Screen */
152
153 static DIGWin *current_dw = NULL;
154 static DIGWin *default_dw = NULL;
155 static int default_width = 768; /* X Window width (default) */
156 static int default_height = 600; /* Y Window width (default) */
157
158 #define Min(x,y) ( ((float)x < (float)y ) ? (float)x : (float)y )
159
160 /*******************************************************************/
161 /* Device coordinates <--> Virtual corrdinates, translation macros */
162 /*******************************************************************/
163
164 #define x_translate(dw,x) (int)((x)*dw->x_scale-1.5)+dw->x_offset
165 #define y_translate(dw,y) (int)(dw->y_len-(y)*dw->y_scale-1.5)+dw->y_offset
166 #define x_untranslate(dw,x) ((x)-dw->x_offset)/dw->x_scale
167 #define y_untranslate(dw,y) (dw->y_len+dw->y_offset-(y))/dw->y_scale
168
169 /*********************************/
170 /*** Window Management Support ***/
171 /*********************************/
172
173 /********************/
174 /* Clear the Pixmap */
175 /********************/
176
gdx11_clear_pixmap(DIGWin * dw)177 void gdx11_clear_pixmap(DIGWin *dw)
178 {
179 XSetForeground(dw->xdisplay, dw->xgc,
180 (unsigned long)dw->pixel_value_for_color[0]);
181 XFillRectangle(dw->xdisplay, dw->svimage,
182 dw->xgc, 0, 0, dw->xwa.width, dw->xwa.height);
183 XSetForeground(dw->xdisplay, dw->xgc,
184 (unsigned long)dw->pixel_value_for_color[1]);
185 }
186
187 /*******************************************************************/
188 /* Adjust the scale of the diglib device to fit the current window */
189 /* given the user's guidelines for what part of the window to use.*/
190 /*******************************************************************/
191
gdx11_adjust_digwin(dw)192 void gdx11_adjust_digwin(dw)
193 DIGWin *dw;
194 {
195
196 int x,y;
197 unsigned int width, height, depth, bdw;
198 Status status;
199 Window root;
200
201 /* static void gdx11_init_polylines(), gdx11_init_strings(); */
202 void gdx11_init_polylines(), gdx11_init_strings();
203
204 XGetWindowAttributes(dw->xdisplay,dw->xwin,&(dw->xwa));
205 dw->x_offset = (dw->min_x*dw->xwa.width)/100+dw->x_border;
206 dw->y_offset = (dw->min_y*dw->xwa.height)/100+dw->y_border;
207 dw->x_len = ((dw->max_x-dw->min_x)*dw->xwa.width)/100-dw->x_border;
208 dw->y_len = ((dw->max_y-dw->min_y)*dw->xwa.height)/100-dw->y_border;
209
210 /* Check is the size has actually changed, if so reset pixmap */
211 status = XGetGeometry(dw->xdisplay, dw->svimage,
212 &root, &x, &y, &width, &height, &bdw, &depth);
213
214 if( width != dw->xwa.width || height != dw->xwa.height || status == 0) {
215 dw->svimage = XCreatePixmap(dw->xdisplay,dw->xwin,
216 dw->xwa.width,dw->xwa.height,
217 dw->xwa.depth);
218 gdx11_clear_pixmap(dw);
219 gdx11_init_polylines(dw);
220 gdx11_init_strings(dw);
221 }
222 }
223
224 /*****************************/
225 /* Refresh the FEAP window */
226 /*****************************/
227
gdx11_refresh_digwin(dw)228 void gdx11_refresh_digwin(dw)
229 DIGWin *dw;
230 {
231 int i,j,x,y,l,flag,width ;
232 int start = 0;
233 Display *disp = dw->xdisplay;
234 unsigned long fg_pv;
235 unsigned long bg_pv;
236 int fg_gray = 0;
237 int pv;
238 int gray_pv;
239 int np;
240 char text[80] ;
241 Font nfont ;
242 XFontStruct *nfont_struct ;
243
244 fg_pv = (unsigned long)dw->polyline_pixel_value[0];
245 XSetForeground(disp,dw->xgc,fg_pv);
246 if(dw->num_fg_colors == 1) {
247 fg_gray = dw->polyline_gray_value[0];
248 XSetStipple(disp,dw->xgc_mono_fill,dw->gray[fg_gray]);
249 }
250 for (i=0;i<dw->npolylines;++i)
251 {
252 if ((pv=dw->polyline_pixel_value[i])!=(int)fg_pv)
253 {
254 fg_pv = (unsigned long)pv;
255 XSetForeground(disp,dw->xgc,fg_pv);
256 }
257 np = dw->npoints[i];
258 if (np<0)
259 {
260 np = -np;
261 if (dw->num_fg_colors > 1){
262 XFillPolygon(disp,dw->svimage,dw->xgc,&(dw->points[start]),np,
263 Complex,CoordModeOrigin);}
264
265 /*Monochrome gray scale stuff */
266 else {
267 if( (gray_pv=dw->polyline_gray_value[i]) != fg_gray) {
268 fg_gray = gray_pv;
269 XSetStipple(disp,dw->xgc_mono_fill,dw->gray[fg_gray]);
270 }
271 XFillPolygon(disp,dw->xwin,dw->xgc_mono_fill,
272 &(dw->points[start]),np,Complex,CoordModeOrigin);
273 }
274 }
275 else {
276 XDrawLines(disp,dw->svimage,dw->xgc,&(dw->points[start]),
277 np,CoordModeOrigin);}
278 start = start+np;
279 }
280
281 if (dw->nstrings == 0) return ;
282
283 fg_pv = (unsigned long)dw->pixel_value_for_color[1];
284 bg_pv = (unsigned long)dw->pixel_value_for_color[0];
285
286 XSetBackground(disp,dw->xgc,bg_pv);
287 XSetForeground(disp,dw->xgc,fg_pv);
288
289 if ( Min ( dw->x_len , 1.27*dw->y_len ) < 440 )
290 nfont = XLoadFont(disp,"*helvetica-medium-r-normal--8*");
291 else if ( Min ( dw->x_len , 1.27*dw->y_len ) < 600. )
292 nfont = XLoadFont(disp,"*helvetica-bold-r-normal--10*");
293 else if ( Min ( dw->x_len , 1.27*dw->y_len ) < 760. )
294 nfont = XLoadFont(disp,"*helvetica-bold-r-normal--12*");
295 else if ( Min ( dw->x_len , 1.27*dw->y_len ) < 920. )
296 nfont = XLoadFont(disp,"*helvetica-bold-r-normal--14*");
297 else if ( Min ( dw->x_len , 1.27*dw->y_len ) < 1080. )
298 nfont = XLoadFont(disp,"*helvetica-bold-r-normal--18*");
299 else
300 nfont = XLoadFont(disp,"*helvetica-bold-r-normal--20*");
301
302 nfont_struct = XQueryFont(disp,nfont);
303
304 XSetFont(disp,dw->xgc,nfont);
305
306 start = 0 ;
307
308 for (i = 0 ; i < dw->nstrings ; ++i )
309 {
310 x = dw->textx[i] ;
311 y = dw->texty[i] ;
312 l = dw->strlen[i] ;
313 flag = dw->strflg[i] ;
314
315 for (j = 0 ; j < l ; ++j )
316 {
317 text[j] = dw->strings[start+j] ;
318 }
319 if (flag == 1)
320 {
321 width = XTextWidth(nfont_struct,text,l) ;
322 x = x - width/2 ;
323 }
324
325 XDrawImageString(disp,dw->svimage,dw->xgc,x,y,text,l);
326
327 start = start + 80 ;
328 }
329 XFreeFont(disp, nfont_struct );
330
331 return;
332 }
333 /* Color map for FEAPpv */
334
335 static char colors[6][10] = { "RED" ,
336 "GREEN" ,
337 "BLUE" ,
338 "YELLOW" ,
339 "CYAN" ,
340 "MAGENTA"};
341
342 /**********************************/
343 /* Make XWindow into FEAP XWindow */
344 /**********************************/
345
gdx11_make_digwin_from_xwin(display,xwindow,back_pixel,fore_pixel,x_border,y_border,min_x,max_x,min_y,max_y)346 DIGWin *gdx11_make_digwin_from_xwin(display,xwindow,
347 back_pixel,fore_pixel,
348 x_border,y_border,
349 min_x,max_x,min_y,max_y)
350 Display *display;
351 Window xwindow;
352 unsigned long back_pixel, fore_pixel;
353 int x_border, y_border;
354 int min_x, max_x, min_y, max_y;
355 {
356 DIGWin *dw;
357 Screen *screen;
358 Colormap cmap;
359 XColor screen_def, exact_def;
360 XGCValues setgc;
361 int color;
362 int colors_allocated;
363
364 if ((dw = (DIGWin *)calloc(sizeof(DIGWin), sizeof(int)))==NULL)
365 {
366 fprintf(stderr,"FEAP X11 Driver unable to get window memory!\n");
367 exit(0);
368 }
369 dw->npoints = (int *)calloc(MAX_SEG+1 , sizeof(int));
370
371 dw->strlen = (int *)calloc(MAX_TEXT , sizeof(int));
372 dw->strflg = (int *)calloc(MAX_TEXT , sizeof(int));
373 dw->strings = (char *)calloc(80*MAX_TEXT, sizeof(char));
374 dw->textx = (int *)calloc(MAX_TEXT , sizeof(int));
375 dw->texty = (int *)calloc(MAX_TEXT , sizeof(int));
376
377 dw->polyline_pixel_value = (int *)calloc(MAX_SEG+1, sizeof(int));
378 dw->polyline_gray_value = (int *)calloc(MAX_SEG+1, sizeof(int));
379 dw->points = (XPoint *)calloc(MAX_POINTS, sizeof(XPoint));
380
381 dw->xdisplay = display;
382 dw->xwin = xwindow;
383
384 XGetWindowAttributes(display,xwindow,&(dw->xwa));
385 screen = dw->xwa.screen;
386 cmap = dw->xwa.colormap;
387
388 /* Get default colors */
389 dw->pixel_value_for_color[0] = (int)back_pixel;
390 dw->pixel_value_for_color[1] = (int)fore_pixel;
391 colors_allocated = 2;
392 if (CellsOfScreen(screen)>=3)
393 {
394 for (color=2;color<8;++color)
395 {
396 if (XAllocNamedColor(display,cmap,colors[color-2],
397 &screen_def,&exact_def))
398 {
399 dw->pixel_value_for_color[colors_allocated++] = (int)screen_def.pixel;
400 if (DEBUG>=3)
401 fprintf(stderr,"Color %s is pixel %d\n",
402 colors[color-2],dw->pixel_value_for_color[color]);
403 }
404 else
405 if (DEBUG>=2)
406 fprintf(stderr,"FEAP-X11: Unable to allocate color %s\n",
407 colors[color-2]);
408 }
409 }
410 else
411 if (DEBUG>=3) fprintf(stderr,"FEAP-X11: Monochrome window - no colors!\n");
412
413 dw->gray[0] = XCreateBitmapFromData(display,xwindow,gray1_bits,
414 gray1_width,gray1_height);
415 dw->gray[1] = XCreateBitmapFromData(display,xwindow,gray2_bits,
416 gray2_width,gray2_height);
417 dw->gray[2] = XCreateBitmapFromData(display,xwindow,gray3_bits,
418 gray3_width,gray3_height);
419 dw->gray[3] = XCreateBitmapFromData(display,xwindow,gray4_bits,
420 gray4_width,gray4_height);
421 dw->gray[4] = XCreateBitmapFromData(display,xwindow,gray5_bits,
422 gray5_width,gray5_height);
423 dw->gray[5] = XCreateBitmapFromData(display,xwindow,gray6_bits,
424 gray6_width,gray6_height);
425 dw->gray[6] = XCreateBitmapFromData(display,xwindow,gray7_bits,
426 gray7_width,gray7_height);
427 dw->gray[7] = XCreateBitmapFromData(display,xwindow,gray8_bits,
428 gray8_width,gray8_height);
429
430 dw->num_fg_colors = colors_allocated - 1;
431 dw->current_pixel_value = dw->pixel_value_for_color[1];
432
433 /* Get scale factors for the screen (and therefore for the window) */
434 dw->x_scale = ((double)WidthOfScreen(screen))/
435 (((double)WidthMMOfScreen(screen))/10.0);
436 dw->y_scale = ((double)HeightOfScreen(screen))/
437 (((double)HeightMMOfScreen(screen))/10.0);
438
439 /* Use portion of window user wants */
440 dw->x_border = x_border;
441 dw->y_border = y_border;
442 dw->min_x = min_x;
443 dw->max_x = max_x;
444 dw->min_y = min_y;
445 dw->max_y = max_y;
446
447 /* Create a GC for this window */
448 setgc.foreground = (unsigned long)dw->pixel_value_for_color[1];
449 setgc.background = (unsigned long)dw->pixel_value_for_color[0];
450 setgc.function = GXcopy;
451 setgc.line_width = 0;
452 setgc.line_style = LineSolid;
453 setgc.fill_style = FillSolid;
454 dw->xgc = XCreateGC(display,xwindow,
455 (GCForeground|GCBackground|GCFunction|GCLineWidth|
456 GCLineStyle|GCFillStyle),
457 &setgc);
458
459 /* Monochrome gray scale stuff */
460 if(dw->num_fg_colors == 1){
461 setgc.fill_style = FillStippled;
462 dw->xgc_mono_fill = XCreateGC(display,xwindow,
463 (GCForeground|GCBackground|GCFunction|GCLineWidth|
464 GCLineStyle|GCFillStyle),
465 &setgc);
466 XSetFillStyle(display,dw->xgc_mono_fill,FillOpaqueStippled);
467 }
468
469 /* Set up Pixmap for the displayed image */
470 XGetWindowAttributes(dw->xdisplay,dw->xwin,&(dw->xwa));
471 dw->x_offset = (dw->min_x*dw->xwa.width)/100+dw->x_border;
472 dw->y_offset = (dw->min_y*dw->xwa.height)/100+dw->y_border;
473 dw->x_len = ((dw->max_x-dw->min_x)*dw->xwa.width)/100-dw->x_border;
474 dw->y_len = ((dw->max_y-dw->min_y)*dw->xwa.height)/100-dw->y_border;
475
476 dw->svimage = XCreatePixmap(dw->xdisplay,dw->xwin,
477 dw->xwa.width,dw->xwa.height,
478 dw->xwa.depth);
479 gdx11_clear_pixmap(dw);
480
481 return(dw);
482 }
483
484 /****************************************/
485 /* Create a FEAP XWindow from scratch */
486 /****************************************/
487
gdx11_create_digwin(xservername,window_width,window_height)488 DIGWin *gdx11_create_digwin(xservername,window_width,window_height)
489 char *xservername ;
490 int window_width, window_height;
491 {
492 Display *disp;
493 Window xwin;
494 Screen *def_screen;
495 Colormap cmap;
496 XColor screen_def, exact_def;
497 XSetWindowAttributes setwin;
498 XSizeHints size_hints;
499 XEvent event;
500 DIGWin *dw;
501 unsigned long background_pixel, foreground_pixel;
502
503
504 /* Window Location on Screen */
505
506 if (!(disp = XOpenDisplay(xservername)))
507 {
508 fprintf(stderr,
509 "FEAP X11 Driver unable to open X windows connection.\n");
510 exit(0);
511 }
512 if (DEBUG>=4)
513 fprintf(stderr,"gdx11_init_device: Inform : X Display opened\n");
514
515 /* Get screen for window */
516 def_screen = DefaultScreenOfDisplay(disp);
517
518 /* Get colors straight */
519 cmap = DefaultColormapOfScreen(def_screen);
520 if (XAllocNamedColor(disp,cmap,"BLACK",&screen_def,&exact_def))
521 background_pixel = screen_def.pixel;
522 else
523 background_pixel = BlackPixelOfScreen(def_screen);
524 if (XAllocNamedColor(disp,cmap,"WHITE",&screen_def,&exact_def))
525 foreground_pixel = screen_def.pixel;
526 else
527 foreground_pixel = WhitePixelOfScreen(def_screen);
528
529 /* Setup gray scale masks */
530
531 /* Create an Xwindow */
532 setwin.event_mask = (ButtonPressMask|ExposureMask|StructureNotifyMask|
533 KeyPressMask);
534 setwin.background_pixel = background_pixel;
535 setwin.backing_store = Always;
536 /* setwin.save_under = True; */
537 xwin = XCreateWindow(disp,
538 RootWindowOfScreen(def_screen),
539 DEFAULT_X,DEFAULT_Y,
540 window_width,window_height,
541 4,
542 DefaultDepthOfScreen(def_screen),
543 InputOutput,
544 DefaultVisualOfScreen(def_screen),
545 (CWBackPixel|CWEventMask|CWBackingStore),
546 &setwin);
547
548 /* Map the window onto the display */
549 size_hints.x = 0 ;
550 size_hints.y = 0 ;
551 size_hints.width = window_width ;
552 size_hints.height = window_height ;
553 size_hints.min_width = 20;
554 size_hints.min_height = 20;
555 size_hints.flags = USPosition|PSize|PMinSize;
556 XSetStandardProperties(disp,xwin,"FEAP Graphics Window","FEAP Win",
557 None,0,0,&size_hints);
558 XMapWindow(disp,xwin);
559
560 /* Wait for exposure event before proceeding - otherwise, some */
561 /* drawing command might get tossed */
562 XWindowEvent(disp,xwin,ExposureMask,&event);
563
564 /* Now turn the XWindow into a FEAP XWindow */
565 dw = gdx11_make_digwin_from_xwin(disp,xwin,
566 background_pixel,foreground_pixel,
567 2,2,0,100,0,100);
568
569 return(dw);
570 }
571
572 /* FORTRAN Interface */
573
574 /* HP and IBM use :
575 DIGWin *gdx11cdw(xservername,widthptr,heightptr)
576 */
577 /* GCC, INTEL, SUN and DEC use :
578 */
gdx11cdw_(xservername,widthptr,heightptr)579 DIGWin *gdx11cdw_(xservername,widthptr,heightptr)
580 char *xservername;
581 int *widthptr, *heightptr;
582 {
583 return(gdx11_create_digwin(xservername,*widthptr,*heightptr));
584 }
585
586
587 /*****************************/
588 /* Set FEAP Drawing Window */
589 /*****************************/
590
gdx11_set_current_digwin(dw)591 DIGWin *gdx11_set_current_digwin(dw)
592 DIGWin *dw;
593 {
594 DIGWin *old_dw = current_dw;
595
596 current_dw = dw;
597
598 /* Force FEAP to do equivalent of a DEVSEL! This is necessary to get */
599 /* FEAP to notice the change in the window. Unfortunately, it also */
600 /* has the side effect of resetting all those things DEVSEL resets, */
601 /* e.g. line type, clipping limits, etc. */
602
603 /* Finally, return the old FEAP window */
604 return(old_dw);
605 }
606
607 /* FORTRAN Interace */
608 /* HP and IBM use :
609 DIGWin *gdx11setdw(dw)
610 */
611 /* GCC, INTEL, SUN and DEC use :
612 */
gdx11setdw_(dw)613 DIGWin *gdx11setdw_(dw)
614 DIGWin **dw;
615 {
616 return(gdx11_set_current_digwin(*dw));
617 }
618
619 /****************************/
620 /* Set Default Xwindow Size */
621 /****************************/
622
gdx11_set_def_window_size(width,height)623 void gdx11_set_def_window_size(width,height)
624 int width, height;
625 {
626 default_width = width;
627 default_height = height;
628 }
629
630 /* FORTRAN Interface */
631 /* HP and IBM use :
632 void gdx11setwindow(widthptr,heightptr)
633 */
634 /* GCC, INTEL, SUN and DEC use :
635 */
gdx11setwindow_(widthptr,heightptr)636 void gdx11setwindow_(widthptr,heightptr)
637 int *widthptr, *heightptr;
638 {
639 gdx11_set_def_window_size(*widthptr,*heightptr);
640 }
641
642 /********************/
643 /* Free FEAP Window */
644 /********************/
645
gdx11_free_digwin(dw)646 void gdx11_free_digwin(dw)
647 DIGWin *dw;
648 {
649 if (current_dw == dw) current_dw = NULL;
650 if (default_dw == dw) default_dw = NULL;
651
652 free(dw->npoints);
653
654 free(dw->polyline_pixel_value);
655 free(dw->polyline_gray_value);
656 free(dw->points);
657
658 free(dw->strlen);
659 free(dw->strflg);
660 free(dw->strings);
661 free(dw->textx);
662 free(dw->texty);
663
664 free(dw);
665 }
666
667
668
669 /***********************************************************/
670 /* Simple Function to Handle Single X Event in FEAP Window */
671 /***********************************************************/
672
673 static XComposeStatus lookup_status;
674
gdx11_handle_digwin_event(dw,eventptr,term_char,term_button)675 int gdx11_handle_digwin_event(dw,eventptr,term_char,term_button)
676 DIGWin *dw;
677 XEvent *eventptr;
678 char term_char;
679 unsigned int term_button;
680 {
681 int terminator = 0;
682 /* static void gdx11_flush(); */
683 void gdx11_flush();
684
685 switch (eventptr->type)
686 {
687 case MappingNotify:
688 XRefreshKeyboardMapping((XMappingEvent *)eventptr);
689 break;
690 case Expose:
691 gdx11_flush(dw);
692 break;
693 case ConfigureNotify:
694 gdx11_adjust_digwin(dw);
695 gdx11_flush(dw);
696 break;
697 case KeyPress:
698 {
699 XKeyEvent *key_event = (XKeyEvent *)eventptr;
700 int length;
701 char buf[8];
702 KeySym ks;
703
704 length = XLookupString(key_event,buf,8,&ks,&lookup_status);
705 if (length > 0 && term_char != 0 && term_char == buf[0])
706 terminator = 1;
707 break;
708 }
709 case ButtonPress:
710 {
711 XButtonEvent *button_event = (XButtonEvent *)eventptr;
712
713 if (term_button != 0 &&
714 term_button == button_event->button) terminator = 1;
715 }
716 default:
717 break;
718 }
719 return(terminator);
720 }
721
722 /******************/
723 /* String support */
724 /******************/
725
726 /* static void gdx11_init_strings(dw) */
gdx11_init_strings(dw)727 void gdx11_init_strings(dw)
728 DIGWin *dw;
729 {
730 dw->nstrings = 0;
731 }
732
733 /********************/
734 /* Polyline support */
735 /********************/
736
737 /* static void gdx11_init_polylines(dw) */
gdx11_init_polylines(dw)738 void gdx11_init_polylines(dw)
739 DIGWin *dw;
740 {
741 dw->npolylines = 0;
742 dw->npoints[0] = 0;
743 dw->next_point = 0;
744 }
745
gdx11_term_polyline(dw)746 static void gdx11_term_polyline(dw)
747 DIGWin *dw;
748 {
749 /* Terminate previous polyline if necessary */
750
751 if (dw->npoints[dw->npolylines]>=2) ++dw->npolylines;
752
753 else dw->next_point -= dw->npoints[dw->npolylines];
754
755 dw->npoints[dw->npolylines] = 0;
756 }
757
gdx11_end_polygon(dw)758 static void gdx11_end_polygon(dw)
759 DIGWin *dw;
760 {
761 int npoly = dw->npolylines;
762
763 if (dw->npoints[npoly]>=2)
764 {
765 dw->npoints[npoly] = -dw->npoints[npoly];
766 ++dw->npolylines;
767 }
768 else dw->next_point -= dw->npoints[dw->npolylines];
769
770 dw->npoints[dw->npolylines] = 0;
771 }
772
gdx11_check_polyline_overflow(dw,n)773 static void gdx11_check_polyline_overflow(dw,n)
774 DIGWin *dw;
775 int n;
776 {
777 if (dw->next_point+n > MAX_POINTS || dw->npolylines >=MAX_SEG)
778 {
779 gdx11_term_polyline(dw);
780 gdx11_refresh_digwin(dw);
781 gdx11_init_polylines(dw);
782
783 }
784 }
785
gdx11_start_polyline(dw,x,y)786 static void gdx11_start_polyline(dw,x,y)
787 DIGWin *dw;
788 int x, y;
789 {
790 gdx11_term_polyline(dw);
791 gdx11_check_polyline_overflow(dw,2);
792
793 /* Initialize current polyline */
794 dw->points[dw->next_point].x = x;
795 dw->points[dw->next_point++].y = y;
796 dw->npoints[dw->npolylines] = 1;
797 dw->polyline_pixel_value[dw->npolylines] = dw->current_pixel_value;
798 if(dw->num_fg_colors == 1)
799 dw->polyline_gray_value[dw->npolylines] = dw->current_gray_value;
800 return;
801 }
802
gdx11_start_polygon(dw,n,x,y)803 static void gdx11_start_polygon(dw,n,x,y)
804 DIGWin *dw;
805 int n;
806 int x, y;
807 {
808 gdx11_term_polyline(dw);
809 gdx11_check_polyline_overflow(dw,n);
810 gdx11_start_polyline(dw,x,y);
811 return;
812 }
813
gdx11_add_point_to_polyline(dw,x,y)814 static void gdx11_add_point_to_polyline(dw,x,y)
815 DIGWin *dw;
816 int x,y;
817 {
818 if (dw->npoints[dw->npolylines]==0)
819 gdx11_start_polyline(dw,dw->current_x,dw->current_y);
820
821 gdx11_check_polyline_overflow(dw,1);
822
823 if(dw->next_point == 0) {
824 dw->polyline_pixel_value[dw->npolylines] = dw->current_pixel_value;
825 dw->points[dw->next_point].x = dw->current_x;
826 dw->points[dw->next_point++].y = dw->current_y;
827 dw->npoints[dw->npolylines] = 1;
828 }
829
830 dw->points[dw->next_point].x = x;
831 dw->points[dw->next_point++].y = y;
832 ++dw->npoints[dw->npolylines];
833 }
834
835 /**************************/
836 /* 1. - INITIALIZE DEVICE */
837 /**************************/
838
gdx11_init_device(dw,x_data,y_data)839 static void gdx11_init_device(dw,x_data,y_data)
840 DIGWin *dw;
841 float (* x_data)[], (* y_data)[];
842 {
843 /* If we do not yet have a diglib Xwindow get one */
844 if (dw == NULL)
845 {
846 if (default_dw == NULL)
847 dw = default_dw =
848 gdx11_create_digwin("",default_width,default_height);
849 else
850 dw = default_dw;
851 }
852
853 /* Now fix the correct screen-size */
854
855 current_dw = dw;
856 gdx11_adjust_digwin(dw);
857 }
858
859 /******************************************************/
860 /* 2. - GET FRESH PLOTTING SURFACE, i.e. ERASE WINDOW */
861 /******************************************************/
862
gdx11_clear_page(dw,x_data,y_data)863 static void gdx11_clear_page(dw,x_data,y_data)
864 DIGWin *dw;
865 float (* x_data)[], (* y_data)[];
866 {
867 dw->current_pixel_value = dw->pixel_value_for_color[1];
868
869 gdx11_init_polylines(dw);
870 gdx11_init_strings(dw);
871
872 if ((*x_data)[0] >= 0.0)
873 {
874 if (DEBUG>=4) fprintf(stderr,"Clearing Window ... ");
875 XClearWindow(dw->xdisplay,dw->xwin);
876 if (DEBUG>=4) fprintf(stderr,"done!\n");
877 gdx11_adjust_digwin(dw);
878 gdx11_clear_pixmap(dw);
879 }
880 }
881
882 /**********************/
883 /* 3. - MOVE TO (X,Y) */
884 /**********************/
885
gdx11_move_to(dw,x_data,y_data)886 static void gdx11_move_to(dw,x_data,y_data)
887 DIGWin *dw;
888 float (* x_data)[], (* y_data)[];
889 {
890
891 int x = x_translate(dw,(*x_data)[0]);
892 int y = y_translate(dw,(*y_data)[0]);
893
894
895 if (x==dw->current_x && y==dw->current_y) return;
896
897 /* Start polyline */
898 gdx11_start_polyline(dw,x,y);
899
900 dw->current_x = x;
901 dw->current_y = y;
902 }
903
904 /**********************/
905 /* 4. - DRAW TO (X,Y) */
906 /**********************/
907
gdx11_draw_to(dw,x_data,y_data)908 static void gdx11_draw_to(dw,x_data,y_data)
909 DIGWin *dw;
910 float (* x_data)[], (* y_data)[];
911 {
912 register int new_x, new_y;
913
914 new_x = x_translate(dw,(*x_data)[0]);
915 new_y = y_translate(dw,(*y_data)[0]);
916 gdx11_add_point_to_polyline(dw,new_x,new_y);
917 dw->current_x = new_x;
918 dw->current_y = new_y;
919 }
920
921 /******************************/
922 /* 5. - FLUSH GRAPHICS BUFFER */
923 /******************************/
924
925 /* static void gdx11_flush(dw,x_data,y_data) */
gdx11_flush(dw,x_data,y_data)926 void gdx11_flush(dw,x_data,y_data)
927 DIGWin *dw;
928 float (* x_data)[], (* y_data)[];
929 {
930 gdx11_term_polyline(dw);
931
932 gdx11_refresh_digwin(dw);
933 XCopyArea(dw->xdisplay, dw->svimage, dw->xwin, dw->xgc,
934 0, 0, dw->xwa.width,dw->xwa.height, 0 ,0);
935 XFlush(dw->xdisplay);
936 }
937
938 /***********************/
939 /* 6. - RELEASE DEVICE */
940 /***********************/
941
gdx11_release_device(dw,x_data,y_data)942 static void gdx11_release_device(dw,x_data,y_data)
943 DIGWin *dw;
944 float (* x_data)[], (* y_data)[];
945 {
946 /*
947 * This routine should really close out the window system,
948 * but we want to be able to get back to this same device if
949 * it gets reopened. So just leave the window around and don't
950 * clear it.
951 */
952 return;
953 }
954
955 /**************************************/
956 /* 7. - RETURN DEVICE CHARACTERISTICS */
957 /**************************************/
958
gdx11_return_device(dw,x_data,y_data)959 static void gdx11_return_device(dw,x_data,y_data)
960 DIGWin *dw;
961 float (* x_data)[], (* y_data)[];
962 {
963 (*x_data)[0] = 11.0; /* Nonzero device ID */
964 if (dw!=NULL && dw->xwin != ((Window)NULL) )
965 {
966 (*x_data)[1] = dw->x_len/dw->x_scale; /* X Length in cm. */
967 (*x_data)[2] = dw->y_len/dw->y_scale; /* Y Length in cm. */
968 (*x_data)[3] = dw->x_scale; /* X pixels per cm */
969 (*x_data)[4] = dw->y_scale; /* Y pixels per cm */
970 (*x_data)[5] = dw->num_fg_colors; /* Number of foreground colors */
971 }
972 else
973 {
974 (*x_data)[1] = 0.001; /* X Length in cm. */
975 (*x_data)[2] = 0.001; /* Y Length in cm. */
976 (*x_data)[3] = 1.0; /* X pixels per cm */
977 (*x_data)[4] = 1.0; /* Y pixels per cm */
978 (*x_data)[5] = 1.0; /* Number of foreground colors */
979 }
980 (*x_data)[6] = RASTER_DEVICE+CAN_DRAW_IN_BACKGROUND+
981 CAN_DO_GIN+CAN_DRAW_FILLED_POLYGONS+
982 CAN_DO_LOCATOR_INPUT; /* FEAP device capabilities */
983 (*x_data)[7] = 1.0; /* Fill every line */
984 return;
985 }
986
987 /******************************/
988 /* 8. - SELECT PLOTTING COLOR */
989 /******************************/
990
gdx11_select_color(dw,x_data,y_data)991 static void gdx11_select_color(dw,x_data,y_data)
992 DIGWin *dw;
993 float (* x_data)[], (* y_data)[];
994 {
995 int new_pv = (int) (*x_data)[0];
996
997 /* Set gray scale for monochrome monitors */
998 if (dw->num_fg_colors == 1) {
999 switch (new_pv) {
1000 case 0:
1001 dw->current_gray_value = 0;
1002 break;
1003 case 2:
1004 dw->current_gray_value = 1;
1005 break;
1006 case 7:
1007 dw->current_gray_value = 2;
1008 break;
1009 case 3:
1010 dw->current_gray_value = 3;
1011 break;
1012 case 5:
1013 dw->current_gray_value = 4;
1014 break;
1015 case 4:
1016 dw->current_gray_value = 5;
1017 break;
1018 case 6:
1019 dw->current_gray_value = 6;
1020 break;
1021 case 1:
1022 dw->current_gray_value = 7;
1023 break;
1024 }
1025
1026 new_pv = (new_pv > 1) ? 1 : new_pv;
1027
1028 }
1029
1030 if (new_pv>=0 && new_pv<=dw->num_fg_colors &&
1031 (new_pv = dw->pixel_value_for_color[new_pv])
1032 !=dw->current_pixel_value)
1033 {
1034 gdx11_term_polyline(dw);
1035 dw->current_pixel_value = new_pv;
1036 }
1037 }
1038
gdx11_get_input(dw,cursor,allow_keys,left,middle,right,press,x,y)1039 static void gdx11_get_input(dw,cursor,allow_keys,left,middle,right,
1040 press,x,y)
1041 DIGWin *dw;
1042 Cursor cursor;
1043 int allow_keys, left, middle, right;
1044 int *press, *x, *y;
1045 {
1046 Display *disp = dw->xdisplay;
1047 Window w = dw->xwin;
1048 XEvent event;
1049 long int event_mask = (ButtonPressMask|ExposureMask|StructureNotifyMask|
1050 KeyPressMask);
1051 int no_button = 1;
1052
1053 /* First, toss all events on this window already in the queue */
1054 while (XCheckWindowEvent(disp,w,event_mask,&event))
1055 gdx11_handle_digwin_event(dw,&event,0,0);
1056
1057
1058 /* Put up cursor to signal we want input */
1059 XDefineCursor(disp,w,cursor);
1060
1061 /* Now look for GIN event */
1062 while(no_button)
1063 {
1064 XWindowEvent(disp,w,event_mask,&event);
1065 switch((int)event.type)
1066 {
1067 case KeyPress:
1068 {
1069 XKeyEvent *key_event = (XKeyEvent *)(&event);
1070 int length;
1071 char buf[8];
1072 KeySym ks;
1073
1074 /* Get the key pressed! */
1075 length = XLookupString(key_event,buf,8,&ks,&lookup_status);
1076 if (length>0)
1077 {
1078 *press = buf[0];
1079 *x = key_event->x;
1080 *y = key_event->y;
1081 no_button = 0;
1082 }
1083 break;
1084 }
1085 case ButtonPress:
1086 {
1087 XButtonEvent *DiglibEvent = (XButtonEvent *)(&event);
1088
1089 if (DiglibEvent->button == Button3)
1090 *press = BUTTON3_KEY;
1091 else if (DiglibEvent->button == Button2)
1092 *press = BUTTON2_KEY;
1093 else if (DiglibEvent->button == Button1)
1094 *press = BUTTON1_KEY;
1095 else
1096 *press = 0;
1097 *x = DiglibEvent->x;
1098 *y = DiglibEvent->y;
1099 no_button = 0;
1100 }
1101 default:
1102 gdx11_handle_digwin_event(dw,&event,0,0);
1103 break;
1104 }
1105 }
1106 /* Remove cross_hair_cursor */
1107 XUndefineCursor(disp,w);
1108 }
1109
1110 /**********************/
1111 /* 9. - GET GIN INPUT */
1112 /**********************/
1113
gdx11_gin(dw,x_data,y_data)1114 static void gdx11_gin(dw,x_data,y_data)
1115 DIGWin *dw;
1116 float (* x_data)[], (* y_data)[];
1117 {
1118 int key;
1119 int x,y;
1120 static Cursor gin_cursor;
1121 static int have_gin_cursor = 0;
1122
1123 /* Make sure we have a cross hair cursor */
1124 if (!have_gin_cursor)
1125 {
1126 gin_cursor = XCreateFontCursor(dw->xdisplay,XC_crosshair);
1127 have_gin_cursor = 1;
1128 }
1129
1130 gdx11_get_input(dw,gin_cursor,1,BUTTON1_KEY,BUTTON2_KEY,BUTTON3_KEY,
1131 &key,&x,&y);
1132 (*x_data)[0] = key;
1133 (*x_data)[1] = x_untranslate(dw,x);
1134 (*x_data)[2] = y_untranslate(dw,y);
1135 }
1136
1137 /********************************/
1138 /* 10. - DEFINE COLOR USING RGB */
1139 /********************************/
1140
1141 /* Not yet implemented */
1142 /* Because colors are allocated READ-ONLY, this will take some work! */
gdx11_set_color_map_rgb(dw,x_data,y_data)1143 static void gdx11_set_color_map_rgb(dw,x_data,y_data)
1144 DIGWin *dw;
1145 float (* x_data)[], (* y_data)[];
1146 {
1147 /* int color_index = (*x_data)[0]; */
1148 }
1149
1150 /********************************/
1151 /* 11. - DEFINE COLOR USING HLS */
1152 /********************************/
1153
1154 /* Not yet implemented, probably never will be */
gdx11_set_color_map_hls(op_code,x_data,y_data)1155 static void gdx11_set_color_map_hls( op_code, x_data, y_data )
1156 int *op_code;
1157 float (* x_data)[], (* y_data)[];
1158 {
1159 }
1160
1161 /***************************/
1162 /* 12. - GET LOCATOR INPUT */
1163 /***************************/
1164
gdx11_button_input(dw,x_data,y_data)1165 static void gdx11_button_input(dw,x_data,y_data)
1166 DIGWin *dw;
1167 float (* x_data)[], (* y_data)[];
1168 {
1169 int button;
1170 int x,y;
1171 static Cursor locator_cursor;
1172 static int have_locator_cursor = 0;
1173
1174 /* Make sure we have a cross hair cursor */
1175 if (!have_locator_cursor)
1176 {
1177 locator_cursor = XCreateFontCursor(dw->xdisplay,XC_diamond_cross);
1178 have_locator_cursor = 1;
1179 }
1180
1181 gdx11_get_input(dw,locator_cursor,0,1,2,4,&button,&x,&y);
1182 (*x_data)[0] = button;
1183 (*x_data)[1] = x_untranslate(dw,x);
1184 (*x_data)[2] = y_untranslate(dw,y);
1185 }
1186
1187 /*****************************/
1188 /* 13. - SET LINE STYLE */
1189 /*****************************/
1190 /* Added by RLT on 1/22/93 */
gdx11_set_line(dw,x_data,y_data)1191 static void gdx11_set_line (dw,x_data,y_data)
1192 DIGWin *dw;
1193 float (* x_data)[], (* y_data)[];
1194 {
1195 unsigned int line_width;
1196 int line_style;
1197 int cap_style;
1198 int join_style;
1199 int new_ln = (int) (*x_data)[0];
1200 int new_wd = (int) (*y_data)[0];
1201
1202 /* Change GC for this window */
1203
1204 XGCValues setgc;
1205
1206 /* First flush buffer with any current events */
1207
1208 gdx11_term_polyline(dw);
1209 gdx11_refresh_digwin(dw);
1210
1211 XFlush(dw->xdisplay);
1212
1213 gdx11_init_polylines(dw);
1214 gdx11_init_strings(dw);
1215
1216 setgc.foreground = (unsigned long)dw->pixel_value_for_color[1];
1217 setgc.background = (unsigned long)dw->pixel_value_for_color[0];
1218 setgc.function = GXcopy;
1219
1220 if (new_ln <= 1)
1221 line_style = LineSolid;
1222 else if (new_ln == 2)
1223 line_style = LineOnOffDash;
1224 else
1225 line_style = LineDoubleDash;
1226
1227 setgc.fill_style = FillSolid;
1228
1229 if (new_wd <= 1)
1230 line_width = 0;
1231 else if (new_wd == 2)
1232 line_width = 1;
1233 else if (new_wd == 3)
1234 line_width = 2;
1235 else if (new_wd == 4)
1236 line_width = 3;
1237 else
1238 line_width = 4;
1239
1240
1241 join_style = JoinMiter;
1242 cap_style = CapButt;
1243
1244 XSetLineAttributes( dw->xdisplay, dw->xgc, line_width, line_style,
1245 cap_style, join_style);
1246
1247 /* Monochrome gray scale stuff */
1248
1249 if(dw->num_fg_colors == 1){
1250 XSetLineAttributes( dw->xdisplay, dw->xgc, line_width, line_style,
1251 cap_style, join_style);
1252 XSetFillStyle(dw->xdisplay,dw->xgc_mono_fill,FillOpaqueStippled);
1253 }
1254 }
1255 /*************************/
1256 /* 14. - Set Clip Window */
1257 /*************************/
1258
gdx11_clip_mask(dw,x_data,y_data)1259 static void gdx11_clip_mask(dw,x_data,y_data)
1260 DIGWin *dw;
1261 float (* x_data)[], (* y_data)[];
1262 {
1263 register int new_x;
1264 XRectangle rectangles[1];
1265 int clip_x_origin, clip_y_origin;
1266 int nrects;
1267 int ordering;
1268
1269 new_x = x_translate(dw,(*x_data)[2]);
1270 if (new_x == 0)
1271 XSetClipMask( dw->xdisplay, dw->xgc, None );
1272 else {
1273 clip_x_origin = x_translate(dw,(*x_data)[0]);
1274 clip_y_origin = y_translate(dw,(*y_data)[0]);
1275 rectangles->x = clip_x_origin;
1276 rectangles->y = clip_y_origin;
1277 rectangles->width = x_translate(dw,(*x_data)[1]);
1278 rectangles->height = y_translate(dw,(*y_data)[1]);
1279 nrects = 1;
1280 ordering = Unsorted;
1281 XSetClipRectangles(dw->xdisplay, dw->xgc, clip_x_origin,
1282 clip_y_origin, rectangles, nrects, ordering );
1283
1284 }
1285 }
1286 /**************************************/
1287 /* MAX_OPCODE-1 - DRAW TEXT STRING */
1288 /**************************************/
1289
gdx11_draw_text(dw,n,x_data,y_data)1290 static void gdx11_draw_text(dw,n,x_data,y_data)
1291 DIGWin *dw;
1292 int n ;
1293 float (* x_data)[], (* y_data)[];
1294 {
1295 int i ;
1296 dw->textx[dw->nstrings] = x_translate(dw,(*x_data)[0]);
1297 dw->texty[dw->nstrings] = y_translate(dw,(*y_data)[0]);
1298 dw->strflg[dw->nstrings] = (int)(*y_data)[1];
1299 dw->strlen[dw->nstrings] = n;
1300 for ( i = 1; i <= n; ++i)
1301 dw->strings[dw->nstrings*80+i-1]=(int)(*x_data)[i];
1302
1303 /* prepare for next text string */
1304 ++dw->nstrings;
1305 if(dw->nstrings==MAX_TEXT) {
1306 gdx11_refresh_digwin(dw);
1307 dw->nstrings = 0;
1308 }
1309 }
1310
1311 /************************************/
1312 /* MAX_OPCODE - DRAW FILLED POLYGON */
1313 /************************************/
1314
gdx11_draw_polygon(dw,n,x_data,y_data)1315 static void gdx11_draw_polygon(dw,n,x_data,y_data)
1316 DIGWin *dw;
1317 int n;
1318 float (* x_data)[], (* y_data)[];
1319 {
1320 int i;
1321 /* Display *disp = dw->xdisplay;*/
1322
1323 dw->current_x = x_translate(dw,(*x_data)[n-1]);
1324 dw->current_y = y_translate(dw,(*y_data)[n-1]);
1325 gdx11_start_polygon(dw,n+1,dw->current_x,dw->current_y);
1326 for ( i = 0; i < n; ++i)
1327 gdx11_add_point_to_polyline(dw,x_translate(dw,(*x_data)[i]),
1328 y_translate(dw,(*y_data)[i]));
1329 gdx11_end_polygon(dw);
1330 }
1331
1332
1333 /******************************************/
1334 /* X11 Window SAVE Options: Dummy routines*/
1335 /******************************************/
1336
1337 /*void gdx11_jpg(DIGWin* dw) {
1338
1339 jpgd(dw);
1340
1341 } */
1342
1343 /*********************/
1344 /* X11 DEVICE DRIVER */
1345 /*********************/
1346
1347 /* FORTRAN Interace */
1348
1349 /* HP and IBM use :
1350 void gdx11( op_code, x_data, y_data )
1351 */
1352 /* GCC, INTEL, SUN and DEC use :
1353 */
gdx11_(op_code,x_data,y_data)1354 void gdx11_( op_code, x_data, y_data )
1355 int *op_code; /* holds device independent op-code */
1356 float (* x_data)[]; /* x coordinate data */
1357 float (* y_data)[]; /* y coordinate data */
1358 {
1359 /* An array of pointers to function */
1360 /* i.e. a jump table that is global to this compilation unit */
1361
1362 static void (* jump_table[MAX_OPCODE])() =
1363 {
1364 gdx11_init_device, /* 1 = initialize new device */
1365 gdx11_clear_page, /* 2 = erase the window */
1366 gdx11_move_to, /* 3 = move - no draw */
1367 gdx11_draw_to, /* 4 = draw - draw line */
1368 gdx11_flush, /* 5 = flush buffer */
1369 gdx11_release_device, /* 6 = release device = NULL */
1370 gdx11_return_device, /* 7 = return device feature */
1371 gdx11_select_color, /* 8 = select colors */
1372 gdx11_gin, /* 9 = gin input selection */
1373 gdx11_set_color_map_rgb, /* 10 = RGB color map = NULL */
1374 gdx11_set_color_map_hls, /* 11 = HLS color map = NULL */
1375 gdx11_button_input, /* 12 = locator input w/mouse */
1376 gdx11_set_line, /* 13 = set line style */
1377 gdx11_clip_mask, /* 14 = set clip region */
1378 gdx11_draw_text, /* MAX_OP - 1 = draw text */
1379 gdx11_draw_polygon /* MAX_OP = polygon fill */
1380 }; /* MAX_OPCODE = 16 */
1381
1382 if (DEBUG>=3) fprintf(stderr,"FEAP-X11 called, op_code = %d\n",*op_code);
1383 /* Check for correct op-code, and run */
1384 if (*op_code > 1024)
1385 jump_table[MAX_OPCODE-1](current_dw,*op_code-1024,x_data,y_data);
1386 else if (*op_code < -1024)
1387 jump_table[MAX_OPCODE-2](current_dw,-*op_code-1024,x_data,y_data);
1388 else if ((0 <= *op_code) && (*op_code <= MAX_OPCODE-1))
1389 jump_table[*op_code-1](current_dw,x_data,y_data);
1390 if (DEBUG>=3) fprintf(stderr,"FEAP-X11 done with op_code = %d\n",*op_code);
1391 }
1392
1393 /*
1394 * C-based input routines to allow for DIGWin Event Handeling if
1395 * the graphics window has been created.
1396 *
1397 * SG: 04/18/2005 (based upon DSB's GPL version)
1398 *
1399 */
1400
1401
1402 /* FEAP's comrec common block */
1403 struct {
1404 char record[256];
1405 } comrec_;
1406
1407 /*
1408 * C stub for overloaded X11 input.
1409 *
1410 * Assumes that Fortran True == 1 and Fortran False == 0
1411 */
1412
1413
cinput_nox()1414 int cinput_nox()
1415 {
1416 int stlen,j;
1417
1418 for(j=0;j<256;j++) comrec_.record[j] = ' '; /* Clear the record */
1419
1420 /* Loop to get line, trap errors */
1421 while ( NULL == fgets(comrec_.record,256,stdin) ) {
1422 printf("\n *ERROR* EOF on input detected, please try again\n");
1423 clearerr(stdin);
1424 }
1425
1426 stlen = strlen(comrec_.record);
1427 comrec_.record[stlen] = ' '; /* zap /0 */
1428 comrec_.record[stlen-1] = ' '; /* zap carraige return */
1429 return 1;
1430 }
1431 /*
1432 * Select switch loop to look for X11 events and keyboard events
1433 */
1434
cinput_x()1435 int cinput_x()
1436 {
1437 fd_set readfds;
1438 struct timeval timeout;
1439
1440 int n, retv;
1441 int fd, cinput_x_unfinished;
1442
1443 cinput_x_unfinished = 1;
1444 retv = 0;
1445
1446 fd = ConnectionNumber(current_dw->xdisplay);
1447
1448 while (cinput_x_unfinished) {
1449
1450 timeout.tv_sec = 2;
1451 timeout.tv_usec = 0;
1452
1453 FD_ZERO(&readfds);
1454 FD_SET (0, &readfds);
1455 FD_SET (fd, &readfds);
1456
1457 /* Select on fd's, process input as needed */
1458 n = select(fd + 1, &readfds, NULL, NULL, &timeout);
1459
1460 /* Data on stdin */
1461 if (FD_ISSET(0, &readfds)) {
1462 retv = cinput_nox();
1463 cinput_x_unfinished = 0;
1464 }
1465
1466 /* Data on X11 pipe */
1467 if(FD_ISSET(fd, &readfds)) {
1468 DIGWin *dw = current_dw;
1469 XEvent event;
1470 while (XCheckWindowEvent(dw->xdisplay,dw->xwin,
1471 dw->xwa.your_event_mask,&event))
1472 gdx11_handle_digwin_event(dw,&event,0,0);
1473 }
1474
1475 }
1476
1477 return retv;
1478 }
1479
1480 /* Input routine for stdin via C */
cinput_()1481 int cinput_()
1482 {
1483 if (current_dw == NULL)
1484 return cinput_nox();
1485 else
1486 return cinput_x();
1487 }
1488
1489
1490