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