diff options
author | Stu Grossman <grossman@cygnus> | 1994-10-21 00:59:20 +0000 |
---|---|---|
committer | Stu Grossman <grossman@cygnus> | 1994-10-21 00:59:20 +0000 |
commit | 479f0f18d4a77e04b32cc7062ee31310b876e16b (patch) | |
tree | 3d0b2d2df5646de9741407942764a2e4981beed6 /gdb/gdbtk.c | |
parent | 1b79c34daa80f7cbbc3c16d603d44f482f9296bf (diff) | |
download | gdb-479f0f18d4a77e04b32cc7062ee31310b876e16b.zip gdb-479f0f18d4a77e04b32cc7062ee31310b876e16b.tar.gz gdb-479f0f18d4a77e04b32cc7062ee31310b876e16b.tar.bz2 |
* defs.h, infrun.c (wait_for_inferior), top.c: Call
target_wait_hook to allow GUI to handle blocking for inferior. Call
call_command_hook in execute_command to provide means for wrapping
commands with GUI state change updates.
* gdbtk.c (gdb_cmd): Force GUI into idle mode when errors occur.
* (gdb_stop): New tcl command to stop the target process.
* (x_event, gdbtk_wait): Allow GUI to interrupt gdb out of target
waits.
* (gdbtk_call_command): Wrapper around command processing to
alert GUI of target state changes.
* (gdbtk_init): Get the fd of X server for doing async
notification of X events (via x_event). Setup new hooks.
* gdbtk.tcl: Add scrollbars to assembly and command windows.
* Change window foreground & background colors.
* Create margin tag for breakpoints in source and assembly windows.
* Add new routines to be invoked when target state changes to/from
idle.
* Add start of expression window.
* Change bindings of mouse button 1 in assembly and source window
to just set or clear breakpoints when in the margin tag.
* Change shape of register window to be more vertical to better
reflect it's contents.
* Add stop button.
* Cleanup some code around command window bindings.
* infrun.c (wait_for_inferior): Make sure
through_sigtramp_breakpoint is non-null before deleting.
Diffstat (limited to 'gdb/gdbtk.c')
-rw-r--r-- | gdb/gdbtk.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/gdb/gdbtk.c b/gdb/gdbtk.c index 9843b43..e96ea19 100644 --- a/gdb/gdbtk.c +++ b/gdb/gdbtk.c @@ -54,6 +54,8 @@ static Tcl_Interp *interp = NULL; /* Handle for TK main window */ static Tk_Window mainWindow = NULL; +static int x_fd; /* X network socket */ + static void null_routine(arg) int arg; @@ -336,6 +338,12 @@ gdb_cmd (clientData, interp, argc, argv) val = catch_errors (gdb_cmd_stub, argv[1], "", RETURN_MASK_ERROR); + /* In case of an error, we may need to force the GUI into idle mode because + gdbtk_call_command may have bombed out while in the command routine. */ + + if (val == 0) + Tcl_VarEval (interp, "gdbtk_tcl_idle", NULL); + bpstat_do_actions (&stop_bpstat); do_cleanups (old_chain); @@ -367,6 +375,22 @@ gdb_listfiles (clientData, interp, argc, argv) return TCL_OK; } + +static int +gdb_stop (clientData, interp, argc, argv) + ClientData clientData; + Tcl_Interp *interp; + int argc; + char *argv[]; +{ + extern pid_t inferior_process_group; + + /* XXX - This is WRONG for remote targets. Probably need a target vector + entry to do this right. */ + + kill (-inferior_process_group, SIGINT); +} + static void tk_command (cmd, from_tty) @@ -401,11 +425,59 @@ gdbtk_interactive () /* Tk_DoOneEvent (TK_DONT_WAIT|TK_IDLE_EVENTS); */ } +/* Come here when there is activity on the X file descriptor. */ + +static void +x_event (signo) + int signo; +{ + /* Process pending events */ + + while (Tk_DoOneEvent (TK_DONT_WAIT|TK_ALL_EVENTS) != 0); +} + +static int +gdbtk_wait (pid, ourstatus) + int pid; + struct target_waitstatus *ourstatus; +{ + signal (SIGIO, x_event); + + pid = target_wait (pid, ourstatus); + + signal (SIGIO, SIG_IGN); + + return pid; +} + +/* This is called from execute_command, and provides a wrapper around + various command routines in a place where both protocol messages and + user input both flow through. Mostly this is used for indicating whether + the target process is running or not. +*/ + +static void +gdbtk_call_command (cmdblk, arg, from_tty) + struct cmd_list_element *cmdblk; + char *arg; + int from_tty; +{ + if (cmdblk->class == class_run) + { + Tcl_VarEval (interp, "gdbtk_tcl_busy", NULL); + (*cmdblk->function.cfunc)(arg, from_tty); + Tcl_VarEval (interp, "gdbtk_tcl_idle", NULL); + } + else + (*cmdblk->function.cfunc)(arg, from_tty); +} + static void gdbtk_init () { struct cleanup *old_chain; char *gdbtk_filename; + int i; old_chain = make_cleanup (cleanup_init, 0); @@ -430,6 +502,7 @@ gdbtk_init () Tcl_CreateCommand (interp, "gdb_cmd", gdb_cmd, NULL, NULL); Tcl_CreateCommand (interp, "gdb_loc", gdb_loc, NULL, NULL); Tcl_CreateCommand (interp, "gdb_listfiles", gdb_listfiles, NULL, NULL); + Tcl_CreateCommand (interp, "gdb_stop", gdb_stop, NULL, NULL); gdbtk_filename = getenv ("GDBTK_FILENAME"); if (!gdbtk_filename) @@ -441,6 +514,19 @@ gdbtk_init () if (Tcl_EvalFile (interp, gdbtk_filename) != TCL_OK) error ("Failure reading %s: %s", gdbtk_filename, interp->result); + /* XXX - Get the file descriptor for the network socket. This is not Kosher + as it involves looking at data private to Xlib. */ + + x_fd = Tk_Display (mainWindow) -> fd; + + /* Setup for I/O interrupts */ + + signal (SIGIO, SIG_IGN); + + i = fcntl (x_fd, F_GETFL, 0); + fcntl (x_fd, F_SETFL, i|FASYNC); + fcntl (x_fd, F_SETOWN, getpid()); + command_loop_hook = Tk_MainLoop; fputs_unfiltered_hook = gdbtk_fputs; print_frame_info_listing_hook = null_routine; @@ -451,6 +537,8 @@ gdbtk_init () enable_breakpoint_hook = gdbtk_enable_breakpoint; disable_breakpoint_hook = gdbtk_disable_breakpoint; interactive_hook = gdbtk_interactive; + target_wait_hook = gdbtk_wait; + call_command_hook = gdbtk_call_command; discard_cleanups (old_chain); |