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