+2013-10-11 Eli Zaretskii <eliz@gnu.org>
+
+ * xdisp.c (display_tty_menu_item): Make sure we never write beyond
+ the end of the frame's glyph matrix. (Bug#15575)
+
+ * term.c (tty_menu_display): Don't move cursor while overwriting
+ frame's glyphs with menu items. Limit the number of items
+ displayed to what can be shown on the available screen lines,
+ excluding the echo area.
+ (tty_menu_activate): Limit the Y coordinate allowed by
+ read_menu_input to the last screen line used for menu display.
+
2013-10-11 Paul Eggert <eggert@cs.ucla.edu>
* lisp.h (eassume): New macro.
int i, face, width, enabled, mousehere, row, col;
struct frame *sf = SELECTED_FRAME ();
struct tty_display_info *tty = FRAME_TTY (sf);
+ /* Don't try to display more menu items than the console can display
+ using the available screen lines. Exclude the echo area line, as
+ it will be overwritten by the help-echo anyway. */
+ int max_items = min (menu->count, FRAME_LINES (sf) - 1);
menu_help_message = NULL;
width = menu->width;
col = cursorX (tty);
row = cursorY (tty);
- for (i = 0; i < menu->count; i++)
+ for (i = 0; i < max_items; i++)
{
int max_width = width + 2; /* +2 for padding blanks on each side */
- cursor_to (sf, y + i, x);
if (menu->submenu[i])
max_width += 2; /* for displaying " >" after the item */
enabled
while (!leave)
{
int input_status;
- int min_y = state[0].y, max_y = min_y + state[0].menu->count - 1;
+ int min_y = state[0].y;
+ int max_y = min (min_y + state[0].menu->count, FRAME_LINES (sf)) - 1;
input_status = read_menu_input (sf, &x, &y, min_y, max_y, &first_time);
if (input_status)
eassert (FRAME_TERMCAP_P (f));
+ /* Don't write beyond the matrix's last row. This can happen for
+ TTY screens that are not high enough to show the entire menu.
+ (This is actually a bit of defensive programming, as
+ tty_menu_display already limits the number of menu items to one
+ less than the number of screen lines.) */
+ if (y >= f->desired_matrix->nrows)
+ return;
+
init_iterator (&it, w, -1, -1, f->desired_matrix->rows + y, MENU_FACE_ID);
it.first_visible_x = 0;
it.last_visible_x = FRAME_COLS (f) - 1;
/* Arrange for the menu item glyphs to start at (X,Y) and have the
desired face. */
+ eassert (x < f->desired_matrix->matrix_w);
it.current_x = it.hpos = x;
it.current_y = it.vpos = y;
saved_used = row->used[TEXT_AREA];