예제 #1
0
// Low level input function.
int os_inchar(uint8_t *buf, int maxlen, int32_t ms, int tb_change_cnt)
{
  InbufPollResult result;

  if (event_has_deferred()) {
    // Return pending event bytes
    return push_event_key(buf, maxlen);
  }

  if (ms >= 0) {
    if ((result = inbuf_poll(ms)) == kInputNone) {
      return 0;
    }
  } else {
    if ((result = inbuf_poll(p_ut)) == kInputNone) {
      if (trigger_cursorhold() && maxlen >= 3
          && !typebuf_changed(tb_change_cnt)) {
        buf[0] = K_SPECIAL;
        buf[1] = KS_EXTRA;
        buf[2] = KE_CURSORHOLD;
        return 3;
      }

      before_blocking();
      result = inbuf_poll(-1);
    }
  }

  // If there are deferred events, return the keys directly
  if (event_has_deferred()) {
    return push_event_key(buf, maxlen);
  }

  // If input was put directly in typeahead buffer bail out here.
  if (typebuf_changed(tb_change_cnt)) {
    return 0;
  }

  if (result == kInputEof) {
    read_error_exit();
    return 0;
  }

  return read_from_input_buf(buf, (int64_t)maxlen);
}
예제 #2
0
파일: input.c 프로젝트: Sean1708/neovim
// Low level input function
int os_inchar(uint8_t *buf, int maxlen, int ms, int tb_change_cnt)
{
  if (rbuffer_pending(input_buffer)) {
    return (int)rbuffer_read(input_buffer, (char *)buf, (size_t)maxlen);
  }

  InbufPollResult result;
  if (ms >= 0) {
    if ((result = inbuf_poll(ms)) == kInputNone) {
      return 0;
    }
  } else {
    if ((result = inbuf_poll((int)p_ut)) == kInputNone) {
      if (trigger_cursorhold() && maxlen >= 3
          && !typebuf_changed(tb_change_cnt)) {
        buf[0] = K_SPECIAL;
        buf[1] = KS_EXTRA;
        buf[2] = KE_CURSORHOLD;
        return 3;
      }

      before_blocking();
      result = inbuf_poll(-1);
    }
  }

  // If input was put directly in typeahead buffer bail out here.
  if (typebuf_changed(tb_change_cnt)) {
    return 0;
  }

  if (rbuffer_pending(input_buffer)) {
    // Safe to convert rbuffer_read to int, it will never overflow since we use
    // relatively small buffers.
    return (int)rbuffer_read(input_buffer, (char *)buf, (size_t)maxlen);
  }

  // If there are deferred events, return the keys directly
  if (event_has_deferred()) {
    return push_event_key(buf, maxlen);
  }

  if (result == kInputEof) {
    read_error_exit();
  }

  return 0;
}
예제 #3
0
파일: event.c 프로젝트: alex-vim/neovim
// Wait for some event
bool event_poll(int32_t ms)
{
  uv_run_mode run_mode = UV_RUN_ONCE;

  if (input_ready()) {
    // If there's a pending input event to be consumed, do it now
    return true;
  }

  static int recursive = 0;

  if (!(recursive++)) {
    // Only needs to start the libuv handle the first time we enter here
    input_start();
  }

  uv_timer_t timer;
  uv_prepare_t timer_prepare;
  TimerData timer_data = {.ms = ms, .timed_out = false, .timer = &timer};

  if (ms > 0) {
    uv_timer_init(uv_default_loop(), &timer);
    // This prepare handle that actually starts the timer
    uv_prepare_init(uv_default_loop(), &timer_prepare);
    // Timeout passed as argument to the timer
    timer.data = &timer_data;
    // We only start the timer after the loop is running, for that we
    // use a prepare handle(pass the interval as data to it)
    timer_prepare.data = &timer_data;
    uv_prepare_start(&timer_prepare, timer_prepare_cb);
  } else if (ms == 0) {
    // For ms == 0, we need to do a non-blocking event poll by
    // setting the run mode to UV_RUN_NOWAIT.
    run_mode = UV_RUN_NOWAIT;
  }

  do {
    // Run one event loop iteration, blocking for events if run_mode is
    // UV_RUN_ONCE
    uv_run(uv_default_loop(), run_mode);
    // Process immediate events outside uv_run since libuv event loop not
    // support recursion(processing events may cause a recursive event_poll
    // call)
    event_process(false);
  } while (
      // Continue running if ...
      !input_ready() &&   // we have no input
      !event_has_deferred() &&   // no events are waiting to be processed
      run_mode != UV_RUN_NOWAIT &&   // ms != 0
      !timer_data.timed_out);  // we didn't get a timeout

  if (!(--recursive)) {
    // Again, only stop when we leave the top-level invocation
    input_stop();
  }

  if (ms > 0) {
    // Ensure the timer-related handles are closed and run the event loop
    // once more to let libuv perform it's cleanup
    uv_close((uv_handle_t *)&timer, NULL);
    uv_close((uv_handle_t *)&timer_prepare, NULL);
    uv_run(uv_default_loop(), UV_RUN_NOWAIT);
    event_process(false);
  }

  return input_ready() || event_has_deferred();
}

bool event_has_deferred()
{
  return !kl_empty(get_queue(true));
}

// Push an event to the queue
void event_push(Event event, bool deferred)
{
  *kl_pushp(Event, get_queue(deferred)) = event;
}
예제 #4
0
파일: input.c 프로젝트: Sean1708/neovim
// Check if there's pending input
static bool input_ready(void)
{
  return typebuf_was_filled ||                 // API call filled typeahead
         rbuffer_pending(input_buffer) > 0 ||  // Input buffer filled
         event_has_deferred();                 // Events must be processed
}