diff options
| -rw-r--r-- | src/ChangeLog | 12 | ||||
| -rw-r--r-- | src/term.c | 10 | ||||
| -rw-r--r-- | src/xdisp.c | 9 |
3 files changed, 28 insertions, 3 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index df44bca7b1c..6947c5eddd5 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,15 @@ | |||
| 1 | 2013-10-11 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * xdisp.c (display_tty_menu_item): Make sure we never write beyond | ||
| 4 | the end of the frame's glyph matrix. (Bug#15575) | ||
| 5 | |||
| 6 | * term.c (tty_menu_display): Don't move cursor while overwriting | ||
| 7 | frame's glyphs with menu items. Limit the number of items | ||
| 8 | displayed to what can be shown on the available screen lines, | ||
| 9 | excluding the echo area. | ||
| 10 | (tty_menu_activate): Limit the Y coordinate allowed by | ||
| 11 | read_menu_input to the last screen line used for menu display. | ||
| 12 | |||
| 1 | 2013-10-11 Paul Eggert <eggert@cs.ucla.edu> | 13 | 2013-10-11 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 14 | ||
| 3 | * lisp.h (eassume): New macro. | 15 | * lisp.h (eassume): New macro. |
diff --git a/src/term.c b/src/term.c index a4f8f2ea17c..9437faee8a2 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -2919,17 +2919,20 @@ tty_menu_display (tty_menu *menu, int x, int y, int pn, int *faces, | |||
| 2919 | int i, face, width, enabled, mousehere, row, col; | 2919 | int i, face, width, enabled, mousehere, row, col; |
| 2920 | struct frame *sf = SELECTED_FRAME (); | 2920 | struct frame *sf = SELECTED_FRAME (); |
| 2921 | struct tty_display_info *tty = FRAME_TTY (sf); | 2921 | struct tty_display_info *tty = FRAME_TTY (sf); |
| 2922 | /* Don't try to display more menu items than the console can display | ||
| 2923 | using the available screen lines. Exclude the echo area line, as | ||
| 2924 | it will be overwritten by the help-echo anyway. */ | ||
| 2925 | int max_items = min (menu->count, FRAME_LINES (sf) - 1); | ||
| 2922 | 2926 | ||
| 2923 | menu_help_message = NULL; | 2927 | menu_help_message = NULL; |
| 2924 | 2928 | ||
| 2925 | width = menu->width; | 2929 | width = menu->width; |
| 2926 | col = cursorX (tty); | 2930 | col = cursorX (tty); |
| 2927 | row = cursorY (tty); | 2931 | row = cursorY (tty); |
| 2928 | for (i = 0; i < menu->count; i++) | 2932 | for (i = 0; i < max_items; i++) |
| 2929 | { | 2933 | { |
| 2930 | int max_width = width + 2; /* +2 for padding blanks on each side */ | 2934 | int max_width = width + 2; /* +2 for padding blanks on each side */ |
| 2931 | 2935 | ||
| 2932 | cursor_to (sf, y + i, x); | ||
| 2933 | if (menu->submenu[i]) | 2936 | if (menu->submenu[i]) |
| 2934 | max_width += 2; /* for displaying " >" after the item */ | 2937 | max_width += 2; /* for displaying " >" after the item */ |
| 2935 | enabled | 2938 | enabled |
| @@ -3285,7 +3288,8 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx, | |||
| 3285 | while (!leave) | 3288 | while (!leave) |
| 3286 | { | 3289 | { |
| 3287 | int input_status; | 3290 | int input_status; |
| 3288 | int min_y = state[0].y, max_y = min_y + state[0].menu->count - 1; | 3291 | int min_y = state[0].y; |
| 3292 | int max_y = min (min_y + state[0].menu->count, FRAME_LINES (sf)) - 1; | ||
| 3289 | 3293 | ||
| 3290 | input_status = read_menu_input (sf, &x, &y, min_y, max_y, &first_time); | 3294 | input_status = read_menu_input (sf, &x, &y, min_y, max_y, &first_time); |
| 3291 | if (input_status) | 3295 | if (input_status) |
diff --git a/src/xdisp.c b/src/xdisp.c index 6c189c698e1..7cfb0ab51ad 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -20640,6 +20640,14 @@ display_tty_menu_item (const char *item_text, int width, int face_id, | |||
| 20640 | 20640 | ||
| 20641 | eassert (FRAME_TERMCAP_P (f)); | 20641 | eassert (FRAME_TERMCAP_P (f)); |
| 20642 | 20642 | ||
| 20643 | /* Don't write beyond the matrix's last row. This can happen for | ||
| 20644 | TTY screens that are not high enough to show the entire menu. | ||
| 20645 | (This is actually a bit of defensive programming, as | ||
| 20646 | tty_menu_display already limits the number of menu items to one | ||
| 20647 | less than the number of screen lines.) */ | ||
| 20648 | if (y >= f->desired_matrix->nrows) | ||
| 20649 | return; | ||
| 20650 | |||
| 20643 | init_iterator (&it, w, -1, -1, f->desired_matrix->rows + y, MENU_FACE_ID); | 20651 | init_iterator (&it, w, -1, -1, f->desired_matrix->rows + y, MENU_FACE_ID); |
| 20644 | it.first_visible_x = 0; | 20652 | it.first_visible_x = 0; |
| 20645 | it.last_visible_x = FRAME_COLS (f) - 1; | 20653 | it.last_visible_x = FRAME_COLS (f) - 1; |
| @@ -20654,6 +20662,7 @@ display_tty_menu_item (const char *item_text, int width, int face_id, | |||
| 20654 | 20662 | ||
| 20655 | /* Arrange for the menu item glyphs to start at (X,Y) and have the | 20663 | /* Arrange for the menu item glyphs to start at (X,Y) and have the |
| 20656 | desired face. */ | 20664 | desired face. */ |
| 20665 | eassert (x < f->desired_matrix->matrix_w); | ||
| 20657 | it.current_x = it.hpos = x; | 20666 | it.current_x = it.hpos = x; |
| 20658 | it.current_y = it.vpos = y; | 20667 | it.current_y = it.vpos = y; |
| 20659 | saved_used = row->used[TEXT_AREA]; | 20668 | saved_used = row->used[TEXT_AREA]; |