int t_wgetch(WINDOW *win, t_char *ch) { wint_t c; int status = wget_wch(win, &c); *ch = (t_char) c; return status; }
void draw_active_window(Tox *m) { ToxWindow *a = active_window; wint_t ch = 0; touchwin(a->window); #ifndef WIN32 wresize(a->window, LINES - 2, COLS); #endif a->blink = false; draw_bar(); a->onDraw(a, m); /* Handle input */ #ifdef HAVE_WIDECHAR wget_wch(stdscr, &ch); #else ch = getch(); #endif if (ch == '\t' || ch == KEY_BTAB) set_next_window((int) ch); else if (ch != ERR) a->onKey(a, m, ch); }
/* * Handle character input from the terminal. Returns non-zero * if CTRL-D was pressed, meaning the application should exit. */ static int handle_key_input(int portfd, WINDOW* win) { static const unsigned char kctab[] = { 0x1B, 0x30 }; // ESC 0 wint_t wc = L'\0'; unsigned char kc; switch (wget_wch(win, &wc)) { case OK: if (wc == L'\4') // C-d: quit return 1; if (wc == L'\t') send_bytes(portfd, kctab, sizeof kctab, win); else if ((kc = kc_from_wide_char(wc))) send_bytes(portfd, &kc, 1, win); else flash(); break; case KEY_CODE_YES: if (wc >= KEY_MIN && wc < KEY_MIN + N_ELEMENTS(keypad2kc) && keypad2kc[wc - KEY_MIN]) send_bytes(portfd, &keypad2kc[wc - KEY_MIN], 1, win); break; default: break; } return 0; }
void draw_active_window(Tox *m) { ToxWindow *a = active_window; a->alert0 = false; a->alert1 = false; a->alert2 = false; wint_t ch = 0; draw_bar(); touchwin(a->window); #ifndef WIN32 wresize(a->window, LINES - 2, COLS); #endif a->onDraw(a, m); wrefresh(a->window); /* Handle input */ #ifdef HAVE_WIDECHAR wget_wch(stdscr, &ch); #else ch = getch(); #endif if (ch == T_KEY_NEXT || ch == T_KEY_PREV) set_next_window((int) ch); else if (ch != ERR) a->onKey(a, m, ch); }
void draw_active_window(Tox *m) { ToxWindow *a = active_window; a->alert0 = false; a->alert1 = false; a->alert2 = false; wint_t ch = 0; draw_bar(); touchwin(a->window); #ifndef WIN32 wresize(a->window, LINES - 2, COLS); #endif a->onDraw(a, m); wrefresh(a->window); /* Handle input */ #ifdef HAVE_WIDECHAR if (wget_wch(stdscr, &ch) == ERR) #else if ((ch = getch()) == ERR) #endif return; if (ch == T_KEY_NEXT || ch == T_KEY_PREV) { set_next_window((int) ch); } else { pthread_mutex_lock(&Winthread.lock); a->onKey(a, m, ch); pthread_mutex_unlock(&Winthread.lock); } }
int mvget_wch(int y, int x, wint_t *wch) { PDC_LOG(("mvget_wch() - called\n")); if (move(y, x) == ERR) return ERR; return wget_wch(stdscr, wch); }
int mvwget_wch(WINDOW *win, int y, int x, wint_t *wch) { PDC_LOG(("mvwget_wch() - called\n")); if (wmove(win, y, x) == ERR) return ERR; return wget_wch(win, wch); }
static int really_getch(WINDOW *win, int *fkey) { int ch; #ifdef USE_WIDE_CURSES int code; mbstate_t state; wchar_t my_wchar; wint_t my_wint; /* * We get a wide character, translate it to multibyte form to avoid * having to change the rest of the code to use wide-characters. */ if (used_last_getc >= have_last_getc) { used_last_getc = 0; have_last_getc = 0; ch = ERR; *fkey = 0; code = wget_wch(win, &my_wint); my_wchar = (wchar_t) my_wint; switch (code) { case KEY_CODE_YES: ch = *fkey = my_wchar; last_getc = my_wchar; break; case OK: memset(&state, 0, sizeof(state)); have_last_getc = (int) wcrtomb(last_getc_bytes, my_wchar, &state); if (have_last_getc < 0) { have_last_getc = used_last_getc = 0; last_getc_bytes[0] = (char) my_wchar; } ch = (int) CharOf(last_getc_bytes[used_last_getc++]); last_getc = my_wchar; break; case ERR: ch = ERR; last_getc = ERR; break; default: break; } } else { ch = (int) CharOf(last_getc_bytes[used_last_getc++]); } #else ch = wgetch(win); last_getc = ch; *fkey = (ch > KEY_MIN && ch < KEY_MAX); #endif return ch; }
static int read_char(WINDOW *win, wint_t *c, int timeout) { static const int T = 150; static const int IPC_F = 10; int i; int result = ERR; for(i = 0; i <= timeout/T; i++) { int j; if(is_redraw_scheduled()) { modes_redraw(); } if(!is_status_bar_multiline() && !is_in_menu_like_mode() && get_mode() != CMDLINE_MODE) { check_if_filelists_have_changed(curr_view); if(curr_stats.number_of_windows != 1 && !curr_stats.view) check_if_filelists_have_changed(other_view); } check_background_jobs(); for(j = 0; j < IPC_F; j++) { ipc_check(); wtimeout(win, MIN(T, timeout)/IPC_F); if((result = wget_wch(win, c)) != ERR) break; if(is_redraw_scheduled()) { modes_redraw(); } } if(result != ERR) break; timeout -= T; } return result; }
static int read_char(WINDOW *win, wint_t *c, int timeout) { static const int T = 150; static const int IPC_F = 10; int i; int result = ERR; for(i = 0; i <= timeout/T; i++) { int j; process_scheduled_updates(); if(should_check_views_for_changes()) { check_view_for_changes(curr_view); check_view_for_changes(other_view); } check_background_jobs(); for(j = 0; j < IPC_F; j++) { ipc_check(); wtimeout(win, MIN(T, timeout)/IPC_F); if((result = wget_wch(win, c)) != ERR) { break; } process_scheduled_updates(); } if(result != ERR) { break; } timeout -= T; } return result; }
void draw_active_window(Tox *m) { ToxWindow *a = active_window; a->alert = WINDOW_ALERT_NONE; wint_t ch = 0; draw_bar(); touchwin(a->window); a->onDraw(a, m); /* Handle input */ bool ltr; #ifdef HAVE_WIDECHAR int status = wget_wch(stdscr, &ch); if (status == ERR) return; if (status == OK) ltr = iswprint(ch); else /* if (status == KEY_CODE_YES) */ ltr = false; #else ch = getch(); if (ch == ERR) return; /* TODO verify if this works */ ltr = isprint(ch); #endif /* HAVE_WIDECHAR */ if (!ltr && (ch == user_settings_->key_next_tab || ch == user_settings_->key_prev_tab)) { set_next_window((int) ch); } else { pthread_mutex_lock(&Winthread.lock); a->onKey(a, m, ch, ltr); pthread_mutex_unlock(&Winthread.lock); } }
static wchar_t *nc_getwch(void) /* gets a key as a wchar_t */ { static wchar_t c[2]; #ifdef CONFOPT_WGET_WCH /* set timer period */ if (timer_msecs > 0) timeout(timer_msecs); if (wget_wch(stdscr, (wint_t *) c) == -1) c[0] = (wchar_t) - 1; #else char tmp[MB_CUR_MAX + 1]; int cc, n = 0; /* read one byte */ cc = wgetch(cw); if (has_key(cc)) { c[0] = cc; return c; } /* set to non-blocking */ nodelay(cw, 1); /* read all possible following characters */ tmp[n++] = cc; while (n < sizeof(tmp) - 1 && (cc = getch()) != ERR) tmp[n++] = cc; /* sets input as blocking */ nodelay(cw, 0); tmp[n] = '\0'; mbstowcs(c, tmp, n); #endif c[1] = '\0'; return c; }
static void test_inserts(int level) { static bool first = TRUE; wint_t ch; int code; int limit; int row = 1; int col; int row2, col2; int length; wchar_t buffer[BUFSIZ]; WINDOW *look = 0; WINDOW *work = 0; WINDOW *show = 0; int margin = (2 * TABSIZE) - 1; Options option = ((m_opt ? oMove : oDefault) | ((w_opt || (level > 0)) ? oWindow : oDefault)); if (first) { static char cmd[80]; setlocale(LC_ALL, ""); putenv(strcpy(cmd, "TABSIZE=8")); initscr(); (void) cbreak(); /* take input chars one at a time, no wait for \n */ (void) noecho(); /* don't echo input */ keypad(stdscr, TRUE); } limit = LINES - 5; if (level > 0) { look = newwin(limit, COLS - (2 * (level - 1)), 0, level - 1); work = newwin(limit - 2, COLS - (2 * level), 1, level); show = newwin(4, COLS, limit + 1, 0); box(look, 0, 0); wnoutrefresh(look); limit -= 2; } else { work = stdscr; show = derwin(stdscr, 4, COLS, limit + 1, 0); } keypad(work, TRUE); for (col = margin + 1; col < COLS; col += TABSIZE) mvwvline(work, row, col, '.', limit - 2); mvwvline(work, row, margin, ACS_VLINE, limit - 2); mvwvline(work, row, margin + 1, ACS_VLINE, limit - 2); limit /= 2; mvwaddstr(work, 1, 2, "String"); mvwaddstr(work, limit + 1, 2, "Chars"); wnoutrefresh(work); buffer[length = 0] = '\0'; legend(show, level, option, buffer, length); wnoutrefresh(show); doupdate(); /* * Show the characters inserted in color, to distinguish from those that * are shifted. */ if (has_colors()) { start_color(); init_pair(1, COLOR_WHITE, COLOR_BLUE); wbkgdset(work, COLOR_PAIR(1) | ' '); } while ((code = wget_wch(work, &ch)) != ERR) { if (code == KEY_CODE_YES) { switch (ch) { case KEY_DOWN: ch = CTRL('N'); break; case KEY_BACKSPACE: ch = '\b'; break; default: beep(); continue; } } else if (code == ERR) { beep(); break; } if (ch == 'q') break; wmove(work, row, margin + 1); switch (ch) { case 'w': test_inserts(level + 1); touchwin(look); touchwin(work); touchwin(show); wnoutrefresh(look); wnoutrefresh(work); wnoutrefresh(show); doupdate(); break; case CTRL('N'): if (row < limit) { ++row; /* put the whole string in, all at once */ col2 = margin + 1; switch (option) { case oDefault: if (n_opt > 1) { for (col = 0; col < length; col += n_opt) { col2 = ColOf(buffer, col, margin); if (move(row, col2) != ERR) { InsNStr(buffer + col, LEN(col)); } } } else { if (move(row, col2) != ERR) { InsStr(buffer); } } break; case oMove: if (n_opt > 1) { for (col = 0; col < length; col += n_opt) { col2 = ColOf(buffer, col, margin); MvInsNStr(row, col2, buffer + col, LEN(col)); } } else { MvInsStr(row, col2, buffer); } break; case oWindow: if (n_opt > 1) { for (col = 0; col < length; col += n_opt) { col2 = ColOf(buffer, col, margin); if (wmove(work, row, col2) != ERR) { WInsNStr(work, buffer + col, LEN(col)); } } } else { if (wmove(work, row, col2) != ERR) { WInsStr(work, buffer); } } break; case oMoveWindow: if (n_opt > 1) { for (col = 0; col < length; col += n_opt) { col2 = ColOf(buffer, col, margin); MvWInsNStr(work, row, col2, buffer + col, LEN(col)); } } else { MvWInsStr(work, row, col2, buffer); } break; } /* do the corresponding single-character insertion */ row2 = limit + row; for (col = 0; col < length; ++col) { col2 = ColOf(buffer, col, margin); switch (option) { case oDefault: if (move(row2, col2) != ERR) { InsCh((chtype) buffer[col]); } break; case oMove: MvInsCh(row2, col2, (chtype) buffer[col]); break; case oWindow: if (wmove(work, row2, col2) != ERR) { WInsCh(work, (chtype) buffer[col]); } break; case oMoveWindow: MvWInsCh(work, row2, col2, (chtype) buffer[col]); break; } } } else { beep(); } break; case KEY_BACKSPACE: ch = '\b'; /* FALLTHRU */ default: buffer[length++] = ch; buffer[length] = '\0'; /* put the string in, one character at a time */ col = ColOf(buffer, length - 1, margin); switch (option) { case oDefault: if (move(row, col) != ERR) { InsStr(buffer + length - 1); } break; case oMove: MvInsStr(row, col, buffer + length - 1); break; case oWindow: if (wmove(work, row, col) != ERR) { WInsStr(work, buffer + length - 1); } break; case oMoveWindow: MvWInsStr(work, row, col, buffer + length - 1); break; } /* do the corresponding single-character insertion */ switch (option) { case oDefault: if (move(limit + row, col) != ERR) { InsCh(ch); } break; case oMove: MvInsCh(limit + row, col, ch); break; case oWindow: if (wmove(work, limit + row, col) != ERR) { WInsCh(work, ch); } break; case oMoveWindow: MvWInsCh(work, limit + row, col, ch); break; } wnoutrefresh(work); legend(show, level, option, buffer, length); wnoutrefresh(show); doupdate(); break; } } if (level > 0) { delwin(show); delwin(work); delwin(look); } }
NCURSES_EXPORT(int) (mvwget_wch) (WINDOW * a1, int a2, int a3, wint_t * z) { T((T_CALLED("mvwget_wch(%p,%d,%d,%p)"), (const void *)a1, a2, a3, (const void *)z)); returnCode((wmove(a1,a2,a3) == (-1) ? (-1) : wget_wch(a1,z))); }
void stfl_form_run(struct stfl_form *f, int timeout) { wchar_t *on_handler = 0; pthread_mutex_lock(&f->mtx); if (f->event) free(f->event); f->event = 0; if (timeout >= 0 && f->event_queue) goto unshift_next_event; if (timeout == -2) goto unshift_next_event; if (!f->root) { fprintf(stderr, "STFL Fatal Error: Called stfl_form_run() without root widget.\n"); abort(); } if (!curses_active) { initscr(); cbreak(); noecho(); nonl(); keypad(stdscr, TRUE); doupdate(); start_color(); use_default_colors(); wbkgdset(stdscr, ' '); curses_active = 1; } stfl_colorpair_counter = 1; f->root->type->f_prepare(f->root, f); struct stfl_widget *fw = stfl_gather_focus_widget(f); f->current_focus_id = fw ? fw->id : 0; getbegyx(stdscr, f->root->y, f->root->x); getmaxyx(stdscr, f->root->h, f->root->w); if (timeout == -3) { WINDOW *dummywin = newwin(0, 0, 0, 0); if (dummywin == NULL) { fprintf(stderr, "STFL Fatal Error: stfl_form_run() got a NULL pointer from newwin(0, 0, 0, 0).\n"); abort(); } f->root->type->f_draw(f->root, f, dummywin); delwin(dummywin); pthread_mutex_unlock(&f->mtx); return; } werase(stdscr); f->root->type->f_draw(f->root, f, stdscr); if (timeout == -1 && f->root->cur_y != -1 && f->root->cur_x != -1) { wmove(stdscr, f->root->cur_y, f->root->cur_x); } refresh(); if (timeout < 0) { pthread_mutex_unlock(&f->mtx); return; } wtimeout(stdscr, timeout == 0 ? -1 : timeout); wmove(stdscr, f->cursor_y, f->cursor_x); wint_t wch; pthread_mutex_unlock(&f->mtx); int rc = wget_wch(stdscr, &wch); pthread_mutex_lock(&f->mtx); /* fw may be invalid, regather it */ fw = stfl_gather_focus_widget(f); f->current_focus_id = fw ? fw->id : 0; struct stfl_widget *w = fw; if (rc == ERR) { stfl_form_event(f, compat_wcsdup(L"TIMEOUT")); goto unshift_next_event; } wchar_t *on_event = stfl_keyname(wch, rc == KEY_CODE_YES); int on_handler_len = wcslen(on_event) + 4; on_handler = malloc(on_handler_len * sizeof(wchar_t)); swprintf(on_handler, on_handler_len, L"on_%ls", on_event); free(on_event); while (w) { const wchar_t *event = stfl_widget_getkv_str(w, on_handler, 0); if (event) { stfl_form_event(f, compat_wcsdup(event)); goto unshift_next_event; } if (w->type->f_process && stfl_widget_getkv_int(w, L"process", 1) && w->type->f_process(w, fw, f, wch, rc == KEY_CODE_YES)) goto unshift_next_event; if (stfl_widget_getkv_int(w, L"modal", 0)) goto generate_event; w = w->parent; } if (rc != KEY_CODE_YES && wch == L'\t') { struct stfl_widget *old_fw = fw = stfl_widget_by_id(f->root, f->current_focus_id); if (!fw) goto generate_event; do { if (fw->first_child) fw = fw->first_child; else if (fw->next_sibling) fw = fw->next_sibling; else { while (fw->parent && !fw->parent->next_sibling) fw = fw->parent; fw = fw->parent ? fw->parent->next_sibling : 0; } if (!fw && old_fw) fw = f->root; } while (fw && !(fw->allow_focus && stfl_widget_getkv_int(fw, L"can_focus", 1))); if (old_fw != fw) { if (old_fw && old_fw->type->f_leave) old_fw->type->f_leave(old_fw, f); if (fw && fw->type->f_enter) fw->type->f_enter(fw, f); f->current_focus_id = fw ? fw->id : 0; } goto unshift_next_event; } else if (rc == KEY_CODE_YES && wch == KEY_BTAB) { struct stfl_widget *old_fw = stfl_widget_by_id(f->root, f->current_focus_id); struct stfl_widget *tmp_fw = f->root; struct stfl_widget *fw = 0; focus_wrap_around: while (tmp_fw && tmp_fw != old_fw) { if (tmp_fw->allow_focus && stfl_widget_getkv_int(tmp_fw, L"can_focus", 1)) fw = tmp_fw; if (tmp_fw->first_child) tmp_fw = tmp_fw->first_child; else if (tmp_fw->next_sibling) tmp_fw = tmp_fw->next_sibling; else { while (tmp_fw->parent && !tmp_fw->parent->next_sibling) tmp_fw = tmp_fw->parent; tmp_fw = tmp_fw->parent ? tmp_fw->parent->next_sibling : 0; } } if (!fw && old_fw) { old_fw = f->root->last_child; goto focus_wrap_around; } if (fw && old_fw != fw) { if (old_fw && old_fw->type->f_leave) old_fw->type->f_leave(old_fw, f); if (fw && fw->type->f_enter) fw->type->f_enter(fw, f); f->current_focus_id = fw ? fw->id : 0; } goto unshift_next_event; } generate_event: stfl_form_event(f, stfl_keyname(wch, rc == KEY_CODE_YES)); unshift_next_event:; struct stfl_event *e = f->event_queue; if (e) { f->event_queue = e->next; f->event = e->event; free(e); } pthread_mutex_unlock(&f->mtx); free(on_handler); }
NCURSES_EXPORT(int) (get_wch) (wint_t * z) { T((T_CALLED("get_wch(%p)"), (const void *)z)); returnCode(wget_wch(stdscr,z)); }
wgetn_wstr(WINDOW *win, wint_t *str, int maxlen) { SCREEN *sp = _nc_screen_of(win); TTY buf; bool oldnl, oldecho, oldraw, oldcbreak; wint_t erasec; wint_t killc; wint_t *oldstr = str; wint_t *tmpstr = str; wint_t ch; int y, x, code; T((T_CALLED("wgetn_wstr(%p,%p, %d)"), win, str, maxlen)); if (!win) returnCode(ERR); _nc_get_tty_mode(&buf); oldnl = sp->_nl; oldecho = sp->_echo; oldraw = sp->_raw; oldcbreak = sp->_cbreak; nl(); noecho(); noraw(); cbreak(); erasec = (wint_t) erasechar(); killc = (wint_t) killchar(); getyx(win, y, x); if (is_wintouched(win) || (win->_flags & _HASMOVED)) wrefresh(win); while ((code = wget_wch(win, &ch)) != ERR) { /* * Map special characters into key-codes. */ if (ch == '\r') ch = '\n'; if (ch == '\n') { code = KEY_CODE_YES; ch = KEY_ENTER; } if (ch < KEY_MIN) { if (ch == erasec) { ch = KEY_BACKSPACE; code = KEY_CODE_YES; } if (ch == killc) { ch = KEY_EOL; code = KEY_CODE_YES; } } if (code == KEY_CODE_YES) { /* * Some terminals (the Wyse-50 is the most common) generate a \n * from the down-arrow key. With this logic, it's the user's * choice whether to set kcud=\n for wget_wch(); terminating * *getn_wstr() with \n should work either way. */ if (ch == KEY_DOWN || ch == KEY_ENTER) { if (oldecho == TRUE && win->_cury == win->_maxy && win->_scroll) wechochar(win, (chtype) '\n'); break; } if (ch == KEY_LEFT || ch == KEY_BACKSPACE) { if (tmpstr > oldstr) { tmpstr = WipeOut(win, y, x, oldstr, tmpstr, oldecho); } } else if (ch == KEY_EOL) { while (tmpstr > oldstr) { tmpstr = WipeOut(win, y, x, oldstr, tmpstr, oldecho); } } else { beep(); } } else if (maxlen >= 0 && tmpstr - oldstr >= maxlen) { beep(); } else { *tmpstr++ = ch; *tmpstr = 0; if (oldecho == TRUE) { int oldy = win->_cury; if (wadd_wint(win, tmpstr - 1) == ERR) { /* * We can't really use the lower-right corner for input, * since it'll mess up bookkeeping for erases. */ win->_flags &= ~_WRAPPED; waddch(win, (chtype) ' '); tmpstr = WipeOut(win, y, x, oldstr, tmpstr, oldecho); continue; } else if (win->_flags & _WRAPPED) { /* * If the last waddch forced a wrap & scroll, adjust our * reference point for erasures. */ if (win->_scroll && oldy == win->_maxy && win->_cury == win->_maxy) { if (--y <= 0) { y = 0; } } win->_flags &= ~_WRAPPED; } wrefresh(win); } } } win->_curx = 0; win->_flags &= ~_WRAPPED; if (win->_cury < win->_maxy) win->_cury++; wrefresh(win); /* Restore with a single I/O call, to fix minor asymmetry between * raw/noraw, etc. */ sp->_nl = oldnl; sp->_echo = oldecho; sp->_raw = oldraw; sp->_cbreak = oldcbreak; (void) _nc_set_tty_mode(&buf); *tmpstr = 0; if (code == ERR) { if (tmpstr == oldstr) { *tmpstr++ = WEOF; *tmpstr = 0; } returnCode(ERR); } T(("wgetn_wstr returns %s", _nc_viswibuf(oldstr))); returnCode(OK); }
/* * ekg_getch() * * czeka na wci¶niêcie klawisza i je¶li wkompilowano obs³ugê pythona, * przekazuje informacjê o zdarzeniu do skryptu. * * - meta - przedrostek klawisza. * * @returns: * -2 - ignore that key * ERR - error * OK - report a (wide) character * KEY_CODE_YES - report the pressing of a function key * */ static int ekg_getch(int meta, unsigned int *ch) { int retcode; #if USE_UNICODE retcode = wget_wch(input, ch); #else *ch = wgetch(input); retcode = *ch >= KEY_MIN ? KEY_CODE_YES : OK; #endif if (retcode == ERR) return ERR; if ((retcode == KEY_CODE_YES) && (*(int *)ch == -1)) return ERR; /* Esc (delay) no key */ #ifndef HAVE_USABLE_TERMINFO /* Debian screen incomplete terminfo workaround */ if (mouse_initialized == 2 && *ch == 27) { /* escape */ int tmp; if ((tmp = wgetch(input)) != '[') ungetch(tmp); else if ((tmp = wgetch(input)) != 'M') { ungetch(tmp); ungetch('['); } else *ch = KEY_MOUSE; } #endif /* * conception is borrowed from Midnight Commander project * (www.ibiblio.org/mc/) */ #define GET_TIME(tv) (g_get_current_time(&tv)) #define DIF_TIME(t1,t2) ((t2.tv_sec -t1.tv_sec) *1000+ \ (t2.tv_usec-t1.tv_usec)/1000) if (*ch == KEY_MOUSE) { int btn, mouse_state = 0, x, y; static GTimeVal tv1 = { 0, 0 }; static GTimeVal tv2; static int clicks; static int last_btn = 0; btn = wgetch (input) - 32; if (btn == 3 && last_btn) { last_btn -= 32; switch (last_btn) { case 0: mouse_state = (clicks) ? EKG_BUTTON1_DOUBLE_CLICKED : EKG_BUTTON1_CLICKED; break; case 1: mouse_state = (clicks) ? EKG_BUTTON2_DOUBLE_CLICKED : EKG_BUTTON2_CLICKED; break; case 2: mouse_state = (clicks) ? EKG_BUTTON3_DOUBLE_CLICKED : EKG_BUTTON3_CLICKED; break; case 64: mouse_state = EKG_SCROLLED_UP; break; case 65: mouse_state = EKG_SCROLLED_DOWN; break; default: break; } last_btn = 0; GET_TIME (tv1); clicks = 0; } else if (!last_btn) { GET_TIME (tv2); if (tv1.tv_sec && (DIF_TIME (tv1,tv2) < 250)){ clicks++; clicks %= 3; } else clicks = 0; switch (btn) { case 0: case 1: case 2: case 64: case 65: btn += 32; break; default: btn = 0; break; } last_btn = btn; } else { switch (btn) { case 64: mouse_state = EKG_SCROLLED_UP; break; case 65: mouse_state = EKG_SCROLLED_DOWN; break; } } /* 33 based */ x = wgetch(input) - 32; y = wgetch(input) - 32; /* XXX query_emit UI_MOUSE ??? */ if (mouse_state) ncurses_mouse_clicked_handler(x, y, mouse_state); } #undef GET_TIME #undef DIF_TIME if (query_emit(NULL, "ui-keypress", ch) == -1) return -2; /* -2 - ignore that key */ return retcode; }
/** * Read user input. * * @param prompt Prompt * @return The read line (dynamically allocated) or NULL */ char * readline(const char *prompt) { char *out; const int sleep_time_milliseconds = 90; volatile struct readline_session_context *ctx; wchar_t *buf_p = &g_push_back_buf[0]; ctx = new_session(prompt); if (setjmp(g_readline_loc_info) != 0) { session_destroy(ctx); mutex_unlock(&g_puts_mutex); return NULL; } g_readline_loop = true; g_resize_requested = false; g_hist_next = false; g_hist_prev = false; mutex_lock(&g_puts_mutex); write_cmdprompt(ctx->act, ctx->prompt, ctx->prompt_size); mutex_unlock(&g_puts_mutex); do { wint_t wc; ctx->insert_mode = (ctx->bufpos != ctx->n_insert); ctx->no_bufspc = (ctx->n_insert + 1 >= readline_buffersize); if (*buf_p) { wc = *buf_p++; } else if (wget_wch(ctx->act, &wc) == ERR) { (void) napms(sleep_time_milliseconds); continue; } mutex_lock(&g_puts_mutex); switch (wc) { case CTRL_A: while (ctx->bufpos != 0) { case_key_left(ctx); ctx->insert_mode = (ctx->bufpos != ctx->n_insert); } break; case CTRL_E: while (ctx->insert_mode) { case_key_right(ctx); ctx->insert_mode = (ctx->bufpos != ctx->n_insert); } break; case MY_KEY_DLE: window_select_prev(); break; /* CTRL+P */ case MY_KEY_SO: window_select_next(); break; /* CTRL+N */ case KEY_DOWN: g_hist_next = true; session_destroy(ctx); mutex_unlock(&g_puts_mutex); return NULL; case KEY_UP: g_hist_prev = true; session_destroy(ctx); mutex_unlock(&g_puts_mutex); return NULL; case KEY_LEFT: case MY_KEY_STX: case_key_left(ctx); break; case KEY_RIGHT: case MY_KEY_ACK: case_key_right(ctx); break; case KEY_BACKSPACE: case MY_KEY_BS: case_key_backspace(ctx); break; case KEY_F(5): case BLINK: handle_key(ctx, btowc(BLINK)); break; case KEY_F(6): case BOLD_ALIAS: handle_key(ctx, btowc(BOLD)); break; case KEY_F(7): case COLOR: handle_key(ctx, btowc(COLOR)); break; case KEY_F(8): case NORMAL: handle_key(ctx, btowc(NORMAL)); break; case KEY_F(9): case REVERSE: handle_key(ctx, btowc(REVERSE)); break; case KEY_F(10): case UNDERLINE: handle_key(ctx, btowc(UNDERLINE)); break; case KEY_F(11): cmd_close(""); break; case KEY_F(12): window_close_all_priv_conv(); break; case KEY_DC: case MY_KEY_EOT: case_key_dc(ctx); break; case KEY_NPAGE: window_scroll_down(g_active_window); break; case KEY_PPAGE: window_scroll_up(g_active_window); break; case '\t': break; case '\n': case KEY_ENTER: case WINDOWS_KEY_ENTER: g_readline_loop = false; break; case KEY_RESIZE: case MY_KEY_RESIZE: g_resize_requested = true; /*FALLTHROUGH*/ case '\a': session_destroy(ctx); mutex_unlock(&g_puts_mutex); return NULL; default: if (iswprint(wc)) { handle_key(ctx, wc); } break; } mutex_unlock(&g_puts_mutex); } while (g_readline_loop); if (ctx->n_insert > 0) { ctx->buffer[ctx->n_insert] = 0L; } else { session_destroy(ctx); return NULL; } mutex_lock(&g_puts_mutex); write_cmdprompt(ctx->act, "", 0); mutex_unlock(&g_puts_mutex); out = finalize_out_string(ctx->buffer); session_destroy(ctx); return out; }
int Input::wait(Session &sess) { const int KEY_ESC = 27; const int KEY_BS = 127; const int KEY_TAB = 9; const int KEY_ENT = 10; wint_t c; MEVENT event; #if NCURSES_MOUSE_VERSION > 1 mousemask(BUTTON3_PRESSED | BUTTON4_PRESSED | BUTTON5_PRESSED, NULL); #else mousemask(BUTTON3_PRESSED, NULL); #endif int& col = sess.col; std::wstring& input_str = sess.input_str; // check if we reached maximum string length if (input_str.length() == 1000) { return 0; } wget_wch(win, &c); switch (c) { case KEY_ESC: // ESC to quit; case KEY_TAB: // tab to switch to roster selection mode case KEY_UP: // go back in chat history case KEY_DOWN: // go forward in chat history case KEY_MOUSE: if (getmouse(&event) == OK) { if (event.bstate & BUTTON3_PRESSED) { c = KEY_TAB; } #if NCURSES_MOUSE_VERSION > 1 /* scroll up and down events associated with mouse wheel */ else if (event.bstate & BUTTON4_PRESSED) { c = KEY_UP; } else if (event.bstate & BUTTON5_PRESSED) { c = KEY_DOWN; } #endif } return c; case KEY_BS: if (!input_str.empty() && col > 0) { col--; input_str.erase(col, 1); fixed_print_input(input_str, col); } break; case KEY_DC: if (!input_str.empty() && col < input_str.length()) { input_str.erase(col, 1); fixed_print_input(input_str, col); } break; case KEY_RIGHT: if (col < input_str.length()) { col++; highlight(col); } break; case KEY_LEFT: if (col > 0) { col--; highlight(col); } break; case KEY_ENT: col = 0; client->send_message(input_str); input_str.clear(); fixed_print_input(input_str, 1); break; default: if (iswprint(c)) { input_str.insert(col, 1, c); col++; fixed_print_input(input_str, col); } break; } return 0; }
/* * __wgetn_wstr -- * The actual implementation. * Note that we include a trailing L'\0' for safety, so str will contain * at most n - 1 other characters. */ int __wgetn_wstr(WINDOW *win, wchar_t *wstr, int n) { wchar_t *ostr, ec, kc, sc[ 2 ]; int oldx, remain; wint_t wc; cchar_t cc; ostr = wstr; if ( erasewchar( &ec ) == ERR ) return ERR; if ( killwchar( &kc ) == ERR ) return ERR; sc[ 0 ] = ( wchar_t )btowc( ' ' ); sc[ 1 ] = L'\0'; setcchar( &cc, sc, win->wattr, 0, NULL ); oldx = win->curx; remain = n - 1; while (wget_wch(win, &wc) != ERR && wc != L'\n' && wc != L'\r') { #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "__wgetn_wstr: win %p, char 0x%x, remain %d\n", win, wc, remain); #endif *wstr = wc; touchline(win, win->cury, 1); if (wc == ec || wc == KEY_BACKSPACE || wc == KEY_LEFT) { *wstr = L'\0'; if (wstr != ostr) { if ((wchar_t)wc == ec) { mvwadd_wch(win, win->cury, win->curx, &cc); wmove(win, win->cury, win->curx - 1); } if (wc == KEY_BACKSPACE || wc == KEY_LEFT) { /* getch() displays the key sequence */ mvwadd_wch(win, win->cury, win->curx - 1, &cc); mvwadd_wch(win, win->cury, win->curx - 2, &cc); wmove(win, win->cury, win->curx - 1); } wstr--; if (n != -1) { /* We're counting chars */ remain++; } } else { /* str == ostr */ if (wc == KEY_BACKSPACE || wc == KEY_LEFT) /* getch() displays the other keys */ mvwadd_wch(win, win->cury, win->curx - 1, &cc); wmove(win, win->cury, oldx); } } else if (wc == kc) { *wstr = L'\0'; if (wstr != ostr) { /* getch() displays the kill character */ mvwadd_wch(win, win->cury, win->curx - 1, &cc); /* Clear the characters from screen and str */ while (wstr != ostr) { mvwadd_wch(win, win->cury, win->curx - 1, &cc); wmove(win, win->cury, win->curx - 1); wstr--; if (n != -1) /* We're counting chars */ remain++; } mvwadd_wch(win, win->cury, win->curx - 1, &cc); wmove(win, win->cury, win->curx - 1); } else /* getch() displays the kill character */ mvwadd_wch( win, win->cury, oldx, &cc ); wmove(win, win->cury, oldx); } else if (wc >= KEY_MIN && wc <= KEY_MAX) { /* get_wch() displays these characters */ mvwadd_wch( win, win->cury, win->curx - 1, &cc ); wmove(win, win->cury, win->curx - 1); } else { if (remain) { wstr++; remain--; } else { mvwadd_wch(win, win->cury, win->curx - 1, &cc); wmove(win, win->cury, win->curx - 1); } } } if (wc == ERR) { *wstr = L'\0'; return ERR; } *wstr = L'\0'; return OK; }
/* * Main Loop * Everything is driven from this function with the exception of * signals which are handled in signals.c */ void main_loop(void) { LOG_FUNC_ENTER; int last_result = 0; int wait_enter = 0; int timeout = cfg.timeout_len; buf[0] = L'\0'; while(1) { wchar_t c; size_t counter; int ret; is_term_working(); #ifdef _WIN32 update_win_console(); #endif lwin.user_selection = 1; rwin.user_selection = 1; if(curr_stats.too_small_term > 0) { touchwin(stdscr); wrefresh(stdscr); mvwin(status_bar, 0, 0); wresize(status_bar, getmaxy(stdscr), getmaxx(stdscr)); werase(status_bar); waddstr(status_bar, "Terminal is too small for vifm"); touchwin(status_bar); wrefresh(status_bar); #ifndef _WIN32 pause(); #endif continue; } else if(curr_stats.too_small_term < 0) { wtimeout(status_bar, 0); while(wget_wch(status_bar, (wint_t*)&c) != ERR); curr_stats.too_small_term = 0; modes_redraw(); wtimeout(status_bar, cfg.timeout_len); wait_enter = 0; curr_stats.save_msg = 0; status_bar_message(""); } modes_pre(); /* This waits for timeout then skips if no keypress. */ ret = read_char(status_bar, (wint_t*)&c, timeout); /* Ensure that current working directory is set correctly (some pieces of * code rely on this). */ (void)vifm_chdir(curr_view->curr_dir); if(ret != ERR && pos != ARRAY_LEN(buf) - 2) { if(c == L'\x1a') /* Ctrl-Z */ { def_prog_mode(); endwin(); #ifndef _WIN32 { void (*saved_stp_sig_handler)(int) = signal(SIGTSTP, SIG_DFL); kill(0, SIGTSTP); signal(SIGTSTP, saved_stp_sig_handler); } #endif continue; } if(wait_enter) { wait_enter = 0; curr_stats.save_msg = 0; clean_status_bar(); if(c == L'\x0d') continue; } buf[pos++] = c; buf[pos] = L'\0'; } if(wait_enter && ret == ERR) continue; counter = get_key_counter(); if(ret == ERR && last_result == KEYS_WAIT_SHORT) { last_result = execute_keys_timed_out(buf); counter = get_key_counter() - counter; assert(counter <= pos); if(counter > 0) { memmove(buf, buf + counter, (wcslen(buf) - counter + 1)*sizeof(wchar_t)); } } else { if(ret != ERR) curr_stats.save_msg = 0; last_result = execute_keys(buf); counter = get_key_counter() - counter; assert(counter <= pos); if(counter > 0) { pos -= counter; memmove(buf, buf + counter, (wcslen(buf) - counter + 1)*sizeof(wchar_t)); } if(last_result == KEYS_WAIT || last_result == KEYS_WAIT_SHORT) { if(ret != ERR) modupd_input_bar(buf); if(last_result == KEYS_WAIT_SHORT && wcscmp(buf, L"\033") == 0) timeout = 1; if(counter > 0) clear_input_bar(); if(!curr_stats.save_msg && curr_view->selected_files && get_mode() != CMDLINE_MODE) print_selected_msg(); continue; } } timeout = cfg.timeout_len; process_scheduled_updates(); pos = 0; buf[0] = L'\0'; clear_input_bar(); if(is_status_bar_multiline()) { wait_enter = 1; update_all_windows(); continue; } /* Ensure that current working directory is set correctly (some pieces of * code rely on this). PWD could be changed during command execution, but * it should be correct for modes_post() in case of preview modes. */ (void)vifm_chdir(curr_view->curr_dir); modes_post(); } }
int get_wch(wint_t *wch) { PDC_LOG(("get_wch() - called\n")); return wget_wch(stdscr, wch); }
NCURSES_EXPORT(int) (mvget_wch) (int a1, int a2, wint_t * z) { T((T_CALLED("mvget_wch(%d,%d,%p)"), a1, a2, (const void *)z)); returnCode((wmove(stdscr,a1,a2) == (-1) ? (-1) : wget_wch(stdscr,z))); }