1130803Smarcel/* TUI Interpreter definitions for GDB, the GNU debugger.
2130803Smarcel
3130803Smarcel   Copyright 2003 Free Software Foundation, Inc.
4130803Smarcel
5130803Smarcel   This file is part of GDB.
6130803Smarcel
7130803Smarcel   This program is free software; you can redistribute it and/or modify
8130803Smarcel   it under the terms of the GNU General Public License as published by
9130803Smarcel   the Free Software Foundation; either version 2 of the License, or
10130803Smarcel   (at your option) any later version.
11130803Smarcel
12130803Smarcel   This program is distributed in the hope that it will be useful,
13130803Smarcel   but WITHOUT ANY WARRANTY; without even the implied warranty of
14130803Smarcel   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15130803Smarcel   GNU General Public License for more details.
16130803Smarcel
17130803Smarcel   You should have received a copy of the GNU General Public License
18130803Smarcel   along with this program; if not, write to the Free Software
19130803Smarcel   Foundation, Inc., 59 Temple Place - Suite 330,
20130803Smarcel   Boston, MA 02111-1307, USA.  */
21130803Smarcel
22130803Smarcel#include "defs.h"
23130803Smarcel#include "interps.h"
24130803Smarcel#include "top.h"
25130803Smarcel#include "event-top.h"
26130803Smarcel#include "event-loop.h"
27130803Smarcel#include "ui-out.h"
28130803Smarcel#include "cli-out.h"
29130803Smarcel#include "tui/tui-data.h"
30130803Smarcel#include "readline/readline.h"
31130803Smarcel#include "tui/tui-win.h"
32130803Smarcel#include "tui/tui.h"
33130803Smarcel#include "tui/tui-io.h"
34130803Smarcel
35130803Smarcel/* Set to 1 when the TUI mode must be activated when we first start gdb.  */
36130803Smarcelstatic int tui_start_enabled = 0;
37130803Smarcel
38130803Smarcel/* Cleanup the tui before exiting.  */
39130803Smarcel
40130803Smarcelstatic void
41130803Smarceltui_exit (void)
42130803Smarcel{
43130803Smarcel  /* Disable the tui.  Curses mode is left leaving the screen
44130803Smarcel     in a clean state (see endwin()).  */
45130803Smarcel  tui_disable ();
46130803Smarcel}
47130803Smarcel
48130803Smarcel/* These implement the TUI interpreter.  */
49130803Smarcel
50130803Smarcelstatic void *
51130803Smarceltui_init (void)
52130803Smarcel{
53130803Smarcel  /* Install exit handler to leave the screen in a good shape.  */
54130803Smarcel  atexit (tui_exit);
55130803Smarcel
56130803Smarcel  tui_initialize_static_data ();
57130803Smarcel
58130803Smarcel  tui_initialize_io ();
59130803Smarcel  tui_initialize_readline ();
60130803Smarcel
61130803Smarcel  return NULL;
62130803Smarcel}
63130803Smarcel
64130803Smarcelstatic int
65130803Smarceltui_resume (void *data)
66130803Smarcel{
67130803Smarcel  struct ui_file *stream;
68130803Smarcel
69130803Smarcel  /* gdb_setup_readline will change gdb_stdout.  If the TUI was previously
70130803Smarcel     writing to gdb_stdout, then set it to the new gdb_stdout afterwards.  */
71130803Smarcel
72130803Smarcel  stream = cli_out_set_stream (tui_old_uiout, gdb_stdout);
73130803Smarcel  if (stream != gdb_stdout)
74130803Smarcel    {
75130803Smarcel      cli_out_set_stream (tui_old_uiout, stream);
76130803Smarcel      stream = NULL;
77130803Smarcel    }
78130803Smarcel
79130803Smarcel  gdb_setup_readline ();
80130803Smarcel
81130803Smarcel  if (stream != NULL)
82130803Smarcel    cli_out_set_stream (tui_old_uiout, gdb_stdout);
83130803Smarcel
84130803Smarcel  if (tui_start_enabled)
85130803Smarcel    tui_enable ();
86130803Smarcel  return 1;
87130803Smarcel}
88130803Smarcel
89130803Smarcelstatic int
90130803Smarceltui_suspend (void *data)
91130803Smarcel{
92130803Smarcel  tui_start_enabled = tui_active;
93130803Smarcel  tui_disable ();
94130803Smarcel  return 1;
95130803Smarcel}
96130803Smarcel
97130803Smarcel/* Display the prompt if we are silent.  */
98130803Smarcel
99130803Smarcelstatic int
100130803Smarceltui_display_prompt_p (void *data)
101130803Smarcel{
102130803Smarcel  if (interp_quiet_p (NULL))
103130803Smarcel    return 0;
104130803Smarcel  else
105130803Smarcel    return 1;
106130803Smarcel}
107130803Smarcel
108130803Smarcelstatic int
109130803Smarceltui_exec (void *data, const char *command_str)
110130803Smarcel{
111130803Smarcel  internal_error (__FILE__, __LINE__, "tui_exec called");
112130803Smarcel}
113130803Smarcel
114130803Smarcel
115130803Smarcel/* Initialize all the necessary variables, start the event loop,
116130803Smarcel   register readline, and stdin, start the loop.  */
117130803Smarcel
118130803Smarcelstatic void
119130803Smarceltui_command_loop (void *data)
120130803Smarcel{
121130803Smarcel  int length;
122130803Smarcel  char *a_prompt;
123130803Smarcel  char *gdb_prompt = get_prompt ();
124130803Smarcel
125130803Smarcel  /* If we are using readline, set things up and display the first
126130803Smarcel     prompt, otherwise just print the prompt.  */
127130803Smarcel  if (async_command_editing_p)
128130803Smarcel    {
129130803Smarcel      /* Tell readline what the prompt to display is and what function
130130803Smarcel         it will need to call after a whole line is read. This also
131130803Smarcel         displays the first prompt.  */
132130803Smarcel      length = strlen (PREFIX (0)) + strlen (gdb_prompt) + strlen (SUFFIX (0)) + 1;
133130803Smarcel      a_prompt = (char *) xmalloc (length);
134130803Smarcel      strcpy (a_prompt, PREFIX (0));
135130803Smarcel      strcat (a_prompt, gdb_prompt);
136130803Smarcel      strcat (a_prompt, SUFFIX (0));
137130803Smarcel      rl_callback_handler_install (a_prompt, input_handler);
138130803Smarcel    }
139130803Smarcel  else
140130803Smarcel    display_gdb_prompt (0);
141130803Smarcel
142130803Smarcel  /* Loop until there is nothing to do. This is the entry point to the
143130803Smarcel     event loop engine. gdb_do_one_event, called via catch_errors()
144130803Smarcel     will process one event for each invocation.  It blocks waits for
145130803Smarcel     an event and then processes it.  >0 when an event is processed, 0
146130803Smarcel     when catch_errors() caught an error and <0 when there are no
147130803Smarcel     longer any event sources registered.  */
148130803Smarcel  while (1)
149130803Smarcel    {
150130803Smarcel      int result = catch_errors (gdb_do_one_event, 0, "", RETURN_MASK_ALL);
151130803Smarcel      if (result < 0)
152130803Smarcel	break;
153130803Smarcel
154130803Smarcel      /* Update gdb output according to TUI mode.  Since catch_errors
155130803Smarcel         preserves the uiout from changing, this must be done at top
156130803Smarcel         level of event loop.  */
157130803Smarcel      if (tui_active)
158130803Smarcel        uiout = tui_out;
159130803Smarcel      else
160130803Smarcel        uiout = tui_old_uiout;
161130803Smarcel
162130803Smarcel      if (result == 0)
163130803Smarcel	{
164130803Smarcel	  /* FIXME: this should really be a call to a hook that is
165130803Smarcel	     interface specific, because interfaces can display the
166130803Smarcel	     prompt in their own way.  */
167130803Smarcel	  display_gdb_prompt (0);
168130803Smarcel	  /* This call looks bizarre, but it is required.  If the user
169130803Smarcel	     entered a command that caused an error,
170130803Smarcel	     after_char_processing_hook won't be called from
171130803Smarcel	     rl_callback_read_char_wrapper.  Using a cleanup there
172130803Smarcel	     won't work, since we want this function to be called
173130803Smarcel	     after a new prompt is printed.  */
174130803Smarcel	  if (after_char_processing_hook)
175130803Smarcel	    (*after_char_processing_hook) ();
176130803Smarcel	  /* Maybe better to set a flag to be checked somewhere as to
177130803Smarcel	     whether display the prompt or not.  */
178130803Smarcel	}
179130803Smarcel    }
180130803Smarcel
181130803Smarcel  /* We are done with the event loop. There are no more event sources
182130803Smarcel     to listen to.  So we exit GDB.  */
183130803Smarcel  return;
184130803Smarcel}
185130803Smarcel
186130803Smarcelvoid
187130803Smarcel_initialize_tui_interp (void)
188130803Smarcel{
189130803Smarcel  static const struct interp_procs procs = {
190130803Smarcel    tui_init,
191130803Smarcel    tui_resume,
192130803Smarcel    tui_suspend,
193130803Smarcel    tui_exec,
194130803Smarcel    tui_display_prompt_p,
195130803Smarcel    tui_command_loop,
196130803Smarcel  };
197130803Smarcel  struct interp *tui_interp;
198130803Smarcel
199130803Smarcel  /* Create a default uiout builder for the TUI. */
200130803Smarcel  tui_out = tui_out_new (gdb_stdout);
201130803Smarcel  interp_add (interp_new ("tui", NULL, tui_out, &procs));
202130803Smarcel  if (interpreter_p && strcmp (interpreter_p, "tui") == 0)
203130803Smarcel    tui_start_enabled = 1;
204130803Smarcel
205130803Smarcel  if (interpreter_p && strcmp (interpreter_p, INTERP_CONSOLE) == 0)
206130803Smarcel    {
207130803Smarcel      xfree (interpreter_p);
208130803Smarcel      interpreter_p = xstrdup ("tui");
209130803Smarcel    }
210130803Smarcel}
211