Esempio n. 1
0
/**
 * mutt_getch - Read a character from the input buffer
 * @retval obj Event to process
 *
 * The priority for reading events is:
 * 1. UngetKeyEvents buffer
 * 2. MacroEvents buffer
 * 3. Keyboard
 *
 * This function can return:
 * - Error `{ -1, OP_NULL }`
 * - Timeout `{ -2, OP_NULL }`
 */
struct Event mutt_getch(void)
{
  int ch;
  struct Event err = { -1, OP_NULL }, ret;
  struct Event timeout = { -2, OP_NULL };

  if (UngetCount)
    return UngetKeyEvents[--UngetCount];

  if (!OptIgnoreMacroEvents && MacroBufferCount)
    return MacroEvents[--MacroBufferCount];

  SigInt = 0;

  mutt_sig_allow_interrupt(1);
#ifdef KEY_RESIZE
  /* ncurses 4.2 sends this when the screen is resized */
  ch = KEY_RESIZE;
  while (ch == KEY_RESIZE)
#endif /* KEY_RESIZE */
#ifdef USE_INOTIFY
    ch = mutt_monitor_getch();
#else
  ch = getch();
#endif /* USE_INOTIFY */
  mutt_sig_allow_interrupt(0);

  if (SigInt)
  {
    mutt_query_exit();
    return err;
  }

  /* either timeout, a sigwinch (if timeout is set), or the terminal
   * has been lost */
  if (ch == ERR)
  {
    if (!isatty(0))
      mutt_exit(1);

    return timeout;
  }

  if ((ch & 0x80) && C_MetaKey)
  {
    /* send ALT-x as ESC-x */
    ch &= ~0x80;
    mutt_unget_event(ch, 0);
    ret.ch = '\033';
    ret.op = 0;
    return ret;
  }

  ret.ch = ch;
  ret.op = 0;
  return (ch == ctrl('G')) ? err : ret;
}
event_t mutt_getch (void)
{
  int ch;
  event_t err = {-1, OP_NULL }, ret;

  if (UngetCount)
    return (KeyEvent[--UngetCount]);

  SigInt = 0;

#ifdef KEY_RESIZE
  /* ncurses 4.2 sends this when the screen is resized */
  ch = KEY_RESIZE;
  while (ch == KEY_RESIZE)
#endif /* KEY_RESIZE */
    ch = getch ();

  if (SigInt)
    mutt_query_exit ();

  if(ch == ERR)
    return err;
  
  if ((ch & 0x80) && option (OPTMETAKEY))
  {
    /* send ALT-x as ESC-x */
    ch &= ~0x80;
    mutt_ungetch (ch, 0);
    ret.ch = '\033';
    ret.op = 0;
    return ret;
  }

  ret.ch = ch;
  ret.op = 0;
  return (ch == ctrl ('G') ? err : ret);
}
Esempio n. 3
0
/**
 * raw_socket_poll - Checks whether reads would block - Implements Connection::conn_poll()
 */
int raw_socket_poll(struct Connection *conn, time_t wait_secs)
{
  fd_set rfds;
  unsigned long wait_millis;
  struct timeval tv, pre_t, post_t;

  if (conn->fd < 0)
    return -1;

  wait_millis = wait_secs * 1000UL;

  while (true)
  {
    tv.tv_sec = wait_millis / 1000;
    tv.tv_usec = (wait_millis % 1000) * 1000;

    FD_ZERO(&rfds);
    FD_SET(conn->fd, &rfds);

    gettimeofday(&pre_t, NULL);
    const int rc = select(conn->fd + 1, &rfds, NULL, NULL, &tv);
    gettimeofday(&post_t, NULL);

    if ((rc > 0) || ((rc < 0) && (errno != EINTR)))
      return rc;

    if (SigInt)
      mutt_query_exit();

    wait_millis += (pre_t.tv_sec * 1000UL) + (pre_t.tv_usec / 1000);
    const unsigned long post_t_millis = (post_t.tv_sec * 1000UL) + (post_t.tv_usec / 1000);
    if (wait_millis <= post_t_millis)
      return 0;
    wait_millis -= post_t_millis;
  }
}