Updated layout and added curve validation callback.
[dyninst.git] / visiClients / tclVisi / src / DGclient.C
1 /*
2  *  DGclient.C -- Code for the visi<->tcl interface.
3  *    
4  * $Log: DGclient.C,v $
5  * Revision 1.2  1994/06/14 18:57:47  rbi
6  * Updated layout and added curve validation callback.
7  *
8  * Revision 1.1  1994/05/31  21:05:47  rbi
9  * Initial version of tclVisi and tabVis
10  *
11  */
12 #include <stdlib.h>
13 #include <tcl.h>
14 #include <tk.h>
15 #include "visi/h/visualization.h"
16
17 extern "C" {
18   int Blt_GraphElement(Tcl_Interp *interp, char *pathName, char *elemName, 
19                        int numValues, double *valueArr);
20 }
21
22 extern Tcl_Interp *MainInterp;
23
24 int Dg_Add(int dummy) {
25   int retval;
26
27   retval = Tcl_Eval(MainInterp, "DgConfigCallback");
28   if (retval == TCL_ERROR) {
29     fprintf(stderr, "%s\n", MainInterp->result);
30   }
31   return(retval);
32 }
33
34 int Dg_Data(int dummy) {
35   int retval = TCL_OK, thislast = -1;
36   static LastBucket = 0;
37   char cmd[256];
38
39   /* 
40    *  Simulate valid callback
41    */
42   for (unsigned m = 0; m < dataGrid.NumMetrics(); m++) {
43     for (unsigned r = 0; r < dataGrid.NumResources(); r++) {
44       if(dataGrid[m][r].Valid){
45         if (! dataGrid[m][r].userdata) {
46           sprintf(cmd,"DgValidCallback %d %d", m, r);
47           retval = Tcl_Eval(MainInterp, cmd);
48           if (retval == TCL_ERROR) {
49             fprintf(stderr, "%s\n", MainInterp->result);
50           }
51           dataGrid[m][r].userdata = (void *) malloc(sizeof (int));
52           *((int *) dataGrid[m][r].userdata) = 1;
53         }
54         if (thislast < 0) {
55           thislast = dataGrid[m][r].LastBucketFilled();
56         }
57       }
58     }
59   }
60
61   /*
62    *  Send range to tcl
63    */
64   if (thislast < LastBucket) {
65     LastBucket = thislast-1;
66   }
67   if (thislast >= 0) {
68     sprintf(cmd,"DgDataCallback %d %d", LastBucket+1, thislast);
69     retval = Tcl_Eval(MainInterp, cmd);
70     if (retval == TCL_ERROR) {
71       fprintf(stderr, "%s\n", MainInterp->result);
72     }
73     LastBucket = thislast;
74   }
75
76   return(retval);
77 }
78
79 int Dg_Fold(int dummy) {
80   int retval;
81
82   retval = Tcl_Eval(MainInterp, "DgFoldCallback");
83   if (retval == TCL_ERROR) {
84     fprintf(stderr, "%s\n", MainInterp->result);
85   }
86   return(retval);
87 }
88
89 int Dg_Invalid(int dummy) {
90   int retval;
91
92   retval = Tcl_Eval(MainInterp, "DgInvalidCallback");
93   if (retval == TCL_ERROR) {
94     fprintf(stderr, "%s\n", MainInterp->result);
95   }
96   return(retval);
97 }
98
99 int Dg_New(int dummy) {
100   int retval;
101
102   retval = Tcl_Eval(MainInterp, "DgConfigCallback");
103   if (retval == TCL_ERROR) {
104     fprintf(stderr, "%s\n", MainInterp->result);
105   }
106   return(retval);
107 }
108
109 int Dg_Phase(int dummy) {
110   int retval;
111
112   retval = Tcl_Eval(MainInterp, "DgPhaseCallback");
113   if (retval == TCL_ERROR) {
114     fprintf(stderr, "%s\n", MainInterp->result);
115   }
116   return(retval);
117 }
118
119 int Dg_GraphElem(Tcl_Interp *interp, char *path, char *elem, int mid, int rid) 
120 {
121   static double *coords = NULL;
122   double *cptr, bwid;
123   float *vals, *vptr;
124   int numb, b;
125
126   /* Allocate an array for the coords */
127   if (coords == NULL) {
128     numb = dataGrid.NumBins();
129     coords = (double *) malloc(sizeof(double) * numb * 2);
130     if (!coords) {
131       sprintf(interp->result, "Dg_GraphElem: Could not allocate coords\n");
132       return TCL_ERROR;
133     }
134   }    
135
136   /* Binwidth and numbuckets give us the t coords */
137   numb = dataGrid[mid][rid].LastBucketFilled()+1;
138   bwid = dataGrid.BinWidth();
139
140   /* Get the data values */
141   vals = dataGrid[mid][rid].Value();
142
143   /* Fill the array */
144   cptr = coords;  
145   vptr = vals;
146   for (b = 0; b < numb; b++) {
147     *cptr++ = b*bwid;
148     if (isnan(*vptr)) {
149       *cptr = 0.0;
150     } else {
151       *cptr = (double) *vptr;
152     }
153     cptr++;
154     vptr++;
155   }
156
157   /* Give it to BLT */
158   return(Blt_GraphElement(interp, path, elem, numb*2, coords));
159 }
160
161
162 #define   AGGREGATE        0
163 #define   BINWIDTH         1
164 #define   FOLDMETHOD       2
165 #define   METRICNAME       3
166 #define   METRICUNITS      4
167 #define   NUMBINS          5
168 #define   NUMMETRICS       6
169 #define   NUMRESOURCES     7
170 #define   DEFINEPHASE      8
171 #define   RESOURCENAME     9
172 #define   STARTSTREAM      10
173 #define   STOPSTREAM       11
174 #define   DGSUM            12
175 #define   DGVALID          13
176 #define   VALUE            14
177 #define   CMDERROR         15
178 #define   LASTBUCKET       16
179 #define   BLTGRAPHELEM     17
180
181 struct cmdTabEntry 
182 {
183   char *cmdname;
184   int index;
185   int numargs;
186 };
187
188 static struct cmdTabEntry Dg_Cmds[] = {
189   {"aggregate",    AGGREGATE,       2},
190   {"binwidth",     BINWIDTH,        0},
191   {"bltgraphelem", BLTGRAPHELEM,    4},
192   {"foldmethod",   FOLDMETHOD,      2},
193   {"lastbucket",   LASTBUCKET,      2},
194   {"metricname",   METRICNAME,      1},
195   {"metricunits",  METRICUNITS,     1},
196   {"numbins",      NUMBINS,         0},
197   {"nummetrics",   NUMMETRICS,      0},
198   {"numresources", NUMRESOURCES,    0},
199   {"phase",        DEFINEPHASE,     3},
200   {"resourcename", RESOURCENAME,    1},
201   {"start",        STARTSTREAM,     2},
202   {"stop",         STOPSTREAM,      2},
203   {"sum",          DGSUM,           2},
204   {"valid",        DGVALID,         2},
205   {"value",        VALUE,           3},
206   {NULL,           CMDERROR,        0}
207 };
208
209 static int findCommand(Tcl_Interp *interp, 
210                        int argc, 
211                        char *argv[])
212 {
213   struct cmdTabEntry *C;
214
215   if (argc == 0) {
216     sprintf(interp->result, "USAGE: Dg <option> [args...]\n");
217     return CMDERROR;
218   }
219   for (C = Dg_Cmds; C->cmdname; C++) {
220     if (strcmp(argv[0], C->cmdname) == 0) {
221       if ((argc-1) == C->numargs) 
222         return C->index;
223       sprintf(interp->result, 
224               "%s: wrong number of args (%d). Should be %d\n",
225               argv[0], argc-1, C->numargs);
226       return CMDERROR;
227     }
228   }
229
230   sprintf(interp->result, "unknown option (%s)\n", argv[0]);
231   return CMDERROR;
232 }
233
234 int Dg_TclCommand(ClientData clientData,
235                Tcl_Interp *interp, 
236                int argc, 
237                char *argv[])
238 {
239   int cmdDex, m, r, buck;
240
241   cmdDex = findCommand(interp, argc-1, argv+1);
242   if (cmdDex == CMDERROR) {
243     return TCL_ERROR;
244   }
245
246   switch(cmdDex) {
247   case AGGREGATE:   
248     m = atoi(argv[2]);
249     r = atoi(argv[3]);
250     sprintf(interp->result,"%g", dataGrid.AggregateValue(m,r));
251     return TCL_OK;
252
253   case BINWIDTH:     
254     sprintf(interp->result, "%g", dataGrid.BinWidth());
255     return TCL_OK;
256
257   case BLTGRAPHELEM:     
258     m = atoi(argv[2]);
259     r = atoi(argv[3]);
260     return (Dg_GraphElem(interp, argv[4], argv[5], m, r));
261
262   case FOLDMETHOD:
263     m = atoi(argv[2]);
264     sprintf(interp->result,"%d", dataGrid.FoldMethod(m));
265     return TCL_OK;
266
267   case LASTBUCKET:
268     m = atoi(argv[2]);
269     r = atoi(argv[3]);
270     sprintf(interp->result,"%d", dataGrid[m][r].LastBucketFilled());
271     return TCL_OK;
272
273   case METRICNAME:  
274     m = atoi(argv[2]);
275     sprintf(interp->result, "%s", dataGrid.MetricName(m));
276     return TCL_OK;
277
278   case METRICUNITS:  
279     m = atoi(argv[2]);
280     sprintf(interp->result, "%s", dataGrid.MetricUnits(m));
281     return TCL_OK;
282
283   case NUMBINS:     
284     sprintf(interp->result, "%d", dataGrid.NumBins());
285     return TCL_OK;
286
287   case NUMMETRICS:  
288     sprintf(interp->result, "%d", dataGrid.NumMetrics());
289     return TCL_OK;
290
291   case NUMRESOURCES:
292     sprintf(interp->result, "%d", dataGrid.NumResources());
293     return TCL_OK;
294
295   case DEFINEPHASE:       
296     NamePhase(atof(argv[2]), atof(argv[3]), argv[4]);
297     return TCL_OK;
298
299   case RESOURCENAME:
300     r = atoi(argv[2]);
301     sprintf(interp->result, "%s", dataGrid.ResourceName(r));
302     return TCL_OK;
303
304   case STARTSTREAM:       
305     GetMetsRes(argv[2], argv[3], 0);
306     return TCL_OK;
307
308   case STOPSTREAM:
309     m = atoi(argv[2]);
310     r = atoi(argv[3]);
311     StopMetRes(m, r);
312     return TCL_OK;
313
314   case DGSUM:         
315     m = atoi(argv[2]);
316     r = atoi(argv[3]);
317     sprintf(interp->result,"%g", dataGrid.SumValue(m,r));
318     return TCL_OK;
319
320   case DGVALID:
321     m = atoi(argv[2]);
322     r = atoi(argv[3]);
323     sprintf(interp->result, "%d", dataGrid.Valid(m,r));
324     return TCL_OK;
325
326   case VALUE:       
327     m = atoi(argv[2]);
328     r = atoi(argv[3]);
329     buck = atoi(argv[4]);
330     sprintf(interp->result,"%g", dataGrid[m][r].Value(buck));
331     return TCL_OK;
332   }
333
334   sprintf(interp->result, "Internal error (func findCommand)\n");
335   return TCL_ERROR;
336 }
337
338 static void
339 my_visi_callback(void* arg0, int* arg1, long unsigned int* arg2)
340 {
341     int ret;
342
343     ret = visi_callback();
344     if (ret == -1) exit(0);
345 }
346
347 int 
348 Dg_Init(Tcl_Interp *interp)
349 {
350   int fd;
351
352   /* Initialize visualization module */
353   if((fd = VisiInit()) < 0){
354     exit(-1);
355   }
356   (void) RegistrationCallback(ADDMETRICSRESOURCES,Dg_Add); 
357   (void) RegistrationCallback(DATAVALUES,Dg_Data); 
358   (void) RegistrationCallback(FOLD,Dg_Fold); 
359   (void) RegistrationCallback(INVALIDMETRICSRESOURCES,Dg_Invalid);
360   (void) RegistrationCallback(NEWMETRICSRESOURCES,Dg_New);
361   (void) RegistrationCallback(PHASENAME,Dg_Phase);
362   (void) StartVisi(0,0);
363
364   Tcl_CreateCommand(interp, "Dg", Dg_TclCommand, 
365                     (ClientData *) NULL,(Tcl_CmdDeleteProc *) NULL);
366  
367   Tk_CreateFileHandler(fd, TK_READABLE, (Tk_FileProc *) my_visi_callback, 0);
368
369   return TCL_OK;
370 }
371
372