TermKeyResult termkey_waitkey(TermKey *tk, TermKeyKey *key) { if(tk->fd == -1) { errno = EBADF; return TERMKEY_RES_ERROR; } while(1) { TermKeyResult ret = termkey_getkey(tk, key); switch(ret) { case TERMKEY_RES_KEY: case TERMKEY_RES_EOF: case TERMKEY_RES_ERROR: return ret; case TERMKEY_RES_NONE: ret = termkey_advisereadable(tk); if(ret == TERMKEY_RES_ERROR) return ret; break; case TERMKEY_RES_AGAIN: { if(tk->is_closed) // We're closed now. Never going to get more bytes so just go with // what we have return termkey_getkey_force(tk, key); struct pollfd fd; retry: fd.fd = tk->fd; fd.events = POLLIN; int pollret = poll(&fd, 1, tk->waittime); if(pollret == -1) { if(errno == EINTR && !(tk->flags & TERMKEY_FLAG_EINTR)) goto retry; return TERMKEY_RES_ERROR; } if(fd.revents & (POLLIN|POLLHUP|POLLERR)) ret = termkey_advisereadable(tk); else ret = TERMKEY_RES_NONE; if(ret == TERMKEY_RES_ERROR) return ret; if(ret == TERMKEY_RES_NONE) return termkey_getkey_force(tk, key); } break; } } /* UNREACHABLE */ }
int main(int argc, char *argv[]) { TERMKEY_CHECK_VERSION; TermKey *tk = termkey_new(0, 0); if(!tk) { fprintf(stderr, "Cannot allocate termkey instance\n"); exit(1); } struct pollfd fd; fd.fd = 0; /* the file descriptor we passed to termkey_new() */ fd.events = POLLIN; TermKeyResult ret; TermKeyKey key; int running = 1; int nextwait = -1; while(running) { if(poll(&fd, 1, nextwait) == 0) { // Timed out if(termkey_getkey_force(tk, &key) == TERMKEY_RES_KEY) on_key(tk, &key); } if(fd.revents & (POLLIN|POLLHUP|POLLERR)) termkey_advisereadable(tk); while((ret = termkey_getkey(tk, &key)) == TERMKEY_RES_KEY) { on_key(tk, &key); if(key.type == TERMKEY_TYPE_UNICODE && key.modifiers & TERMKEY_KEYMOD_CTRL && (key.code.codepoint == 'C' || key.code.codepoint == 'c')) running = 0; } if(ret == TERMKEY_RES_AGAIN) nextwait = termkey_get_waittime(tk); else nextwait = -1; } termkey_destroy(tk); }
gboolean CoreManager::io_input(GIOChannel *source, GIOCondition cond) { if (io_input_timeout_conn.connected()) io_input_timeout_conn.disconnect(); termkey_advisereadable(tk); TermKeyKey key; TermKeyResult ret; while ((ret = termkey_getkey(tk, &key)) == TERMKEY_RES_KEY) { if (key.type == TERMKEY_TYPE_UNICODE && !utf8) { gsize bwritten; GError *err = NULL; char *utf8; // convert data from user charset to UTF-8 if (!(utf8 = g_locale_to_utf8(key.utf8, -1, NULL, &bwritten, &err))) { if (err) { g_warning(_("Error converting input to UTF-8 (%s)."), err->message); g_error_free(err); err = NULL; } else g_warning(_("Error converting input to UTF-8.")); continue; } memcpy(key.utf8, utf8, bwritten + 1); g_free(utf8); key.code.codepoint = g_utf8_get_char(key.utf8); } ProcessInput(key); } if (ret == TERMKEY_RES_AGAIN) { int wait = termkey_get_waittime(tk); io_input_timeout_conn = TimeoutOnceConnect(sigc::mem_fun(this, &CoreManager::io_input_timeout), wait); } return TRUE; }