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