/* * Read a character from the given window. Handle repainting here (to simplify * things in the calling application). Also, if input-callback(s) are set up, * poll the corresponding files and handle the updates, e.g., for displaying a * tailbox. */ int dlg_getc(WINDOW *win, int *fkey) { WINDOW *save_win = win; int ch = ERR; int before_chr; int before_fkey; int result; bool done = FALSE; bool literal = FALSE; DIALOG_CALLBACK *p = 0; int interval = (dialog_vars.timeout_secs * 1000); time_t expired = time((time_t *) 0) + dialog_vars.timeout_secs; time_t current; if (may_handle_inputs()) wtimeout(win, WTIMEOUT_VAL); else if (interval > 0) wtimeout(win, interval); while (!done) { bool handle_others = FALSE; /* * If there was no pending file-input, check the keyboard. */ ch = really_getch(win, fkey); if (literal) { done = TRUE; continue; } before_chr = ch; before_fkey = *fkey; ch = dlg_lookup_key(win, ch, fkey); dlg_trace_chr(ch, *fkey); current = time((time_t *) 0); /* * If we acquired a fkey value, then it is one of dialog's builtin * codes such as DLGK_HELPFILE. */ if (!*fkey || *fkey != before_fkey) { switch (ch) { case CHR_LITERAL: literal = TRUE; keypad(win, FALSE); continue; case CHR_REPAINT: (void) touchwin(win); (void) wrefresh(curscr); break; case ERR: /* wtimeout() in effect; check for file I/O */ if (interval > 0 && current >= expired) { dlg_exiterr("timeout"); } if (!valid_file(stdin) || !valid_file(dialog_state.screen_output)) { ch = ESC; done = TRUE; } else if (check_inputs()) { if (handle_inputs(win)) dlg_raise_window(win); else done = TRUE; } else { done = (interval <= 0); } break; case DLGK_HELPFILE: if (dialog_vars.help_file) { int yold, xold; getyx(win, yold, xold); dialog_helpfile("HELP", dialog_vars.help_file, 0, 0); dlg_raise_window(win); wmove(win, yold, xold); } continue; case DLGK_FIELD_PREV: /* FALLTHRU */ case KEY_BTAB: /* FALLTHRU */ case DLGK_FIELD_NEXT: /* FALLTHRU */ case TAB: /* Handle tab/backtab as a special case for traversing between * the nominal "current" window, and other windows having * callbacks. If the nominal (control) window closes, we'll * close the windows with callbacks. */ if (dialog_state.getc_callbacks != 0 && (isBeforeChr(TAB) || isBeforeFkey(KEY_BTAB))) { p = (isBeforeChr(TAB) ? next_callback(p) : prev_callback(p)); if ((dialog_state.getc_redirect = p) != 0) { win = p->win; } else { win = save_win; } dlg_raise_window(win); break; } /* FALLTHRU */ default: #ifdef NO_LEAKS if (isBeforeChr(DLG_CTRL('P'))) { /* for testing, ^P closes the connection */ close(0); close(1); close(2); break; } #endif handle_others = TRUE; break; #ifdef HAVE_DLG_TRACE case CHR_TRACE: dlg_trace_win(win); break; #endif } } else { handle_others = TRUE; } if (handle_others) { if ((p = dialog_state.getc_redirect) != 0) { if (!(p->handle_getc(p, ch, *fkey, &result))) { done = (p->win == save_win) && (!p->keep_win); dlg_remove_callback(p); dialog_state.getc_redirect = 0; win = save_win; } } else { done = TRUE; } } } if (literal) keypad(win, TRUE); return ch; }
void File_Browser::_prev_callback() { prev_callback(true); }