/* TUI support I/O functions.

   Copyright (C) 1998-2013 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_rl_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.  The restore must only be done if the command has finished.
     The command could call prompt_for_continue and we must not
     restore SingleKey so that the prompt and normal keymap are used.  */
  if (tui_current_key_mode == TUI_ONE_COMMAND_MODE && rl_end == 0
      && immediate_quit == 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 const char *
printable_part (const char *pathname)
{
  return rl_filename_completion_desired ? lbasename (pathname) : 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 (const char *to_print, const char *full_pathname)
{
  int printed_len = 0;
  const 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;
  const 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];

      xsnprintf (msg, sizeof (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 _rl_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_rl_echoing_p = _rl_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;
      _rl_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 = current_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 */
      current_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 */
      current_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;
      _rl_echoing_p = tui_old_rl_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 = 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;
}
