diff options
Diffstat (limited to 'Build/source/utils/dialog/dialog-1.1-20110118/ui_getc.c')
-rw-r--r-- | Build/source/utils/dialog/dialog-1.1-20110118/ui_getc.c | 604 |
1 files changed, 0 insertions, 604 deletions
diff --git a/Build/source/utils/dialog/dialog-1.1-20110118/ui_getc.c b/Build/source/utils/dialog/dialog-1.1-20110118/ui_getc.c deleted file mode 100644 index 5527bd5dd69..00000000000 --- a/Build/source/utils/dialog/dialog-1.1-20110118/ui_getc.c +++ /dev/null @@ -1,604 +0,0 @@ -/* - * $Id: ui_getc.c,v 1.58 2011/01/18 10:41:01 tom Exp $ - * - * ui_getc.c - user interface glue for getc() - * - * Copyright 2001-2010,2011 Thomas E. Dickey - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License, version 2.1 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to - * Free Software Foundation, Inc. - * 51 Franklin St., Fifth Floor - * Boston, MA 02110, USA. - */ - -#include <dialog.h> -#include <dlg_keys.h> - -#ifdef NEED_WCHAR_H -#include <wchar.h> -#endif - -#if TIME_WITH_SYS_TIME -# include <sys/time.h> -# include <time.h> -#else -# if HAVE_SYS_TIME_H -# include <sys/time.h> -# else -# include <time.h> -# endif -#endif - -#ifdef HAVE_SYS_WAIT_H -#include <sys/wait.h> -#endif - -#ifdef __QNX__ -#include <sys/select.h> -#endif - -#ifndef WEXITSTATUS -# ifdef HAVE_TYPE_UNIONWAIT -# define WEXITSTATUS(status) (status.w_retcode) -# else -# define WEXITSTATUS(status) (((status) & 0xff00) >> 8) -# endif -#endif - -#ifndef WTERMSIG -# ifdef HAVE_TYPE_UNIONWAIT -# define WTERMSIG(status) (status.w_termsig) -# else -# define WTERMSIG(status) ((status) & 0x7f) -# endif -#endif - -void -dlg_add_callback(DIALOG_CALLBACK * p) -{ - p->next = dialog_state.getc_callbacks; - dialog_state.getc_callbacks = p; - wtimeout(p->win, WTIMEOUT_VAL); -} - -/* - * Like dlg_add_callback(), but providing for cleanup of caller's associated - * state. - */ -void -dlg_add_callback_ref(DIALOG_CALLBACK ** p, DIALOG_FREEBACK freeback) -{ - (*p)->caller = p; - (*p)->freeback = freeback; - dlg_add_callback(*p); -} - -void -dlg_remove_callback(DIALOG_CALLBACK * p) -{ - DIALOG_CALLBACK *q; - - if (p->input != 0) { - fclose(p->input); - if (p->input == dialog_state.pipe_input) - dialog_state.pipe_input = 0; - p->input = 0; - } - - if (!(p->keep_win)) - dlg_del_window(p->win); - if ((q = dialog_state.getc_callbacks) == p) { - dialog_state.getc_callbacks = p->next; - } else { - while (q != 0) { - if (q->next == p) { - q->next = p->next; - break; - } - q = q->next; - } - } - - /* handle dlg_add_callback_ref cleanup */ - if (p->freeback != 0) - p->freeback(p); - if (p->caller != 0) - *(p->caller) = 0; - - free(p); -} - -/* - * A select() might find more than one input ready for service. Handle them - * all. - */ -static bool -handle_inputs(WINDOW *win) -{ - bool result = FALSE; - DIALOG_CALLBACK *p; - DIALOG_CALLBACK *q; - int cur_y, cur_x; - int state = ERR; - - getyx(win, cur_y, cur_x); - for (p = dialog_state.getc_callbacks, q = 0; p != 0; p = q) { - q = p->next; - if ((p->handle_input != 0) && p->input_ready) { - p->input_ready = FALSE; - if (state == ERR) { - state = curs_set(0); - } - if (p->handle_input(p)) { - result = TRUE; - } - } - } - if (result) { - (void) wmove(win, cur_y, cur_x); /* Restore cursor position */ - wrefresh(win); - curs_set(state); - } - return result; -} - -static bool -may_handle_inputs(void) -{ - bool result = FALSE; - - DIALOG_CALLBACK *p; - - for (p = dialog_state.getc_callbacks; p != 0; p = p->next) { - if (p->input != 0) { - result = TRUE; - break; - } - } - - return result; -} - -/* - * Check any any inputs registered via callbacks, to see if there is any input - * available. If there is, return a file-descriptor which should be read. - * Otherwise, return -1. - */ -static int -check_inputs(void) -{ - DIALOG_CALLBACK *p; - fd_set read_fds; - struct timeval test; - int last_fd = -1; - int fd; - int found; - int result = -1; - - if ((p = dialog_state.getc_callbacks) != 0) { - FD_ZERO(&read_fds); - - while (p != 0) { - p->input_ready = FALSE; - if (p->input != 0 && (fd = fileno(p->input)) >= 0) { - FD_SET(fd, &read_fds); - if (last_fd < fd) - last_fd = fd; - } - p = p->next; - } - - test.tv_sec = 0; - test.tv_usec = WTIMEOUT_VAL * 1000; - found = select(last_fd + 1, &read_fds, - (fd_set *) 0, - (fd_set *) 0, - &test); - - if (found > 0) { - for (p = dialog_state.getc_callbacks; p != 0; p = p->next) { - if (p->input != 0 - && (fd = fileno(p->input)) >= 0 - && FD_ISSET(fd, &read_fds)) { - p->input_ready = TRUE; - result = fd; - } - } - } - } - - return result; -} - -int -dlg_getc_callbacks(int ch, int fkey, int *result) -{ - int code = FALSE; - DIALOG_CALLBACK *p, *q; - - if ((p = dialog_state.getc_callbacks) != 0) { - if (check_inputs() >= 0) { - do { - q = p->next; - if (p->input_ready) { - if (!(p->handle_getc(p, ch, fkey, result))) { - dlg_remove_callback(p); - } - } - } while ((p = q) != 0); - } - code = (dialog_state.getc_callbacks != 0); - } - return code; -} - -static void -dlg_raise_window(WINDOW *win) -{ - touchwin(win); - wmove(win, getcury(win), getcurx(win)); - wnoutrefresh(win); - doupdate(); -} - -/* - * This is a work-around for the case where we actually need the wide-character - * code versus a byte stream. - */ -static int last_getc = ERR; - -#ifdef USE_WIDE_CURSES -static char last_getc_bytes[80]; -static int have_last_getc; -static int used_last_getc; -#endif - -int -dlg_last_getc(void) -{ -#ifdef USE_WIDE_CURSES - if (used_last_getc != 1) - return ERR; /* not really an error... */ -#endif - return last_getc; -} - -void -dlg_flush_getc(void) -{ - last_getc = ERR; -#ifdef USE_WIDE_CURSES - have_last_getc = 0; - used_last_getc = 0; -#endif -} - -/* - * Check if the stream has been unexpectedly closed, returning false in that - * case. - */ -static bool -valid_file(FILE *fp) -{ - bool code = FALSE; - int fd = fileno(fp); - - if (fd >= 0) { - long result = 0; - if ((result = fcntl(fd, F_GETFL, 0)) >= 0) { - code = TRUE; - } - } - return code; -} - -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 DIALOG_CALLBACK * -next_callback(DIALOG_CALLBACK * p) -{ - if ((p = dialog_state.getc_redirect) != 0) { - p = p->next; - } else { - p = dialog_state.getc_callbacks; - } - return p; -} - -static DIALOG_CALLBACK * -prev_callback(DIALOG_CALLBACK * p) -{ - DIALOG_CALLBACK *q; - - if ((p = dialog_state.getc_redirect) != 0) { - if (p == dialog_state.getc_callbacks) { - for (p = dialog_state.getc_callbacks; p->next != 0; p = p->next) ; - } else { - for (q = dialog_state.getc_callbacks; q->next != p; q = q->next) ; - p = q; - } - } else { - p = dialog_state.getc_callbacks; - } - return p; -} - -/* - * 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_lookup; - int result; - bool done = FALSE; - bool literal = FALSE; - DIALOG_CALLBACK *p = 0; - int interval = dialog_vars.timeout_secs; - 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) { - /* - * If there was no pending file-input, check the keyboard. - */ - ch = really_getch(win, fkey); - if (literal) { - done = TRUE; - continue; - } - - before_lookup = ch; - ch = dlg_lookup_key(win, ch, fkey); - dlg_trace_chr(ch, *fkey); - - current = time((time_t *) 0); - - switch (ch) { - case CHR_LITERAL: - if (!literal) { - literal = TRUE; - keypad(win, FALSE); - continue; - } - break; - 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_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 && - (before_lookup == TAB || - before_lookup == KEY_BTAB)) { - if (before_lookup == TAB) - p = next_callback(p); - else - 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 (before_lookup == DLG_CTRL('P')) { - /* for testing, ^P closes the connection */ - close(0); - close(1); - close(2); - break; - } -#endif - if ((p = dialog_state.getc_redirect) != 0) { - if (!(p->handle_getc(p, ch, *fkey, &result))) { - dlg_remove_callback(p); - dialog_state.getc_redirect = 0; - win = save_win; - } - } else { - done = TRUE; - } - break; -#ifdef HAVE_DLG_TRACE - case CHR_TRACE: - dlg_trace_win(win); - break; -#endif - } - } - if (literal) - keypad(win, TRUE); - return ch; -} - -static void -finish_bg(int sig GCC_UNUSED) -{ - end_dialog(); - dlg_exit(DLG_EXIT_ERROR); -} - -/* - * If we have callbacks active, purge the list of all that are not marked - * to keep in the background. If any remain, run those in a background - * process. - */ -void -dlg_killall_bg(int *retval) -{ - DIALOG_CALLBACK *cb; - int pid; -#ifdef HAVE_TYPE_UNIONWAIT - union wait wstatus; -#else - int wstatus; -#endif - - if ((cb = dialog_state.getc_callbacks) != 0) { - while (cb != 0) { - if (cb->keep_bg) { - cb = cb->next; - } else { - dlg_remove_callback(cb); - cb = dialog_state.getc_callbacks; - } - } - if (dialog_state.getc_callbacks != 0) { - - refresh(); - fflush(stdout); - fflush(stderr); - reset_shell_mode(); - if ((pid = fork()) != 0) { - _exit(pid > 0 ? DLG_EXIT_OK : DLG_EXIT_ERROR); - } else if (pid == 0) { /* child */ - if ((pid = fork()) != 0) { - /* - * Echo the process-id of the grandchild so a shell script - * can read that, and kill that process. We'll wait around - * until then. Our parent has already left, leaving us - * temporarily orphaned. - */ - if (pid > 0) { /* parent */ - fprintf(stderr, "%d\n", pid); - fflush(stderr); - } - /* wait for child */ -#ifdef HAVE_WAITPID - while (-1 == waitpid(pid, &wstatus, 0)) { -#ifdef EINTR - if (errno == EINTR) - continue; -#endif /* EINTR */ -#ifdef ERESTARTSYS - if (errno == ERESTARTSYS) - continue; -#endif /* ERESTARTSYS */ - break; - } -#else - while (wait(&wstatus) != pid) /* do nothing */ - ; -#endif - _exit(WEXITSTATUS(wstatus)); - } else if (pid == 0) { - if (!dialog_vars.cant_kill) - (void) signal(SIGHUP, finish_bg); - (void) signal(SIGINT, finish_bg); - (void) signal(SIGQUIT, finish_bg); - (void) signal(SIGSEGV, finish_bg); - while (dialog_state.getc_callbacks != 0) { - int fkey = 0; - dlg_getc_callbacks(ERR, fkey, retval); - napms(1000); - } - } - } - } - } -} |