/* elmo - ELectronic Mail Operator Copyright (C) 2002, 2003, 2004 rzyjontko This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2. 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ---------------------------------------------------------------------- handles command loop */ /**************************************************************************** * IMPLEMENTATION HEADERS ****************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include "ecurses.h" #include "cmd.h" #include "status.h" #include "folder.h" #include "mailreader.h" #include "error.h" #include "elmo.h" #include "box_selection.h" #include "xmalloc.h" #include "fetch.h" #include "confread.h" #include "compose.h" #include "sender.h" #include "attach.h" #include "abook.h" #include "read.h" #include "exec.h" #include "keymap.h" #include "hook.h" #include "choose.h" #include "ask.h" #include "bayes.h" #include "gettext.h" #include "help.h" #include "color.h" #include "interface.h" #include "debug.h" #include "smtp.h" #include "pgp.h" #include "select.h" /**************************************************************************** * IMPLEMENTATION PRIVATE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS ****************************************************************************/ #define STACK_SIZE 10 #ifndef DEBUG # define DEBUG 0 #endif /**************************************************************************** * IMPLEMENTATION PRIVATE CLASS PROTOTYPES / EXTERNAL CLASS REFERENCES ****************************************************************************/ /**************************************************************************** * IMPLEMENTATION PRIVATE STRUCTURES / UTILITY CLASSES ****************************************************************************/ struct fd_handler { struct fd_handler *next; int fd; void (*handler)(int); }; /**************************************************************************** * IMPLEMENTATION REQUIRED EXTERNAL REFERENCES (AVOID) ****************************************************************************/ /**************************************************************************** * IMPLEMENTATION PRIVATE DATA ****************************************************************************/ /* Each keymap is bound to a particular state. Opening a window usually pushes new state on the stack, and closing - pops the state from the top of the stack. Switching between windows works in the same manner. Elmo determines action by watching at a keymap bound to the state on the top of the stack. */ static cmd_state_t state_stack[STACK_SIZE]; static cmd_state_t *state_top; /* Colors used to display messages in echo area. */ static chtype text_color; static chtype error_color; /* Lists of handlers for read, and write descriptors used in select call. */ static struct fd_handler *readfd_list = NULL; static struct fd_handler *writefd_list = NULL; /* List of functions to execute on timeout. */ static struct fd_handler *timeout_list = NULL; /* This is the last character - input from user. */ static int last_char = 0; /* We use digits as prefix arguments to functions. */ static int prefix_arg = 0; /**************************************************************************** * INTERFACE DATA ****************************************************************************/ /* Echo area window. It is not static because error.c uses this window to display error messages, and read.c uses this window to read the input string. */ WINDOW *cmd_win = NULL; /* These are keymaps, and hooks bindings. The array is indexed with state number. */ keymap_t keymaps[CMD_STATE_COUNT]; /**************************************************************************** * IMPLEMENTATION PRIVATE FUNCTION PROTOTYPES ****************************************************************************/ static void destroy_keymaps (void); static void destroy_list (struct fd_handler *list); /**************************************************************************** * IMPLEMENTATION PRIVATE FUNCTIONS ****************************************************************************/ static void quit (void) { destroy_keymaps (); destroy_list (readfd_list); destroy_list (writefd_list); destroy_list (timeout_list); readfd_list = NULL; writefd_list = NULL; timeout_list = NULL; elmo_finish (0); exit (EXIT_SUCCESS); } static void init_keymaps (void) { int i; for (i = 0; i < CMD_STATE_COUNT; i++) keymap_init (keymaps + i); keymap_init (&keymap_default); for (i = '0'; i < '9'; i++) keymap_add (& keymap_default, i, 1, interface_num_window); keymap_add (&keymap_default, 12, 0, interface_redraw); keymap_add (&keymap_default, '\t', 0, interface_next_window); keymap_add (&keymap_default, 'q', 0, cmd_quit); keymap_add (&keymap_default, '?', 0, help_open); keymap_add (&keymap_default, 'h', 0, help_open); keymap_add (&keymap_default, KEY_F (1), 0, help_open); keymap_add (&keymap_default, 6, 0, pgp_forget_passphrase); keymap_add (keymaps + CMD_LIST, KEY_PPAGE, 0, folder_page_prev); keymap_add (keymaps + CMD_LIST, KEY_NPAGE, 0, folder_page_next); keymap_add (keymaps + CMD_LIST, KEY_HOME, 0, folder_bar_first); keymap_add (keymaps + CMD_LIST, KEY_END, 0, folder_bar_last); keymap_add (keymaps + CMD_LIST, KEY_UP, 0, folder_bar_prev); keymap_add (keymaps + CMD_LIST, KEY_DOWN, 0, folder_bar_next); keymap_add (keymaps + CMD_LIST, KEY_DC, 0, folder_delete_mail); keymap_add (keymaps + CMD_LIST, 'K', 0, folder_kill_mail); keymap_add (keymaps + CMD_LIST, 'd', 0, folder_sort_date); keymap_add (keymaps + CMD_LIST, 't', 0, folder_sort_threads); keymap_add (keymaps + CMD_LIST, 'A', 0, folder_sort_from); keymap_add (keymaps + CMD_LIST, 's', 0, folder_sort_subject); keymap_add (keymaps + CMD_LIST, 'a', 0, abook_show); keymap_add (keymaps + CMD_LIST, '\r', 0, mailreader_show); keymap_add (keymaps + CMD_LIST, 'F', 0, fetch_open); keymap_add (keymaps + CMD_LIST, 'm', 0, sender_open_new); keymap_add (keymaps + CMD_LIST, 'r', 0, sender_open_reply); keymap_add (keymaps + CMD_LIST, 'R', 0, sender_open_reply_all); keymap_add (keymaps + CMD_LIST, 'f', 0, sender_open_fwd); keymap_add (keymaps + CMD_LIST, 'e', 0, sender_open_edit); keymap_add (keymaps + CMD_LIST, '$', 0, folder_flush); keymap_add (keymaps + CMD_LIST, ' ', 0, folder_toggle_flag); keymap_add (keymaps + CMD_LIST, '*', 0, folder_flag_invert); keymap_add (keymaps + CMD_LIST, '+', 0, folder_flag_all); keymap_add (keymaps + CMD_LIST, '-', 0, folder_unflag_all); keymap_add (keymaps + CMD_LIST, '=', 0, folder_flag_duplicates); keymap_add (keymaps + CMD_LIST, 'N', 0, folder_scroll_down); keymap_add (keymaps + CMD_LIST, 'P', 0, folder_scroll_up); keymap_add (keymaps + CMD_LIST, 'c', 0, folder_recenter); keymap_add (keymaps + CMD_LIST, 'M', 0, folder_move_mail); keymap_add (keymaps + CMD_LIST, 'n', 0, folder_next_unread); keymap_add (keymaps + CMD_LIST, 'p', 0, folder_prev_unread); keymap_add (keymaps + CMD_LIST, 'S', 0, smtp_flush_outbox); keymap_add (keymaps + CMD_LIST, 18, 0, folder_search_backward); keymap_add (keymaps + CMD_LIST, 19, 0, folder_search_forward); keymap_add (keymaps + CMD_SELECT_BOX, KEY_PPAGE, 0, box_selection_prev_page); keymap_add (keymaps + CMD_SELECT_BOX, KEY_NPAGE, 0, box_selection_next_page); keymap_add (keymaps + CMD_SELECT_BOX, KEY_HOME, 0, box_selection_first); keymap_add (keymaps + CMD_SELECT_BOX, KEY_END, 0, box_selection_last); keymap_add (keymaps + CMD_SELECT_BOX, KEY_UP, 0, box_selection_prev); keymap_add (keymaps + CMD_SELECT_BOX, KEY_DOWN, 0, box_selection_next); keymap_add (keymaps + CMD_SELECT_BOX, '\r', 0, box_selection_hit); keymap_add (keymaps + CMD_SELECT_BOX, 18, 0, box_selection_search_backward); keymap_add (keymaps + CMD_SELECT_BOX, 19, 0, box_selection_search_forward); keymap_add (keymaps + CMD_ABOOK, KEY_PPAGE, 0, abook_prev_page); keymap_add (keymaps + CMD_ABOOK, KEY_NPAGE, 0, abook_next_page); keymap_add (keymaps + CMD_ABOOK, KEY_HOME, 0, abook_first); keymap_add (keymaps + CMD_ABOOK, KEY_END, 0, abook_last); keymap_add (keymaps + CMD_ABOOK, KEY_DOWN, 0, abook_next); keymap_add (keymaps + CMD_ABOOK, KEY_UP, 0, abook_prev); keymap_add (keymaps + CMD_ABOOK, KEY_DC, 0, abook_remove); keymap_add (keymaps + CMD_ABOOK, 'n', 0, abook_change_name); keymap_add (keymaps + CMD_ABOOK, 'e', 0, abook_change_email); keymap_add (keymaps + CMD_ABOOK, 'g', 0, abook_change_groups); keymap_add (keymaps + CMD_ABOOK, 's', 0, abook_change_sex); keymap_add (keymaps + CMD_ABOOK, 'o', 0, abook_change_official); keymap_add (keymaps + CMD_ABOOK, 'f', 0, abook_change_foreign); keymap_add (keymaps + CMD_ABOOK, 'a', 0, abook_insert); keymap_add (keymaps + CMD_ABOOK, 'q', 0, abook_hide); keymap_add (keymaps + CMD_ABOOK, ' ', 0, abook_hit); keymap_add (keymaps + CMD_ABOOK, '*', 0, abook_hit_all); keymap_add (keymaps + CMD_ABOOK, '+', 0, abook_set_all); keymap_add (keymaps + CMD_ABOOK, '-', 0, abook_unset_all); keymap_add (keymaps + CMD_ABOOK, 'm', 0, abook_compose); keymap_add (keymaps + CMD_ABOOK, 18, 0, abook_search_backward); keymap_add (keymaps + CMD_ABOOK, 19, 0, abook_search_forward); keymap_add (keymaps + CMD_READ_MAIL, 'q', 0, mailreader_close); keymap_add (keymaps + CMD_READ_MAIL, KEY_PPAGE, 0, mailreader_page_up); keymap_add (keymaps + CMD_READ_MAIL, KEY_NPAGE, 0, mailreader_page_down); keymap_add (keymaps + CMD_READ_MAIL, KEY_HOME, 0, mailreader_top); keymap_add (keymaps + CMD_READ_MAIL, KEY_END, 0, mailreader_bottom); keymap_add (keymaps + CMD_READ_MAIL, KEY_DOWN, 0, mailreader_line_down); keymap_add (keymaps + CMD_READ_MAIL, KEY_UP, 0, mailreader_line_up); keymap_add (keymaps + CMD_READ_MAIL, 18, 0, mailreader_search_backward); keymap_add (keymaps + CMD_READ_MAIL, 19, 0, mailreader_search_forward); keymap_add (keymaps + CMD_READ_MAIL, 'h', 0, mailreader_header_switch); keymap_add (keymaps + CMD_READ_MAIL, 'b', 0, abook_add_show); keymap_add (keymaps + CMD_READ_MAIL, 'a', 0, attach_show); keymap_add (keymaps + CMD_READ_MAIL, 'r', 0, sender_open_reply); keymap_add (keymaps + CMD_READ_MAIL, 'R', 0, sender_open_reply_all); keymap_add (keymaps + CMD_READ_MAIL, 'f', 0, sender_open_fwd); keymap_add (keymaps + CMD_FETCH, KEY_PPAGE, 0, fetch_prev_page); keymap_add (keymaps + CMD_FETCH, KEY_NPAGE, 0, fetch_next_page); keymap_add (keymaps + CMD_FETCH, KEY_HOME, 0, fetch_first); keymap_add (keymaps + CMD_FETCH, KEY_END, 0, fetch_last); keymap_add (keymaps + CMD_FETCH, KEY_DOWN, 0, fetch_next); keymap_add (keymaps + CMD_FETCH, KEY_UP, 0, fetch_prev); keymap_add (keymaps + CMD_FETCH, 'q', 0, fetch_close); keymap_add (keymaps + CMD_FETCH, 'f', 0, fetch_get_mail); keymap_add (keymaps + CMD_FETCH, 'd', 0, fetch_del_mail); keymap_add (keymaps + CMD_FETCH, 'r', 0, fetch_rset); keymap_add (keymaps + CMD_ATTACH, KEY_PPAGE, 0, attach_prev_page); keymap_add (keymaps + CMD_ATTACH, KEY_NPAGE, 0, attach_next_page); keymap_add (keymaps + CMD_ATTACH, KEY_HOME, 0, attach_first); keymap_add (keymaps + CMD_ATTACH, KEY_END, 0, attach_last); keymap_add (keymaps + CMD_ATTACH, KEY_DOWN, 0, attach_next); keymap_add (keymaps + CMD_ATTACH, KEY_UP, 0, attach_prev); keymap_add (keymaps + CMD_ATTACH, 's', 0, attach_save); keymap_add (keymaps + CMD_ATTACH, 'S', 0, attach_save_all); keymap_add (keymaps + CMD_ATTACH, '\r', 0, attach_hit); keymap_add (keymaps + CMD_ATTACH, 'q', 0, attach_hide); keymap_add (keymaps + CMD_ABOOK_ADD, KEY_PPAGE, 0, abook_add_prev_page); keymap_add (keymaps + CMD_ABOOK_ADD, KEY_NPAGE, 0, abook_add_next_page); keymap_add (keymaps + CMD_ABOOK_ADD, KEY_HOME, 0, abook_add_first); keymap_add (keymaps + CMD_ABOOK_ADD, KEY_END, 0, abook_add_last); keymap_add (keymaps + CMD_ABOOK_ADD, KEY_DOWN, 0, abook_add_next); keymap_add (keymaps + CMD_ABOOK_ADD, KEY_UP, 0, abook_add_prev); keymap_add (keymaps + CMD_ABOOK_ADD, 'q', 0, abook_add_hide); keymap_add (keymaps + CMD_ABOOK_ADD, '\r', 0, abook_add_hit); keymap_add (keymaps + CMD_SENDER, KEY_PPAGE, 0, sender_prev_page); keymap_add (keymaps + CMD_SENDER, KEY_NPAGE, 0, sender_next_page); keymap_add (keymaps + CMD_SENDER, KEY_HOME, 0, sender_first); keymap_add (keymaps + CMD_SENDER, KEY_END, 0, sender_last); keymap_add (keymaps + CMD_SENDER, KEY_DOWN, 0, sender_next); keymap_add (keymaps + CMD_SENDER, KEY_UP, 0, sender_prev); keymap_add (keymaps + CMD_SENDER, 'q', 0, sender_close); keymap_add (keymaps + CMD_SENDER, 'y', 0, sender_go); keymap_add (keymaps + CMD_SENDER, 'S', 0, sender_change_smtp); keymap_add (keymaps + CMD_SENDER, 'f', 0, sender_change_from); keymap_add (keymaps + CMD_SENDER, 'r', 0, sender_change_reply_to); keymap_add (keymaps + CMD_SENDER, 't', 0, sender_change_to); keymap_add (keymaps + CMD_SENDER, 'c', 0, sender_change_cc); keymap_add (keymaps + CMD_SENDER, 'b', 0, sender_change_bcc); keymap_add (keymaps + CMD_SENDER, 's', 0, sender_change_subject); keymap_add (keymaps + CMD_SENDER, 'a', 0, sender_add_attachment); keymap_add (keymaps + CMD_SENDER, KEY_DC, 0, sender_delete_attachment); keymap_add (keymaps + CMD_SENDER, 'T', 0, sender_change_type); keymap_add (keymaps + CMD_ASK, KEY_HOME, 0, choose_first); keymap_add (keymaps + CMD_ASK, KEY_END, 0, choose_last); keymap_add (keymaps + CMD_ASK, KEY_DOWN, 0, choose_next); keymap_add (keymaps + CMD_ASK, KEY_RIGHT, 0, choose_next); keymap_add (keymaps + CMD_ASK, KEY_UP, 0, choose_prev); keymap_add (keymaps + CMD_ASK, KEY_LEFT, 0, choose_prev); keymap_add (keymaps + CMD_HELP, KEY_HOME, 0, help_beg); keymap_add (keymaps + CMD_HELP, KEY_END, 0, help_end); keymap_add (keymaps + CMD_HELP, KEY_DOWN, 0, help_scroll_down); keymap_add (keymaps + CMD_HELP, KEY_UP, 0, help_scroll_up); keymap_add (keymaps + CMD_HELP, KEY_NPAGE, 0, help_next_page); keymap_add (keymaps + CMD_HELP, KEY_PPAGE, 0, help_prev_page); keymap_add (keymaps + CMD_HELP, 'q', 0, help_close); keymap_add (keymaps + CMD_HELP, 27, 0, help_close); keymap_add (keymaps + CMD_HELP, 7, 0, help_close); keymap_add (keymaps + CMD_HELP, '?', 0, cmd_nothing); keymap_add (keymaps + CMD_READ, 7, 0, read_abort); keymap_add (keymaps + CMD_READ, '\r', 0, read_accept); keymap_add (keymaps + CMD_READ, KEY_HOME, 0, read_begin); keymap_add (keymaps + CMD_READ, 1, 0, read_begin); keymap_add (keymaps + CMD_READ, KEY_END, 0, read_end); keymap_add (keymaps + CMD_READ, 5, 0, read_end); keymap_add (keymaps + CMD_READ, KEY_LEFT, 0, read_backward_char); keymap_add (keymaps + CMD_READ, 2, 0, read_backward_char); keymap_add (keymaps + CMD_READ, KEY_RIGHT, 0, read_forward_char); keymap_add (keymaps + CMD_READ, 6, 0, read_forward_char); keymap_add (keymaps + CMD_READ, 'b', 1, read_backward_word); keymap_add (keymaps + CMD_READ, 'f', 1, read_forward_word); keymap_add (keymaps + CMD_READ, 4, 0, read_del_char_fwd); keymap_add (keymaps + CMD_READ, KEY_DC, 0, read_del_char_fwd); keymap_add (keymaps + CMD_READ, KEY_BACKSPACE, 0, read_del_char_back); keymap_add (keymaps + CMD_READ, '\b', 0, read_del_char_back); keymap_add (keymaps + CMD_READ, 127, 0, read_del_char_back); keymap_add (keymaps + CMD_READ, 'd', 1, read_del_word_fwd); keymap_add (keymaps + CMD_READ, KEY_BACKSPACE, 1, read_del_word_back); keymap_add (keymaps + CMD_READ, '\b', 1, read_del_word_back); keymap_add (keymaps + CMD_READ, 127, 1, read_del_word_back); keymap_add (keymaps + CMD_READ, 11, 0, read_kill_line); keymap_add (keymaps + CMD_READ, '\t', 0, read_complete); keymap_add (keymaps + CMD_READ, 14, 0, read_choose_next); keymap_add (keymaps + CMD_READ, KEY_DOWN, 0, read_choose_next); keymap_add (keymaps + CMD_READ, 16, 0, read_choose_prev); keymap_add (keymaps + CMD_READ, KEY_UP, 0, read_choose_prev); keymap_add (keymaps + CMD_SEARCH, 18, 0, select_search_backward); keymap_add (keymaps + CMD_SEARCH, 19, 0, select_search_forward); keymap_add (keymaps + CMD_SEARCH, '\b', 0, select_search_backspace); keymap_add (keymaps + CMD_SEARCH, 127, 0, select_search_backspace); keymap_add (keymaps + CMD_SEARCH, KEY_BACKSPACE, 0, select_search_backspace); #if DEBUG keymap_add (keymaps + CMD_DEBUG, KEY_HOME, 0, debug_first); keymap_add (keymaps + CMD_DEBUG, KEY_END, 0, debug_last); keymap_add (keymaps + CMD_DEBUG, KEY_UP, 0, debug_prev); keymap_add (keymaps + CMD_DEBUG, KEY_DOWN, 0, debug_next); keymap_add (keymaps + CMD_DEBUG, KEY_PPAGE, 0, debug_prev_page); keymap_add (keymaps + CMD_DEBUG, KEY_NPAGE, 0, debug_next_page); keymap_add (keymaps + CMD_DEBUG, ' ', 0, debug_show); #endif } static void destroy_keymaps (void) { int i; for (i = 0; i < CMD_STATE_COUNT; i++){ keymap_destroy (keymaps + i); } keymap_destroy (&keymap_default); } static void destroy_list (struct fd_handler *list) { if (list == NULL) return; destroy_list (list->next); xfree (list); } static void key_action (int nothing) { int meta; int c; char *arg; meta = 0; c = wgetch (cmd_win); if (c == 27){ meta = 1; c = wgetch (cmd_win); } last_char = c; if (c == ':'){ arg = read_argument (": ", NULL, COMPLETE_FUNS, HIDE_NO); if (arg) exec_run_name (arg); return; } if (! meta && isdigit (c)){ prefix_arg = c - '0'; return; } if (keymap_action (keymaps + *state_top, c, meta)) fprintf (stderr, "%c", '\a'); prefix_arg = 0; } /* This file is generated by interface.pl script from interface.desc, and inc.in. */ static WINDOW *interface_init (void); #include "cmd.inc" static void init (void) { cmd_win = interface_init (); keypad (cmd_win, TRUE); meta (cmd_win, TRUE); init_keymaps (); state_top = state_stack; *state_top = CMD_LIST; cmd_add_readfd_handler (0, key_action); } static void put_fds (fd_set *set, struct fd_handler *list) { if (list == NULL) return; FD_SET (list->fd, set); put_fds (set, list->next); } /* The reversed order of taking actions is *very* important. The action may change the list by removing or adding new elements. */ static void take_actions (fd_set *set, struct fd_handler *list) { if (list == NULL) return; take_actions (set, list->next); if (set == NULL || FD_ISSET (list->fd, set)) list->handler (list->fd); } static struct fd_handler * list_rem (struct fd_handler *list, int fd) { struct fd_handler *result; if (list == NULL) return NULL; if (list->fd != fd){ list->next = list_rem (list->next, fd); return list; } result = list->next; xfree (list); return result; } /**************************************************************************** * INTERFACE FUNCTIONS ****************************************************************************/ void cmd_text_color (void) { wattrset (cmd_win, text_color); } void cmd_error_color (void) { wattrset (cmd_win, error_color); } void cmd_init (void) { init (); } void cmd_quit (void) { exec_t *exec; exec = exec_lookup_fun (cmd_quit); hook_execute (exec->hook); quit (); } void cmd_nothing (void) { } void cmd_state_push (cmd_state_t requested_state) { if (state_top == state_stack + STACK_SIZE){ error_ (0, _("state stack overflow, please send bug report")); } state_top++; *state_top = requested_state; } int cmd_state_pop (void) { if (state_top == state_stack){ error_ (0, _("state stack underflow, " "please send bug report")); } state_top--; return 0; } cmd_state_t cmd_state_get (int from_top) { return *(state_top - from_top); } void cmd_add_writefd_handler (int fd, void (*handler)(int)) { struct fd_handler *elem = xmalloc (sizeof (struct fd_handler)); elem->fd = fd; elem->handler = handler; elem->next = writefd_list; writefd_list = elem; } void cmd_add_readfd_handler (int fd, void (*handler)(int)) { struct fd_handler *elem = xmalloc (sizeof (struct fd_handler)); elem->fd = fd; elem->handler = handler; elem->next = readfd_list; readfd_list = elem; } void cmd_add_timeout_handler (void (*handler)(int)) { struct fd_handler *elem = xmalloc (sizeof (struct fd_handler)); elem->fd = 0; elem->handler = handler; elem->next = timeout_list; timeout_list = elem; } void cmd_del_writefd_handler (int fd) { writefd_list = list_rem (writefd_list, fd); } void cmd_del_readfd_handler (int fd) { readfd_list = list_rem (readfd_list, fd); } void cmd_read_loop (void) { struct timeval tv; fd_set readfds; fd_set writefds; int ret; interface_redraw (); cmd_after_startup (); while (1){ doupdate (); tv.tv_sec = 0; tv.tv_usec = 3000; FD_ZERO (& readfds); FD_ZERO (& writefds); put_fds (& readfds, readfd_list); put_fds (& writefds, writefd_list); ret = select (FD_SETSIZE, & readfds, & writefds, NULL, & tv); if (ret > 0){ take_actions (& readfds, readfd_list); take_actions (& writefds, writefd_list); } else if (ret == 0){ take_actions (NULL, timeout_list); } else { error_critical (EXIT_FAILURE, errno, "select"); } } } void cmd_choose (void) { int meta; int c; while (1){ doupdate (); meta = 0; c = wgetch (cmd_win); if (c == 27){ meta = 1; c = wgetch (cmd_win); } if (c == '\r'){ break; } if (c == 7){ choose_cancel (); break; } keymap_action (keymaps + CMD_ASK, c, meta); } interface_redraw (); } int cmd_last_char (void) { return last_char; } int cmd_prefix_arg (void) { return prefix_arg; } void cmd_after_startup (void) { exec_t *exec; exec = exec_lookup_fun (cmd_after_startup); hook_execute (exec->hook); } /**************************************************************************** * INTERFACE CLASS BODIES ****************************************************************************/ /**************************************************************************** * * END MODULE cmd.c * ****************************************************************************/