]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/gdbtk-hooks.c
This is the merge of the Itcl3.0 gdbtk development branch into the
[thirdparty/binutils-gdb.git] / gdb / gdbtk-hooks.c
CommitLineData
ca4e7e14
JI
1/* Startup code for gdbtk.
2 Copyright 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
3
4 Written by Stu Grossman <grossman@cygnus.com> of Cygnus Support.
5
6This file is part of GDB.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
22#include "defs.h"
23#include "symtab.h"
24#include "inferior.h"
25#include "command.h"
26#include "bfd.h"
27#include "symfile.h"
28#include "objfiles.h"
29#include "target.h"
30#include "gdbcore.h"
31#include "tracepoint.h"
32#include "demangle.h"
33
34#ifdef _WIN32
35#include <winuser.h>
36#endif
37
38#include <sys/stat.h>
39
40#include <tcl.h>
41#include <tk.h>
42#include <itcl.h>
43#include <tix.h>
44#include "guitcl.h"
45#include "gdbtk.h"
46
47#ifdef IDE
48/* start-sanitize-ide */
49#include "event.h"
50#include "idetcl.h"
51#include "ilutk.h"
52/* end-sanitize-ide */
53#endif
54
55#ifdef ANSI_PROTOTYPES
56#include <stdarg.h>
57#else
58#include <varargs.h>
59#endif
60#include <signal.h>
61#include <fcntl.h>
62#include <unistd.h>
63#include <setjmp.h>
64#include "top.h"
65#include <sys/ioctl.h>
66#include "gdb_string.h"
67#include "dis-asm.h"
68#include <stdio.h>
69#include "gdbcmd.h"
70
71#include "annotate.h"
72#include <sys/time.h>
73
74int in_fputs = 0;
75
3d64f1e0
KS
76extern int (*ui_load_progress_hook) PARAMS ((char *, unsigned long));
77extern void (*pre_add_symbol_hook) PARAMS ((char *));
78extern void (*post_add_symbol_hook) PARAMS ((void));
79extern void (*selected_frame_level_changed_hook) PARAMS ((int));
c98fe0c1 80#ifdef __CYGWIN32__
ca4e7e14
JI
81extern void (*ui_loop_hook) PARAMS ((int));
82#endif
3d64f1e0 83
ca4e7e14
JI
84static void gdbtk_create_tracepoint PARAMS ((struct tracepoint *));
85static void gdbtk_delete_tracepoint PARAMS ((struct tracepoint *));
86static void gdbtk_modify_tracepoint PARAMS ((struct tracepoint *));
63d138d9 87static void gdbtk_trace_find PARAMS ((char *arg, int from_tty));
2aae6397 88static void gdbtk_trace_start_stop PARAMS ((int, int));
ca4e7e14
JI
89static void gdbtk_create_breakpoint PARAMS ((struct breakpoint *));
90static void gdbtk_delete_breakpoint PARAMS ((struct breakpoint *));
91static void gdbtk_modify_breakpoint PARAMS ((struct breakpoint *));
4fb67eb5
KS
92static void gdbtk_file_changed PARAMS ((char *));
93static void gdbtk_exec_file_display PARAMS ((char *));
ca4e7e14
JI
94static void tk_command_loop PARAMS ((void));
95static void gdbtk_call_command PARAMS ((struct cmd_list_element *, char *, int));
96static int gdbtk_wait PARAMS ((int, struct target_waitstatus *));
97 void x_event PARAMS ((int));
98static int gdbtk_query PARAMS ((const char *, va_list));
99static void gdbtk_warning PARAMS ((const char *, va_list));
100void gdbtk_ignorable_warning PARAMS ((const char *));
101static char* gdbtk_readline PARAMS ((char *));
102static void
103#ifdef ANSI_PROTOTYPES
104gdbtk_readline_begin (char *format, ...);
105#else
106gdbtk_readline_begin ();
107#endif
108static void gdbtk_readline_end PARAMS ((void));
65b07ddc 109static void gdbtk_flush PARAMS ((GDB_FILE *));
ca4e7e14
JI
110static void gdbtk_pre_add_symbol PARAMS ((char *));
111static void gdbtk_print_frame_info PARAMS ((struct symtab *, int, int, int));
112static void gdbtk_post_add_symbol PARAMS ((void));
113static void pc_changed PARAMS ((void));
114static void tracepoint_notify PARAMS ((struct tracepoint *, const char *));
3d64f1e0 115static void gdbtk_selected_frame_changed PARAMS ((int));
4ff5d55a 116static void gdbtk_context_change PARAMS ((int));
c98fe0c1 117static void gdbtk_error_begin PARAMS ((void));
ca4e7e14
JI
118
119/*
120 * gdbtk_fputs can't be static, because we need to call it in gdbtk.c.
121 * See note there for details.
122 */
123
65b07ddc 124void gdbtk_fputs PARAMS ((const char *, GDB_FILE *));
ca4e7e14
JI
125int gdbtk_load_hash PARAMS ((char *, unsigned long));
126static void breakpoint_notify PARAMS ((struct breakpoint *, const char *));
127
128/*
129 * gdbtk_add_hooks - add all the hooks to gdb. This will get called by the
130 * startup code to fill in the hooks needed by core gdb.
131 */
132
133void
134gdbtk_add_hooks(void)
135{
136 command_loop_hook = tk_command_loop;
137 call_command_hook = gdbtk_call_command;
138 readline_begin_hook = gdbtk_readline_begin;
139 readline_hook = gdbtk_readline;
140 readline_end_hook = gdbtk_readline_end;
141
142 print_frame_info_listing_hook = gdbtk_print_frame_info;
143 query_hook = gdbtk_query;
144 warning_hook = gdbtk_warning;
145 flush_hook = gdbtk_flush;
146
147 create_breakpoint_hook = gdbtk_create_breakpoint;
148 delete_breakpoint_hook = gdbtk_delete_breakpoint;
149 modify_breakpoint_hook = gdbtk_modify_breakpoint;
150
2c04e0d9
KS
151 interactive_hook = gdbtk_interactive;
152 target_wait_hook = gdbtk_wait;
153 ui_load_progress_hook = gdbtk_load_hash;
154
c98fe0c1 155#ifdef __CYGWIN32__
ca4e7e14
JI
156 ui_loop_hook = x_event;
157#endif
2c04e0d9
KS
158 pre_add_symbol_hook = gdbtk_pre_add_symbol;
159 post_add_symbol_hook = gdbtk_post_add_symbol;
4fb67eb5
KS
160 file_changed_hook = gdbtk_file_changed;
161 exec_file_display_hook = gdbtk_exec_file_display;
ca4e7e14
JI
162
163 create_tracepoint_hook = gdbtk_create_tracepoint;
164 delete_tracepoint_hook = gdbtk_delete_tracepoint;
165 modify_tracepoint_hook = gdbtk_modify_tracepoint;
63d138d9 166 trace_find_hook = gdbtk_trace_find;
2aae6397 167 trace_start_stop_hook = gdbtk_trace_start_stop;
c98fe0c1 168
ca4e7e14 169 pc_changed_hook = pc_changed;
3d64f1e0 170 selected_frame_level_changed_hook = gdbtk_selected_frame_changed;
4ff5d55a 171 context_hook = gdbtk_context_change;
c98fe0c1
JI
172
173 error_begin_hook = gdbtk_error_begin;
ca4e7e14
JI
174}
175
176/* These control where to put the gdb output which is created by
177 {f}printf_{un}filtered and friends. gdbtk_fputs and gdbtk_flush are the
178 lowest level of these routines and capture all output from the rest of GDB.
179
180 The reason to use the result_ptr rather than the gdbtk_interp's result
181 directly is so that a call_wrapper invoked function can preserve its result
182 across calls into Tcl which might be made in the course of the function's
183 execution.
184
185 * result_ptr->obj_ptr is where to accumulate the result.
186 * GDBTK_TO_RESULT flag means the output goes to the gdbtk_tcl_fputs proc
187 instead of to the result_ptr.
188 * GDBTK_MAKES_LIST flag means add to the result as a list element.
189
190 */
191
192gdbtk_result *result_ptr = NULL;
193\f
194
195/* This allows you to Tcl_Eval a tcl command which takes
196 a command word, and then a single argument. */
197
198int gdbtk_two_elem_cmd (cmd_name, argv1)
199 char *cmd_name;
200 char * argv1;
201{
202 char *command;
203 int result, flags_ptr, arg_len, cmd_len;
204
205 arg_len = Tcl_ScanElement (argv1, &flags_ptr);
206 cmd_len = strlen (cmd_name);
207 command = malloc(arg_len + cmd_len + 2);
208 strcpy (command, cmd_name);
209 strcat (command, " ");
210
211 Tcl_ConvertElement (argv1, command + cmd_len + 1, flags_ptr);
212
213 result = Tcl_Eval (gdbtk_interp, command);
214 free (command);
215 return result;
216
217}
218
219static void
220gdbtk_flush (stream)
65b07ddc 221 GDB_FILE *stream;
ca4e7e14
JI
222{
223#if 0
224 /* Force immediate screen update */
225
226 Tcl_VarEval (gdbtk_interp, "gdbtk_tcl_flush", NULL);
227#endif
228}
229
230/* This handles all the output from gdb. All the gdb printf_xxx functions
231 * eventually end up here. The output is either passed to the result_ptr
232 * where it will go to the result of some gdbtk command, or passed to the
233 * Tcl proc gdbtk_tcl_fputs (where it is usually just dumped to the console
234 * window.
235 *
236 * The cases are:
237 *
238 * 1) result_ptr == NULL - This happens when some output comes from gdb which
f3b86a30 239 * is not generated by a command in gdbtk-cmds, usually startup stuff.
ca4e7e14
JI
240 * In this case we just route the data to gdbtk_tcl_fputs.
241 * 2) The GDBTK_TO_RESULT flag is set - The result is supposed to go to Tcl.
242 * We place the data into the result_ptr, either as a string,
243 * or a list, depending whether the GDBTK_MAKES_LIST bit is set.
244 * 3) The GDBTK_TO_RESULT flag is unset - We route the data to gdbtk_tcl_fputs
65b07ddc 245 * UNLESS it was coming to gdb_stderr. Then we place it in the result_ptr
ca4e7e14
JI
246 * anyway, so it can be dealt with.
247 *
248 */
249
250void
251gdbtk_fputs (ptr, stream)
252 const char *ptr;
65b07ddc 253 GDB_FILE *stream;
ca4e7e14
JI
254{
255 in_fputs = 1;
256
257 if (result_ptr != NULL)
258 {
259 if (result_ptr->flags & GDBTK_TO_RESULT)
260 {
261 if (result_ptr->flags & GDBTK_MAKES_LIST)
262 Tcl_ListObjAppendElement(NULL, result_ptr->obj_ptr,
263 Tcl_NewStringObj((char *) ptr, -1));
264 else
265 Tcl_AppendToObj (result_ptr->obj_ptr, (char *) ptr, -1);
266 }
c98fe0c1 267 else if (stream == gdb_stderr || result_ptr->flags & GDBTK_ERROR_ONLY)
ca4e7e14
JI
268 {
269 if (result_ptr->flags & GDBTK_ERROR_STARTED)
270 Tcl_AppendToObj (result_ptr->obj_ptr, (char *) ptr, -1);
271 else
272 {
273 Tcl_SetStringObj (result_ptr->obj_ptr, (char *) ptr, -1);
274 result_ptr->flags |= GDBTK_ERROR_STARTED;
275 }
276 }
277 else
278 {
279 gdbtk_two_elem_cmd ("gdbtk_tcl_fputs", (char *) ptr);
280 if (result_ptr->flags & GDBTK_MAKES_LIST)
281 gdbtk_two_elem_cmd ("gdbtk_tcl_fputs", " ");
282 }
283 }
284 else
285 {
286 gdbtk_two_elem_cmd ("gdbtk_tcl_fputs", (char *) ptr);
287 }
288
289 in_fputs = 0;
290}
291
292/*
293 * This routes all warnings to the Tcl function "gdbtk_tcl_warning".
294 */
295
296static void
297gdbtk_warning (warning, args)
298 const char *warning;
299 va_list args;
300{
301 char buf[200];
302
303 vsprintf (buf, warning, args);
304 gdbtk_two_elem_cmd ("gdbtk_tcl_warning", buf);
305
306}
307
308/*
309 * This routes all ignorable warnings to the Tcl function
310 * "gdbtk_tcl_ignorable_warning".
311 */
312
313void
314gdbtk_ignorable_warning (warning)
315 const char *warning;
316{
6f5af15b 317 char buf[512];
ca4e7e14
JI
318 sprintf (buf, warning);
319 gdbtk_two_elem_cmd ("gdbtk_tcl_ignorable_warning", buf);
ca4e7e14
JI
320}
321
ca4e7e14
JI
322static void
323pc_changed()
324{
325 Tcl_Eval (gdbtk_interp, "gdbtk_pc_changed");
326}
327
328\f
329/* This function is called instead of gdb's internal command loop. This is the
330 last chance to do anything before entering the main Tk event loop.
331 At the end of the command, we enter the main loop. */
332
333static void
334tk_command_loop ()
335{
65b07ddc 336 extern FILE *instream;
ca4e7e14
JI
337
338 /* We no longer want to use stdin as the command input stream */
339 instream = NULL;
340
341 if (Tcl_Eval (gdbtk_interp, "gdbtk_tcl_preloop") != TCL_OK)
342 {
343 char *msg;
344
345 /* Force errorInfo to be set up propertly. */
346 Tcl_AddErrorInfo (gdbtk_interp, "");
347
348 msg = Tcl_GetVar (gdbtk_interp, "errorInfo", TCL_GLOBAL_ONLY);
349#ifdef _WIN32
350 MessageBox (NULL, msg, NULL, MB_OK | MB_ICONERROR | MB_TASKMODAL);
351#else
352 fputs_unfiltered (msg, gdb_stderr);
353#endif
354 }
355
356#ifdef _WIN32
357 close_bfds ();
358#endif
359
360 Tk_MainLoop ();
361}
362
363/* Come here when there is activity on the X file descriptor. */
364
365void
366x_event (signo)
367 int signo;
368{
369 static int in_x_event = 0;
370 static Tcl_Obj *varname = NULL;
371 if (in_x_event || in_fputs)
372 return;
373
374 in_x_event = 1;
375
c98fe0c1 376#ifdef __CYGWIN32__
ca4e7e14
JI
377 if (signo == -2)
378 gdbtk_stop_timer ();
379#endif
380
381 /* Process pending events */
382 while (Tcl_DoOneEvent (TCL_DONT_WAIT|TCL_ALL_EVENTS) != 0)
383 ;
384
385 if (load_in_progress)
386 {
387 int val;
388 if (varname == NULL)
389 {
390 Tcl_Obj *varnamestrobj = Tcl_NewStringObj("download_cancel_ok",-1);
391 varname = Tcl_ObjGetVar2(gdbtk_interp,varnamestrobj,NULL,TCL_GLOBAL_ONLY);
392 }
393 if ((Tcl_GetIntFromObj(gdbtk_interp,varname,&val) == TCL_OK) && val)
394 {
395 quit_flag = 1;
396#ifdef REQUEST_QUIT
397 REQUEST_QUIT;
398#else
399 if (immediate_quit)
400 quit ();
401#endif
402 }
403 }
404 in_x_event = 0;
405}
406
407/* VARARGS */
408static void
409#ifdef ANSI_PROTOTYPES
410gdbtk_readline_begin (char *format, ...)
411#else
412gdbtk_readline_begin (va_alist)
413 va_dcl
414#endif
415{
416 va_list args;
6f5af15b 417 char buf[200];
ca4e7e14
JI
418
419#ifdef ANSI_PROTOTYPES
420 va_start (args, format);
421#else
422 char *format;
423 va_start (args);
424 format = va_arg (args, char *);
425#endif
426
427 vsprintf (buf, format, args);
428 gdbtk_two_elem_cmd ("gdbtk_tcl_readline_begin", buf);
429
430}
431
432static char *
433gdbtk_readline (prompt)
434 char *prompt;
435{
436 int result;
437
438#ifdef _WIN32
439 close_bfds ();
440#endif
441
442 result = gdbtk_two_elem_cmd ("gdbtk_tcl_readline", prompt);
443
444 if (result == TCL_OK)
445 {
446 return (strdup (gdbtk_interp -> result));
447 }
448 else
449 {
450 gdbtk_fputs (gdbtk_interp -> result, gdb_stdout);
451 gdbtk_fputs ("\n", gdb_stdout);
452 return (NULL);
453 }
454}
455
456static void
457gdbtk_readline_end ()
458{
459 Tcl_Eval (gdbtk_interp, "gdbtk_tcl_readline_end");
460}
461
462static void
463gdbtk_call_command (cmdblk, arg, from_tty)
464 struct cmd_list_element *cmdblk;
465 char *arg;
466 int from_tty;
467{
468 running_now = 0;
469 if (cmdblk->class == class_run || cmdblk->class == class_trace)
470 {
471
2aae6397
JI
472 running_now = 1;
473 if (!No_Update)
474 Tcl_Eval (gdbtk_interp, "gdbtk_tcl_busy");
475 (*cmdblk->function.cfunc)(arg, from_tty);
476 running_now = 0;
477 if (!No_Update)
478 Tcl_Eval (gdbtk_interp, "gdbtk_tcl_idle");
ca4e7e14
JI
479 }
480 else
481 (*cmdblk->function.cfunc)(arg, from_tty);
482}
483
484/* The next three functions use breakpoint_notify to allow the GUI
485 * to handle creating, deleting and modifying breakpoints. These three
486 * functions are put into the appropriate gdb hooks in gdbtk_init.
487 */
488
489static void
490gdbtk_create_breakpoint(b)
491 struct breakpoint *b;
492{
493 breakpoint_notify (b, "create");
494}
495
496static void
497gdbtk_delete_breakpoint(b)
498 struct breakpoint *b;
499{
500 breakpoint_notify (b, "delete");
501}
502
503static void
504gdbtk_modify_breakpoint(b)
505 struct breakpoint *b;
506{
507 breakpoint_notify (b, "modify");
508}
509
510/* This is the generic function for handling changes in
511 * a breakpoint. It routes the information to the Tcl
512 * command "gdbtk_tcl_breakpoint" in the form:
513 * gdbtk_tcl_breakpoint action b_number b_address b_line b_file
514 * On error, the error string is written to gdb_stdout.
515 */
516
517static void
518breakpoint_notify(b, action)
519 struct breakpoint *b;
520 const char *action;
521{
522 char buf[256];
523 int v;
524 struct symtab_and_line sal;
525 char *filename;
526
527 if (b->type != bp_breakpoint)
528 return;
529
530 /* We ensure that ACTION contains no special Tcl characters, so we
531 can do this. */
532 sal = find_pc_line (b->address, 0);
533 filename = symtab_to_filename (sal.symtab);
534 if (filename == NULL)
535 filename = "";
536
63d138d9
JI
537 sprintf (buf, "gdbtk_tcl_breakpoint %s %d 0x%lx %d {%s} {%s} %d %d",
538 action, b->number, (long)b->address, b->line_number, filename,
539 bpdisp[b->disposition], b->enable, b->thread);
ca4e7e14
JI
540
541 v = Tcl_Eval (gdbtk_interp, buf);
542
543 if (v != TCL_OK)
544 {
545 gdbtk_fputs (Tcl_GetStringResult (gdbtk_interp), gdb_stdout);
546 gdbtk_fputs ("\n", gdb_stdout);
547 }
548}
549
550int
551gdbtk_load_hash (section, num)
552 char *section;
553 unsigned long num;
554{
555 char buf[128];
556 sprintf (buf, "download_hash %s %ld", section, num);
557 Tcl_Eval (gdbtk_interp, buf);
558 return atoi (gdbtk_interp->result);
559}
560
561
562/* This hook is called whenever we are ready to load a symbol file so that
563 the UI can notify the user... */
564static void
565gdbtk_pre_add_symbol (name)
566 char *name;
567{
568
569 gdbtk_two_elem_cmd("gdbtk_tcl_pre_add_symbol", name);
570
571}
572
573/* This hook is called whenever we finish loading a symbol file. */
574static void
575gdbtk_post_add_symbol ()
576{
577 Tcl_Eval (gdbtk_interp, "gdbtk_tcl_post_add_symbol");
578}
579
580/* This hook function is called whenever we want to wait for the
581 target. */
582
583static int
584gdbtk_wait (pid, ourstatus)
585 int pid;
586 struct target_waitstatus *ourstatus;
587{
4ce8d0e9
KS
588 /* Don't run the timer on various targets... */
589 if (!STREQ (target_shortname, "ice"))
590 gdbtk_start_timer ();
ca4e7e14
JI
591 pid = target_wait (pid, ourstatus);
592 gdbtk_stop_timer ();
593 return pid;
594}
595
596/*
597 * This handles all queries from gdb.
598 * The first argument is a printf style format statement, the rest are its
599 * arguments. The resultant formatted string is passed to the Tcl function
600 * "gdbtk_tcl_query".
601 * It returns the users response to the query, as well as putting the value
602 * in the result field of the Tcl interpreter.
603 */
604
605static int
606gdbtk_query (query, args)
607 const char *query;
608 va_list args;
609{
610 char buf[200];
611 long val;
612
613 vsprintf (buf, query, args);
614 gdbtk_two_elem_cmd ("gdbtk_tcl_query", buf);
615
616 val = atol (gdbtk_interp->result);
617 return val;
618}
619
620
621static void
622gdbtk_print_frame_info (s, line, stopline, noerror)
623 struct symtab *s;
624 int line;
625 int stopline;
626 int noerror;
627{
628 current_source_symtab = s;
629 current_source_line = line;
630}
631
632static void
633gdbtk_create_tracepoint (tp)
634 struct tracepoint *tp;
635{
636 tracepoint_notify (tp, "create");
637}
638
639static void
640gdbtk_delete_tracepoint (tp)
641 struct tracepoint *tp;
642{
643 tracepoint_notify (tp, "delete");
644}
645
646static void
647gdbtk_modify_tracepoint (tp)
648 struct tracepoint *tp;
649{
650 tracepoint_notify (tp, "modify");
651}
652
653static void
654tracepoint_notify(tp, action)
655 struct tracepoint *tp;
656 const char *action;
657{
658 char buf[256];
659 int v;
660 struct symtab_and_line sal;
661 char *filename;
662
663 /* We ensure that ACTION contains no special Tcl characters, so we
664 can do this. */
665 sal = find_pc_line (tp->address, 0);
666
667 filename = symtab_to_filename (sal.symtab);
668 if (filename == NULL)
669 filename = "N/A";
6f5af15b 670 sprintf (buf, "gdbtk_tcl_tracepoint %s %d 0x%lx %d {%s} %d", action, tp->number,
ca4e7e14
JI
671 (long)tp->address, sal.line, filename, tp->pass_count);
672
673 v = Tcl_Eval (gdbtk_interp, buf);
674
675 if (v != TCL_OK)
676 {
677 gdbtk_fputs (gdbtk_interp->result, gdb_stdout);
678 gdbtk_fputs ("\n", gdb_stdout);
679 }
680}
681
63d138d9
JI
682/*
683 * gdbtk_trace_find
684 *
685 * This is run by the trace_find_command. arg is the argument that was passed
686 * to that command, from_tty is 1 if the command was run from a tty, 0 if it
687 * was run from a script. It runs gdbtk_tcl_tfind_hook passing on these two
688 * arguments.
689 *
690 */
691
692static void
693gdbtk_trace_find (arg, from_tty)
694 char *arg;
695 int from_tty;
696{
697 Tcl_Obj *cmdObj;
698
2aae6397
JI
699 if (from_tty) {
700 Tcl_GlobalEval (gdbtk_interp, "debug {*** In gdbtk_trace_find, from_tty is true}");
701 cmdObj = Tcl_NewListObj (0, NULL);
702 Tcl_ListObjAppendElement (gdbtk_interp, cmdObj,
703 Tcl_NewStringObj ("gdbtk_tcl_trace_find_hook", -1));
704 Tcl_ListObjAppendElement (gdbtk_interp, cmdObj, Tcl_NewStringObj (arg, -1));
705 Tcl_ListObjAppendElement (gdbtk_interp, cmdObj, Tcl_NewIntObj(from_tty));
706 Tcl_GlobalEvalObj (gdbtk_interp, cmdObj);
707 } else {
708 Tcl_GlobalEval (gdbtk_interp, "debug {*** In gdbtk_trace_find, from_tty is false}");
709 }
710}
711
712/*
713 * gdbtk_trace_start_stop
714 *
715 * This is run by the trace_start_command and trace_stop_command.
716 * The START variable determines which, 1 meaning trace_start was run,
717 * 0 meaning trace_stop was run.
718 *
719 */
720
721static void
722gdbtk_trace_start_stop (start, from_tty)
723 int start;
724 int from_tty;
725{
726 Tcl_Obj *cmdObj;
63d138d9 727
2aae6397
JI
728 if (from_tty) {
729 Tcl_GlobalEval (gdbtk_interp, "debug {*** In gdbtk_trace_start, from_tty is true}");
730 cmdObj = Tcl_NewListObj (0, NULL);
731 if (start)
732 Tcl_ListObjAppendElement (gdbtk_interp, cmdObj,
733 Tcl_NewStringObj ("gdbtk_tcl_tstart", -1));
734 else
735 Tcl_ListObjAppendElement (gdbtk_interp, cmdObj,
736 Tcl_NewStringObj ("gdbtk_tcl_tstop", -1));
737 Tcl_GlobalEvalObj (gdbtk_interp, cmdObj);
738 } else {
739 Tcl_GlobalEval (gdbtk_interp, "debug {*** In gdbtk_trace_startd, from_tty is false}");
740 }
741
63d138d9
JI
742}
743
3d64f1e0
KS
744static void
745gdbtk_selected_frame_changed (level)
746 int level;
747{
748 Tcl_UpdateLinkedVar (gdbtk_interp, "gdb_selected_frame_level");
749}
4ff5d55a
MH
750
751/* Called when the current thread changes. */
752/* gdb_context is linked to the tcl variable "gdb_context_id" */
753static void
754gdbtk_context_change (num)
755 int num;
756{
757 gdb_context = num;
758}
2c04e0d9 759
4fb67eb5
KS
760/* Called from file_command */
761static void
762gdbtk_file_changed (filename)
763 char *filename;
764{
765 gdbtk_two_elem_cmd ("gdbtk_tcl_file_changed", filename);
766}
767
2c04e0d9
KS
768/* Called from exec_file_command */
769static void
4fb67eb5 770gdbtk_exec_file_display (filename)
2c04e0d9
KS
771 char *filename;
772{
4fb67eb5 773 gdbtk_two_elem_cmd ("gdbtk_tcl_exec_file_display", filename);
2c04e0d9 774}
c98fe0c1
JI
775
776/* Called from error_begin, this hook is used to warn the gui
777 about multi-line error messages */
778static void
779gdbtk_error_begin ()
780{
781 if (result_ptr != NULL)
782 result_ptr->flags |= GDBTK_ERROR_ONLY;
783}
784\f
785/* Local variables: */
786/* change-log-default-name: "ChangeLog-gdbtk" */
787/* End: */