diff options
author | Eli Zaretskii <eliz@gnu.org> | 2013-10-08 20:49:20 +0300 |
---|---|---|
committer | Eli Zaretskii <eliz@gnu.org> | 2013-10-08 20:49:20 +0300 |
commit | 4ed774157d1687cc5236ecaf088dc48442e92431 (patch) | |
tree | 4dd32cb0104172c6b12f90c2651f58f0040bfe20 /src/xdisp.c | |
parent | 06286513730d013c2033d1dae892349e5eec98d9 (diff) | |
parent | f3370a94fd887e9e01db81a86e42036d12dcda9b (diff) |
Support menus on text-mode terminals.
src/xterm.h (xw_popup_dialog): Add prototype.
src/xmenu.c (Fx_popup_dialog): Function moved to menu.c.
(xmenu_show): Block input here, instead in Fx_popup_menu.
(xw_popup_dialog): New function, with X-specific bits of popup
dialogs.
src/xdisp.c (deep_copy_glyph_row, display_tty_menu_item): New
functions.
src/window.c (Fset_window_configuration): Use run-time tests of the
frame type instead of compile-time conditionals, when menu-bar
lines are considered.
src/w32term.h (w32con_hide_cursor, w32con_show_cursor)
(w32_popup_dialog): New prototypes.
src/w32menu.c (Fx_popup_dialog): Function deleted.
(w32_popup_dialog): New function, with w32 specific bits of popup
dialogs. Block input here.
src/w32inevt.c (w32_console_read_socket): Minor change to add
debugging TTY events.
src/w32fns.c (show_hourglass): If returning early because the frame
is not a GUI frame, unblock input.
src/w32console.c (w32con_hide_cursor, w32con_show_cursor, cursorX)
(cursorY): New functions.
src/termhooks.h (cursorX, cursorY): Prototypes of functions on
WINDOWSNT, macros that call curX and curY elsewhere.
src/termchar.h (struct tty_display_info) <showing_menu>: New flag.
src/term.c (tty_hide_cursor, tty_show_cursor) [WINDOWSNT]: Call w32
specific function to hide and show cursor on a text-mode terminal.
(tty_menu_struct, struct tty_menu_state): New structures.
(tty_menu_create, tty_menu_make_room, tty_menu_search_pane)
(tty_menu_calc_size, mouse_get_xy, tty_menu_display)
(have_menus_p, tty_menu_add_pane, tty_menu_add_selection)
(tty_menu_locate, save_and_enable_current_matrix)
(restore_desired_matrix, screen_update, read_menu_input)
(tty_menu_activate, tty_menu_destroy, tty_menu_help_callback)
(tty_pop_down_menu, tty_menu_last_menubar_item)
(tty_menu_new_item_coords, tty_menu_show): New functions.
(syms_of_term): New DEFSYMs for tty-menu-* symbols.
src/nsterm.h (ns_popup_dialog): Adjust prototype.
src/nsmenu.m (ns_menu_show): Block and unblock input here, instead
of in x-popup-menu.
(ns_popup_dialog): Adapt order of arguments to the other
*_menu_show implementations.
(Fx_popup_dialog): Function deleted.
src/msdos.c (x_set_menu_bar_lines): Delete unused function.
src/menu.h (tty_menu_show, menu_item_width): provide prototypes.
src/menu.c (have_boxes): New function.
(single_keymap_panes): Use it instead of a compile-time
conditional.
(single_menu_item): Use run-time tests of the frame type instead
of compile-time conditionals.
(encode_menu_string): New function.
(list_of_items, list_of_panes): Use it instead of ENCODE_STRING
the macro, since different types of frame need different encoding
of menu items.
(digest_single_submenu): Use run-time tests of frame type instead
of, or in addition to, compile-time conditionals.
(menu_item_width, Fmenu_bar_menu_at_x_y): New functions.
(Fx_popup_menu): Detect when the function is called from keyboard
on a TTY. Don't barf when invoked on a text-mode frame. Check
frame type at run time, instead of compile-time conditionals for
invoking terminal-specific menu-show functions. Call
tty_menu_show on text-mode frames.
(Fx_popup_dialog): Moved here from xmenu.c. Test frame types at
run time to determine which alternative to invoke; support dialogs
on TTYs.
src/keyboard.h <Qmouse_movement>: Declare.
src/keyboard.c <Qmouse_movement>: Now extern.
<Qecho_keystrokes>: New static variable.
(read_key_sequence): Accept an additional argument, a flag to
prevent redisplay during reading of the key sequence. All callers
changed.
(read_menu_command): New function.
(read_char): When COMMANDFLAG is -2, do not redisplay and do not
autosave.
(toolkit_menubar_in_use): New function.
(make_lispy_event): Use it instead of a compile-time test.
src/fns.c (Fyes_or_no_p) [HAVE_MENUS]: Don't condition on
window-system being available.
src/editfns.c (Fmessage_box) [HAVE_MENUS]: Don't condition the call
to x-popup-dialog on the frame type, they all now support popup
dialogs.
src/dispnew.c (save_current_matrix): Save the margin areas.
(restore_current_matrix): Restore margin areas.
(update_frame_with_menu): New function.
src/dispextern.h (display_tty_menu_item, update_frame_with_menu):
Add prototypes.
src/alloc.c (make_save_ptr): Now compiled unconditionally.
lisp/tmm.el (tmm-menubar): Adapt doc string to TTY menus
functionality.
lisp/tooltip.el (tooltip-mode): Don't error out on TTYs.
lisp/menu-bar.el (popup-menu, popup-menu-normalize-position): Moved
here from mouse.el.
(popup-menu): Support menu-bar navigation on TTYs using C-f/C-b
and arrow keys.
(tty-menu-navigation-map): New map for TTY menu navigation.
lisp/loadup.el ("tooltip"): Load even if x-show-tip is not available.
lisp/frame.el (display-mouse-p): Report text-mode mouse as available
on w32.
(display-popup-menus-p): Report availability if mouse is
available; don't condition on window-system.
lisp/faces.el (tty-menu-enabled-face, tty-menu-disabled-face)
(tty-menu-selected-face): New faces.
configure.ac (HAVE_MENUS): Define unconditionally.
doc/emacs/screen.texi (Menu Bar): Adapt to TTY menus.
doc/emacs/frames.texi (Frames): Mention menu support on text terminals.
doc/emacs/files.texi (Visiting): Mention the "File" menu-bar menu.
doc/emacs/display.texi (Standard Faces): Mention TTY faces for menus.
doc/lispref/keymaps.texi (Defining Menus, Mouse Menus, Menu Bar): Modify
wording to the effect that menus are supported on TTYs.
doc/lisprefframes.texi (Pop-Up Menus, Dialog Boxes)
(Display Feature Testing): Update for menu support on TTYs.
etc/NEWS: Mention the new features.
Diffstat (limited to 'src/xdisp.c')
-rw-r--r-- | src/xdisp.c | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index 5d5ce12d09..675ed63833 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -20584,7 +20584,128 @@ display_menu_bar (struct window *w) compute_line_metrics (&it); } +#ifdef HAVE_MENUS +/* Deep copy of a glyph row, including the glyphs. */ +static void +deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from) +{ + int area, i, sum_used = 0; + struct glyph *pointers[1 + LAST_AREA]; + + /* Save glyph pointers of TO. */ + memcpy (pointers, to->glyphs, sizeof to->glyphs); + + /* Do a structure assignment. */ + *to = *from; + + /* Restore original pointers of TO. */ + memcpy (to->glyphs, pointers, sizeof to->glyphs); + /* Count how many glyphs to copy and update glyph pointers. */ + for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) + { + if (area > LEFT_MARGIN_AREA) + { + eassert (from->glyphs[area] - from->glyphs[area - 1] + == from->used[area - 1]); + to->glyphs[area] = to->glyphs[area - 1] + to->used[area - 1]; + } + sum_used += from->used[area]; + } + + /* Copy the glyphs. */ + eassert (sum_used <= to->glyphs[LAST_AREA] - to->glyphs[LEFT_MARGIN_AREA]); + for (i = 0; i < sum_used; i++) + to->glyphs[LEFT_MARGIN_AREA][i] = from->glyphs[LEFT_MARGIN_AREA][i]; +} + +/* Display one menu item on a TTY, by overwriting the glyphs in the + frame F's desired glyph matrix with glyphs produced from the menu + item text. Called from term.c to display TTY drop-down menus one + item at a time. + + ITEM_TEXT is the menu item text as a C string. + + FACE_ID is the face ID to be used for this menu item. FACE_ID + could specify one of 3 faces: a face for an enabled item, a face + for a disabled item, or a face for a selected item. + + X and Y are coordinates of the first glyph in the frame's desired + matrix to be overwritten by the menu item. Since this is a TTY, Y + is the zero-based number of the glyph row and X is the zero-based + glyph number in the row, starting from left, where to start + displaying the item. + + SUBMENU non-zero means this menu item drops down a submenu, which + should be indicated by displaying a proper visual cue after the + item text. */ + +void +display_tty_menu_item (const char *item_text, int width, int face_id, + int x, int y, int submenu) +{ + struct it it; + struct frame *f = SELECTED_FRAME (); + struct window *w = XWINDOW (f->selected_window); + int saved_used, saved_truncated, saved_width, saved_reversed; + struct glyph_row *row; + size_t item_len = strlen (item_text); + + eassert (FRAME_TERMCAP_P (f)); + + 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; + row = it.glyph_row; + /* Start with the row contents from the current matrix. */ + deep_copy_glyph_row (row, f->current_matrix->rows + y); + saved_width = row->full_width_p; + row->full_width_p = 1; + saved_reversed = row->reversed_p; + row->reversed_p = 0; + row->enabled_p = 1; + + /* Arrange for the menu item glyphs to start at (X,Y) and have the + desired face. */ + it.current_x = it.hpos = x; + it.current_y = it.vpos = y; + saved_used = row->used[TEXT_AREA]; + saved_truncated = row->truncated_on_right_p; + row->used[TEXT_AREA] = x; + it.face_id = face_id; + it.line_wrap = TRUNCATE; + + /* FIXME: This should be controlled by a user option. See the + comments in redisplay_tool_bar and display_mode_line about this. + Also, if paragraph_embedding could ever be R2L, changes will be + needed to avoid shifting to the right the row characters in + term.c:append_glyph. */ + it.paragraph_embedding = L2R; + + /* Pad with a space on the left. */ + display_string (" ", Qnil, Qnil, 0, 0, &it, 1, 0, FRAME_COLS (f) - 1, -1); + width--; + /* Display the menu item, pad with spaces to WIDTH. */ + if (submenu) + { + display_string (item_text, Qnil, Qnil, 0, 0, &it, + item_len, 0, FRAME_COLS (f) - 1, -1); + width -= item_len; + /* Indicate with " >" that there's a submenu. */ + display_string (" >", Qnil, Qnil, 0, 0, &it, width, 0, + FRAME_COLS (f) - 1, -1); + } + else + display_string (item_text, Qnil, Qnil, 0, 0, &it, + width, 0, FRAME_COLS (f) - 1, -1); + + row->used[TEXT_AREA] = max (saved_used, row->used[TEXT_AREA]); + row->truncated_on_right_p = saved_truncated; + row->hash = row_hash (row); + row->full_width_p = saved_width; + row->reversed_p = saved_reversed; +} +#endif /* HAVE_MENUS */ /*********************************************************************** Mode Line |