summaryrefslogtreecommitdiff
path: root/src/xdisp.c
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2013-10-08 20:49:20 +0300
committerEli Zaretskii <eliz@gnu.org>2013-10-08 20:49:20 +0300
commit4ed774157d1687cc5236ecaf088dc48442e92431 (patch)
tree4dd32cb0104172c6b12f90c2651f58f0040bfe20 /src/xdisp.c
parent06286513730d013c2033d1dae892349e5eec98d9 (diff)
parentf3370a94fd887e9e01db81a86e42036d12dcda9b (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.c121
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