Fixed poor handling of RCS logs by last CVS checkin
[dyninst.git] / paradyn / src / UIthread / shgTcl.C
1 /*
2  * Copyright (c) 1996-1998 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 // shgTcl.C
43 // Ariel Tamches
44
45 // Implementations of new commands and tk bindings related to the search history graph.
46
47 /* $Log: shgTcl.C,v $
48 /* Revision 1.13  1999/03/12 22:59:32  pcroth
49 /* Fixed poor handling of RCS logs by last CVS checkin
50 /*
51  * Revision 1.12  1999/03/03 18:16:11  pcroth
52  * Updated to support Windows NT as a front-end platform
53  * Changes made to X code, to use Tcl analogues when appropriate
54  * Also changed in response to modifications in thread library and igen output.
55  *
56  * Revision 1.11  1996/08/16 21:07:21  tamches
57  * updated copyright for release 1.1
58  *
59  * Revision 1.10  1996/08/05 07:30:51  tamches
60  * update for tcl 7.5
61  *
62  * Revision 1.9  1996/02/08 01:01:15  tamches
63  * removed some old code
64  *
65  * Revision 1.8  1996/02/07 19:14:28  tamches
66  * made use of new routines in shgPhases which operate on the current
67  * search -- no more getCurrent() usage here.
68  * Some global vars moved to shgPhases
69  *
70  * Revision 1.7  1996/02/02 18:54:13  tamches
71  * added shgDrawKeyCallback, shgDrawTipsCallback,
72  * shgMiddleClickCallbackCommand is new.
73  * shgAltReleaseCommand shrunk accordingly.
74  * added shgRefineGlobalPhase (temporarily)
75  * fixed code in shgSearchCommand
76  *
77  * Revision 1.6  1996/02/02 02:03:12  karavan
78  * oops!  corrected call to performanceconsultant::newSearch
79  *
80  * Revision 1.5  1996/02/02 01:01:34  karavan
81  * Changes to support the new PC/UI interface
82  *
83  * Revision 1.4  1996/01/23 07:10:16  tamches
84  * fixed a UI bug noticed by Marcelo that could lead to an assertion
85  * failure when scrolling large amounts.
86  *
87  */
88
89 #include "util/h/headers.h"
90 #include "tkTools.h"
91
92 #ifndef PARADYN
93 // The test program has "correct" -I paths already set
94 #include "DMinclude.h" // for resourceHandle
95 #else
96 #include "paradyn/src/DMthread/DMinclude.h" // for resourceHandle
97 #endif
98
99 #ifdef PARADYN
100 #include "performanceConsultant.thread.CLNT.h"
101 extern performanceConsultantUser *perfConsult;
102 #endif
103
104 #include "shgPhases.h"
105 #include "shgTcl.h"
106
107 // Here is the main shg global variable.  Why is it a pointer?  Because
108 // we don't want to construct it until the shg window is created.
109 // Why?  Because the constructor assumes the shg window and certain
110 // subwindows exist.
111 shgPhases *theShgPhases;
112
113 extern bool haveSeenFirstGoodShgWid; // main.C
114 extern bool tryFirstGoodShgWid(Tcl_Interp *, Tk_Window); // main.C
115
116 void shgWhenIdleDrawRoutine(ClientData cd) {
117    assert(haveSeenFirstGoodShgWid);
118
119    const bool doubleBuffer = (bool)cd;
120
121 #ifdef PARADYN
122 #ifdef XSYNCH
123    const bool isXsynchOn = true;
124 #else
125    const bool isXsynchOn = false;
126 #endif
127 #else
128    extern bool xsynchronize;
129    const bool isXsynchOn = xsynchronize; // main.C
130 #endif
131
132    theShgPhases->draw(doubleBuffer, isXsynchOn);
133 }
134 tkInstallIdle shgDrawWhenIdle(&shgWhenIdleDrawRoutine);
135
136 void initiateShgRedraw(Tcl_Interp *, bool doubleBuffer) {
137    shgDrawWhenIdle.install((ClientData)doubleBuffer);
138 }
139
140 int shgResizeCallbackCommand(ClientData, Tcl_Interp *interp, int, char **) {
141    if (!tryFirstGoodShgWid(interp, Tk_MainWindow(interp)))
142       return TCL_ERROR;
143
144    if (theShgPhases->resize())
145       initiateShgRedraw(interp, true); // true-->use double-buffering
146
147    return TCL_OK;
148 }
149
150 int shgExposeCallbackCommand(ClientData, Tcl_Interp *interp,
151                              int argc, char **argv) {
152    if (!tryFirstGoodShgWid(interp, Tk_MainWindow(interp)))
153       return TCL_ERROR;
154
155    assert(argc == 2);
156    const int count = atoi(argv[1]); // Xevent count field (we should only redraw if 0)
157
158    if (count==0)
159       initiateShgRedraw(interp, true); // true --> double buffer
160
161    return TCL_OK;
162 }
163
164 int shgSingleClickCallbackCommand(ClientData, Tcl_Interp *, int argc, char **argv) {
165    assert(haveSeenFirstGoodShgWid);
166
167    assert(argc == 3);
168    const int x = atoi(argv[1]);
169    const int y = atoi(argv[2]);
170
171    theShgPhases->processSingleClick(x, y);
172
173    return TCL_OK;
174 }
175
176 int shgMiddleClickCallbackCommand(ClientData, Tcl_Interp *, int argc, char **argv) {
177    assert(haveSeenFirstGoodShgWid);
178
179    assert(argc == 3);
180    const int x = atoi(argv[1]);
181    const int y = atoi(argv[2]);
182
183    theShgPhases->processMiddleClick(x, y);
184
185    return TCL_OK;
186 }
187
188 int shgDoubleClickCallbackCommand(ClientData, Tcl_Interp *interp,
189                                   int argc, char **argv) {
190    assert(haveSeenFirstGoodShgWid);
191    assert(argc==3);
192
193    const int x = atoi(argv[1]);
194    const int y = atoi(argv[2]);
195
196    if (theShgPhases->processDoubleClick(x, y))
197       initiateShgRedraw(interp, true); // true--> use double buffer
198
199    return TCL_OK;
200 }
201
202 //int shgShiftDoubleClickCallbackCommand(ClientData, Tcl_Interp *interp,
203 //                                     int argc, char **argv) {
204 //   assert(haveSeenFirstGoodShgWid);
205 //   assert(argc == 3);
206 //
207 //   const int x = atoi(argv[1]);
208 //   const int y = atoi(argv[2]);
209 //
210 //   if (theShg != NULL) {
211 //      bool needToRedrawAll=theShg->processShiftDoubleClick(x, y);
212 //      if (needToRedrawAll)
213 //         initiateShgRedraw(interp, true); // true --> double buffer
214 //   }
215 //
216 //   return TCL_OK;
217 //}
218 //
219 //int shgCtrlDoubleClickCallbackCommand(ClientData, Tcl_Interp *interp,
220 //                                    int argc, char **argv) {
221 //   assert(haveSeenFirstGoodShgWid);
222 //
223 //   assert(argc==3);
224 //   const int x = atoi(argv[1]);
225 //   const int y = atoi(argv[2]);
226 //
227 //   if (theShg != NULL) {
228 //      bool needToRedrawAll=theShg->processCtrlDoubleClick(x, y);
229 //      if (needToRedrawAll)
230 //         initiateShgRedraw(interp, true);
231 //   }
232 //
233 //   return TCL_OK;
234 //}
235
236 int shgNewVertScrollPositionCommand(ClientData, Tcl_Interp *interp,
237                                     int argc, char **argv) {
238    assert(haveSeenFirstGoodShgWid);
239
240    // The arguments will be one of:
241    // 1) moveto [fraction]
242    // 2) scroll [num-units] unit   (num-units is always either -1 or 1)
243    // 3) scroll [num-pages] page   (num-pages is always either -1 or 1)
244
245    if (theShgPhases->newVertScrollPosition(argc, argv))
246       initiateShgRedraw(interp, true);
247
248    return TCL_OK;
249 }
250
251 int shgNewHorizScrollPositionCommand(ClientData, Tcl_Interp *interp,
252                                      int argc, char **argv) {
253    assert(haveSeenFirstGoodShgWid);
254
255    // The arguments will be one of:
256    // 1) moveto [fraction]
257    // 2) scroll [num-units] unit   (num-units is always either -1 or 1)
258    // 3) scroll [num-pages] page   (num-pages is always either -1 or 1)
259
260    if (theShgPhases->newHorizScrollPosition(argc, argv))
261       initiateShgRedraw(interp, true); // true --> double buffer
262
263    return TCL_OK;
264 }
265
266 //int shgClearSelectionsCommand(ClientData, Tcl_Interp *interp,
267 //                            int argc, char **) {
268 //   assert(haveSeenFirstGoodShgWid);
269 //
270 //   assert(argc == 1);
271 //   if (theShg != NULL) {
272 //      theShg->clearSelections(); // doesn't redraw
273 //      initiateShgRedraw(interp, true); // true --> double buffer
274 //   }
275 // 
276 //   return TCL_OK;
277 //}
278
279 //int shgNavigateToCommand(ClientData, Tcl_Interp *interp, int argc, char **argv) {
280 //   assert(haveSeenFirstGoodShgWid);
281 //
282 //   assert(argc == 2);
283 //   const int level = atoi(argv[1]);
284 //
285 //   if (theShg != NULL) {
286 //      theShg->navigateTo(level);
287 //      initiateShgRedraw(interp, true); // true --> redraw now
288 //   }
289 //
290 //   return TCL_OK;
291 //}
292
293 //int whereAxisFindCommand(ClientData, Tcl_Interp *interp,
294 //                       int argc, char **argv) {
295 //   assert(haveSeenFirstGoodWhereAxisWid);
296 //
297 //   assert(argc == 2);
298 //   const char *str = argv[1];
299 //
300 //   if (theAbstractions->existsCurrent()) {
301 //      const int result = theAbstractions->getCurrent().find(str);
302 //         // 0 --> not found
303 //         // 1 --> found, and nothing had to be expanded (i.e. just a pure scroll)
304 //         // 2 --> found, and stuff had to be expanded (i.e. must redraw everything)
305 //   
306 //      if (result==1 || result==2)
307 //         initiateWhereAxisRedraw(interp, true);
308 //   }
309 //
310 //   return TCL_OK;
311 //}
312
313
314 int shgAltPressCommand(ClientData, Tcl_Interp *interp, int argc, char **argv) {
315    if (!haveSeenFirstGoodShgWid)
316       return TCL_OK;
317
318    assert(argc==3);
319    int x = atoi(argv[1]);
320    int y = atoi(argv[2]);
321
322    if (theShgPhases->altPress(x, y))
323       initiateShgRedraw(interp, true);
324
325    return TCL_OK;
326 }
327
328 int shgAltReleaseCommand(ClientData, Tcl_Interp *, int, char **) {
329    // Un-install the mouse-move event handler that may have been
330    // installed by the above routine.
331
332    if (haveSeenFirstGoodShgWid)
333       theShgPhases->altRelease();
334
335    return TCL_OK;
336 }
337
338 int shgChangePhaseCommand(ClientData, Tcl_Interp *interp, int argc, char **argv) {
339    if (!haveSeenFirstGoodShgWid)
340       return TCL_OK;
341
342    assert(argc == 2);
343    const int phaseId = atoi(argv[1]);
344
345    if (theShgPhases->changeByPhaseId(phaseId))
346       initiateShgRedraw(interp, true);
347
348    return TCL_OK;
349 }
350
351 int shgSearchCommand(ClientData, Tcl_Interp *interp, int, char **) {
352    // sets tcl result string to true/false indicating whether the search
353    // was successfully started.
354
355 #ifdef PARADYN
356    // the shg test program does not "really" do a search
357    setResultBool(interp, theShgPhases->activateCurrSearch());
358 #else
359    strcpy(interp->result, "true");
360 #endif
361
362    return TCL_OK;
363 }
364
365 int shgPauseCommand(ClientData, Tcl_Interp *interp, int, char **) {
366    // sets tcl result string to true/false indicating whether the search
367    // was successfully paused.
368
369 #ifdef PARADYN
370    // the shg test program does not "really" do a search
371    setResultBool(interp, theShgPhases->pauseCurrSearch());
372 #else
373    strcpy(interp->result, "true");
374 #endif
375
376    return TCL_OK;
377 }
378
379 int shgResumeCommand(ClientData, Tcl_Interp *interp, int, char **) {
380    // sets tcl result string to true/false indicating whether the search
381    // was successfully resumed.
382
383 #ifdef PARADYN
384    // the shg test program does not "really" do a search
385    setResultBool(interp, theShgPhases->resumeCurrSearch());
386 #else
387    strcpy(interp->result, "true");
388 #endif
389
390    return TCL_OK;
391 }
392
393 /* ******************************************************************** */
394
395 #ifdef PARADYN
396 void shgDrawKeyCallback(bool newValue) {
397    extern Tcl_Interp *interp;
398    if (newValue)
399       myTclEval(interp, "redrawKeyAndTipsAreas on nc");
400    else
401       myTclEval(interp, "redrawKeyAndTipsAreas off nc");
402 }
403 void shgDrawTipsCallback(bool newValue) {
404    extern Tcl_Interp *interp;
405    if (newValue)
406       myTclEval(interp, "redrawKeyAndTipsAreas nc on");
407    else
408       myTclEval(interp, "redrawKeyAndTipsAreas nc off");
409 }
410 #endif
411
412 /* ******************************************************************** */
413
414 void shgDeleteDummyProc(ClientData) {}
415 void installShgCommands(Tcl_Interp *interp) {
416    Tcl_CreateCommand(interp, "shgConfigureHook", shgResizeCallbackCommand,
417                      NULL, // clientData
418                      shgDeleteDummyProc);
419    Tcl_CreateCommand(interp, "shgExposeHook", shgExposeCallbackCommand,
420                      NULL, shgDeleteDummyProc);
421    Tcl_CreateCommand(interp, "shgSingleClickHook", shgSingleClickCallbackCommand,
422                      NULL, shgDeleteDummyProc);
423    Tcl_CreateCommand(interp, "shgMiddleClickHook", shgMiddleClickCallbackCommand,
424                      NULL, shgDeleteDummyProc);
425    Tcl_CreateCommand(interp, "shgDoubleClickHook", shgDoubleClickCallbackCommand,
426                      NULL, shgDeleteDummyProc);
427 //   Tcl_CreateCommand(interp, "shgShiftDoubleClickHook",
428 //                   shgShiftDoubleClickCallbackCommand,
429 //                   NULL, shgDeleteDummyProc);
430 //   Tcl_CreateCommand(interp, "shgCtrlDoubleClickHook",
431 //                   shgCtrlDoubleClickCallbackCommand,
432 //                   NULL, shgDeleteDummyProc);
433    Tcl_CreateCommand(interp, "shgNewVertScrollPosition",
434                      shgNewVertScrollPositionCommand,
435                      NULL, shgDeleteDummyProc);
436    Tcl_CreateCommand(interp, "shgNewHorizScrollPosition",
437                      shgNewHorizScrollPositionCommand,
438                      NULL, shgDeleteDummyProc);
439 //   Tcl_CreateCommand(interp, "shgClearSelections",
440 //                   shgClearSelectionsCommand,
441 //                   NULL, shgDeleteDummyProc);
442 //   Tcl_CreateCommand(interp, "shgNavigateTo", shgNavigateToCommand,
443 //                   NULL, shgDeleteDummyProc);
444 //   Tcl_CreateCommand(interp, "shgFindHook", shgFindCommand,
445 //                   NULL, shgDeleteDummyProc);
446    Tcl_CreateCommand(interp, "shgAltPressHook", shgAltPressCommand,
447                      NULL, shgDeleteDummyProc);
448    Tcl_CreateCommand(interp, "shgAltReleaseHook", shgAltReleaseCommand,
449                      NULL, shgDeleteDummyProc);
450    Tcl_CreateCommand(interp, "shgChangePhase", shgChangePhaseCommand,
451                      NULL, shgDeleteDummyProc);
452    Tcl_CreateCommand(interp, "shgSearchCommand", shgSearchCommand,
453                      NULL, shgDeleteDummyProc);
454    Tcl_CreateCommand(interp, "shgPauseCommand", shgPauseCommand,
455                      NULL, shgDeleteDummyProc);
456    Tcl_CreateCommand(interp, "shgResumeCommand", shgResumeCommand,
457                      NULL, shgDeleteDummyProc);
458 }
459
460 void unInstallShgCommands(Tcl_Interp *interp) {
461    Tcl_DeleteCommand(interp, "shgChangePhase");
462    Tcl_DeleteCommand(interp, "shgAltReleaseHook");
463    Tcl_DeleteCommand(interp, "shgAltPressHook");
464    Tcl_DeleteCommand(interp, "shgFindHook");
465    Tcl_DeleteCommand(interp, "shgChangeAbstraction");
466    Tcl_DeleteCommand(interp, "shgNavigateTo");
467    Tcl_DeleteCommand(interp, "shgClearSelections");
468    Tcl_DeleteCommand(interp, "shgNewHorizScrollPosition");
469    Tcl_DeleteCommand(interp, "shgNewVertScrollPosition");
470 //   Tcl_DeleteCommand(interp, "shgCtrlDoubleClickHook");
471 //   Tcl_DeleteCommand(interp, "shgShiftDoubleClickHook");
472    Tcl_DeleteCommand(interp, "shgDoubleClickHook");
473    Tcl_DeleteCommand(interp, "shgSingleClickHook");
474    Tcl_DeleteCommand(interp, "shgMiddleClickHook");
475    Tcl_DeleteCommand(interp, "shgExposeHook");
476    Tcl_DeleteCommand(interp, "shgConfigureHook");
477    Tcl_DeleteCommand(interp, "shgSearchCommand");
478    Tcl_DeleteCommand(interp, "shgPauseCommand");
479    Tcl_DeleteCommand(interp, "shgResumeCommand");
480 }
481
482 void shgDevelModeChange(Tcl_Interp *interp, bool inDevelMode) {
483    // the developer-mode tunable constant has changed.
484    // If the PC shg window is up, then we need to change the height of
485    // the status line window, ".shg.nontop.labelarea.current"
486
487    unsigned height = inDevelMode ? 4 : 1;
488    string commandStr = string("shgChangeCurrLabelHeight ") + string(height);
489    myTclEval(interp, commandStr);
490 }