X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/798aef02223bdfdf4ff383e59590b2a44eaf3a0c..df384736fc4559b05c180a88a8b586bf9795ce02:/src/term.c?ds=sidebyside diff --git a/src/term.c b/src/term.c index f86d71ac2f..379c94e54a 100644 --- a/src/term.c +++ b/src/term.c @@ -1,5 +1,5 @@ /* Terminal control module for terminals described by TERMCAP - Copyright (C) 1985-1987, 1993-1995, 1998, 2000-2013 Free Software + Copyright (C) 1985-1987, 1993-1995, 1998, 2000-2014 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -131,6 +131,9 @@ enum no_color_bit static int max_frame_cols; +static Lisp_Object Qtty_mode_set_strings; +static Lisp_Object Qtty_mode_reset_strings; + #ifdef HAVE_GPM @@ -161,6 +164,28 @@ tty_ring_bell (struct frame *f) /* Set up termcap modes for Emacs. */ +static void +tty_send_additional_strings (struct terminal *terminal, Lisp_Object sym) +{ + Lisp_Object lisp_terminal; + Lisp_Object extra_codes; + struct tty_display_info *tty = terminal->display_info.tty; + + XSETTERMINAL (lisp_terminal, terminal); + for (extra_codes = Fterminal_parameter (lisp_terminal, sym); + CONSP (extra_codes); + extra_codes = XCDR (extra_codes)) + { + Lisp_Object string = XCAR (extra_codes); + if (STRINGP (string)) + { + fwrite (SDATA (string), 1, SBYTES (string), tty->output); + if (tty->termscript) + fwrite (SDATA (string), 1, SBYTES (string), tty->termscript); + } + } +} + static void tty_set_terminal_modes (struct terminal *terminal) { @@ -183,6 +208,7 @@ tty_set_terminal_modes (struct terminal *terminal) OUTPUT_IF (tty, visible_cursor ? tty->TS_cursor_visible : tty->TS_cursor_normal); OUTPUT_IF (tty, tty->TS_keypad_mode); losecursor (tty); + tty_send_additional_strings (terminal, Qtty_mode_set_strings); fflush (tty->output); } } @@ -196,6 +222,7 @@ tty_reset_terminal_modes (struct terminal *terminal) if (tty->output) { + tty_send_additional_strings (terminal, Qtty_mode_reset_strings); tty_turn_off_highlight (tty); tty_turn_off_insert (tty); OUTPUT_IF (tty, tty->TS_end_keypad_mode); @@ -500,7 +527,7 @@ static ptrdiff_t encode_terminal_dst_size; Set CODING->produced to the byte-length of the resulting byte sequence, and return a pointer to that byte sequence. */ -#ifndef WINDOWSNT +#ifndef DOS_NT static #endif unsigned char * @@ -1339,7 +1366,7 @@ term_get_fkeys_1 (void) if (!KEYMAPP (KVAR (kboard, Vinput_decode_map))) kset_input_decode_map (kboard, Fmake_sparse_keymap (Qnil)); - for (i = 0; i < (sizeof (keys) / sizeof (keys[0])); i++) + for (i = 0; i < ARRAYELTS (keys); i++) { char *sequence = tgetstr (keys[i].cap, address); if (sequence) @@ -1422,18 +1449,6 @@ term_get_fkeys_1 (void) CONDITIONAL_REASSIGN ("kD", "kI", "insert"); /* if there's no key_end keycap, map key_ll to 'end' keysym */ CONDITIONAL_REASSIGN ("@7", "kH", "end"); - - /* IBM has their own non-standard dialect of terminfo. - If the standard name isn't found, try the IBM name. */ - CONDITIONAL_REASSIGN ("kB", "KO", "backtab"); - CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */ - CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */ - CONDITIONAL_REASSIGN ("%7", "ki", "menu"); - CONDITIONAL_REASSIGN ("@7", "kw", "end"); - CONDITIONAL_REASSIGN ("F1", "k<", "f11"); - CONDITIONAL_REASSIGN ("F2", "k>", "f12"); - CONDITIONAL_REASSIGN ("%1", "kq", "help"); - CONDITIONAL_REASSIGN ("*6", "kU", "select"); #undef CONDITIONAL_REASSIGN } @@ -2064,17 +2079,9 @@ tty_default_color_capabilities (struct tty_display_info *tty, bool save) if (save) { - xfree (default_orig_pair); - default_orig_pair = tty->TS_orig_pair ? xstrdup (tty->TS_orig_pair) : NULL; - - xfree (default_set_foreground); - default_set_foreground = tty->TS_set_foreground ? xstrdup (tty->TS_set_foreground) - : NULL; - - xfree (default_set_background); - default_set_background = tty->TS_set_background ? xstrdup (tty->TS_set_background) - : NULL; - + dupstring (&default_orig_pair, tty->TS_orig_pair); + dupstring (&default_set_foreground, tty->TS_set_foreground); + dupstring (&default_set_background, tty->TS_set_background); default_max_colors = tty->TN_max_colors; default_max_pairs = tty->TN_max_pairs; default_no_color_video = tty->TN_no_color_video; @@ -2407,7 +2414,7 @@ frame's terminal). */) was suspended. */ get_tty_size (fileno (t->display_info.tty->input), &width, &height); if (width != old_width || height != old_height) - change_frame_size (f, height, width, 0, 0, 0); + change_frame_size (f, width, height, 0, 0, 0, 0); SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1); } @@ -2739,7 +2746,7 @@ DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop, Sgpm_mouse_stop, Menus ***********************************************************************/ -#if defined (HAVE_MENUS) && !defined (MSDOS) +#if !defined (MSDOS) /* TTY menu implementation and main ideas are borrowed from msdos.c. @@ -2917,6 +2924,13 @@ tty_menu_display (tty_menu *menu, int x, int y, int pn, int *faces, menu_help_paneno = pn - 1; menu_help_itemno = j; } + /* Take note of the coordinates of the active menu item, to + display the cursor there. */ + if (mousehere) + { + row = y + i; + col = x; + } display_tty_menu_item (menu->text[j], max_width, face, x, y + i, menu->submenu[j] != NULL); } @@ -3039,7 +3053,7 @@ save_and_enable_current_matrix (struct frame *f) /* Make sure every row is enabled, or else update_frame will not redraw them. (Rows that are identical to what is already on screen will not be redrawn anyway.) */ - to->enabled_p = 1; + to->enabled_p = true; to->hash = from->hash; } @@ -3074,7 +3088,7 @@ free_saved_screen (struct glyph_matrix *saved) int i; if (!saved) - return; /* already freed */ + return; /* Already freed! */ for (i = 0; i < saved->nrows; ++i) { @@ -3136,7 +3150,11 @@ read_menu_input (struct frame *sf, int *x, int *y, int min_y, int max_y, tty->showing_menu = 0; do_mouse_tracking = saved_mouse_tracking; - if (EQ (cmd, Qt) || EQ (cmd, Qtty_menu_exit)) + if (EQ (cmd, Qt) || EQ (cmd, Qtty_menu_exit) + /* If some input switched frames under our feet, exit the + menu, since the menu faces are no longer valid, and the + menu is no longer relevant anyway. */ + || sf != SELECTED_FRAME ()) return MI_QUIT_MENU; if (EQ (cmd, Qtty_menu_mouse_movement)) mouse_get_xy (x, y); @@ -3186,13 +3204,14 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx, int statecount, x, y, i; bool leave, onepane; int result IF_LINT (= 0); - int title_faces[4]; /* face to display the menu title */ + int title_faces[4]; /* Face to display the menu title. */ int faces[4], buffers_num_deleted = 0; struct frame *sf = SELECTED_FRAME (); struct tty_display_info *tty = FRAME_TTY (sf); bool first_time; Lisp_Object selectface; int first_item = 0; + int col, row; /* Don't allow non-positive x0 and y0, lest the menu will wrap around the display. */ @@ -3248,7 +3267,10 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx, /* Turn off the cursor. Otherwise it shows through the menu panes, which is ugly. */ + col = cursorX (tty); + row = cursorY (tty); tty_hide_cursor (tty); + if (buffers_num_deleted) menu->text[0][7] = ' '; onepane = menu->count == 1 && menu->submenu[0]; @@ -3348,7 +3370,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx, have been opened. That does not include an open and active submenu. */ if (i != statecount - 2 - || state[i].menu->submenu[dy] != state[i+1].menu) + || state[i].menu->submenu[dy] != state[i + 1].menu) while (i != statecount - 1) { statecount--; @@ -3380,6 +3402,11 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx, faces, x, y, first_item, 1); tty_hide_cursor (tty); fflush (tty->output); + /* The call to display help-echo below will move the cursor, + so remember its current position as computed by + tty_menu_display. */ + col = cursorX (tty); + row = cursorY (tty); } /* Display the help-echo message for the currently-selected menu @@ -3389,6 +3416,10 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx, { help_callback (menu_help_message, menu_help_paneno, menu_help_itemno); + /* Move the cursor to the beginning of the current menu + item, so that screen readers and other accessibility aids + know where the active region is. */ + cursor_to (sf, row, col); tty_hide_cursor (tty); fflush (tty->output); prev_menu_help_message = menu_help_message; @@ -3399,7 +3430,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx, screen_update (sf, state[0].screen_behind); while (statecount--) free_saved_screen (state[statecount].screen_behind); - tty_show_cursor (tty); /* turn cursor back on */ + tty_show_cursor (tty); /* Turn cursor back on. */ fflush (tty->output); /* Clean up any mouse events that are waiting inside Emacs event queue. @@ -3490,7 +3521,7 @@ tty_menu_last_menubar_item (struct frame *f) break; i += 4; } - i -= 4; /* went one too far */ + i -= 4; /* Went one too far! */ } return i; } @@ -3535,7 +3566,7 @@ tty_menu_new_item_coords (struct frame *f, int which, int *x, int *y) if (i < last_i) *x = XINT (AREF (items, i + 4 + 3)); else - *x = 0; /* wrap around to the first item */ + *x = 0; /* Wrap around to the first item. */ } else if (prev_x < 0) { @@ -3663,7 +3694,7 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, if (!NILP (descrip)) { - /* if alloca is fast, use that to make the space, + /* If alloca is fast, use that to make the space, to reduce gc needs. */ item_data = (char *) alloca (maxwidth + SBYTES (descrip) + 1); memcpy (item_data, SSDATA (item_name), SBYTES (item_name)); @@ -3710,7 +3741,7 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, uly = dispheight - height; } - if (FRAME_HAS_MINIBUF_P (f) && uly+height > dispheight - 2) + if (FRAME_HAS_MINIBUF_P (f) && uly + height > dispheight - 2) { /* Move the menu away of the echo area, to avoid overwriting the menu with help echo messages or vice versa. */ @@ -3739,8 +3770,8 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, /* If position was not given by a mouse click, adjust so upper left corner of the menu as a whole ends up at given coordinates. This is what x-popup-menu says in its documentation. */ - x += width/2; - y += 1.5*height/(maxlines+2); + x += width / 2; + y += 1.5 * height / (maxlines + 2); } #endif @@ -3803,6 +3834,11 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, case TTYM_IA_SELECT: break; case TTYM_NO_SELECT: + /* If the selected frame was changed while we displayed a menu, + throw to top level in order to undo any temporary settings + made by TTY menu code. */ + if (f != SELECTED_FRAME ()) + Ftop_level (); /* Make "Cancel" equivalent to C-g unless FOR_CLICK (which means the menu was invoked with a mouse event as POSITION). */ if (! for_click) @@ -3816,7 +3852,7 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, return entry; } -#endif /* HAVE_MENUS && !MSDOS */ +#endif /* !MSDOS */ #ifndef MSDOS @@ -3825,7 +3861,7 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, ***********************************************************************/ /* Initialize the tty-dependent part of frame F. The frame must - already have its device initialized. */ + already have its device initialized. */ void create_tty_output (struct frame *f) @@ -3839,30 +3875,25 @@ create_tty_output (struct frame *f) f->output_data.tty = t; } -/* Delete frame F's face cache, and its tty-dependent part. */ +/* Delete frame F's face cache, and its tty-dependent part. */ static void tty_free_frame_resources (struct frame *f) { eassert (FRAME_TERMCAP_P (f)); - - if (FRAME_FACE_CACHE (f)) - free_frame_faces (f); - + free_frame_faces (f); xfree (f->output_data.tty); } #else /* MSDOS */ -/* Delete frame F's face cache. */ +/* Delete frame F's face cache. */ static void tty_free_frame_resources (struct frame *f) { eassert (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)); - - if (FRAME_FACE_CACHE (f)) - free_frame_faces (f); + free_frame_faces (f); } #endif /* MSDOS */ @@ -3909,43 +3940,24 @@ clear_tty_hooks (struct terminal *terminal) static void set_tty_hooks (struct terminal *terminal) { - terminal->rif = 0; /* ttys don't support window-based redisplay. */ - terminal->cursor_to_hook = &tty_cursor_to; terminal->raw_cursor_to_hook = &tty_raw_cursor_to; - terminal->clear_to_end_hook = &tty_clear_to_end; terminal->clear_frame_hook = &tty_clear_frame; terminal->clear_end_of_line_hook = &tty_clear_end_of_line; - terminal->ins_del_lines_hook = &tty_ins_del_lines; - terminal->insert_glyphs_hook = &tty_insert_glyphs; terminal->write_glyphs_hook = &tty_write_glyphs; terminal->delete_glyphs_hook = &tty_delete_glyphs; - terminal->ring_bell_hook = &tty_ring_bell; - terminal->reset_terminal_modes_hook = &tty_reset_terminal_modes; terminal->set_terminal_modes_hook = &tty_set_terminal_modes; - terminal->update_begin_hook = 0; /* Not needed. */ terminal->update_end_hook = &tty_update_end; terminal->set_terminal_window_hook = &tty_set_terminal_window; - - terminal->mouse_position_hook = 0; /* Not needed. */ - terminal->frame_rehighlight_hook = 0; /* Not needed. */ - terminal->frame_raise_lower_hook = 0; /* Not needed. */ - - terminal->set_vertical_scroll_bar_hook = 0; /* Not needed. */ - terminal->condemn_scroll_bars_hook = 0; /* Not needed. */ - terminal->redeem_scroll_bar_hook = 0; /* Not needed. */ - terminal->judge_scroll_bars_hook = 0; /* Not needed. */ - terminal->read_socket_hook = &tty_read_avail_input; /* keyboard.c */ - terminal->frame_up_to_date_hook = 0; /* Not needed. */ - terminal->delete_frame_hook = &tty_free_frame_resources; terminal->delete_terminal_hook = &delete_tty; + /* Other hooks are NULL by default. */ } /* If FD is the controlling terminal, drop it. */ @@ -3960,9 +3972,10 @@ dissociate_if_controlling_tty (int fd) /* setsid failed, presumably because Emacs is already a process group leader. Fall back on the obsolescent way to dissociate a controlling tty. */ - block_tty_out_signal (); + sigset_t oldset; + block_tty_out_signal (&oldset); ioctl (fd, TIOCNOTTY, 0); - unblock_tty_out_signal (); + unblock_tty_out_signal (&oldset); #endif } } @@ -3986,6 +3999,7 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed) int status; struct tty_display_info *tty = NULL; struct terminal *terminal = NULL; + sigset_t oldset; bool ctty = false; /* True if asked to open controlling tty. */ if (!terminal_type) @@ -4007,7 +4021,7 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed) if (terminal) return terminal; - terminal = create_terminal (); + terminal = create_terminal (output_termcap, NULL); #ifdef MSDOS if (been_here > 0) maybe_fatal (0, 0, "Attempt to create another terminal %s", "", @@ -4021,7 +4035,6 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed) tty->next = tty_list; tty_list = tty; - terminal->type = output_termcap; terminal->display_info.tty = tty; tty->terminal = terminal; @@ -4047,12 +4060,15 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed) open a frame on the same terminal. */ int flags = O_RDWR | O_NOCTTY | (ctty ? 0 : O_IGNORE_CTTY); int fd = emacs_open (name, flags, 0); - tty->input = tty->output = fd < 0 || ! isatty (fd) ? 0 : fdopen (fd, "w+"); + tty->input = tty->output = + ((fd < 0 || ! isatty (fd)) + ? NULL + : fdopen (fd, "w+")); if (! tty->input) { char const *diagnostic - = tty->input ? "Not a tty device: %s" : "Could not open file: %s"; + = (fd < 0) ? "Could not open file: %s" : "Not a tty device: %s"; emacs_close (fd); maybe_fatal (must_succeed, terminal, diagnostic, diagnostic, name); } @@ -4072,11 +4088,11 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed) /* On some systems, tgetent tries to access the controlling terminal. */ - block_tty_out_signal (); + block_tty_out_signal (&oldset); status = tgetent (tty->termcap_term_buffer, terminal_type); if (tty->termcap_term_buffer[TERMCAP_BUFFER_SIZE - 1]) emacs_abort (); - unblock_tty_out_signal (); + unblock_tty_out_signal (&oldset); if (status < 0) { @@ -4573,6 +4589,10 @@ bigger, or it may make it blink, or it may do nothing at all. */); encode_terminal_src = NULL; encode_terminal_dst = NULL; + DEFSYM (Qtty_mode_set_strings, "tty-mode-set-strings"); + DEFSYM (Qtty_mode_reset_strings, "tty-mode-reset-strings"); + +#ifndef MSDOS DEFSYM (Qtty_menu_next_item, "tty-menu-next-item"); DEFSYM (Qtty_menu_prev_item, "tty-menu-prev-item"); DEFSYM (Qtty_menu_next_menu, "tty-menu-next-menu"); @@ -4582,4 +4602,5 @@ bigger, or it may make it blink, or it may do nothing at all. */); DEFSYM (Qtty_menu_exit, "tty-menu-exit"); DEFSYM (Qtty_menu_mouse_movement, "tty-menu-mouse-movement"); DEFSYM (Qtty_menu_navigation_map, "tty-menu-navigation-map"); +#endif }