GDB (API)
/home/stan/gdb/src/gdb/tui/tui-io.c
Go to the documentation of this file.
00001 /* TUI support I/O functions.
00002 
00003    Copyright (C) 1998-2013 Free Software Foundation, Inc.
00004 
00005    Contributed by Hewlett-Packard Company.
00006 
00007    This file is part of GDB.
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 3 of the License, or
00012    (at your option) any later version.
00013 
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00021 
00022 #include "defs.h"
00023 #include "target.h"
00024 #include "event-loop.h"
00025 #include "event-top.h"
00026 #include "command.h"
00027 #include "top.h"
00028 #include "tui/tui.h"
00029 #include "tui/tui-data.h"
00030 #include "tui/tui-io.h"
00031 #include "tui/tui-command.h"
00032 #include "tui/tui-win.h"
00033 #include "tui/tui-wingeneral.h"
00034 #include "tui/tui-file.h"
00035 #include "ui-out.h"
00036 #include "cli-out.h"
00037 #include <fcntl.h>
00038 #include <signal.h>
00039 #include <stdio.h>
00040 #include "filestuff.h"
00041 
00042 #include "gdb_curses.h"
00043 
00044 /* This redefines CTRL if it is not already defined, so it must come
00045    after terminal state releated include files like <term.h> and
00046    "gdb_curses.h".  */
00047 #include "readline/readline.h"
00048 
00049 int
00050 key_is_start_sequence (int ch)
00051 {
00052   return (ch == 27);
00053 }
00054 
00055 int
00056 key_is_end_sequence (int ch)
00057 {
00058   return (ch == 126);
00059 }
00060 
00061 int
00062 key_is_backspace (int ch)
00063 {
00064   return (ch == 8);
00065 }
00066 
00067 int
00068 key_is_command_char (int ch)
00069 {
00070   return ((ch == KEY_NPAGE) || (ch == KEY_PPAGE)
00071           || (ch == KEY_LEFT) || (ch == KEY_RIGHT)
00072           || (ch == KEY_UP) || (ch == KEY_DOWN)
00073           || (ch == KEY_SF) || (ch == KEY_SR)
00074           || (ch == (int)'\f') 
00075           || key_is_start_sequence (ch));
00076 }
00077 
00078 /* Use definition from readline 4.3.  */
00079 #undef CTRL_CHAR
00080 #define CTRL_CHAR(c) \
00081      ((c) < control_character_threshold && (((c) & 0x80) == 0))
00082 
00083 /* This file controls the IO interactions between gdb and curses.
00084    When the TUI is enabled, gdb has two modes a curses and a standard
00085    mode.
00086 
00087    In curses mode, the gdb outputs are made in a curses command
00088    window.  For this, the gdb_stdout and gdb_stderr are redirected to
00089    the specific ui_file implemented by TUI.  The output is handled by
00090    tui_puts().  The input is also controlled by curses with
00091    tui_getc().  The readline library uses this function to get its
00092    input.  Several readline hooks are installed to redirect readline
00093    output to the TUI (see also the note below).
00094 
00095    In normal mode, the gdb outputs are restored to their origin, that
00096    is as if TUI is not used.  Readline also uses its original getc()
00097    function with stdin.
00098 
00099    Note SCz/2001-07-21: the current readline is not clean in its
00100    management of the output.  Even if we install a redisplay handler,
00101    it sometimes writes on a stdout file.  It is important to redirect
00102    every output produced by readline, otherwise the curses window will
00103    be garbled.  This is implemented with a pipe that TUI reads and
00104    readline writes to.  A gdb input handler is created so that reading
00105    the pipe is handled automatically.  This will probably not work on
00106    non-Unix platforms.  The best fix is to make readline clean enougth
00107    so that is never write on stdout.
00108 
00109    Note SCz/2002-09-01: we now use more readline hooks and it seems
00110    that with them we don't need the pipe anymore (verified by creating
00111    the pipe and closing its end so that write causes a SIGPIPE).  The
00112    old pipe code is still there and can be conditionally removed by
00113    #undef TUI_USE_PIPE_FOR_READLINE.  */
00114 
00115 /* For gdb 5.3, prefer to continue the pipe hack as a backup wheel.  */
00116 #ifdef HAVE_PIPE
00117 #define TUI_USE_PIPE_FOR_READLINE
00118 #endif
00119 /* #undef TUI_USE_PIPE_FOR_READLINE */
00120 
00121 /* TUI output files.  */
00122 static struct ui_file *tui_stdout;
00123 static struct ui_file *tui_stderr;
00124 struct ui_out *tui_out;
00125 
00126 /* GDB output files in non-curses mode.  */
00127 static struct ui_file *tui_old_stdout;
00128 static struct ui_file *tui_old_stderr;
00129 struct ui_out *tui_old_uiout;
00130 
00131 /* Readline previous hooks.  */
00132 static Function *tui_old_rl_getc_function;
00133 static VFunction *tui_old_rl_redisplay_function;
00134 static VFunction *tui_old_rl_prep_terminal;
00135 static VFunction *tui_old_rl_deprep_terminal;
00136 static int tui_old_rl_echoing_p;
00137 
00138 /* Readline output stream.
00139    Should be removed when readline is clean.  */
00140 static FILE *tui_rl_outstream;
00141 static FILE *tui_old_rl_outstream;
00142 #ifdef TUI_USE_PIPE_FOR_READLINE
00143 static int tui_readline_pipe[2];
00144 #endif
00145 
00146 /* The last gdb prompt that was registered in readline.
00147    This may be the main gdb prompt or a secondary prompt.  */
00148 static char *tui_rl_saved_prompt;
00149 
00150 static unsigned int tui_handle_resize_during_io (unsigned int);
00151 
00152 static void
00153 tui_putc (char c)
00154 {
00155   char buf[2];
00156 
00157   buf[0] = c;
00158   buf[1] = 0;
00159   tui_puts (buf);
00160 }
00161 
00162 /* Print the string in the curses command window.  */
00163 void
00164 tui_puts (const char *string)
00165 {
00166   static int tui_skip_line = -1;
00167   char c;
00168   WINDOW *w;
00169 
00170   w = TUI_CMD_WIN->generic.handle;
00171   while ((c = *string++) != 0)
00172     {
00173       /* Catch annotation and discard them.  We need two \032 and
00174          discard until a \n is seen.  */
00175       if (c == '\032')
00176         {
00177           tui_skip_line++;
00178         }
00179       else if (tui_skip_line != 1)
00180         {
00181           tui_skip_line = -1;
00182           waddch (w, c);
00183         }
00184       else if (c == '\n')
00185         tui_skip_line = -1;
00186     }
00187   getyx (w, TUI_CMD_WIN->detail.command_info.cur_line,
00188          TUI_CMD_WIN->detail.command_info.curch);
00189   TUI_CMD_WIN->detail.command_info.start_line
00190     = TUI_CMD_WIN->detail.command_info.cur_line;
00191 
00192   /* We could defer the following.  */
00193   wrefresh (w);
00194   fflush (stdout);
00195 }
00196 
00197 /* Readline callback.
00198    Redisplay the command line with its prompt after readline has
00199    changed the edited text.  */
00200 void
00201 tui_redisplay_readline (void)
00202 {
00203   int prev_col;
00204   int height;
00205   int col, line;
00206   int c_pos;
00207   int c_line;
00208   int in;
00209   WINDOW *w;
00210   char *prompt;
00211   int start_line;
00212 
00213   /* Detect when we temporarily left SingleKey and now the readline
00214      edit buffer is empty, automatically restore the SingleKey
00215      mode.  The restore must only be done if the command has finished.
00216      The command could call prompt_for_continue and we must not
00217      restore SingleKey so that the prompt and normal keymap are used.  */
00218   if (tui_current_key_mode == TUI_ONE_COMMAND_MODE && rl_end == 0
00219       && immediate_quit == 0)
00220     tui_set_key_mode (TUI_SINGLE_KEY_MODE);
00221 
00222   if (tui_current_key_mode == TUI_SINGLE_KEY_MODE)
00223     prompt = "";
00224   else
00225     prompt = tui_rl_saved_prompt;
00226   
00227   c_pos = -1;
00228   c_line = -1;
00229   w = TUI_CMD_WIN->generic.handle;
00230   start_line = TUI_CMD_WIN->detail.command_info.start_line;
00231   wmove (w, start_line, 0);
00232   prev_col = 0;
00233   height = 1;
00234   for (in = 0; prompt && prompt[in]; in++)
00235     {
00236       waddch (w, prompt[in]);
00237       getyx (w, line, col);
00238       if (col < prev_col)
00239         height++;
00240       prev_col = col;
00241     }
00242   for (in = 0; in < rl_end; in++)
00243     {
00244       unsigned char c;
00245       
00246       c = (unsigned char) rl_line_buffer[in];
00247       if (in == rl_point)
00248         {
00249           getyx (w, c_line, c_pos);
00250         }
00251 
00252       if (CTRL_CHAR (c) || c == RUBOUT)
00253         {
00254           waddch (w, '^');
00255           waddch (w, CTRL_CHAR (c) ? UNCTRL (c) : '?');
00256         }
00257       else
00258         {
00259           waddch (w, c);
00260         }
00261       if (c == '\n')
00262         {
00263           getyx (w, TUI_CMD_WIN->detail.command_info.start_line,
00264                  TUI_CMD_WIN->detail.command_info.curch);
00265         }
00266       getyx (w, line, col);
00267       if (col < prev_col)
00268         height++;
00269       prev_col = col;
00270     }
00271   wclrtobot (w);
00272   getyx (w, TUI_CMD_WIN->detail.command_info.start_line,
00273          TUI_CMD_WIN->detail.command_info.curch);
00274   if (c_line >= 0)
00275     {
00276       wmove (w, c_line, c_pos);
00277       TUI_CMD_WIN->detail.command_info.cur_line = c_line;
00278       TUI_CMD_WIN->detail.command_info.curch = c_pos;
00279     }
00280   TUI_CMD_WIN->detail.command_info.start_line -= height - 1;
00281 
00282   wrefresh (w);
00283   fflush(stdout);
00284 }
00285 
00286 /* Readline callback to prepare the terminal.  It is called once each
00287    time we enter readline.  Terminal is already setup in curses
00288    mode.  */
00289 static void
00290 tui_prep_terminal (int notused1)
00291 {
00292   /* Save the prompt registered in readline to correctly display it.
00293      (we can't use gdb_prompt() due to secondary prompts and can't use
00294      rl_prompt because it points to an alloca buffer).  */
00295   xfree (tui_rl_saved_prompt);
00296   tui_rl_saved_prompt = xstrdup (rl_prompt);
00297 }
00298 
00299 /* Readline callback to restore the terminal.  It is called once each
00300    time we leave readline.  There is nothing to do in curses mode.  */
00301 static void
00302 tui_deprep_terminal (void)
00303 {
00304 }
00305 
00306 #ifdef TUI_USE_PIPE_FOR_READLINE
00307 /* Read readline output pipe and feed the command window with it.
00308    Should be removed when readline is clean.  */
00309 static void
00310 tui_readline_output (int error, gdb_client_data data)
00311 {
00312   int size;
00313   char buf[256];
00314 
00315   size = read (tui_readline_pipe[0], buf, sizeof (buf) - 1);
00316   if (size > 0 && tui_active)
00317     {
00318       buf[size] = 0;
00319       tui_puts (buf);
00320     }
00321 }
00322 #endif
00323 
00324 /* Return the portion of PATHNAME that should be output when listing
00325    possible completions.  If we are hacking filename completion, we
00326    are only interested in the basename, the portion following the
00327    final slash.  Otherwise, we return what we were passed.
00328 
00329    Comes from readline/complete.c.  */
00330 static const char *
00331 printable_part (const char *pathname)
00332 {
00333   return rl_filename_completion_desired ? lbasename (pathname) : pathname;
00334 }
00335 
00336 /* Output TO_PRINT to rl_outstream.  If VISIBLE_STATS is defined and
00337    we are using it, check for and output a single character for
00338    `special' filenames.  Return the number of characters we
00339    output.  */
00340 
00341 #define PUTX(c) \
00342     do { \
00343       if (CTRL_CHAR (c)) \
00344         { \
00345           tui_puts ("^"); \
00346           tui_putc (UNCTRL (c)); \
00347           printed_len += 2; \
00348         } \
00349       else if (c == RUBOUT) \
00350         { \
00351           tui_puts ("^?"); \
00352           printed_len += 2; \
00353         } \
00354       else \
00355         { \
00356           tui_putc (c); \
00357           printed_len++; \
00358         } \
00359     } while (0)
00360 
00361 static int
00362 print_filename (const char *to_print, const char *full_pathname)
00363 {
00364   int printed_len = 0;
00365   const char *s;
00366 
00367   for (s = to_print; *s; s++)
00368     {
00369       PUTX (*s);
00370     }
00371   return printed_len;
00372 }
00373 
00374 /* The user must press "y" or "n".  Non-zero return means "y" pressed.
00375    Comes from readline/complete.c.  */
00376 static int
00377 get_y_or_n (void)
00378 {
00379   extern int _rl_abort_internal ();
00380   int c;
00381 
00382   for (;;)
00383     {
00384       c = rl_read_key ();
00385       if (c == 'y' || c == 'Y' || c == ' ')
00386         return (1);
00387       if (c == 'n' || c == 'N' || c == RUBOUT)
00388         return (0);
00389       if (c == ABORT_CHAR)
00390         _rl_abort_internal ();
00391       beep ();
00392     }
00393 }
00394 
00395 /* A convenience function for displaying a list of strings in
00396    columnar format on readline's output stream.  MATCHES is the list
00397    of strings, in argv format, LEN is the number of strings in MATCHES,
00398    and MAX is the length of the longest string in MATCHES.
00399 
00400    Comes from readline/complete.c and modified to write in
00401    the TUI command window using tui_putc/tui_puts.  */
00402 static void
00403 tui_rl_display_match_list (char **matches, int len, int max)
00404 {
00405   typedef int QSFUNC (const void *, const void *);
00406   extern int _rl_qsort_string_compare (const void *, 
00407                                        const void *);
00408   extern int _rl_print_completions_horizontally;
00409   
00410   int count, limit, printed_len;
00411   int i, j, k, l;
00412   const char *temp;
00413 
00414   /* Screen dimension correspond to the TUI command window.  */
00415   int screenwidth = TUI_CMD_WIN->generic.width;
00416 
00417   /* If there are many items, then ask the user if she really wants to
00418      see them all.  */
00419   if (len >= rl_completion_query_items)
00420     {
00421       char msg[256];
00422 
00423       xsnprintf (msg, sizeof (msg),
00424                  "\nDisplay all %d possibilities? (y or n)", len);
00425       tui_puts (msg);
00426       if (get_y_or_n () == 0)
00427         {
00428           tui_puts ("\n");
00429           return;
00430         }
00431     }
00432 
00433   /* How many items of MAX length can we fit in the screen window?  */
00434   max += 2;
00435   limit = screenwidth / max;
00436   if (limit != 1 && (limit * max == screenwidth))
00437     limit--;
00438 
00439   /* Avoid a possible floating exception.  If max > screenwidth, limit
00440      will be 0 and a divide-by-zero fault will result.  */
00441   if (limit == 0)
00442     limit = 1;
00443 
00444   /* How many iterations of the printing loop?  */
00445   count = (len + (limit - 1)) / limit;
00446 
00447   /* Watch out for special case.  If LEN is less than LIMIT, then
00448      just do the inner printing loop.
00449            0 < len <= limit  implies  count = 1.  */
00450 
00451   /* Sort the items if they are not already sorted.  */
00452   if (rl_ignore_completion_duplicates == 0)
00453     qsort (matches + 1, len, sizeof (char *),
00454            (QSFUNC *)_rl_qsort_string_compare);
00455 
00456   tui_putc ('\n');
00457 
00458   if (_rl_print_completions_horizontally == 0)
00459     {
00460       /* Print the sorted items, up-and-down alphabetically, like ls.  */
00461       for (i = 1; i <= count; i++)
00462         {
00463           for (j = 0, l = i; j < limit; j++)
00464             {
00465               if (l > len || matches[l] == 0)
00466                 break;
00467               else
00468                 {
00469                   temp = printable_part (matches[l]);
00470                   printed_len = print_filename (temp, matches[l]);
00471 
00472                   if (j + 1 < limit)
00473                     for (k = 0; k < max - printed_len; k++)
00474                       tui_putc (' ');
00475                 }
00476               l += count;
00477             }
00478           tui_putc ('\n');
00479         }
00480     }
00481   else
00482     {
00483       /* Print the sorted items, across alphabetically, like ls -x.  */
00484       for (i = 1; matches[i]; i++)
00485         {
00486           temp = printable_part (matches[i]);
00487           printed_len = print_filename (temp, matches[i]);
00488           /* Have we reached the end of this line?  */
00489           if (matches[i+1])
00490             {
00491               if (i && (limit > 1) && (i % limit) == 0)
00492                 tui_putc ('\n');
00493               else
00494                 for (k = 0; k < max - printed_len; k++)
00495                   tui_putc (' ');
00496             }
00497         }
00498       tui_putc ('\n');
00499     }
00500 }
00501 
00502 /* Setup the IO for curses or non-curses mode.
00503    - In non-curses mode, readline and gdb use the standard input and
00504    standard output/error directly.
00505    - In curses mode, the standard output/error is controlled by TUI
00506    with the tui_stdout and tui_stderr.  The output is redirected in
00507    the curses command window.  Several readline callbacks are installed
00508    so that readline asks for its input to the curses command window
00509    with wgetch().  */
00510 void
00511 tui_setup_io (int mode)
00512 {
00513   extern int _rl_echoing_p;
00514 
00515   if (mode)
00516     {
00517       /* Redirect readline to TUI.  */
00518       tui_old_rl_redisplay_function = rl_redisplay_function;
00519       tui_old_rl_deprep_terminal = rl_deprep_term_function;
00520       tui_old_rl_prep_terminal = rl_prep_term_function;
00521       tui_old_rl_getc_function = rl_getc_function;
00522       tui_old_rl_outstream = rl_outstream;
00523       tui_old_rl_echoing_p = _rl_echoing_p;
00524       rl_redisplay_function = tui_redisplay_readline;
00525       rl_deprep_term_function = tui_deprep_terminal;
00526       rl_prep_term_function = tui_prep_terminal;
00527       rl_getc_function = tui_getc;
00528       _rl_echoing_p = 0;
00529       rl_outstream = tui_rl_outstream;
00530       rl_prompt = 0;
00531       rl_completion_display_matches_hook = tui_rl_display_match_list;
00532       rl_already_prompted = 0;
00533 
00534       /* Keep track of previous gdb output.  */
00535       tui_old_stdout = gdb_stdout;
00536       tui_old_stderr = gdb_stderr;
00537       tui_old_uiout = current_uiout;
00538 
00539       /* Reconfigure gdb output.  */
00540       gdb_stdout = tui_stdout;
00541       gdb_stderr = tui_stderr;
00542       gdb_stdlog = gdb_stdout;  /* for moment */
00543       gdb_stdtarg = gdb_stderr; /* for moment */
00544       gdb_stdtargerr = gdb_stderr;      /* for moment */
00545       current_uiout = tui_out;
00546 
00547       /* Save tty for SIGCONT.  */
00548       savetty ();
00549     }
00550   else
00551     {
00552       /* Restore gdb output.  */
00553       gdb_stdout = tui_old_stdout;
00554       gdb_stderr = tui_old_stderr;
00555       gdb_stdlog = gdb_stdout;  /* for moment */
00556       gdb_stdtarg = gdb_stderr; /* for moment */
00557       gdb_stdtargerr = gdb_stderr;      /* for moment */
00558       current_uiout = tui_old_uiout;
00559 
00560       /* Restore readline.  */
00561       rl_redisplay_function = tui_old_rl_redisplay_function;
00562       rl_deprep_term_function = tui_old_rl_deprep_terminal;
00563       rl_prep_term_function = tui_old_rl_prep_terminal;
00564       rl_getc_function = tui_old_rl_getc_function;
00565       rl_outstream = tui_old_rl_outstream;
00566       rl_completion_display_matches_hook = 0;
00567       _rl_echoing_p = tui_old_rl_echoing_p;
00568       rl_already_prompted = 0;
00569 
00570       /* Save tty for SIGCONT.  */
00571       savetty ();
00572     }
00573 }
00574 
00575 #ifdef SIGCONT
00576 /* Catch SIGCONT to restore the terminal and refresh the screen.  */
00577 static void
00578 tui_cont_sig (int sig)
00579 {
00580   if (tui_active)
00581     {
00582       /* Restore the terminal setting because another process (shell)
00583          might have changed it.  */
00584       resetty ();
00585 
00586       /* Force a refresh of the screen.  */
00587       tui_refresh_all_win ();
00588 
00589       /* Update cursor position on the screen.  */
00590       wmove (TUI_CMD_WIN->generic.handle,
00591              TUI_CMD_WIN->detail.command_info.start_line,
00592              TUI_CMD_WIN->detail.command_info.curch);
00593       wrefresh (TUI_CMD_WIN->generic.handle);
00594     }
00595   signal (sig, tui_cont_sig);
00596 }
00597 #endif
00598 
00599 /* Initialize the IO for gdb in curses mode.  */
00600 void
00601 tui_initialize_io (void)
00602 {
00603 #ifdef SIGCONT
00604   signal (SIGCONT, tui_cont_sig);
00605 #endif
00606 
00607   /* Create tui output streams.  */
00608   tui_stdout = tui_fileopen (stdout);
00609   tui_stderr = tui_fileopen (stderr);
00610   tui_out = tui_out_new (tui_stdout);
00611 
00612   /* Create the default UI.  */
00613   tui_old_uiout = cli_out_new (gdb_stdout);
00614 
00615 #ifdef TUI_USE_PIPE_FOR_READLINE
00616   /* Temporary solution for readline writing to stdout: redirect
00617      readline output in a pipe, read that pipe and output the content
00618      in the curses command window.  */
00619   if (gdb_pipe_cloexec (tui_readline_pipe) != 0)
00620     {
00621       fprintf_unfiltered (gdb_stderr, "Cannot create pipe for readline");
00622       exit (1);
00623     }
00624   tui_rl_outstream = fdopen (tui_readline_pipe[1], "w");
00625   if (tui_rl_outstream == 0)
00626     {
00627       fprintf_unfiltered (gdb_stderr, "Cannot redirect readline output");
00628       exit (1);
00629     }
00630   setvbuf (tui_rl_outstream, (char*) NULL, _IOLBF, 0);
00631 
00632 #ifdef O_NONBLOCK
00633   (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NONBLOCK);
00634 #else
00635 #ifdef O_NDELAY
00636   (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NDELAY);
00637 #endif
00638 #endif
00639   add_file_handler (tui_readline_pipe[0], tui_readline_output, 0);
00640 #else
00641   tui_rl_outstream = stdout;
00642 #endif
00643 }
00644 
00645 /* Get a character from the command window.  This is called from the
00646    readline package.  */
00647 int
00648 tui_getc (FILE *fp)
00649 {
00650   int ch;
00651   WINDOW *w;
00652 
00653   w = TUI_CMD_WIN->generic.handle;
00654 
00655 #ifdef TUI_USE_PIPE_FOR_READLINE
00656   /* Flush readline output.  */
00657   tui_readline_output (0, 0);
00658 #endif
00659 
00660   ch = wgetch (w);
00661   ch = tui_handle_resize_during_io (ch);
00662 
00663   /* The \n must be echoed because it will not be printed by
00664      readline.  */
00665   if (ch == '\n')
00666     {
00667       /* When hitting return with an empty input, gdb executes the last
00668          command.  If we emit a newline, this fills up the command window
00669          with empty lines with gdb prompt at beginning.  Instead of that,
00670          stay on the same line but provide a visual effect to show the
00671          user we recognized the command.  */
00672       if (rl_end == 0)
00673         {
00674           wmove (w, TUI_CMD_WIN->detail.command_info.cur_line, 0);
00675 
00676           /* Clear the line.  This will blink the gdb prompt since
00677              it will be redrawn at the same line.  */
00678           wclrtoeol (w);
00679           wrefresh (w);
00680           napms (20);
00681         }
00682       else
00683         {
00684           wmove (w, TUI_CMD_WIN->detail.command_info.cur_line,
00685                  TUI_CMD_WIN->detail.command_info.curch);
00686           waddch (w, ch);
00687         }
00688     }
00689   
00690   if (key_is_command_char (ch))
00691     {                           /* Handle prev/next/up/down here.  */
00692       ch = tui_dispatch_ctrl_char (ch);
00693     }
00694   
00695   if (ch == '\n' || ch == '\r' || ch == '\f')
00696     TUI_CMD_WIN->detail.command_info.curch = 0;
00697   if (ch == KEY_BACKSPACE)
00698     return '\b';
00699   
00700   return ch;
00701 }
00702 
00703 
00704 /* Cleanup when a resize has occured.
00705    Returns the character that must be processed.  */
00706 static unsigned int
00707 tui_handle_resize_during_io (unsigned int original_ch)
00708 {
00709   if (tui_win_resized ())
00710     {
00711       tui_resize_all ();
00712       tui_refresh_all_win ();
00713       dont_repeat ();
00714       tui_set_win_resized_to (FALSE);
00715       return '\n';
00716     }
00717   else
00718     return original_ch;
00719 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines