/* TUI support I/O functions.

   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009,
   2010, 2011 Free Software Foundation, Inc.

   Contributed by Hewlett-Packard Company.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "target.h"
#include "event-loop.h"
#include "event-top.h"
#include "command.h"
#include "top.h"
#include "tui/tui.h"
#include "tui/tui-data.h"
#include "tui/tui-io.h"
#include "tui/tui-command.h"
#include "tui/tui-win.h"
#include "tui/tui-wingeneral.h"
#include "tui/tui-file.h"
#include "ui-out.h"
#include "cli-out.h"
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>

#include "gdb_curses.h"

/* This redefines CTRL if it is not already defined, so it must come
   after terminal state releated include files like <term.h> and
   "gdb_curses.h".  */
#include "readline/readline.h"

int
key_is_start_sequence (int ch)
{
  return (ch == 27);
}

int
key_is_end_sequence (int ch)
{
  return (ch == 126);
}

int
key_is_backspace (int ch)
{
  return (ch == 8);
}

int
key_is_command_char (int ch)
{
  return ((ch == KEY_NPAGE) || (ch == KEY_PPAGE)
	  || (ch == KEY_LEFT) || (ch == KEY_RIGHT)
	  || (ch == KEY_UP) || (ch == KEY_DOWN)
	  || (ch == KEY_SF) || (ch == KEY_SR)
	  || (ch == (int)'\f') 
	  || key_is_start_sequence (ch));
}

/* Use definition from readline 4.3.  */
#undef CTRL_CHAR
#define CTRL_CHAR(c) \
     ((c) < control_character_threshold && (((c) & 0x80) == 0))

/* This file controls the IO interactions between gdb and curses.
   When the TUI is enabled, gdb has two modes a curses and a standard
   mode.

   In curses mode, the gdb outputs are made in a curses command
   window.  For this, the gdb_stdout and gdb_stderr are redirected to
   the specific ui_file implemented by TUI.  The output is handled by
   tui_puts().  The input is also controlled by curses with
   tui_getc().  The readline library uses this function to get its
   input.  Several readline hooks are installed to redirect readline
   output to the TUI (see also the note below).

   In normal mode, the gdb outputs are restored to their origin, that
   is as if TUI is not used.  Readline also uses its original getc()
   function with stdin.

   Note SCz/2001-07-21: the current readline is not clean in its
   management of the output.  Even if we install a redisplay handler,
   it sometimes writes on a stdout file.  It is important to redirect
   every output produced by readline, otherwise the curses window will
   be garbled.  This is implemented with a pipe that TUI reads and
   readline writes to.  A gdb input handler is created so that reading
   the pipe is handled automatically.  This will probably not work on
   non-Unix platforms.  The best fix is to make readline clean enougth
   so that is never write on stdout.

   Note SCz/2002-09-01: we now use more readline hooks and it seems
   that with them we don't need the pipe anymore (verified by creating
   the pipe and closing its end so that write causes a SIGPIPE).  The
   old pipe code is still there and can be conditionally removed by
   #undef TUI_USE_PIPE_FOR_READLINE.  */

/* For gdb 5.3, prefer to continue the pipe hack as a backup wheel.  */
#ifdef HAVE_PIPE
#define TUI_USE_PIPE_FOR_READLINE
#endif
/* #undef TUI_USE_PIPE_FOR_READLINE */

/* TUI output files.  */
static struct ui_file *tui_stdout;
static struct ui_file *tui_stderr;
struct ui_out *tui_out;

/* GDB output files in non-curses mode.  */
static struct ui_file *tui_old_stdout;
static struct ui_file *tui_old_stderr;
struct ui_out *tui_old_uiout;

/* Readline previous hooks.  */
static Function *tui_old_rl_getc_function;
static VFunction *tui_old_rl_redisplay_function;
static VFunction *tui_old_rl_prep_terminal;
static VFunction *tui_old_rl_deprep_terminal;
static int tui_old_readline_echoing_p;

/* Readline output stream.
   Should be removed when readline is clean.  */
static FILE *tui_rl_outstream;
static FILE *tui_old_rl_outstream;
#ifdef TUI_USE_PIPE_FOR_READLINE
static int tui_readline_pipe[2];
#endif

/* The last gdb prompt that was registered in readline.
   This may be the main gdb prompt or a secondary prompt.  */
static char *tui_rl_saved_prompt;

static unsigned int tui_handle_resize_during_io (unsigned int);

static void
tui_putc (char c)
{
  char buf[2];

  buf[0] = c;
  buf[1] = 0;
  tui_puts (buf);
}

/* Print the string in the curses command window.  */
void
tui_puts (const char *string)
{
  static int tui_skip_line = -1;
  char c;
  WINDOW *w;

  w = TUI_CMD_WIN->generic.handle;
  while ((c = *string++) != 0)
    {
      /* Catch annotation and discard them.  We need two \032 and
         discard until a \n is seen.  */
      if (c == '\032')
        {
          tui_skip_line++;
        }
      else if (tui_skip_line != 1)
        {
          tui_skip_line = -1;
          waddch (w, c);
        }
      else if (c == '\n')
        tui_skip_line = -1;
    }
  getyx (w, TUI_CMD_WIN->detail.command_info.cur_line,
         TUI_CMD_WIN->detail.command_info.curch);
  TUI_CMD_WIN->detail.command_info.start_line
    = TUI_CMD_WIN->detail.command_info.cur_line;

  /* We could defer the following.  */
  wrefresh (w);
  fflush (stdout);
}

/* Readline callback.
   Redisplay the command line with its prompt after readline has
   changed the edited text.  */
void
tui_redisplay_readline (void)
{
  int prev_col;
  int height;
  int col, line;
  int c_pos;
  int c_line;
  int in;
  WINDOW *w;
  char *prompt;
  int start_line;

  /* Detect when we temporarily left SingleKey and now the readline
     edit buffer is empty, automatically restore the SingleKey
     mode.  */
  if (tui_current_key_mode == TUI_ONE_COMMAND_MODE && rl_end == 0)
    tui_set_key_mode (TUI_SINGLE_KEY_MODE);

  if (tui_current_key_mode == TUI_SINGLE_KEY_MODE)
    prompt = "";
  else
    prompt = tui_rl_saved_prompt;
  
  c_pos = -1;
  c_line = -1;
  w = TUI_CMD_WIN->generic.handle;
  start_line = TUI_CMD_WIN->detail.command_info.start_line;
  wmove (w, start_line, 0);
  prev_col = 0;
  height = 1;
  for (in = 0; prompt && prompt[in]; in++)
    {
      waddch (w, prompt[in]);
      getyx (w, line, col);
      if (col < prev_col)
        height++;
      prev_col = col;
    }
  for (in = 0; in < rl_end; in++)
    {
      unsigned char c;
      
      c = (unsigned char) rl_line_buffer[in];
      if (in == rl_point)
	{
          getyx (w, c_line, c_pos);
	}

      if (CTRL_CHAR (c) || c == RUBOUT)
	{
          waddch (w, '^');
          waddch (w, CTRL_CHAR (c) ? UNCTRL (c) : '?');
	}
      else
	{
          waddch (w, c);
	}
      if (c == '\n')
        {
          getyx (w, TUI_CMD_WIN->detail.command_info.start_line,
                 TUI_CMD_WIN->detail.command_info.curch);
        }
      getyx (w, line, col);
      if (col < prev_col)
        height++;
      prev_col = col;
    }
  wclrtobot (w);
  getyx (w, TUI_CMD_WIN->detail.command_info.start_line,
         TUI_CMD_WIN->detail.command_info.curch);
  if (c_line >= 0)
    {
      wmove (w, c_line, c_pos);
      TUI_CMD_WIN->detail.command_info.cur_line = c_line;
      TUI_CMD_WIN->detail.command_info.curch = c_pos;
    }
  TUI_CMD_WIN->detail.command_info.start_line -= height - 1;

  wrefresh (w);
  fflush(stdout);
}

/* Readline callback to prepare the terminal.  It is called once each
   time we enter readline.  Terminal is already setup in curses
   mode.  */
static void
tui_prep_terminal (int notused1)
{
  /* Save the prompt registered in readline to correctly display it.
     (we can't use gdb_prompt() due to secondary prompts and can't use
     rl_prompt because it points to an alloca buffer).  */
  xfree (tui_rl_saved_prompt);
  tui_rl_saved_prompt = xstrdup (rl_prompt);
}

/* Readline callback to restore the terminal.  It is called once each
   time we leave readline.  There is nothing to do in curses mode.  */
static void
tui_deprep_terminal (void)
{
}

#ifdef TUI_USE_PIPE_FOR_READLINE
/* Read readline output pipe and feed the command window with it.
   Should be removed when readline is clean.  */
static void
tui_readline_output (int error, gdb_client_data data)
{
  int size;
  char buf[256];

  size = read (tui_readline_pipe[0], buf, sizeof (buf) - 1);
  if (size > 0 && tui_active)
    {
      buf[size] = 0;
      tui_puts (buf);
    }
}
#endif

/* Return the portion of PATHNAME that should be output when listing
   possible completions.  If we are hacking filename completion, we
   are only interested in the basename, the portion following the
   final slash.  Otherwise, we return what we were passed.

   Comes from readline/complete.c.  */
static char *
printable_part (char *pathname)
{
  char *temp;

  temp = rl_filename_completion_desired
    ? strrchr (pathname, '/') : (char *)NULL;
#if defined (__MSDOS__)
  if (rl_filename_completion_desired 
      && temp == 0 && isalpha (pathname[0]) 
      && pathname[1] == ':')
    temp = pathname + 1;
#endif
  return (temp ? ++temp : pathname);
}

/* Output TO_PRINT to rl_outstream.  If VISIBLE_STATS is defined and
   we are using it, check for and output a single character for
   `special' filenames.  Return the number of characters we
   output.  */

#define PUTX(c) \
    do { \
      if (CTRL_CHAR (c)) \
        { \
          tui_puts ("^"); \
          tui_putc (UNCTRL (c)); \
          printed_len += 2; \
        } \
      else if (c == RUBOUT) \
	{ \
	  tui_puts ("^?"); \
	  printed_len += 2; \
	} \
      else \
	{ \
	  tui_putc (c); \
	  printed_len++; \
	} \
    } while (0)

static int
print_filename (char *to_print, char *full_pathname)
{
  int printed_len = 0;
  char *s;

  for (s = to_print; *s; s++)
    {
      PUTX (*s);
    }
  return printed_len;
}

/* The user must press "y" or "n".  Non-zero return means "y" pressed.
   Comes from readline/complete.c.  */
static int
get_y_or_n (void)
{
  extern int _rl_abort_internal ();
  int c;

  for (;;)
    {
      c = rl_read_key ();
      if (c == 'y' || c == 'Y' || c == ' ')
	return (1);
      if (c == 'n' || c == 'N' || c == RUBOUT)
	return (0);
      if (c == ABORT_CHAR)
	_rl_abort_internal ();
      beep ();
    }
}

/* A convenience function for displaying a list of strings in
   columnar format on readline's output stream.  MATCHES is the list
   of strings, in argv format, LEN is the number of strings in MATCHES,
   and MAX is the length of the longest string in MATCHES.

   Comes from readline/complete.c and modified to write in
   the TUI command window using tui_putc/tui_puts.  */
static void
tui_rl_display_match_list (char **matches, int len, int max)
{
  typedef int QSFUNC (const void *, const void *);
  extern int _rl_qsort_string_compare (const void *, 
				       const void *);
  extern int _rl_print_completions_horizontally;
  
  int count, limit, printed_len;
  int i, j, k, l;
  char *temp;

  /* Screen dimension correspond to the TUI command window.  */
  int screenwidth = TUI_CMD_WIN->generic.width;

  /* If there are many items, then ask the user if she really wants to
     see them all.  */
  if (len >= rl_completion_query_items)
    {
      char msg[256];

      sprintf (msg, "\nDisplay all %d possibilities? (y or n)", len);
      tui_puts (msg);
      if (get_y_or_n () == 0)
	{
	  tui_puts ("\n");
	  return;
	}
    }

  /* How many items of MAX length can we fit in the screen window?  */
  max += 2;
  limit = screenwidth / max;
  if (limit != 1 && (limit * max == screenwidth))
    limit--;

  /* Avoid a possible floating exception.  If max > screenwidth, limit
     will be 0 and a divide-by-zero fault will result.  */
  if (limit == 0)
    limit = 1;

  /* How many iterations of the printing loop?  */
  count = (len + (limit - 1)) / limit;

  /* Watch out for special case.  If LEN is less than LIMIT, then
     just do the inner printing loop.
	   0 < len <= limit  implies  count = 1.  */

  /* Sort the items if they are not already sorted.  */
  if (rl_ignore_completion_duplicates == 0)
    qsort (matches + 1, len, sizeof (char *),
           (QSFUNC *)_rl_qsort_string_compare);

  tui_putc ('\n');

  if (_rl_print_completions_horizontally == 0)
    {
      /* Print the sorted items, up-and-down alphabetically, like ls.  */
      for (i = 1; i <= count; i++)
	{
	  for (j = 0, l = i; j < limit; j++)
	    {
	      if (l > len || matches[l] == 0)
		break;
	      else
		{
		  temp = printable_part (matches[l]);
		  printed_len = print_filename (temp, matches[l]);

		  if (j + 1 < limit)
		    for (k = 0; k < max - printed_len; k++)
		      tui_putc (' ');
		}
	      l += count;
	    }
	  tui_putc ('\n');
	}
    }
  else
    {
      /* Print the sorted items, across alphabetically, like ls -x.  */
      for (i = 1; matches[i]; i++)
	{
	  temp = printable_part (matches[i]);
	  printed_len = print_filename (temp, matches[i]);
	  /* Have we reached the end of this line?  */
	  if (matches[i+1])
	    {
	      if (i && (limit > 1) && (i % limit) == 0)
		tui_putc ('\n');
	      else
		for (k = 0; k < max - printed_len; k++)
		  tui_putc (' ');
	    }
	}
      tui_putc ('\n');
    }
}

/* Setup the IO for curses or non-curses mode.
   - In non-curses mode, readline and gdb use the standard input and
   standard output/error directly.
   - In curses mode, the standard output/error is controlled by TUI
   with the tui_stdout and tui_stderr.  The output is redirected in
   the curses command window.  Several readline callbacks are installed
   so that readline asks for its input to the curses command window
   with wgetch().  */
void
tui_setup_io (int mode)
{
  extern int readline_echoing_p;
 
  if (mode)
    {
      /* Redirect readline to TUI.  */
      tui_old_rl_redisplay_function = rl_redisplay_function;
      tui_old_rl_deprep_terminal = rl_deprep_term_function;
      tui_old_rl_prep_terminal = rl_prep_term_function;
      tui_old_rl_getc_function = rl_getc_function;
      tui_old_rl_outstream = rl_outstream;
      tui_old_readline_echoing_p = readline_echoing_p;
      rl_redisplay_function = tui_redisplay_readline;
      rl_deprep_term_function = tui_deprep_terminal;
      rl_prep_term_function = tui_prep_terminal;
      rl_getc_function = tui_getc;
      readline_echoing_p = 0;
      rl_outstream = tui_rl_outstream;
      rl_prompt = 0;
      rl_completion_display_matches_hook = tui_rl_display_match_list;
      rl_already_prompted = 0;

      /* Keep track of previous gdb output.  */
      tui_old_stdout = gdb_stdout;
      tui_old_stderr = gdb_stderr;
      tui_old_uiout = uiout;

      /* Reconfigure gdb output.  */
      gdb_stdout = tui_stdout;
      gdb_stderr = tui_stderr;
      gdb_stdlog = gdb_stdout;	/* for moment */
      gdb_stdtarg = gdb_stderr;	/* for moment */
      gdb_stdtargerr = gdb_stderr;	/* for moment */
      uiout = tui_out;

      /* Save tty for SIGCONT.  */
      savetty ();
    }
  else
    {
      /* Restore gdb output.  */
      gdb_stdout = tui_old_stdout;
      gdb_stderr = tui_old_stderr;
      gdb_stdlog = gdb_stdout;	/* for moment */
      gdb_stdtarg = gdb_stderr;	/* for moment */
      gdb_stdtargerr = gdb_stderr;	/* for moment */
      uiout = tui_old_uiout;

      /* Restore readline.  */
      rl_redisplay_function = tui_old_rl_redisplay_function;
      rl_deprep_term_function = tui_old_rl_deprep_terminal;
      rl_prep_term_function = tui_old_rl_prep_terminal;
      rl_getc_function = tui_old_rl_getc_function;
      rl_outstream = tui_old_rl_outstream;
      rl_completion_display_matches_hook = 0;
      readline_echoing_p = tui_old_readline_echoing_p;
      rl_already_prompted = 0;

      /* Save tty for SIGCONT.  */
      savetty ();
    }
}

#ifdef SIGCONT
/* Catch SIGCONT to restore the terminal and refresh the screen.  */
static void
tui_cont_sig (int sig)
{
  if (tui_active)
    {
      /* Restore the terminal setting because another process (shell)
         might have changed it.  */
      resetty ();

      /* Force a refresh of the screen.  */
      tui_refresh_all_win ();

      /* Update cursor position on the screen.  */
      wmove (TUI_CMD_WIN->generic.handle,
             TUI_CMD_WIN->detail.command_info.start_line,
             TUI_CMD_WIN->detail.command_info.curch);
      wrefresh (TUI_CMD_WIN->generic.handle);
    }
  signal (sig, tui_cont_sig);
}
#endif

/* Initialize the IO for gdb in curses mode.  */
void
tui_initialize_io (void)
{
#ifdef SIGCONT
  signal (SIGCONT, tui_cont_sig);
#endif

  /* Create tui output streams.  */
  tui_stdout = tui_fileopen (stdout);
  tui_stderr = tui_fileopen (stderr);
  tui_out = tui_out_new (tui_stdout);

  /* Create the default UI.  It is not created because we installed a
     deprecated_init_ui_hook.  */
  tui_old_uiout = uiout = cli_out_new (gdb_stdout);

#ifdef TUI_USE_PIPE_FOR_READLINE
  /* Temporary solution for readline writing to stdout: redirect
     readline output in a pipe, read that pipe and output the content
     in the curses command window.  */
  if (pipe (tui_readline_pipe) != 0)
    {
      fprintf_unfiltered (gdb_stderr, "Cannot create pipe for readline");
      exit (1);
    }
  tui_rl_outstream = fdopen (tui_readline_pipe[1], "w");
  if (tui_rl_outstream == 0)
    {
      fprintf_unfiltered (gdb_stderr, "Cannot redirect readline output");
      exit (1);
    }
  setvbuf (tui_rl_outstream, (char*) NULL, _IOLBF, 0);

#ifdef O_NONBLOCK
  (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NONBLOCK);
#else
#ifdef O_NDELAY
  (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NDELAY);
#endif
#endif
  add_file_handler (tui_readline_pipe[0], tui_readline_output, 0);
#else
  tui_rl_outstream = stdout;
#endif
}

/* Get a character from the command window.  This is called from the
   readline package.  */
int
tui_getc (FILE *fp)
{
  int ch;
  WINDOW *w;

  w = TUI_CMD_WIN->generic.handle;

#ifdef TUI_USE_PIPE_FOR_READLINE
  /* Flush readline output.  */
  tui_readline_output (0, 0);
#endif

  ch = wgetch (w);
  ch = tui_handle_resize_during_io (ch);

  /* The \n must be echoed because it will not be printed by
     readline.  */
  if (ch == '\n')
    {
      /* When hitting return with an empty input, gdb executes the last
         command.  If we emit a newline, this fills up the command window
         with empty lines with gdb prompt at beginning.  Instead of that,
         stay on the same line but provide a visual effect to show the
         user we recognized the command.  */
      if (rl_end == 0)
        {
          wmove (w, TUI_CMD_WIN->detail.command_info.cur_line, 0);

          /* Clear the line.  This will blink the gdb prompt since
             it will be redrawn at the same line.  */
          wclrtoeol (w);
          wrefresh (w);
          napms (20);
        }
      else
        {
          wmove (w, TUI_CMD_WIN->detail.command_info.cur_line,
                 TUI_CMD_WIN->detail.command_info.curch);
          waddch (w, ch);
        }
    }
  
  if (key_is_command_char (ch))
    {				/* Handle prev/next/up/down here.  */
      ch = tui_dispatch_ctrl_char (ch);
    }
  
  if (ch == '\n' || ch == '\r' || ch == '\f')
    TUI_CMD_WIN->detail.command_info.curch = 0;
  if (ch == KEY_BACKSPACE)
    return '\b';
  
  return ch;
}


/* Cleanup when a resize has occured.
   Returns the character that must be processed.  */
static unsigned int
tui_handle_resize_during_io (unsigned int original_ch)
{
  if (tui_win_resized ())
    {
      tui_resize_all ();
      tui_refresh_all_win ();
      dont_repeat ();
      tui_set_win_resized_to (FALSE);
      return '\n';
    }
  else
    return original_ch;
}
