reorginization of visiLib
[dyninst.git] / visiClients / barchart / barChartTcl.C
1 // barChartTcl.C
2
3 /* $Log: barChartTcl.C,v $
4 /* Revision 1.11  1996/01/11 01:53:42  tamches
5 /* added long2shortFocusNameCommand to compute short focus names
6 /*
7  * Revision 1.10  1996/01/10 19:36:12  tamches
8  * launchBarChart now takes 4 args instead of 7
9  *
10  * Revision 1.9  1996/01/10 02:24:25  tamches
11  * dataFormatHasChangedCommand now takes in an arg
12  * added getMetricColorNameCommand
13  * hardcoded barColorNames here
14  *
15  * Revision 1.8  1995/09/22 19:25:29  tamches
16  * removed warnings under g++ 2.7.0
17  *
18  * Revision 1.7  1994/11/06  10:24:59  tamches
19  * minor cleanups (especially comments)
20  *
21  * Revision 1.6  1994/10/14  10:29:33  tamches
22  * commented out diagnosted message when gracefully closing
23  *
24  * Revision 1.5  1994/10/13  00:52:38  tamches
25  * Minor additions to support a new command related to sorting
26  * of resources
27  *
28  * Revision 1.4  1994/10/10  23:08:44  tamches
29  * preliminary changes on the way to swapping the x and y axes
30  *
31  * Revision 1.3  1994/10/10  14:36:17  tamches
32  * fixed some resizing bugs
33  *
34  * Revision 1.2  1994/09/29  20:05:37  tamches
35  * minor cvs fixes
36  *
37  * Revision 1.1  1994/09/29  19:51:38  tamches
38  * initial implementation.
39  * Receiving point for visi lib callback routines.  Pretty much
40  * just calls the appropriate class member function in barChart.C
41  *
42 */
43
44 #include <iostream.h>
45
46 #include "Vector.h"
47 #include "String.h"
48
49 #include <tcl.h>
50 #include <tk.h>
51 #include "dg2.h" // for dataGrid[][]
52 #include "visi/h/visualization.h"
53 #include "barChart.h"
54
55 bool barChartIsValid = false;
56    // set to true ** after ** barChart::barChart
57    // until then, callbacks check this flag and do nothing
58
59 int Dg2NewDataCallback(int lastBucket) {
60    if (barChartIsValid) {
61       theBarChart->processNewData(lastBucket);
62       return TCL_OK;
63    }
64    else
65       return TCL_ERROR;
66 }
67
68 int resizeCallbackCommand(ClientData, Tcl_Interp *, int argc, char **argv) {
69    // called from barChart.tcl when it detects a resize; gives our C++ code
70    // a chance to process the resize, too.
71
72    // params: new width, new height
73    if (barChartIsValid && argc==3) {
74       theBarChart->processResizeWindow(atoi(argv[1]), atoi(argv[2]));
75       return TCL_OK;
76    }
77    else
78       return TCL_ERROR;
79 }
80
81 int exposeCallbackCommand(ClientData, Tcl_Interp *, int, char **) {
82    // called from barChart.tcl when it detects an expose; gives our C++ code
83    // a chance to process the expose, too.
84
85    if (barChartIsValid) {
86       theBarChart->processExposeWindow();
87       return TCL_OK;
88    }
89    else
90       return TCL_ERROR;
91 }
92
93 int resourcesAxisHasChangedCommand(ClientData, Tcl_Interp *, int argc, char **) {
94    // called from barChart.tcl when the x-axis layout has changed due to resize,
95    // insertion/deletion, etc; gives our C++ code a chance to update its
96    // internal structures.
97
98    // arg: new width
99
100    if (barChartIsValid && argc==2) {
101       theBarChart->RethinkMetricsAndResources();
102       return TCL_OK;
103    }
104    else
105       return TCL_ERROR;
106 }
107
108 int metricsAxisHasChangedCommand(ClientData, Tcl_Interp *, int argc, char **) {
109    // called from barChart.tcl when the y-axis layout has changed due to resize,
110    // insertion/deletion, etc; gives our C++ code a chance to update its
111    // internal structures.
112
113    // argument: new height (but currently unused)
114
115    if (barChartIsValid && argc==2) {
116       theBarChart->RethinkMetricsAndResources();
117       return TCL_OK;
118    }
119    else
120       return TCL_ERROR;
121 }
122
123 int newScrollPositionCommand(ClientData, Tcl_Interp *, int argc, char **argv) {
124    // called by tcl code when it's time to scroll the bars to a given value.
125    // argument: new first-visible-pixel.
126
127    if (barChartIsValid && argc==2) {
128       int newPos = atoi(argv[1]);
129       theBarChart->processNewScrollPosition(newPos);
130       return TCL_OK;
131    }
132    else
133       return TCL_ERROR;
134 }
135
136 int dataFormatHasChangedCommand(ClientData, Tcl_Interp *, int argc, char **argv) {
137    // rethink current vs. average vs. total
138    assert(argc == 2);
139    if (barChartIsValid) {
140       char *dataFormatString = argv[1];
141       if (0==strcmp(dataFormatString, "Instantaneous"))
142          theBarChart->rethinkDataFormat(BarChart::Current);
143       else if (0==strcmp(dataFormatString, "Average"))
144          theBarChart->rethinkDataFormat(BarChart::Average);
145       else if (0==strcmp(dataFormatString, "Sum"))
146          theBarChart->rethinkDataFormat(BarChart::Total);
147       else
148          panic("barChart dataFormatHasChangedCommand: unrecognized argument");
149       return TCL_OK;
150    }
151    else
152       return TCL_ERROR;
153 }
154
155 int rethinkIndirectResourcesCommand(ClientData, Tcl_Interp *, int, char **) {
156    // rethink how things are sorted
157    if (barChartIsValid) {
158       theBarChart->rethinkIndirectResources();
159       return TCL_OK;
160    }
161    else
162       return TCL_ERROR;
163 }
164
165 int getMetricColorNameCommand(ClientData, Tcl_Interp *interp,
166                               int argc, char **argv) {
167    // argument: metric index
168    assert(argc==2);
169    unsigned index = atoi(argv[1]);
170
171    const string &result = theBarChart->getMetricColorName(index);
172    strcpy(interp->result, result.string_of());
173    return TCL_OK;
174 }
175
176 int long2shortFocusNameCommand(ClientData, Tcl_Interp *interp, int argc, char **argv) {
177    assert(argc==2);
178    char *longName = argv[1];
179
180    // NOTE: most of this code is borrowed/stolen from tableVisi's tvFocus::tvFocus
181    //       routine.
182
183    if (0==strcmp(longName, "Whole Program")) {
184       // no change
185       strcpy(interp->result, longName);
186       return TCL_OK;
187    }
188
189    // Step 1: split up into components; 1 per resource hierarchy
190    vector<string> components;
191    const char *ptr = longName;
192
193    while (*ptr != '\0') {
194       // begin a new component; collect upto & including the first seen comma
195       char buffer[200];
196       char *bufferPtr = &buffer[0];
197       do {
198          *bufferPtr++ = *ptr++;
199       } while (*ptr != ',' && *ptr != '\0');
200
201       if (*ptr == ',')
202          *bufferPtr++ = *ptr++;
203
204       *bufferPtr = '\0';
205
206       components += string(buffer);
207    }
208
209    // Step 2: for each component, strip off all upto and including
210    //         the last '/'
211    for (unsigned componentlcv=0; componentlcv < components.size(); componentlcv++) {
212       const string &oldComponentString = components[componentlcv];
213
214       char *ptr = strrchr(oldComponentString.string_of(), '/');
215       if (ptr == NULL)
216          cerr << "tableVisi: could not find / in component " << oldComponentString << endl;
217       else if (ptr+1 == '\0')
218          cerr << "tableVisi: there was nothing after / in component " << oldComponentString << endl;
219       else
220          components[componentlcv] = string(ptr+1);
221    }
222
223    // Step 3: combine the components
224    string theShortName;
225    for (unsigned componentlcv=0; componentlcv < components.size(); componentlcv++)
226       theShortName += components[componentlcv];
227
228    // Step 4: pull it all together:
229    strcpy(interp->result, theShortName.string_of());
230    return TCL_OK;
231 }
232
233 int launchBarChartCommand(ClientData, Tcl_Interp *, int argc, char **argv) {
234    // called just once to fix some information needed by drawBarsCommand, especially
235    // the (sub-)window in which to draw.
236
237    // parameters:
238    // 1) window name (tk-style; e.g. ".top.middle.bar") of the area in which the bars
239    //    are drawn.
240    // 2) do you want double-buffering? ("doublebuffer" or "nodoublebuffer")
241    // 3) do you want no-flicker?       ("noflicker" or "flicker")
242    //       [you automatically get noflicker with doublebuffer]
243    // 4) initial numMetrics
244    // 5) initial numResources
245    // 6) flush flag (0 or 1); use 1 during debugging only
246
247    // cout << "Welcome to launchBarChartCommand()" << endl;
248    
249    if (argc != 4)
250       panic("launchBarChartCommand() -- cannot create barchart (incorrect #args)");
251
252    char *wname = argv[1];
253    const int iNumMetrics   = atoi(argv[2]);
254    const int iNumResources = atoi(argv[3]);
255
256    // bar colors: (see /usr/lib/X11/rgb.txt)
257    vector<string> barColorNames;
258    barColorNames += "cornflower blue";
259    barColorNames += "medium sea green";
260    barColorNames += "hotpink";
261    barColorNames += "chocolate";
262    barColorNames += "orange";
263
264    theBarChart = new BarChart(wname, iNumMetrics, iNumResources, barColorNames);
265    assert(theBarChart);
266
267    barChartIsValid = true;
268    return TCL_OK;
269 }
270
271 void deleteLaunchBarChartCommand(ClientData) {
272    // cout << "Gracefully closing down barchart..." << endl;
273
274    barChartIsValid = false; // important!
275    delete theBarChart;
276 }
277
278 void deleteDummyProc(ClientData) { }
279    // do-nothing routine to be called when a command is deleted that
280    // doesn't require closing down...