Make the axis appears before the curve surface shows up.
[dyninst.git] / visiClients / terrain / src / terrain.c
1 /*-----------------------------------------------------------------------------
2  *   gnuplot_x11 - X11 outboard terminal driver for gnuplot 2
3  *
4  *   Requires installation of companion inboard x11 driver in gnuplot/term.c
5  *
6  *   Acknowledgements: 
7  *      Chris Peterson (MIT) - original Xlib gnuplot support (and Xaw examples)
8  *      Dana Chee (Bellcore)  - mods to original support for gnuplot 2.0
9  *      Arthur Smith (Cornell) - graphical-label-widget idea (xplot)
10  *      Hendri Hondorp (University of Twente, The Netherlands) - Motif xgnuplot
11  *
12  *   This code is provided as is and with no warranties of any kind.
13  *       
14  *   Ed Kubaitis - Computing Services Office -  University of Illinois, Urbana
15  *---------------------------------------------------------------------------*/
16
17 /*
18  * Modified for terrain plot:
19  *      Chi-Ting Lam
20  *
21  */
22
23 #ifndef lint
24 static char rcsid[] = "@(#) $Header: /home/jaw/CVSROOT_20081103/CVSROOT/core/visiClients/terrain/src/terrain.c,v 1.3 1997/05/19 19:43:07 tung Exp $";
25 #endif
26
27 /*
28  * terrain.c - main entry point and x driver.
29  *
30  * $Log: terrain.c,v $
31  * Revision 1.3  1997/05/19 19:43:07  tung
32  * Make the axis appears before the curve surface shows up.
33  *
34  * Revision 1.2  1997/05/18 22:50:11  tung
35  * Eliminate ips dependent library files.
36  *
37  * Revision 1.1  1997/05/12 20:15:44  naim
38  * Adding "Terrain" visualization to paradyn (commited by naim, done by tung).
39  *
40  * Revision 1.2  1992/05/19  17:37:04  lam
41  * Added call to initialize pop up message windows.
42  *
43  * Revision 1.1  1992/05/19  06:30:55  lam
44  * Initial revision
45  *
46  *
47  */
48
49 #include <stdio.h>
50 #include <signal.h>
51 #include <math.h>
52 #include <assert.h>
53 #include <string.h>
54
55
56 #define Ncolors 11              /* Number of colors for GNUPlot part */
57
58 #include "terrain.h"
59 #include "term.h"
60 #include "form.h"
61 #include "command.h"
62 #include "misc.h"
63 #include "visi/h/visualization.h" 
64
65 unsigned long colors[Ncolors];  /* Colors for GNUPlot part */
66 char color_keys[Ncolors][30] =   { "text", "border", "axis", 
67    "line1", "line2", "line3", "line4", "line5", "line6", "line7", "line8" };
68 char color_values[Ncolors][30] = { "black", "black", "black", 
69    "red",  "black", "blue",  "magenta", "cyan", "sienna", "orange", "coral" };
70
71 int color_disp = 0;             /* Do we have a color display? */
72 int Ntcolors=25;                /* Number of color used by terrain */
73 unsigned long *tcolors;         /* The colors used by terrain */
74
75 /* Line stypes */
76
77 char dashes[10][5] = { {0}, {1,6,0}, 
78    {0}, {4,2,0}, {1,3,0}, {4,4,0}, {1,5,0}, {4,4,4,1,0}, {4,2,0}, {1,3,0}
79    };
80
81 Widget w_top,                   /* Top level application widget */
82        w_label;                 /* The main viewer window */
83 Window win;                     /* Which window we are in */
84 Display *dpy;                   /* Which display we are in */
85 Pixmap pixmap;                  /* The drawing area in the main viewer */
86 GC gc = (GC)NULL;
87 Dimension W = 640, H = 450, D = 0; /* Initial dimension of terrain window */
88 Arg args[5];
89
90 static void resize();
91
92 int cx=0, cy=0, vchar, nc = 0;  /* Char location, size, length, etc */
93
94 int cur_lt;                     /* What kind of line we are using */
95
96 float xscale, yscale;           /* GNUPlot rescale the plot to fit the */
97                                 /* window before actually drawing      */
98 enum JUSTIFY { LEFT, CENTRE, RIGHT } jmode; /* How texts are drawn */
99
100 RValues rv;
101
102 XtResource resources[] = {
103    { XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), 
104      XtOffset(RVptr, font), XtRString, "fixed" },
105    { XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), 
106      XtOffset(RVptr, fg), XtRString, "black" },
107    { XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel), 
108      XtOffset(RVptr, bg), XtRString, "white" },
109    };
110
111 /* New action to tell terrain to draw shadow plot when rotating */
112 XtActionProc NotifyEndThumb();
113
114 XtActionsRec actionTable[] = {
115    { "NotifyEndThumb", NotifyEndThumb }
116 };
117  
118
119
120 /***********************************************************************************
121  ************************* modified section starts *********************************/
122
123 /*
124  * default resources
125  */
126
127 String fallback_resources[] = { 
128  "*background: Grey",
129  "*foreground: Black",
130  "*font: *-Helvetica-*-r-*-12-*",
131  "*titlebar*font: *-New*Century*Schoolbook-Bold-R-*-18-*",
132  "*titlebar*background: Red",
133  "*titlebar*foreground: White",
134  NULL,
135 };
136
137
138 static int ft;
139 static int numGroups;
140 static int phase_displayed;
141 static Widget input;
142 static int numRes;
143
144 struct HistData {
145     int      curve_id;
146     unsigned prev_last;
147     char*    title;
148     unsigned metric;
149     unsigned resource;
150     int      groupId;
151 };
152
153
154 void setNotFt()
155 {
156   ft = 0;
157
158 }
159
160
161 static int get_groupId(const char *axis_label){
162
163   int id = -1;
164   struct HistData* hdp = 0;
165   const char *temp;
166   int m, r;
167
168   for (m = 0; m < 1; m++) {
169      temp = visi_MetricLabel(m);
170      for (r = 0; r < numRes; r++) {
171         if(visi_Enabled(m,r)){
172            if(strcmp(temp,axis_label) == 0){
173               hdp = (struct HistData *)visi_GetUserData(m,r);
174               if(hdp){
175                 id =  hdp->groupId;
176                 break;
177               }
178            }
179         }
180   }}
181
182   if(id == -1){  // create a new group number
183     id = numGroups++;
184   }
185
186   return(id);
187
188 }
189
190
191 static int add_new_curve(unsigned m, unsigned r)
192 {
193   struct HistData* hdp = 0;
194   float* data;
195   float zero;
196   char* m_name;
197   char* r_name;
198   char* p_name;
199
200     if (visi_Enabled(m,r) &&
201        (hdp = (struct HistData *) visi_GetUserData(m,r)) == 0) {
202
203         hdp = (struct HistData *) malloc(sizeof(struct HistData));
204         assert(hdp);
205
206         hdp->curve_id  = -1;
207         hdp->groupId  = -1;
208         hdp->prev_last = 0;
209         hdp->metric    = m;
210         hdp->resource  = r;
211
212         m_name = visi_MetricName(m);
213         r_name = visi_ResourceName(r);
214         p_name = visi_GetMyPhaseName();
215
216         m_name = (m_name) ? (m_name) : "";
217         r_name = (r_name) ? (r_name) : "";
218
219         hdp->title   = (char *) malloc(strlen(m_name)+strlen(r_name)+4);
220         assert(hdp->title);
221         sprintf(hdp->title, "%s <%s>", m_name, r_name);
222
223
224         hdp->groupId = get_groupId(visi_MetricLabel(m));
225
226         hdp->curve_id = Graph3DAddNewCurve(m_name, r_name, p_name, 
227                                            visi_MetricLabel(m), hdp->groupId, 
228                                            visi_NumBuckets(), numRes);
229
230         visi_SetUserData(m,r,(void *) hdp);
231
232    }
233     
234    return 0;
235
236
237
238 }
239
240
241
242
243
244 static void drawData(int is_fold)
245 {
246     struct HistData* hdp;
247     int m, r;
248     float *data;
249
250     for (m = 0; m < 1; m++) {
251        if (visi_NumResources() > 111)
252           numRes = 11;
253        else
254           numRes = visi_NumResources();
255
256         for (r = 0; r < numRes; r++) {
257          if (!visi_Valid(m,r)) {  // invalid histo-cell
258                 continue;
259          }
260             // this curve was previously deleted and now has new data
261             // need to add new curve to histogram widget
262          if((hdp = (struct HistData *) visi_GetUserData(m,r)) == 0){
263                 add_new_curve(m,r);
264                 hdp = (struct HistData *) visi_GetUserData(m,r);
265                 assert(hdp);
266          }
267          
268          data = visi_DataValues(m,r);
269
270             //
271             // why is this being set everytime not just outside the loop ???
272             // jkh 5/2/94
273
274             // TODO: set start time to real start time rather that 0.0
275             // HistSampleInfo(hw, BucketWidth(), NumBuckets(),
276             // 0.0, FALSE);
277
278          if (is_fold) {
279                 Graph3DSetCurveData(hdp->curve_id,0,
280                                  visi_LastBucketFilled(m,r),data, visi_GetStartTime(), 
281                                  visi_BucketWidth(), is_fold,
282                                  color_disp, dpy, gc, rv, pixmap, W, H, win);
283          } 
284          else {
285
286                 Graph3DSetCurveData(hdp->curve_id, 
287                                     hdp->prev_last,
288                                     visi_LastBucketFilled(m,r) - hdp->prev_last,
289                                     &(data[hdp->prev_last]), visi_GetStartTime(), 
290                                     visi_BucketWidth(), is_fold,
291                                     color_disp, dpy, gc, rv, pixmap, W, H, win);
292         
293          }
294          hdp->prev_last = visi_LastBucketFilled(m,r);
295        }
296      }
297
298       
299    return;
300
301
302
303   
304 }
305
306
307 /* Event Handler to process new values from the visilib */
308 static int process_datavalues(int parameter)
309 {
310   static int checkError = 1;
311   
312   /* check for errors for datas come in at the first time */
313   if (checkError == 1)  
314   {
315      if (visi_NumMetrics() != 1)
316         visi_showErrorVisiCallback("Please select only one metric for the 3D Histogram.\nOnly one of the metrics selected will be shown.");
317
318      if (visi_NumResources() < 2)
319          visi_showErrorVisiCallback("Please select more than one resource for the 3D Histogram.\mNo curve will be shown.");
320
321      if (visi_NumResources() > 11)
322         visi_showErrorVisiCallback("Exceed the maximum number(11) of resources.\nOnly 11 of the resources selected will be shown.");
323
324      checkError = 0;
325   }
326
327   /* get and draw the graph */
328   drawData(0);
329
330   return 0;
331
332 }
333
334
335
336 /* Event Handler to process new values from the visilib */
337 static int process_fold(int parameter)
338 {
339
340    /* get and draw the graph */
341    drawData(1);
342
343    
344    return 0;
345
346 }
347
348 /**************************modified section ends ************************************
349  ************************************************************************************/
350
351
352
353
354
355 /*-----------------------------------------------------------------------------
356  *   main program - fire up application and callbacks
357  *---------------------------------------------------------------------------*/
358
359 main(argc, argv) int argc; char *argv[]; {
360    float colStep;
361
362    XtAppContext app_con;        /* Application context */ 
363
364 /***********************************************************************************
365  ************************* modified section starts *********************************/
366  
367    int l, r;
368    int fd;
369
370    fd = visi_Init();
371    if (fd < 0)
372    {
373       fprintf(stderr, "error initializing Visi library\n");
374       exit(-1);
375    }
376    
377    phase_displayed = 0;
378    numGroups = 0;
379    ft = 1;
380
381 /**************************modified section ends ************************************
382  ************************************************************************************/
383
384    signal(SIGINT, SIG_IGN);
385    signal(SIGTSTP, SIG_IGN);
386
387
388
389    /* initialize application */
390    w_top = XtAppInitialize(&app_con, "Terrain", NULL, ZERO, &argc, argv,
391                            fallback_resources, NULL, ZERO);
392
393    /* Initialize application action for scroll bar jump clean-ups */
394    XtAppAddActions(app_con, actionTable, ONE);
395
396    /* Initialize the frame */
397    w_label = (Widget) createForm(w_top, H, W);
398
399    tcolors = (unsigned long*)terrain_alloc(sizeof(unsigned long) * Ntcolors);
400
401    /* Don't display the window until it is ready */
402    XtSetMappedWhenManaged(w_top, False);
403    XtRealizeWidget(w_top);
404
405
406    /* extract needed information */
407    dpy = XtDisplay(w_top); win = XtWindow(w_label);
408
409    /* Do we have enough colors? */
410    color_disp = (XDisplayCells(dpy, DefaultScreen(dpy)) > 40);
411    if (color_disp)
412        D = DefaultDepth(dpy, DefaultScreen(dpy));
413    else
414        D = 1;
415
416    if (color_disp) {
417       char option[20], *value; 
418       XColor used, exact; 
419       int n;
420
421       /* Allocate colors for old GNUPlot stuffs */
422       for(n=0; n<Ncolors; n++) {
423          strcpy(option, color_keys[n]);
424          strcat(option, "Color");
425          value = XGetDefault(dpy, "terrain", option);
426          if (!value) { value = color_values[n]; }
427          if (XAllocNamedColor(dpy, DefaultColormap(dpy,0), value, &used,&exact))
428             colors[n] = used.pixel; 
429          else {
430             fprintf(stderr, "terrain: cannot allocate %s:%s\n", option, value);
431             fprintf(stderr, "terrain: assuming %s:black\n", option);
432             colors[n] = BlackPixel(dpy,0);
433          }
434       }
435
436       /* Allocate a spectum of colors for Terrain Plot */
437
438       colStep = 330.0/(float) Ntcolors;
439
440       for(n=0; n<Ntcolors; n++) {
441         hsv2Rgb(((float) n)*colStep+75.0, 65535.0, 0.75, &used);
442
443         if (XAllocColor(dpy, DefaultColormap(dpy,0), &used)) {
444            tcolors[n] = used.pixel;
445 /*
446            fprintf(stderr, "R=%u, G=%u, B=%u\n", used.red, used.green, used.blue);
447 */
448         } else {
449            fprintf(stderr, "Warning: cannot allocate color R=%u, B=%u\n", used.red, used.blue);
450            tcolors[n] = WhitePixel(dpy,0);
451         }
452       }
453    }
454
455    XtSetArg(args[0], XtNwidth, &W);
456    XtSetArg(args[1], XtNheight,&H);
457    XtGetValues(w_label, args, (Cardinal)2);
458    XtGetApplicationResources(w_top, &rv, resources, XtNumber(resources),NULL,0);
459    vchar = (rv.font->ascent + rv.font->descent);
460
461    /* add callbacks on window-resized */
462    XtAddEventHandler(w_label, StructureNotifyMask, FALSE, resize, NULL);
463    
464
465
466 /***********************************************************************************
467  ************************* modified section starts *********************************/
468   
469   (void) visi_RegistrationCallback(DATAVALUES, process_datavalues);
470   (void) visi_RegistrationCallback(FOLD,       process_fold);
471
472   XtAppAddInput(app_con, fd, XtInputReadMask, visi_callback, input);
473
474
475 /**************************modified section ends ************************************
476  ************************************************************************************/
477
478    /* Initialize terminal */
479    change_term("x11", 3);
480
481    /* PopUpInit(); */
482    
483
484    /* Create and display the graph */
485    init_pixmap();
486
487    /* Clean the screen when starts up */
488    #ifndef MOTIF
489    if (color_disp) { /* Athena needs different erase for color and mono */
490    #endif
491       XSetForeground(dpy, gc, rv.bg);
492       XFillRectangle(dpy, win, gc, 0, 0, W, H);
493       XFillRectangle(dpy, pixmap, gc, 0, 0, W, H);
494       XSetForeground(dpy, gc, rv.fg);
495       XSetBackground(dpy, gc, rv.bg);
496    #ifndef MOTIF  
497       }
498    else {
499       XSetFunction(dpy, gc, GXxor);
500       XCopyArea(dpy, win, win, gc, 0, 0, W, H, 0, 0);
501       XCopyArea(dpy, pixmap, pixmap, gc, 0, 0, W, H, 0, 0);
502       XSetFunction(dpy, gc, GXcopyInverted);
503       }
504    #endif
505
506    XtMapWidget(w_top);
507
508    XtAppMainLoop(app_con);
509
510 }
511
512 /*-----------------------------------------------------------------------------
513  *   display - display accumulated commands from inboard driver
514  *---------------------------------------------------------------------------*/
515
516 display(action)
517 int action;
518 {
519    /* clean the screen when ReDisplay the Graph is needed */
520    #ifndef MOTIF
521    if (color_disp) { /* Athena needs different erase for color and mono */
522    #endif
523       XSetForeground(dpy, gc, rv.bg);
524       XFillRectangle(dpy, win, gc, 0, 0, W, H);
525       XFillRectangle(dpy, pixmap, gc, 0, 0, W, H);
526       XSetForeground(dpy, gc, rv.fg);
527       XSetBackground(dpy, gc, rv.bg);
528    #ifndef MOTIF
529    }
530    else {
531       XSetFunction(dpy, gc, GXxor);
532       XCopyArea(dpy, win, win, gc, 0, 0, W, H, 0, 0);
533       XSetFunction(dpy, gc, GXcopyInverted);
534    }
535    #endif
536
537
538    /* get and draw the graph */
539    plot3drequest(action); 
540
541    /* trigger expose events to display pixmap */
542    XClearArea(dpy, win, 0, 0, 0, 0, True);
543
544    
545 }
546
547
548
549 /*************************************************************************
550 * resize - Called by X when the window got resized.  It make a new pixmap
551 *          according to the new size of the main viewer, and redraw the
552 *          terrain in it.
553 *
554 *************************************************************************/
555
556
557 static void
558 resize(w, cd, e) 
559 Widget w;
560 char *cd;
561 XConfigureEvent *e; {
562    if (e->type != ConfigureNotify) return;
563    W = e->width; H = e->height;
564
565    init_pixmap();
566
567    display(SA_RESIZE); 
568
569
570 }
571
572
573 /*************************************************************************
574 *
575 * init_pixmap - Create a pixmap corresponding to the current size of the
576 *               main viewer.
577 *
578 *************************************************************************/
579
580 init_pixmap()
581 {
582    /* set scaling factor between internal driver & window geometry */
583    xscale = (float)W / 4096.;  yscale = (float)H / 4096.;  
584
585    /* create new pixmap & GC */
586    if (gc) { XFreeGC(dpy, gc); XFreePixmap(dpy, pixmap); }
587    pixmap = XCreatePixmap(dpy, RootWindow(dpy,DefaultScreen(dpy)), W, H, D);
588    gc = XCreateGC(dpy, win, 0, NULL);
589    XSetFont(dpy, gc, rv.font->fid);
590
591    /* the display belongs to w_label */
592    XtSetArg(args[0], XtNbitmap, pixmap);
593    XtSetValues(w_label, args, (Cardinal)1);
594
595 }
596
597
598
599
600 /*************************************************************************
601 *
602 * X11_vector - used by GNUPlot to draw axis and the base lines.
603 *
604 *************************************************************************/
605
606 X11_vector(x,y)
607 unsigned int x,y;
608 {
609    if (ft == 1)
610       XDrawLine(dpy, win, gc, X(cx), Y(cy), X(x), Y(y));
611
612    XDrawLine(dpy, pixmap, gc, X(cx), Y(cy), X(x), Y(y));
613    cx = x; cy = y;
614 }
615
616
617 /*************************************************************************
618 *
619 * X11_move - used by GNUPlot to draw axis and the base lines.
620 *
621 *************************************************************************/
622
623 X11_move(x,y)
624 unsigned int x,y;
625 {
626    cx = x; cy = y;
627 }
628
629
630
631 /*************************************************************************
632 *
633 * X11_put_text - put a string to the specified location in the main viewer
634 *
635 *************************************************************************/
636
637 X11_put_text(x,y,str)
638 unsigned int x,y;
639 char *str;
640 {
641    int sw, sl;
642    sl = strlen(str);
643    sw = XTextWidth(rv.font, str, sl);
644
645    switch(jmode) {
646       case LEFT:   sw = 0;     break;
647       case CENTRE: sw = -sw/2; break;
648       case RIGHT:  sw = -sw;   break;
649    }
650
651    if (!color_disp) 
652    {
653       if (ft == 1)
654          XDrawString(dpy, win, gc, X(x)+sw, Y(y)+vchar/3, str, sl);
655
656       XDrawString(dpy, pixmap, gc, X(x)+sw, Y(y)+vchar/3, str, sl);
657    }
658    else { 
659       XSetForeground(dpy, gc, colors[0]);
660       if (ft == 1)
661          XDrawString(dpy, win, gc, X(x)+sw, Y(y)+vchar/3, str, sl);
662
663       XDrawString(dpy, pixmap, gc, X(x)+sw, Y(y)+vchar/3, str, sl);
664       XSetForeground(dpy, gc, colors[cur_lt+1]);
665    }
666 }
667
668
669
670 /*************************************************************************
671 *
672 * X11_justify_text - Set the justify (left, right, middle) mode when
673 *                    drawing text.
674 *
675 *************************************************************************/
676
677 X11_justify_text(mode)
678 enum JUSTIFY mode;
679 {
680    jmode = mode;
681    return 1;
682 }
683
684
685
686
687 /*************************************************************************
688 *
689 * X11_linetype - Set the current line type.
690 *
691 *************************************************************************/
692
693 X11_linetype(lt)
694 int lt;
695
696    int width, type;
697
698     lt = (lt+2)%10;
699     width = (lt == 0) ? 2 : 0;
700     if (color_disp) {
701         if (lt != 1) 
702             type = LineSolid;
703         else {
704             type = LineOnOffDash;
705             XSetDashes(dpy, gc, 0, dashes[lt], strlen(dashes[lt]));
706         }
707         XSetForeground(dpy, gc, colors[lt+1]);
708     } else {
709         type  = (lt == 0 || lt == 2) ? LineSolid : LineOnOffDash;
710         if (dashes[lt][0])
711             XSetDashes(dpy, gc, 0, dashes[lt], strlen(dashes[lt]));
712     }
713     XSetLineAttributes( dpy,gc, width, type, CapButt, JoinBevel);
714
715     cur_lt = lt;
716 }
717
718
719
720
721
722 /*************************************************************************
723 *
724 * hsv2Rgb - convert a color in HSV system into RGB system.
725 *           X11R5 should do a better job than this, but R4 does not even
726 *           have this kind of functions.
727 *           The algorithm can be found in many graphic text books.
728 *
729 *************************************************************************/
730
731
732 hsv2Rgb(hue, val, sat, rgb)
733 float hue,                      /* Where (which angle) the color falls into */
734       val,                      /* Maximun value to be returned */
735       sat;                      /* Saturation of the color (how much white */
736 XColor *rgb;                    /* The resulting  RGB value */
737 {
738    float minCol;
739
740    hue = (hue/360.0 - ((int)hue)/360)*360.0;
741    minCol = val * (1.0 - sat);
742    if (hue <= 120.0) {
743       rgb->green = minCol;
744       if (hue <= 60.0) {
745          rgb->red = val;
746          rgb->blue = minCol + hue * (val - minCol)/(120.0 - hue);
747       } else {
748          rgb->blue = val;
749          rgb->red = minCol + (120.0 - hue) * (val - minCol)/hue;
750       }
751    } else if (hue <= 240.0) {
752       rgb->red = minCol;
753       if (hue <= 180.0) {
754          rgb->blue = val;
755          rgb->green = minCol + (hue - 120.0) * (val - minCol)/(240 - hue);
756       } else {
757          rgb->green = val;
758          rgb->blue = minCol + (240.0 - hue) * (val - minCol)/(hue - 120.0);
759       }
760    } else {
761       rgb->blue = minCol;
762       if (hue <= 300.0) {
763          rgb->green = val;
764          rgb->red = minCol + (hue - 240.0) * (val - minCol)/(360.0 - hue);
765       } else {
766          rgb->red = val;
767          rgb->green = minCol + (360.0 - hue) * (val - minCol)/(hue - 240.0);
768       }
769    }
770 }
771
772
773
774
775 /*************************************************************************
776 *
777 * NotifyEndThumb - An application action which enable terrain to tell the
778 *                  difference between jumping and smooth rotating.
779 *                  (Xaw does not have enough action to do this)
780 *
781 *************************************************************************/
782
783
784 XtActionProc
785 NotifyEndThumb(w, event, params, num_params)
786 Widget w;
787 XEvent *event;
788 String *params;
789 Cardinal *num_params;
790 {
791    display(SA_JUMP);
792 }
793
794
795 /*************************************************************************
796 * The following dummy rotines keeps GNUPlot happy
797 *************************************************************************/
798
799 X11_init()
800 {
801 }
802
803 X11_reset()
804 {
805 }
806
807 X11_graphics()
808 {
809 }
810
811 X11_text()
812 {
813 }
814
815