/*
From: Jeff Solomon <jsolomon@stanford.edu>
Date: Fri,  9 Apr 1999 10:13:27 -0700 (PDT)
To: chet@po.cwru.edu
Subject: new readline example
Message-ID: <14094.12094.527305.199695@mrclean.Stanford.EDU>

Chet,

I've been using readline 4.0. Specifically, I've been using the perl
version Term::ReadLine::Gnu. It works great.

Anyway, I've been playing around the alternate interface and I wanted
to contribute a little C program, callback.c, to you that you could
use as an example of the alternate interface in the /examples
directory of the readline distribution.

My example shows how, using the alternate interface, you can
interactively change the prompt (which is very nice imo). Also, I
point out that you must roll your own terminal setting when using the
alternate interface because readline depreps (using your parlance) the
terminal while in the user callback. I try to demostrate what I mean
with an example. I've included the program below.

To compile, I just put the program in the examples directory and made
the appropriate changes to the EXECUTABLES and OBJECTS line and added
an additional target 'callback'.

I compiled on my Sun Solaris2.6 box using Sun's cc.

Let me know what you think.

Jeff
*/
/*
Copyright (C) 1999 Jeff Solomon
*/

#if defined (HAVE_CONFIG_H)
#include <config.h>
#endif

#include <stdio.h>
#include <sys/types.h>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#include <termios.h>	/* xxx - should make this more general */

#ifdef READLINE_LIBRARY
#  include "readline.h"
#else
#  include <readline/readline.h>
#endif

/* This little examples demonstrates the alternate interface to using readline.
 * In the alternate interface, the user maintains control over program flow and
 * only calls readline when STDIN is readable. Using the alternate interface,
 * you can do anything else while still using readline (like talking to a
 * network or another program) without blocking.
 *
 * Specifically, this program highlights two importants features of the
 * alternate interface. The first is the ability to interactively change the
 * prompt, which can't be done using the regular interface since rl_prompt is
 * read-only.
 * 
 * The second feature really highlights a subtle point when using the alternate
 * interface. That is, readline will not alter the terminal when inside your
 * callback handler. So let's so, your callback executes a user command that
 * takes a non-trivial amount of time to complete (seconds). While your
 * executing the command, the user continues to type keystrokes and expects them
 * to be re-echoed on the new prompt when it returns. Unfortunately, the default
 * terminal configuration doesn't do this. After the prompt returns, the user
 * must hit one additional keystroke and then will see all of his previous
 * keystrokes. To illustrate this, compile and run this program. Type "sleep" at
 * the prompt and then type "bar" before the prompt returns (you have 3
 * seconds). Notice how "bar" is re-echoed on the prompt after the prompt
 * returns? This is what you expect to happen. Now comment out the 4 lines below
 * the line that says COMMENT LINE BELOW. Recompile and rerun the program and do
 * the same thing. When the prompt returns, you should not see "bar". Now type
 * "f", see how "barf" magically appears? This behavior is un-expected and not
 * desired.
 */

void process_line(char *line);
int  change_prompt(void);
char *get_prompt(void);

int prompt = 1;
char prompt_buf[40], line_buf[256];
tcflag_t old_lflag;
cc_t     old_vtime;
struct termios term;

int 
main()
{
    fd_set fds;

    /* Adjust the terminal slightly before the handler is installed. Disable
     * canonical mode processing and set the input character time flag to be
     * non-blocking.
     */
    if( tcgetattr(STDIN_FILENO, &term) < 0 ) {
        perror("tcgetattr");
        exit(1);
    }
    old_lflag = term.c_lflag;
    old_vtime = term.c_cc[VTIME];
    term.c_lflag &= ~ICANON;
    term.c_cc[VTIME] = 1;
    /* COMMENT LINE BELOW - see above */
    if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 ) {
        perror("tcsetattr");
        exit(1);
    }

    rl_add_defun("change-prompt", change_prompt, CTRL('t'));
    rl_callback_handler_install(get_prompt(), process_line);

    while(1) {
      FD_ZERO(&fds);
      FD_SET(fileno(stdin), &fds);

      if( select(FD_SETSIZE, &fds, NULL, NULL, NULL) < 0) {
        perror("select");
        exit(1);
      }

      if( FD_ISSET(fileno(stdin), &fds) ) {
        rl_callback_read_char();
      }
    }
}

void
process_line(char *line)
{
  if( line == NULL ) {
    fprintf(stderr, "\n", line);

    /* reset the old terminal setting before exiting */
    term.c_lflag     = old_lflag;
    term.c_cc[VTIME] = old_vtime;
    if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 ) {
        perror("tcsetattr");
        exit(1);
    }
    exit(0);
  }

  if( strcmp(line, "sleep") == 0 ) {
    sleep(3);
  } else {
    fprintf(stderr, "|%s|\n", line);
  }

  free (line);
}

int
change_prompt(void)
{
  /* toggle the prompt variable */
  prompt = !prompt;

  /* save away the current contents of the line */
  strcpy(line_buf, rl_line_buffer);

  /* install a new handler which will change the prompt and erase the current line */
  rl_callback_handler_install(get_prompt(), process_line);

  /* insert the old text on the new line */
  rl_insert_text(line_buf);

  /* redraw the current line - this is an undocumented function. It invokes the
   * redraw-current-line command.
   */
  rl_refresh_line(0, 0);
}

char *
get_prompt(void)
{
  /* The prompts can even be different lengths! */
  sprintf(prompt_buf, "%s", 
    prompt ? "Hit ctrl-t to toggle prompt> " : "Pretty cool huh?> ");
  return prompt_buf;
}
