summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/.arch-inventory3
-rw-r--r--src/.gdbinit2
-rw-r--r--src/ChangeLog606
-rw-r--r--src/Makefile.in57
-rw-r--r--src/alloc.c8
-rw-r--r--src/buffer.c48
-rw-r--r--src/callint.c7
-rw-r--r--src/callproc.c316
-rw-r--r--src/cm.c216
-rw-r--r--src/cm.h118
-rw-r--r--src/coding.c62
-rw-r--r--src/coding.h10
-rw-r--r--src/config.in8
-rw-r--r--src/data.c67
-rw-r--r--src/dispextern.h92
-rw-r--r--src/dispnew.c389
-rw-r--r--src/emacs.c43
-rw-r--r--src/eval.c10
-rw-r--r--src/fileio.c6
-rw-r--r--src/fns.c7
-rw-r--r--src/fontset.c3
-rw-r--r--src/frame.c562
-rw-r--r--src/frame.h112
-rw-r--r--src/fringe.c10
-rw-r--r--src/gtkutil.c4
-rw-r--r--src/image.c3
-rw-r--r--src/indent.c2
-rw-r--r--src/keyboard.c1085
-rw-r--r--src/keyboard.h39
-rw-r--r--src/keymap.c56
-rw-r--r--src/keymap.h1
-rw-r--r--src/lisp.h27
-rw-r--r--src/lread.c12
-rw-r--r--src/macfns.c145
-rw-r--r--src/macmenu.c6
-rw-r--r--src/macterm.c121
-rw-r--r--src/macterm.h6
-rw-r--r--src/makefile.w32-in31
-rw-r--r--src/minibuf.c12
-rw-r--r--src/msdos.c16
-rw-r--r--src/prefix-args.c1
-rw-r--r--src/print.c4
-rw-r--r--src/process.c22
-rw-r--r--src/puresize.h2
-rw-r--r--src/s/darwin.h2
-rw-r--r--src/s/ms-w32.h2
-rw-r--r--src/scroll.c52
-rw-r--r--src/sysdep.c710
-rw-r--r--src/syssignal.h1
-rw-r--r--src/term.c2532
-rw-r--r--src/termchar.h203
-rw-r--r--src/termhooks.h499
-rw-r--r--src/terminal.c629
-rw-r--r--src/termopts.h5
-rw-r--r--src/w32.c12
-rw-r--r--src/w32console.c171
-rw-r--r--src/w32fns.c31
-rw-r--r--src/w32inevt.c4
-rw-r--r--src/w32inevt.h2
-rw-r--r--src/w32menu.c9
-rw-r--r--src/w32term.c241
-rw-r--r--src/w32term.h14
-rw-r--r--src/widget.c4
-rw-r--r--src/window.c4
-rw-r--r--src/window.h2
-rw-r--r--src/xdisp.c338
-rw-r--r--src/xfaces.c45
-rw-r--r--src/xfns.c384
-rw-r--r--src/xmenu.c60
-rw-r--r--src/xselect.c58
-rw-r--r--src/xsmfns.c9
-rw-r--r--src/xterm.c537
-rw-r--r--src/xterm.h11
73 files changed, 7309 insertions, 3619 deletions
diff --git a/src/.arch-inventory b/src/.arch-inventory
index fe99529135f..c21e38d47d7 100644
--- a/src/.arch-inventory
+++ b/src/.arch-inventory
@@ -3,7 +3,10 @@ source ^\.(gdbinit|dbxinit)$
# Auto-generated files, which ignore
precious ^(config\.stamp|config\.h|epaths\.h|buildobj\.lst)$
+precious ^(TAGS-LISP)$
+precious ^(buildobj\.lst)$
backup ^(stamp-oldxmenu|prefix-args|temacs|emacs|emacs-[0-9.]*)$
+backup ^(bootstrap-emacs)$
# arch-tag: 277cc7ae-b3f5-44af-abf1-84c073164543
diff --git a/src/.gdbinit b/src/.gdbinit
index 851322059a8..be91a100f49 100644
--- a/src/.gdbinit
+++ b/src/.gdbinit
@@ -1115,7 +1115,7 @@ end
tbreak init_sys_modes
commands
silent
- xgetptr Vwindow_system
+ xgetptr Vinitial_window_system
set $tem = (struct Lisp_Symbol *) $ptr
xgetptr $tem->xname
set $tem = (struct Lisp_String *) $ptr
diff --git a/src/ChangeLog b/src/ChangeLog
index 70f1656f303..5c690bfbf7c 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,609 @@
+2007-08-29 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * callproc.c (child_setup, getenv_internal): Use the
+ display-environment-variable and term-environment-variable frame
+ params.
+ (set_initial_environment): Initialise Vprocess_environment.
+
+ * config.in: Disable multi-keyboard support on a mac.
+
+ * frame.c (Qterm_environment_variable)
+ (Qdisplay_environment_variable): New variables.
+ (syms_of_frame): Intern and staticpro them.
+ (Fmake_terminal_frame): Disable output method test.
+
+ * frame.h: Declare them here.
+
+ * macfns.c (x_set_mouse_color): Get rif from the frame.
+ (x_set_tool_bar_lines): Don't use updating_frame.
+ (mac_window): Add 2 new parameters for consistency with other systems.
+ (Fx_create_frame): Fix doc string. Rename the parameter. Set the
+ frame parameters following what is done in X11 and w32. Don't use
+ FRAME_MAC_DISPLAY_INFO.
+ (Fx_open_connection, start_hourglass): Remove window-system check.
+ (x_create_tip_frame): Get the keyboard from the terminal.
+
+ * macmenu.c: Reorder includes.
+ (Fx_popup_menu): Use terminal specific mouse_position_hook.
+
+ * macterm.c (XTset_terminal_modes, XTreset_terminal_modes): Add a
+ terminal parameter.
+ (x_clear_frame): Add a frame parameter.
+ (note_mouse_movement): Get rif from the frame.
+ (mac_term_init): Initialize the terminal.
+ (mac_initialize): Make static and move terminal initialization ...
+ (mac_create_terminal): ... to this new function.
+
+ * macterm.h (struct mac_display_info): Add terminal.
+
+ * puresize.h (BASE_PURESIZE): Increase base value to 1158000.
+
+ * sysdep.c: Comment out text after #endif.
+
+ * term.c (init_tty): Only use terminal->kboard when MULTI_KBOARD
+ is defined. Better initialize ttys in windows. Use terminal
+ specific mouse_position_hook.
+
+ * termhooks.h (union display_info): Add mac_display_info.
+
+ * w32fns.c (Fx_create_frame): Use kboard from the terminal. Set
+ the default minibuffer frame, window_system and the rest of the
+ frame parameters following what is done in X11.
+
+ * w32term.c (w32_initialize): Make static.
+
+ * xselect.c (x_handle_selection_clear): Only access
+ terminal->kboard when MULTI_KBOARD is defined.
+
+ * s/darwin.h (SYSTEM_PURESIZE_EXTRA): Define here.
+ (SYSTEM_PURESIZE_EXTRA): Only define on Carbon.
+
+2007-08-29 Jason Rumney <jasonr@gnu.org>
+
+ * frame.c (Fdelete_frame): Only get kboard when MULTI_KBOARD defined.
+ (make_terminal_frame) [WINDOWSNT]: Initialize terminal.
+
+ * fringe.c (w32_init_fringe w32_reset_fringes) [HAVE_NTGUI]:
+ (mac_init_fringe) [MAC_OS]: Get rif from selected_frame.
+
+ * keyboard.c (restore_kboard_configuration): Only define when
+ MULTI_KBOARD defined.
+
+ * makefile.w32-in: Update dependancies from Makefile.in
+ (OBJ1): Add terminal.$(O)
+
+ * term.c (dissociate_if_controlling_tty) [WINDOWSNT]: Don't
+ define function body.
+ (init_tty) [WINDOWSNT]: Use selected_frame for initializing.
+
+ * termhooks.h (display_info) [WINDOWSNT]: Add w32.
+
+ * w32.c (request_sigio, unrequest_sigio): Remove.
+
+ * w32console.c (w32con_move_cursor, w32con_clear_to_end)
+ (w32con_clear_frame, w32con_clear_end_of_line)
+ (w32con_ins_del_lines, w32con_insert_glyphs, w32con_write_glyphs)
+ (w32con_delete_glyphs, w32con_set_terminal_window)
+ (scroll_line, w32_sys_ring_bell): Add frame arg.
+ (w32con_set_terminal_modes, w32con_reset_terminal_modes): Add
+ terminal arg.
+ (PICK_FRAME): Remove.
+ (w32con_write_glyphs): Use frame specific terminal coding.
+ (one_and_only_w32cons): New global variable.
+ (initialize_w32_display): Use it for storing hooks.
+ (create_w32cons_output): New function.
+
+ * w32inevt.c, w32inevt.h (w32_console_read_socket): Make first
+ arg a frame.
+
+ * w32fns.c (x_create_tip_frame): Set terminal and ref count. Set
+ window_system.
+ (x_set_tool_bar_lines): Don't use updating_frame.
+ (Fx_create_frame): Set terminal and ref count.
+ (Fx_open_connection): Remove window-system check.
+
+ * w32menu.c (Fx_popup_menu): Use terminal specific mouse_position_hook.
+
+ * w32term.c (w32_term_init): Call add_keyboard_wait_descriptor.
+ (w32_set_terminal_modes, w32_reset_terminal_modes): Add terminal arg.
+ (x_clear_frame, x_delete_glyphs, w32_ring_bell, x_ins_del_lines):
+ Add frame arg.
+ (x_delete_terminal, w32_create_terminal): New functions.
+ (w32_term_init): Create a terminal.
+ (w32_initialize): Move terminal specific initialization to
+ w32_create_terminal.
+
+ * w32term.h (x_output): Remove foreground_pixel and
+ background_pixel.
+ (w32_clear_rect, w32_clear_area): Use background from frame.
+ (w32_display_info): Add terminal.
+ (w32_sys_ring_bell, x_delete_display): Declare here.
+
+ * xdisp.c (display_menu_bar) [HAVE_NTGUI]: Check frame type.
+
+ * s/ms-w32.h (SYSTEM_PURESIZE_EXTRA): Bump to 50k.
+
+2007-08-29 Kalle Olavi Niemitalo <kon@iki.fi> (tiny change)
+
+ * keyboard.c (interrupt_signal, handle_interrupt, Fset_quit_char):
+ Fix get_named_tty calls for the controlling tty.
+
+2007-08-29 ARISAWA Akihiro <ari@mbf.ocn.ne.jp> (tiny change)
+
+ * term.c (dissociate_if_controlling_tty)[USG]: Fix parse error.
+
+2007-08-29 Yoshiaki Kasahara <kasahara@nc.kyushu-u.ac.jp> (tiny change)
+
+ * term.c (tty_insert_glyphs): Add missing first parameter.
+
+2007-08-29 Karoly Lorentey <karoly@lorentey.hu>
+
+ * buffer.c (Fbuffer_list, Fbury_buffer): Take
+ frame->buried_buffer_list into account.
+
+ * cm.c (current_tty): New variable, for cmputc().
+ (cmputc): Use it.
+ (cmcheckmagic): Add tty parameter, look up terminal streams there.
+ (calccost): Add tty parameter. Use emacs_tputs() instead of tputs().
+ (cmgoto): Add tty parameter. Pass it on to calccost(). Use
+ emacs_tputs() instead of tputs().
+
+ * cm.h (emacs_tputs): New macro to set current_tty, and then call
+ tputs().
+ (current_tty): New variable, for cmputc().
+ (cmcheckmagic, cmputc, cmgoto): Add prototypes.
+
+ * eval.c (unwind_to_catch): Don't call x_fully_uncatch_errors.
+ (internal_condition_case, internal_condition_case_1)
+ (internal_condition_case_2): Don't abort when x_catching_errors.
+
+ * fns.c (Fyes_or_no_p): Don't try to open an X dialog on tty terminals.
+ (Fy_or_n_p): Likewise. Use temporarily_switch_to_single_kboard to
+ prevent crashes caused by bogus longjmps in read_char.
+
+ * keymap.h (Fset_keymap_parent): Add EXFUN.
+
+ * macterm.h (FRAME_FOREGROUND_PIXEL, FRAME_BACKGROUND_PIXEL)
+ * w32term.h (FRAME_FOREGROUND_PIXEL, FRAME_BACKGROUND_PIXEL):
+ Remove redundant definition.
+
+ * macfns.c (x_set_mouse_color,x_make_gc): Use
+ FRAME_BACKGROUND_PIXEL and FRAME_FOREGROUND_PIXEL.
+
+ * w32term.c (x_free_frame_resources): Use
+ FRAME_BACKGROUND_PIXEL and FRAME_FOREGROUND_PIXEL.
+ (w32_initialize): Use the accessor macros for terminal characteristics.
+
+ * macterm.c (mac_initialize): Use Fset_input_interrupt_mode.
+ Use the accessor macros for terminal characteristics.
+ * msdos.c (internal_terminal_init): Use the accessor macros for
+ terminal characteristics.
+ (ScreenVisualBell,internal_terminal_init): Use
+ FRAME_BACKGROUND_PIXEL and FRAME_FOREGROUND_PIXEL.
+
+ * termopts.h (no_redraw_on_reenter): Declare.
+
+ * alloc.c (emacs_blocked_malloc): Disable mallopt call.
+ (mark_terminals,mark_ttys): Declare.
+ (Fgarbage_collect): Call them.
+ (mark_object): Mark buried_buffer_list;
+
+ * prefix-args.c: Include stdlib.h for exit.
+
+ * syssignal.h: Add comment.
+
+ * indent.c: Include stdio.h.
+
+ * window.h (Vinitial_window_system): Declare.
+ (Vwindow_system): Delete declaration.
+
+ * fontset.c (Finternal_char_font): Use FRAME_RIF.
+
+ * image.c (lookup_image): Don't initialize `c' until the xasserts
+ have been run.
+
+ * gtkutil.c (xg_create_frame_widgets): Use FRAME_BACKGROUND_PIXEL and
+ FRAME_FOREGROUND_PIXEL.
+
+ * print.c (print_preprocess): Don't lose print_depth levels while
+ iterating.
+
+ * widget.c (update_from_various_frame_slots): Use
+ FRAME_BACKGROUND_PIXEL and FRAME_FOREGROUND_PIXEL.
+
+ * window.c (set_window_buffer): Don't call clear_mouse_face on tty
+ frames.
+ (window_internal_height): Remove bogus make_number call.
+ (init_window_once): Call make_terminal_frame with two zero
+ parameters.
+
+ * fileio.c (Fread_file_name): Update comment.
+
+ * callint.c (Fcall_interactively): Use
+ temporarily_switch_to_single_kboard instead of single_kboard_state.
+ Make sure it is correctly unwound.
+
+ * xsmfns.c (x_session_close): New function.
+
+ * coding.h (terminal_coding,safe_terminal_coding,keyboard_coding):
+ Delete declarations.
+
+ * xterm.h: Remove declaration for x_fully_uncatch_errors.
+ (x_output): Remove background_pixel and foreground_pixel fields.
+ (x_display_info): Add new field TERMINAL. Remove KBOARD field.
+ (x_delete_device):
+ (x_session_close): Declare.
+
+ * lread.c: Include setjmp.h. Update declaration of `read_char'.
+ (read_filtered_event): Call `read_char' with a local
+ `wrong_kboard_jmpbuf'.
+
+ * minibuf.c (read_minibuf): Call
+ temporarily_switch_to_single_kboard. Don't call
+ single_kboard_state. Use FRAME_RIF.
+
+ * process.c (Fmake_network_process): Don't unrequest_sigio on modern
+ systems.
+
+ * lisp.h (set_process_environment): Rename to
+ `set_global_environment'.
+ (Fframe_with_environment,Fset_input_meta_mode)
+ (Fset_quit_char): EXFUN.
+ (x_create_device,tty_output,terminal,tty_display_info): Declare.
+ (init_sys_modes, reset_sys_modes): Update prototypes.
+ (init_all_sys_modes, reset_all_sys_modes): New prototypes.
+
+ * keyboard.h (struct kboard): Add new fields:
+ Vlocal_function_key_map, Vlocal_key_translation_map,
+ Vkeyboard_translate_table.
+ (Vfunction_key_map,Vkeyboard_translate_table,single_kboard_state):
+ Delete declarations.
+ (Vfunction_key_map,Vkey_translation_map,push_kboard,pop_kboard)
+ (temporarily_switch_to_single_kboard,tty_read_avail_input):
+ New declarations.
+
+ * emacs.c (main): Don't call init_sys_modes(), the new term_init()
+ already does that during init_display(). Call syms_of_keymap
+ before syms_of_keyboard. Call `syms_of_terminal'. Call
+ set_initial_environment, not set_process_environment.
+ (shut_down_emacs): Call reset_all_sys_modes() instead of
+ reset_sys_modes().
+
+ * xfaces.c (x_free_gc): Protect xassert with GLYPH_DEBUG.
+ (internal_resolve_face_name, resolve_face_name_error): New
+ functions.
+ (resolve_face_name): Protect against loops and errors thrown by
+ Fget.
+ (realize_default_face): Don't use FRAME_FONT unless frame is an X
+ frame.
+ (Ftty_supports_face_attributes_p): Update tty_capable_p call.
+
+ * scroll.c: Replace CURTTY() with local variables throughout the
+ file (where applicable).
+ (calculate_scrolling, calculate_direct_scrolling)
+ (scrolling_1, scroll_cost): Use the accessor macros for terminal
+ characteristics.
+
+ * keymap.c (Vfunction_key_map): Remove.
+ (Fdescribe_buffer_bindings): Update references to
+ Vfunction_key_map.
+ (syms_of_keymap): Remove DEFVAR for Vfunction_key_map.
+ (Vkey_translation_map): Remove.
+ (syms_of_keymap): Remove DEFVAR for key-translation-map.
+ (Fdescribe_buffer_bindings):
+ (read_key_sequence, init_kboard, syms_of_keyboard, mark_kboards):
+ Update for terminal-local key-translation-map.
+
+ * Makefile.in (callproc.o): Update dependencies.
+ (lisp, shortlisp): Add termdev.elc.
+ (obj): Add terminal.o.
+ (terminal.o): Add dependencies.
+ [HAVE_CARBON]: Make terminal.o depend on macgui.h.
+ (data.o, fns.o): Add termhooks.h dependency.
+ (SOME_MACHINE_LISP): Add dnd.elc.
+ (minibuf.o): Fix typo.
+ Update dependencies.
+
+ * data.c (do_symval_forwarding, store_symval_forwarding)
+ (find_symbol_value): Use the selected frame's keyboard, not
+ current_kboard.
+
+ * .gdbinit (init_sys_modes): Use Vinitial_window_system instead of
+ Vwindow_system.
+
+ * xmenu.c (Fx_menu_bar_open) [USE_X_TOOLKIT, USE_GTK]: Rename from
+ Fmenu_bar_open.
+ (syms_of_xmenu): Update defsubr.
+ (mouse_position_for_popup, Fx_popup_menu)
+ (Fx_popup_dialog, x_activate_menubar, update_frame_menubar)
+ (set_frame_menubar, free_frame_menubar)
+ (create_and_show_popup_menu, xmenu_show, )
+ (create_and_show_dialog, xdialog_show, xmenu_show): Abort if not
+ an X frame.
+
+ * xselect.c (x_own_selection): Abort if not an X frame.
+ (some_frame_on_display): Check if it is an X frame.
+ (x_handle_selection_clear): Deal with MULTI_KBOARD.
+
+ * coding.c: Include frame.h and termhooks.h.
+ (terminal_coding,keyboard_coding): Delete.
+ (Fset_terminal_coding_system_internal):
+ (Fset_keyboard_coding_system_internal):
+ (Fkeyboard_coding_system):
+ (Fterminal_coding_system): Add a terminal parameter. Get
+ terminal_coding from the terminal.
+ (init_coding_once): Don't call setup_coding_system here.
+
+ * dispextern.h (set_scroll_region, turn_off_insert)
+ (turn_off_highlight, background_highlight, clear_end_of_line_raw)
+ (tty_clear_end_of_line, tty_setup_colors)
+ (delete_tty,updating_frame)
+ (produce_special_glyphs, produce_glyphs, write_glyphs)
+ (insert_glyphs): Remove.
+ (raw_cursor_to, clear_to_end, tty_turn_off_insert)
+ (tty_turn_off_highlight,get_tty_size): Add declaration.
+ (tabs_safe_p, init_baud_rate, get_tty_terminal): Update
+ prototypes.
+
+ * frame.h (enum output_method): Add output_initial.
+ (struct x_output): Delete.
+ (FRAME_FOREGROUND_PIXEL, FRAME_BACKGROUND_PIXEL): Access
+ foreground_pixel and background_pixel directly from the frame.
+ (tty_display): Delete.
+ (struct frame): Add buried_buffer_list, foreground_pixel,
+ background_pixel and terminal. Delete kboard
+ (union output_data): Add tty.
+ (FRAME_KBOARD): Get the kboard from the terminal.
+ (FRAME_INITIAL_P): New macro.
+ (Qtty, Qtty_type, Qterminal, Qterminal_live_p, Qenvironment)
+ (Qterm_environment_variable, Qdisplay_environment_variable)
+ (make_terminal_frame, Qburied_buffer_list, Qwindow_system): New
+ declarations.
+
+ * termchar.h (tty_output, tty_display_info): New structures.
+ (tty_list): Declare.
+ (FRAME_TTY, CURTTY): New macros.
+ (must_write_spaces, min_padding_speed, fast_clear_end_of_line)
+ (line_ins_del_ok, char_ins_del_ok, scroll_region_ok)
+ (scroll_region_cost, memory_below_frame, fast_clear_end_of_line)
+ (dont_calculate_costs, no_redraw_on_reenter): Remove declarations.
+
+ * callproc.c: Include frame.h and termhooks.h, for terminal
+ parameters.
+ (add_env): New function.
+ (child_setup): Use it.
+ (child_setup, getenv_internal): Handle the new
+ Vprocess_environment.
+ (getenv_internal): Fix get_terminal_param call.
+ (Fgetenv_internal, egetenv): Update doc.
+ (syms_of_callproc): Initialize Vprocess_environment to nil.
+ Register and initialize them. Remove obsolete defvars. Update doc
+ strings.
+ (child_setup): Handle Vlocal_environment_variables.
+ (getenv_internal): Add terminal parameter. Handle
+ Vlocal_environment_variables.
+ (Fgetenv_internal): Add terminal parameter.
+ (child_setup, getenv_internal, Fgetenv_internal): Store the local
+ environment in a frame (not terminal) parameter. Update doc
+ strings.
+ (set_initial_environment): Rename from set_global_environment.
+ Store Emacs environment in initial frame parameter.
+
+ * xdisp.c (redisplay_internal): Update references to
+ `previous_terminal_frame'.
+ (display_mode_line, Fformat_mode_line): Replace calls to
+ `push_frame_kboard' with `push_kboard'.
+ (get_glyph_string_clip_rects): Add extra parentheses and
+ braces to prevent compiler warnings.
+ (calc_pixel_width_or_height): Add xassert to check that the
+ frame is alive. Don't call `lookup_image' on a termcap frame.
+ (message2_nolog, message3_nolog, redisplay_internal)
+ (set_vertical_scroll_bar, redisplay_window, check_x_display_info)
+ (x_set_scroll_bar_foreground, x_set_scroll_bar_background)
+ (Fx_create_frame, Fxw_display_color_p, Fx_display_grayscale_p)
+ (Fx_display_pixel_width, Fx_display_pixel_height)
+ (Fx_display_planes, Fx_display_color_cells)
+ (Fx_server_max_request_size, Fx_server_vendor, Fx_server_version)
+ (Fx_display_screens, Fx_display_mm_height, Fx_display_mm_width)
+ (Fx_display_backing_store, Fx_display_visual_class)
+ (Fx_display_save_under, Fx_close_connection, x_create_tip_frame):
+ Use FRAME_TERMINAL_P, FRAME_WINDOW_P, FRAME_TTY and FRAME_RIF.
+
+ * xfns.c (x_set_foreground_color x_set_background_color)
+ (x_set_mouse_color, x_set_cursor_color, x_make_gc): Use
+ FRAME_BACKGROUND_PIXEL and FRAME_FOREGROUND_PIXEL.
+ (Fx_create_frame, x_create_tip_frame, build_string, x_window)
+ (Fx_create_frame, x_create_tip_frame): Don't create frames on a
+ terminal that is being deleted.
+ (Fx_create_frame): Use `store_frame_param' to set `window-system'
+ frame parameter, and make sure it overrides any user-supplied
+ setting.
+ (Fx_close_connection, Fx_synchronize): Unify argument names with
+ the rest of the DEFUNs.
+
+ * dispnew.c (Fsend_string_to_terminal): Update call to
+ `get_tty_terminal'.
+ (Fredraw_frame, Fsend_string_to_terminal)
+ (Fsend_string_to_terminal, init_display): User FRAME_RIF,
+ FRAME_TERMCAP_P and FRAME_TTY.
+ (window_change_signal): Don't believe width/height values that are
+ impossibly small.
+ (Vinitial_window_system): Rename from Vwindow_system.
+ (termscript, Wcm, rif): Delete.
+
+ * termhooks.h (struct terminal): New struct containing the
+ previously global text display hooks and new members NAME,
+ DELETED and PARAM_ALIST.
+ (FRAME_TERMINAL, TERMINAL_TERMINAL_CODING)
+ (TERMINAL_KEYBOARD_CODING, TERMINAL_ACTIVE_P, FRAME_WINDOW_P)
+ (FRAME_RIF): New macros.
+ (get_terminal_param, get_device): New declarations.
+ (termscript): Delete declaration.
+
+ * xterm.c (x_initialize): Use Fset_input_interrupt_mode.
+ (XTflash, x_free_frame_resources, x_scroll_bar_create)
+ (x_scroll_bar_set_handle): Use FRAME_BACKGROUND_PIXEL and
+ FRAME_FOREGROUND_PIXEL.
+ (x_fully_uncatch_errors): Disable definition.
+ (x_scroll_bar_expose): Fix reference to foreground pixel.
+ (XTread_socket): Disable loop on all X displays.
+ (x_delete_terminal): Don't set terminal->deleted and let
+ delete_terminal delete the frames on the terminal.
+ (x_delete_display): Doc update to reflect changes in
+ delete_terminal.
+ (x_display_info) <terminal>: Move member earlier in the struct.
+ (x_delete_terminal): Use terminal->deleted. Delete all frames on
+ the display explicitly.
+ (deleting_tty): Remove old variable.
+ (Fsuspend_tty): Call clear_tty_hooks.
+ (Fresume_tty, init_tty): Call set_tty_hooks.
+ (clear_tty_hooks, set_tty_hooks): New functions.
+ (Ftty_display_color_p, Ftty_display_color_cells): Don't throw
+ errors on X frames.
+ (x_catch_errors_unwind): Abort if x_error_message is NULL.
+ (handle_one_xevent): Initialize `f' to NULL.
+ (x_delete_device, x_create_device): New functions.
+ (XTset_terminal_modes, XTreset_terminal_modes)
+ (XTread_socket, x_connection_closed, x_term_init)
+ (x_term_init, x_delete_display): Add terminal parameter.
+ (x_term_init) [!HAVE_GTK_MULTIDISPLAY]: Refuse to create secondary
+ X connections.
+
+ * frame.c (Fframep): Deal with output_initial.
+ (Qbuffer_predicate, Qbuffer_list, Qburied_buffer_list, Qtty)
+ (Qtty_type, Qwindow_system, Qenvironment)
+ (Qterm_environment_variable, Qdisplay_environment_variable): New
+ variables.
+ (x_set_screen_gamma, store_frame_param): Fix compilation errors.
+ (make_terminal_frame): Don't create frames on a terminal that is
+ being deleted.
+ (make_terminal_frame): Use FRAME_BACKGROUND_PIXEL and
+ FRAME_FOREGROUND_PIXEL.
+ (store_frame_param): Check for found_for_frame before calling
+ XFRAME.
+ (Fmake_terminal_frame): Handle NULL tty names correctly.
+ (syms_of_frame): Enhance doc string of `default-frame-alist'.
+ (Fdelete_frame): Remove unused variable `count'.
+ (Qenvironment): New variable.
+ (Fdelete_frame): Don't allow other frames to refer to a deleted
+ frame in their 'environment parameter.
+ (Fframe_with_environment): New function.
+ (syms_of_frame): Defsubr it. Initialize and staticpro
+ Qenvironment.
+ (get_future_frame_param): New function.
+ (Fmake_terminal_frame): Use it.
+
+ * sysdep.c (init_sys_modes, reset_sys_modes): Update for renames.
+ * sysdep.c (reset_sys_modes): Update for renames.
+
+ * keyboard.c (tty_read_avail_input): New function.
+ (Fset_input_interrupt_mode,Fset_output_flow_control): New
+ functions.
+ (syms_of_keyboard): Defsubr them.
+ (Fset_input_meta_mode, Fset_quit_char): New functions.
+ (Fset_input_mode): Split to above functions.
+
+ (read_char_minibuf_menu_prompt): Add wrong_kboard_jmpbuf
+ parameter. Use it in call to `read_char'.
+ (read_char): Declare. Update call to
+ `read_char_minibuf_menu_prompt'. Set wrong_kboard_jmpbuf
+ correctly in recursive calls. Use current_kboard to access
+ Vkeyboard_translate_table. Enhance comment before extra longjmp
+ to wrong_kboard_jmpbuf. Add wrong_kboard_jmpbuf parameter to
+ allow for recursive calls. Update longjmp invocations. Remember
+ the original current_kboard, and longjmp to `wrong_kboard_jmpbuf'
+ when a filter, timer or sentinel changes it. Comment out
+ unnecessary calls to `record_single_kboard_state' and
+ `any_kboard_state'. Update recursive calls.
+ (wrong_kboard_jmpbuf): Remove global variable.
+ (read_key_sequence): Remove unused variable wrong_kboard_jmpbuf.
+ Handle deleted interrupted_kboards correctly; that is a legal
+ case. Add `wrong_kboard_jmpbuf' local variable. Update setjmp
+ and read_char calls. Abort if interrupted_kboard died in
+ read_char.
+ (any_kboard_state, single_kboard_state)
+ (push_frame_kboard): Remove function.
+ (pop_kboard): Switch out of single_kboard mode if the kboard has
+ been deleted. Remove unused variable. Help debugging by not
+ changing current_kboard unnecessarily. Set current_kboard to the
+ kboard of the selected frame when the stored kboard object has
+ been deleted before pop_kboard.
+ (temporarily_switch_to_single_kboard): Change first parameter to a
+ frame pointer. Throw an error when caller wants to change kboards
+ while in single_kboard mode. Don't push_kboard if we weren't in
+ single kboard state. Don't pop_kboard if we popped into any
+ kboard state.
+ (restore_kboard_configuration): Abort if pop_kboard changed the
+ kboard in single_kboard mode. Call pop_kboard only after setting
+ up single_kboard mode.
+ (Frecursive_edit): Switch to single_kboard mode only in nested
+ command loops.
+ (cmd_error, command_loop, command_loop_1, timer_check): Comment
+ out unnecessary call to `any_kboard_state' and
+ `record_single_kboard_state'.
+ (delete_kboard): Exit single_kboard mode if we have just deleted
+ that kboard. Use FRAME_KBOARD.
+ (interrupt_signal): Use `Fkill_emacs' to exit Emacs, not
+ `fatal_error_signal'.
+ (record_single_kboard_state): Don't push_kboard if we weren't in
+ single kboard state. Don't pop_kboard if we popped into any
+ kboard state.
+ (push_frame_kboard): Rename to push_kboard.
+ (kbd_buffer_get_event): Use FRAME_TERMINAL.
+ (read_avail_input): Read input from all terminals.
+ (mark_kboards): Also mark Vkeyboard_translate_table.
+ (kbd_buffer_store_event_hold): Simplify condition.
+ (read_key_sequence): Reinitialize fkey and keytran at each replay.
+ (Vkeyboard_translate_table): Move to struct kboard.
+ (init_kboard): Initialize Vkeyboard_translate_table.
+ (syms_of_keyboard): Use DEFVAR_KBOARD to define
+ Vkeyboard_translate_table. Update doc strings. Update docs of
+ local-function-key-map and function-key-map.
+
+ * terminal.c: New file.
+
+ * term.c: Include errno.h.
+ (Vring_bell_function, device_list, initial_device)
+ (next_device_id, ring_bell, update_begin, update_end)
+ (set_terminal_window, cursor_to, raw_cursor_to)
+ (clear_to_end, clear_frame, clear_end_of_line)
+ (write_glyphs, insert_glyphs, delete_glyphs, ins_del_lines)
+ (Fdisplay_name, create_device, delete_device): Move to terminal.c.
+ (syms_of_term): Move their initialization to terminal.c.
+ (get_tty_terminal, Fdisplay_tty_type, Ftty_display_color_p)
+ (Ftty_display_color_cells)
+ (Ftty_no_underline, Fsuspend_tty, Fresume_tty, create_tty_output)
+ (init_tty, maybe_fatal): New functions.
+ (Ftty_type): Return nil if terminal is not on a tty instead of
+ throwing an error. Doc update.
+ (syms_of_term) <Vsuspend_tty_functions, Vresume_tty_functions>:
+ Doc update. Initialize new subrs and variables.
+ (delete_tty): Use terminal->deleted.
+ (tty_set_terminal_modes): Rename from set_terminal_modes.
+ (tty_reset_terminal_modes): Rename from reset_terminal_modes.
+ (set_scroll_region): Rename to `tty_set_scroll_region'.
+ (turn_on_insert): Rename to `tty_turn_on_insert'.
+ (turn_off_insert): Rename to `tty_turn_off_insert'.
+ (turn_off_highlight): Rename to `tty_turn_off_highlight'.
+ (turn_on_highlight): Rename to `tty_turn_on_highlight'.
+ (toggle_highligh): Rename to `tty_toggle_highlight'.
+ (background_highlight): Rename to `tty_background_highlight'.
+ (highlight_if_desired): Rename to `tty_highlight_if_desired'.
+ (tty_ring_bell, tty_update_end, tty_set_terminal_window)
+ (tty_set_scroll_region, tty_background_highlight)
+ (tty_cursor_to, tty_raw_cursor_to, tty_clear_to_end)
+ (tty_clear_frame, tty_clear_end_of_line, tty_write_glyphs)
+ (tty_insert_glyphs, tty_delete_glyphs, tty_ins_del_lines)
+ (term_get_fkeys, tty_setup_colors, dissociate_if_controlling_tty):
+ Add static modifier.
+ (tty_reset_terminal_modes, tty_set_terminal_window)
+ (tty_set_scroll_region, tty_background_highlight)
+ (tty_highlight_if_desired, tty_cursor_to)
+ (tty_raw_cursor_to, tty_clear_to_end, tty_clear_frame)
+ (tty_clear_end_of_line, tty_write_glyphs, tty_insert_glyphs)
+ (tty_delete_glyphs, tty_ins_del_lines, turn_on_face): Update for
+ renames.
+
2007-08-28 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
* keyboard.c: Qrtl is new.
diff --git a/src/Makefile.in b/src/Makefile.in
index d34c272faa4..86c394f7bb2 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -595,7 +595,7 @@ emacsappsrc = ${srcdir}/../mac/Emacs.app/
whose initialized data areas should be dumped as pure by dump-emacs. */
obj= dispnew.o frame.o scroll.o xdisp.o $(XMENU_OBJ) window.o \
charset.o coding.o category.o ccl.o \
- cm.o term.o xfaces.o $(XOBJ) $(GTK_OBJ)\
+ cm.o term.o terminal.o xfaces.o $(XOBJ) $(GTK_OBJ)\
emacs.o keyboard.o macros.o keymap.o sysdep.o \
buffer.o filelock.o insdel.o marker.o \
minibuf.o fileio.o dired.o filemode.o \
@@ -741,6 +741,7 @@ otherobj= $(termcapobj) lastfile.o $(mallocobj) $(allocaobj) $(widgetobj) $(LIBO
lisp= \
${lispsource}abbrev.elc \
${lispsource}buff-menu.elc \
+ ${lispsource}server.elc \
${lispsource}button.elc \
${lispsource}emacs-lisp/byte-run.elc \
${lispsource}cus-face.elc \
@@ -757,6 +758,7 @@ lisp= \
MOUSE_SUPPORT \
${lispsource}emacs-lisp/float-sup.elc \
${lispsource}frame.elc \
+ ${lispsource}termdev.elc \
${lispsource}help.elc \
${lispsource}indent.elc \
${lispsource}isearch.elc \
@@ -840,6 +842,7 @@ lisp= \
shortlisp= \
../lisp/abbrev.elc \
../lisp/buff-menu.elc \
+ ../lisp/server.elc \
../lisp/button.elc \
../lisp/emacs-lisp/byte-run.elc \
../lisp/cus-face.elc \
@@ -854,6 +857,7 @@ shortlisp= \
../lisp/emacs-lisp/float-sup.elc \
../lisp/format.elc \
../lisp/frame.elc \
+ ../lisp/termdev.elc \
../lisp/help.elc \
../lisp/indent.elc \
../lisp/isearch.elc \
@@ -943,7 +947,9 @@ SOME_MACHINE_LISP = ${dotdot}/lisp/mouse.elc \
${dotdot}/lisp/x-dnd.elc \
${dotdot}/lisp/international/ccl.elc \
${dotdot}/lisp/international/codepage.elc \
- ${dotdot}/lisp/international/fontset.elc
+ ${dotdot}/lisp/international/fontset.elc \
+ ${dotdot}/lisp/mouse.elc \
+ ${dotdot}/lisp/term/x-win.elc
/* Construct full set of libraries to be linked.
Note that SunOS needs -lm to come before -lc; otherwise, you get
@@ -989,7 +995,7 @@ emacs${EXEEXT}: temacs${EXEEXT} ${etc}DOC ${lisp}
for the first time, this prevents any variation between configurations
in the contents of the DOC file.
Likewise for ${SOME_MACHINE_LISP}. */
-${etc}DOC: ${libsrc}make-docfile${EXEEXT} ${obj} ${shortlisp} ${SOME_MACHINE_LISP}
+${etc}DOC: ${libsrc}make-docfile ${obj} ${shortlisp} ${SOME_MACHINE_LISP}
-rm -f ${etc}DOC
${libsrc}make-docfile -d ${srcdir} ${SOME_MACHINE_OBJECTS} ${obj} > ${etc}DOC
${libsrc}make-docfile -a ${etc}DOC -d ${srcdir} ${SOME_MACHINE_LISP} ${shortlisp}
@@ -1112,7 +1118,7 @@ callint.o: callint.c window.h commands.h buffer.h keymap.h \
keyboard.h dispextern.h $(config_h)
callproc.o: callproc.c epaths.h buffer.h commands.h $(config_h) \
process.h systty.h syssignal.h charset.h coding.h ccl.h msdos.h \
- composite.h w32.h blockinput.h atimer.h systime.h
+ composite.h w32.h blockinput.h atimer.h systime.h frame.h termhooks.h
casefiddle.o: casefiddle.c syntax.h commands.h buffer.h composite.h \
charset.h keymap.h $(config_h)
casetab.o: casetab.c buffer.h $(config_h)
@@ -1121,8 +1127,8 @@ ccl.o: ccl.c ccl.h charset.h coding.h $(config_h)
charset.o: charset.c charset.h buffer.h coding.h composite.h disptab.h \
$(config_h)
coding.o: coding.c coding.h ccl.h buffer.h charset.h intervals.h composite.h \
- window.h dispextern.h $(config_h)
-cm.o: cm.c cm.h termhooks.h $(config_h)
+ window.h dispextern.h frame.h termhooks.h $(config_h)
+cm.o: cm.c frame.h cm.h termhooks.h termchar.h $(config_h)
cmds.o: cmds.c syntax.h buffer.h charset.h commands.h window.h $(config_h) \
msdos.h dispextern.h keyboard.h keymap.h
pre-crt0.o: pre-crt0.c
@@ -1130,7 +1136,7 @@ ecrt0.o: ecrt0.c $(config_h)
CRT0_COMPILE ${srcdir}/ecrt0.c
dired.o: dired.c commands.h buffer.h $(config_h) charset.h coding.h regex.h \
systime.h blockinput.h atimer.h
-dispnew.o: dispnew.c systty.h systime.h commands.h process.h frame.h \
+dispnew.o: dispnew.c systime.h commands.h process.h frame.h \
window.h buffer.h dispextern.h termchar.h termopts.h termhooks.h cm.h \
disptab.h indent.h intervals.h \
xterm.h blockinput.h atimer.h charset.h msdos.h composite.h keyboard.h \
@@ -1151,10 +1157,10 @@ filelock.o: filelock.c buffer.h charset.h coding.h systime.h epaths.h $(config_h
filemode.o: filemode.c $(config_h)
frame.o: frame.c xterm.h window.h frame.h termhooks.h commands.h keyboard.h \
blockinput.h atimer.h systime.h buffer.h charset.h fontset.h \
- msdos.h dosfns.h dispextern.h w32term.h macterm.h $(config_h)
-fringe.o: fringe.c dispextern.h frame.h window.h buffer.h $(config_h)
+ msdos.h dosfns.h dispextern.h w32term.h macterm.h termchar.h $(config_h)
+fringe.o: fringe.c dispextern.h frame.h window.h buffer.h termhooks.h $(config_h)
fontset.o: dispextern.h fontset.h fontset.c ccl.h buffer.h charset.h frame.h \
- keyboard.h $(config_h)
+ keyboard.h termhooks.h $(config_h)
getloadavg.o: getloadavg.c $(config_h)
image.o: image.c frame.h window.h dispextern.h blockinput.h atimer.h \
systime.h xterm.h w32term.h w32gui.h macterm.h macgui.h $(config_h)
@@ -1165,7 +1171,7 @@ insdel.o: insdel.c window.h buffer.h $(INTERVAL_SRC) blockinput.h charset.h \
dispextern.h atimer.h systime.h region-cache.h $(config_h)
keyboard.o: keyboard.c termchar.h termhooks.h termopts.h buffer.h charset.h \
commands.h frame.h window.h macros.h disptab.h keyboard.h syssignal.h \
- systty.h systime.h dispextern.h syntax.h $(INTERVAL_SRC) blockinput.h \
+ systime.h dispextern.h syntax.h $(INTERVAL_SRC) blockinput.h \
atimer.h xterm.h puresize.h msdos.h keymap.h w32term.h macterm.h $(config_h)
keymap.o: keymap.c buffer.h commands.h keyboard.h termhooks.h blockinput.h \
atimer.h systime.h puresize.h charset.h intervals.h keymap.h window.h \
@@ -1180,7 +1186,8 @@ vm-limit.o: vm-limit.c mem-limits.h $(config_h)
marker.o: marker.c buffer.h charset.h $(config_h)
md5.o: md5.c md5.h $(config_h)
minibuf.o: minibuf.c syntax.h dispextern.h frame.h window.h keyboard.h \
- buffer.h commands.h charset.h msdos.h $(INTERVAL_SRC) keymap.h $(config_h)
+ buffer.h commands.h charset.h msdos.h $(INTERVAL_SRC) keymap.h \
+ termhooks.h $(config_h)
mktime.o: mktime.c $(config_h)
msdos.o: msdos.c msdos.h dosfns.h systime.h termhooks.h dispextern.h frame.h \
termopts.h termchar.h charset.h coding.h ccl.h disptab.h window.h \
@@ -1192,7 +1199,7 @@ process.o: process.c process.h buffer.h window.h termhooks.h termopts.h \
regex.o: regex.c syntax.h buffer.h $(config_h) regex.h category.h charset.h
region-cache.o: region-cache.c buffer.h region-cache.h $(config_h)
scroll.o: scroll.c termchar.h dispextern.h frame.h msdos.h keyboard.h \
- $(config_h)
+ termhooks.h $(config_h)
search.o: search.c regex.h commands.h buffer.h region-cache.h syntax.h \
blockinput.h atimer.h systime.h category.h charset.h composite.h \
$(INTERVAL_SRC) $(config_h)
@@ -1201,11 +1208,13 @@ syntax.o: syntax.c syntax.h buffer.h commands.h category.h charset.h \
composite.h keymap.h regex.h $(INTERVAL_SRC) $(config_h)
sysdep.o: sysdep.c syssignal.h systty.h systime.h syswait.h blockinput.h \
process.h dispextern.h termhooks.h termchar.h termopts.h \
- frame.h atimer.h window.h msdos.h dosfns.h keyboard.h $(config_h)
+ frame.h atimer.h window.h msdos.h dosfns.h keyboard.h cm.h $(config_h)
term.o: term.c termchar.h termhooks.h termopts.h $(config_h) cm.h frame.h \
disptab.h dispextern.h keyboard.h charset.h coding.h ccl.h msdos.h \
window.h keymap.h blockinput.h atimer.h systime.h
termcap.o: termcap.c $(config_h)
+terminal.o: terminal.c frame.h termchar.h termhooks.h charset.h coding.h \
+ keyboard.h $(config_h)
terminfo.o: terminfo.c $(config_h)
tparam.o: tparam.c $(config_h)
undo.o: undo.c buffer.h commands.h window.h $(config_h)
@@ -1218,7 +1227,7 @@ w16select.o: w16select.c dispextern.h frame.h blockinput.h atimer.h systime.h \
widget.o: widget.c xterm.h frame.h dispextern.h widgetprv.h \
$(srcdir)/../lwlib/lwlib.h $(config_h)
window.o: window.c indent.h commands.h frame.h window.h buffer.h termchar.h \
- termhooks.h disptab.h keyboard.h dispextern.h msdos.h composite.h \
+ disptab.h keyboard.h dispextern.h msdos.h composite.h \
keymap.h blockinput.h atimer.h systime.h $(INTERVAL_SRC) \
xterm.h w32term.h macterm.h $(config_h)
xdisp.o: xdisp.c macros.h commands.h process.h indent.h buffer.h dispextern.h coding.h \
@@ -1227,10 +1236,11 @@ xdisp.o: xdisp.c macros.h commands.h process.h indent.h buffer.h dispextern.h co
msdos.h composite.h fontset.h blockinput.h atimer.h systime.h keymap.h
xfaces.o: xfaces.c dispextern.h frame.h xterm.h buffer.h blockinput.h \
window.h charset.h msdos.h dosfns.h composite.h atimer.h systime.h \
- keyboard.h fontset.h w32term.h macterm.h $(INTERVAL_SRC) $(config_h)
+ keyboard.h fontset.h w32term.h macterm.h $(INTERVAL_SRC) termchar.h \
+ termhooks.h $(config_h)
xfns.o: xfns.c buffer.h frame.h window.h keyboard.h xterm.h dispextern.h \
$(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h epaths.h \
- charset.h gtkutil.h $(config_h)
+ charset.h gtkutil.h termchar.h termhooks.h $(config_h)
xmenu.o: xmenu.c xterm.h termhooks.h window.h dispextern.h frame.h buffer.h \
keyboard.h $(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h \
gtkutil.h msdos.h coding.h $(config_h)
@@ -1239,7 +1249,7 @@ xterm.o: xterm.c xterm.h termhooks.h termopts.h termchar.h window.h buffer.h \
keyboard.h gnu.h charset.h ccl.h fontset.h composite.h \
coding.h process.h gtkutil.h $(config_h)
xselect.o: xselect.c process.h dispextern.h frame.h xterm.h blockinput.h \
- buffer.h atimer.h systime.h $(config_h)
+ buffer.h atimer.h systime.h termhooks.h $(config_h)
xrdb.o: xrdb.c $(config_h) epaths.h
xsmfns.o: xsmfns.c $(config_h) systime.h sysselect.h termhooks.h xterm.h \
lisp.h termopts.h
@@ -1257,19 +1267,18 @@ alloc.o: alloc.c process.h frame.h window.h buffer.h puresize.h syssignal.h key
blockinput.h atimer.h systime.h charset.h dispextern.h $(config_h) $(INTERVAL_SRC)
bytecode.o: bytecode.c buffer.h syntax.h charset.h window.h dispextern.h \
frame.h xterm.h $(config_h)
-data.o: data.c buffer.h puresize.h charset.h syssignal.h keyboard.h frame.h $(config_h)
+data.o: data.c buffer.h puresize.h charset.h syssignal.h keyboard.h frame.h termhooks.h $(config_h)
eval.o: eval.c commands.h keyboard.h blockinput.h atimer.h systime.h \
dispextern.h $(config_h)
floatfns.o: floatfns.c $(config_h)
fns.o: fns.c commands.h $(config_h) frame.h buffer.h charset.h keyboard.h \
keymap.h frame.h window.h dispextern.h $(INTERVAL_SRC) coding.h md5.h \
- blockinput.h atimer.h systime.h xterm.h
+ blockinput.h atimer.h systime.h xterm.h termhooks.h
print.o: print.c process.h frame.h window.h buffer.h keyboard.h charset.h \
$(config_h) dispextern.h termchar.h $(INTERVAL_SRC) msdos.h composite.h \
blockinput.h atimer.h systime.h
lread.o: lread.c commands.h keyboard.h buffer.h epaths.h charset.h \
- $(config_h) $(INTERVAL_SRC) termhooks.h coding.h msdos.h blockinput.h \
- atimer.h systime.h
+ $(config_h) $(INTERVAL_SRC) termhooks.h coding.h msdos.h
/* Text properties support */
textprop.o: textprop.c buffer.h window.h dispextern.h $(INTERVAL_SRC) \
@@ -1282,12 +1291,12 @@ composite.o: composite.c buffer.h charset.h $(INTERVAL_SRC) $(config_h)
OTHER_FILES and OBJECTS_MACHINE
select which of these should be compiled. */
-sunfns.o: sunfns.c buffer.h window.h dispextern.h $(config_h)
+sunfns.o: sunfns.c buffer.h window.h dispextern.h termhooks.h $(config_h)
#ifdef HAVE_CARBON
abbrev.o buffer.o callint.o cmds.o dispnew.o editfns.o fileio.o frame.o \
fontset.o indent.o insdel.o keyboard.o macros.o minibuf.o msdos.o process.o \
- scroll.o sysdep.o term.o widget.o window.o xdisp.o xfaces.o xfns.o xmenu.o \
+ scroll.o sysdep.o term.o terminal.o widget.o window.o xdisp.o xfaces.o xfns.o xmenu.o \
xterm.o xselect.o sound.o: macgui.h
mac.o: mac.c process.h sysselect.h blockinput.h atimer.h systime.h charset.h \
coding.h ccl.h $(config_h)
diff --git a/src/alloc.c b/src/alloc.c
index 2947e48f815..8aea81a0f72 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -341,7 +341,9 @@ Lisp_Object Vgc_elapsed; /* accumulated elapsed time in GC */
EMACS_INT gcs_done; /* accumulated GCs */
static void mark_buffer P_ ((Lisp_Object));
+extern void mark_terminals P_ ((void));
extern void mark_kboards P_ ((void));
+extern void mark_ttys P_ ((void));
extern void mark_backtrace P_ ((void));
static void gc_sweep P_ ((void));
static void mark_glyph_matrix P_ ((struct glyph_matrix *));
@@ -1234,7 +1236,8 @@ emacs_blocked_malloc (size, ptr)
BLOCK_INPUT_ALLOC;
__malloc_hook = old_malloc_hook;
#ifdef DOUG_LEA_MALLOC
- mallopt (M_TOP_PAD, malloc_hysteresis * 4096);
+ /* Segfaults on my system. --lorentey */
+ /* mallopt (M_TOP_PAD, malloc_hysteresis * 4096); */
#else
__malloc_extra_blocks = malloc_hysteresis;
#endif
@@ -5170,7 +5173,9 @@ returns nil, because real GC can't be done. */)
mark_object (bind->symbol);
mark_object (bind->old_value);
}
+ mark_terminals ();
mark_kboards ();
+ mark_ttys ();
#ifdef USE_GTK
{
@@ -5605,6 +5610,7 @@ mark_object (arg)
mark_object (ptr->menu_bar_vector);
mark_object (ptr->buffer_predicate);
mark_object (ptr->buffer_list);
+ mark_object (ptr->buried_buffer_list);
mark_object (ptr->menu_bar_window);
mark_object (ptr->tool_bar_window);
mark_face_cache (ptr->face_cache);
diff --git a/src/buffer.c b/src/buffer.c
index 127bfba44e0..8cd13b07855 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -215,25 +215,38 @@ frame parameter come first, followed by the rest of the buffers. */)
(frame)
Lisp_Object frame;
{
- Lisp_Object framelist, general;
+ Lisp_Object general;
general = Fmapcar (Qcdr, Vbuffer_alist);
if (FRAMEP (frame))
{
- Lisp_Object tail;
+ Lisp_Object framelist, prevlist, tail;
+ Lisp_Object args[3];
CHECK_FRAME (frame);
framelist = Fcopy_sequence (XFRAME (frame)->buffer_list);
+ prevlist = Fnreverse (Fcopy_sequence (XFRAME (frame)->buried_buffer_list));
- /* Remove from GENERAL any buffer that duplicates one in FRAMELIST. */
+ /* Remove from GENERAL any buffer that duplicates one in
+ FRAMELIST or PREVLIST. */
tail = framelist;
- while (! NILP (tail))
+ while (CONSP (tail))
{
general = Fdelq (XCAR (tail), general);
tail = XCDR (tail);
}
- return nconc2 (framelist, general);
+ tail = prevlist;
+ while (CONSP (tail))
+ {
+ general = Fdelq (XCAR (tail), general);
+ tail = XCDR (tail);
+ }
+
+ args[0] = framelist;
+ args[1] = general;
+ args[2] = prevlist;
+ return Fnconc (3, args);
}
return general;
@@ -1583,6 +1596,23 @@ record_buffer (buf)
XSETCDR (link, Vbuffer_alist);
Vbuffer_alist = link;
+ /* Effectively do a delq on buried_buffer_list. */
+
+ prev = Qnil;
+ for (link = XFRAME (frame)->buried_buffer_list; CONSP (link);
+ link = XCDR (link))
+ {
+ if (EQ (XCAR (link), buf))
+ {
+ if (NILP (prev))
+ XFRAME (frame)->buried_buffer_list = XCDR (link);
+ else
+ XSETCDR (prev, XCDR (XCDR (prev)));
+ break;
+ }
+ prev = link;
+ }
+
/* Now move this buffer to the front of frame_buffer_list also. */
prev = Qnil;
@@ -2065,10 +2095,10 @@ selected window if it is displayed there. */)
XSETCDR (link, Qnil);
Vbuffer_alist = nconc2 (Vbuffer_alist, link);
- /* Removing BUFFER from frame-specific lists
- has the effect of putting BUFFER at the end
- of the combined list in each frame. */
- frames_discard_buffer (buffer);
+ XFRAME (selected_frame)->buffer_list
+ = Fdelq (buffer, XFRAME (selected_frame)->buffer_list);
+ XFRAME (selected_frame)->buried_buffer_list
+ = Fcons (buffer, Fdelq (buffer, XFRAME (selected_frame)->buried_buffer_list));
}
return Qnil;
diff --git a/src/callint.c b/src/callint.c
index 9b3535474c0..57c86f0a633 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -402,8 +402,8 @@ invoke it. If KEYS is omitted or nil, the return value of
real_this_command= save_real_this_command;
current_kboard->Vlast_command = save_last_command;
- single_kboard_state ();
- return apply1 (function, specs);
+ temporarily_switch_to_single_kboard (NULL);
+ return unbind_to (speccount, apply1 (function, specs));
}
/* Here if function specifies a string to control parsing the defaults */
@@ -854,12 +854,11 @@ invoke it. If KEYS is omitted or nil, the return value of
real_this_command= save_real_this_command;
current_kboard->Vlast_command = save_last_command;
- single_kboard_state ();
-
{
Lisp_Object val;
specbind (Qcommand_debug_status, Qnil);
+ temporarily_switch_to_single_kboard (NULL);
val = Ffuncall (count + 1, args);
UNGCPRO;
return unbind_to (speccount, val);
diff --git a/src/callproc.c b/src/callproc.c
index bf7ea43b868..5bd4cee9cfa 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -84,6 +84,8 @@ extern int errno;
#include "syssignal.h"
#include "systty.h"
#include "blockinput.h"
+#include "frame.h"
+#include "termhooks.h"
#ifdef MSDOS
#include "msdos.h"
@@ -130,6 +132,7 @@ int synch_process_termsig;
/* If synch_process_death is zero,
this is exit code of synchronous subprocess. */
int synch_process_retcode;
+
/* Clean up when exiting Fcall_process.
On MSDOS, delete the temporary file on any kind of termination.
@@ -1181,6 +1184,40 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
static int relocate_fd ();
+static char **
+add_env (char **env, char **new_env, char *string)
+{
+ char **ep;
+ int ok = 1;
+ if (string == NULL)
+ return new_env;
+
+ /* See if this string duplicates any string already in the env.
+ If so, don't put it in.
+ When an env var has multiple definitions,
+ we keep the definition that comes first in process-environment. */
+ for (ep = env; ok && ep != new_env; ep++)
+ {
+ char *p = *ep, *q = string;
+ while (ok)
+ {
+ if (*q != *p)
+ break;
+ if (*q == 0)
+ /* The string is a lone variable name; keep it for now, we
+ will remove it later. It is a placeholder for a
+ variable that is not to be included in the environment. */
+ break;
+ if (*q == '=')
+ ok = 0;
+ p++, q++;
+ }
+ }
+ if (ok)
+ *new_env++ = string;
+ return new_env;
+}
+
/* This is the last thing run in a newly forked inferior
either synchronous or asynchronous.
Copy descriptors IN, OUT and ERR as descriptors 0, 1 and 2.
@@ -1208,6 +1245,8 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir)
{
char **env;
char *pwd_var;
+ char *term_var;
+ char *display_var;
#ifdef WINDOWSNT
int cpid;
HANDLE handles[3];
@@ -1282,57 +1321,101 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir)
temp[--i] = 0;
}
- /* Set `env' to a vector of the strings in Vprocess_environment. */
+ /* Set `env' to a vector of the strings in the environment. */
{
register Lisp_Object tem;
register char **new_env;
+ char **p, **q;
register int new_length;
+ Lisp_Object local = selected_frame; /* get_frame_param (XFRAME (Fframe_with_environment (selected_frame)), */
+/* Qenvironment); */
+ Lisp_Object term;
+ Lisp_Object display;
+
new_length = 0;
+
for (tem = Vprocess_environment;
+ CONSP (tem) && STRINGP (XCAR (tem));
+ tem = XCDR (tem))
+ new_length++;
+
+#if 0
+ for (tem = local;
CONSP (tem) && STRINGP (XCAR (tem));
tem = XCDR (tem))
new_length++;
+#endif
+
+ /* Add TERM and DISPLAY from the frame local values. */
+ term = get_frame_param (XFRAME (local), Qterm_environment_variable);
+ if (! NILP (term))
+ new_length++;
+
+ display = get_frame_param (XFRAME (local), Qdisplay_environment_variable);
+ if (! NILP (display))
+ new_length++;
/* new_length + 2 to include PWD and terminating 0. */
env = new_env = (char **) alloca ((new_length + 2) * sizeof (char *));
/* If we have a PWD envvar, pass one down,
but with corrected value. */
- if (getenv ("PWD"))
+ if (egetenv ("PWD"))
*new_env++ = pwd_var;
+
+ if (! NILP (term))
+ {
+ int vlen = strlen ("TERM=") + strlen (SDATA (term)) + 1;
+ char *vdata = (char *) alloca (vlen);
+ strcpy (vdata, "TERM=");
+ strcat (vdata, SDATA (term));
+ new_env = add_env (env, new_env, vdata);
+ }
+
+ if (! NILP (display))
+ {
+ int vlen = strlen ("DISPLAY=") + strlen (SDATA (display)) + 1;
+ char *vdata = (char *) alloca (vlen);
+ strcpy (vdata, "DISPLAY=");
+ strcat (vdata, SDATA (display));
+ new_env = add_env (env, new_env, vdata);
+ }
- /* Copy the Vprocess_environment strings into new_env. */
+ /* Overrides. */
for (tem = Vprocess_environment;
CONSP (tem) && STRINGP (XCAR (tem));
tem = XCDR (tem))
{
- char **ep = env;
- char *string = (char *) SDATA (XCAR (tem));
- /* See if this string duplicates any string already in the env.
- If so, don't put it in.
- When an env var has multiple definitions,
- we keep the definition that comes first in process-environment. */
- for (; ep != new_env; ep++)
- {
- char *p = *ep, *q = string;
- while (1)
- {
- if (*q == 0)
- /* The string is malformed; might as well drop it. */
- goto duplicate;
- if (*q != *p)
- break;
- if (*q == '=')
- goto duplicate;
- p++, q++;
- }
- }
- *new_env++ = string;
- duplicate: ;
+ if ((strcmp (SDATA (XCAR (tem)), "TERM") != 0)
+ && (strcmp (SDATA (XCAR (tem)), "DISPLAY") != 0))
+ new_env = add_env (env, new_env, SDATA (XCAR (tem)));
}
+
+
+#if 0
+ /* Local part of environment. */
+ for (tem = local;
+ CONSP (tem) && STRINGP (XCAR (tem));
+ tem = XCDR (tem))
+ new_env = add_env (env, new_env, SDATA (XCAR (tem)));
+#endif
+
*new_env = 0;
+
+ /* Remove variable names without values. */
+ p = q = env;
+ while (*p != 0)
+ {
+ while (*q != 0 && strchr (*q, '=') == NULL)
+ *q++;
+ *p = *q++;
+ if (*p != 0)
+ p++;
+ }
}
+
+
#ifdef WINDOWSNT
prepare_standard_handles (in, out, err, handles);
set_process_dir (SDATA (current_dir));
@@ -1446,59 +1529,160 @@ relocate_fd (fd, minfd)
}
static int
-getenv_internal (var, varlen, value, valuelen)
+getenv_internal (var, varlen, value, valuelen, frame)
char *var;
int varlen;
char **value;
int *valuelen;
+ Lisp_Object frame;
{
Lisp_Object scan;
+ Lisp_Object term;
+ Lisp_Object display;
+
+
+ if (NILP (frame))
+ {
+ /* Try to find VAR in Vprocess_environment first. */
+ for (scan = Vprocess_environment; CONSP (scan); scan = XCDR (scan))
+ {
+ Lisp_Object entry = XCAR (scan);
+ if (STRINGP (entry)
+ && SBYTES (entry) >= varlen
+#ifdef WINDOWSNT
+ /* NT environment variables are case insensitive. */
+ && ! strnicmp (SDATA (entry), var, varlen)
+#else /* not WINDOWSNT */
+ && ! bcmp (SDATA (entry), var, varlen)
+#endif /* not WINDOWSNT */
+ )
+ {
+ if (SBYTES (entry) > varlen && SREF (entry, varlen) == '=')
+ {
+ *value = (char *) SDATA (entry) + (varlen + 1);
+ *valuelen = SBYTES (entry) - (varlen + 1);
+ return 1;
+ }
+ else if (SBYTES (entry) == varlen)
+ {
+ /* Lone variable names in Vprocess_environment mean that
+ variable should be removed from the environment. */
+ return 0;
+ }
+ }
+ }
+ frame = selected_frame;
+ }
+
+ /* For TERM and DISPLAY first try to get the values from the frame. */
+ term = get_frame_param (XFRAME (frame), Qterm_environment_variable);
+ if (strcmp (var, "TERM") == 0)
+ if (! NILP (term))
+ {
+ *value = (char *) SDATA (term);
+ *valuelen = SBYTES (term);
+ return 1;
+ }
+ display = get_frame_param (XFRAME (frame), Qdisplay_environment_variable);
+ if (strcmp (var, "DISPLAY") == 0)
+ if (! NILP (display))
+ {
+ *value = (char *) SDATA (display);
+ *valuelen = SBYTES (display);
+ return 1;
+ }
+
+ {
+ /* Try to find VAR in Vprocess_environment. */
+ for (scan = Vprocess_environment; CONSP (scan); scan = XCDR (scan))
+ {
+ Lisp_Object entry = XCAR (scan);
+ if (STRINGP (entry)
+ && SBYTES (entry) >= varlen
+#ifdef WINDOWSNT
+ /* NT environment variables are case insensitive. */
+ && ! strnicmp (SDATA (entry), var, varlen)
+#else /* not WINDOWSNT */
+ && ! bcmp (SDATA (entry), var, varlen)
+#endif /* not WINDOWSNT */
+ )
+ {
+ if (SBYTES (entry) > varlen && SREF (entry, varlen) == '=')
+ {
+ *value = (char *) SDATA (entry) + (varlen + 1);
+ *valuelen = SBYTES (entry) - (varlen + 1);
+ return 1;
+ }
+ else if (SBYTES (entry) == varlen)
+ {
+ /* Lone variable names in Vprocess_environment mean that
+ variable should be removed from the environment. */
+ return 0;
+ }
+ }
+ }
+ }
- for (scan = Vprocess_environment; CONSP (scan); scan = XCDR (scan))
+#if 0
+ /* Find the environment in which to search the variable. */
+ CHECK_FRAME (frame);
+ frame = Fframe_with_environment (frame);
+
+ for (scan = get_frame_param (XFRAME (frame), Qenvironment);
+ CONSP (scan);
+ scan = XCDR (scan))
{
Lisp_Object entry;
entry = XCAR (scan);
if (STRINGP (entry)
- && SBYTES (entry) > varlen
- && SREF (entry, varlen) == '='
+ && SBYTES (entry) > varlen
+ && SREF (entry, varlen) == '='
#ifdef WINDOWSNT
- /* NT environment variables are case insensitive. */
- && ! strnicmp (SDATA (entry), var, varlen)
+ /* NT environment variables are case insensitive. */
+ && ! strnicmp (SDATA (entry), var, varlen)
#else /* not WINDOWSNT */
- && ! bcmp (SDATA (entry), var, varlen)
+ && ! bcmp (SDATA (entry), var, varlen)
#endif /* not WINDOWSNT */
- )
+ )
{
*value = (char *) SDATA (entry) + (varlen + 1);
*valuelen = SBYTES (entry) - (varlen + 1);
return 1;
}
}
-
+#endif
return 0;
}
-DEFUN ("getenv-internal", Fgetenv_internal, Sgetenv_internal, 1, 1, 0,
- doc: /* Return the value of environment variable VAR, as a string.
-VAR should be a string. Value is nil if VAR is undefined in the environment.
-This function consults the variable `process-environment' for its value. */)
- (var)
- Lisp_Object var;
+DEFUN ("getenv-internal", Fgetenv_internal, Sgetenv_internal, 1, 2, 0,
+ doc: /* Get the value of environment variable VARIABLE.
+VARIABLE should be a string. Value is nil if VARIABLE is undefined in
+the environment. Otherwise, value is a string.
+
+This function searches `process-environment' for VARIABLE. If it is
+not found there, then it continues the search in the environment list
+of the selected frame.
+
+If optional parameter FRAME is non-nil, then this function will ignore
+`process-environment' and will simply look up the variable in that
+frame's environment. */)
+ (variable, frame)
+ Lisp_Object variable, frame;
{
char *value;
int valuelen;
- CHECK_STRING (var);
- if (getenv_internal (SDATA (var), SBYTES (var),
- &value, &valuelen))
+ CHECK_STRING (variable);
+ if (getenv_internal (SDATA (variable), SBYTES (variable),
+ &value, &valuelen, frame))
return make_string (value, valuelen);
else
return Qnil;
}
-/* A version of getenv that consults process_environment, easily
- callable from C. */
+/* A version of getenv that consults the Lisp environment lists,
+ easily callable from C. */
char *
egetenv (var)
char *var;
@@ -1506,7 +1690,7 @@ egetenv (var)
char *value;
int valuelen;
- if (getenv_internal (var, strlen (var), &value, &valuelen))
+ if (getenv_internal (var, strlen (var), &value, &valuelen, Qnil))
return value;
else
return 0;
@@ -1629,8 +1813,8 @@ init_callproc ()
{
char *dir = getenv ("TMPDIR");
Vtemp_file_name_pattern
- = Fexpand_file_name (build_string ("emacsXXXXXX"),
- build_string (dir));
+ = Fexpand_file_name (build_string ("emacsXXXXXX"),
+ build_string (dir));
}
else
Vtemp_file_name_pattern = build_string ("/tmp/emacsXXXXXX");
@@ -1646,17 +1830,19 @@ init_callproc ()
}
void
-set_process_environment ()
+set_initial_environment ()
{
register char **envp;
-
- Vprocess_environment = Qnil;
+ Lisp_Object env = Vprocess_environment;
#ifndef CANNOT_DUMP
if (initialized)
#endif
- for (envp = environ; *envp; envp++)
- Vprocess_environment = Fcons (build_string (*envp),
- Vprocess_environment);
+ {
+ for (envp = environ; *envp; envp++)
+ Vprocess_environment = Fcons (build_string (*envp),
+ Vprocess_environment);
+ store_frame_param (SELECTED_FRAME(), Qenvironment, Vprocess_environment);
+ }
}
void
@@ -1716,15 +1902,27 @@ This is used by `call-process-region'. */);
/* This variable is initialized in init_callproc. */
DEFVAR_LISP ("process-environment", &Vprocess_environment,
- doc: /* List of environment variables for subprocesses to inherit.
+ doc: /* List of overridden environment variables for subprocesses to inherit.
Each element should be a string of the form ENVVARNAME=VALUE.
+
+Entries in this list take precedence to those in the frame-local
+environments. Therefore, let-binding `process-environment' is an easy
+way to temporarily change the value of an environment variable,
+irrespective of where it comes from. To use `process-environment' to
+remove an environment variable, include only its name in the list,
+without "=VALUE".
+
+This variable is set to nil when Emacs starts.
+
If multiple entries define the same variable, the first one always
takes precedence.
-The environment which Emacs inherits is placed in this variable
-when Emacs starts.
+
Non-ASCII characters are encoded according to the initial value of
-`locale-coding-system', i.e. the elements must normally be decoded for use.
+`locale-coding-system', i.e. the elements must normally be decoded for
+use.
+
See `setenv' and `getenv'. */);
+ Vprocess_environment = Qnil;
#ifndef VMS
defsubr (&Scall_process);
diff --git a/src/cm.c b/src/cm.c
index 18331216776..ad8ec080c9d 100644
--- a/src/cm.c
+++ b/src/cm.c
@@ -23,8 +23,13 @@ Boston, MA 02110-1301, USA. */
#include <config.h>
#include <stdio.h>
+
+#include "lisp.h"
+#include "frame.h"
#include "cm.h"
#include "termhooks.h"
+#include "termchar.h"
+
/* For now, don't try to include termcap.h. On some systems,
configure finds a non-standard termcap.h that the main build
@@ -53,13 +58,16 @@ evalcost (c)
return c;
}
+/* The terminal to use for low-level output. */
+struct tty_display_info *current_tty;
+
int
cmputc (c)
char c;
{
- if (termscript)
- fputc (c & 0177, termscript);
- putchar (c & 0177);
+ if (current_tty->termscript)
+ putc (c & 0177, current_tty->termscript);
+ putc (c & 0177, current_tty->output);
return c;
}
@@ -72,9 +80,9 @@ cmputc (c)
*/
static
-at (row, col) {
- curY = row;
- curX = col;
+at (tty, row, col) {
+ curY (tty) = row;
+ curX (tty) = col;
}
/*
@@ -82,8 +90,8 @@ at (row, col) {
*/
static
-addcol (n) {
- curX += n;
+addcol (tty, n) {
+ curX (tty) += n;
/*
* If cursor hit edge of screen, what happened?
@@ -93,21 +101,21 @@ addcol (n) {
* of the last line.
*/
- if (curX == Wcm.cm_cols) {
+ if (curX (tty) == tty->Wcm->cm_cols) {
/*
* Well, if magicwrap, still there, past the edge of the
* screen (!). If autowrap, on the col 0 of the next line.
* Otherwise on last column.
*/
- if (Wcm.cm_magicwrap)
+ if (tty->Wcm->cm_magicwrap)
; /* "limbo" */
- else if (Wcm.cm_autowrap) {
- curX = 0;
- curY++; /* Beware end of screen! */
+ else if (tty->Wcm->cm_autowrap) {
+ curX (tty) = 0;
+ curY (tty) ++; /* Beware end of screen! */
}
else
- curX--;
+ curX (tty)--;
}
}
#endif
@@ -123,20 +131,20 @@ addcol (n) {
* after we reach the last column; this takes us to a known state.
*/
void
-cmcheckmagic ()
+cmcheckmagic (struct tty_display_info *tty)
{
- if (curX == FrameCols)
+ if (curX (tty) == FrameCols (tty))
{
- if (!MagicWrap || curY >= FrameRows - 1)
+ if (!MagicWrap (tty) || curY (tty) >= FrameRows (tty) - 1)
abort ();
- if (termscript)
- putc ('\r', termscript);
- putchar ('\r');
- if (termscript)
- putc ('\n', termscript);
- putchar ('\n');
- curX = 0;
- curY++;
+ if (tty->termscript)
+ putc ('\r', tty->termscript);
+ putc ('\r', tty->output);
+ if (tty->termscript)
+ putc ('\n', tty->termscript);
+ putc ('\n', tty->output);
+ curX (tty) = 0;
+ curY (tty)++;
}
}
@@ -148,21 +156,21 @@ cmcheckmagic ()
*/
void
-cmcostinit ()
+cmcostinit (struct tty_display_info *tty)
{
char *p;
#define COST(x,e) (x ? (cost = 0, tputs (x, 1, e), cost) : BIG)
#define CMCOST(x,e) ((x == 0) ? BIG : (p = tgoto(x, 0, 0), COST(p ,e)))
- Wcm.cc_up = COST (Wcm.cm_up, evalcost);
- Wcm.cc_down = COST (Wcm.cm_down, evalcost);
- Wcm.cc_left = COST (Wcm.cm_left, evalcost);
- Wcm.cc_right = COST (Wcm.cm_right, evalcost);
- Wcm.cc_home = COST (Wcm.cm_home, evalcost);
- Wcm.cc_cr = COST (Wcm.cm_cr, evalcost);
- Wcm.cc_ll = COST (Wcm.cm_ll, evalcost);
- Wcm.cc_tab = Wcm.cm_tabwidth ? COST (Wcm.cm_tab, evalcost) : BIG;
+ tty->Wcm->cc_up = COST (tty->Wcm->cm_up, evalcost);
+ tty->Wcm->cc_down = COST (tty->Wcm->cm_down, evalcost);
+ tty->Wcm->cc_left = COST (tty->Wcm->cm_left, evalcost);
+ tty->Wcm->cc_right = COST (tty->Wcm->cm_right, evalcost);
+ tty->Wcm->cc_home = COST (tty->Wcm->cm_home, evalcost);
+ tty->Wcm->cc_cr = COST (tty->Wcm->cm_cr, evalcost);
+ tty->Wcm->cc_ll = COST (tty->Wcm->cm_ll, evalcost);
+ tty->Wcm->cc_tab = tty->Wcm->cm_tabwidth ? COST (tty->Wcm->cm_tab, evalcost) : BIG;
/*
* These last three are actually minimum costs. When (if) they are
@@ -173,9 +181,9 @@ cmcostinit ()
* cursor motion seem to take straight numeric values. --ACT)
*/
- Wcm.cc_abs = CMCOST (Wcm.cm_abs, evalcost);
- Wcm.cc_habs = CMCOST (Wcm.cm_habs, evalcost);
- Wcm.cc_vabs = CMCOST (Wcm.cm_vabs, evalcost);
+ tty->Wcm->cc_abs = CMCOST (tty->Wcm->cm_abs, evalcost);
+ tty->Wcm->cc_habs = CMCOST (tty->Wcm->cm_habs, evalcost);
+ tty->Wcm->cc_vabs = CMCOST (tty->Wcm->cm_vabs, evalcost);
#undef CMCOST
#undef COST
@@ -188,8 +196,8 @@ cmcostinit ()
*/
static int
-calccost (srcy, srcx, dsty, dstx, doit)
- int srcy, srcx, dsty, dstx, doit;
+calccost (struct tty_display_info *tty,
+ int srcy, int srcx, int dsty, int dstx, int doit)
{
register int deltay,
deltax,
@@ -206,16 +214,16 @@ calccost (srcy, srcx, dsty, dstx, doit)
don't believe the cursor position: give up here
and force use of absolute positioning. */
- if (curX == Wcm.cm_cols)
+ if (curX (tty) == tty->Wcm->cm_cols)
goto fail;
totalcost = 0;
if ((deltay = dsty - srcy) == 0)
goto x;
if (deltay < 0)
- p = Wcm.cm_up, c = Wcm.cc_up, deltay = -deltay;
+ p = tty->Wcm->cm_up, c = tty->Wcm->cc_up, deltay = -deltay;
else
- p = Wcm.cm_down, c = Wcm.cc_down;
+ p = tty->Wcm->cm_down, c = tty->Wcm->cc_down;
if (c == BIG) { /* caint get thar from here */
if (doit)
printf ("OOPS");
@@ -224,16 +232,16 @@ calccost (srcy, srcx, dsty, dstx, doit)
totalcost = c * deltay;
if (doit)
while (--deltay >= 0)
- tputs (p, 1, cmputc);
+ emacs_tputs (tty, p, 1, cmputc);
x:
if ((deltax = dstx - srcx) == 0)
goto done;
if (deltax < 0) {
- p = Wcm.cm_left, c = Wcm.cc_left, deltax = -deltax;
+ p = tty->Wcm->cm_left, c = tty->Wcm->cc_left, deltax = -deltax;
goto dodelta; /* skip all the tab junk */
}
/* Tabs (the toughie) */
- if (Wcm.cc_tab >= BIG || !Wcm.cm_usetabs)
+ if (tty->Wcm->cc_tab >= BIG || !tty->Wcm->cm_usetabs)
goto olddelta; /* forget it! */
/*
@@ -244,12 +252,12 @@ x:
* we will put into tabx (for ntabs) and tab2x (for n2tabs)).
*/
- ntabs = (deltax + srcx % Wcm.cm_tabwidth) / Wcm.cm_tabwidth;
+ ntabs = (deltax + srcx % tty->Wcm->cm_tabwidth) / tty->Wcm->cm_tabwidth;
n2tabs = ntabs + 1;
- tabx = (srcx / Wcm.cm_tabwidth + ntabs) * Wcm.cm_tabwidth;
- tab2x = tabx + Wcm.cm_tabwidth;
+ tabx = (srcx / tty->Wcm->cm_tabwidth + ntabs) * tty->Wcm->cm_tabwidth;
+ tab2x = tabx + tty->Wcm->cm_tabwidth;
- if (tab2x >= Wcm.cm_cols) /* too far (past edge) */
+ if (tab2x >= tty->Wcm->cm_cols) /* too far (past edge) */
n2tabs = 0;
/*
@@ -257,12 +265,12 @@ x:
* for using n2tabs, then pick the minimum.
*/
- /* cost for ntabs + cost for right motion */
- tabcost = ntabs ? ntabs * Wcm.cc_tab + (dstx - tabx) * Wcm.cc_right
+ /* cost for ntabs + cost for right motion */
+ tabcost = ntabs ? ntabs * tty->Wcm->cc_tab + (dstx - tabx) * tty->Wcm->cc_right
: BIG;
- /* cost for n2tabs + cost for left motion */
- c = n2tabs ? n2tabs * Wcm.cc_tab + (tab2x - dstx) * Wcm.cc_left
+ /* cost for n2tabs + cost for left motion */
+ c = n2tabs ? n2tabs * tty->Wcm->cc_tab + (tab2x - dstx) * tty->Wcm->cc_left
: BIG;
if (c < tabcost) /* then cheaper to overshoot & back up */
@@ -275,11 +283,11 @@ x:
* See if tabcost is less than just moving right
*/
- if (tabcost < (deltax * Wcm.cc_right)) {
+ if (tabcost < (deltax * tty->Wcm->cc_right)) {
totalcost += tabcost; /* use the tabs */
if (doit)
while (--ntabs >= 0)
- tputs (Wcm.cm_tab, 1, cmputc);
+ emacs_tputs (tty, tty->Wcm->cm_tab, 1, cmputc);
srcx = tabx;
}
@@ -292,9 +300,9 @@ newdelta:
goto done;
olddelta:
if (deltax > 0)
- p = Wcm.cm_right, c = Wcm.cc_right;
+ p = tty->Wcm->cm_right, c = tty->Wcm->cc_right;
else
- p = Wcm.cm_left, c = Wcm.cc_left, deltax = -deltax;
+ p = tty->Wcm->cm_left, c = tty->Wcm->cc_left, deltax = -deltax;
dodelta:
if (c == BIG) { /* caint get thar from here */
@@ -306,7 +314,7 @@ fail:
totalcost += c * deltax;
if (doit)
while (--deltax >= 0)
- tputs (p, 1, cmputc);
+ emacs_tputs (tty, p, 1, cmputc);
done:
return totalcost;
}
@@ -324,7 +332,8 @@ losecursor ()
#define USECR 3
void
-cmgoto (row, col)
+cmgoto (tty, row, col)
+ struct tty_display_info *tty;
int row, col;
{
int homecost,
@@ -337,47 +346,47 @@ cmgoto (row, col)
*dcm;
/* First the degenerate case */
- if (row == curY && col == curX) /* already there */
+ if (row == curY (tty) && col == curX (tty)) /* already there */
return;
- if (curY >= 0 && curX >= 0)
+ if (curY (tty) >= 0 && curX (tty) >= 0)
{
/* We may have quick ways to go to the upper-left, bottom-left,
* start-of-line, or start-of-next-line. Or it might be best to
* start where we are. Examine the options, and pick the cheapest.
*/
- relcost = calccost (curY, curX, row, col, 0);
+ relcost = calccost (tty, curY (tty), curX (tty), row, col, 0);
use = USEREL;
- if ((homecost = Wcm.cc_home) < BIG)
- homecost += calccost (0, 0, row, col, 0);
+ if ((homecost = tty->Wcm->cc_home) < BIG)
+ homecost += calccost (tty, 0, 0, row, col, 0);
if (homecost < relcost)
- relcost = homecost, use = USEHOME;
- if ((llcost = Wcm.cc_ll) < BIG)
- llcost += calccost (Wcm.cm_rows - 1, 0, row, col, 0);
+ relcost = homecost, use = USEHOME;
+ if ((llcost = tty->Wcm->cc_ll) < BIG)
+ llcost += calccost (tty, tty->Wcm->cm_rows - 1, 0, row, col, 0);
if (llcost < relcost)
- relcost = llcost, use = USELL;
- if ((crcost = Wcm.cc_cr) < BIG) {
- if (Wcm.cm_autolf)
- if (curY + 1 >= Wcm.cm_rows)
- crcost = BIG;
+ relcost = llcost, use = USELL;
+ if ((crcost = tty->Wcm->cc_cr) < BIG) {
+ if (tty->Wcm->cm_autolf)
+ if (curY (tty) + 1 >= tty->Wcm->cm_rows)
+ crcost = BIG;
else
- crcost += calccost (curY + 1, 0, row, col, 0);
+ crcost += calccost (tty, curY (tty) + 1, 0, row, col, 0);
else
- crcost += calccost (curY, 0, row, col, 0);
+ crcost += calccost (tty, curY (tty), 0, row, col, 0);
}
if (crcost < relcost)
relcost = crcost, use = USECR;
- directcost = Wcm.cc_abs, dcm = Wcm.cm_abs;
- if (row == curY && Wcm.cc_habs < BIG)
- directcost = Wcm.cc_habs, dcm = Wcm.cm_habs;
- else if (col == curX && Wcm.cc_vabs < BIG)
- directcost = Wcm.cc_vabs, dcm = Wcm.cm_vabs;
+ directcost = tty->Wcm->cc_abs, dcm = tty->Wcm->cm_abs;
+ if (row == curY (tty) && tty->Wcm->cc_habs < BIG)
+ directcost = tty->Wcm->cc_habs, dcm = tty->Wcm->cm_habs;
+ else if (col == curX (tty) && tty->Wcm->cc_vabs < BIG)
+ directcost = tty->Wcm->cc_vabs, dcm = tty->Wcm->cm_vabs;
}
else
{
directcost = 0, relcost = 100000;
- dcm = Wcm.cm_abs;
+ dcm = tty->Wcm->cm_abs;
}
/*
@@ -388,13 +397,14 @@ cmgoto (row, col)
{
/* compute REAL direct cost */
cost = 0;
- p = dcm == Wcm.cm_habs ? tgoto (dcm, row, col) :
- tgoto (dcm, col, row);
- tputs (p, 1, evalcost);
+ p = (dcm == tty->Wcm->cm_habs
+ ? tgoto (dcm, row, col)
+ : tgoto (dcm, col, row));
+ emacs_tputs (tty, p, 1, evalcost);
if (cost <= relcost)
{ /* really is cheaper */
- tputs (p, 1, cmputc);
- curY = row, curX = col;
+ emacs_tputs (tty, p, 1, cmputc);
+ curY (tty) = row, curX (tty) = col;
return;
}
}
@@ -402,25 +412,25 @@ cmgoto (row, col)
switch (use)
{
case USEHOME:
- tputs (Wcm.cm_home, 1, cmputc);
- curY = 0, curX = 0;
+ emacs_tputs (tty, tty->Wcm->cm_home, 1, cmputc);
+ curY (tty) = 0, curX (tty) = 0;
break;
case USELL:
- tputs (Wcm.cm_ll, 1, cmputc);
- curY = Wcm.cm_rows - 1, curX = 0;
+ emacs_tputs (tty, tty->Wcm->cm_ll, 1, cmputc);
+ curY (tty) = tty->Wcm->cm_rows - 1, curX (tty) = 0;
break;
case USECR:
- tputs (Wcm.cm_cr, 1, cmputc);
- if (Wcm.cm_autolf)
- curY++;
- curX = 0;
+ emacs_tputs (tty, tty->Wcm->cm_cr, 1, cmputc);
+ if (tty->Wcm->cm_autolf)
+ curY (tty)++;
+ curX (tty) = 0;
break;
}
- (void) calccost (curY, curX, row, col, 1);
- curY = row, curX = col;
+ (void) calccost (tty, curY (tty), curX (tty), row, col, 1);
+ curY (tty) = row, curX (tty) = col;
}
/* Clear out all terminal info.
@@ -428,9 +438,9 @@ cmgoto (row, col)
*/
void
-Wcm_clear ()
+Wcm_clear (struct tty_display_info *tty)
{
- bzero (&Wcm, sizeof Wcm);
+ bzero (tty->Wcm, sizeof (struct cm));
UP = 0;
BC = 0;
}
@@ -443,21 +453,21 @@ Wcm_clear ()
*/
int
-Wcm_init ()
+Wcm_init (struct tty_display_info *tty)
{
#if 0
- if (Wcm.cm_abs && !Wcm.cm_ds)
+ if (tty->Wcm->cm_abs && !tty->Wcm->cm_ds)
return 0;
#endif
- if (Wcm.cm_abs)
+ if (tty->Wcm->cm_abs)
return 0;
/* Require up and left, and, if no absolute, down and right */
- if (!Wcm.cm_up || !Wcm.cm_left)
+ if (!tty->Wcm->cm_up || !tty->Wcm->cm_left)
return - 1;
- if (!Wcm.cm_abs && (!Wcm.cm_down || !Wcm.cm_right))
+ if (!tty->Wcm->cm_abs && (!tty->Wcm->cm_down || !tty->Wcm->cm_right))
return - 1;
/* Check that we know the size of the screen.... */
- if (Wcm.cm_rows <= 0 || Wcm.cm_cols <= 0)
+ if (tty->Wcm->cm_rows <= 0 || tty->Wcm->cm_cols <= 0)
return - 2;
return 0;
}
diff --git a/src/cm.h b/src/cm.h
index 7c26a9ce66a..36413703a92 100644
--- a/src/cm.h
+++ b/src/cm.h
@@ -99,76 +99,78 @@ struct cm
int cc_vabs;
};
-extern struct cm Wcm; /* Terminal capabilities */
extern char PC; /* Pad character */
/* Shorthand */
#ifndef NoCMShortHand
-#define curY Wcm.cm_curY
-#define curX Wcm.cm_curX
-#define Up Wcm.cm_up
-#define Down Wcm.cm_down
-#define Left Wcm.cm_left
-#define Right Wcm.cm_right
-#define Tab Wcm.cm_tab
-#define BackTab Wcm.cm_backtab
-#define TabWidth Wcm.cm_tabwidth
-#define CR Wcm.cm_cr
-#define Home Wcm.cm_home
-#define LastLine Wcm.cm_ll
-#define AbsPosition Wcm.cm_abs
-#define ColPosition Wcm.cm_habs
-#define RowPosition Wcm.cm_vabs
-#define MultiUp Wcm.cm_multiup
-#define MultiDown Wcm.cm_multidown
-#define MultiLeft Wcm.cm_multileft
-#define MultiRight Wcm.cm_multiright
-#define AutoWrap Wcm.cm_autowrap
-#define MagicWrap Wcm.cm_magicwrap
-#define UseTabs Wcm.cm_usetabs
-#define FrameRows Wcm.cm_rows
-#define FrameCols Wcm.cm_cols
-
-#define UpCost Wcm.cc_up
-#define DownCost Wcm.cc_down
-#define LeftCost Wcm.cc_left
-#define RightCost Wcm.cc_right
-#define HomeCost Wcm.cc_home
-#define CRCost Wcm.cc_cr
-#define LastLineCost Wcm.cc_ll
-#define TabCost Wcm.cc_tab
-#define BackTabCost Wcm.cc_backtab
-#define AbsPositionCost Wcm.cc_abs
-#define ColPositionCost Wcm.cc_habs
-#define RowPositionCost Wcm.cc_vabs
-#define MultiUpCost Wcm.cc_multiup
-#define MultiDownCost Wcm.cc_multidown
-#define MultiLeftCost Wcm.cc_multileft
-#define MultiRightCost Wcm.cc_multiright
+#define curY(tty) (tty)->Wcm->cm_curY
+#define curX(tty) (tty)->Wcm->cm_curX
+#define Up(tty) (tty)->Wcm->cm_up
+#define Down(tty) (tty)->Wcm->cm_down
+#define Left(tty) (tty)->Wcm->cm_left
+#define Right(tty) (tty)->Wcm->cm_right
+#define Tab(tty) (tty)->Wcm->cm_tab
+#define BackTab(tty) (tty)->Wcm->cm_backtab
+#define TabWidth(tty) (tty)->Wcm->cm_tabwidth
+#define CR(tty) (tty)->Wcm->cm_cr
+#define Home(tty) (tty)->Wcm->cm_home
+#define LastLine(tty) (tty)->Wcm->cm_ll
+#define AbsPosition(tty) (tty)->Wcm->cm_abs
+#define ColPosition(tty) (tty)->Wcm->cm_habs
+#define RowPosition(tty) (tty)->Wcm->cm_vabs
+#define MultiUp(tty) (tty)->Wcm->cm_multiup
+#define MultiDown(tty) (tty)->Wcm->cm_multidown
+#define MultiLeft(tty) (tty)->Wcm->cm_multileft
+#define MultiRight(tty) (tty)->Wcm->cm_multiright
+#define AutoWrap(tty) (tty)->Wcm->cm_autowrap
+#define MagicWrap(tty) (tty)->Wcm->cm_magicwrap
+#define UseTabs(tty) (tty)->Wcm->cm_usetabs
+#define FrameRows(tty) (tty)->Wcm->cm_rows
+#define FrameCols(tty) (tty)->Wcm->cm_cols
+
+#define UpCost(tty) (tty)->Wcm->cc_up
+#define DownCost(tty) (tty)->Wcm->cc_down
+#define LeftCost(tty) (tty)->Wcm->cc_left
+#define RightCost(tty) (tty)->Wcm->cc_right
+#define HomeCost(tty) (tty)->Wcm->cc_home
+#define CRCost(tty) (tty)->Wcm->cc_cr
+#define LastLineCost(tty) (tty)->Wcm->cc_ll
+#define TabCost(tty) (tty)->Wcm->cc_tab
+#define BackTabCost(tty) (tty)->Wcm->cc_backtab
+#define AbsPositionCost(tty) (tty)->Wcm->cc_abs
+#define ColPositionCost(tty) (tty)->Wcm->cc_habs
+#define RowPositionCost(tty) (tty)->Wcm->cc_vabs
+#define MultiUpCost(tty) (tty)->Wcm->cc_multiup
+#define MultiDownCost(tty) (tty)->Wcm->cc_multidown
+#define MultiLeftCost(tty) (tty)->Wcm->cc_multileft
+#define MultiRightCost(tty) (tty)->Wcm->cc_multiright
#endif
-#define cmat(row,col) (curY = (row), curX = (col))
-#define cmplus(n) \
- { \
- if ((curX += (n)) >= FrameCols && !MagicWrap) \
- { \
- if (Wcm.cm_losewrap) losecursor (); \
- else if (AutoWrap) curX = 0, curY++; \
- else curX--; \
- } \
+#define cmat(tty,row,col) (curY(tty) = (row), curX(tty) = (col))
+#define cmplus(tty,n) \
+ { \
+ if ((curX (tty) += (n)) >= FrameCols (tty) && !MagicWrap (tty)) \
+ { \
+ if ((tty)->Wcm->cm_losewrap) losecursor (tty); \
+ else if (AutoWrap (tty)) curX (tty) = 0, curY (tty)++; \
+ else curX (tty)--; \
+ } \
}
-#define losecursor() (curX = -1, curY = -1)
+#define losecursor(tty) (curX(tty) = -1, curY(tty) = -1)
extern int cost;
extern int evalcost ();
-extern void cmcheckmagic ();
-extern int cmputc ();
-extern void cmcostinit ();
-extern void cmgoto ();
-extern void Wcm_clear ();
-extern int Wcm_init ();
+#define emacs_tputs(tty, str, affcnt, putc) (current_tty = (tty), tputs (str, affcnt, putc))
+
+extern struct tty_display_info *current_tty;
+extern void cmcheckmagic P_ ((struct tty_display_info *));
+extern int cmputc P_ ((int));
+extern void cmcostinit P_ ((struct tty_display_info *));
+extern void cmgoto P_ ((struct tty_display_info *, int, int));
+extern void Wcm_clear P_ ((struct tty_display_info *));
+extern int Wcm_init P_ ((struct tty_display_info *));
/* arch-tag: acc1535a-7136-49d6-b22d-9bc85702251b
(do not change this comment) */
diff --git a/src/coding.c b/src/coding.c
index 7359f0214ba..e2ce0c9f8de 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -351,6 +351,8 @@ encode_coding_XXX (coding, source, destination, src_bytes, dst_bytes)
#include "coding.h"
#include "window.h"
#include "intervals.h"
+#include "frame.h"
+#include "termhooks.h"
#else /* not emacs */
@@ -436,16 +438,10 @@ int inhibit_iso_escape_detection;
/* Flag to make buffer-file-coding-system inherit from process-coding. */
int inherit_process_coding_system;
-/* Coding system to be used to encode text for terminal display. */
-struct coding_system terminal_coding;
-
/* Coding system to be used to encode text for terminal display when
terminal coding system is nil. */
struct coding_system safe_terminal_coding;
-/* Coding system of what is sent from terminal keyboard. */
-struct coding_system keyboard_coding;
-
/* Default coding system to be used to write a file. */
struct coding_system default_buffer_file_coding;
@@ -7368,21 +7364,23 @@ Return the corresponding character code in Big5. */)
}
DEFUN ("set-terminal-coding-system-internal", Fset_terminal_coding_system_internal,
- Sset_terminal_coding_system_internal, 1, 1, 0,
+ Sset_terminal_coding_system_internal, 1, 2, 0,
doc: /* Internal use only. */)
- (coding_system)
+ (coding_system, terminal)
Lisp_Object coding_system;
+ Lisp_Object terminal;
{
+ struct coding_system *terminal_coding = TERMINAL_TERMINAL_CODING (get_terminal (terminal, 1));
CHECK_SYMBOL (coding_system);
- setup_coding_system (Fcheck_coding_system (coding_system), &terminal_coding);
+ setup_coding_system (Fcheck_coding_system (coding_system), terminal_coding);
/* We had better not send unsafe characters to terminal. */
- terminal_coding.mode |= CODING_MODE_INHIBIT_UNENCODABLE_CHAR;
+ terminal_coding->mode |= CODING_MODE_INHIBIT_UNENCODABLE_CHAR;
/* Character composition should be disabled. */
- terminal_coding.composing = COMPOSITION_DISABLED;
+ terminal_coding->composing = COMPOSITION_DISABLED;
/* Error notification should be suppressed. */
- terminal_coding.suppress_error = 1;
- terminal_coding.src_multibyte = 1;
- terminal_coding.dst_multibyte = 0;
+ terminal_coding->suppress_error = 1;
+ terminal_coding->src_multibyte = 1;
+ terminal_coding->dst_multibyte = 0;
return Qnil;
}
@@ -7405,32 +7403,42 @@ DEFUN ("set-safe-terminal-coding-system-internal", Fset_safe_terminal_coding_sys
}
DEFUN ("terminal-coding-system", Fterminal_coding_system,
- Sterminal_coding_system, 0, 0, 0,
- doc: /* Return coding system specified for terminal output. */)
- ()
+ Sterminal_coding_system, 0, 1, 0,
+ doc: /* Return coding system specified for terminal output on the given terminal.
+TERMINAL may be a terminal id, a frame, or nil for the selected
+frame's terminal device. */)
+ (terminal)
+ Lisp_Object terminal;
{
- return terminal_coding.symbol;
+ return TERMINAL_TERMINAL_CODING (get_terminal (terminal, 1))->symbol;
}
DEFUN ("set-keyboard-coding-system-internal", Fset_keyboard_coding_system_internal,
- Sset_keyboard_coding_system_internal, 1, 1, 0,
+ Sset_keyboard_coding_system_internal, 1, 2, 0,
doc: /* Internal use only. */)
- (coding_system)
+ (coding_system, terminal)
Lisp_Object coding_system;
+ Lisp_Object terminal;
{
+ struct terminal *t = get_terminal (terminal, 1);
CHECK_SYMBOL (coding_system);
- setup_coding_system (Fcheck_coding_system (coding_system), &keyboard_coding);
+
+ setup_coding_system (Fcheck_coding_system (coding_system),
+ TERMINAL_KEYBOARD_CODING (t));
/* Character composition should be disabled. */
- keyboard_coding.composing = COMPOSITION_DISABLED;
+ TERMINAL_KEYBOARD_CODING (t)->composing = COMPOSITION_DISABLED;
return Qnil;
}
DEFUN ("keyboard-coding-system", Fkeyboard_coding_system,
- Skeyboard_coding_system, 0, 0, 0,
- doc: /* Return coding system specified for decoding keyboard input. */)
- ()
+ Skeyboard_coding_system, 0, 1, 0,
+ doc: /* Return coding system for decoding keyboard input on TERMINAL.
+TERMINAL may be a terminal id, a frame, or nil for the selected
+frame's terminal device. */)
+ (terminal)
+ Lisp_Object terminal;
{
- return keyboard_coding.symbol;
+ return TERMINAL_KEYBOARD_CODING (get_terminal (terminal, 1))->symbol;
}
@@ -7695,8 +7703,6 @@ init_coding_once ()
iso_code_class[ISO_CODE_SS3] = ISO_single_shift_3;
iso_code_class[ISO_CODE_CSI] = ISO_control_sequence_introducer;
- setup_coding_system (Qnil, &keyboard_coding);
- setup_coding_system (Qnil, &terminal_coding);
setup_coding_system (Qnil, &safe_terminal_coding);
setup_coding_system (Qnil, &default_buffer_file_coding);
diff --git a/src/coding.h b/src/coding.h
index 2efcd4f47e2..a53a74ec161 100644
--- a/src/coding.h
+++ b/src/coding.h
@@ -696,20 +696,10 @@ extern Lisp_Object Vlocale_coding_system;
the subprocess output. */
extern int inherit_process_coding_system;
-/* Coding-system to be used for encoding terminal output. This
- structure contains information of a coding-system specified by the
- function `set-terminal-coding-system'. */
-extern struct coding_system terminal_coding;
-
/* Coding system to be used to encode text for terminal display when
terminal coding system is nil. */
extern struct coding_system safe_terminal_coding;
-/* Coding-system of what is sent from terminal keyboard. This
- structure contains information of a coding-system specified by the
- function `set-keyboard-coding-system'. */
-extern struct coding_system keyboard_coding;
-
/* Default coding system to be used to write a file. */
extern struct coding_system default_buffer_file_coding;
diff --git a/src/config.in b/src/config.in
index e050ceae44f..59d4b91ed31 100644
--- a/src/config.in
+++ b/src/config.in
@@ -929,11 +929,19 @@ Boston, MA 02110-1301, USA. */
#define HAVE_MOUSE
#endif
+/* Multi-tty support relies on MULTI_KBOARD. It seems safe to turn it
+ on unconditionally. */
+#ifndef MULTI_KBOARD
+#define MULTI_KBOARD
+#endif
+
/* If we're using the Carbon API on Mac OS X, define a few more
variables as well. */
#ifdef HAVE_CARBON
#define HAVE_WINDOW_SYSTEM
#define HAVE_MOUSE
+/* XXX The MULTI_KBOARD support does not work yet on this platform. */
+#undef MULTI_KBOARD
#endif
/* Define USER_FULL_NAME to return a string
diff --git a/src/data.c b/src/data.c
index 3f27e387350..1f82f929281 100644
--- a/src/data.c
+++ b/src/data.c
@@ -30,6 +30,7 @@ Boston, MA 02110-1301, USA. */
#include "keyboard.h"
#include "frame.h"
#include "syssignal.h"
+#include "termhooks.h" /* For FRAME_KBOARD reference in y-or-n-p. */
#ifdef STDC_HEADERS
#include <float.h>
@@ -873,7 +874,18 @@ do_symval_forwarding (valcontents)
case Lisp_Misc_Kboard_Objfwd:
offset = XKBOARD_OBJFWD (valcontents)->offset;
- return *(Lisp_Object *)(offset + (char *)current_kboard);
+ /* We used to simply use current_kboard here, but from Lisp
+ code, it's value is often unexpected. It seems nicer to
+ allow constructions like this to work as intuitively expected:
+
+ (with-selected-frame frame
+ (define-key local-function-map "\eOP" [f1]))
+
+ On the other hand, this affects the semantics of
+ last-command and real-last-command, and people may rely on
+ that. I took a quick look at the Lisp codebase, and I
+ don't think anything will break. --lorentey */
+ return *(Lisp_Object *)(offset + (char *)FRAME_KBOARD (SELECTED_FRAME ()));
}
return valcontents;
}
@@ -961,7 +973,7 @@ store_symval_forwarding (symbol, valcontents, newval, buf)
case Lisp_Misc_Kboard_Objfwd:
{
- char *base = (char *) current_kboard;
+ char *base = (char *) FRAME_KBOARD (SELECTED_FRAME ());
char *p = base + XKBOARD_OBJFWD (valcontents)->offset;
*(Lisp_Object *) p = newval;
}
@@ -1107,7 +1119,7 @@ find_symbol_value (symbol)
case Lisp_Misc_Kboard_Objfwd:
return *(Lisp_Object *)(XKBOARD_OBJFWD (valcontents)->offset
- + (char *)current_kboard);
+ + (char *)FRAME_KBOARD (SELECTED_FRAME ()));
}
}
@@ -1868,6 +1880,51 @@ If the current binding is global (the default), the value is nil. */)
return Qnil;
}
+
+/* This code is disabled now that we use the selected frame to return
+ keyboard-local-values. */
+#if 0
+extern struct terminal *get_terminal P_ ((Lisp_Object display, int));
+
+DEFUN ("terminal-local-value", Fterminal_local_value, Sterminal_local_value, 2, 2, 0,
+ doc: /* Return the terminal-local value of SYMBOL on TERMINAL.
+If SYMBOL is not a terminal-local variable, then return its normal
+value, like `symbol-value'.
+
+TERMINAL may be a terminal id, a frame, or nil (meaning the
+selected frame's terminal device). */)
+ (symbol, terminal)
+ Lisp_Object symbol;
+ Lisp_Object terminal;
+{
+ Lisp_Object result;
+ struct terminal *t = get_terminal (terminal, 1);
+ push_kboard (t->kboard);
+ result = Fsymbol_value (symbol);
+ pop_kboard ();
+ return result;
+}
+
+DEFUN ("set-terminal-local-value", Fset_terminal_local_value, Sset_terminal_local_value, 3, 3, 0,
+ doc: /* Set the terminal-local binding of SYMBOL on TERMINAL to VALUE.
+If VARIABLE is not a terminal-local variable, then set its normal
+binding, like `set'.
+
+TERMINAL may be a terminal id, a frame, or nil (meaning the
+selected frame's terminal device). */)
+ (symbol, terminal, value)
+ Lisp_Object symbol;
+ Lisp_Object terminal;
+ Lisp_Object value;
+{
+ Lisp_Object result;
+ struct terminal *t = get_terminal (terminal, 1);
+ push_kboard (d->kboard);
+ result = Fset (symbol, value);
+ pop_kboard ();
+ return result;
+}
+#endif
/* Find the function at the end of a chain of symbol function indirections. */
@@ -3327,6 +3384,10 @@ syms_of_data ()
defsubr (&Slocal_variable_p);
defsubr (&Slocal_variable_if_set_p);
defsubr (&Svariable_binding_locus);
+#if 0 /* XXX Remove this. --lorentey */
+ defsubr (&Sterminal_local_value);
+ defsubr (&Sset_terminal_local_value);
+#endif
defsubr (&Saref);
defsubr (&Saset);
defsubr (&Snumber_to_string);
diff --git a/src/dispextern.h b/src/dispextern.h
index 9e899f9ccb2..de9dadec6bc 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1029,13 +1029,8 @@ extern int fonts_changed_p;
extern struct glyph space_glyph;
-/* Frame being updated by update_window/update_frame. */
-
-extern struct frame *updating_frame;
-
/* Window being updated by update_window. This is non-null as long as
- update_window has not finished, and null otherwise. It's role is
- analogous to updating_frame. */
+ update_window has not finished, and null otherwise. */
extern struct window *updated_window;
@@ -1355,7 +1350,7 @@ struct glyph_string
DESCENT = FONT->descent
HEIGHT = FONT_HEIGHT (FONT)
F_DESCENT = (FRAME_FONT (F)->descent
- - F->output_data.x->baseline_offset)
+ - F->terminal->output_data.x->baseline_offset)
F_HEIGHT = FRAME_LINE_HEIGHT (F)
*/
@@ -2184,16 +2179,16 @@ struct it
/* Call produce_glyphs or produce_glyphs_hook, if set. Shortcut to
avoid the function call overhead. */
-#define PRODUCE_GLYPHS(IT) \
- do { \
- extern int inhibit_free_realized_faces; \
- if (rif != NULL) \
- rif->produce_glyphs ((IT)); \
- else \
- produce_glyphs ((IT)); \
- if ((IT)->glyph_row != NULL) \
- inhibit_free_realized_faces = 1; \
- } while (0)
+#define PRODUCE_GLYPHS(IT) \
+ do { \
+ extern int inhibit_free_realized_faces; \
+ if (FRAME_RIF ((IT)->f) != NULL) \
+ FRAME_RIF ((IT)->f)->produce_glyphs ((IT)); \
+ else \
+ produce_glyphs ((IT)); \
+ if ((IT)->glyph_row != NULL) \
+ inhibit_free_realized_faces = 1; \
+ } while (0)
/* Bit-flags indicating what operation move_it_to should perform. */
@@ -2367,10 +2362,6 @@ struct redisplay_interface
#endif /* HAVE_WINDOW_SYSTEM */
};
-/* The current interface for window-based redisplay. */
-
-extern struct redisplay_interface *rif;
-
/***********************************************************************
Images
@@ -2674,8 +2665,6 @@ void init_iterator_to_row_start P_ ((struct it *, struct window *,
struct glyph_row *));
int get_next_display_element P_ ((struct it *));
void set_iterator_to_next P_ ((struct it *, int));
-void produce_glyphs P_ ((struct it *));
-void produce_special_glyphs P_ ((struct it *, enum display_element_type));
void start_display P_ ((struct it *, struct window *, struct text_pos));
void move_it_to P_ ((struct it *, int, int, int, int, int));
void move_it_vertically P_ ((struct it *, int));
@@ -2822,11 +2811,11 @@ int image_ascent P_ ((struct image *, struct face *, struct glyph_slice *));
/* Defined in sysdep.c */
-void get_frame_size P_ ((int *, int *));
+void get_tty_size P_ ((int, int *, int *));
void request_sigio P_ ((void));
void unrequest_sigio P_ ((void));
-int tabs_safe_p P_ ((void));
-void init_baud_rate P_ ((void));
+int tabs_safe_p P_ ((int));
+void init_baud_rate P_ ((int));
void init_sigio P_ ((int));
/* Defined in xfaces.c */
@@ -2965,8 +2954,6 @@ void clear_glyph_row P_ ((struct glyph_row *));
void prepare_desired_row P_ ((struct glyph_row *));
int line_hash_code P_ ((struct glyph_row *));
void set_window_update_flags P_ ((struct window *, int));
-void write_glyphs P_ ((struct glyph *, int));
-void insert_glyphs P_ ((struct glyph *, int));
void redraw_frame P_ ((struct frame *));
void redraw_garbaged_frames P_ ((void));
int scroll_cost P_ ((struct frame *, int, int, int));
@@ -2983,31 +2970,44 @@ void syms_of_display P_ ((void));
extern Lisp_Object Qredisplay_dont_pause;
GLYPH spec_glyph_lookup_face P_ ((struct window *, GLYPH));
-/* Defined in term.c */
+/* Defined in terminal.c */
-extern void ring_bell P_ ((void));
-extern void set_terminal_modes P_ ((void));
-extern void reset_terminal_modes P_ ((void));
+extern void ring_bell P_ ((struct frame *));
extern void update_begin P_ ((struct frame *));
extern void update_end P_ ((struct frame *));
-extern void set_terminal_window P_ ((int));
-extern void set_scroll_region P_ ((int, int));
-extern void turn_off_insert P_ ((void));
-extern void turn_off_highlight P_ ((void));
-extern void background_highlight P_ ((void));
-extern void clear_frame P_ ((void));
-extern void clear_end_of_line P_ ((int));
-extern void clear_end_of_line_raw P_ ((int));
-extern void delete_glyphs P_ ((int));
-extern void ins_del_lines P_ ((int, int));
+extern void set_terminal_window P_ ((struct frame *, int));
+extern void cursor_to P_ ((struct frame *, int, int));
+extern void raw_cursor_to P_ ((struct frame *, int, int));
+extern void clear_to_end P_ ((struct frame *));
+extern void clear_frame P_ ((struct frame *));
+extern void clear_end_of_line P_ ((struct frame *, int));
+extern void write_glyphs P_ ((struct frame *, struct glyph *, int));
+extern void insert_glyphs P_ ((struct frame *, struct glyph *, int));
+extern void delete_glyphs P_ ((struct frame *, int));
+extern void ins_del_lines P_ ((struct frame *, int, int));
+
+extern struct terminal *init_initial_terminal P_ ((void));
+
+
+/* Defined in term.c */
+
+extern void tty_set_terminal_modes P_ ((struct terminal *));
+extern void tty_reset_terminal_modes P_ ((struct terminal *));
+extern void tty_turn_off_insert P_ ((struct tty_display_info *));
+extern void tty_turn_off_highlight P_ ((struct tty_display_info *));
extern int string_cost P_ ((char *));
extern int per_line_cost P_ ((char *));
extern void calculate_costs P_ ((struct frame *));
+extern void produce_glyphs P_ ((struct it *));
+extern void produce_special_glyphs P_ ((struct it *, enum display_element_type));
+extern int tty_capable_p P_ ((struct tty_display_info *, unsigned, unsigned long, unsigned long));
extern void set_tty_color_mode P_ ((struct frame *, Lisp_Object));
-extern void tty_setup_colors P_ ((int));
-extern void term_init P_ ((char *));
-void cursor_to P_ ((int, int));
-extern int tty_capable_p P_ ((struct frame *, unsigned, unsigned long, unsigned long));
+extern struct terminal *get_tty_terminal P_ ((Lisp_Object, int));
+extern struct terminal *get_named_tty P_ ((char *));
+EXFUN (Ftty_type, 1);
+extern void create_tty_output P_ ((struct frame *));
+extern struct terminal *init_tty P_ ((char *, char *, int));
+
/* Defined in scroll.c */
diff --git a/src/dispnew.c b/src/dispnew.c
index 1502ffd753c..7a80a8a618a 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -32,7 +32,6 @@ Boston, MA 02110-1301, USA. */
#include "lisp.h"
#include "termchar.h"
#include "termopts.h"
-#include "termhooks.h"
/* cm.h must come after dispextern.h on Windows. */
#include "dispextern.h"
#include "cm.h"
@@ -40,6 +39,7 @@ Boston, MA 02110-1301, USA. */
#include "charset.h"
#include "keyboard.h"
#include "frame.h"
+#include "termhooks.h"
#include "window.h"
#include "commands.h"
#include "disptab.h"
@@ -238,9 +238,9 @@ int inverse_video;
EMACS_INT baud_rate;
/* Either nil or a symbol naming the window system under which Emacs
- is running. */
+ creates the first frame. */
-Lisp_Object Vwindow_system;
+Lisp_Object Vinitial_window_system;
/* Version number of X windows: 10, 11 or nil. */
@@ -282,14 +282,6 @@ Lisp_Object selected_frame;
struct frame *last_nonminibuf_frame;
-/* Stdio stream being used for copy of all output. */
-
-FILE *termscript;
-
-/* Structure for info on cursor positioning. */
-
-struct cm Wcm;
-
/* 1 means SIGWINCH happened when not safe. */
int delayed_size_change;
@@ -328,11 +320,6 @@ int glyph_pool_count;
static struct frame *frame_matrix_frame;
-/* Current interface for window-based redisplay. Set from init_xterm.
- A null value means we are not using window-based redisplay. */
-
-struct redisplay_interface *rif;
-
/* Non-zero means that fonts have been loaded since the last glyph
matrix adjustments. Redisplay must stop, and glyph matrices must
be adjusted when this flag becomes non-zero during display. The
@@ -1423,7 +1410,7 @@ line_hash_code (row)
{
int c = glyph->u.ch;
int face_id = glyph->face_id;
- if (must_write_spaces)
+ if (FRAME_MUST_WRITE_SPACES (SELECTED_FRAME ())) /* XXX Is SELECTED_FRAME OK here? */
c -= SPACEGLYPH;
hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + c;
hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + face_id;
@@ -1455,7 +1442,7 @@ line_draw_cost (matrix, vpos)
int glyph_table_len = GLYPH_TABLE_LENGTH;
/* Ignore trailing and leading spaces if we can. */
- if (!must_write_spaces)
+ if (!FRAME_MUST_WRITE_SPACES (SELECTED_FRAME ())) /* XXX Is SELECTED_FRAME OK here? */
{
/* Skip from the end over trailing spaces. */
while (end > beg && CHAR_GLYPH_SPACE_P (*(end - 1)))
@@ -1671,8 +1658,10 @@ realloc_glyph_pool (pool, matrix_dim)
#if GLYPH_DEBUG
-/* Flush standard output. This is sometimes useful to call from
- the debugger. */
+/* Flush standard output. This is sometimes useful to call from the debugger.
+ XXX Maybe this should be changed to flush the current terminal instead of
+ stdout.
+*/
void
flush_stdout ()
@@ -3393,12 +3382,15 @@ DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0,
return Qnil;
update_begin (f);
+#ifdef MSDOS
if (FRAME_MSDOS_P (f))
- set_terminal_modes ();
- clear_frame ();
+ set_terminal_modes (FRAME_TERMINAL (f));
+#endif
+ clear_frame (f);
clear_current_matrices (f);
update_end (f);
- fflush (stdout);
+ if (FRAME_TERMCAP_P (f))
+ fflush (FRAME_TTY (f)->output);
windows_or_buffers_changed++;
/* Mark all windows as inaccurate, so that every window will have
its redisplay done. */
@@ -3539,7 +3531,7 @@ direct_output_for_insert (g)
/* If we can't insert glyphs, we can use this method only
at the end of a line. */
- if (!char_ins_del_ok)
+ if (!FRAME_CHAR_INS_DEL_OK (f))
if (PT != ZV && FETCH_BYTE (PT_BYTE) != '\n')
return 0;
@@ -3689,24 +3681,24 @@ direct_output_for_insert (g)
updated_row = glyph_row;
updated_area = TEXT_AREA;
update_begin (f);
- if (rif)
+ if (FRAME_RIF (f))
{
- rif->update_window_begin_hook (w);
+ FRAME_RIF (f)->update_window_begin_hook (w);
if (glyphs == end - n
/* In front of a space added by append_space. */
|| (glyphs == end - n - 1
&& (end - n)->charpos <= 0))
- rif->write_glyphs (glyphs, n);
+ FRAME_RIF (f)->write_glyphs (glyphs, n);
else
- rif->insert_glyphs (glyphs, n);
+ FRAME_RIF (f)->insert_glyphs (glyphs, n);
}
else
{
if (glyphs == end - n)
- write_glyphs (glyphs, n);
+ write_glyphs (f, glyphs, n);
else
- insert_glyphs (glyphs, n);
+ insert_glyphs (f, glyphs, n);
}
w->cursor.hpos += n;
@@ -3719,8 +3711,8 @@ direct_output_for_insert (g)
a frame matrix is used, cursor_to expects frame coordinates,
and the X and Y parameters are not used. */
if (window_redisplay_p)
- rif->cursor_to (w->cursor.vpos, w->cursor.hpos,
- w->cursor.y, w->cursor.x);
+ FRAME_RIF (f)->cursor_to (w->cursor.vpos, w->cursor.hpos,
+ w->cursor.y, w->cursor.x);
else
{
int x, y;
@@ -3729,18 +3721,19 @@ direct_output_for_insert (g)
? XFASTINT (w->left_margin_cols)
: 0));
y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
- cursor_to (y, x);
+ cursor_to (f, y, x);
}
#ifdef HAVE_WINDOW_SYSTEM
update_window_fringes (w, 0);
#endif
- if (rif)
- rif->update_window_end_hook (w, 1, 0);
+ if (FRAME_RIF (f))
+ FRAME_RIF (f)->update_window_end_hook (w, 1, 0);
update_end (f);
updated_row = NULL;
- fflush (stdout);
+ if (FRAME_TERMCAP_P (f))
+ fflush (FRAME_TTY (f)->output);
TRACE ((stderr, "direct output for insert\n"));
mark_window_display_accurate (it.window, 1);
@@ -3818,8 +3811,8 @@ direct_output_forward_char (n)
&& w->cursor.hpos < w->desired_matrix->matrix_w);
if (FRAME_WINDOW_P (f))
- rif->cursor_to (w->cursor.vpos, w->cursor.hpos,
- w->cursor.y, w->cursor.x);
+ FRAME_RIF (f)->cursor_to (w->cursor.vpos, w->cursor.hpos,
+ w->cursor.y, w->cursor.x);
else
{
int x, y;
@@ -3828,10 +3821,11 @@ direct_output_forward_char (n)
? XFASTINT (w->left_margin_cols)
: 0));
y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
- cursor_to (y, x);
+ cursor_to (f, y, x);
}
- fflush (stdout);
+ if (FRAME_TERMCAP_P (f))
+ fflush (FRAME_TTY (f)->output);
redisplay_performed_directly_p = 1;
return 1;
}
@@ -3930,14 +3924,14 @@ update_frame (f, force_p, inhibit_hairy_id_p)
update_end (f);
/* This flush is a performance bottleneck under X,
- and it doesn't seem to be necessary anyway (in general).
+ and it doesn't seem to be necessary anyway (in general).
It is necessary when resizing the window with the mouse, or
- at least the fringes are not redrawn in a timely manner. ++kfs */
+ at least the fringes are not redrawn in a timely manner. ++kfs */
if (f->force_flush_display_p)
- {
- rif->flush_display (f);
- f->force_flush_display_p = 0;
- }
+ {
+ FRAME_RIF (f)->flush_display (f);
+ f->force_flush_display_p = 0;
+ }
}
else
{
@@ -3953,9 +3947,12 @@ update_frame (f, force_p, inhibit_hairy_id_p)
paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p);
update_end (f);
- if (termscript)
- fflush (termscript);
- fflush (stdout);
+ if (FRAME_TERMCAP_P (f))
+ {
+ if (FRAME_TTY (f)->termscript)
+ fflush (FRAME_TTY (f)->termscript);
+ fflush (FRAME_TTY (f)->output);
+ }
/* Check window matrices for lost pointers. */
#if GLYPH_DEBUG
@@ -4060,7 +4057,8 @@ redraw_overlapped_rows (w, yb)
int yb;
{
int i;
-
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
+
/* If rows overlapping others have been changed, the rows being
overlapped have to be redrawn. This won't draw lines that have
already been drawn in update_window_line because overlapped_p in
@@ -4083,10 +4081,12 @@ redraw_overlapped_rows (w, yb)
{
updated_row = row;
updated_area = area;
- rif->cursor_to (i, 0, row->y, area == TEXT_AREA ? row->x : 0);
+ FRAME_RIF (f)->cursor_to (i, 0, row->y,
+ area == TEXT_AREA ? row->x : 0);
if (row->used[area])
- rif->write_glyphs (row->glyphs[area], row->used[area]);
- rif->clear_end_of_line (-1);
+ FRAME_RIF (f)->write_glyphs (row->glyphs[area],
+ row->used[area]);
+ FRAME_RIF (f)->clear_end_of_line (-1);
}
row->overlapped_p = 0;
@@ -4108,7 +4108,8 @@ redraw_overlapping_rows (w, yb)
{
int i, bottom_y;
struct glyph_row *row;
-
+ struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
+
for (i = 0; i < w->current_matrix->nrows; ++i)
{
row = w->current_matrix->rows + i;
@@ -4199,10 +4200,10 @@ update_window (w, force_p)
#endif
extern int input_pending;
extern Lisp_Object do_mouse_tracking;
+ struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
#if GLYPH_DEBUG
/* Check that W's frame doesn't have glyph matrices. */
xassert (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))));
- xassert (updating_frame != NULL);
#endif
/* Check pending input the first time so that we can quickly return. */
@@ -4387,6 +4388,7 @@ update_marginal_area (w, area, vpos)
int area, vpos;
{
struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
+ struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
/* Let functions in xterm.c know what area subsequent X positions
will be relative to. */
@@ -4412,6 +4414,7 @@ update_text_area (w, vpos)
{
struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
+ struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
int changed_p = 0;
/* Let functions in xterm.c know what area subsequent X positions
@@ -4647,6 +4650,7 @@ update_window_line (w, vpos, mouse_face_overwritten_p)
{
struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
+ struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
int changed_p = 0;
/* Set the row being updated. This is important to let xterm.c
@@ -4715,6 +4719,7 @@ set_window_cursor_after_update (w)
struct window *w;
{
struct frame *f = XFRAME (w->frame);
+ struct redisplay_interface *rif = FRAME_RIF (f);
int cx, cy, vpos, hpos;
/* Not intended for frame matrix updates. */
@@ -4938,6 +4943,7 @@ scrolling_window (w, header_line_p)
int i, j, first_old, first_new, last_old, last_new;
int nruns, nbytes, n, run_idx;
struct row_entry *entry;
+ struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
/* Skip over rows equal at the start. */
for (i = header_line_p ? 1 : 0; i < current_matrix->nrows - 1; ++i)
@@ -5262,7 +5268,7 @@ update_frame_1 (f, force_p, inhibit_id_p)
#endif
/* If we cannot insert/delete lines, it's no use trying it. */
- if (!line_ins_del_ok)
+ if (!FRAME_LINE_INS_DEL_OK (f))
inhibit_id_p = 1;
/* See if any of the desired lines are enabled; don't compute for
@@ -5290,18 +5296,18 @@ update_frame_1 (f, force_p, inhibit_id_p)
Also flush out if likely to have more than 1k buffered
otherwise. I'm told that some telnet connections get
really screwed by more than 1k output at once. */
- int outq = PENDING_OUTPUT_COUNT (stdout);
+ int outq = PENDING_OUTPUT_COUNT (FRAME_TTY (f)->output);
if (outq > 900
|| (outq > 20 && ((i - 1) % preempt_count == 0)))
{
- fflush (stdout);
+ fflush (FRAME_TTY (f)->output);
if (preempt_count == 1)
{
#ifdef EMACS_OUTQSIZE
if (EMACS_OUTQSIZE (0, &outq) < 0)
/* Probably not a tty. Ignore the error and reset
the outq count. */
- outq = PENDING_OUTPUT_COUNT (stdout);
+ outq = PENDING_OUTPUT_COUNT (FRAME_TTY (f->output));
#endif
outq *= 10;
if (baud_rate <= outq && baud_rate > 0)
@@ -5404,7 +5410,7 @@ update_frame_1 (f, force_p, inhibit_id_p)
}
}
- cursor_to (row, col);
+ cursor_to (f, row, col);
}
else
{
@@ -5426,7 +5432,7 @@ update_frame_1 (f, force_p, inhibit_id_p)
x += XFASTINT (w->left_margin_cols);
/* x = max (min (x, FRAME_TOTAL_COLS (f) - 1), 0); */
- cursor_to (y, x);
+ cursor_to (f, y, x);
}
}
}
@@ -5495,21 +5501,23 @@ scrolling (frame)
}
/* If changed lines are few, don't allow preemption, don't scroll. */
- if ((!scroll_region_ok && changed_lines < baud_rate / 2400)
+ if ((!FRAME_SCROLL_REGION_OK (frame)
+ && changed_lines < baud_rate / 2400)
|| unchanged_at_bottom == FRAME_LINES (frame))
return 1;
window_size = (FRAME_LINES (frame) - unchanged_at_top
- unchanged_at_bottom);
- if (scroll_region_ok)
+ if (FRAME_SCROLL_REGION_OK (frame))
free_at_end_vpos -= unchanged_at_bottom;
- else if (memory_below_frame)
+ else if (FRAME_MEMORY_BELOW_FRAME (frame))
free_at_end_vpos = -1;
/* If large window, fast terminal and few lines in common between
current frame and desired frame, don't bother with i/d calc. */
- if (!scroll_region_ok && window_size >= 18 && baud_rate > 2400
+ if (!FRAME_SCROLL_REGION_OK (frame)
+ && window_size >= 18 && baud_rate > 2400
&& (window_size >=
10 * scrolling_max_lines_saved (unchanged_at_top,
FRAME_LINES (frame) - unchanged_at_bottom,
@@ -5589,7 +5597,7 @@ update_frame_line (f, vpos)
struct glyph_row *current_row = MATRIX_ROW (current_matrix, vpos);
struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, vpos);
int must_write_whole_line_p;
- int write_spaces_p = must_write_spaces;
+ int write_spaces_p = FRAME_MUST_WRITE_SPACES (f);
int colored_spaces_p = (FACE_FROM_ID (f, DEFAULT_FACE_ID)->background
!= FACE_TTY_DEFAULT_BG_COLOR);
@@ -5640,8 +5648,8 @@ update_frame_line (f, vpos)
/* Write the contents of the desired line. */
if (nlen)
{
- cursor_to (vpos, 0);
- write_glyphs (nbody, nlen);
+ cursor_to (f, vpos, 0);
+ write_glyphs (f, nbody, nlen);
}
/* Don't call clear_end_of_line if we already wrote the whole
@@ -5649,13 +5657,13 @@ update_frame_line (f, vpos)
case but in the line below. */
if (nlen < FRAME_TOTAL_COLS (f))
{
- cursor_to (vpos, nlen);
- clear_end_of_line (FRAME_TOTAL_COLS (f));
+ cursor_to (f, vpos, nlen);
+ clear_end_of_line (f, FRAME_TOTAL_COLS (f));
}
else
/* Make sure we are in the right row, otherwise cursor movement
with cmgoto might use `ch' in the wrong row. */
- cursor_to (vpos, 0);
+ cursor_to (f, vpos, 0);
make_current (desired_matrix, current_matrix, vpos);
return;
@@ -5668,7 +5676,7 @@ update_frame_line (f, vpos)
nlen--;
/* If there's no i/d char, quickly do the best we can without it. */
- if (!char_ins_del_ok)
+ if (!FRAME_CHAR_INS_DEL_OK (f))
{
int i, j;
@@ -5687,8 +5695,8 @@ update_frame_line (f, vpos)
++j;
/* Output this run of non-matching chars. */
- cursor_to (vpos, i);
- write_glyphs (nbody + i, j - i);
+ cursor_to (f, vpos, i);
+ write_glyphs (f, nbody + i, j - i);
i = j - 1;
/* Now find the next non-match. */
@@ -5698,8 +5706,8 @@ update_frame_line (f, vpos)
/* Clear the rest of the line, or the non-clear part of it. */
if (olen > nlen)
{
- cursor_to (vpos, nlen);
- clear_end_of_line (olen);
+ cursor_to (f, vpos, nlen);
+ clear_end_of_line (f, olen);
}
/* Make current row = desired row. */
@@ -5721,8 +5729,8 @@ update_frame_line (f, vpos)
if (nlen > nsp)
{
- cursor_to (vpos, nsp);
- write_glyphs (nbody + nsp, nlen - nsp);
+ cursor_to (f, vpos, nsp);
+ write_glyphs (f, nbody + nsp, nlen - nsp);
}
/* Exchange contents between current_frame and new_frame. */
@@ -5771,7 +5779,8 @@ update_frame_line (f, vpos)
tem = (nlen - nsp) - (olen - osp);
if (endmatch && tem
- && (!char_ins_del_ok || endmatch <= char_ins_del_cost (f)[tem]))
+ && (!FRAME_CHAR_INS_DEL_OK (f)
+ || endmatch <= char_ins_del_cost (f)[tem]))
endmatch = 0;
/* nsp - osp is the distance to insert or delete.
@@ -5780,7 +5789,7 @@ update_frame_line (f, vpos)
Is it worth it? */
if (nsp != osp
- && (!char_ins_del_ok
+ && (!FRAME_CHAR_INS_DEL_OK (f)
|| begmatch + endmatch <= char_ins_del_cost (f)[nsp - osp]))
{
begmatch = 0;
@@ -5793,8 +5802,8 @@ update_frame_line (f, vpos)
if (osp > nsp)
{
- cursor_to (vpos, nsp);
- delete_glyphs (osp - nsp);
+ cursor_to (f, vpos, nsp);
+ delete_glyphs (f, osp - nsp);
}
else if (nsp > osp)
{
@@ -5803,12 +5812,12 @@ update_frame_line (f, vpos)
must delete first to avoid losing data in the insert */
if (endmatch && nlen < olen + nsp - osp)
{
- cursor_to (vpos, nlen - endmatch + osp - nsp);
- delete_glyphs (olen + nsp - osp - nlen);
+ cursor_to (f, vpos, nlen - endmatch + osp - nsp);
+ delete_glyphs (f, olen + nsp - osp - nlen);
olen = nlen - (nsp - osp);
}
- cursor_to (vpos, osp);
- insert_glyphs (0, nsp - osp);
+ cursor_to (f, vpos, osp);
+ insert_glyphs (f, 0, nsp - osp);
}
olen += nsp - osp;
@@ -5829,8 +5838,8 @@ update_frame_line (f, vpos)
unnecessary cursor movement. */
if (nlen - tem > 0)
{
- cursor_to (vpos, nsp + begmatch);
- write_glyphs (nbody + nsp + begmatch, nlen - tem);
+ cursor_to (f, vpos, nsp + begmatch);
+ write_glyphs (f, nbody + nsp + begmatch, nlen - tem);
}
}
else if (nlen > olen)
@@ -5845,27 +5854,27 @@ update_frame_line (f, vpos)
int out = olen - tem; /* Columns to be overwritten originally. */
int del;
- cursor_to (vpos, nsp + begmatch);
+ cursor_to (f, vpos, nsp + begmatch);
/* Calculate columns we can actually overwrite. */
while (CHAR_GLYPH_PADDING_P (nbody[nsp + begmatch + out]))
out--;
- write_glyphs (nbody + nsp + begmatch, out);
+ write_glyphs (f, nbody + nsp + begmatch, out);
/* If we left columns to be overwritten, we must delete them. */
del = olen - tem - out;
if (del > 0)
- delete_glyphs (del);
+ delete_glyphs (f, del);
/* At last, we insert columns not yet written out. */
- insert_glyphs (nbody + nsp + begmatch + out, nlen - olen + del);
+ insert_glyphs (f, nbody + nsp + begmatch + out, nlen - olen + del);
olen = nlen;
}
else if (olen > nlen)
{
- cursor_to (vpos, nsp + begmatch);
- write_glyphs (nbody + nsp + begmatch, nlen - tem);
- delete_glyphs (olen - nlen);
+ cursor_to (f, vpos, nsp + begmatch);
+ write_glyphs (f, nbody + nsp + begmatch, nlen - tem);
+ delete_glyphs (f, olen - nlen);
olen = nlen;
}
}
@@ -5874,8 +5883,8 @@ update_frame_line (f, vpos)
/* If any unerased characters remain after the new line, erase them. */
if (olen > nlen)
{
- cursor_to (vpos, nlen);
- clear_end_of_line (olen);
+ cursor_to (f, vpos, nlen);
+ clear_end_of_line (f, olen);
}
/* Exchange contents between current_frame and new_frame. */
@@ -6172,31 +6181,34 @@ window_change_signal (signalnum) /* If we don't have an argument, */
#endif
int old_errno = errno;
+ struct tty_display_info *tty;
+
signal (SIGWINCH, window_change_signal);
SIGNAL_THREAD_CHECK (signalnum);
- get_frame_size (&width, &height);
-
- /* The frame size change obviously applies to a termcap-controlled
- frame. Find such a frame in the list, and assume it's the only
- one (since the redisplay code always writes to stdout, not a
- FILE * specified in the frame structure). Record the new size,
- but don't reallocate the data structures now. Let that be done
- later outside of the signal handler. */
+ /* The frame size change obviously applies to a single
+ termcap-controlled terminal, but we can't decide which.
+ Therefore, we resize the frames corresponding to each tty.
+ */
+ for (tty = tty_list; tty; tty = tty->next) {
- {
- Lisp_Object tail, frame;
+ if (! tty->term_initted)
+ continue;
- FOR_EACH_FRAME (tail, frame)
- {
- if (FRAME_TERMCAP_P (XFRAME (frame)))
- {
- change_frame_size (XFRAME (frame), height, width, 0, 1, 0);
- break;
- }
- }
+ get_tty_size (fileno (tty->input), &width, &height);
+
+ if (width > 5 && height > 2) {
+ Lisp_Object tail, frame;
+
+ FOR_EACH_FRAME (tail, frame)
+ if (FRAME_TERMCAP_P (XFRAME (frame)) && FRAME_TTY (XFRAME (frame)) == tty)
+ /* Record the new sizes, but don't reallocate the data
+ structures now. Let that be done later outside of the
+ signal handler. */
+ change_frame_size (XFRAME (frame), height, width, 0, 1, 0);
+ }
}
-
+
errno = old_errno;
}
#endif /* SIGWINCH */
@@ -6250,10 +6262,11 @@ change_frame_size (f, newheight, newwidth, pretend, delay, safe)
{
Lisp_Object tail, frame;
- if (! FRAME_WINDOW_P (f))
+ if (FRAME_MSDOS_P (f))
{
- /* When using termcap, or on MS-DOS, all frames use
- the same screen, so a change in size affects all frames. */
+ /* On MS-DOS, all frames use the same screen, so a change in
+ size affects all frames. Termcap now supports multiple
+ ttys. */
FOR_EACH_FRAME (tail, frame)
if (! FRAME_WINDOW_P (XFRAME (frame)))
change_frame_size_1 (XFRAME (frame), newheight, newwidth,
@@ -6333,7 +6346,7 @@ change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe)
newheight - FRAME_TOP_MARGIN (f), 0);
if (FRAME_TERMCAP_P (f) && !pretend)
- FrameRows = newheight;
+ FrameRows (FRAME_TTY (f)) = newheight;
}
if (new_frame_total_cols != FRAME_TOTAL_COLS (f))
@@ -6343,7 +6356,7 @@ change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe)
set_window_width (FRAME_MINIBUF_WINDOW (f), new_frame_total_cols, 0);
if (FRAME_TERMCAP_P (f) && !pretend)
- FrameCols = newwidth;
+ FrameCols (FRAME_TTY (f)) = newwidth;
if (WINDOWP (f->tool_bar_window))
XSETFASTINT (XWINDOW (f->tool_bar_window)->total_cols, newwidth);
@@ -6393,19 +6406,26 @@ FILE = nil means just close any termscript file currently open. */)
(file)
Lisp_Object file;
{
- if (termscript != 0)
- {
- BLOCK_INPUT;
- fclose (termscript);
- UNBLOCK_INPUT;
- }
- termscript = 0;
+ struct tty_display_info *tty;
+
+ if (! FRAME_TERMCAP_P (SELECTED_FRAME ()))
+ error ("Current frame is not on a tty device");
+
+ tty = CURTTY ();
+
+ if (tty->termscript != 0)
+ {
+ BLOCK_INPUT;
+ fclose (tty->termscript);
+ UNBLOCK_INPUT;
+ }
+ tty->termscript = 0;
if (! NILP (file))
{
file = Fexpand_file_name (file, Qnil);
- termscript = fopen (SDATA (file), "w");
- if (termscript == 0)
+ tty->termscript = fopen (SDATA (file), "w");
+ if (tty->termscript == 0)
report_file_error ("Opening termscript", Fcons (file, Qnil));
}
return Qnil;
@@ -6413,23 +6433,36 @@ FILE = nil means just close any termscript file currently open. */)
DEFUN ("send-string-to-terminal", Fsend_string_to_terminal,
- Ssend_string_to_terminal, 1, 1, 0,
+ Ssend_string_to_terminal, 1, 2, 0,
doc: /* Send STRING to the terminal without alteration.
-Control characters in STRING will have terminal-dependent effects. */)
- (string)
+Control characters in STRING will have terminal-dependent effects.
+
+Optional parameter TERMINAL specifies the tty terminal device to use.
+It may be a terminal id, a frame, or nil for the terminal used by the
+currently selected frame. */)
+ (string, terminal)
Lisp_Object string;
+ Lisp_Object terminal;
{
+ struct terminal *t = get_tty_terminal (terminal, 1);
+ struct tty_display_info *tty;
+
/* ??? Perhaps we should do something special for multibyte strings here. */
CHECK_STRING (string);
BLOCK_INPUT;
- fwrite (SDATA (string), 1, SBYTES (string), stdout);
- fflush (stdout);
- if (termscript)
+
+ if (!t)
+ error ("Unknown terminal device");
+
+ tty = t->display_info.tty;
+
+ if (tty->termscript)
{
- fwrite (SDATA (string), 1, SBYTES (string),
- termscript);
- fflush (termscript);
+ fwrite (SDATA (string), 1, SBYTES (string), tty->termscript);
+ fflush (tty->termscript);
}
+ fwrite (SDATA (string), 1, SBYTES (string), tty->output);
+ fflush (tty->output);
UNBLOCK_INPUT;
return Qnil;
}
@@ -6447,8 +6480,7 @@ terminate any keyboard macro currently executing. */)
if (noninteractive)
putchar (07);
else
- ring_bell ();
- fflush (stdout);
+ ring_bell (XFRAME (selected_frame));
}
else
bitch_at_user ();
@@ -6464,8 +6496,7 @@ bitch_at_user ()
else if (!INTERACTIVE) /* Stop executing a keyboard macro. */
error ("Keyboard macro terminated by a command ringing the bell");
else
- ring_bell ();
- fflush (stdout);
+ ring_bell (XFRAME (selected_frame));
}
@@ -6748,8 +6779,6 @@ pass nil for VARIABLE. */)
Initialization
***********************************************************************/
-char *terminal_type;
-
/* Initialization done when Emacs fork is started, before doing stty.
Determine terminal type and set terminal_driver. Then invoke its
decoding routine to set up variables in the terminal package. */
@@ -6757,6 +6786,8 @@ char *terminal_type;
void
init_display ()
{
+ char *terminal_type;
+
#ifdef HAVE_X_WINDOWS
extern int display_arg;
#endif
@@ -6766,14 +6797,23 @@ init_display ()
SET_CHAR_GLYPH_FROM_GLYPH (space_glyph, ' ');
space_glyph.charpos = -1;
- meta_key = 0;
inverse_video = 0;
cursor_in_echo_area = 0;
terminal_type = (char *) 0;
/* Now is the time to initialize this; it's used by init_sys_modes
during startup. */
- Vwindow_system = Qnil;
+ Vinitial_window_system = Qnil;
+
+ /* SIGWINCH needs to be handled no matter what display we start
+ with. Otherwise newly opened tty frames will not resize
+ automatically. */
+#ifdef SIGWINCH
+#ifndef CANNOT_DUMP
+ if (initialized)
+#endif /* CANNOT_DUMP */
+ signal (SIGWINCH, window_change_signal);
+#endif /* SIGWINCH */
/* If the user wants to use a window system, we shouldn't bother
initializing the terminal. This is especially important when the
@@ -6809,7 +6849,7 @@ init_display ()
#endif
)
{
- Vwindow_system = intern ("x");
+ Vinitial_window_system = intern ("x");
#ifdef HAVE_X11
Vwindow_system_version = make_number (11);
#else
@@ -6829,7 +6869,7 @@ init_display ()
#ifdef HAVE_NTGUI
if (!inhibit_window_system)
{
- Vwindow_system = intern ("w32");
+ Vinitial_window_system = intern ("w32");
Vwindow_system_version = make_number (1);
adjust_frame_glyphs_initially ();
return;
@@ -6839,7 +6879,7 @@ init_display ()
#ifdef MAC_OS
if (!inhibit_window_system)
{
- Vwindow_system = intern ("mac");
+ Vinitial_window_system = intern ("mac");
Vwindow_system_version = make_number (1);
adjust_frame_glyphs_initially ();
return;
@@ -6891,8 +6931,38 @@ For types not defined in VMS, use define emacs_term \"TYPE\".\n\
}
#endif /* VMS */
- term_init (terminal_type);
-
+ {
+ struct terminal *t;
+ struct frame *f = XFRAME (selected_frame);
+
+ /* Open a display on the controlling tty. */
+ t = init_tty (0, terminal_type, 1); /* Errors are fatal. */
+
+ /* Convert the initial frame to use the new display. */
+ if (f->output_method != output_initial)
+ abort ();
+ f->output_method = t->type;
+ f->terminal = t;
+
+ t->reference_count++;
+ t->display_info.tty->top_frame = selected_frame;
+ change_frame_size (XFRAME (selected_frame),
+ FrameRows (t->display_info.tty),
+ FrameCols (t->display_info.tty), 0, 0, 1);
+
+ /* Delete the initial terminal. */
+ if (--initial_terminal->reference_count == 0
+ && initial_terminal->delete_terminal_hook)
+ (*initial_terminal->delete_terminal_hook) (initial_terminal);
+
+ /* Update frame parameters to reflect the new type. */
+ Fmodify_frame_parameters (selected_frame, Fcons (Fcons (Qwindow_system, Qnil), Qnil));
+ Fmodify_frame_parameters
+ (selected_frame, Fcons (Fcons (Qtty_type,
+ Ftty_type (selected_frame)), Qnil));
+ Fmodify_frame_parameters (selected_frame, Fcons (Fcons (Qtty, Qnil), Qnil));
+ }
+
{
struct frame *sf = SELECTED_FRAME ();
int width = FRAME_TOTAL_COLS (sf);
@@ -6909,13 +6979,6 @@ For types not defined in VMS, use define emacs_term \"TYPE\".\n\
adjust_frame_glyphs_initially ();
calculate_costs (XFRAME (selected_frame));
-#ifdef SIGWINCH
-#ifndef CANNOT_DUMP
- if (initialized)
-#endif /* CANNOT_DUMP */
- signal (SIGWINCH, window_change_signal);
-#endif /* SIGWINCH */
-
/* Set up faces of the initial terminal frame of a dumped Emacs. */
if (initialized
&& !noninteractive
@@ -6926,7 +6989,7 @@ For types not defined in VMS, use define emacs_term \"TYPE\".\n\
and internal_terminal_init. */
&& (strcmp (terminal_type, "internal") != 0 || inhibit_window_system)
#endif
- && NILP (Vwindow_system))
+ && NILP (Vinitial_window_system))
{
/* For the initial frame, we don't have any way of knowing what
are the foreground and background colors of the terminal. */
@@ -7038,8 +7101,8 @@ A non-nil value is useful if the terminal can automatically preserve
Emacs's frame display when you reenter Emacs.
It is up to you to set this variable if your terminal can do that. */);
- DEFVAR_LISP ("window-system", &Vwindow_system,
- doc: /* Name of window system that Emacs is displaying through.
+ DEFVAR_LISP ("initial-window-system", &Vinitial_window_system,
+ doc: /* Name of the window system that Emacs uses for the first frame.
The value is a symbol--for instance, `x' for X windows.
The value is nil if Emacs is using a text-only terminal. */);
@@ -7082,7 +7145,7 @@ If nil, never pre-empt redisplay. */);
if (noninteractive)
#endif
{
- Vwindow_system = Qnil;
+ Vinitial_window_system = Qnil;
Vwindow_system_version = Qnil;
}
}
diff --git a/src/emacs.c b/src/emacs.c
index 5dacafc9b3e..55475e57799 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -57,6 +57,7 @@ Boston, MA 02110-1301, USA. */
#include "blockinput.h"
#include "syssignal.h"
#include "process.h"
+#include "frame.h"
#include "termhooks.h"
#include "keyboard.h"
#include "keymap.h"
@@ -214,7 +215,7 @@ static unsigned long heap_bss_diff;
#ifdef HAVE_WINDOW_SYSTEM
-extern Lisp_Object Vwindow_system;
+extern Lisp_Object Vinitial_window_system;
#endif /* HAVE_WINDOW_SYSTEM */
extern Lisp_Object Vauto_save_list_file_name;
@@ -1296,6 +1297,9 @@ main (argc, argv
faces, and the face implementation uses some symbols as
face names. */
syms_of_xfaces ();
+ /* XXX syms_of_keyboard uses some symbols in keymap.c. It would
+ be better to arrange things not to have this dependency. */
+ syms_of_keymap ();
/* Call syms_of_keyboard before init_window_once because
keyboard sets up symbols that include some face names that
the X support will want to use. This can happen when
@@ -1493,10 +1497,10 @@ main (argc, argv
/* egetenv is a pretty low-level facility, which may get called in
many circumstances; it seems flimsy to put off initializing it
until calling init_callproc. */
- set_process_environment ();
+ set_initial_environment ();
/* AIX crashes are reported in system versions 3.2.3 and 3.2.4
- if this is not done. Do it after set_process_environment so that we
- don't pollute Vprocess_environment. */
+ if this is not done. Do it after set_global_environment so that we
+ don't pollute Vglobal_environment. */
/* Setting LANG here will defeat the startup locale processing... */
#ifdef AIX3_2
putenv ("LANG=C");
@@ -1567,7 +1571,7 @@ main (argc, argv
#endif /* CLASH_DETECTION */
syms_of_indent ();
syms_of_insdel ();
- syms_of_keymap ();
+ /* syms_of_keymap (); */
syms_of_macros ();
syms_of_marker ();
syms_of_minibuf ();
@@ -1578,6 +1582,7 @@ main (argc, argv
syms_of_frame ();
#endif
syms_of_syntax ();
+ syms_of_terminal ();
syms_of_term ();
syms_of_undo ();
#ifdef HAVE_SOUND
@@ -1662,13 +1667,7 @@ main (argc, argv
#endif /* HAVE_NTGUI */
}
- if (!noninteractive)
- {
-#ifdef VMS
- init_vms_input ();/* init_display calls get_frame_size, that needs this. */
-#endif /* VMS */
- init_display (); /* Determine terminal type. init_sys_modes uses results. */
- }
+ init_process (); /* init_display uses add_keyboard_wait_descriptor. */
#ifndef MAC_OS8
/* Called before init_window_once for Mac OS Classic. */
init_keyboard (); /* This too must precede init_sys_modes. */
@@ -1676,7 +1675,13 @@ main (argc, argv
#ifdef VMS
init_vmsproc (); /* And this too. */
#endif /* VMS */
- init_sys_modes (); /* Init system terminal modes (RAW or CBREAK, etc.). */
+ if (!noninteractive)
+ {
+#ifdef VMS
+ init_vms_input ();/* init_display calls get_tty_size, that needs this. */
+#endif /* VMS */
+ init_display (); /* Determine terminal type. Calls init_sys_modes. */
+ }
init_fns ();
init_xdisp ();
#ifdef HAVE_WINDOW_SYSTEM
@@ -1689,7 +1694,6 @@ main (argc, argv
#ifdef VMS
init_vmsfns ();
#endif /* VMS */
- init_process ();
#ifdef HAVE_SOUND
init_sound ();
#endif
@@ -2102,15 +2106,14 @@ shut_down_emacs (sig, no_x, stuff)
if (EMACS_GET_TTY_PGRP (0, &tpgrp) != -1
&& tpgrp == pgrp)
{
- fflush (stdout);
- reset_sys_modes ();
+ reset_all_sys_modes ();
if (sig && sig != SIGTERM)
fprintf (stderr, "Fatal error (%d)", sig);
}
}
#else
fflush (stdout);
- reset_sys_modes ();
+ reset_all_sys_modes ();
#endif
stuff_buffered_input (stuff);
@@ -2132,9 +2135,9 @@ shut_down_emacs (sig, no_x, stuff)
#if 0 /* This triggers a bug in XCloseDisplay and is not needed. */
#ifdef HAVE_X_WINDOWS
/* It's not safe to call intern here. Maybe we are crashing. */
- if (!noninteractive && SYMBOLP (Vwindow_system)
- && SCHARS (SYMBOL_NAME (Vwindow_system)) == 1
- && SREF (SYMBOL_NAME (Vwindow_system), 0) == 'x'
+ if (!noninteractive && SYMBOLP (Vinitial_window_system)
+ && SCHARS (SYMBOL_NAME (Vinitial_window_system)) == 1
+ && SREF (SYMBOL_NAME (Vinitial_window_system), 0) == 'x'
&& ! no_x)
Fx_close_current_connection ();
#endif /* HAVE_X_WINDOWS */
diff --git a/src/eval.c b/src/eval.c
index 20be847f273..830476a61bc 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1280,8 +1280,12 @@ unwind_to_catch (catch, value)
#if HAVE_X_WINDOWS
/* If x_catch_errors was done, turn it off now.
(First we give unbind_to a chance to do that.) */
+#if 0 /* This would disable x_catch_errors after x_connection_closed.
+ * The catch must remain in effect during that delicate
+ * state. --lorentey */
x_fully_uncatch_errors ();
#endif
+#endif
byte_stack_list = catch->byte_stack;
gcprolist = catch->gcpro;
@@ -1458,10 +1462,12 @@ internal_condition_case (bfun, handlers, hfun)
/* Since Fsignal will close off all calls to x_catch_errors,
we will get the wrong results if some are not closed now. */
+#if 0 /* Fsignal doesn't do that anymore. --lorentey */
#if HAVE_X_WINDOWS
if (x_catching_errors ())
abort ();
#endif
+#endif
c.tag = Qnil;
c.val = Qnil;
@@ -1506,10 +1512,12 @@ internal_condition_case_1 (bfun, arg, handlers, hfun)
/* Since Fsignal will close off all calls to x_catch_errors,
we will get the wrong results if some are not closed now. */
+#if 0 /* Fsignal doesn't do that anymore. --lorentey */
#if HAVE_X_WINDOWS
if (x_catching_errors ())
abort ();
#endif
+#endif
c.tag = Qnil;
c.val = Qnil;
@@ -1557,10 +1565,12 @@ internal_condition_case_2 (bfun, nargs, args, handlers, hfun)
/* Since Fsignal will close off all calls to x_catch_errors,
we will get the wrong results if some are not closed now. */
+#if 0 /* Fsignal doesn't do that anymore. --lorentey */
#if HAVE_X_WINDOWS
if (x_catching_errors ())
abort ();
#endif
+#endif
c.tag = Qnil;
c.val = Qnil;
diff --git a/src/fileio.c b/src/fileio.c
index 62331122a24..2a0e93ebe18 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -78,6 +78,8 @@ extern int errno;
#include "coding.h"
#include "window.h"
#include "blockinput.h"
+#include "frame.h"
+#include "dispextern.h"
#ifdef WINDOWSNT
#define NOMINMAX 1
@@ -5825,7 +5827,7 @@ auto_save_error (error)
char *msgbuf;
USE_SAFE_ALLOCA;
- ring_bell ();
+ ring_bell (XFRAME (selected_frame));
args[0] = build_string ("Auto-saving %s: %s");
args[1] = current_buffer->name;
@@ -6387,7 +6389,7 @@ and `read-file-name-function'. */)
/* If dir starts with user's homedir, change that to ~. */
homedir = (char *) egetenv ("HOME");
#ifdef DOS_NT
- /* homedir can be NULL in temacs, since Vprocess_environment is not
+ /* homedir can be NULL in temacs, since Vglobal_environment is not
yet set up. We shouldn't crash in that case. */
if (homedir != 0)
{
diff --git a/src/fns.c b/src/fns.c
index eef67551b48..d37b9d2c281 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -3236,7 +3236,8 @@ is nil and `use-dialog-box' is non-nil. */)
{
#ifdef HAVE_MENUS
- if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
+ if (FRAME_WINDOW_P (SELECTED_FRAME ())
+ && (NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
&& use_dialog_box
&& have_menus_p ())
{
@@ -3275,6 +3276,7 @@ is nil and `use-dialog-box' is non-nil. */)
Fraise_frame (mini_frame);
}
+ temporarily_switch_to_single_kboard (SELECTED_FRAME ());
obj = read_filtered_event (1, 0, 0, 0, Qnil);
cursor_in_echo_area = 0;
/* If we need to quit, quit with cursor_in_echo_area = 0. */
@@ -3367,7 +3369,8 @@ is nil, and `use-dialog-box' is non-nil. */)
CHECK_STRING (prompt);
#ifdef HAVE_MENUS
- if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
+ if (FRAME_WINDOW_P (SELECTED_FRAME ())
+ && (NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
&& use_dialog_box
&& have_menus_p ())
{
diff --git a/src/fontset.c b/src/fontset.c
index 9056e2da6ec..1d6e73517b6 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -49,6 +49,7 @@ Boston, MA 02110-1301, USA. */
#ifdef MAC_OS
#include "macterm.h"
#endif
+#include "termhooks.h"
#ifdef FONTSET_DEBUG
#undef xassert
@@ -1347,7 +1348,7 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
STORE_XCHAR2B (&char2b, c1, c2);
else
STORE_XCHAR2B (&char2b, 0, c1);
- rif->encode_char (c, &char2b, fontp, NULL);
+ FRAME_RIF (f)->encode_char (c, &char2b, fontp, NULL);
code = (XCHAR2B_BYTE1 (&char2b) << 8) | XCHAR2B_BYTE2 (&char2b);
}
return Fcons (build_string (face->font_name), make_number (code));
diff --git a/src/frame.c b/src/frame.c
index b29e20ab0ca..091abfdbf31 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -42,6 +42,7 @@ Boston, MA 02110-1301, USA. */
#include "fontset.h"
#endif
#include "blockinput.h"
+#include "termchar.h"
#include "termhooks.h"
#include "dispextern.h"
#include "window.h"
@@ -74,6 +75,8 @@ Lisp_Object Qbackground_mode;
Lisp_Object Qx_frame_parameter;
Lisp_Object Qx_resource_name;
+Lisp_Object Qterminal;
+Lisp_Object Qterminal_live_p;
/* Frame parameters (set or reported). */
@@ -103,15 +106,19 @@ Lisp_Object Qtitle, Qname;
Lisp_Object Qunsplittable;
Lisp_Object Qmenu_bar_lines, Qtool_bar_lines;
Lisp_Object Qleft_fringe, Qright_fringe;
-Lisp_Object Qbuffer_predicate, Qbuffer_list;
+Lisp_Object Qbuffer_predicate, Qbuffer_list, Qburied_buffer_list;
Lisp_Object Qtty_color_mode;
+Lisp_Object Qtty, Qtty_type;
+Lisp_Object Qwindow_system;
+Lisp_Object Qenvironment;
+Lisp_Object Qterm_environment_variable;
+Lisp_Object Qdisplay_environment_variable;
Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth;
Lisp_Object Qinhibit_face_set_after_frame_default;
Lisp_Object Qface_set_after_frame_default;
-
Lisp_Object Vterminal_frame;
Lisp_Object Vdefault_frame_alist;
Lisp_Object Vdefault_frame_scroll_bars;
@@ -121,8 +128,8 @@ Lisp_Object Vdelete_frame_functions;
static void
set_menu_bar_lines_1 (window, n)
- Lisp_Object window;
- int n;
+ Lisp_Object window;
+ int n;
{
struct window *w = XWINDOW (window);
@@ -180,8 +187,6 @@ set_menu_bar_lines (f, value, oldval)
Lisp_Object Vemacs_iconified;
Lisp_Object Vframe_list;
-struct x_output tty_display;
-
extern Lisp_Object Vminibuffer_list;
extern Lisp_Object get_minibuffer ();
extern Lisp_Object Fhandle_switch_frame ();
@@ -203,6 +208,7 @@ See also `frame-live-p'. */)
return Qnil;
switch (XFRAME (object)->output_method)
{
+ case output_initial: /* The initial frame is like a termcap frame. */
case output_termcap:
return Qt;
case output_x_window:
@@ -221,7 +227,7 @@ See also `frame-live-p'. */)
DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
doc: /* Return non-nil if OBJECT is a frame which has not been deleted.
Value is nil if OBJECT is not a live frame. If object is a live
-frame, the return value indicates what sort of output device it is
+frame, the return value indicates what sort of terminal device it is
displayed on. See the documentation of `framep' for possible
return values. */)
(object)
@@ -233,6 +239,30 @@ return values. */)
: Qnil);
}
+DEFUN ("window-system", Fwindow_system, Swindow_system, 0, 1, 0,
+ doc: /* The name of the window system that FRAME is displaying through.
+The value is a symbol---for instance, 'x' for X windows.
+The value is nil if Emacs is using a text-only terminal.
+
+FRAME defaults to the currently selected frame. */)
+ (frame)
+ Lisp_Object frame;
+{
+ Lisp_Object type;
+ if (NILP (frame))
+ frame = selected_frame;
+
+ type = Fframep (frame);
+
+ if (NILP (type))
+ wrong_type_argument (Qframep, frame);
+
+ if (EQ (type, Qt))
+ return Qnil;
+ else
+ return type;
+}
+
struct frame *
make_frame (mini_p)
int mini_p;
@@ -276,9 +306,7 @@ make_frame (mini_p)
f->menu_bar_items_used = 0;
f->buffer_predicate = Qnil;
f->buffer_list = Qnil;
-#ifdef MULTI_KBOARD
- f->kboard = initial_kboard;
-#endif
+ f->buried_buffer_list = Qnil;
f->namebuf = 0;
f->title = Qnil;
f->menu_bar_window = Qnil;
@@ -398,8 +426,8 @@ make_frame_without_minibuffer (mini_window, kb, display)
#ifdef MULTI_KBOARD
if (!NILP (mini_window)
- && XFRAME (XWINDOW (mini_window)->frame)->kboard != kb)
- error ("Frame and minibuffer must be on the same display");
+ && FRAME_KBOARD (XFRAME (XWINDOW (mini_window)->frame)) != kb)
+ error ("Frame and minibuffer must be on the same terminal");
#endif
/* Make a frame containing just a root window. */
@@ -475,18 +503,19 @@ make_minibuffer_frame ()
}
#endif /* HAVE_WINDOW_SYSTEM */
-/* Construct a frame that refers to the terminal (stdin and stdout). */
+/* Construct a frame that refers to a terminal. */
-static int terminal_frame_count;
+static int tty_frame_count;
struct frame *
-make_terminal_frame ()
+make_initial_frame (void)
{
- register struct frame *f;
+ struct frame *f;
+ struct terminal *terminal;
Lisp_Object frame;
- char name[20];
#ifdef MULTI_KBOARD
+ /* Create the initial keyboard. */
if (!initial_kboard)
{
initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
@@ -500,13 +529,51 @@ make_terminal_frame ()
if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
Vframe_list = Qnil;
+ terminal = init_initial_terminal ();
+
+ f = make_frame (1);
+ XSETFRAME (frame, f);
+
+ Vframe_list = Fcons (frame, Vframe_list);
+
+ tty_frame_count = 1;
+ f->name = build_string ("F1");
+
+ f->visible = 1;
+ f->async_visible = 1;
+
+ f->output_method = terminal->type;
+ f->terminal = terminal;
+ f->terminal->reference_count++;
+ f->output_data.nothing = 0;
+
+ FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
+ FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
+
+ FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
+ FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
+
+ return f;
+}
+
+
+struct frame *
+make_terminal_frame (struct terminal *terminal)
+{
+ register struct frame *f;
+ Lisp_Object frame;
+ char name[20];
+
+ if (terminal->deleted)
+ error ("Terminal is being deleted, can't create new frames on it");
+
f = make_frame (1);
XSETFRAME (frame, f);
Vframe_list = Fcons (frame, Vframe_list);
- terminal_frame_count++;
- sprintf (name, "F%d", terminal_frame_count);
+ tty_frame_count++;
+ sprintf (name, "F%d", tty_frame_count);
f->name = build_string (name);
f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
@@ -526,11 +593,11 @@ make_terminal_frame ()
for the black color. Other frames all inherit their pixels
from what's already in the_only_x_display. */
if ((!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame)))
- && f->output_data.x->background_pixel == 0
- && f->output_data.x->foreground_pixel == 0)
+ && FRAME_BACKGROUND_PIXEL (f) == 0
+ && FRAME_FOREGROUND_PIXEL (f) == 0)
{
- f->output_data.x->background_pixel = FACE_TTY_DEFAULT_BG_COLOR;
- f->output_data.x->foreground_pixel = FACE_TTY_DEFAULT_FG_COLOR;
+ FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
+ FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
}
}
else
@@ -538,12 +605,33 @@ make_terminal_frame ()
#else
#ifdef WINDOWSNT
f->output_method = output_termcap;
- f->output_data.x = &tty_display;
+ f->terminal = terminal;
+ f->terminal->reference_count++;
+ create_w32cons_output (f);
#else
#ifdef MAC_OS8
make_mac_terminal_frame (f);
#else
- f->output_data.x = &tty_display;
+ {
+ f->output_method = output_termcap;
+ f->terminal = terminal;
+ f->terminal->reference_count++;
+ create_tty_output (f);
+
+ FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
+ FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
+
+ FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
+ FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
+
+ /* Set the top frame to the newly created frame. */
+ if (FRAME_TTY (f)->top_frame
+ && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame)))
+ XFRAME (FRAME_TTY (f)->top_frame)->async_visible = 2; /* obscured */
+
+ FRAME_TTY (f)->top_frame = frame;
+ }
+
#ifdef CANNOT_DUMP
FRAME_FOREGROUND_PIXEL(f) = FACE_TTY_DEFAULT_FG_COLOR;
FRAME_BACKGROUND_PIXEL(f) = FACE_TTY_DEFAULT_BG_COLOR;
@@ -558,18 +646,55 @@ make_terminal_frame ()
return f;
}
+/* Get a suitable value for frame parameter PARAMETER for a newly
+ created frame, based on (1) the user-supplied frame parameter
+ alist SUPPLIED_PARMS, (2) CURRENT_VALUE, and finally, if all else
+ fails, (3) Vdefault_frame_alist. */
+
+static Lisp_Object
+get_future_frame_param (Lisp_Object parameter,
+ Lisp_Object supplied_parms,
+ char *current_value)
+{
+ Lisp_Object result;
+
+ result = Fassq (parameter, supplied_parms);
+ if (NILP (result))
+ result = Fassq (parameter, XFRAME (selected_frame)->param_alist);
+ if (NILP (result) && current_value != NULL)
+ result = build_string (current_value);
+ if (NILP (result))
+ result = Fassq (parameter, Vdefault_frame_alist);
+ if (!NILP (result) && !STRINGP (result))
+ result = XCDR (result);
+ if (NILP (result) || !STRINGP (result))
+ result = Qnil;
+
+ return result;
+}
+
DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
1, 1, 0,
- doc: /* Create an additional terminal frame.
-You can create multiple frames on a text-only terminal in this way.
-Only the selected terminal frame is actually displayed.
+ doc: /* Create an additional terminal frame, possibly on another terminal.
This function takes one argument, an alist specifying frame parameters.
-In practice, generally you don't need to specify any parameters.
-Note that changing the size of one terminal frame automatically affects all. */)
+
+You can create multiple frames on a single text-only terminal, but
+only one of them (the selected terminal frame) is actually displayed.
+
+In practice, generally you don't need to specify any parameters,
+except when you want to create a new frame on another terminal.
+In that case, the `tty' parameter specifies the device file to open,
+and the `tty-type' parameter specifies the terminal type. Example:
+
+ (make-terminal-frame '((tty . "/dev/pts/5") (tty-type . "xterm")))
+
+Note that changing the size of one terminal frame automatically
+affects all frames on the same terminal device. */)
(parms)
Lisp_Object parms;
{
struct frame *f;
+ struct terminal *t = NULL;
Lisp_Object frame, tem;
struct frame *sf = SELECTED_FRAME ();
@@ -579,25 +704,84 @@ Note that changing the size of one terminal frame automatically affects all. */
abort ();
#else /* not MSDOS */
-#ifdef MAC_OS
+#if 0 /* #ifdef MAC_OS */
+ /* This can happen for multi-tty when using both terminal frames and
+ Carbon frames. */
if (sf->output_method != output_mac)
error ("Not running on a Macintosh screen; cannot make a new Macintosh frame");
#else
+#if 0 /* This should work now! */
if (sf->output_method != output_termcap)
error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
#endif
+#endif
#endif /* not MSDOS */
+
+ {
+ Lisp_Object terminal;
+
+ terminal = Fassq (Qterminal, parms);
+ if (!NILP (terminal))
+ {
+ terminal = XCDR (terminal);
+ t = get_terminal (terminal, 1);
+ }
+ }
+
+ if (!t)
+ {
+ char *name = 0, *type = 0;
+ Lisp_Object tty, tty_type;
+
+ tty = get_future_frame_param
+ (Qtty, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
+ ? FRAME_TTY (XFRAME (selected_frame))->name
+ : NULL));
+ if (!NILP (tty))
+ {
+ name = (char *) alloca (SBYTES (tty) + 1);
+ strncpy (name, SDATA (tty), SBYTES (tty));
+ name[SBYTES (tty)] = 0;
+ }
+
+ tty_type = get_future_frame_param
+ (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
+ ? FRAME_TTY (XFRAME (selected_frame))->type
+ : NULL));
+ if (!NILP (tty_type))
+ {
+ type = (char *) alloca (SBYTES (tty_type) + 1);
+ strncpy (type, SDATA (tty_type), SBYTES (tty_type));
+ type[SBYTES (tty_type)] = 0;
+ }
+
+ t = init_tty (name, type, 0); /* Errors are not fatal. */
+ }
- f = make_terminal_frame ();
+ f = make_terminal_frame (t);
- change_frame_size (f, FRAME_LINES (sf),
- FRAME_COLS (sf), 0, 0, 0);
+ {
+ int width, height;
+ get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
+ change_frame_size (f, height, width, 0, 0, 0);
+ }
+
adjust_glyphs (f);
calculate_costs (f);
XSETFRAME (frame, f);
Fmodify_frame_parameters (frame, Vdefault_frame_alist);
Fmodify_frame_parameters (frame, parms);
-
+ Fmodify_frame_parameters (frame, Fcons (Fcons (Qwindow_system, Qnil), Qnil));
+ Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty_type,
+ build_string (t->display_info.tty->type)),
+ Qnil));
+ if (t->display_info.tty->name != NULL)
+ Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty,
+ build_string (t->display_info.tty->name)),
+ Qnil));
+ else
+ Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty, Qnil), Qnil));
+
/* Make the frame face alist be frame-specific, so that each
frame could change its face definitions independently. */
f->face_alist = Fcopy_alist (sf->face_alist);
@@ -620,7 +804,7 @@ Note that changing the size of one terminal frame automatically affects all. */
frame's focus to FRAME instead.
FOR_DELETION non-zero means that the selected frame is being
- deleted, which includes the possibility that the frame's display
+ deleted, which includes the possibility that the frame's terminal
is dead. */
Lisp_Object
@@ -695,6 +879,15 @@ do_switch_frame (frame, track, for_deletion)
if (!for_deletion && FRAME_HAS_MINIBUF_P (sf))
resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1);
+ if (FRAME_TERMCAP_P (XFRAME (selected_frame))
+ && FRAME_TERMCAP_P (XFRAME (frame))
+ && FRAME_TTY (XFRAME (selected_frame)) == FRAME_TTY (XFRAME (frame)))
+ {
+ XFRAME (selected_frame)->async_visible = 2; /* obscured */
+ XFRAME (frame)->async_visible = 1;
+ FRAME_TTY (XFRAME (frame))->top_frame = frame;
+ }
+
selected_frame = frame;
if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
last_nonminibuf_frame = XFRAME (selected_frame);
@@ -878,6 +1071,7 @@ If FRAME is the selected frame, this makes WINDOW the selected window. */)
return XFRAME (frame)->selected_window = window;
}
+
DEFUN ("frame-list", Fframe_list, Sframe_list,
0, 0, 0,
@@ -925,7 +1119,10 @@ next_frame (frame, minibuf)
f = XCAR (tail);
if (passed
- && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
+ && ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
+ && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
+ || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame))
+ && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame)))))
{
/* Decide whether this frame is eligible to be returned. */
@@ -1002,7 +1199,10 @@ prev_frame (frame, minibuf)
if (EQ (frame, f) && !NILP (prev))
return prev;
- if (FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
+ if ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
+ && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
+ || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame))
+ && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame))))
{
/* Decide whether this frame is eligible to be returned,
according to minibuf. */
@@ -1136,6 +1336,14 @@ other_visible_frames (f)
return 1;
}
+/* Error handler for `delete-frame-functions'. */
+static Lisp_Object
+delete_frame_handler (Lisp_Object arg)
+{
+ add_to_log ("Error during `delete-frame': %s", arg, Qnil);
+ return Qnil;
+}
+
DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
doc: /* Delete FRAME, permanently eliminating it from use.
If omitted, FRAME defaults to the selected frame.
@@ -1151,6 +1359,8 @@ The functions are run with one arg, the frame to be deleted. */)
{
struct frame *f;
struct frame *sf = SELECTED_FRAME ();
+ struct kboard *kb;
+
int minibuffer_selected;
if (EQ (frame, Qnil))
@@ -1209,11 +1419,22 @@ The functions are run with one arg, the frame to be deleted. */)
&& NILP (Fframe_parameter (frame, intern ("tooltip"))))
{
Lisp_Object args[2];
+ struct gcpro gcpro1, gcpro2;
+
+ /* Don't let a rogue function in `delete-frame-functions'
+ prevent the frame deletion. */
+ GCPRO2 (args[0], args[1]);
args[0] = intern ("delete-frame-functions");
args[1] = frame;
- Frun_hook_with_args (2, args);
+ internal_condition_case_2 (Frun_hook_with_args, 2, args,
+ Qt, delete_frame_handler);
+ UNGCPRO;
}
+ /* The hook may sometimes (indirectly) cause the frame to be deleted. */
+ if (! FRAME_LIVE_P (f))
+ return Qnil;
+
minibuffer_selected = EQ (minibuf_window, selected_window);
/* Don't let the frame remain selected. */
@@ -1229,7 +1450,7 @@ The functions are run with one arg, the frame to be deleted. */)
{
FOR_EACH_FRAME (tail, frame1)
{
- if (! EQ (frame, frame1))
+ if (! EQ (frame, frame1) && FRAME_LIVE_P (XFRAME (frame1)))
break;
}
}
@@ -1255,6 +1476,24 @@ The functions are run with one arg, the frame to be deleted. */)
if (EQ (f->minibuffer_window, echo_area_window))
echo_area_window = sf->minibuffer_window;
+ /* Don't allow other frames to refer to a deleted frame in their
+ 'environment parameter. */
+ {
+ Lisp_Object tail, frame1;
+ Lisp_Object env = get_frame_param (XFRAME (frame), Qenvironment);
+ FOR_EACH_FRAME (tail, frame1)
+ {
+ if (EQ (frame, frame1) || !FRAME_LIVE_P (XFRAME (frame1)))
+ continue;
+ if (EQ (frame, get_frame_param (XFRAME (frame1), Qenvironment)))
+ {
+ store_frame_param (XFRAME (frame1), Qenvironment, env);
+ if (!FRAMEP (env))
+ env = frame1;
+ }
+ }
+ }
+
/* Clear any X selections for this frame. */
#ifdef HAVE_X_WINDOWS
if (FRAME_X_P (f))
@@ -1295,18 +1534,36 @@ The functions are run with one arg, the frame to be deleted. */)
xfree (FRAME_MESSAGE_BUF (f));
/* Since some events are handled at the interrupt level, we may get
- an event for f at any time; if we zero out the frame's display
+ an event for f at any time; if we zero out the frame's terminal
now, then we may trip up the event-handling code. Instead, we'll
- promise that the display of the frame must be valid until we have
- called the window-system-dependent frame destruction routine. */
+ promise that the terminal of the frame must be valid until we
+ have called the window-system-dependent frame destruction
+ routine. */
- /* I think this should be done with a hook. */
-#ifdef HAVE_WINDOW_SYSTEM
- if (FRAME_WINDOW_P (f))
- x_destroy_window (f);
-#endif
+ if (FRAME_TERMINAL (f)->delete_frame_hook)
+ (*FRAME_TERMINAL (f)->delete_frame_hook) (f);
- f->output_data.nothing = 0;
+ {
+ struct terminal *terminal = FRAME_TERMINAL (f);
+ f->output_data.nothing = 0;
+ f->terminal = 0; /* Now the frame is dead. */
+
+ /* If needed, delete the terminal that this frame was on.
+ (This must be done after the frame is killed.) */
+ terminal->reference_count--;
+ if (terminal->reference_count == 0)
+ {
+ kb = NULL;
+ if (terminal->delete_terminal_hook)
+ (*terminal->delete_terminal_hook) (terminal);
+ else
+ delete_terminal (terminal);
+ }
+#ifdef MULTI_KBOARD
+ else
+ kb = terminal->kboard;
+#endif
+ }
/* If we've deleted the last_nonminibuf_frame, then try to find
another one. */
@@ -1331,38 +1588,39 @@ The functions are run with one arg, the frame to be deleted. */)
/* If there's no other frame on the same kboard, get out of
single-kboard state if we're in it for this kboard. */
- {
- Lisp_Object frames;
- /* Some frame we found on the same kboard, or nil if there are none. */
- Lisp_Object frame_on_same_kboard;
+ if (kb != NULL)
+ {
+ Lisp_Object frames;
+ /* Some frame we found on the same kboard, or nil if there are none. */
+ Lisp_Object frame_on_same_kboard;
- frame_on_same_kboard = Qnil;
+ frame_on_same_kboard = Qnil;
- for (frames = Vframe_list;
- CONSP (frames);
- frames = XCDR (frames))
- {
- Lisp_Object this;
- struct frame *f1;
+ for (frames = Vframe_list;
+ CONSP (frames);
+ frames = XCDR (frames))
+ {
+ Lisp_Object this;
+ struct frame *f1;
- this = XCAR (frames);
- if (!FRAMEP (this))
- abort ();
- f1 = XFRAME (this);
+ this = XCAR (frames);
+ if (!FRAMEP (this))
+ abort ();
+ f1 = XFRAME (this);
- if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
- frame_on_same_kboard = this;
- }
+ if (kb == FRAME_KBOARD (f1))
+ frame_on_same_kboard = this;
+ }
- if (NILP (frame_on_same_kboard))
- not_single_kboard_state (FRAME_KBOARD (f));
- }
+ if (NILP (frame_on_same_kboard))
+ not_single_kboard_state (kb);
+ }
/* If we've deleted this keyboard's default_minibuffer_frame, try to
find another one. Prefer minibuffer-only frames, but also notice
frames with other windows. */
- if (EQ (frame, FRAME_KBOARD (f)->Vdefault_minibuffer_frame))
+ if (kb != NULL && EQ (frame, kb->Vdefault_minibuffer_frame))
{
Lisp_Object frames;
@@ -1388,7 +1646,7 @@ The functions are run with one arg, the frame to be deleted. */)
/* Consider only frames on the same kboard
and only those with minibuffers. */
- if (FRAME_KBOARD (f) == FRAME_KBOARD (f1)
+ if (kb == FRAME_KBOARD (f1)
&& FRAME_HAS_MINIBUF_P (f1))
{
frame_with_minibuf = this;
@@ -1396,7 +1654,7 @@ The functions are run with one arg, the frame to be deleted. */)
break;
}
- if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
+ if (kb == FRAME_KBOARD (f1))
frame_on_same_kboard = this;
}
@@ -1411,11 +1669,11 @@ The functions are run with one arg, the frame to be deleted. */)
if (NILP (frame_with_minibuf))
abort ();
- FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf;
+ kb->Vdefault_minibuffer_frame = frame_with_minibuf;
}
else
/* No frames left on this kboard--say no minibuffer either. */
- FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil;
+ kb->Vdefault_minibuffer_frame = Qnil;
}
/* Cause frame titles to update--necessary if we now have just one frame. */
@@ -1452,11 +1710,11 @@ and returns whatever that function returns. */)
#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
/* It's okay for the hook to refrain from storing anything. */
- if (mouse_position_hook)
- (*mouse_position_hook) (&f, -1,
- &lispy_dummy, &party_dummy,
- &x, &y,
- &long_dummy);
+ if (FRAME_TERMINAL (f)->mouse_position_hook)
+ (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
+ &lispy_dummy, &party_dummy,
+ &x, &y,
+ &long_dummy);
if (! NILP (x))
{
col = XINT (x);
@@ -1496,11 +1754,11 @@ and nil for X and Y. */)
#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
/* It's okay for the hook to refrain from storing anything. */
- if (mouse_position_hook)
- (*mouse_position_hook) (&f, -1,
- &lispy_dummy, &party_dummy,
- &x, &y,
- &long_dummy);
+ if (FRAME_TERMINAL (f)->mouse_position_hook)
+ (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
+ &lispy_dummy, &party_dummy,
+ &x, &y,
+ &long_dummy);
#endif
XSETFRAME (lispy_dummy, f);
return Fcons (lispy_dummy, Fcons (x, y));
@@ -1787,16 +2045,19 @@ doesn't support multiple overlapping frames, this function does nothing. */)
(frame)
Lisp_Object frame;
{
+ struct frame *f;
if (NILP (frame))
frame = selected_frame;
CHECK_LIVE_FRAME (frame);
+ f = XFRAME (frame);
+
/* Do like the documentation says. */
Fmake_frame_visible (frame);
- if (frame_raise_lower_hook)
- (*frame_raise_lower_hook) (XFRAME (frame), 1);
+ if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
+ (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 1);
return Qnil;
}
@@ -1810,13 +2071,17 @@ doesn't support multiple overlapping frames, this function does nothing. */)
(frame)
Lisp_Object frame;
{
+ struct frame *f;
+
if (NILP (frame))
frame = selected_frame;
CHECK_LIVE_FRAME (frame);
- if (frame_raise_lower_hook)
- (*frame_raise_lower_hook) (XFRAME (frame), 0);
+ f = XFRAME (frame);
+
+ if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
+ (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 0);
return Qnil;
}
@@ -1850,6 +2115,8 @@ The redirection lasts until `redirect-frame-focus' is called to change it. */)
(frame, focus_frame)
Lisp_Object frame, focus_frame;
{
+ struct frame *f;
+
/* Note that we don't check for a live frame here. It's reasonable
to redirect the focus of a frame you're about to delete, if you
know what other frame should receive those keystrokes. */
@@ -1858,10 +2125,12 @@ The redirection lasts until `redirect-frame-focus' is called to change it. */)
if (! NILP (focus_frame))
CHECK_LIVE_FRAME (focus_frame);
- XFRAME (frame)->focus_frame = focus_frame;
+ f = XFRAME (frame);
+
+ f->focus_frame = focus_frame;
- if (frame_rehighlight_hook)
- (*frame_rehighlight_hook) (XFRAME (frame));
+ if (FRAME_TERMINAL (f)->frame_rehighlight_hook)
+ (*FRAME_TERMINAL (f)->frame_rehighlight_hook) (f);
return Qnil;
}
@@ -1923,7 +2192,7 @@ set_frame_buffer_list (frame, list)
XFRAME (frame)->buffer_list = list;
}
-/* Discard BUFFER from the buffer-list of each frame. */
+/* Discard BUFFER from the buffer-list and buried-buffer-list of each frame. */
void
frames_discard_buffer (buffer)
@@ -1935,6 +2204,8 @@ frames_discard_buffer (buffer)
{
XFRAME (frame)->buffer_list
= Fdelq (buffer, XFRAME (frame)->buffer_list);
+ XFRAME (frame)->buried_buffer_list
+ = Fdelq (buffer, XFRAME (frame)->buried_buffer_list);
}
}
@@ -1993,8 +2264,8 @@ set_term_frame_name (f, name)
SBYTES (f->name)))
return;
- terminal_frame_count++;
- sprintf (namebuf, "F%d", terminal_frame_count);
+ tty_frame_count++;
+ sprintf (namebuf, "F%d", tty_frame_count);
name = build_string (namebuf);
}
else
@@ -2022,13 +2293,18 @@ store_frame_param (f, prop, val)
{
register Lisp_Object old_alist_elt;
- /* The buffer-alist parameter is stored in a special place and is
- not in the alist. */
+ /* The buffer-list parameters are stored in a special place and not
+ in the alist. */
if (EQ (prop, Qbuffer_list))
{
f->buffer_list = val;
return;
}
+ if (EQ (prop, Qburied_buffer_list))
+ {
+ f->buried_buffer_list = val;
+ return;
+ }
/* If PROP is a symbol which is supposed to have frame-local values,
and it is set up based on this frame, switch to the global
@@ -2041,6 +2317,7 @@ store_frame_param (f, prop, val)
if ((BUFFER_LOCAL_VALUEP (valcontents)
|| SOME_BUFFER_LOCAL_VALUEP (valcontents))
&& XBUFFER_LOCAL_VALUE (valcontents)->check_frame
+ && XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame
&& XFRAME (XBUFFER_LOCAL_VALUE (valcontents)->frame) == f)
swap_in_global_binding (prop);
}
@@ -2168,6 +2445,7 @@ If FRAME is omitted, return information on the currently selected frame. */)
: FRAME_MINIBUF_WINDOW (f)));
store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
store_in_alist (&alist, Qbuffer_list, frame_buffer_list (frame));
+ store_in_alist (&alist, Qburied_buffer_list, XFRAME (frame)->buried_buffer_list);
/* I think this should be done with a hook. */
#ifdef HAVE_WINDOW_SYSTEM
@@ -2335,9 +2613,44 @@ enabled such bindings for that variable with `make-variable-frame-local'. */)
call1 (Qframe_set_background_mode, frame);
}
}
+}
- return Qnil;
+DEFUN ("frame-with-environment", Fframe_with_environment, Sframe_with_environment, 0, 1, 0,
+ doc: /* Return the frame that has the environment variable list for FRAME.
+
+The frame-local environment variable list is normally shared between
+frames that were created in the same Emacsclient session. The
+environment list is stored in a single frame's 'environment parameter;
+the other frames' 'environment parameter is set to this frame. This
+function follows the chain of 'environment references to reach the
+frame that stores the actual local environment list, and returns that
+frame. */)
+ (frame)
+ Lisp_Object frame;
+{
+ Lisp_Object hare, tortoise;
+
+ if (NILP (frame))
+ frame = selected_frame;
+ CHECK_FRAME (frame);
+
+ hare = tortoise = get_frame_param (XFRAME (frame), Qenvironment);
+ while (!NILP (hare) && FRAMEP (hare))
+ {
+ frame = hare;
+ hare = get_frame_param (XFRAME (hare), Qenvironment);
+ if (NILP (hare) || !FRAMEP (hare))
+ break;
+ frame = hare;
+ hare = get_frame_param (XFRAME (hare), Qenvironment);
+ tortoise = get_frame_param (XFRAME (tortoise), Qenvironment);
+ if (EQ (hare, tortoise))
+ error ("Cyclic frame-local environment indirection");
+ }
+
+ return frame;
}
+
DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
0, 1, 0,
@@ -2754,9 +3067,8 @@ x_set_frame_parameters (f, alist)
if (NATNUMP (param_index)
&& (XFASTINT (param_index)
< sizeof (frame_parms)/sizeof (frame_parms[0]))
- && rif->frame_parm_handlers[XINT (param_index)])
- (*(rif->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
-
+ && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])
+ (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
unbind_to (count, Qnil);
}
}
@@ -2800,8 +3112,8 @@ x_set_frame_parameters (f, alist)
if (NATNUMP (param_index)
&& (XFASTINT (param_index)
< sizeof (frame_parms)/sizeof (frame_parms[0]))
- && rif->frame_parm_handlers[XINT (param_index)])
- (*(rif->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
+ && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])
+ (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
}
}
@@ -3039,8 +3351,8 @@ x_set_fullscreen (f, new_value, old_value)
else if (EQ (new_value, Qfullheight))
f->want_fullscreen = FULLSCREEN_HEIGHT;
- if (fullscreen_hook != NULL)
- fullscreen_hook (f);
+ if (FRAME_TERMINAL (f)->fullscreen_hook != NULL)
+ FRAME_TERMINAL (f)->fullscreen_hook (f);
}
@@ -3089,9 +3401,9 @@ x_set_screen_gamma (f, new_value, old_value)
if (NATNUMP (index)
&& (XFASTINT (index)
< sizeof (frame_parms)/sizeof (frame_parms[0]))
- && rif->frame_parm_handlers[XFASTINT (index)])
- (*(rif->frame_parm_handlers[XFASTINT (index)]))
- (f, bgcolor, Qnil);
+ && FRAME_RIF (f)->frame_parm_handlers[XFASTINT (index)])
+ (*FRAME_RIF (f)->frame_parm_handlers[XFASTINT (index)])
+ (f, bgcolor, Qnil);
}
Fclear_face_cache (Qnil);
@@ -4027,12 +4339,27 @@ syms_of_frame ()
staticpro (&Qbuffer_predicate);
Qbuffer_list = intern ("buffer-list");
staticpro (&Qbuffer_list);
+ Qburied_buffer_list = intern ("buried-buffer-list");
+ staticpro (&Qburied_buffer_list);
Qdisplay_type = intern ("display-type");
staticpro (&Qdisplay_type);
Qbackground_mode = intern ("background-mode");
staticpro (&Qbackground_mode);
Qtty_color_mode = intern ("tty-color-mode");
staticpro (&Qtty_color_mode);
+ Qtty = intern ("tty");
+ staticpro (&Qtty);
+ Qtty_type = intern ("tty-type");
+ staticpro (&Qtty_type);
+ Qwindow_system = intern ("window-system");
+ staticpro (&Qwindow_system);
+ Qenvironment = intern ("environment");
+ staticpro (&Qenvironment);
+
+ Qterm_environment_variable = intern ("term-environment-variable");
+ staticpro (&Qterm_environment_variable);
+ Qdisplay_environment_variable = intern ("display-environment-variable");
+ staticpro (&Qdisplay_environment_variable);
Qface_set_after_frame_default = intern ("face-set-after-frame-default");
staticpro (&Qface_set_after_frame_default);
@@ -4053,6 +4380,11 @@ syms_of_frame ()
Qx_frame_parameter = intern ("x-frame-parameter");
staticpro (&Qx_frame_parameter);
+ Qterminal = intern ("terminal");
+ staticpro (&Qterminal);
+ Qterminal_live_p = intern ("terminal-live-p");
+ staticpro (&Qterminal_live_p);
+
{
int i;
@@ -4101,6 +4433,7 @@ These may be set in your init file, like this:
These override values given in window system configuration data,
including X Windows' defaults database.
For values specific to the first Emacs frame, see `initial-frame-alist'.
+For window-system specific values, see `window-system-default-frame-alist'.
For values specific to the separate minibuffer frame, see
`minibuffer-frame-alist'.
The `menu-bar-lines' element of the list controls whether new frames
@@ -4122,7 +4455,7 @@ Setting this variable does not affect existing frames, only new ones. */);
#endif
DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
- doc: /* The initial frame-object, which represents Emacs's stdout. */);
+ doc: /* The initial frame-object, which represents Emacs's stdout. */);
DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
doc: /* Non-nil if all of Emacs is iconified and frame updates are not needed. */);
@@ -4147,7 +4480,14 @@ when the mouse is over clickable text. */);
DEFVAR_LISP ("delete-frame-functions", &Vdelete_frame_functions,
doc: /* Functions to be run before deleting a frame.
The functions are run with one arg, the frame to be deleted.
-See `delete-frame'. */);
+See `delete-frame'.
+
+Note that functions in this list may be called twice on the same
+frame. In the second invocation, the frame is already deleted, and
+the function should do nothing. (You can use `frame-live-p' to check
+for this.) This wrinkle happens when an earlier function in
+`delete-frame-functions' (indirectly) calls delete-frame
+recursively. */);
Vdelete_frame_functions = Qnil;
DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
@@ -4170,6 +4510,7 @@ This variable is local to the current terminal and cannot be buffer-local. */);
defsubr (&Sactive_minibuffer_window);
defsubr (&Sframep);
defsubr (&Sframe_live_p);
+ defsubr (&Swindow_system);
defsubr (&Smake_terminal_frame);
defsubr (&Shandle_switch_frame);
defsubr (&Sselect_frame);
@@ -4203,6 +4544,7 @@ This variable is local to the current terminal and cannot be buffer-local. */);
defsubr (&Sframe_parameters);
defsubr (&Sframe_parameter);
defsubr (&Smodify_frame_parameters);
+ defsubr (&Sframe_with_environment);
defsubr (&Sframe_char_height);
defsubr (&Sframe_char_width);
defsubr (&Sframe_pixel_height);
diff --git a/src/frame.h b/src/frame.h
index d5e9f21ed10..9c00e319a57 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -29,9 +29,7 @@ Boston, MA 02110-1301, USA. */
/* Miscellanea. */
-/* Nonzero means don't assume anything about current contents of
- actual terminal frame */
-
+/* Nonzero means there is at least one garbaged frame. */
extern int frame_garbaged;
/* Nonzero means FRAME_MESSAGE_BUF (selected_frame) is being used by
@@ -44,6 +42,7 @@ extern int message_buf_print;
enum output_method
{
+ output_initial,
output_termcap,
output_x_window,
output_msdos_raw,
@@ -68,30 +67,10 @@ enum text_cursor_kinds
HBAR_CURSOR
};
-#if !defined(MSDOS) && !defined(WINDOWSNT) && !defined(MAC_OS)
-
-#if !defined(HAVE_X_WINDOWS)
-
-#define PIX_TYPE unsigned long
-
-/* A (mostly empty) x_output structure definition for building Emacs
- on Unix and GNU/Linux without X support. */
-struct x_output
-{
- PIX_TYPE background_pixel;
- PIX_TYPE foreground_pixel;
-};
-
-#endif /* ! HAVE_X_WINDOWS */
-
+#define FRAME_FOREGROUND_PIXEL(f) ((f)->foreground_pixel)
+#define FRAME_BACKGROUND_PIXEL(f) ((f)->background_pixel)
-#define FRAME_FOREGROUND_PIXEL(f) ((f)->output_data.x->foreground_pixel)
-#define FRAME_BACKGROUND_PIXEL(f) ((f)->output_data.x->background_pixel)
-
-/* A structure describing a termcap frame display. */
-extern struct x_output tty_display;
-
-#endif /* ! MSDOS && ! WINDOWSNT && ! MAC_OS */
+struct terminal;
struct frame
{
@@ -153,7 +132,7 @@ struct frame
Actually, we don't specify exactly what is stored here at all; the
scroll bar implementation code can use it to store anything it likes.
This field is marked by the garbage collector. It is here
- instead of in the `display' structure so that the garbage
+ instead of in the `device' structure so that the garbage
collector doesn't need to look inside the window-system-dependent
structure. */
Lisp_Object scroll_bars;
@@ -182,6 +161,10 @@ struct frame
/* List of buffers viewed in this frame, for other-buffer. */
Lisp_Object buffer_list;
+ /* List of buffers that were viewed, then buried in this frame. The
+ most recently buried buffer is first. For last-buffer. */
+ Lisp_Object buried_buffer_list;
+
/* A dummy window used to display menu bars under X when no X
toolkit support is available. */
Lisp_Object menu_bar_window;
@@ -283,20 +266,24 @@ struct frame
/* Canonical Y unit. Height of a line, in pixels. */
int line_height;
- /* The output method says how the contents of this frame
- are displayed. It could be using termcap, or using an X window. */
+ /* The output method says how the contents of this frame are
+ displayed. It could be using termcap, or using an X window.
+ This must be the same as the terminal->type. */
enum output_method output_method;
- /* A structure of auxiliary data used for displaying the contents.
- struct x_output is used for X window frames;
- it is defined in xterm.h.
- struct w32_output is used for W32 window frames;
- it is defined in w32term.h. */
+ /* The terminal device that this frame uses. If this is NULL, then
+ the frame has been deleted. */
+ struct terminal *terminal;
+
+ /* Device-dependent, frame-local auxiliary data used for displaying
+ the contents. When the frame is deleted, this data is deleted as
+ well. */
union output_data
{
- struct x_output *x;
- struct w32_output *w32;
- struct mac_output *mac;
+ struct tty_output *tty; /* termchar.h */
+ struct x_output *x; /* xterm.h */
+ struct w32_output *w32; /* w32term.h */
+ struct mac_output *mac; /* macterm.h */
EMACS_INT nothing;
}
output_data;
@@ -311,13 +298,6 @@ struct frame
/* The extra width (in pixels) currently allotted for fringes. */
int left_fringe_width, right_fringe_width;
-#ifdef MULTI_KBOARD
- /* A pointer to the kboard structure associated with this frame.
- For termcap frames, this points to initial_kboard. For X frames,
- it will be the same as display.x->display_info->kboard. */
- struct kboard *kboard;
-#endif
-
/* See FULLSCREEN_ enum below */
int want_fullscreen;
@@ -341,13 +321,13 @@ struct frame
frame becomes visible again, it must be marked as garbaged. The
FRAME_SAMPLE_VISIBILITY macro takes care of this.
- On Windows NT/9X, to avoid wasting effort updating visible frames
- that are actually completely obscured by other windows on the
- display, we bend the meaning of visible slightly: if greater than
- 1, then the frame is obscured - we still consider it to be
- "visible" as seen from lisp, but we don't bother updating it. We
- must take care to garbage the frame when it ceaces to be obscured
- though. Note that these semantics are only used on NT/9X.
+ On ttys and on Windows NT/9X, to avoid wasting effort updating
+ visible frames that are actually completely obscured by other
+ windows on the display, we bend the meaning of visible slightly:
+ if greater than 1, then the frame is obscured - we still consider
+ it to be "visible" as seen from lisp, but we don't bother
+ updating it. We must take care to garbage the frame when it
+ ceaces to be obscured though.
iconified is nonzero if the frame is currently iconified.
@@ -441,7 +421,7 @@ struct frame
/* The baud rate that was used to calculate costs for this frame. */
int cost_calculation_baud_rate;
- /* Nonzero if the mouse has moved on this display
+ /* Nonzero if the mouse has moved on this display device
since the last time we checked. */
char mouse_moved;
@@ -460,7 +440,11 @@ struct frame
/* Set to non-zero in when we want for force a flush_display in
update_frame, usually after resizing the frame. */
unsigned force_flush_display_p : 1;
-
+
+ /* All display backends seem to need these two pixel values. */
+ unsigned long background_pixel;
+ unsigned long foreground_pixel;
+
/* Set to non-zero if the default face for the frame has been
realized. Reset to zero whenever the default face changes.
Used to see the difference between a font change and face change. */
@@ -479,7 +463,7 @@ struct frame
};
#ifdef MULTI_KBOARD
-#define FRAME_KBOARD(f) ((f)->kboard)
+#define FRAME_KBOARD(f) ((f)->terminal->kboard)
#else
#define FRAME_KBOARD(f) (&the_only_kboard)
#endif
@@ -493,6 +477,7 @@ typedef struct frame *FRAME_PTR;
#define WINDOW_FRAME(w) (w)->frame
/* Test a frame for particular kinds of display methods. */
+#define FRAME_INITIAL_P(f) ((f)->output_method == output_initial)
#define FRAME_TERMCAP_P(f) ((f)->output_method == output_termcap)
#define FRAME_X_P(f) ((f)->output_method == output_x_window)
#define FRAME_W32_P(f) ((f)->output_method == output_w32)
@@ -516,7 +501,7 @@ typedef struct frame *FRAME_PTR;
#endif
/* Nonzero if frame F is still alive (not deleted). */
-#define FRAME_LIVE_P(f) ((f)->output_data.nothing != 0)
+#define FRAME_LIVE_P(f) ((f)->terminal != 0)
/* Nonzero if frame F is a minibuffer-only frame. */
#define FRAME_MINIBUF_ONLY_P(f) \
@@ -756,7 +741,10 @@ typedef struct frame *FRAME_PTR;
Also, if a frame used to be invisible, but has just become visible,
it must be marked as garbaged, since redisplay hasn't been keeping
- up its contents. */
+ up its contents.
+
+ Note that a tty frame is visible if and only if it is the topmost
+ frame. */
#define FRAME_SAMPLE_VISIBILITY(f) \
(((f)->async_visible && (f)->visible != (f)->async_visible) ? \
@@ -789,10 +777,16 @@ typedef struct frame *FRAME_PTR;
extern Lisp_Object Qframep, Qframe_live_p;
+extern Lisp_Object Qtty, Qtty_type;
+extern Lisp_Object Qterminal, Qterminal_live_p;
+extern Lisp_Object Qenvironment;
+extern Lisp_Object Qterm_environment_variable;
+extern Lisp_Object Qdisplay_environment_variable;
extern struct frame *last_nonminibuf_frame;
-extern struct frame *make_terminal_frame P_ ((void));
+extern struct frame *make_initial_frame P_ ((void));
+extern struct frame *make_terminal_frame P_ ((struct terminal *));
extern struct frame *make_frame P_ ((int));
#ifdef HAVE_WINDOW_SYSTEM
extern struct frame *make_minibuffer_frame P_ ((void));
@@ -992,7 +986,7 @@ extern Lisp_Object selected_frame;
extern Lisp_Object Qauto_raise, Qauto_lower;
extern Lisp_Object Qborder_color, Qborder_width;
-extern Lisp_Object Qbuffer_predicate, Qbuffer_list;
+extern Lisp_Object Qbuffer_predicate, Qbuffer_list, Qburied_buffer_list;
extern Lisp_Object Qcursor_color, Qcursor_type;
extern Lisp_Object Qfont;
extern Lisp_Object Qbackground_color, Qforeground_color;
@@ -1024,6 +1018,8 @@ extern Lisp_Object Qx_resource_name;
extern Lisp_Object Qleft, Qright, Qtop, Qbox;
extern Lisp_Object Qdisplay;
+extern Lisp_Object Qwindow_system;
+
#ifdef HAVE_WINDOW_SYSTEM
/* The class of this X application. */
diff --git a/src/fringe.c b/src/fringe.c
index 3241786a115..a39e729cfde 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -29,6 +29,7 @@ Boston, MA 02110-1301, USA. */
#include "dispextern.h"
#include "buffer.h"
#include "blockinput.h"
+#include "termhooks.h"
#ifdef HAVE_WINDOW_SYSTEM
@@ -686,7 +687,7 @@ draw_fringe_bitmap_1 (w, row, left_p, overlay, which)
break;
}
- rif->draw_fringe_bitmap (w, row, &p);
+ FRAME_RIF (f)->draw_fringe_bitmap (w, row, &p);
}
static int
@@ -1278,6 +1279,8 @@ destroy_fringe_bitmap (n)
fbp = &fringe_bitmaps[n];
if (*fbp && (*fbp)->dynamic)
{
+ /* XXX Is SELECTED_FRAME OK here? */
+ struct redisplay_interface *rif = FRAME_RIF (SELECTED_FRAME ());
if (rif && rif->destroy_fringe_bitmap)
rif->destroy_fringe_bitmap (n);
xfree (*fbp);
@@ -1383,6 +1386,9 @@ init_fringe_bitmap (which, fb, once_p)
if (!once_p)
{
+ /* XXX Is SELECTED_FRAME OK here? */
+ struct redisplay_interface *rif = FRAME_RIF (SELECTED_FRAME ());
+
destroy_fringe_bitmap (which);
if (rif && rif->define_fringe_bitmap)
@@ -1699,6 +1705,7 @@ mac_init_fringe ()
#endif
{
int bt;
+ struct redisplay_interface *rif = FRAME_RIF (SELECTED_FRAME ());
if (!rif)
return;
@@ -1717,6 +1724,7 @@ w32_reset_fringes ()
{
/* Destroy row bitmaps. */
int bt;
+ struct redisplay_interface *rif = FRAME_RIF (SELECTED_FRAME ());
if (!rif)
return;
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 9fb011de919..2af1e03cc28 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -874,7 +874,7 @@ xg_create_frame_widgets (f)
/* Since GTK clears its window by filling with the background color,
we must keep X and GTK background in sync. */
- xg_pix_to_gcolor (wfixed, f->output_data.x->background_pixel, &bg);
+ xg_pix_to_gcolor (wfixed, FRAME_BACKGROUND_PIXEL (f), &bg);
gtk_widget_modify_bg (wfixed, GTK_STATE_NORMAL, &bg);
/* Also, do not let any background pixmap to be set, this looks very
@@ -2043,7 +2043,7 @@ xg_create_one_menuitem (item, f, select_cb, highlight_cb, cl_data, group)
return w;
}
-/* Callback called when keyboard traversal (started by menu-bar-open) ends.
+/* Callback called when keyboard traversal (started by x-menu-bar-open) ends.
WMENU is the menu for which traversal has been done. DATA points to the
frame for WMENU. We must release grabs, some bad interaction between GTK
and Emacs makes the menus keep the grabs. */
diff --git a/src/image.c b/src/image.c
index 54c01cf36b3..db50d94d4c1 100644
--- a/src/image.c
+++ b/src/image.c
@@ -1905,6 +1905,7 @@ lookup_image (f, spec)
struct frame *f;
Lisp_Object spec;
{
+ struct image_cache *c;
struct image *img;
unsigned hash;
struct gcpro gcpro1;
@@ -1915,6 +1916,8 @@ lookup_image (f, spec)
xassert (FRAME_WINDOW_P (f));
xassert (valid_image_p (spec));
+ c = FRAME_X_IMAGE_CACHE (f);
+
GCPRO1 (spec);
/* Look up SPEC in the hash table of the image cache. */
diff --git a/src/indent.c b/src/indent.c
index b3c1d0cf81a..88856814279 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -20,6 +20,8 @@ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
#include <config.h>
+#include <stdio.h>
+
#include "lisp.h"
#include "buffer.h"
#include "charset.h"
diff --git a/src/keyboard.c b/src/keyboard.c
index adbbbcf85dd..95a4aecfe39 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -23,13 +23,13 @@ Boston, MA 02110-1301, USA. */
#include <config.h>
#include <signal.h>
#include <stdio.h>
+#include "lisp.h"
#include "termchar.h"
#include "termopts.h"
-#include "lisp.h"
+#include "frame.h"
#include "termhooks.h"
#include "macros.h"
#include "keyboard.h"
-#include "frame.h"
#include "window.h"
#include "commands.h"
#include "buffer.h"
@@ -59,7 +59,6 @@ Boston, MA 02110-1301, USA. */
#endif /* not MSDOS */
#include "syssignal.h"
-#include "systty.h"
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
@@ -97,9 +96,6 @@ volatile int interrupt_input_blocked;
int interrupt_input_pending;
-/* File descriptor to use for input. */
-extern int input_fd;
-
#ifdef HAVE_WINDOW_SYSTEM
/* Make all keyboard buffers much bigger when using X windows. */
#ifdef MAC_OS8
@@ -425,16 +421,6 @@ Lisp_Object Vecho_keystrokes;
/* Form to evaluate (if non-nil) when Emacs is started. */
Lisp_Object Vtop_level;
-/* User-supplied table to translate input characters. */
-Lisp_Object Vkeyboard_translate_table;
-
-/* Keymap mapping ASCII function key sequences onto their preferred forms. */
-extern Lisp_Object Vfunction_key_map;
-
-/* Another keymap that maps key sequences into key sequences.
- This one takes precedence over ordinary definitions. */
-extern Lisp_Object Vkey_translation_map;
-
/* If non-nil, this implements the current input method. */
Lisp_Object Vinput_method_function;
Lisp_Object Qinput_method_function;
@@ -458,6 +444,12 @@ Lisp_Object Qpre_command_hook, Vpre_command_hook;
Lisp_Object Qpost_command_hook, Vpost_command_hook;
Lisp_Object Qcommand_hook_internal, Vcommand_hook_internal;
+/* Parent keymap of terminal-local function-key-map instances. */
+Lisp_Object Vfunction_key_map;
+
+/* Parent keymap of terminal-local key-translation-map instances. */
+Lisp_Object Vkey_translation_map;
+
/* List of deferred actions to be performed at a later time.
The precise format isn't relevant here; we just check whether it is nil. */
Lisp_Object Vdeferred_action_list;
@@ -475,11 +467,6 @@ FILE *dribble;
/* Nonzero if input is available. */
int input_pending;
-/* 1 if should obey 0200 bit in input chars as "Meta", 2 if should
- keep 0200 bit in input chars. 0 to ignore the 0200 bit. */
-
-int meta_key;
-
extern char *pending_malloc_warning;
/* Circular buffer for pre-read keyboard input. */
@@ -609,9 +596,6 @@ int interrupt_input;
/* Nonzero while interrupts are temporarily deferred during redisplay. */
int interrupts_deferred;
-/* Nonzero means use ^S/^Q for flow control. */
-int flow_control;
-
/* Allow m- file to inhibit use of FIONREAD. */
#ifdef BROKEN_FIONREAD
#undef FIONREAD
@@ -694,8 +678,11 @@ static void save_getcjmp ();
static void restore_getcjmp P_ ((jmp_buf));
static Lisp_Object apply_modifiers P_ ((int, Lisp_Object));
static void clear_event P_ ((struct input_event *));
-static void any_kboard_state P_ ((void));
+#ifdef MULTI_KBOARD
+static Lisp_Object restore_kboard_configuration P_ ((Lisp_Object));
+#endif
static SIGTYPE interrupt_signal P_ ((int signalnum));
+static void handle_interrupt P_ ((void));
static void timer_start_idle P_ ((void));
static void timer_stop_idle P_ ((void));
static void timer_resume_idle P_ ((void));
@@ -1061,24 +1048,20 @@ This function is called by the editor initialization to begin editing. */)
like it is done in the splash screen display, we have to
make sure that we restore single_kboard as command_loop_1
would have done if it were left normally. */
- record_unwind_protect (recursive_edit_unwind,
- Fcons (buffer, single_kboard ? Qt : Qnil));
+ if (command_loop_level > 0)
+ temporarily_switch_to_single_kboard (SELECTED_FRAME ());
+ record_unwind_protect (recursive_edit_unwind, buffer);
recursive_edit_1 ();
return unbind_to (count, Qnil);
}
Lisp_Object
-recursive_edit_unwind (info)
- Lisp_Object info;
+recursive_edit_unwind (buffer)
+ Lisp_Object buffer;
{
- if (BUFFERP (XCAR (info)))
- Fset_buffer (XCAR (info));
-
- if (NILP (XCDR (info)))
- any_kboard_state ();
- else
- single_kboard_state ();
+ if (BUFFERP (buffer))
+ Fset_buffer (buffer);
command_loop_level--;
update_mode_lines = 1;
@@ -1086,6 +1069,8 @@ recursive_edit_unwind (info)
}
+#if 0 /* These two functions are now replaced with
+ temporarily_switch_to_single_kboard. */
static void
any_kboard_state ()
{
@@ -1116,6 +1101,7 @@ single_kboard_state ()
single_kboard = 1;
#endif
}
+#endif
/* If we're in single_kboard state for kboard KBOARD,
get out of it. */
@@ -1143,8 +1129,8 @@ struct kboard_stack
static struct kboard_stack *kboard_stack;
void
-push_frame_kboard (f)
- FRAME_PTR f;
+push_kboard (k)
+ struct kboard *k;
{
#ifdef MULTI_KBOARD
struct kboard_stack *p
@@ -1154,20 +1140,110 @@ push_frame_kboard (f)
p->kboard = current_kboard;
kboard_stack = p;
- current_kboard = FRAME_KBOARD (f);
+ current_kboard = k;
#endif
}
void
-pop_frame_kboard ()
+pop_kboard ()
{
#ifdef MULTI_KBOARD
+ struct terminal *t;
struct kboard_stack *p = kboard_stack;
- current_kboard = p->kboard;
+ int found = 0;
+ for (t = terminal_list; t; t = t->next_terminal)
+ {
+ if (t->kboard == p->kboard)
+ {
+ current_kboard = p->kboard;
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ {
+ /* The terminal we remembered has been deleted. */
+ current_kboard = FRAME_KBOARD (SELECTED_FRAME ());
+ single_kboard = 0;
+ }
kboard_stack = p->next;
xfree (p);
#endif
}
+
+/* Switch to single_kboard mode, making current_kboard the only KBOARD
+ from which further input is accepted. If F is non-nil, set its
+ KBOARD as the current keyboard.
+
+ This function uses record_unwind_protect to return to the previous
+ state later.
+
+ If Emacs is already in single_kboard mode, and F's keyboard is
+ locked, then this function will throw an errow. */
+
+void
+temporarily_switch_to_single_kboard (f)
+ struct frame *f;
+{
+#ifdef MULTI_KBOARD
+ int was_locked = single_kboard;
+ if (was_locked)
+ {
+ if (f != NULL && FRAME_KBOARD (f) != current_kboard)
+ /* We can not switch keyboards while in single_kboard mode.
+ In rare cases, Lisp code may call `recursive-edit' (or
+ `read-minibuffer' or `y-or-n-p') after it switched to a
+ locked frame. For example, this is likely to happen
+ when server.el connects to a new terminal while Emacs is in
+ single_kboard mode. It is best to throw an error instead
+ of presenting the user with a frozen screen. */
+ error ("Terminal %d is locked, cannot read from it",
+ FRAME_TERMINAL (f)->id);
+ else
+ /* This call is unnecessary, but helps
+ `restore_kboard_configuration' discover if somebody changed
+ `current_kboard' behind our back. */
+ push_kboard (current_kboard);
+ }
+ else if (f != NULL)
+ current_kboard = FRAME_KBOARD (f);
+ single_kboard = 1;
+ record_unwind_protect (restore_kboard_configuration,
+ (was_locked ? Qt : Qnil));
+#endif
+}
+
+#if 0 /* This function is not needed anymore. */
+void
+record_single_kboard_state ()
+{
+ if (single_kboard)
+ push_kboard (current_kboard);
+ record_unwind_protect (restore_kboard_configuration,
+ (single_kboard ? Qt : Qnil));
+}
+#endif
+
+#ifdef MULTI_KBOARD
+static Lisp_Object
+restore_kboard_configuration (was_locked)
+ Lisp_Object was_locked;
+{
+ if (NILP (was_locked))
+ single_kboard = 0;
+ else
+ {
+ struct kboard *prev = current_kboard;
+ single_kboard = 1;
+ pop_kboard ();
+ /* The pop should not change the kboard. */
+ if (single_kboard && current_kboard != prev)
+ abort ();
+ }
+ return Qnil;
+}
+#endif
+
/* Handle errors that are not handled at inner levels
by printing an error message and returning to the editor command loop. */
@@ -1215,10 +1291,12 @@ cmd_error (data)
Vquit_flag = Qnil;
Vinhibit_quit = Qnil;
+#if 0 /* This shouldn't be necessary anymore. --lorentey */
#ifdef MULTI_KBOARD
if (command_loop_level == 0 && minibuf_level == 0)
any_kboard_state ();
#endif
+#endif
return make_number (0);
}
@@ -1254,11 +1332,7 @@ cmd_error_internal (data, context)
/* If the window system or terminal frame hasn't been initialized
yet, or we're not interactive, write the message to stderr and exit. */
else if (!sf->glyphs_initialized_p
- /* This is the case of the frame dumped with Emacs, when we're
- running under a window system. */
- || (!NILP (Vwindow_system)
- && !inhibit_window_system
- && FRAME_TERMCAP_P (sf))
+ || FRAME_INITIAL_P (sf)
|| noninteractive)
{
print_error_message (data, Qexternal_debugging_output,
@@ -1301,10 +1375,12 @@ command_loop ()
while (1)
{
internal_catch (Qtop_level, top_level_1, Qnil);
- /* Reset single_kboard in case top-level set it while
- evaluating an -f option, or we are stuck there for some
- other reason. */
- any_kboard_state ();
+#if 0 /* This shouldn't be necessary anymore. --lorentey */
+ /* Reset single_kboard in case top-level set it while
+ evaluating an -f option, or we are stuck there for some
+ other reason. */
+ any_kboard_state ();
+#endif
internal_catch (Qtop_level, command_loop_2, Qnil);
executing_kbd_macro = Qnil;
@@ -1499,10 +1575,12 @@ command_loop_1 ()
int no_direct;
int prev_modiff = 0;
struct buffer *prev_buffer = NULL;
+#if 0 /* This shouldn't be necessary anymore. --lorentey */
#ifdef MULTI_KBOARD
int was_locked = single_kboard;
#endif
- int already_adjusted;
+#endif
+ int already_adjusted = 0;
current_kboard->Vprefix_arg = Qnil;
current_kboard->Vlast_prefix_arg = Qnil;
@@ -1961,10 +2039,11 @@ command_loop_1 ()
if (!NILP (current_kboard->defining_kbd_macro)
&& NILP (current_kboard->Vprefix_arg))
finalize_kbd_macro_chars ();
-
+#if 0 /* This shouldn't be necessary anymore. --lorentey */
#ifdef MULTI_KBOARD
if (!was_locked)
- any_kboard_state ();
+ any_kboard_state ();
+#endif
#endif
}
}
@@ -2203,7 +2282,10 @@ void
start_polling ()
{
#ifdef POLL_FOR_INPUT
- if (read_socket_hook && !interrupt_input)
+ /* XXX This condition was (read_socket_hook && !interrupt_input),
+ but read_socket_hook is not global anymore. Let's pretend that
+ it's always set. */
+ if (!interrupt_input)
{
/* Turn alarm handling on unconditionally. It might have
been turned off in process.c. */
@@ -2237,7 +2319,10 @@ int
input_polling_used ()
{
#ifdef POLL_FOR_INPUT
- return read_socket_hook && !interrupt_input;
+ /* XXX This condition was (read_socket_hook && !interrupt_input),
+ but read_socket_hook is not global anymore. Let's pretend that
+ it's always set. */
+ return !interrupt_input;
#else
return 0;
#endif
@@ -2249,7 +2334,10 @@ void
stop_polling ()
{
#ifdef POLL_FOR_INPUT
- if (read_socket_hook && !interrupt_input)
+ /* XXX This condition was (read_socket_hook && !interrupt_input),
+ but read_socket_hook is not global anymore. Let's pretend that
+ it's always set. */
+ if (!interrupt_input)
++poll_suppress_count;
#endif
}
@@ -2461,10 +2549,6 @@ read_char_help_form_unwind (arg)
return Qnil;
}
-#ifdef MULTI_KBOARD
-static jmp_buf wrong_kboard_jmpbuf;
-#endif
-
#define STOP_POLLING \
do { if (! polling_stopped_here) stop_polling (); \
polling_stopped_here = 1; } while (0)
@@ -2491,6 +2575,9 @@ do { if (polling_stopped_here) start_polling (); \
if we used a mouse menu to read the input, or zero otherwise. If
USED_MOUSE_MENU is null, we don't dereference it.
+ Value is -2 when we find input on another keyboard. A second call
+ to read_char will read it.
+
If END_TIME is non-null, it is a pointer to an EMACS_TIME
specifying the maximum time to wait until. If no input arrives by
that time, stop waiting and return nil.
@@ -2517,6 +2604,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu, end_time)
volatile int reread;
struct gcpro gcpro1, gcpro2;
int polling_stopped_here = 0;
+ struct kboard *orig_kboard = current_kboard;
also_record = Qnil;
@@ -2731,6 +2819,10 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu, end_time)
&& !detect_input_pending_run_timers (0))
{
c = read_char_minibuf_menu_prompt (commandflag, nmaps, maps);
+
+ if (INTEGERP (c) && XINT (c) == -2)
+ return c; /* wrong_kboard_jmpbuf */
+
if (! NILP (c))
{
key_already_recorded = 1;
@@ -2747,6 +2839,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu, end_time)
jmpcount = SPECPDL_INDEX ();
if (_setjmp (local_getcjmp))
{
+ /* Handle quits while reading the keyboard. */
/* We must have saved the outer value of getcjmp here,
so restore it now. */
restore_getcjmp (save_jump);
@@ -2784,7 +2877,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu, end_time)
/* This is going to exit from read_char
so we had better get rid of this frame's stuff. */
UNGCPRO;
- longjmp (wrong_kboard_jmpbuf, 1);
+ return make_number (-2); /* wrong_kboard_jmpbuf */
}
}
#endif
@@ -2921,6 +3014,19 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu, end_time)
}
}
+ /* Notify the caller if an autosave hook, or a timer, sentinel or
+ filter in the sit_for calls above have changed the current
+ kboard. This could happen if they use the minibuffer or start a
+ recursive edit, like the fancy splash screen in server.el's
+ filter. If this longjmp wasn't here, read_key_sequence would
+ interpret the next key sequence using the wrong translation
+ tables and function keymaps. */
+ if (NILP (c) && current_kboard != orig_kboard)
+ {
+ UNGCPRO;
+ return make_number (-2); /* wrong_kboard_jmpbuf */
+ }
+
/* If this has become non-nil here, it has been set by a timer
or sentinel or filter. */
if (CONSP (Vunread_command_events))
@@ -2969,7 +3075,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu, end_time)
/* This is going to exit from read_char
so we had better get rid of this frame's stuff. */
UNGCPRO;
- longjmp (wrong_kboard_jmpbuf, 1);
+ return make_number (-2); /* wrong_kboard_jmpbuf */
}
}
#endif
@@ -3025,7 +3131,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu, end_time)
/* This is going to exit from read_char
so we had better get rid of this frame's stuff. */
UNGCPRO;
- longjmp (wrong_kboard_jmpbuf, 1);
+ return make_number (-2);
}
#endif
}
@@ -3080,8 +3186,12 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu, end_time)
if (!NILP (tem))
{
+#if 0 /* This shouldn't be necessary anymore. --lorentey */
int was_locked = single_kboard;
-
+ int count = SPECPDL_INDEX ();
+ record_single_kboard_state ();
+#endif
+
last_input_char = c;
Fcommand_execute (tem, Qnil, Fvector (1, &last_input_char), Qt);
@@ -3092,9 +3202,12 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu, end_time)
example banishing the mouse under mouse-avoidance-mode. */
timer_resume_idle ();
+#if 0 /* This shouldn't be necessary anymore. --lorentey */
/* Resume allowing input from any kboard, if that was true before. */
if (!was_locked)
any_kboard_state ();
+ unbind_to (count, Qnil);
+#endif
goto retry;
}
@@ -3106,15 +3219,15 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu, end_time)
if (XINT (c) == -1)
goto exit;
- if ((STRINGP (Vkeyboard_translate_table)
- && SCHARS (Vkeyboard_translate_table) > (unsigned) XFASTINT (c))
- || (VECTORP (Vkeyboard_translate_table)
- && XVECTOR (Vkeyboard_translate_table)->size > (unsigned) XFASTINT (c))
- || (CHAR_TABLE_P (Vkeyboard_translate_table)
+ if ((STRINGP (current_kboard->Vkeyboard_translate_table)
+ && SCHARS (current_kboard->Vkeyboard_translate_table) > (unsigned) XFASTINT (c))
+ || (VECTORP (current_kboard->Vkeyboard_translate_table)
+ && XVECTOR (current_kboard->Vkeyboard_translate_table)->size > (unsigned) XFASTINT (c))
+ || (CHAR_TABLE_P (current_kboard->Vkeyboard_translate_table)
&& CHAR_VALID_P (XINT (c), 0)))
{
Lisp_Object d;
- d = Faref (Vkeyboard_translate_table, c);
+ d = Faref (current_kboard->Vkeyboard_translate_table, c);
/* nil in keyboard-translate-table means no translation. */
if (!NILP (d))
c = d;
@@ -3734,12 +3847,10 @@ kbd_buffer_store_event_hold (event, hold_quit)
if (c == quit_char)
{
#ifdef MULTI_KBOARD
- KBOARD *kb;
+ KBOARD *kb = FRAME_KBOARD (XFRAME (event->frame_or_window));
struct input_event *sp;
- if (single_kboard
- && (kb = FRAME_KBOARD (XFRAME (event->frame_or_window)),
- kb != current_kboard))
+ if (single_kboard && kb != current_kboard)
{
kb->kbd_queue
= Fcons (make_lispy_switch_frame (event->frame_or_window),
@@ -3782,7 +3893,7 @@ kbd_buffer_store_event_hold (event, hold_quit)
}
last_event_timestamp = event->timestamp;
- interrupt_signal (0 /* dummy */);
+ handle_interrupt ();
return;
}
@@ -4264,11 +4375,15 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
unsigned long time;
*kbp = current_kboard;
- /* Note that this uses F to determine which display to look at.
+ /* Note that this uses F to determine which terminal to look at.
If there is no valid info, it does not store anything
so x remains nil. */
x = Qnil;
- (*mouse_position_hook) (&f, 0, &bar_window, &part, &x, &y, &time);
+
+ /* XXX Can f or mouse_position_hook be NULL here? */
+ if (f && FRAME_TERMINAL (f)->mouse_position_hook)
+ (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, 0, &bar_window,
+ &part, &x, &y, &time);
obj = Qnil;
@@ -4565,10 +4680,14 @@ timer_check (do_it_now)
{
if (NILP (vector[0]))
{
- int was_locked = single_kboard;
int count = SPECPDL_INDEX ();
Lisp_Object old_deactivate_mark = Vdeactivate_mark;
+#if 0 /* This shouldn't be necessary anymore. --lorentey */
+ /* On unbind_to, resume allowing input from any kboard, if that
+ was true before. */
+ record_single_kboard_state ();
+#endif
/* Mark the timer as triggered to prevent problems if the lisp
code fails to reschedule it right. */
vector[0] = Qt;
@@ -4580,10 +4699,6 @@ timer_check (do_it_now)
timers_run++;
unbind_to (count, Qnil);
- /* Resume allowing input from any kboard, if that was true before. */
- if (!was_locked)
- any_kboard_state ();
-
/* Since we have handled the event,
we don't need to tell the caller to wake up and do it. */
}
@@ -6544,8 +6659,8 @@ modify_event_symbol (symbol_num, modifiers, symbol_kind, name_alist_or_stem,
{
int len = SBYTES (name_alist_or_stem);
char *buf = (char *) alloca (len + 50);
- sprintf (buf, "%s-%ld", SDATA (name_alist_or_stem),
- (long) XINT (symbol_int) + 1);
+ sprintf (buf, "%s-%ld", SDATA (name_alist_or_stem),
+ (long) XINT (symbol_int) + 1);
value = intern (buf);
}
else if (name_table != 0 && name_table[symbol_num])
@@ -6810,7 +6925,10 @@ gobble_input (expected)
}
else
#ifdef POLL_FOR_INPUT
- if (read_socket_hook && !interrupt_input && poll_suppress_count == 0)
+ /* XXX This condition was (read_socket_hook && !interrupt_input),
+ but read_socket_hook is not global anymore. Let's pretend that
+ it's always set. */
+ if (!interrupt_input && poll_suppress_count == 0)
{
SIGMASKTYPE mask;
mask = sigblock (sigmask (SIGALRM));
@@ -6887,170 +7005,241 @@ static int
read_avail_input (expected)
int expected;
{
- register int i;
int nread = 0;
+ int err = 0;
+ struct terminal *t;
/* Store pending user signal events, if any. */
if (store_user_signal_events ())
expected = 0;
- if (read_socket_hook)
+ /* Loop through the available terminals, and call their input hooks. */
+ t = terminal_list;
+ while (t)
{
- int nr;
- struct input_event hold_quit;
+ struct terminal *next = t->next_terminal;
- EVENT_INIT (hold_quit);
- hold_quit.kind = NO_EVENT;
+ if (t->read_socket_hook)
+ {
+ int nr;
+ struct input_event hold_quit;
+
+ EVENT_INIT (hold_quit);
+ hold_quit.kind = NO_EVENT;
+
+ /* No need for FIONREAD or fcntl; just say don't wait. */
+ while (nr = (*t->read_socket_hook) (t, expected, &hold_quit), nr > 0)
+ {
+ nread += nr;
+ expected = 0;
+ }
+
+ if (nr == -1) /* Not OK to read input now. */
+ {
+ err = 1;
+ }
+ else if (nr == -2) /* Non-transient error. */
+ {
+ /* The terminal device terminated; it should be closed. */
+
+ /* Kill Emacs if this was our last terminal. */
+ if (!terminal_list->next_terminal)
+ /* Formerly simply reported no input, but that
+ sometimes led to a failure of Emacs to terminate.
+ SIGHUP seems appropriate if we can't reach the
+ terminal. */
+ /* ??? Is it really right to send the signal just to
+ this process rather than to the whole process
+ group? Perhaps on systems with FIONREAD Emacs is
+ alone in its group. */
+ kill (getpid (), SIGHUP);
+
+ /* XXX Is calling delete_terminal safe here? It calls Fdelete_frame. */
+ if (t->delete_terminal_hook)
+ (*t->delete_terminal_hook) (t);
+ else
+ delete_terminal (t);
+ }
+
+ if (hold_quit.kind != NO_EVENT)
+ kbd_buffer_store_event (&hold_quit);
+ }
- /* No need for FIONREAD or fcntl; just say don't wait. */
- while (nr = (*read_socket_hook) (input_fd, expected, &hold_quit), nr > 0)
- {
- nread += nr;
- expected = 0;
- }
- if (hold_quit.kind != NO_EVENT)
- kbd_buffer_store_event (&hold_quit);
+ t = next;
}
- else
- {
- /* Using KBD_BUFFER_SIZE - 1 here avoids reading more than
- the kbd_buffer can really hold. That may prevent loss
- of characters on some systems when input is stuffed at us. */
- unsigned char cbuf[KBD_BUFFER_SIZE - 1];
- int n_to_read;
- /* Determine how many characters we should *try* to read. */
+ if (err && !nread)
+ nread = -1;
+
+ return nread;
+}
+
+/* This is the tty way of reading available input.
+
+ Note that each terminal device has its own `struct terminal' object,
+ and so this function is called once for each individual termcap
+ terminal. The first parameter indicates which terminal to read from. */
+
+int
+tty_read_avail_input (struct terminal *terminal,
+ int expected,
+ struct input_event *hold_quit)
+{
+ /* Using KBD_BUFFER_SIZE - 1 here avoids reading more than
+ the kbd_buffer can really hold. That may prevent loss
+ of characters on some systems when input is stuffed at us. */
+ unsigned char cbuf[KBD_BUFFER_SIZE - 1];
+ int n_to_read, i;
+ struct tty_display_info *tty = terminal->display_info.tty;
+ int nread = 0;
+
+ if (terminal->deleted) /* Don't read from a deleted terminal. */
+ return;
+
+ if (terminal->type != output_termcap)
+ abort ();
+
+ /* XXX I think the following code should be moved to separate hook
+ functions in system-dependent files. */
#ifdef WINDOWSNT
- return 0;
+ return 0;
#else /* not WINDOWSNT */
#ifdef MSDOS
- n_to_read = dos_keysns ();
- if (n_to_read == 0)
- return 0;
+ n_to_read = dos_keysns ();
+ if (n_to_read == 0)
+ return 0;
+
+ cbuf[0] = dos_keyread ();
+ nread = 1;
+
#else /* not MSDOS */
+
+ if (! tty->term_initted) /* In case we get called during bootstrap. */
+ return 0;
+
+ if (! tty->input)
+ return 0; /* The terminal is suspended. */
+
#ifdef HAVE_GPM
- if (term_gpm)
- {
- Gpm_Event event;
- struct input_event hold_quit;
- int gpm;
+ if (term_gpm && gpm_tty == tty->terminal->id)
+ {
+ Gpm_Event event;
+ struct input_event hold_quit;
+ int gpm;
- EVENT_INIT (hold_quit);
- hold_quit.kind = NO_EVENT;
+ EVENT_INIT (hold_quit);
+ hold_quit.kind = NO_EVENT;
- while (gpm = Gpm_GetEvent (&event), gpm == 1) {
- nread += handle_one_term_event (&event, &hold_quit);
- }
- if (hold_quit.kind != NO_EVENT)
- kbd_buffer_store_event (&hold_quit);
- if (nread)
- return nread;
- }
+ while (gpm = Gpm_GetEvent (&event), gpm == 1) {
+ nread += handle_one_term_event (tty, &event, &hold_quit);
+ }
+ if (hold_quit.kind != NO_EVENT)
+ kbd_buffer_store_event (&hold_quit);
+ if (nread)
+ return nread;
+ }
#endif /* HAVE_GPM */
-#ifdef FIONREAD
- /* Find out how much input is available. */
- if (ioctl (input_fd, FIONREAD, &n_to_read) < 0)
- /* Formerly simply reported no input, but that sometimes led to
- a failure of Emacs to terminate.
- SIGHUP seems appropriate if we can't reach the terminal. */
- /* ??? Is it really right to send the signal just to this process
- rather than to the whole process group?
- Perhaps on systems with FIONREAD Emacs is alone in its group. */
- {
- if (! noninteractive)
- kill (getpid (), SIGHUP);
- else
- n_to_read = 0;
- }
- if (n_to_read == 0)
- return 0;
- if (n_to_read > sizeof cbuf)
- n_to_read = sizeof cbuf;
+/* Determine how many characters we should *try* to read. */
+#ifdef FIONREAD
+ /* Find out how much input is available. */
+ if (ioctl (fileno (tty->input), FIONREAD, &n_to_read) < 0)
+ {
+ if (! noninteractive)
+ return -2; /* Close this terminal. */
+ else
+ n_to_read = 0;
+ }
+ if (n_to_read == 0)
+ return 0;
+ if (n_to_read > sizeof cbuf)
+ n_to_read = sizeof cbuf;
#else /* no FIONREAD */
#if defined (USG) || defined (DGUX) || defined(CYGWIN)
- /* Read some input if available, but don't wait. */
- n_to_read = sizeof cbuf;
- fcntl (input_fd, F_SETFL, O_NDELAY);
+ /* Read some input if available, but don't wait. */
+ n_to_read = sizeof cbuf;
+ fcntl (fileno (tty->input), F_SETFL, O_NDELAY);
#else
- you lose;
+ you lose;
#endif
#endif
-#endif /* not MSDOS */
-#endif /* not WINDOWSNT */
- /* Now read; for one reason or another, this will not block.
- NREAD is set to the number of chars read. */
- do
- {
-#ifdef MSDOS
- cbuf[0] = dos_keyread ();
- nread = 1;
-#else
- nread = emacs_read (input_fd, cbuf, n_to_read);
-#endif
- /* POSIX infers that processes which are not in the session leader's
- process group won't get SIGHUP's at logout time. BSDI adheres to
- this part standard and returns -1 from read (0) with errno==EIO
- when the control tty is taken away.
- Jeffrey Honig <jch@bsdi.com> says this is generally safe. */
- if (nread == -1 && errno == EIO)
- kill (0, SIGHUP);
+ /* Now read; for one reason or another, this will not block.
+ NREAD is set to the number of chars read. */
+ do
+ {
+ nread = emacs_read (fileno (tty->input), cbuf, n_to_read);
+ /* POSIX infers that processes which are not in the session leader's
+ process group won't get SIGHUP's at logout time. BSDI adheres to
+ this part standard and returns -1 from read (0) with errno==EIO
+ when the control tty is taken away.
+ Jeffrey Honig <jch@bsdi.com> says this is generally safe. */
+ if (nread == -1 && errno == EIO)
+ return -2; /* Close this terminal. */
#if defined (AIX) && (! defined (aix386) && defined (_BSD))
- /* The kernel sometimes fails to deliver SIGHUP for ptys.
- This looks incorrect, but it isn't, because _BSD causes
- O_NDELAY to be defined in fcntl.h as O_NONBLOCK,
- and that causes a value other than 0 when there is no input. */
- if (nread == 0)
- kill (0, SIGHUP);
-#endif
- }
- while (
- /* We used to retry the read if it was interrupted.
- But this does the wrong thing when O_NDELAY causes
- an EAGAIN error. Does anybody know of a situation
- where a retry is actually needed? */
+ /* The kernel sometimes fails to deliver SIGHUP for ptys.
+ This looks incorrect, but it isn't, because _BSD causes
+ O_NDELAY to be defined in fcntl.h as O_NONBLOCK,
+ and that causes a value other than 0 when there is no input. */
+ if (nread == 0)
+ return -2; /* Close this terminal. */
+#endif
+ }
+ while (
+ /* We used to retry the read if it was interrupted.
+ But this does the wrong thing when O_NDELAY causes
+ an EAGAIN error. Does anybody know of a situation
+ where a retry is actually needed? */
#if 0
- nread < 0 && (errno == EAGAIN
+ nread < 0 && (errno == EAGAIN
#ifdef EFAULT
- || errno == EFAULT
+ || errno == EFAULT
#endif
#ifdef EBADSLT
- || errno == EBADSLT
+ || errno == EBADSLT
#endif
- )
+ )
#else
- 0
+ 0
#endif
- );
+ );
#ifndef FIONREAD
#if defined (USG) || defined (DGUX) || defined (CYGWIN)
- fcntl (input_fd, F_SETFL, 0);
+ fcntl (fileno (tty->input), F_SETFL, 0);
#endif /* USG or DGUX or CYGWIN */
#endif /* no FIONREAD */
- for (i = 0; i < nread; i++)
- {
- struct input_event buf;
- EVENT_INIT (buf);
- buf.kind = ASCII_KEYSTROKE_EVENT;
- buf.modifiers = 0;
- if (meta_key == 1 && (cbuf[i] & 0x80))
- buf.modifiers = meta_modifier;
- if (meta_key != 2)
- cbuf[i] &= ~0x80;
-
- buf.code = cbuf[i];
- buf.frame_or_window = selected_frame;
- buf.arg = Qnil;
-
- kbd_buffer_store_event (&buf);
- /* Don't look at input that follows a C-g too closely.
- This reduces lossage due to autorepeat on C-g. */
- if (buf.kind == ASCII_KEYSTROKE_EVENT
- && buf.code == quit_char)
- break;
- }
+
+ if (nread <= 0)
+ return nread;
+
+#endif /* not MSDOS */
+#endif /* not WINDOWSNT */
+
+ for (i = 0; i < nread; i++)
+ {
+ struct input_event buf;
+ EVENT_INIT (buf);
+ buf.kind = ASCII_KEYSTROKE_EVENT;
+ buf.modifiers = 0;
+ if (tty->meta_key == 1 && (cbuf[i] & 0x80))
+ buf.modifiers = meta_modifier;
+ if (tty->meta_key != 2)
+ cbuf[i] &= ~0x80;
+
+ buf.code = cbuf[i];
+ /* Set the frame corresponding to the active tty. Note that the
+ value of selected_frame is not reliable here, redisplay tends
+ to temporarily change it. */
+ buf.frame_or_window = tty->top_frame;
+ buf.arg = Qnil;
+
+ kbd_buffer_store_event (&buf);
+ /* Don't look at input that follows a C-g too closely.
+ This reduces lossage due to autorepeat on C-g. */
+ if (buf.kind == ASCII_KEYSTROKE_EVENT
+ && buf.code == quit_char)
+ break;
}
return nread;
@@ -8632,6 +8821,8 @@ read_char_minibuf_menu_prompt (commandflag, nmaps, maps)
if (!INTEGERP (obj))
return obj;
+ else if (XINT (obj) == -2)
+ return obj;
else
ch = XINT (obj);
@@ -8978,11 +9169,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
last_nonmenu_event = Qnil;
delayed_switch_frame = Qnil;
- fkey.map = fkey.parent = Vfunction_key_map;
- keytran.map = keytran.parent = Vkey_translation_map;
- fkey.start = fkey.end = 0;
- keytran.start = keytran.end = 0;
-
+
if (INTERACTIVE)
{
if (!NILP (prompt))
@@ -9022,6 +9209,13 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
keybuf[0..mock_input] holds the sequence we should reread. */
replay_sequence:
+ /* We may switch keyboards between rescans, so we need to
+ reinitialize fkey and keytran before each replay. */
+ fkey.map = fkey.parent = current_kboard->Vlocal_function_key_map;
+ keytran.map = keytran.parent = current_kboard->Vlocal_key_translation_map;
+ fkey.start = fkey.end = 0;
+ keytran.start = keytran.end = 0;
+
starting_buffer = current_buffer;
first_unbound = bufsize + 1;
@@ -9186,8 +9380,28 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
#ifdef MULTI_KBOARD
KBOARD *interrupted_kboard = current_kboard;
struct frame *interrupted_frame = SELECTED_FRAME ();
- if (setjmp (wrong_kboard_jmpbuf))
+#endif
+ key = read_char (NILP (prompt), nmaps,
+ (Lisp_Object *) submaps, last_nonmenu_event,
+ &used_mouse_menu, NULL);
+#ifdef MULTI_KBOARD
+ if (INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */
{
+ int found = 0;
+ struct kboard *k;
+
+ for (k = all_kboards; k; k = k->next_kboard)
+ if (k == interrupted_kboard)
+ found = 1;
+
+ if (!found)
+ {
+ /* Don't touch interrupted_kboard when it's been
+ deleted. */
+ delayed_switch_frame = Qnil;
+ goto replay_sequence;
+ }
+
if (!NILP (delayed_switch_frame))
{
interrupted_kboard->kbd_queue
@@ -9195,6 +9409,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
interrupted_kboard->kbd_queue);
delayed_switch_frame = Qnil;
}
+
while (t > 0)
interrupted_kboard->kbd_queue
= Fcons (keybuf[--t], interrupted_kboard->kbd_queue);
@@ -9219,9 +9434,6 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
goto replay_sequence;
}
#endif
- key = read_char (NILP (prompt), nmaps,
- (Lisp_Object *) submaps, last_nonmenu_event,
- &used_mouse_menu, NULL);
}
/* read_char returns t when it shows a menu and the user rejects it.
@@ -10333,8 +10545,12 @@ detect_input_pending_run_timers (do_display)
from an idle timer function. The symptom of the bug is that
the cursor sometimes doesn't become visible until the next X
event is processed. --gerd. */
- if (rif)
- rif->flush_display (NULL);
+ {
+ Lisp_Object tail, frame;
+ FOR_EACH_FRAME (tail, frame)
+ if (FRAME_RIF (XFRAME (frame)))
+ FRAME_RIF (XFRAME (frame))->flush_display (XFRAME (frame));
+ }
}
return input_pending;
@@ -10586,6 +10802,9 @@ On such systems, Emacs starts a subshell instead of suspending. */)
int width, height;
struct gcpro gcpro1;
+ if (tty_list && tty_list->next)
+ error ("There are other tty frames open; close them before suspending Emacs");
+
if (!NILP (stuffstring))
CHECK_STRING (stuffstring);
@@ -10594,11 +10813,11 @@ On such systems, Emacs starts a subshell instead of suspending. */)
call1 (Vrun_hooks, intern ("suspend-hook"));
GCPRO1 (stuffstring);
- get_frame_size (&old_width, &old_height);
- reset_sys_modes ();
+ get_tty_size (fileno (CURTTY ()->input), &old_width, &old_height);
+ reset_all_sys_modes ();
/* sys_suspend can get an error if it tries to fork a subshell
and the system resources aren't available for that. */
- record_unwind_protect ((Lisp_Object (*) P_ ((Lisp_Object))) init_sys_modes,
+ record_unwind_protect ((Lisp_Object (*) P_ ((Lisp_Object))) init_all_sys_modes,
Qnil);
stuff_buffered_input (stuffstring);
if (cannot_suspend)
@@ -10610,7 +10829,7 @@ On such systems, Emacs starts a subshell instead of suspending. */)
/* Check if terminal/window size has changed.
Note that this is not useful when we are running directly
with a window system; but suspend should be disabled in that case. */
- get_frame_size (&width, &height);
+ get_tty_size (fileno (CURTTY ()->input), &width, &height);
if (width != old_width || height != old_height)
change_frame_size (SELECTED_FRAME (), height, width, 0, 0, 0);
@@ -10670,10 +10889,10 @@ set_waiting_for_input (time_to_clear)
{
input_available_clear_time = time_to_clear;
- /* Tell interrupt_signal to throw back to read_char, */
+ /* Tell handle_interrupt to throw back to read_char, */
waiting_for_input = 1;
- /* If interrupt_signal was called before and buffered a C-g,
+ /* If handle_interrupt was called before and buffered a C-g,
make it run again now, to avoid timing error. */
if (!NILP (Vquit_flag))
quit_throw_to_read_char ();
@@ -10682,48 +10901,82 @@ set_waiting_for_input (time_to_clear)
void
clear_waiting_for_input ()
{
- /* Tell interrupt_signal not to throw back to read_char, */
+ /* Tell handle_interrupt not to throw back to read_char, */
waiting_for_input = 0;
input_available_clear_time = 0;
}
-/* This routine is called at interrupt level in response to C-g.
-
- If interrupt_input, this is the handler for SIGINT. Otherwise, it
- is called from kbd_buffer_store_event, in handling SIGIO or
- SIGTINT.
+/* The SIGINT handler.
- If `waiting_for_input' is non zero, then unless `echoing' is
- nonzero, immediately throw back to read_char.
-
- Otherwise it sets the Lisp variable quit-flag not-nil. This causes
- eval to throw, when it gets a chance. If quit-flag is already
- non-nil, it stops the job right away. */
+ If we have a frame on the controlling tty, we assume that the
+ SIGINT was generated by C-g, so we call handle_interrupt.
+ Otherwise, the handler kills Emacs. */
static SIGTYPE
interrupt_signal (signalnum) /* If we don't have an argument, */
int signalnum; /* some compilers complain in signal calls. */
{
- char c;
/* Must preserve main program's value of errno. */
int old_errno = errno;
- struct frame *sf = SELECTED_FRAME ();
+ struct terminal *terminal;
#if defined (USG) && !defined (POSIX_SIGNALS)
- if (!read_socket_hook && NILP (Vwindow_system))
- {
- /* USG systems forget handlers when they are used;
- must reestablish each time */
- signal (SIGINT, interrupt_signal);
- signal (SIGQUIT, interrupt_signal);
- }
+ /* USG systems forget handlers when they are used;
+ must reestablish each time */
+ signal (SIGINT, interrupt_signal);
+ signal (SIGQUIT, interrupt_signal);
#endif /* USG */
SIGNAL_THREAD_CHECK (signalnum);
+
+ /* See if we have an active terminal on our controlling tty. */
+ terminal = get_named_tty ("/dev/tty");
+ if (!terminal)
+ {
+ /* If there are no frames there, let's pretend that we are a
+ well-behaving UN*X program and quit. */
+ Fkill_emacs (Qnil);
+ }
+ else
+ {
+ /* Otherwise, the SIGINT was probably generated by C-g. */
+
+ /* Set internal_last_event_frame to the top frame of the
+ controlling tty, if we have a frame there. We disable the
+ interrupt key on secondary ttys, so the SIGINT must have come
+ from the controlling tty. */
+ internal_last_event_frame = terminal->display_info.tty->top_frame;
+
+ handle_interrupt ();
+ }
+
+ errno = old_errno;
+}
+
+/* This routine is called at interrupt level in response to C-g.
+
+ It is called from the SIGINT handler or kbd_buffer_store_event.
+
+ If `waiting_for_input' is non zero, then unless `echoing' is
+ nonzero, immediately throw back to read_char.
+
+ Otherwise it sets the Lisp variable quit-flag not-nil. This causes
+ eval to throw, when it gets a chance. If quit-flag is already
+ non-nil, it stops the job right away. */
+
+static void
+handle_interrupt ()
+{
+ char c;
+
cancel_echoing ();
+ /* XXX This code needs to be revised for multi-tty support. */
if (!NILP (Vquit_flag)
- && (FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf)))
+#ifndef MSDOS
+ && get_named_tty ("/dev/tty")
+#endif
+ )
{
/* If SIGINT isn't blocked, don't let us be interrupted by
another SIGINT, it might be harmful due to non-reentrancy
@@ -10731,7 +10984,7 @@ interrupt_signal (signalnum) /* If we don't have an argument, */
sigblock (sigmask (SIGINT));
fflush (stdout);
- reset_sys_modes ();
+ reset_all_sys_modes ();
#ifdef SIGTSTP /* Support possible in later USG versions */
/*
@@ -10810,7 +11063,7 @@ interrupt_signal (signalnum) /* If we don't have an argument, */
printf ("Continuing...\n");
#endif /* not MSDOS */
fflush (stdout);
- init_sys_modes ();
+ init_all_sys_modes ();
sigfree ();
}
else
@@ -10838,9 +11091,7 @@ interrupt_signal (signalnum) /* If we don't have an argument, */
}
if (waiting_for_input && !echoing)
- quit_throw_to_read_char ();
-
- errno = old_errno;
+ quit_throw_to_read_char ();
}
/* Handle a C-g by making read_char return C-g. */
@@ -10873,75 +11124,202 @@ quit_throw_to_read_char ()
_longjmp (getcjmp, 1);
}
-DEFUN ("set-input-mode", Fset_input_mode, Sset_input_mode, 3, 4, 0,
- doc: /* Set mode of reading keyboard input.
-First arg INTERRUPT non-nil means use input interrupts;
- nil means use CBREAK mode.
-Second arg FLOW non-nil means use ^S/^Q flow control for output to terminal
- (no effect except in CBREAK mode).
-Third arg META t means accept 8-bit input (for a Meta key).
- META nil means ignore the top bit, on the assumption it is parity.
- Otherwise, accept 8-bit input and don't use the top bit for Meta.
-Optional fourth arg QUIT if non-nil specifies character to use for quitting.
+DEFUN ("set-input-interrupt-mode", Fset_input_interrupt_mode, Sset_input_interrupt_mode, 1, 1, 0,
+ doc: /* Set interrupt mode of reading keyboard input.
+If INTERRUPT is non-nil, Emacs will use input interrupts;
+otherwise Emacs uses CBREAK mode.
+
See also `current-input-mode'. */)
- (interrupt, flow, meta, quit)
- Lisp_Object interrupt, flow, meta, quit;
+ (interrupt)
+ Lisp_Object interrupt;
{
- if (!NILP (quit)
- && (!INTEGERP (quit) || XINT (quit) < 0 || XINT (quit) > 0400))
- error ("set-input-mode: QUIT must be an ASCII character");
-
-#ifdef POLL_FOR_INPUT
- stop_polling ();
-#endif
-
-#ifndef DOS_NT
- /* this causes startup screen to be restored and messes with the mouse */
- reset_sys_modes ();
-#endif
-
+ int new_interrupt_input;
#ifdef SIGIO
/* Note SIGIO has been undef'd if FIONREAD is missing. */
- if (read_socket_hook)
+#ifdef HAVE_X_WINDOWS
+ if (x_display_list != NULL)
{
/* When using X, don't give the user a real choice,
because we haven't implemented the mechanisms to support it. */
#ifdef NO_SOCK_SIGIO
- interrupt_input = 0;
+ new_interrupt_input = 0;
#else /* not NO_SOCK_SIGIO */
- interrupt_input = 1;
+ new_interrupt_input = 1;
#endif /* NO_SOCK_SIGIO */
}
else
- interrupt_input = !NILP (interrupt);
+#endif
+ new_interrupt_input = !NILP (interrupt);
#else /* not SIGIO */
- interrupt_input = 0;
+ new_interrupt_input = 0;
#endif /* not SIGIO */
/* Our VMS input only works by interrupts, as of now. */
#ifdef VMS
- interrupt_input = 1;
+ new_interrupt_input = 1;
#endif
- flow_control = !NILP (flow);
+ if (new_interrupt_input != interrupt_input)
+ {
+#ifdef POLL_FOR_INPUT
+ stop_polling ();
+#endif
+#ifndef DOS_NT
+ /* this causes startup screen to be restored and messes with the mouse */
+ reset_all_sys_modes ();
+#endif
+ interrupt_input = new_interrupt_input;
+#ifndef DOS_NT
+ init_all_sys_modes ();
+#endif
+
+#ifdef POLL_FOR_INPUT
+ poll_suppress_count = 1;
+ start_polling ();
+#endif
+ }
+ return Qnil;
+}
+
+DEFUN ("set-output-flow-control", Fset_output_flow_control, Sset_output_flow_control, 1, 2, 0,
+ doc: /* Enable or disable ^S/^Q flow control for output to TERMINAL.
+If FLOW is non-nil, flow control is enabled and you cannot use C-s or
+C-q in key sequences.
+
+This setting only has an effect on tty terminals and only when
+Emacs reads input in CBREAK mode; see `set-input-interrupt-mode'.
+
+See also `current-input-mode'. */)
+ (flow, terminal)
+ Lisp_Object flow, terminal;
+{
+ struct terminal *t = get_terminal (terminal, 1);
+ struct tty_display_info *tty;
+ if (t == NULL || t->type != output_termcap)
+ return Qnil;
+ tty = t->display_info.tty;
+
+ if (tty->flow_control != !NILP (flow))
+ {
+#ifndef DOS_NT
+ /* this causes startup screen to be restored and messes with the mouse */
+ reset_sys_modes (tty);
+#endif
+
+ tty->flow_control = !NILP (flow);
+
+#ifndef DOS_NT
+ init_sys_modes (tty);
+#endif
+ }
+ return Qnil;
+}
+
+DEFUN ("set-input-meta-mode", Fset_input_meta_mode, Sset_input_meta_mode, 1, 2, 0,
+ doc: /* Enable or disable 8-bit input on TERMINAL.
+If META is t, Emacs will accept 8-bit input, and interpret the 8th
+bit as the Meta modifier.
+
+If META is nil, Emacs will ignore the top bit, on the assumption it is
+parity.
+
+Otherwise, Emacs will accept and pass through 8-bit input without
+specially interpreting the top bit.
+
+This setting only has an effect on tty terminal devices.
+
+Optional parameter TERMINAL specifies the tty terminal device to use.
+It may be a terminal id, a frame, or nil for the terminal used by the
+currently selected frame.
+
+See also `current-input-mode'. */)
+ (meta, terminal)
+ Lisp_Object meta, terminal;
+{
+ struct terminal *t = get_terminal (terminal, 1);
+ struct tty_display_info *tty;
+ int new_meta;
+
+ if (t == NULL || t->type != output_termcap)
+ return Qnil;
+ tty = t->display_info.tty;
+
if (NILP (meta))
- meta_key = 0;
+ new_meta = 0;
else if (EQ (meta, Qt))
- meta_key = 1;
+ new_meta = 1;
else
- meta_key = 2;
- if (!NILP (quit))
- /* Don't let this value be out of range. */
- quit_char = XINT (quit) & (meta_key ? 0377 : 0177);
+ new_meta = 2;
+ if (tty->meta_key != new_meta)
+ {
#ifndef DOS_NT
- init_sys_modes ();
+ /* this causes startup screen to be restored and messes with the mouse */
+ reset_sys_modes (tty);
#endif
-#ifdef POLL_FOR_INPUT
- poll_suppress_count = 1;
- start_polling ();
+ tty->meta_key = new_meta;
+
+#ifndef DOS_NT
+ init_sys_modes (tty);
#endif
+ }
+ return Qnil;
+}
+
+DEFUN ("set-quit-char", Fset_quit_char, Sset_quit_char, 1, 1, 0,
+ doc: /* Specify character used for quitting.
+QUIT must be an ASCII character.
+
+This function only has an effect on the controlling tty of the Emacs
+process.
+
+See also `current-input-mode'. */)
+ (quit)
+ Lisp_Object quit;
+{
+ struct terminal *t = get_named_tty ("/dev/tty");
+ struct tty_display_info *tty;
+ if (t == NULL || t->type != output_termcap)
+ return Qnil;
+ tty = t->display_info.tty;
+
+ if (NILP (quit) || !INTEGERP (quit) || XINT (quit) < 0 || XINT (quit) > 0400)
+ error ("QUIT must be an ASCII character");
+
+#ifndef DOS_NT
+ /* this causes startup screen to be restored and messes with the mouse */
+ reset_sys_modes (tty);
+#endif
+
+ /* Don't let this value be out of range. */
+ quit_char = XINT (quit) & (tty->meta_key == 0 ? 0177 : 0377);
+
+#ifndef DOS_NT
+ init_sys_modes (tty);
+#endif
+
+ return Qnil;
+}
+
+DEFUN ("set-input-mode", Fset_input_mode, Sset_input_mode, 3, 4, 0,
+ doc: /* Set mode of reading keyboard input.
+First arg INTERRUPT non-nil means use input interrupts;
+ nil means use CBREAK mode.
+Second arg FLOW non-nil means use ^S/^Q flow control for output to terminal
+ (no effect except in CBREAK mode).
+Third arg META t means accept 8-bit input (for a Meta key).
+ META nil means ignore the top bit, on the assumption it is parity.
+ Otherwise, accept 8-bit input and don't use the top bit for Meta.
+Optional fourth arg QUIT if non-nil specifies character to use for quitting.
+See also `current-input-mode'. */)
+ (interrupt, flow, meta, quit)
+ Lisp_Object interrupt, flow, meta, quit;
+{
+ Fset_input_interrupt_mode (interrupt);
+ Fset_output_flow_control (flow, Qnil);
+ Fset_input_meta_mode (meta, Qnil);
+ Fset_quit_char (quit);
return Qnil;
}
@@ -10962,10 +11340,21 @@ The elements of this list correspond to the arguments of
()
{
Lisp_Object val[4];
+ struct frame *sf = XFRAME (selected_frame);
val[0] = interrupt_input ? Qt : Qnil;
- val[1] = flow_control ? Qt : Qnil;
- val[2] = meta_key == 2 ? make_number (0) : meta_key == 1 ? Qt : Qnil;
+ if (FRAME_TERMCAP_P (sf))
+ {
+ val[1] = FRAME_TTY (sf)->flow_control ? Qt : Qnil;
+ val[2] = (FRAME_TTY (sf)->meta_key == 2
+ ? make_number (0)
+ : (CURTTY ()->meta_key == 1 ? Qt : Qnil));
+ }
+ else
+ {
+ val[1] = Qnil;
+ val[2] = Qt;
+ }
XSETFASTINT (val[3], quit_char);
return Flist (sizeof (val) / sizeof (val[0]), val);
@@ -11057,6 +11446,7 @@ init_kboard (kb)
kb->Voverriding_terminal_local_map = Qnil;
kb->Vlast_command = Qnil;
kb->Vreal_last_command = Qnil;
+ kb->Vkeyboard_translate_table = Qnil;
kb->Vprefix_arg = Qnil;
kb->Vlast_prefix_arg = Qnil;
kb->kbd_queue = Qnil;
@@ -11071,6 +11461,10 @@ init_kboard (kb)
kb->reference_count = 0;
kb->Vsystem_key_alist = Qnil;
kb->system_key_syms = Qnil;
+ kb->Vlocal_function_key_map = Fmake_sparse_keymap (Qnil);
+ Fset_keymap_parent (kb->Vlocal_function_key_map, Vfunction_key_map);
+ kb->Vlocal_key_translation_map = Fmake_sparse_keymap (Qnil);
+ Fset_keymap_parent (kb->Vlocal_key_translation_map, Vkey_translation_map);
kb->Vdefault_minibuffer_frame = Qnil;
}
@@ -11107,7 +11501,8 @@ delete_kboard (kb)
&& FRAMEP (selected_frame)
&& FRAME_LIVE_P (XFRAME (selected_frame)))
{
- current_kboard = XFRAME (selected_frame)->kboard;
+ current_kboard = FRAME_KBOARD (XFRAME (selected_frame));
+ single_kboard = 0;
if (current_kboard == kb)
abort ();
}
@@ -11150,8 +11545,14 @@ init_keyboard ()
wipe_kboard (current_kboard);
init_kboard (current_kboard);
- if (!noninteractive && !read_socket_hook && NILP (Vwindow_system))
+ if (!noninteractive)
{
+ /* Before multi-tty support, these handlers used to be installed
+ only if the current session was a tty session. Now an Emacs
+ session may have multiple display types, so we always handle
+ SIGINT. There is special code in interrupt_signal to exit
+ Emacs on SIGINT when there are no termcap frames on the
+ controlling terminal. */
signal (SIGINT, interrupt_signal);
#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
/* For systems with SysV TERMIO, C-g is set up for both SIGINT and
@@ -11476,6 +11877,10 @@ syms_of_keyboard ()
defsubr (&Stop_level);
defsubr (&Sdiscard_input);
defsubr (&Sopen_dribble_file);
+ defsubr (&Sset_input_interrupt_mode);
+ defsubr (&Sset_output_flow_control);
+ defsubr (&Sset_input_meta_mode);
+ defsubr (&Sset_quit_char);
defsubr (&Sset_input_mode);
defsubr (&Scurrent_input_mode);
defsubr (&Sexecute_extended_command);
@@ -11542,7 +11947,10 @@ In other words, the present command is the event that made the previous
command exit.
The value `kill-region' is special; it means that the previous command
-was a kill command. */);
+was a kill command.
+
+`last-command' has a separate binding for each terminal device.
+See Info node `(elisp)Multiple displays'. */);
DEFVAR_KBOARD ("real-last-command", Vreal_last_command,
doc: /* Same as `last-command', but never altered by Lisp code. */);
@@ -11654,8 +12062,8 @@ for that character after that prefix key. */);
Useful to set before you dump a modified Emacs. */);
Vtop_level = Qnil;
- DEFVAR_LISP ("keyboard-translate-table", &Vkeyboard_translate_table,
- doc: /* Translate table for keyboard input, or nil.
+ DEFVAR_KBOARD ("keyboard-translate-table", Vkeyboard_translate_table,
+ doc: /* Translate table for local keyboard input, or nil.
If non-nil, the value should be a char-table. Each character read
from the keyboard is looked up in this char-table. If the value found
there is non-nil, then it is used instead of the actual input character.
@@ -11665,8 +12073,10 @@ If it is a string or vector of length N, character codes N and up are left
untranslated. In a vector, an element which is nil means "no translation".
This is applied to the characters supplied to input methods, not their
-output. See also `translation-table-for-input'. */);
- Vkeyboard_translate_table = Qnil;
+output. See also `translation-table-for-input'.
+
+This variable has a separate binding for each terminal. See Info node
+`(elisp)Multiple displays'. */);
DEFVAR_BOOL ("cannot-suspend", &cannot_suspend,
doc: /* Non-nil means to always spawn a subshell instead of suspending.
@@ -11751,7 +12161,11 @@ buffer's local map, and the minor mode keymaps and text property keymaps.
It also replaces `overriding-local-map'.
This variable is intended to let commands such as `universal-argument'
-set up a different keymap for reading the next command. */);
+set up a different keymap for reading the next command.
+
+`overriding-terminal-local-map' has a separate binding for each
+terminal device.
+See Info node `(elisp)Multiple displays'. */);
DEFVAR_LISP ("overriding-local-map", &Voverriding_local_map,
doc: /* Keymap that overrides all other local keymaps.
@@ -11776,7 +12190,61 @@ and the minor mode maps regardless of `overriding-local-map'. */);
doc: /* Alist of system-specific X windows key symbols.
Each element should have the form (N . SYMBOL) where N is the
numeric keysym code (sans the \"system-specific\" bit 1<<28)
-and SYMBOL is its name. */);
+and SYMBOL is its name.
+
+`system-key-alist' has a separate binding for each terminal device.
+See Info node `(elisp)Multiple displays'. */);
+
+ DEFVAR_KBOARD ("local-function-key-map", Vlocal_function_key_map,
+ doc: /* Keymap that translates key sequences to key sequences during input.
+This is used mainly for mapping ASCII function key sequences into
+real Emacs function key events (symbols).
+
+The `read-key-sequence' function replaces any subsequence bound by
+`local-function-key-map' with its binding. More precisely, when the
+active keymaps have no binding for the current key sequence but
+`local-function-key-map' binds a suffix of the sequence to a vector or
+string, `read-key-sequence' replaces the matching suffix with its
+binding, and continues with the new sequence.
+
+If the binding is a function, it is called with one argument (the prompt)
+and its return value (a key sequence) is used.
+
+The events that come from bindings in `local-function-key-map' are not
+themselves looked up in `local-function-key-map'.
+
+For example, suppose `local-function-key-map' binds `ESC O P' to [f1].
+Typing `ESC O P' to `read-key-sequence' would return [f1]. Typing
+`C-x ESC O P' would return [?\\C-x f1]. If [f1] were a prefix key,
+typing `ESC O P x' would return [f1 x].
+
+`local-function-key-map' has a separate binding for each terminal
+device. See Info node `(elisp)Multiple displays'. If you need to
+define a binding on all terminals, change `function-key-map'
+instead. Initially, `local-function-key-map' is an empty keymap that
+has `function-key-map' as its parent on all terminal devices. */);
+
+ DEFVAR_LISP ("function-key-map", &Vfunction_key_map,
+ doc: /* The parent keymap of all `local-function-key-map' instances.
+Function key definitions that apply to all terminal devices should go
+here. If a mapping is defined in both the current
+`local-function-key-map' binding and this variable, then the local
+definition will take precendence. */);
+ Vfunction_key_map = Fmake_sparse_keymap (Qnil);
+
+ DEFVAR_KBOARD ("local-key-translation-map", Vlocal_key_translation_map,
+ doc: /* Keymap of key translations that can override keymaps.
+This keymap works like `function-key-map', but comes after that,
+and its non-prefix bindings override ordinary bindings.
+
+`key-translation-map' has a separate binding for each terminal device.
+(See Info node `(elisp)Multiple displays'.) If you need to set a key
+translation on all terminals, change `global-key-translation-map' instead. */);
+
+ DEFVAR_LISP ("key-translation-map", &Vkey_translation_map,
+ doc: /* The parent keymap of all `local-key-translation-map' instances.
+Key translations that apply to all terminal devices should go here. */);
+ Vkey_translation_map = Fmake_sparse_keymap (Qnil);
DEFVAR_LISP ("deferred-action-list", &Vdeferred_action_list,
doc: /* List of deferred actions to be performed at a later time.
@@ -11945,6 +12413,7 @@ mark_kboards ()
mark_object (kb->Voverriding_terminal_local_map);
mark_object (kb->Vlast_command);
mark_object (kb->Vreal_last_command);
+ mark_object (kb->Vkeyboard_translate_table);
mark_object (kb->Vprefix_arg);
mark_object (kb->Vlast_prefix_arg);
mark_object (kb->kbd_queue);
@@ -11952,6 +12421,8 @@ mark_kboards ()
mark_object (kb->Vlast_kbd_macro);
mark_object (kb->Vsystem_key_alist);
mark_object (kb->system_key_syms);
+ mark_object (kb->Vlocal_function_key_map);
+ mark_object (kb->Vlocal_key_translation_map);
mark_object (kb->Vdefault_minibuffer_frame);
mark_object (kb->echo_string);
}
diff --git a/src/keyboard.h b/src/keyboard.h
index 15e55ad4e67..a65bf8cfa02 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -23,8 +23,9 @@ Boston, MA 02110-1301, USA. */
/* Length of echobuf field in each KBOARD. */
-/* Each KBOARD represents one logical input stream from which Emacs gets input.
- If we are using an ordinary terminal, it has one KBOARD object.
+/* Each KBOARD represents one logical input stream from which Emacs
+ gets input. If we are using ordinary terminals, it has one KBOARD
+ object for each terminal device.
Usually each X display screen has its own KBOARD,
but when two of them are on the same X server,
we assume they share a keyboard and give them one KBOARD in common.
@@ -83,6 +84,9 @@ struct kboard
other commands. */
Lisp_Object Vreal_last_command;
+ /* User-supplied table to translate input characters through. */
+ Lisp_Object Vkeyboard_translate_table;
+
/* The prefix argument for the next command, in raw form. */
Lisp_Object Vprefix_arg;
@@ -123,6 +127,14 @@ struct kboard
/* Cache for modify_event_symbol. */
Lisp_Object system_key_syms;
+ /* Keymap mapping ASCII function key sequences onto their
+ preferred forms. Initialized by the terminal-specific lisp
+ files. See the DEFVAR for more documentation. */
+ Lisp_Object Vlocal_function_key_map;
+
+ /* Keymap of key translations that can override keymaps. */
+ Lisp_Object Vlocal_key_translation_map;
+
/* Minibufferless frames on this display use this frame's minibuffer. */
Lisp_Object Vdefault_minibuffer_frame;
@@ -155,7 +167,7 @@ struct kboard
};
#ifdef MULTI_KBOARD
-/* Temporarily used before a frame has been opened, and for termcap frames */
+/* Temporarily used before a frame has been opened. */
extern KBOARD *initial_kboard;
/* In the single-kboard state, this is the kboard
@@ -190,10 +202,6 @@ extern EMACS_INT num_nonmacro_input_events;
/* Nonzero means polling for input is temporarily suppressed. */
extern int poll_suppress_count;
-/* Keymap mapping ASCII function key sequences onto their preferred forms.
- Initialized by the terminal-specific lisp files. */
-extern Lisp_Object Vfunction_key_map;
-
/* Vector holding the key sequence that invoked the current command.
It is reused for each command, and it may be longer than the current
sequence; this_command_key_count indicates how many elements
@@ -301,18 +309,24 @@ extern Lisp_Object parse_modifiers P_ ((Lisp_Object));
extern Lisp_Object reorder_modifiers P_ ((Lisp_Object));
extern Lisp_Object read_char P_ ((int, int, Lisp_Object *, Lisp_Object,
int *, EMACS_TIME *));
-/* User-supplied string to translate input characters through. */
-extern Lisp_Object Vkeyboard_translate_table;
+
+
+/* Parent keymap of terminal-local function-key-map instances. */
+extern Lisp_Object Vfunction_key_map;
+
+/* Parent keymap of terminal-local key-translation-map instances. */
+extern Lisp_Object Vkey_translation_map;
extern int parse_menu_item P_ ((Lisp_Object, int, int));
extern void echo_now P_ ((void));
extern void init_kboard P_ ((KBOARD *));
extern void delete_kboard P_ ((KBOARD *));
-extern void single_kboard_state P_ ((void));
extern void not_single_kboard_state P_ ((KBOARD *));
+extern void push_kboard P_ ((struct kboard *));
extern void push_frame_kboard P_ ((struct frame *));
-extern void pop_frame_kboard P_ ((void));
+extern void pop_kboard P_ ((void));
+extern void temporarily_switch_to_single_kboard P_ ((struct frame *));
extern void record_asynch_buffer_change P_ ((void));
extern SIGTYPE input_poll_signal P_ ((int));
extern void start_polling P_ ((void));
@@ -346,5 +360,8 @@ extern Lisp_Object menu_item_eval_property P_ ((Lisp_Object));
extern int kbd_buffer_events_waiting P_ ((int));
extern void add_user_signals P_ ((int, const char *));
+extern int tty_read_avail_input P_ ((struct terminal *, int,
+ struct input_event *));
+
/* arch-tag: 769cbade-1ba9-4950-b886-db265b061aa3
(do not change this comment) */
diff --git a/src/keymap.c b/src/keymap.c
index 2c760050c1d..181d43a4f48 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -31,6 +31,7 @@ Boston, MA 02110-1301, USA. */
#include "buffer.h"
#include "charset.h"
#include "keyboard.h"
+#include "frame.h"
#include "termhooks.h"
#include "blockinput.h"
#include "puresize.h"
@@ -90,14 +91,6 @@ Lisp_Object Vminor_mode_overriding_map_alist;
/* List of emulation mode keymap alists. */
Lisp_Object Vemulation_mode_map_alists;
-/* Keymap mapping ASCII function key sequences onto their preferred forms.
- Initialized by the terminal-specific lisp files. See DEFVAR for more
- documentation. */
-Lisp_Object Vfunction_key_map;
-
-/* Keymap mapping ASCII function key sequences onto their preferred forms. */
-Lisp_Object Vkey_translation_map;
-
/* A list of all commands given new bindings since a certain time
when nil was stored here.
This is used to speed up recomputation of menu key equivalents
@@ -3001,11 +2994,11 @@ You type Translation\n\
outbuf = Fcurrent_buffer ();
/* Report on alternates for keys. */
- if (STRINGP (Vkeyboard_translate_table) && !NILP (prefix))
+ if (STRINGP (current_kboard->Vkeyboard_translate_table) && !NILP (prefix))
{
int c;
- const unsigned char *translate = SDATA (Vkeyboard_translate_table);
- int translate_len = SCHARS (Vkeyboard_translate_table);
+ const unsigned char *translate = SDATA (current_kboard->Vkeyboard_translate_table);
+ int translate_len = SCHARS (current_kboard->Vkeyboard_translate_table);
for (c = 0; c < translate_len; c++)
if (translate[c] != c)
@@ -3028,14 +3021,14 @@ You type Translation\n\
insert ("\n", 1);
/* Insert calls signal_after_change which may GC. */
- translate = SDATA (Vkeyboard_translate_table);
+ translate = SDATA (current_kboard->Vkeyboard_translate_table);
}
insert ("\n", 1);
}
- if (!NILP (Vkey_translation_map))
- describe_map_tree (Vkey_translation_map, 0, Qnil, prefix,
+ if (!NILP (current_kboard->Vlocal_key_translation_map))
+ describe_map_tree (current_kboard->Vlocal_key_translation_map, 0, Qnil, prefix,
"Key translations", nomenu, 1, 0, 0);
@@ -3124,8 +3117,8 @@ You type Translation\n\
"\f\nGlobal Bindings", nomenu, 0, 1, 0);
/* Print the function-key-map translations under this prefix. */
- if (!NILP (Vfunction_key_map))
- describe_map_tree (Vfunction_key_map, 0, Qnil, prefix,
+ if (!NILP (current_kboard->Vlocal_function_key_map))
+ describe_map_tree (current_kboard->Vlocal_function_key_map, 0, Qnil, prefix,
"\f\nFunction key map translations", nomenu, 1, 0, 0);
UNGCPRO;
@@ -4095,37 +4088,6 @@ the same way. The "active" keymaps in each alist are used before
`minor-mode-map-alist' and `minor-mode-overriding-map-alist'. */);
Vemulation_mode_map_alists = Qnil;
-
- DEFVAR_LISP ("function-key-map", &Vfunction_key_map,
- doc: /* Keymap that translates key sequences to key sequences during input.
-This is used mainly for mapping ASCII function key sequences into
-real Emacs function key events (symbols).
-
-The `read-key-sequence' function replaces any subsequence bound by
-`function-key-map' with its binding. More precisely, when the active
-keymaps have no binding for the current key sequence but
-`function-key-map' binds a suffix of the sequence to a vector or string,
-`read-key-sequence' replaces the matching suffix with its binding, and
-continues with the new sequence.
-
-If the binding is a function, it is called with one argument (the prompt)
-and its return value (a key sequence) is used.
-
-The events that come from bindings in `function-key-map' are not
-themselves looked up in `function-key-map'.
-
-For example, suppose `function-key-map' binds `ESC O P' to [f1].
-Typing `ESC O P' to `read-key-sequence' would return [f1]. Typing
-`C-x ESC O P' would return [?\\C-x f1]. If [f1] were a prefix
-key, typing `ESC O P x' would return [f1 x]. */);
- Vfunction_key_map = Fmake_sparse_keymap (Qnil);
-
- DEFVAR_LISP ("key-translation-map", &Vkey_translation_map,
- doc: /* Keymap of key translations that can override keymaps.
-This keymap works like `function-key-map', but comes after that,
-and its non-prefix bindings override ordinary bindings. */);
- Vkey_translation_map = Qnil;
-
staticpro (&Vmouse_events);
Vmouse_events = Fcons (intern ("menu-bar"),
Fcons (intern ("tool-bar"),
diff --git a/src/keymap.h b/src/keymap.h
index 1a51de705be..3268967089a 100644
--- a/src/keymap.h
+++ b/src/keymap.h
@@ -38,6 +38,7 @@ EXFUN (Fcurrent_active_maps, 2);
extern Lisp_Object access_keymap P_ ((Lisp_Object, Lisp_Object, int, int, int));
extern Lisp_Object get_keyelt P_ ((Lisp_Object, int));
extern Lisp_Object get_keymap P_ ((Lisp_Object, int, int));
+EXFUN (Fset_keymap_parent, 2);
extern void describe_map_tree P_ ((Lisp_Object, int, Lisp_Object, Lisp_Object,
char *, int, int, int, int));
extern int current_minor_maps P_ ((Lisp_Object **, Lisp_Object **));
diff --git a/src/lisp.h b/src/lisp.h
index c5d9724e96c..b2bca426431 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2992,6 +2992,10 @@ extern Lisp_Object Qvertical_scroll_bar;
extern void discard_mouse_events P_ ((void));
EXFUN (Fevent_convert_list, 1);
EXFUN (Fread_key_sequence, 5);
+EXFUN (Fset_input_interrupt_mode, 1);
+EXFUN (Fset_output_flow_control, 2);
+EXFUN (Fset_input_meta_mode, 2);
+EXFUN (Fset_quit_char, 1);
EXFUN (Fset_input_mode, 4);
extern int detect_input_pending P_ ((void));
extern int detect_input_pending_ignore_squeezables P_ ((void));
@@ -3047,6 +3051,7 @@ EXFUN (Fvisible_frame_list, 0);
EXFUN (Fframe_parameter, 2);
EXFUN (Fframe_parameters, 1);
EXFUN (Fmodify_frame_parameters, 2);
+EXFUN (Fframe_with_environment, 1);
EXFUN (Fset_frame_height, 3);
EXFUN (Fset_frame_width, 3);
EXFUN (Fset_frame_size, 3);
@@ -3115,7 +3120,7 @@ EXFUN (Fcall_process, MANY);
extern int child_setup P_ ((int, int, int, char **, int, Lisp_Object));
extern void init_callproc_1 P_ ((void));
extern void init_callproc P_ ((void));
-extern void set_process_environment P_ ((void));
+extern void set_global_environment P_ ((void));
extern void syms_of_callproc P_ ((void));
/* defined in doc.c */
@@ -3177,28 +3182,31 @@ EXFUN (Fx_popup_menu, 2);
EXFUN (Fx_popup_dialog, 3);
extern void syms_of_xmenu P_ ((void));
+/* defined in termchar.h */
+struct tty_display_info;
+
+/* defined in termhooks.h */
+struct terminal;
+
/* defined in sysdep.c */
#ifndef HAVE_GET_CURRENT_DIR_NAME
extern char *get_current_dir_name P_ ((void));
#endif
extern void stuff_char P_ ((char c));
extern void init_sigio P_ ((int));
-extern void request_sigio P_ ((void));
-extern void unrequest_sigio P_ ((void));
-extern void reset_sys_modes P_ ((void));
extern void sys_subshell P_ ((void));
extern void sys_suspend P_ ((void));
extern void discard_tty_input P_ ((void));
-extern void init_sys_modes P_ ((void));
-extern void get_frame_size P_ ((int *, int *));
+extern void init_sys_modes P_ ((struct tty_display_info *));
+extern void reset_sys_modes P_ ((struct tty_display_info *));
+extern void init_all_sys_modes P_ ((void));
+extern void reset_all_sys_modes P_ ((void));
extern void wait_for_termination P_ ((int));
extern void flush_pending_output P_ ((int));
extern void child_setup_tty P_ ((int));
extern void setup_pty P_ ((int));
extern int set_window_size P_ ((int, int, int));
extern void create_process P_ ((Lisp_Object, char **, Lisp_Object));
-extern int tabs_safe_p P_ ((void));
-extern void init_baud_rate P_ ((void));
extern int emacs_open P_ ((const char *, int, int));
extern int emacs_close P_ ((int));
extern int emacs_read P_ ((int, char *, unsigned int));
@@ -3233,6 +3241,9 @@ extern void syms_of_dired P_ ((void));
extern void syms_of_term P_ ((void));
extern void fatal () NO_RETURN;
+/* Defined in terminal.c */
+extern void syms_of_terminal P_ ((void));
+
#ifdef HAVE_WINDOW_SYSTEM
/* Defined in fontset.c */
extern void syms_of_fontset P_ ((void));
diff --git a/src/lread.c b/src/lread.c
index a67fff1fc92..e8ff0ee63df 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -27,6 +27,7 @@ Boston, MA 02110-1301, USA. */
#include <sys/stat.h>
#include <sys/file.h>
#include <errno.h>
+#include <setjmp.h>
#include "lisp.h"
#include "intervals.h"
#include "buffer.h"
@@ -34,6 +35,7 @@ Boston, MA 02110-1301, USA. */
#include <epaths.h>
#include "commands.h"
#include "keyboard.h"
+#include "frame.h"
#include "termhooks.h"
#include "coding.h"
#include "blockinput.h"
@@ -447,8 +449,6 @@ static void substitute_in_interval P_ ((INTERVAL, Lisp_Object));
/* Get a character from the tty. */
-extern Lisp_Object read_char ();
-
/* Read input events until we get one that's acceptable for our purposes.
If NO_SWITCH_FRAME is non-zero, switch-frame events are stashed
@@ -500,10 +500,12 @@ read_filtered_event (no_switch_frame, ascii_required, error_nonascii,
EMACS_ADD_TIME (end_time, end_time, wait_time);
}
- /* Read until we get an acceptable event. */
+/* Read until we get an acceptable event. */
retry:
- val = read_char (0, 0, 0, (input_method ? Qnil : Qt), 0,
- NUMBERP (seconds) ? &end_time : NULL);
+ do
+ val = read_char (0, 0, 0, (input_method ? Qnil : Qt), 0,
+ NUMBERP (seconds) ? &end_time : NULL);
+ while (INTEGERP (val) && XINT (val) == -2); /* wrong_kboard_jmpbuf */
if (BUFFERP (val))
goto retry;
diff --git a/src/macfns.c b/src/macfns.c
index 34f80943497..d447ee90a4f 100644
--- a/src/macfns.c
+++ b/src/macfns.c
@@ -107,7 +107,6 @@ extern Lisp_Object Vwindow_system_version;
int image_cache_refcount, dpyinfo_refcount;
#endif
-
#if 0 /* Use xstricmp instead. */
/* compare two strings ignoring case */
@@ -1367,11 +1366,11 @@ x_set_mouse_color (f, arg, oldval)
Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
Cursor hourglass_cursor, horizontal_drag_cursor;
unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
- unsigned long mask_color = x->background_pixel;
+ unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
/* Don't let pointers be invisible. */
if (mask_color == pixel)
- pixel = x->foreground_pixel;
+ pixel = FRAME_FOREGROUND_PIXEL (f);
f->output_data.mac->mouse_pixel = pixel;
@@ -1444,7 +1443,7 @@ x_set_mouse_color (f, arg, oldval)
BLOCK_INPUT;
if (FRAME_MAC_WINDOW (f) != 0)
- rif->define_frame_cursor (f, cursor);
+ FRAME_TERMINAL (f)->rif->define_frame_cursor (f, cursor);
f->output_data.mac->text_cursor = cursor;
f->output_data.mac->nontext_cursor = nontext_cursor;
@@ -1724,10 +1723,8 @@ x_set_tool_bar_lines (f, value, oldval)
below the menu bar. */
if (FRAME_MAC_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
{
- updating_frame = f;
- clear_frame ();
+ clear_frame (f);
clear_current_matrices (f);
- updating_frame = NULL;
}
/* If the tool bar gets smaller, the internal border below it
@@ -2253,8 +2250,10 @@ XParseGeometry (string, x, y, width, height)
/* Create and set up the Mac window for frame F. */
static void
-mac_window (f)
+mac_window (f, window_prompting, minibuffer_only)
struct frame *f;
+ long window_prompting;
+ int minibuffer_only;
{
Rect r;
@@ -2427,8 +2426,8 @@ x_make_gc (f)
= (XCreatePixmapFromBitmapData
(FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
gray_bits, gray_width, gray_height,
- f->output_data.x->foreground_pixel,
- f->output_data.x->background_pixel,
+ FRAME_FOREGROUND_PIXEL (f),
+ FRAME_BACKGROUND_PIXEL (f),
DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
#endif
@@ -2523,15 +2522,15 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
1, 1, 0,
doc: /* Make a new window, which is called a "frame" in Emacs terms.
Returns an Emacs frame object.
-ALIST is an alist of frame parameters.
+PARAMETERS is an alist of frame parameters.
If the parameters specify that the frame should not have a minibuffer,
and do not specify a specific minibuffer window to use,
then `default-minibuffer-frame' must be a frame whose minibuffer can
be shared by the new frame.
This function is an internal primitive--use `make-frame' instead. */)
- (parms)
- Lisp_Object parms;
+ (parameters)
+ Lisp_Object parameters;
{
struct frame *f;
Lisp_Object frame, tem;
@@ -2548,23 +2547,21 @@ This function is an internal primitive--use `make-frame' instead. */)
check_mac ();
- parms = Fcopy_alist (parms);
-
/* Use this general default value to start with
until we know if this frame has a specified name. */
Vx_resource_name = Vinvocation_name;
- display = mac_get_arg (parms, Qdisplay, 0, 0, RES_TYPE_STRING);
+ display = mac_get_arg (parameters, Qdisplay, 0, 0, RES_TYPE_STRING);
if (EQ (display, Qunbound))
display = Qnil;
dpyinfo = check_x_display_info (display);
#ifdef MULTI_KBOARD
- kb = dpyinfo->kboard;
+ kb = dpyinfo->terminal->kboard;
#else
kb = &the_only_kboard;
#endif
- name = mac_get_arg (parms, Qname, "name", "Name", RES_TYPE_STRING);
+ name = mac_get_arg (parameters, Qname, "name", "Name", RES_TYPE_STRING);
if (!STRINGP (name)
&& ! EQ (name, Qunbound)
&& ! NILP (name))
@@ -2574,7 +2571,7 @@ This function is an internal primitive--use `make-frame' instead. */)
Vx_resource_name = name;
/* See if parent window is specified. */
- parent = mac_get_arg (parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
+ parent = mac_get_arg (parameters, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
if (EQ (parent, Qunbound))
parent = Qnil;
if (! NILP (parent))
@@ -2584,8 +2581,8 @@ This function is an internal primitive--use `make-frame' instead. */)
/* No need to protect DISPLAY because that's not used after passing
it to make_frame_without_minibuffer. */
frame = Qnil;
- GCPRO4 (parms, parent, name, frame);
- tem = mac_get_arg (parms, Qminibuffer, "minibuffer", "Minibuffer",
+ GCPRO4 (parameters, parent, name, frame);
+ tem = mac_get_arg (parameters, Qminibuffer, "minibuffer", "Minibuffer",
RES_TYPE_SYMBOL);
if (EQ (tem, Qnone) || NILP (tem))
f = make_frame_without_minibuffer (Qnil, kb, display);
@@ -2604,20 +2601,24 @@ This function is an internal primitive--use `make-frame' instead. */)
/* Note that X Windows does support scroll bars. */
FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
+ f->terminal = dpyinfo->terminal;
+ f->terminal->reference_count++;
+
f->output_method = output_mac;
f->output_data.mac = (struct mac_output *) xmalloc (sizeof (struct mac_output));
bzero (f->output_data.mac, sizeof (struct mac_output));
FRAME_FONTSET (f) = -1;
+ record_unwind_protect (unwind_create_frame, frame);
f->icon_name
- = mac_get_arg (parms, Qicon_name, "iconName", "Title", RES_TYPE_STRING);
+ = mac_get_arg (parameters, Qicon_name, "iconName", "Title", RES_TYPE_STRING);
if (! STRINGP (f->icon_name))
f->icon_name = Qnil;
-/* FRAME_MAC_DISPLAY_INFO (f) = dpyinfo; */
+ /* XXX Is this needed? */
+ /*FRAME_MAC_DISPLAY_INFO (f) = dpyinfo;*/
/* With FRAME_MAC_DISPLAY_INFO set up, this unwind-protect is safe. */
- record_unwind_protect (unwind_create_frame, frame);
#if GLYPH_DEBUG
image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount;
dpyinfo_refcount = dpyinfo->reference_count;
@@ -2659,7 +2660,7 @@ This function is an internal primitive--use `make-frame' instead. */)
{
Lisp_Object font;
- font = mac_get_arg (parms, Qfont, "font", "Font", RES_TYPE_STRING);
+ font = mac_get_arg (parameters, Qfont, "font", "Font", RES_TYPE_STRING);
BLOCK_INPUT;
/* First, try whatever font the caller has specified. */
@@ -2671,7 +2672,6 @@ This function is an internal primitive--use `make-frame' instead. */)
else
font = x_new_font (f, SDATA (font));
}
-
/* Try out a font which we hope has bold and italic variations. */
#if USE_ATSUI
if (! STRINGP (font))
@@ -2690,48 +2690,50 @@ This function is an internal primitive--use `make-frame' instead. */)
error ("Cannot find any usable font");
UNBLOCK_INPUT;
- x_set_frame_parameters (f, Fcons (Fcons (Qfont, font), Qnil));
+ x_default_parameter (f, parameters, Qfont, font,
+ "font", "Font", RES_TYPE_STRING);
}
- x_default_parameter (f, parms, Qborder_width, make_number (0),
+ /* XXX Shouldn't this be borderWidth, not borderwidth ?*/
+ x_default_parameter (f, parameters, Qborder_width, make_number (0),
"borderwidth", "BorderWidth", RES_TYPE_NUMBER);
/* This defaults to 2 in order to match xterm. We recognize either
internalBorderWidth or internalBorder (which is what xterm calls
it). */
- if (NILP (Fassq (Qinternal_border_width, parms)))
+ if (NILP (Fassq (Qinternal_border_width, parameters)))
{
Lisp_Object value;
- value = mac_get_arg (parms, Qinternal_border_width,
+ value = mac_get_arg (parameters, Qinternal_border_width,
"internalBorder", "InternalBorder", RES_TYPE_NUMBER);
if (! EQ (value, Qunbound))
- parms = Fcons (Fcons (Qinternal_border_width, value),
- parms);
+ parameters = Fcons (Fcons (Qinternal_border_width, value),
+ parameters);
}
/* Default internalBorderWidth to 0 on Windows to match other programs. */
- x_default_parameter (f, parms, Qinternal_border_width, make_number (0),
+ x_default_parameter (f, parameters, Qinternal_border_width, make_number (0),
"internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER);
- x_default_parameter (f, parms, Qvertical_scroll_bars, Qright,
+ x_default_parameter (f, parameters, Qvertical_scroll_bars, Qright,
"verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
/* Also do the stuff which must be set before the window exists. */
- x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
+ x_default_parameter (f, parameters, Qforeground_color, build_string ("black"),
"foreground", "Foreground", RES_TYPE_STRING);
- x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
+ x_default_parameter (f, parameters, Qbackground_color, build_string ("white"),
"background", "Background", RES_TYPE_STRING);
- x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
+ x_default_parameter (f, parameters, Qmouse_color, build_string ("black"),
"pointerColor", "Foreground", RES_TYPE_STRING);
- x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
+ x_default_parameter (f, parameters, Qcursor_color, build_string ("black"),
"cursorColor", "Foreground", RES_TYPE_STRING);
- x_default_parameter (f, parms, Qborder_color, build_string ("black"),
+ x_default_parameter (f, parameters, Qborder_color, build_string ("black"),
"borderColor", "BorderColor", RES_TYPE_STRING);
- x_default_parameter (f, parms, Qscreen_gamma, Qnil,
+ x_default_parameter (f, parameters, Qscreen_gamma, Qnil,
"screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
- x_default_parameter (f, parms, Qline_spacing, Qnil,
+ x_default_parameter (f, parameters, Qline_spacing, Qnil,
"lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
- x_default_parameter (f, parms, Qleft_fringe, Qnil,
+ x_default_parameter (f, parameters, Qleft_fringe, Qnil,
"leftFringe", "LeftFringe", RES_TYPE_NUMBER);
- x_default_parameter (f, parms, Qright_fringe, Qnil,
+ x_default_parameter (f, parameters, Qright_fringe, Qnil,
"rightFringe", "RightFringe", RES_TYPE_NUMBER);
@@ -2743,29 +2745,29 @@ This function is an internal primitive--use `make-frame' instead. */)
happen. */
init_frame_faces (f);
- x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
+ x_default_parameter (f, parameters, Qmenu_bar_lines, make_number (1),
"menuBar", "MenuBar", RES_TYPE_NUMBER);
- x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),
- "toolBar", "ToolBar", RES_TYPE_NUMBER);
- x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
- "bufferPredicate", "BufferPredicate",
- RES_TYPE_SYMBOL);
- x_default_parameter (f, parms, Qtitle, Qnil,
+ x_default_parameter (f, parameters, Qtool_bar_lines, make_number (1),
+ "toolBar", "ToolBar", RES_TYPE_NUMBER);
+
+ x_default_parameter (f, parameters, Qbuffer_predicate, Qnil,
+ "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL);
+ x_default_parameter (f, parameters, Qtitle, Qnil,
"title", "Title", RES_TYPE_STRING);
- x_default_parameter (f, parms, Qfullscreen, Qnil,
+ x_default_parameter (f, parameters, Qfullscreen, Qnil,
"fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
/* Compute the size of the window. */
- window_prompting = x_figure_window_size (f, parms, 1);
+ window_prompting = x_figure_window_size (f, parameters, 1);
- tem = mac_get_arg (parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
+ tem = mac_get_arg (parameters, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
f->no_split = minibuffer_only || EQ (tem, Qt);
- mac_window (f);
+ mac_window (f, window_prompting, minibuffer_only);
+ x_icon (f, parameters);
- x_icon (f, parms);
x_make_gc (f);
/* Now consider the frame official. */
@@ -2774,18 +2776,17 @@ This function is an internal primitive--use `make-frame' instead. */)
/* We need to do this after creating the window, so that the
icon-creation functions can say whose icon they're describing. */
- x_default_parameter (f, parms, Qicon_type, Qnil,
+ x_default_parameter (f, parameters, Qicon_type, Qnil,
"bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
- x_default_parameter (f, parms, Qauto_raise, Qnil,
+ x_default_parameter (f, parameters, Qauto_raise, Qnil,
"autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
- x_default_parameter (f, parms, Qauto_lower, Qnil,
+ x_default_parameter (f, parameters, Qauto_lower, Qnil,
"autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
- x_default_parameter (f, parms, Qcursor_type, Qbox,
+ x_default_parameter (f, parameters, Qcursor_type, Qbox,
"cursorType", "CursorType", RES_TYPE_SYMBOL);
- x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
- "scrollBarWidth", "ScrollBarWidth",
- RES_TYPE_NUMBER);
+ x_default_parameter (f, parameters, Qscroll_bar_width, Qnil,
+ "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER);
/* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
Change will not be effected unless different from the current
@@ -2793,8 +2794,8 @@ This function is an internal primitive--use `make-frame' instead. */)
width = FRAME_COLS (f);
height = FRAME_LINES (f);
- SET_FRAME_COLS (f, 0);
FRAME_LINES (f) = 0;
+ SET_FRAME_COLS (f, 0);
change_frame_size (f, height, width, 1, 0, 0);
/* Tell the server what size and position, etc, we want, and how
@@ -2811,7 +2812,7 @@ This function is an internal primitive--use `make-frame' instead. */)
{
Lisp_Object visibility;
- visibility = mac_get_arg (parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL);
+ visibility = mac_get_arg (parameters, Qvisibility, 0, 0, RES_TYPE_SYMBOL);
if (EQ (visibility, Qunbound))
visibility = Qt;
@@ -2833,10 +2834,12 @@ This function is an internal primitive--use `make-frame' instead. */)
/* All remaining specified parameters, which have not been "used"
by x_get_arg and friends, now go in the misc. alist of the frame. */
- for (tem = parms; !NILP (tem); tem = XCDR (tem))
+ for (tem = parameters; !NILP (tem); tem = XCDR (tem))
if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
f->param_alist = Fcons (XCAR (tem), f->param_alist);
+ store_frame_param (f, Qwindow_system, Qmac);
+
UNGCPRO;
/* Make sure windows on this frame appear in calls to next-window
@@ -3299,9 +3302,6 @@ x_display_info_for_name (name)
CHECK_STRING (name);
- if (! EQ (Vwindow_system, intern ("mac")))
- error ("Not using Mac native windows");
-
for (dpyinfo = &one_mac_display_info, names = x_display_name_list;
dpyinfo;
dpyinfo = dpyinfo->next, names = XCDR (names))
@@ -3346,9 +3346,6 @@ terminate Emacs if we can't open the connection. */)
if (! NILP (xrm_string))
CHECK_STRING (xrm_string);
- if (! EQ (Vwindow_system, intern ("mac")))
- error ("Not using Mac native windows");
-
if (! NILP (xrm_string))
xrm_option = (unsigned char *) SDATA (xrm_string);
else
@@ -3611,10 +3608,6 @@ start_hourglass ()
EMACS_TIME delay;
int secs, usecs = 0;
- /* Don't bother for ttys. */
- if (NILP (Vwindow_system))
- return;
-
cancel_hourglass ();
if (INTEGERP (Vhourglass_delay)
@@ -3827,7 +3820,7 @@ x_create_tip_frame (dpyinfo, parms, text)
parms = Fcopy_alist (parms);
#ifdef MULTI_KBOARD
- kb = dpyinfo->kboard;
+ kb = dpyinfo->terminal->kboard;
#else
kb = &the_only_kboard;
#endif
diff --git a/src/macmenu.c b/src/macmenu.c
index 883a8463c2d..8305c89ee68 100644
--- a/src/macmenu.c
+++ b/src/macmenu.c
@@ -26,10 +26,10 @@ Boston, MA 02110-1301, USA. */
#include <stdio.h>
#include "lisp.h"
+#include "frame.h"
#include "termhooks.h"
#include "keyboard.h"
#include "keymap.h"
-#include "frame.h"
#include "window.h"
#include "blockinput.h"
#include "buffer.h"
@@ -720,8 +720,8 @@ no quit occurs and `x-popup-menu' returns nil. */)
enum scroll_bar_part part;
unsigned long time;
- if (mouse_position_hook)
- (*mouse_position_hook) (&new_f, 1, &bar_window,
+ if (FRAME_TERMINAL (new_f)->mouse_position_hook)
+ (*FRAME_TERMINAL (new_f)->mouse_position_hook) (&new_f, 1, &bar_window,
&part, &x, &y, &time);
if (new_f != 0)
XSETFRAME (window, new_f);
diff --git a/src/macterm.c b/src/macterm.c
index 0f2b053853d..8b3cee42f5c 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -226,14 +226,14 @@ void x_raise_frame P_ ((struct frame *));
void x_set_window_size P_ ((struct frame *, int, int, int));
void x_wm_set_window_state P_ ((struct frame *, int));
void x_wm_set_icon_pixmap P_ ((struct frame *, int));
-void mac_initialize P_ ((void));
+static void mac_initialize P_ ((void));
static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
static int x_compute_min_glyph_bounds P_ ((struct frame *));
static void x_update_end P_ ((struct frame *));
static void XTframe_up_to_date P_ ((struct frame *));
-static void XTset_terminal_modes P_ ((void));
-static void XTreset_terminal_modes P_ ((void));
-static void x_clear_frame P_ ((void));
+static void XTset_terminal_modes P_ ((struct terminal *));
+static void XTreset_terminal_modes P_ ((struct terminal *));
+static void x_clear_frame P_ ((struct frame *));
static void frame_highlight P_ ((struct frame *));
static void frame_unhighlight P_ ((struct frame *));
static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
@@ -261,6 +261,8 @@ static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
static int is_emacs_window P_ ((WindowRef));
static XCharStruct *mac_per_char_metric P_ ((XFontStruct *, XChar2b *, int));
static void XSetFont P_ ((Display *, GC, XFontStruct *));
+static struct terminal *mac_create_terminal P_ ((struct mac_display_info *dpyinfo));
+
#define GC_FORE_COLOR(gc) (&(gc)->fore_color)
#define GC_BACK_COLOR(gc) (&(gc)->back_color)
@@ -2389,7 +2391,7 @@ mac_destroy_fringe_bitmap (which)
rarely happens). */
static void
-XTset_terminal_modes ()
+XTset_terminal_modes (struct terminal *t)
{
}
@@ -2397,7 +2399,7 @@ XTset_terminal_modes ()
the windows go away, and suspending requires no action. */
static void
-XTreset_terminal_modes ()
+XTreset_terminal_modes (struct terminal *t)
{
}
@@ -4047,15 +4049,8 @@ x_delete_glyphs (n)
frame. Otherwise clear the selected frame. */
static void
-x_clear_frame ()
+x_clear_frame (struct frame *f)
{
- struct frame *f;
-
- if (updating_frame)
- f = updating_frame;
- else
- f = SELECTED_FRAME ();
-
/* Clearing the frame will erase any cursor, so mark them all as no
longer visible. */
mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
@@ -4573,7 +4568,7 @@ note_mouse_movement (frame, pos)
clear_mouse_face (dpyinfo);
dpyinfo->mouse_face_mouse_frame = 0;
if (!dpyinfo->grabbed)
- rif->define_frame_cursor (frame,
+ FRAME_RIF (frame)->define_frame_cursor (frame,
frame->output_data.mac->nontext_cursor);
}
@@ -12531,6 +12526,7 @@ mac_term_init (display_name, xrm_option, resource_name)
char *resource_name;
{
struct mac_display_info *dpyinfo;
+ struct terminal *terminal;
BLOCK_INPUT;
@@ -12546,6 +12542,13 @@ mac_term_init (display_name, xrm_option, resource_name)
dpyinfo = &one_mac_display_info;
bzero (dpyinfo, sizeof (*dpyinfo));
+ terminal = mac_create_terminal (dpyinfo);
+
+ /* Set the name of the terminal. */
+ terminal->name = (char *) xmalloc (SBYTES (display_name) + 1);
+ strncpy (terminal->name, SDATA (display_name), SBYTES (display_name));
+ terminal->name[SBYTES (display_name)] = 0;
+
#ifdef MAC_OSX
dpyinfo->mac_id_name
= (char *) xmalloc (SCHARS (Vinvocation_name)
@@ -12747,44 +12750,71 @@ static struct redisplay_interface x_redisplay_interface =
mac_shift_glyphs_for_insert
};
-void
+static struct terminal *
+mac_create_terminal (struct mac_display_info *dpyinfo)
+{
+ struct terminal *terminal;
+
+ terminal = create_terminal ();
+
+ terminal->type = output_mac;
+ terminal->display_info.mac = dpyinfo;
+ dpyinfo->terminal = terminal;
+
+ terminal->clear_frame_hook = x_clear_frame;
+ terminal->ins_del_lines_hook = x_ins_del_lines;
+ terminal->delete_glyphs_hook = x_delete_glyphs;
+ terminal->ring_bell_hook = XTring_bell;
+ terminal->reset_terminal_modes_hook = XTreset_terminal_modes;
+ terminal->set_terminal_modes_hook = XTset_terminal_modes;
+ terminal->update_begin_hook = x_update_begin;
+ terminal->update_end_hook = x_update_end;
+ terminal->set_terminal_window_hook = XTset_terminal_window;
+ terminal->read_socket_hook = XTread_socket;
+ terminal->frame_up_to_date_hook = XTframe_up_to_date;
+ terminal->mouse_position_hook = XTmouse_position;
+ terminal->frame_rehighlight_hook = XTframe_rehighlight;
+ terminal->frame_raise_lower_hook = XTframe_raise_lower;
+ /* terminal->fullscreen_hook = XTfullscreen_hook; */
+ terminal->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
+ terminal->condemn_scroll_bars_hook = XTcondemn_scroll_bars;
+ terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar;
+ terminal->judge_scroll_bars_hook = XTjudge_scroll_bars;
+ terminal->delete_frame_hook = x_destroy_window;
+ /* terminal->delete_terminal_hook = x_delete_terminal; */
+
+ terminal->rif = &x_redisplay_interface;
+#if 0
+ TTY_SCROLL_REGION_OK (CURTTY ()) = 1; /* we'll scroll partial frames */
+ TTY_CHAR_INS_DEL_OK (CURTTY ()) = 1;
+ TTY_LINE_INS_DEL_OK (CURTTY ()) = 1; /* we'll just blt 'em */
+ TTY_FAST_CLEAR_END_OF_LINE (CURTTY ()) = 1; /* X does this well */
+ TTY_MEMORY_BELOW_FRAME (CURTTY ()) = 0; /* we don't remember what
+ scrolls off the
+ bottom */
+#else
+ terminal->scroll_region_ok = 1; /* We'll scroll partial frames. */
+ terminal->char_ins_del_ok = 1;
+ terminal->line_ins_del_ok = 1; /* We'll just blt 'em. */
+ terminal->fast_clear_end_of_line = 1; /* X does this well. */
+ terminal->memory_below_frame = 0; /* We don't remember what scrolls
+ off the bottom. */
+
+#endif
+ return terminal;
+}
+
+static void
mac_initialize ()
{
- rif = &x_redisplay_interface;
-
- clear_frame_hook = x_clear_frame;
- ins_del_lines_hook = x_ins_del_lines;
- delete_glyphs_hook = x_delete_glyphs;
- ring_bell_hook = XTring_bell;
- reset_terminal_modes_hook = XTreset_terminal_modes;
- set_terminal_modes_hook = XTset_terminal_modes;
- update_begin_hook = x_update_begin;
- update_end_hook = x_update_end;
- set_terminal_window_hook = XTset_terminal_window;
- read_socket_hook = XTread_socket;
- frame_up_to_date_hook = XTframe_up_to_date;
- mouse_position_hook = XTmouse_position;
- frame_rehighlight_hook = XTframe_rehighlight;
- frame_raise_lower_hook = XTframe_raise_lower;
-
- set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
- condemn_scroll_bars_hook = XTcondemn_scroll_bars;
- redeem_scroll_bar_hook = XTredeem_scroll_bar;
- judge_scroll_bars_hook = XTjudge_scroll_bars;
-
- scroll_region_ok = 1; /* we'll scroll partial frames */
- char_ins_del_ok = 1;
- line_ins_del_ok = 1; /* we'll just blt 'em */
- fast_clear_end_of_line = 1; /* X does this well */
- memory_below_frame = 0; /* we don't remember what scrolls
- off the bottom */
+
baud_rate = 19200;
last_tool_bar_item = -1;
any_help_event_p = 0;
/* Try to use interrupt input; if we can't, then start polling. */
- Fset_input_mode (Qt, Qnil, Qt, Qnil);
+ Fset_input_interrupt_mode (Qt);
BLOCK_INPUT;
@@ -12821,6 +12851,7 @@ mac_initialize ()
#endif
UNBLOCK_INPUT;
+
}
diff --git a/src/macterm.h b/src/macterm.h
index 8a85e714ab5..9df9b1abcdb 100644
--- a/src/macterm.h
+++ b/src/macterm.h
@@ -64,6 +64,9 @@ struct mac_display_info
/* Chain of all mac_display_info structures. */
struct mac_display_info *next;
+ /* The generic display parameters corresponding to this X display. */
+ struct terminal *terminal;
+
/* This is a cons cell of the form (NAME . FONT-LIST-CACHE).
The same cons cell also appears in x_display_name_list. */
Lisp_Object name_list_element;
@@ -358,9 +361,6 @@ typedef struct mac_output mac_output;
#define FRAME_MAC_WINDOW(f) ((f)->output_data.mac->window_desc)
#define FRAME_X_WINDOW(f) ((f)->output_data.mac->window_desc)
-#define FRAME_FOREGROUND_PIXEL(f) ((f)->output_data.x->foreground_pixel)
-#define FRAME_BACKGROUND_PIXEL(f) ((f)->output_data.x->background_pixel)
-
#define FRAME_FONT(f) ((f)->output_data.mac->font)
#define FRAME_FONTSET(f) ((f)->output_data.mac->fontset)
diff --git a/src/makefile.w32-in b/src/makefile.w32-in
index 6611efbe3b2..d1ac66f7771 100644
--- a/src/makefile.w32-in
+++ b/src/makefile.w32-in
@@ -123,7 +123,8 @@ OBJ1 = $(BLD)/abbrev.$(O) \
$(BLD)/ccl.$(O) \
$(BLD)/fontset.$(O) \
$(BLD)/fringe.$(O) \
- $(BLD)/image.$(O)
+ $(BLD)/image.$(O) \
+ $(BLD)/terminal.$(O)
WIN32OBJ = $(BLD)/w32term.$(O) \
$(BLD)/w32xfns.$(O) \
@@ -380,6 +381,8 @@ $(BLD)/callproc.$(O) : \
$(SRC)/process.h \
$(SRC)/syssignal.h \
$(SRC)/systty.h \
+ $(SRC)/frame.h \
+ $(SRC)/termhooks.h \
$(SRC)/w32.h
$(BLD)/casefiddle.$(O) : \
@@ -469,6 +472,8 @@ $(BLD)/coding.$(O) : \
$(SRC)/composite.h \
$(SRC)/dispextern.h \
$(SRC)/intervals.h \
+ $(SRC)/frame.h \
+ $(SRC)/termhooks.h \
$(SRC)/w32bdf.h \
$(SRC)/w32gui.h \
$(SRC)/window.h
@@ -496,7 +501,8 @@ $(BLD)/data.$(O) : \
$(SRC)/frame.h \
$(SRC)/keyboard.h \
$(SRC)/puresize.h \
- $(SRC)/syssignal.h
+ $(SRC)/syssignal.h \
+ $(SRC)/termhooks.h
$(BLD)/dired.$(O) : \
$(SRC)/dired.c \
@@ -699,6 +705,7 @@ $(BLD)/fns.$(O) : \
$(SRC)/keymap.h \
$(SRC)/md5.h \
$(SRC)/systime.h \
+ $(SRC)/termhooks.h \
$(SRC)/w32bdf.h \
$(SRC)/w32gui.h \
$(SRC)/window.h
@@ -715,6 +722,7 @@ $(BLD)/fontset.$(O) : \
$(SRC)/fontset.h \
$(SRC)/frame.h \
$(SRC)/keyboard.h \
+ $(SRC)/termhooks.h \
$(SRC)/w32bdf.h \
$(SRC)/w32gui.h \
$(SRC)/window.h
@@ -734,6 +742,7 @@ $(BLD)/frame.$(O) : \
$(SRC)/frame.h \
$(SRC)/keyboard.h \
$(SRC)/systime.h \
+ $(SRC)/termchar.h \
$(SRC)/termhooks.h \
$(SRC)/w32bdf.h \
$(SRC)/w32gui.h \
@@ -903,6 +912,7 @@ $(BLD)/lread.$(O) : \
$(EMACS_ROOT)/src/config.h \
$(EMACS_ROOT)/nt/inc/sys/file.h \
$(EMACS_ROOT)/src/epaths.h \
+ $(SRC)/blockinput.h \
$(SRC)/buffer.h \
$(SRC)/ccl.h \
$(SRC)/charset.h \
@@ -957,6 +967,7 @@ $(BLD)/minibuf.$(O) : \
$(SRC)/keyboard.h \
$(SRC)/keymap.h \
$(SRC)/syntax.h \
+ $(SRC)/termhooks.h \
$(SRC)/w32bdf.h \
$(SRC)/w32gui.h \
$(SRC)/window.h
@@ -1118,6 +1129,7 @@ $(BLD)/scroll.$(O) : \
$(SRC)/frame.h \
$(SRC)/keyboard.h \
$(SRC)/termchar.h \
+ $(SRC)/termhooks.h \
$(SRC)/w32bdf.h \
$(SRC)/w32gui.h \
$(SRC)/window.h
@@ -1184,6 +1196,7 @@ $(BLD)/sysdep.$(O) : \
$(EMACS_ROOT)/nt/inc/sys/file.h \
$(SRC)/atimer.h \
$(SRC)/blockinput.h \
+ $(SRC)/cm.h \
$(SRC)/dispextern.h \
$(SRC)/frame.h \
$(SRC)/keyboard.h \
@@ -1229,6 +1242,18 @@ $(BLD)/termcap.$(O) : \
$(EMACS_ROOT)/src/config.h \
$(EMACS_ROOT)/nt/inc/sys/file.h
+$(BLD)/terminal.$(O) : \
+ $(SRC)/terminal.c \
+ $(EMACS_ROOT)/src/s/ms-w32.h \
+ $(EMACS_ROOT)/src/m/intel386.h \
+ $(EMACS_ROOT)/src/config.h \
+ $(SRC)/charset.h \
+ $(SRC)/coding.h \
+ $(SRC)/frame.h \
+ $(SRC)/keyboard.h \
+ $(SRC)/termchar.h \
+ $(SRC)/termhooks.h
+
$(BLD)/textprop.$(O) : \
$(SRC)/textprop.c \
$(EMACS_ROOT)/src/s/ms-w32.h \
@@ -1342,6 +1367,8 @@ $(BLD)/xfaces.$(O): \
$(SRC)/intervals.h \
$(SRC)/keyboard.h \
$(SRC)/systime.h \
+ $(SRC)/termchar.h \
+ $(SRC)/termhooks.h \
$(SRC)/w32bdf.h \
$(SRC)/w32gui.h \
$(SRC)/w32term.h \
diff --git a/src/minibuf.c b/src/minibuf.c
index 863528819f8..489c714fcb4 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -35,6 +35,7 @@ Boston, MA 02110-1301, USA. */
#include "syntax.h"
#include "intervals.h"
#include "keymap.h"
+#include "termhooks.h"
extern int quit_char;
@@ -491,7 +492,6 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
if (EQ (Vminibuffer_completing_file_name, Qlambda))
Vminibuffer_completing_file_name = Qnil;
- single_kboard_state ();
#ifdef HAVE_X_WINDOWS
if (display_hourglass_p)
cancel_hourglass ();
@@ -575,6 +575,8 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
if (minibuffer_auto_raise)
Fraise_frame (mini_frame);
+ temporarily_switch_to_single_kboard (XFRAME (mini_frame));
+
/* We have to do this after saving the window configuration
since that is what restores the current buffer. */
@@ -758,8 +760,12 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
XWINDOW (minibuf_window)->cursor.x = 0;
XWINDOW (minibuf_window)->must_be_updated_p = 1;
update_frame (XFRAME (selected_frame), 1, 1);
- if (rif && rif->flush_display)
- rif->flush_display (XFRAME (XWINDOW (minibuf_window)->frame));
+ {
+ struct frame *f = XFRAME (XWINDOW (minibuf_window)->frame);
+ struct redisplay_interface *rif = FRAME_RIF (f);
+ if (rif && rif->flush_display)
+ rif->flush_display (f);
+ }
}
/* Make minibuffer contents into a string. */
diff --git a/src/msdos.c b/src/msdos.c
index ef65597f7e7..fc14be2705c 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -508,8 +508,8 @@ ScreenVisualBell (void)
{
/* This creates an xor-mask that will swap the default fore- and
background colors. */
- do_visible_bell (((the_only_x_display.foreground_pixel
- ^ the_only_x_display.background_pixel)
+ do_visible_bell (((FRAME_FOREGROUND_PIXEL (SELECTED_FRAME ())
+ ^ FRAME_BACKGROUND_PIXEL (SELECTED_FRAME ()))
* 0x11) & 0x7f);
}
#endif
@@ -2531,8 +2531,8 @@ internal_terminal_init ()
initial_screen_colors[0] = initial_screen_colors[1] = -1;
bzero (&the_only_x_display, sizeof the_only_x_display);
- the_only_x_display.background_pixel = 7; /* White */
- the_only_x_display.foreground_pixel = 0; /* Black */
+ FRAME_BACKGROUND_PIXEL (SELECTED_FRAME ()) = 7; /* White */
+ FRAME_FOREGROUND_PIXEL (SELECTED_FRAME ()) = 0; /* Black */
bright_bg ();
colors = getenv ("EMACSCOLORS");
if (colors && strlen (colors) >= 2)
@@ -2543,13 +2543,13 @@ internal_terminal_init ()
else if (isxdigit (colors[0]))
colors[0] -= (isupper (colors[0]) ? 'A' : 'a') - 10;
if (colors[0] >= 0 && colors[0] < 16)
- the_only_x_display.foreground_pixel = colors[0];
+ FRAME_FOREGROUND_PIXEL (SELECTED_FRAME ()) = colors[0];
if (isdigit (colors[1]))
colors[1] -= '0';
else if (isxdigit (colors[1]))
colors[1] -= (isupper (colors[1]) ? 'A' : 'a') - 10;
if (colors[1] >= 0 && colors[1] < 16)
- the_only_x_display.background_pixel = colors[1];
+ FRAME_BACKGROUND_PIXEL (SELECTED_FRAME ()) = colors[1];
}
the_only_x_display.font = (XFontStruct *)1; /* must *not* be zero */
the_only_x_display.display_info.mouse_face_mouse_frame = NULL;
@@ -2583,7 +2583,7 @@ internal_terminal_init ()
set_terminal_modes_hook = IT_set_terminal_modes;
reset_terminal_modes_hook = IT_reset_terminal_modes;
set_terminal_window_hook = IT_set_terminal_window;
- char_ins_del_ok = 0;
+ TTY_CHAR_INS_DEL_OK (CURTTY ()) = 0;
#endif
}
@@ -4880,7 +4880,7 @@ croak (badfunc)
char *badfunc;
{
fprintf (stderr, "%s not yet implemented\r\n", badfunc);
- reset_sys_modes ();
+ reset_all_sys_modes ();
exit (1);
}
diff --git a/src/prefix-args.c b/src/prefix-args.c
index adf2743ba21..16d7b7dba17 100644
--- a/src/prefix-args.c
+++ b/src/prefix-args.c
@@ -53,6 +53,7 @@ Boston, MA 02110-1301, USA. */
#endif
#include <stdio.h>
+#include <stdlib.h>
int
main (argc, argv)
diff --git a/src/print.c b/src/print.c
index cae80d1acfe..cd3d6438bff 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1388,10 +1388,10 @@ print_preprocess (obj)
for (i = 0; i < print_number_index; i++)
if (EQ (PRINT_NUMBER_OBJECT (Vprint_number_table, i), obj))
{
- /* OBJ appears more than once. Let's remember that. */
+ /* OBJ appears more than once. Let's remember that. */
PRINT_NUMBER_STATUS (Vprint_number_table, i) = Qt;
print_depth--;
- return;
+ return;
}
/* OBJ is not yet recorded. Let's add to the table. */
diff --git a/src/process.c b/src/process.c
index 4515b7a2c86..dfb97b8d615 100644
--- a/src/process.c
+++ b/src/process.c
@@ -130,11 +130,11 @@ Boston, MA 02110-1301, USA. */
#include "charset.h"
#include "coding.h"
#include "process.h"
+#include "frame.h"
#include "termhooks.h"
#include "termopts.h"
#include "commands.h"
#include "keyboard.h"
-#include "frame.h"
#include "blockinput.h"
#include "dispextern.h"
#include "composite.h"
@@ -3157,6 +3157,10 @@ usage: (make-network-process &rest ARGS) */)
open_socket:
+#ifdef __ultrix__
+ /* Previously this was compiled unconditionally, but that seems
+ unnecessary on modern systems, and `unrequest_sigio' was a noop
+ under X anyway. --lorentey */
/* Kernel bugs (on Ultrix at least) cause lossage (not just EINTR)
when connect is interrupted. So let's not let it get interrupted.
Note we do not turn off polling, because polling is only used
@@ -3173,6 +3177,7 @@ usage: (make-network-process &rest ARGS) */)
record_unwind_protect (unwind_request_sigio, Qnil);
unrequest_sigio ();
}
+#endif
/* Do this in case we never enter the for-loop below. */
count1 = SPECPDL_INDEX ();
@@ -6956,20 +6961,12 @@ DEFUN ("process-filter-multibyte-p", Fprocess_filter_multibyte_p,
-/* The first time this is called, assume keyboard input comes from DESC
- instead of from where we used to expect it.
- Subsequent calls mean assume input keyboard can come from DESC
- in addition to other places. */
-
-static int add_keyboard_wait_descriptor_called_flag;
+/* Add DESC to the set of keyboard input descriptors. */
void
add_keyboard_wait_descriptor (desc)
int desc;
{
- if (! add_keyboard_wait_descriptor_called_flag)
- FD_CLR (0, &input_wait_mask);
- add_keyboard_wait_descriptor_called_flag = 1;
FD_SET (desc, &input_wait_mask);
FD_SET (desc, &non_process_wait_mask);
if (desc > max_keyboard_desc)
@@ -7075,7 +7072,12 @@ init_process ()
process_output_skip = 0;
#endif
+ /* Don't do this, it caused infinite select loops. The display
+ method should call add_keyboard_wait_descriptor on stdin if it
+ needs that. */
+#if 0
FD_SET (0, &input_wait_mask);
+#endif
Vprocess_alist = Qnil;
#ifdef SIGCHLD
diff --git a/src/puresize.h b/src/puresize.h
index 8ce51dbfd8b..5f72dfb04cc 100644
--- a/src/puresize.h
+++ b/src/puresize.h
@@ -43,7 +43,7 @@ Boston, MA 02110-1301, USA. */
#endif
#ifndef BASE_PURESIZE
-#define BASE_PURESIZE (1140000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA)
+#define BASE_PURESIZE (1161000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA)
#endif
/* Increase BASE_PURESIZE by a ratio depending on the machine's word size. */
diff --git a/src/s/darwin.h b/src/s/darwin.h
index 183aecaf5d8..a2a3d862f80 100644
--- a/src/s/darwin.h
+++ b/src/s/darwin.h
@@ -50,6 +50,8 @@ Boston, MA 02110-1301, USA. */
#ifdef MAC_OSX
#ifdef HAVE_CARBON
#define MAC_OS
+/* We need a little extra space, see ../../lisp/loadup.el. */
+#define SYSTEM_PURESIZE_EXTRA 30000
#endif
#endif
diff --git a/src/s/ms-w32.h b/src/s/ms-w32.h
index a5898410b3b..e4f5cc119e0 100644
--- a/src/s/ms-w32.h
+++ b/src/s/ms-w32.h
@@ -480,7 +480,7 @@ extern char *get_emacs_configuration_options (void);
/* We need a little extra space, see ../../lisp/loadup.el.
The number below comes from 23923 bytes worth (as of 2006-04)
of w32-specific files loaded by loadup.el, plus 1K spare. */
-#define SYSTEM_PURESIZE_EXTRA 25000
+#define SYSTEM_PURESIZE_EXTRA 50000
/* For unexec to work on Alpha systems, we need to put Emacs'
initialized data into a separate section from the CRT initialized
diff --git a/src/scroll.c b/src/scroll.c
index 48a40fe23d2..5a59c69003e 100644
--- a/src/scroll.c
+++ b/src/scroll.c
@@ -23,12 +23,13 @@ Boston, MA 02110-1301, USA. */
#include <config.h>
#include <stdio.h>
#include <string.h>
-#include "termchar.h"
#include "lisp.h"
+#include "termchar.h"
#include "dispextern.h"
#include "keyboard.h"
#include "frame.h"
#include "window.h"
+#include "termhooks.h"
/* All costs measured in characters.
So no cost can exceed the area of a frame, measured in characters.
@@ -58,10 +59,12 @@ struct matrix_elt
unsigned char writecount;
};
-static void do_direct_scrolling P_ ((struct glyph_matrix *,
+static void do_direct_scrolling P_ ((struct frame *,
+ struct glyph_matrix *,
struct matrix_elt *,
int, int));
-static void do_scrolling P_ ((struct glyph_matrix *,
+static void do_scrolling P_ ((struct frame *,
+ struct glyph_matrix *,
struct matrix_elt *,
int, int));
@@ -101,7 +104,8 @@ calculate_scrolling (frame, matrix, window_size, lines_below,
register struct matrix_elt *p, *p1;
register int cost, cost1;
- int lines_moved = window_size + (scroll_region_ok ? 0 : lines_below);
+ int lines_moved = window_size
+ + (FRAME_SCROLL_REGION_OK (frame) ? 0 : lines_below);
/* first_insert_cost[I] is the cost of doing the first insert-line
at the i'th line of the lines we are considering,
where I is origin 1 (as it is below). */
@@ -241,7 +245,8 @@ calculate_scrolling (frame, matrix, window_size, lines_below,
of lines. */
static void
-do_scrolling (current_matrix, matrix, window_size, unchanged_at_top)
+do_scrolling (frame, current_matrix, matrix, window_size, unchanged_at_top)
+ struct frame *frame;
struct glyph_matrix *current_matrix;
struct matrix_elt *matrix;
int window_size;
@@ -308,12 +313,12 @@ do_scrolling (current_matrix, matrix, window_size, unchanged_at_top)
/* Set the terminal window, if not done already. */
if (! terminal_window_p)
{
- set_terminal_window (window_size + unchanged_at_top);
+ set_terminal_window (frame, window_size + unchanged_at_top);
terminal_window_p = 1;
}
/* Delete lines on the terminal. */
- ins_del_lines (j + unchanged_at_top, - p->deletecount);
+ ins_del_lines (frame, j + unchanged_at_top, - p->deletecount);
}
else
{
@@ -338,7 +343,7 @@ do_scrolling (current_matrix, matrix, window_size, unchanged_at_top)
/* Set the terminal window if not yet done. */
if (!terminal_window_p)
{
- set_terminal_window (window_size + unchanged_at_top);
+ set_terminal_window (frame, window_size + unchanged_at_top);
terminal_window_p = 1;
}
@@ -347,7 +352,7 @@ do_scrolling (current_matrix, matrix, window_size, unchanged_at_top)
--queue;
/* Do the deletion on the terminal. */
- ins_del_lines (queue->pos, queue->count);
+ ins_del_lines (frame, queue->pos, queue->count);
/* All lines in the range deleted become empty in the glyph
matrix. Assign to them glyph rows that are not retained.
@@ -380,7 +385,7 @@ do_scrolling (current_matrix, matrix, window_size, unchanged_at_top)
CHECK_MATRIX (current_matrix);
if (terminal_window_p)
- set_terminal_window (0);
+ set_terminal_window (frame, 0);
}
@@ -467,7 +472,8 @@ calculate_direct_scrolling (frame, matrix, window_size, lines_below,
/* Overhead of setting the scroll window, plus the extra cost
cost of scrolling by a distance of one. The extra cost is
added once for consistency with the cost vectors */
- scroll_overhead = scroll_region_cost + extra_cost;
+ scroll_overhead
+ = FRAME_SCROLL_REGION_COST (frame) + extra_cost;
/* initialize the top left corner of the matrix */
matrix->writecost = 0;
@@ -650,8 +656,9 @@ calculate_direct_scrolling (frame, matrix, window_size, lines_below,
the cost matrix for this approach is constructed. */
static void
-do_direct_scrolling (current_matrix, cost_matrix, window_size,
- unchanged_at_top)
+do_direct_scrolling (frame, current_matrix, cost_matrix,
+ window_size, unchanged_at_top)
+ struct frame *frame;
struct glyph_matrix *current_matrix;
struct matrix_elt *cost_matrix;
int window_size;
@@ -742,9 +749,9 @@ do_direct_scrolling (current_matrix, cost_matrix, window_size,
if (i > j)
{
/* Immediately insert lines */
- set_terminal_window (i + unchanged_at_top);
+ set_terminal_window (frame, i + unchanged_at_top);
terminal_window_p = 1;
- ins_del_lines (j - n_to_write + unchanged_at_top, i - j);
+ ins_del_lines (frame, j - n_to_write + unchanged_at_top, i - j);
}
else if (i < j)
{
@@ -774,9 +781,9 @@ do_direct_scrolling (current_matrix, cost_matrix, window_size,
--queue;
if (queue->count)
{
- set_terminal_window (queue->window);
+ set_terminal_window (frame, queue->window);
terminal_window_p = 1;
- ins_del_lines (queue->pos, queue->count);
+ ins_del_lines (frame, queue->pos, queue->count);
}
else
{
@@ -799,7 +806,7 @@ do_direct_scrolling (current_matrix, cost_matrix, window_size,
copy_from, retained_p);
if (terminal_window_p)
- set_terminal_window (0);
+ set_terminal_window (frame, 0);
}
@@ -819,13 +826,13 @@ scrolling_1 (frame, window_size, unchanged_at_top, unchanged_at_bottom,
matrix = ((struct matrix_elt *)
alloca ((window_size + 1) * (window_size + 1) * sizeof *matrix));
- if (scroll_region_ok)
+ if (FRAME_SCROLL_REGION_OK (frame))
{
calculate_direct_scrolling (frame, matrix, window_size,
unchanged_at_bottom,
draw_cost, old_draw_cost,
old_hash, new_hash, free_at_end);
- do_direct_scrolling (frame->current_matrix,
+ do_direct_scrolling (frame, frame->current_matrix,
matrix, window_size, unchanged_at_top);
}
else
@@ -833,7 +840,8 @@ scrolling_1 (frame, window_size, unchanged_at_top, unchanged_at_bottom,
calculate_scrolling (frame, matrix, window_size, unchanged_at_bottom,
draw_cost, old_hash, new_hash,
free_at_end);
- do_scrolling (frame->current_matrix, matrix, window_size,
+ do_scrolling (frame,
+ frame->current_matrix, matrix, window_size,
unchanged_at_top);
}
}
@@ -915,7 +923,7 @@ scroll_cost (frame, from, to, amount)
if (amount == 0)
return 0;
- if (! scroll_region_ok)
+ if (! FRAME_SCROLL_REGION_OK (frame))
limit = height;
else if (amount > 0)
limit += amount;
diff --git a/src/sysdep.c b/src/sysdep.c
index f2170dabed7..ff7a4f5f42c 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -46,6 +46,8 @@ extern void srandom P_ ((unsigned int));
#endif
#endif
+#include "sysselect.h"
+
#include "blockinput.h"
#ifdef MAC_OS8
@@ -176,6 +178,7 @@ extern int quit_char;
#include "termopts.h"
#include "dispextern.h"
#include "process.h"
+#include "cm.h" /* for reset_sys_modes */
#ifdef WINDOWSNT
#include <direct.h>
@@ -239,16 +242,11 @@ static int baud_convert[] =
int emacs_ospeed;
-/* The file descriptor for Emacs's input terminal.
- Under Unix, this is normally zero except when using X;
- under VMS, we place the input channel number here. */
-int input_fd;
-
void croak P_ ((char *)) NO_RETURN;
#ifdef AIXHFT
-void hft_init ();
-void hft_reset ();
+void hft_init P_ ((struct tty_display_info *));
+void hft_reset P_ ((struct tty_display_info *));
#endif
/* Temporary used by `sigblock' when defined in terms of signprocmask. */
@@ -331,16 +329,7 @@ get_current_dir_name ()
#endif
-/* Specify a different file descriptor for further input operations. */
-
-void
-change_input_fd (fd)
- int fd;
-{
- input_fd = fd;
-}
-
-/* Discard pending input on descriptor input_fd. */
+/* Discard pending input on all input descriptors. */
void
discard_tty_input ()
@@ -351,54 +340,61 @@ discard_tty_input ()
if (noninteractive)
return;
- /* Discarding input is not safe when the input could contain
- replies from the X server. So don't do it. */
- if (read_socket_hook)
- return;
-
#ifdef VMS
end_kbd_input ();
- SYS$QIOW (0, input_fd, IO$_READVBLK|IO$M_PURGE, input_iosb, 0, 0,
+ SYS$QIOW (0, fileno (CURTTY()->input), IO$_READVBLK|IO$M_PURGE, input_iosb, 0, 0,
&buf.main, 0, 0, terminator_mask, 0, 0);
queue_kbd_input ();
#else /* not VMS */
#ifdef APOLLO
{
- int zero = 0;
- ioctl (input_fd, TIOCFLUSH, &zero);
+ struct tty_display_info *tty;
+ for (tty = tty_list; tty; tty = tty->next)
+ {
+ int zero = 0;
+ if (tty->input)
+ ioctl (fileno (tty->input), TIOCFLUSH, &zero);
+ }
}
#else /* not Apollo */
#ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
while (dos_keyread () != -1)
;
#else /* not MSDOS */
- EMACS_GET_TTY (input_fd, &buf);
- EMACS_SET_TTY (input_fd, &buf, 0);
+ {
+ struct tty_display_info *tty;
+ for (tty = tty_list; tty; tty = tty->next)
+ {
+ if (tty->input) /* Is the device suspended? */
+ {
+ EMACS_GET_TTY (fileno (tty->input), &buf);
+ EMACS_SET_TTY (fileno (tty->input), &buf, 0);
+ }
+ }
+ }
#endif /* not MSDOS */
#endif /* not Apollo */
#endif /* not VMS */
#endif /* not WINDOWSNT */
}
+
#ifdef SIGTSTP
/* Arrange for character C to be read as the next input from
- the terminal. */
+ the terminal.
+ XXX What if we have multiple ttys?
+*/
void
-#ifdef PROTOTYPES
stuff_char (char c)
-#else
-stuff_char (c)
- char c;
-#endif
{
- if (read_socket_hook)
+ if (! FRAME_TERMCAP_P (SELECTED_FRAME ()))
return;
/* Should perhaps error if in batch mode */
#ifdef TIOCSTI
- ioctl (input_fd, TIOCSTI, &c);
+ ioctl (fileno (CURTTY()->input), TIOCSTI, &c);
#else /* no TIOCSTI */
error ("Cannot stuff terminal input characters in this version of Unix");
#endif /* no TIOCSTI */
@@ -407,7 +403,7 @@ stuff_char (c)
#endif /* SIGTSTP */
void
-init_baud_rate ()
+init_baud_rate (int fd)
{
if (noninteractive)
emacs_ospeed = 0;
@@ -422,7 +418,7 @@ init_baud_rate ()
#ifdef VMS
struct sensemode sg;
- SYS$QIOW (0, input_fd, IO$_SENSEMODE, &sg, 0, 0,
+ SYS$QIOW (0, fd, IO$_SENSEMODE, &sg, 0, 0,
&sg.class, 12, 0, 0, 0, 0 );
emacs_ospeed = sg.xmit_baud;
#else /* not VMS */
@@ -430,7 +426,7 @@ init_baud_rate ()
struct termios sg;
sg.c_cflag = B9600;
- tcgetattr (input_fd, &sg);
+ tcgetattr (fd, &sg);
emacs_ospeed = cfgetospeed (&sg);
#if defined (USE_GETOBAUD) && defined (getobaud)
/* m88k-motorola-sysv3 needs this (ghazi@noc.rutgers.edu) 9/1/94. */
@@ -443,16 +439,16 @@ init_baud_rate ()
sg.c_cflag = B9600;
#ifdef HAVE_TCATTR
- tcgetattr (input_fd, &sg);
+ tcgetattr (fd, &sg);
#else
- ioctl (input_fd, TCGETA, &sg);
+ ioctl (fd, TCGETA, &sg);
#endif
emacs_ospeed = sg.c_cflag & CBAUD;
#else /* neither VMS nor TERMIOS nor TERMIO */
struct sgttyb sg;
sg.sg_ospeed = B9600;
- if (ioctl (input_fd, TIOCGETP, &sg) < 0)
+ if (ioctl (fd, TIOCGETP, &sg) < 0)
abort ();
emacs_ospeed = sg.sg_ospeed;
#endif /* not HAVE_TERMIO */
@@ -468,6 +464,7 @@ init_baud_rate ()
baud_rate = 1200;
}
+
/*ARGSUSED*/
void
set_exclusive_use (fd)
@@ -729,7 +726,7 @@ child_setup_tty (out)
#ifdef BSD4_1
if (interrupt_input)
- reset_sigio ();
+ reset_sigio (0);
#endif /* BSD4_1 */
#ifdef RTU
{
@@ -986,53 +983,86 @@ restore_signal_handlers (saved_handlers)
}
}
+#ifndef SIGIO
+/* If SIGIO is broken, don't do anything. */
+void
+init_sigio (int fd)
+{
+}
+
+void
+reset_sigio (int fd)
+{
+}
+
+void
+request_sigio (void)
+{
+}
+
+void
+unrequest_sigio (void)
+{
+}
+
+#else
#ifdef F_SETFL
-int old_fcntl_flags;
+int old_fcntl_flags[MAXDESC];
void
init_sigio (fd)
int fd;
{
#ifdef FASYNC
- old_fcntl_flags = fcntl (fd, F_GETFL, 0) & ~FASYNC;
- fcntl (fd, F_SETFL, old_fcntl_flags | FASYNC);
+ old_fcntl_flags[fd] = fcntl (fd, F_GETFL, 0) & ~FASYNC;
+ fcntl (fd, F_SETFL, old_fcntl_flags[fd] | FASYNC);
#endif
interrupts_deferred = 0;
}
void
-reset_sigio ()
+reset_sigio (fd)
+ int fd;
{
- unrequest_sigio ();
+#ifdef FASYNC
+ fcntl (fd, F_SETFL, old_fcntl_flags[fd]);
+#endif
}
#ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */
+/* XXX Uhm, FASYNC is not used anymore here. */
+/* XXX Yeah, but you need it for SIGIO, don't you? */
void
request_sigio ()
{
- if (noninteractive || read_socket_hook)
+ if (noninteractive)
return;
#ifdef SIGWINCH
sigunblock (sigmask (SIGWINCH));
#endif
- fcntl (input_fd, F_SETFL, old_fcntl_flags | FASYNC);
+ sigunblock (sigmask (SIGIO));
interrupts_deferred = 0;
}
void
-unrequest_sigio ()
-{
- if (noninteractive || read_socket_hook)
+unrequest_sigio (void)
+{
+ if (noninteractive)
return;
+#if 0 /* XXX What's wrong with blocking SIGIO under X? */
+ if (x_display_list)
+ return;
+#endif
+
#ifdef SIGWINCH
sigblock (sigmask (SIGWINCH));
#endif
- fcntl (input_fd, F_SETFL, old_fcntl_flags);
+ sigblock (sigmask (SIGIO));
interrupts_deferred = 1;
}
@@ -1047,7 +1077,8 @@ request_sigio ()
if (noninteractive || read_socket_hook)
return;
- ioctl (input_fd, FIOASYNC, &on);
+ /* XXX CURTTY() is bogus here. */
+ ioctl (fileno (CURTTY ()->input), FIOASYNC, &on);
interrupts_deferred = 0;
}
@@ -1059,7 +1090,8 @@ unrequest_sigio ()
if (noninteractive || read_socket_hook)
return;
- ioctl (input_fd, FIOASYNC, &off);
+ /* XXX CURTTY() is bogus here. */
+ ioctl (fileno (CURTTY ()->input), FIOASYNC, &off);
interrupts_deferred = 1;
}
@@ -1080,7 +1112,7 @@ request_sigio ()
sigemptyset (&st);
sigaddset (&st, SIGIO);
- ioctl (input_fd, FIOASYNC, &on);
+ ioctl (0, FIOASYNC, &on); /* XXX This fails for multiple ttys. */
interrupts_deferred = 0;
sigprocmask (SIG_UNBLOCK, &st, (sigset_t *)0);
}
@@ -1093,7 +1125,7 @@ unrequest_sigio ()
if (noninteractive || read_socket_hook)
return;
- ioctl (input_fd, FIOASYNC, &off);
+ ioctl (0, FIOASYNC, &off); /* XXX This fails for multiple ttys. */
interrupts_deferred = 1;
}
@@ -1123,6 +1155,7 @@ unrequest_sigio ()
#endif /* STRIDE */
#endif /* FASYNC */
#endif /* F_SETFL */
+#endif /* SIGIO */
/* Saving and restoring the process group of Emacs's terminal. */
@@ -1145,30 +1178,39 @@ unrequest_sigio ()
the tty's pgroup just like any other terminal setting. If
inherited_group was not the tty's pgroup, then we'll get a
SIGTTmumble when we try to change the tty's pgroup, and a CONT if
- it goes foreground in the future, which is what should happen. */
+ it goes foreground in the future, which is what should happen.
+
+ This variable is initialized in emacs.c. */
int inherited_pgroup;
-/* Split off the foreground process group to Emacs alone.
- When we are in the foreground, but not started in our own process
- group, redirect the TTY to point to our own process group. We need
- to be in our own process group to receive SIGIO properly. */
+/* Split off the foreground process group to Emacs alone. When we are
+ in the foreground, but not started in our own process group,
+ redirect the tty device handle FD to point to our own process
+ group. We need to be in our own process group to receive SIGIO
+ properly. */
void
-narrow_foreground_group ()
+narrow_foreground_group (int fd)
{
int me = getpid ();
setpgrp (0, inherited_pgroup);
+#if 0
+ /* XXX inherited_pgroup should not be zero here, but GTK seems to
+ mess this up. */
+ if (! inherited_pgroup)
+ abort (); /* Should not happen. */
+#endif
if (inherited_pgroup != me)
- EMACS_SET_TTY_PGRP (input_fd, &me);
+ EMACS_SET_TTY_PGRP (fd, &me); /* XXX This only works on the controlling tty. */
setpgrp (0, me);
}
/* Set the tty to our original foreground group. */
void
-widen_foreground_group ()
+widen_foreground_group (int fd)
{
if (inherited_pgroup != getpid ())
- EMACS_SET_TTY_PGRP (input_fd, &inherited_pgroup);
+ EMACS_SET_TTY_PGRP (fd, &inherited_pgroup);
setpgrp (0, inherited_pgroup);
}
@@ -1326,14 +1368,6 @@ emacs_set_tty (fd, settings, flushp)
}
-/* The initial tty mode bits */
-struct emacs_tty old_tty;
-
-/* 1 if we have been through init_sys_modes. */
-int term_initted;
-
-/* 1 if outer tty status has been recorded. */
-int old_tty_valid;
#ifdef BSD4_1
/* BSD 4.1 needs to keep track of the lmode bits in order to start
@@ -1343,7 +1377,7 @@ int lmode;
#ifndef F_SETOWN_BUG
#ifdef F_SETOWN
-int old_fcntl_owner;
+int old_fcntl_owner[MAXDESC];
#endif /* F_SETOWN */
#endif /* F_SETOWN_BUG */
@@ -1368,8 +1402,22 @@ static struct ltchars new_ltchars = {-1,-1,-1,-1,-1,-1};
static struct tchars new_tchars = {-1,-1,-1,-1,-1,-1};
#endif
+/* Initialize the terminal mode on all tty devices that are currently
+ open. */
+
void
-init_sys_modes ()
+init_all_sys_modes (void)
+{
+ struct tty_display_info *tty;
+ for (tty = tty_list; tty; tty = tty->next)
+ init_sys_modes (tty);
+}
+
+/* Initialize the terminal mode on the given tty device. */
+
+void
+init_sys_modes (tty_out)
+ struct tty_display_info *tty_out;
{
struct emacs_tty tty;
@@ -1385,6 +1433,9 @@ init_sys_modes ()
if (noninteractive)
return;
+ if (!tty_out->output)
+ return; /* The tty is suspended. */
+
#ifdef VMS
if (!input_ef)
input_ef = get_kbd_event_flag ();
@@ -1415,266 +1466,287 @@ init_sys_modes ()
#ifndef VMS4_4
sys_access_reinit ();
#endif
-#endif /* not VMS */
+#endif /* VMS */
#ifdef BSD_PGRPS
- if (! read_socket_hook && EQ (Vwindow_system, Qnil))
- narrow_foreground_group ();
+#if 0
+ /* read_socket_hook is not global anymore. I think doing this
+ unconditionally will not cause any problems. */
+ if (! read_socket_hook && EQ (Vinitial_window_system, Qnil))
#endif
-
-#ifdef HAVE_WINDOW_SYSTEM
- /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
- needs the initialization code below. */
- if (!read_socket_hook && EQ (Vwindow_system, Qnil))
+ narrow_foreground_group (fileno (tty_out->input));
#endif
- {
- EMACS_GET_TTY (input_fd, &old_tty);
- old_tty_valid = 1;
+ if (! tty_out->old_tty)
+ tty_out->old_tty = (struct emacs_tty *) xmalloc (sizeof (struct emacs_tty));
+
+ EMACS_GET_TTY (fileno (tty_out->input), tty_out->old_tty);
- tty = old_tty;
+ tty = *tty_out->old_tty;
#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
- XSETINT (Vtty_erase_char, old_tty.main.c_cc[VERASE]);
+ XSETINT (Vtty_erase_char, tty.main.c_cc[VERASE]);
#ifdef DGUX
- /* This allows meta to be sent on 8th bit. */
- tty.main.c_iflag &= ~INPCK; /* don't check input for parity */
+ /* This allows meta to be sent on 8th bit. */
+ tty.main.c_iflag &= ~INPCK; /* don't check input for parity */
#endif
- tty.main.c_iflag |= (IGNBRK); /* Ignore break condition */
- tty.main.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */
+ tty.main.c_iflag |= (IGNBRK); /* Ignore break condition */
+ tty.main.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */
#ifdef INLCR /* I'm just being cautious,
since I can't check how widespread INLCR is--rms. */
- tty.main.c_iflag &= ~INLCR; /* Disable map of NL to CR on input */
+ tty.main.c_iflag &= ~INLCR; /* Disable map of NL to CR on input */
#endif
#ifdef ISTRIP
- tty.main.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
+ tty.main.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
#endif
- tty.main.c_lflag &= ~ECHO; /* Disable echo */
- tty.main.c_lflag &= ~ICANON; /* Disable erase/kill processing */
+ tty.main.c_lflag &= ~ECHO; /* Disable echo */
+ tty.main.c_lflag &= ~ICANON; /* Disable erase/kill processing */
#ifdef IEXTEN
- tty.main.c_lflag &= ~IEXTEN; /* Disable other editing characters. */
+ tty.main.c_lflag &= ~IEXTEN; /* Disable other editing characters. */
#endif
- tty.main.c_lflag |= ISIG; /* Enable signals */
- if (flow_control)
- {
- tty.main.c_iflag |= IXON; /* Enable start/stop output control */
+ tty.main.c_lflag |= ISIG; /* Enable signals */
+ if (tty_out->flow_control)
+ {
+ tty.main.c_iflag |= IXON; /* Enable start/stop output control */
#ifdef IXANY
- tty.main.c_iflag &= ~IXANY;
+ tty.main.c_iflag &= ~IXANY;
#endif /* IXANY */
- }
- else
- tty.main.c_iflag &= ~IXON; /* Disable start/stop output control */
- tty.main.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL
- on output */
- tty.main.c_oflag &= ~TAB3; /* Disable tab expansion */
+ }
+ else
+ tty.main.c_iflag &= ~IXON; /* Disable start/stop output control */
+ tty.main.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL
+ on output */
+ tty.main.c_oflag &= ~TAB3; /* Disable tab expansion */
#ifdef CS8
- if (meta_key)
- {
- tty.main.c_cflag |= CS8; /* allow 8th bit on input */
- tty.main.c_cflag &= ~PARENB;/* Don't check parity */
- }
+ if (tty_out->meta_key)
+ {
+ tty.main.c_cflag |= CS8; /* allow 8th bit on input */
+ tty.main.c_cflag &= ~PARENB;/* Don't check parity */
+ }
#endif
+ if (tty_out->input == stdin)
+ {
tty.main.c_cc[VINTR] = quit_char; /* C-g (usually) gives SIGINT */
/* Set up C-g for both SIGQUIT and SIGINT.
- We don't know which we will get, but we handle both alike
- so which one it really gives us does not matter. */
+ We don't know which we will get, but we handle both alike
+ so which one it really gives us does not matter. */
tty.main.c_cc[VQUIT] = quit_char;
- tty.main.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */
- tty.main.c_cc[VTIME] = 0; /* no matter how long that takes. */
+ }
+ else
+ {
+ /* We normally don't get interrupt or quit signals from tty
+ devices other than our controlling terminal; therefore,
+ we must handle C-g as normal input. Unfortunately, this
+ means that the interrupt and quit feature must be
+ disabled on secondary ttys, or we would not even see the
+ keypress.
+
+ Note that even though emacsclient could have special code
+ to pass SIGINT to Emacs, we should _not_ enable
+ interrupt/quit keys for emacsclient frames. This means
+ that we can't break out of loops in C code from a
+ secondary tty frame, but we can always decide what
+ display the C-g came from, which is more important from a
+ usability point of view. (Consider the case when two
+ people work together using the same Emacs instance.) */
+ tty.main.c_cc[VINTR] = CDISABLE;
+ tty.main.c_cc[VQUIT] = CDISABLE;
+ }
+ tty.main.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */
+ tty.main.c_cc[VTIME] = 0; /* no matter how long that takes. */
#ifdef VSWTCH
- tty.main.c_cc[VSWTCH] = CDISABLE; /* Turn off shell layering use
+ tty.main.c_cc[VSWTCH] = CDISABLE; /* Turn off shell layering use
of C-z */
#endif /* VSWTCH */
-
+
#if defined (mips) || defined (HAVE_TCATTR)
#ifdef VSUSP
- tty.main.c_cc[VSUSP] = CDISABLE; /* Turn off mips handling of C-z. */
+ tty.main.c_cc[VSUSP] = CDISABLE; /* Turn off mips handling of C-z. */
#endif /* VSUSP */
#ifdef V_DSUSP
- tty.main.c_cc[V_DSUSP] = CDISABLE; /* Turn off mips handling of C-y. */
+ tty.main.c_cc[V_DSUSP] = CDISABLE; /* Turn off mips handling of C-y. */
#endif /* V_DSUSP */
#ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
- tty.main.c_cc[VDSUSP] = CDISABLE;
+ tty.main.c_cc[VDSUSP] = CDISABLE;
#endif /* VDSUSP */
#ifdef VLNEXT
- tty.main.c_cc[VLNEXT] = CDISABLE;
+ tty.main.c_cc[VLNEXT] = CDISABLE;
#endif /* VLNEXT */
#ifdef VREPRINT
- tty.main.c_cc[VREPRINT] = CDISABLE;
+ tty.main.c_cc[VREPRINT] = CDISABLE;
#endif /* VREPRINT */
#ifdef VWERASE
- tty.main.c_cc[VWERASE] = CDISABLE;
+ tty.main.c_cc[VWERASE] = CDISABLE;
#endif /* VWERASE */
#ifdef VDISCARD
- tty.main.c_cc[VDISCARD] = CDISABLE;
+ tty.main.c_cc[VDISCARD] = CDISABLE;
#endif /* VDISCARD */
- if (flow_control)
- {
+ if (tty_out->flow_control)
+ {
#ifdef VSTART
- tty.main.c_cc[VSTART] = '\021';
+ tty.main.c_cc[VSTART] = '\021';
#endif /* VSTART */
#ifdef VSTOP
- tty.main.c_cc[VSTOP] = '\023';
+ tty.main.c_cc[VSTOP] = '\023';
#endif /* VSTOP */
- }
- else
- {
+ }
+ else
+ {
#ifdef VSTART
- tty.main.c_cc[VSTART] = CDISABLE;
+ tty.main.c_cc[VSTART] = CDISABLE;
#endif /* VSTART */
#ifdef VSTOP
- tty.main.c_cc[VSTOP] = CDISABLE;
+ tty.main.c_cc[VSTOP] = CDISABLE;
#endif /* VSTOP */
- }
+ }
#endif /* mips or HAVE_TCATTR */
#ifdef SET_LINE_DISCIPLINE
- /* Need to explicitly request TERMIODISC line discipline or
- Ultrix's termios does not work correctly. */
- tty.main.c_line = SET_LINE_DISCIPLINE;
+ /* Need to explicitly request TERMIODISC line discipline or
+ Ultrix's termios does not work correctly. */
+ tty.main.c_line = SET_LINE_DISCIPLINE;
#endif
#ifdef AIX
#ifndef IBMR2AIX
- /* AIX enhanced edit loses NULs, so disable it. */
- tty.main.c_line = 0;
- tty.main.c_iflag &= ~ASCEDIT;
+ /* AIX enhanced edit loses NULs, so disable it. */
+ tty.main.c_line = 0;
+ tty.main.c_iflag &= ~ASCEDIT;
#else
- tty.main.c_cc[VSTRT] = CDISABLE;
- tty.main.c_cc[VSTOP] = CDISABLE;
- tty.main.c_cc[VSUSP] = CDISABLE;
- tty.main.c_cc[VDSUSP] = CDISABLE;
+ tty.main.c_cc[VSTRT] = CDISABLE;
+ tty.main.c_cc[VSTOP] = CDISABLE;
+ tty.main.c_cc[VSUSP] = CDISABLE;
+ tty.main.c_cc[VDSUSP] = CDISABLE;
#endif /* IBMR2AIX */
- if (flow_control)
- {
+ if (tty_out->flow_control)
+ {
#ifdef VSTART
- tty.main.c_cc[VSTART] = '\021';
+ tty.main.c_cc[VSTART] = '\021';
#endif /* VSTART */
#ifdef VSTOP
- tty.main.c_cc[VSTOP] = '\023';
+ tty.main.c_cc[VSTOP] = '\023';
#endif /* VSTOP */
- }
- /* Also, PTY overloads NUL and BREAK.
- don't ignore break, but don't signal either, so it looks like NUL.
- This really serves a purpose only if running in an XTERM window
- or via TELNET or the like, but does no harm elsewhere. */
- tty.main.c_iflag &= ~IGNBRK;
- tty.main.c_iflag &= ~BRKINT;
+ }
+ /* Also, PTY overloads NUL and BREAK.
+ don't ignore break, but don't signal either, so it looks like NUL.
+ This really serves a purpose only if running in an XTERM window
+ or via TELNET or the like, but does no harm elsewhere. */
+ tty.main.c_iflag &= ~IGNBRK;
+ tty.main.c_iflag &= ~BRKINT;
#endif
#else /* if not HAVE_TERMIO */
#ifdef VMS
- tty.main.tt_char |= TT$M_NOECHO;
- if (meta_key)
- tty.main.tt_char |= TT$M_EIGHTBIT;
- if (flow_control)
- tty.main.tt_char |= TT$M_TTSYNC;
- else
- tty.main.tt_char &= ~TT$M_TTSYNC;
- tty.main.tt2_char |= TT2$M_PASTHRU | TT2$M_XON;
+ tty.main.tt_char |= TT$M_NOECHO;
+ if (meta_key)
+ tty.main.tt_char |= TT$M_EIGHTBIT;
+ if (tty_out->flow_control)
+ tty.main.tt_char |= TT$M_TTSYNC;
+ else
+ tty.main.tt_char &= ~TT$M_TTSYNC;
+ tty.main.tt2_char |= TT2$M_PASTHRU | TT2$M_XON;
#else /* not VMS (BSD, that is) */
#ifndef DOS_NT
- XSETINT (Vtty_erase_char, tty.main.sg_erase);
- tty.main.sg_flags &= ~(ECHO | CRMOD | XTABS);
- if (meta_key)
- tty.main.sg_flags |= ANYP;
- tty.main.sg_flags |= interrupt_input ? RAW : CBREAK;
+ XSETINT (Vtty_erase_char, tty.main.sg_erase);
+ tty.main.sg_flags &= ~(ECHO | CRMOD | XTABS);
+ if (meta_key)
+ tty.main.sg_flags |= ANYP;
+ tty.main.sg_flags |= interrupt_input ? RAW : CBREAK;
#endif /* not DOS_NT */
#endif /* not VMS (BSD, that is) */
#endif /* not HAVE_TERMIO */
- /* If going to use CBREAK mode, we must request C-g to interrupt
- and turn off start and stop chars, etc. If not going to use
- CBREAK mode, do this anyway so as to turn off local flow
- control for user coming over network on 4.2; in this case,
- only t_stopc and t_startc really matter. */
+ /* If going to use CBREAK mode, we must request C-g to interrupt
+ and turn off start and stop chars, etc. If not going to use
+ CBREAK mode, do this anyway so as to turn off local flow
+ control for user coming over network on 4.2; in this case,
+ only t_stopc and t_startc really matter. */
#ifndef HAVE_TERMIO
#ifdef HAVE_TCHARS
- /* Note: if not using CBREAK mode, it makes no difference how we
- set this */
- tty.tchars = new_tchars;
- tty.tchars.t_intrc = quit_char;
- if (flow_control)
- {
- tty.tchars.t_startc = '\021';
- tty.tchars.t_stopc = '\023';
- }
-
- tty.lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | old_tty.lmode;
+ /* Note: if not using CBREAK mode, it makes no difference how we
+ set this */
+ tty.tchars = new_tchars;
+ tty.tchars.t_intrc = quit_char;
+ if (tty_out->flow_control)
+ {
+ tty.tchars.t_startc = '\021';
+ tty.tchars.t_stopc = '\023';
+ }
+
+ tty.lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | tty_out->old_tty.lmode;
#ifdef ultrix
- /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
- anything, and leaving it in breaks the meta key. Go figure. */
- tty.lmode &= ~LLITOUT;
+ /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
+ anything, and leaving it in breaks the meta key. Go figure. */
+ tty.lmode &= ~LLITOUT;
#endif
-
+
#ifdef BSD4_1
- lmode = tty.lmode;
+ lmode = tty.lmode;
#endif
#endif /* HAVE_TCHARS */
#endif /* not HAVE_TERMIO */
#ifdef HAVE_LTCHARS
- tty.ltchars = new_ltchars;
+ tty.ltchars = new_ltchars;
#endif /* HAVE_LTCHARS */
#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
- if (!term_initted)
- internal_terminal_init ();
- dos_ttraw ();
+ if (!tty_out->term_initted)
+ internal_terminal_init ();
+ dos_ttraw ();
#endif
- EMACS_SET_TTY (input_fd, &tty, 0);
+ EMACS_SET_TTY (fileno (tty_out->input), &tty, 0);
- /* This code added to insure that, if flow-control is not to be used,
- we have an unlocked terminal at the start. */
+ /* This code added to insure that, if flow-control is not to be used,
+ we have an unlocked terminal at the start. */
#ifdef TCXONC
- if (!flow_control) ioctl (input_fd, TCXONC, 1);
+ if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TCXONC, 1);
#endif
#ifndef APOLLO
#ifdef TIOCSTART
- if (!flow_control) ioctl (input_fd, TIOCSTART, 0);
+ if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TIOCSTART, 0);
#endif
#endif
#if defined (HAVE_TERMIOS) || defined (HPUX9)
#ifdef TCOON
- if (!flow_control) tcflow (input_fd, TCOON);
+ if (!tty_out->flow_control) tcflow (fileno (tty_out->input), TCOON);
#endif
#endif
#ifdef AIXHFT
- hft_init ();
+ hft_init (tty_out);
#ifdef IBMR2AIX
- {
- /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
- to be only LF. This is the way that is done. */
- struct termio tty;
-
- if (ioctl (1, HFTGETID, &tty) != -1)
- write (1, "\033[20l", 5);
- }
+ {
+ /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
+ to be only LF. This is the way that is done. */
+ struct termio tty;
+
+ if (ioctl (1, HFTGETID, &tty) != -1)
+ write (1, "\033[20l", 5);
+ }
#endif
#endif /* AIXHFT */
#ifdef VMS
/* Appears to do nothing when in PASTHRU mode.
- SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
+ SYS$QIOW (0, fileno (tty_out->input), IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
interrupt_signal, oob_chars, 0, 0, 0, 0);
*/
- queue_kbd_input (0);
+ queue_kbd_input (0);
#endif /* VMS */
- }
#ifdef F_SETFL
#ifndef F_SETOWN_BUG
#ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
- if (interrupt_input
- && ! read_socket_hook && EQ (Vwindow_system, Qnil))
+ if (interrupt_input)
{
- old_fcntl_owner = fcntl (input_fd, F_GETOWN, 0);
- fcntl (input_fd, F_SETOWN, getpid ());
- init_sigio (input_fd);
+ old_fcntl_owner[fileno (tty_out->input)] =
+ fcntl (fileno (tty_out->input), F_GETOWN, 0);
+ fcntl (fileno (tty_out->input), F_SETOWN, getpid ());
+ init_sigio (fileno (tty_out->input));
#ifdef HAVE_GPM
if (term_gpm)
{
@@ -1690,7 +1762,7 @@ init_sys_modes ()
#ifdef BSD4_1
if (interrupt_input)
- init_sigio (input_fd);
+ init_sigio (fileno (tty_out->input));
#endif
#ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
@@ -1700,53 +1772,56 @@ init_sys_modes ()
/* This symbol is defined on recent USG systems.
Someone says without this call USG won't really buffer the file
even with a call to setbuf. */
- setvbuf (stdout, (char *) _sobuf, _IOFBF, sizeof _sobuf);
+ setvbuf (tty_out->output, (char *) _sobuf, _IOFBF, sizeof _sobuf);
#else
- setbuf (stdout, (char *) _sobuf);
-#endif
-#ifdef HAVE_WINDOW_SYSTEM
- /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
- needs the initialization code below. */
- if (EQ (Vwindow_system, Qnil)
-#ifndef WINDOWSNT
- /* When running in tty mode on NT/Win95, we have a read_socket
- hook, but still need the rest of the initialization code below. */
- && (! read_socket_hook)
+ setbuf (tty_out->output, (char *) _sobuf);
#endif
- )
-#endif
- set_terminal_modes ();
- if (!term_initted
- && FRAMEP (Vterminal_frame)
- && FRAME_TERMCAP_P (XFRAME (Vterminal_frame)))
- init_frame_faces (XFRAME (Vterminal_frame));
+ tty_set_terminal_modes (tty_out->terminal);
- if (term_initted && no_redraw_on_reenter)
+ if (!tty_out->term_initted)
{
+ Lisp_Object tail, frame;
+ FOR_EACH_FRAME (tail, frame)
+ {
+ /* XXX This needs to be revised. */
+ if (FRAME_TERMCAP_P (XFRAME (frame))
+ && FRAME_TTY (XFRAME (frame)) == tty_out)
+ init_frame_faces (XFRAME (frame));
+ }
+ }
+
+ if (tty_out->term_initted && no_redraw_on_reenter)
+ {
+ /* XXX This seems wrong on multi-tty. */
if (display_completed)
direct_output_forward_char (0);
}
else
{
+ Lisp_Object tail, frame;
frame_garbaged = 1;
- if (FRAMEP (Vterminal_frame))
- FRAME_GARBAGED_P (XFRAME (Vterminal_frame)) = 1;
+ FOR_EACH_FRAME (tail, frame)
+ {
+ if (FRAME_TERMCAP_P (XFRAME (frame))
+ && FRAME_TTY (XFRAME (frame)) == tty_out)
+ FRAME_GARBAGED_P (XFRAME (frame)) = 1;
+ }
}
- term_initted = 1;
+ tty_out->term_initted = 1;
}
/* Return nonzero if safe to use tabs in output.
At the time this is called, init_sys_modes has not been done yet. */
int
-tabs_safe_p ()
+tabs_safe_p (int fd)
{
- struct emacs_tty tty;
+ struct emacs_tty etty;
- EMACS_GET_TTY (input_fd, &tty);
- return EMACS_TTY_TABS_OK (&tty);
+ EMACS_GET_TTY (fd, &etty);
+ return EMACS_TTY_TABS_OK (&etty);
}
/* Get terminal size from system.
@@ -1754,8 +1829,7 @@ tabs_safe_p ()
We store 0 if there's no valid information. */
void
-get_frame_size (widthp, heightp)
- int *widthp, *heightp;
+get_tty_size (int fd, int *widthp, int *heightp)
{
#ifdef TIOCGWINSZ
@@ -1763,7 +1837,7 @@ get_frame_size (widthp, heightp)
/* BSD-style. */
struct winsize size;
- if (ioctl (input_fd, TIOCGWINSZ, &size) == -1)
+ if (ioctl (fd, TIOCGWINSZ, &size) == -1)
*widthp = *heightp = 0;
else
{
@@ -1777,7 +1851,7 @@ get_frame_size (widthp, heightp)
/* SunOS - style. */
struct ttysize size;
- if (ioctl (input_fd, TIOCGSIZE, &size) == -1)
+ if (ioctl (fd, TIOCGSIZE, &size) == -1)
*widthp = *heightp = 0;
else
{
@@ -1809,7 +1883,6 @@ get_frame_size (widthp, heightp)
*widthp = 0;
*heightp = 0;
#endif
-
#endif /* not VMS */
#endif /* not SunOS-style */
#endif /* not BSD-style */
@@ -1853,37 +1926,58 @@ set_window_size (fd, height, width)
}
-/* Prepare the terminal for exiting Emacs; move the cursor to the
- bottom of the frame, turn off interrupt-driven I/O, etc. */
+
+/* Prepare all terminal devices for exiting Emacs. */
+
void
-reset_sys_modes ()
+reset_all_sys_modes (void)
{
- struct frame *sf;
+ struct tty_display_info *tty;
+ for (tty = tty_list; tty; tty = tty->next)
+ reset_sys_modes (tty);
+}
+/* Prepare the terminal for closing it; move the cursor to the
+ bottom of the frame, turn off interrupt-driven I/O, etc. */
+
+void
+reset_sys_modes (tty_out)
+ struct tty_display_info *tty_out;
+{
if (noninteractive)
{
fflush (stdout);
return;
}
- if (!term_initted)
+ if (!tty_out->term_initted)
return;
-#ifdef HAVE_WINDOW_SYSTEM
- /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
- needs the clean-up code below. */
- if (!EQ (Vwindow_system, Qnil)
-#ifndef WINDOWSNT
- /* When running in tty mode on NT/Win95, we have a read_socket
- hook, but still need the rest of the clean-up code below. */
- || read_socket_hook
-#endif
- )
- return;
-#endif
- sf = SELECTED_FRAME ();
- cursor_to (FRAME_LINES (sf) - 1, 0);
- clear_end_of_line (FRAME_COLS (sf));
- /* clear_end_of_line may move the cursor */
- cursor_to (FRAME_LINES (sf) - 1, 0);
+
+ if (!tty_out->output)
+ return; /* The tty is suspended. */
+
+ /* Go to and clear the last line of the terminal. */
+
+ cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
+
+ /* Code adapted from tty_clear_end_of_line. */
+ if (tty_out->TS_clr_line)
+ {
+ emacs_tputs (tty_out, tty_out->TS_clr_line, 1, cmputc);
+ }
+ else
+ { /* have to do it the hard way */
+ int i;
+ tty_turn_off_insert (tty_out);
+
+ for (i = curX (tty_out); i < FrameCols (tty_out) - 1; i++)
+ {
+ fputc (' ', tty_out->output);
+ }
+ }
+
+ cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
+ fflush (tty_out->output);
+
#if defined (IBMR2AIX) && defined (AIXHFT)
{
/* HFT devices normally use ^J as a LF/CR. We forced it to
@@ -1895,12 +1989,12 @@ reset_sys_modes ()
}
#endif
- reset_terminal_modes ();
- fflush (stdout);
+ tty_reset_terminal_modes (tty_out->terminal);
+
#ifdef BSD_SYSTEM
#ifndef BSD4_1
/* Avoid possible loss of output when changing terminal modes. */
- fsync (fileno (stdout));
+ fsync (fileno (tty_out->output));
#endif
#endif
@@ -1909,22 +2003,25 @@ reset_sys_modes ()
#ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
if (interrupt_input)
{
- reset_sigio ();
- fcntl (input_fd, F_SETOWN, old_fcntl_owner);
+ reset_sigio (fileno (tty_out->input));
+ fcntl (fileno (tty_out->input), F_SETOWN,
+ old_fcntl_owner[fileno (tty_out->input)]);
}
#endif /* F_SETOWN */
#endif /* F_SETOWN_BUG */
#ifdef O_NDELAY
- fcntl (input_fd, F_SETFL, fcntl (input_fd, F_GETFL, 0) & ~O_NDELAY);
+ fcntl (fileno (tty_out->input), F_SETFL,
+ fcntl (fileno (tty_out->input), F_GETFL, 0) & ~O_NDELAY);
#endif
#endif /* F_SETFL */
#ifdef BSD4_1
if (interrupt_input)
- reset_sigio ();
+ reset_sigio (fileno (tty_out->input));
#endif /* BSD4_1 */
- if (old_tty_valid)
- while (EMACS_SET_TTY (input_fd, &old_tty, 0) < 0 && errno == EINTR)
+ if (tty_out->old_tty)
+ while (EMACS_SET_TTY (fileno (tty_out->input),
+ tty_out->old_tty, 0) < 0 && errno == EINTR)
;
#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
@@ -1935,7 +2032,7 @@ reset_sys_modes ()
/* Ultrix's termios *ignores* any line discipline except TERMIODISC.
A different old line discipline is therefore not restored, yet.
Restore the old line discipline by hand. */
- ioctl (0, TIOCSETD, &old_tty.main.c_line);
+ ioctl (0, TIOCSETD, &tty_out->old_tty.main.c_line);
#endif
#ifdef AIXHFT
@@ -1943,7 +2040,7 @@ reset_sys_modes ()
#endif
#ifdef BSD_PGRPS
- widen_foreground_group ();
+ widen_foreground_group (fileno (tty_out->input));
#endif
}
@@ -2008,9 +2105,9 @@ init_vms_input ()
{
int status;
- if (input_fd == 0)
+ if (fileno (CURTTY ()->input)) == 0)
{
- status = SYS$ASSIGN (&input_dsc, &input_fd, 0, 0);
+ status = SYS$ASSIGN (&input_dsc, &fileno (CURTTY ()->input)), 0, 0);
if (! (status & 1))
LIB$STOP (status);
}
@@ -2021,7 +2118,7 @@ init_vms_input ()
void
stop_vms_input ()
{
- return SYS$DASSGN (input_fd);
+ return SYS$DASSGN (fileno (CURTTY ()->input)));
}
short input_buffer;
@@ -2037,7 +2134,7 @@ queue_kbd_input ()
waiting_for_ast = 0;
stop_input = 0;
- status = SYS$QIO (0, input_fd, IO$_READVBLK,
+ status = SYS$QIO (0, fileno (CURTTY()->input), IO$_READVBLK,
&input_iosb, kbd_input_ast, 1,
&input_buffer, 1, 0, terminator_mask, 0, 0);
}
@@ -2154,7 +2251,7 @@ end_kbd_input ()
#endif
if (LIB$AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
{
- SYS$CANCEL (input_fd);
+ SYS$CANCEL (fileno (CURTTY()->input));
return;
}
@@ -2163,7 +2260,7 @@ end_kbd_input ()
SYS$CLREF (input_ef);
waiting_for_ast = 1;
stop_input = 1;
- SYS$CANCEL (input_fd);
+ SYS$CANCEL (fileno (CURTTY()->input));
SYS$SETAST (1);
SYS$WAITFR (input_ef);
waiting_for_ast = 0;
@@ -2225,7 +2322,8 @@ init_sigio (fd)
request_sigio ();
}
-reset_sigio ()
+reset_sigio (fd)
+ int fd;
{
unrequest_sigio ();
}
@@ -2567,7 +2665,9 @@ sys_select (nfds, rfds, wfds, efds, timeout)
SELECT_TYPE *rfds, *wfds, *efds;
EMACS_TIME *timeout;
{
- int ravail = 0;
+ /* XXX This needs to be updated for multi-tty support. Is there
+ anybody who needs to emulate select these days? */
+ int ravail = 0;
SELECT_TYPE orfds;
int timeoutval;
int *local_timeout;
@@ -2582,7 +2682,7 @@ sys_select (nfds, rfds, wfds, efds, timeout)
#if defined (HAVE_SELECT) && defined (HAVE_X_WINDOWS)
/* If we're using X, then the native select will work; we only need the
emulation for non-X usage. */
- if (!NILP (Vwindow_system))
+ if (!NILP (Vinitial_window_system))
return select (nfds, rfds, wfds, efds, timeout);
#endif
timeoutval = timeout ? EMACS_SECS (*timeout) : 100000;
@@ -2699,6 +2799,8 @@ sys_select (nfds, rfds, wfds, efds, timeout)
void
read_input_waiting ()
{
+ /* XXX This needs to be updated for multi-tty support. Is there
+ anybody who needs to emulate select these days? */
int nread, i;
extern int quit_char;
@@ -2752,6 +2854,10 @@ read_input_waiting ()
}
}
+#if !defined (HAVE_SELECT) || defined (BROKEN_SELECT_NON_X)
+#define select sys_select
+#endif
+
#endif /* not HAVE_SELECT */
#endif /* not VMS */
#endif /* not MSDOS */
@@ -2768,12 +2874,13 @@ init_sigio (fd)
}
void
-reset_sigio ()
+reset_sigio (fd)
+ int fd;
{
if (noninteractive)
return;
lmode = ~LINTRUP & lmode;
- ioctl (0, TIOCLSET, &lmode);
+ ioctl (fd, TIOCLSET, &lmode);
}
void
@@ -3229,7 +3336,7 @@ sys_getenv (name)
#undef abort
sys_abort ()
{
- reset_sys_modes ();
+ reset_all_sys_modes ();
LIB$SIGNAL (SS$_DEBUG);
}
#endif /* abort */
@@ -3556,7 +3663,7 @@ croak (badfunc)
char *badfunc;
{
printf ("%s not yet implemented\r\n", badfunc);
- reset_sys_modes ();
+ reset_all_sys_modes ();
exit (1);
}
@@ -5143,7 +5250,7 @@ croak (badfunc)
char *badfunc;
{
printf ("%s not yet implemented\r\n", badfunc);
- reset_sys_modes ();
+ reset_all_sys_modes ();
exit (1);
}
@@ -5165,7 +5272,7 @@ srandom (seed)
/* Called from init_sys_modes. */
void
-hft_init ()
+hft_init (struct tty_display_info *tty_out)
{
int junk;
@@ -5211,15 +5318,12 @@ hft_init ()
keymap.hfkey[1].hf_char = 127;
hftctl (0, HFSKBD, &buf);
}
- /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
- at times. */
- line_ins_del_ok = char_ins_del_ok = 0;
}
/* Reset the rubout key to backspace. */
void
-hft_reset ()
+hft_reset (struct tty_display_info *tty_out)
{
struct hfbuf buf;
struct hfkeymap keymap;
diff --git a/src/syssignal.h b/src/syssignal.h
index b52e2dd4b95..72ac1ed7f62 100644
--- a/src/syssignal.h
+++ b/src/syssignal.h
@@ -33,6 +33,7 @@ extern pthread_t main_thread;
indicate that SIGIO doesn't work by #undef-ing SIGIO. If this file
#includes <signal.h>, then that will re-#define SIGIO and confuse
things. */
+/* XXX This is not correct anymore, there is a BROKEN_SIGIO macro. */
#define SIGMASKTYPE sigset_t
diff --git a/src/term.c b/src/term.c
index 63455f525da..c906e1eb15a 100644
--- a/src/term.c
+++ b/src/term.c
@@ -25,13 +25,22 @@ Boston, MA 02110-1301, USA. */
#include <stdio.h>
#include <ctype.h>
#include <string.h>
+#include <errno.h>
+#include <sys/file.h>
+
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
+#if HAVE_TERMIOS_H
+#include <termios.h> /* For TIOCNOTTY. */
+#endif
+
+#include <signal.h>
+
+#include "lisp.h"
#include "termchar.h"
#include "termopts.h"
-#include "lisp.h"
#include "charset.h"
#include "coding.h"
#include "keyboard.h"
@@ -42,6 +51,8 @@ Boston, MA 02110-1301, USA. */
#include "window.h"
#include "keymap.h"
#include "blockinput.h"
+#include "syssignal.h"
+#include "systty.h"
#include "intervals.h"
/* For now, don't try to include termcap.h. On some systems,
@@ -65,221 +76,68 @@ extern int tgetnum P_ ((char *id));
#include "macterm.h"
#endif
+#ifndef O_RDWR
+#define O_RDWR 2
+#endif
+
+#ifndef O_NOCTTY
+#define O_NOCTTY 0
+#endif
+
+static void tty_set_scroll_region P_ ((struct frame *f, int start, int stop));
static void turn_on_face P_ ((struct frame *, int face_id));
static void turn_off_face P_ ((struct frame *, int face_id));
-static void tty_show_cursor P_ ((void));
-static void tty_hide_cursor P_ ((void));
-
-#define OUTPUT(a) \
- tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) - curY), cmputc)
-#define OUTPUT1(a) tputs (a, 1, cmputc)
-#define OUTPUTL(a, lines) tputs (a, lines, cmputc)
+static void tty_show_cursor P_ ((struct tty_display_info *));
+static void tty_hide_cursor P_ ((struct tty_display_info *));
+static void tty_background_highlight P_ ((struct tty_display_info *tty));
+static void clear_tty_hooks P_ ((struct terminal *terminal));
+static void set_tty_hooks P_ ((struct terminal *terminal));
+static void dissociate_if_controlling_tty P_ ((int fd));
+static void delete_tty P_ ((struct terminal *));
+
+#define OUTPUT(tty, a) \
+ emacs_tputs ((tty), a, \
+ (int) (FRAME_LINES (XFRAME (selected_frame)) \
+ - curY (tty)), \
+ cmputc)
+
+#define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
+#define OUTPUTL(tty, a, lines) emacs_tputs ((tty), a, lines, cmputc)
+
+#define OUTPUT_IF(tty, a) \
+ do { \
+ if (a) \
+ emacs_tputs ((tty), a, \
+ (int) (FRAME_LINES (XFRAME (selected_frame)) \
+ - curY (tty) ), \
+ cmputc); \
+ } while (0)
+
+#define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
-#define OUTPUT_IF(a) \
- do { \
- if (a) \
- tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) \
- - curY), cmputc); \
- } while (0)
+/* If true, use "vs", otherwise use "ve" to make the cursor visible. */
-#define OUTPUT1_IF(a) do { if (a) tputs (a, 1, cmputc); } while (0)
+static int visible_cursor;
/* Display space properties */
extern Lisp_Object Qspace, QCalign_to, QCwidth;
-/* Function to use to ring the bell. */
-
-Lisp_Object Vring_bell_function;
+/* Functions to call after suspending a tty. */
+Lisp_Object Vsuspend_tty_functions;
-/* If true, use "vs", otherwise use "ve" to make the cursor visible. */
-
-static int visible_cursor;
-
-/* Terminal characteristics that higher levels want to look at.
- These are all extern'd in termchar.h */
+/* Functions to call after resuming a tty. */
+Lisp_Object Vresume_tty_functions;
-int must_write_spaces; /* Nonzero means spaces in the text
- must actually be output; can't just skip
- over some columns to leave them blank. */
-int min_padding_speed; /* Speed below which no padding necessary */
-
-int line_ins_del_ok; /* Terminal can insert and delete lines */
-int char_ins_del_ok; /* Terminal can insert and delete chars */
-int scroll_region_ok; /* Terminal supports setting the
- scroll window */
-int scroll_region_cost; /* Cost of setting a scroll window,
- measured in characters */
-int memory_below_frame; /* Terminal remembers lines
- scrolled off bottom */
-int fast_clear_end_of_line; /* Terminal has a `ce' string */
-
-/* Nonzero means no need to redraw the entire frame on resuming
- a suspended Emacs. This is useful on terminals with multiple pages,
- where one page is used for Emacs and another for all else. */
+/* Chain of all tty device parameters. */
+struct tty_display_info *tty_list;
+/* Nonzero means no need to redraw the entire frame on resuming a
+ suspended Emacs. This is useful on terminals with multiple
+ pages, where one page is used for Emacs and another for all
+ else. */
int no_redraw_on_reenter;
-/* Hook functions that you can set to snap out the functions in this file.
- These are all extern'd in termhooks.h */
-
-void (*cursor_to_hook) P_ ((int, int));
-void (*raw_cursor_to_hook) P_ ((int, int));
-void (*clear_to_end_hook) P_ ((void));
-void (*clear_frame_hook) P_ ((void));
-void (*clear_end_of_line_hook) P_ ((int));
-
-void (*ins_del_lines_hook) P_ ((int, int));
-
-void (*delete_glyphs_hook) P_ ((int));
-
-void (*ring_bell_hook) P_ ((void));
-
-void (*reset_terminal_modes_hook) P_ ((void));
-void (*set_terminal_modes_hook) P_ ((void));
-void (*update_begin_hook) P_ ((struct frame *));
-void (*update_end_hook) P_ ((struct frame *));
-void (*set_terminal_window_hook) P_ ((int));
-void (*insert_glyphs_hook) P_ ((struct glyph *, int));
-void (*write_glyphs_hook) P_ ((struct glyph *, int));
-void (*delete_glyphs_hook) P_ ((int));
-
-int (*read_socket_hook) P_ ((int, int, struct input_event *));
-
-void (*frame_up_to_date_hook) P_ ((struct frame *));
-
-void (*mouse_position_hook) P_ ((FRAME_PTR *f, int insist,
- Lisp_Object *bar_window,
- enum scroll_bar_part *part,
- Lisp_Object *x,
- Lisp_Object *y,
- unsigned long *time));
-
-/* When reading from a minibuffer in a different frame, Emacs wants
- to shift the highlight from the selected frame to the mini-buffer's
- frame; under X, this means it lies about where the focus is.
- This hook tells the window system code to re-decide where to put
- the highlight. */
-
-void (*frame_rehighlight_hook) P_ ((FRAME_PTR f));
-
-/* If we're displaying frames using a window system that can stack
- frames on top of each other, this hook allows you to bring a frame
- to the front, or bury it behind all the other windows. If this
- hook is zero, that means the device we're displaying on doesn't
- support overlapping frames, so there's no need to raise or lower
- anything.
-
- If RAISE is non-zero, F is brought to the front, before all other
- windows. If RAISE is zero, F is sent to the back, behind all other
- windows. */
-
-void (*frame_raise_lower_hook) P_ ((FRAME_PTR f, int raise));
-
-/* If the value of the frame parameter changed, whis hook is called.
- For example, if going from fullscreen to not fullscreen this hook
- may do something OS dependent, like extended window manager hints on X11. */
-void (*fullscreen_hook) P_ ((struct frame *f));
-
-/* Set the vertical scroll bar for WINDOW to have its upper left corner
- at (TOP, LEFT), and be LENGTH rows high. Set its handle to
- indicate that we are displaying PORTION characters out of a total
- of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
- have a scroll bar, create one for it. */
-
-void (*set_vertical_scroll_bar_hook)
- P_ ((struct window *window,
- int portion, int whole, int position));
-
-
-/* The following three hooks are used when we're doing a thorough
- redisplay of the frame. We don't explicitly know which scroll bars
- are going to be deleted, because keeping track of when windows go
- away is a real pain - can you say set-window-configuration?
- Instead, we just assert at the beginning of redisplay that *all*
- scroll bars are to be removed, and then save scroll bars from the
- fiery pit when we actually redisplay their window. */
-
-/* Arrange for all scroll bars on FRAME to be removed at the next call
- to `*judge_scroll_bars_hook'. A scroll bar may be spared if
- `*redeem_scroll_bar_hook' is applied to its window before the judgment.
-
- This should be applied to each frame each time its window tree is
- redisplayed, even if it is not displaying scroll bars at the moment;
- if the HAS_SCROLL_BARS flag has just been turned off, only calling
- this and the judge_scroll_bars_hook will get rid of them.
-
- If non-zero, this hook should be safe to apply to any frame,
- whether or not it can support scroll bars, and whether or not it is
- currently displaying them. */
-
-void (*condemn_scroll_bars_hook) P_ ((FRAME_PTR frame));
-
-/* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
- Note that it's okay to redeem a scroll bar that is not condemned. */
-
-void (*redeem_scroll_bar_hook) P_ ((struct window *window));
-
-/* Remove all scroll bars on FRAME that haven't been saved since the
- last call to `*condemn_scroll_bars_hook'.
-
- This should be applied to each frame after each time its window
- tree is redisplayed, even if it is not displaying scroll bars at the
- moment; if the HAS_SCROLL_BARS flag has just been turned off, only
- calling this and condemn_scroll_bars_hook will get rid of them.
-
- If non-zero, this hook should be safe to apply to any frame,
- whether or not it can support scroll bars, and whether or not it is
- currently displaying them. */
-
-void (*judge_scroll_bars_hook) P_ ((FRAME_PTR FRAME));
-
-/* Strings, numbers and flags taken from the termcap entry. */
-
-char *TS_ins_line; /* "al" */
-char *TS_ins_multi_lines; /* "AL" (one parameter, # lines to insert) */
-char *TS_bell; /* "bl" */
-char *TS_clr_to_bottom; /* "cd" */
-char *TS_clr_line; /* "ce", clear to end of line */
-char *TS_clr_frame; /* "cl" */
-char *TS_set_scroll_region; /* "cs" (2 params, first line and last line) */
-char *TS_set_scroll_region_1; /* "cS" (4 params: total lines,
- lines above scroll region, lines below it,
- total lines again) */
-char *TS_del_char; /* "dc" */
-char *TS_del_multi_chars; /* "DC" (one parameter, # chars to delete) */
-char *TS_del_line; /* "dl" */
-char *TS_del_multi_lines; /* "DL" (one parameter, # lines to delete) */
-char *TS_delete_mode; /* "dm", enter character-delete mode */
-char *TS_end_delete_mode; /* "ed", leave character-delete mode */
-char *TS_end_insert_mode; /* "ei", leave character-insert mode */
-char *TS_ins_char; /* "ic" */
-char *TS_ins_multi_chars; /* "IC" (one parameter, # chars to insert) */
-char *TS_insert_mode; /* "im", enter character-insert mode */
-char *TS_pad_inserted_char; /* "ip". Just padding, no commands. */
-char *TS_end_keypad_mode; /* "ke" */
-char *TS_keypad_mode; /* "ks" */
-char *TS_pad_char; /* "pc", char to use as padding */
-char *TS_repeat; /* "rp" (2 params, # times to repeat
- and character to be repeated) */
-char *TS_end_standout_mode; /* "se" */
-char *TS_fwd_scroll; /* "sf" */
-char *TS_standout_mode; /* "so" */
-char *TS_rev_scroll; /* "sr" */
-char *TS_end_termcap_modes; /* "te" */
-char *TS_termcap_modes; /* "ti" */
-char *TS_visible_bell; /* "vb" */
-char *TS_cursor_normal; /* "ve" */
-char *TS_cursor_visible; /* "vs" */
-char *TS_cursor_invisible; /* "vi" */
-char *TS_set_window; /* "wi" (4 params, start and end of window,
- each as vpos and hpos) */
-
-/* Value of the "NC" (no_color_video) capability, or 0 if not
- present. */
-
-static int TN_no_color_video;
-
/* Meaning of bits in no_color_video. Each bit set means that the
corresponding attribute cannot be combined with colors. */
@@ -296,68 +154,6 @@ enum no_color_bit
NC_ALT_CHARSET = 1 << 8
};
-/* "md" -- turn on bold (extra bright mode). */
-
-char *TS_enter_bold_mode;
-
-/* "mh" -- turn on half-bright mode. */
-
-char *TS_enter_dim_mode;
-
-/* "mb" -- enter blinking mode. */
-
-char *TS_enter_blink_mode;
-
-/* "mr" -- enter reverse video mode. */
-
-char *TS_enter_reverse_mode;
-
-/* "us"/"ue" -- start/end underlining. */
-
-char *TS_exit_underline_mode, *TS_enter_underline_mode;
-
-/* "as"/"ae" -- start/end alternate character set. Not really
- supported, yet. */
-
-char *TS_enter_alt_charset_mode, *TS_exit_alt_charset_mode;
-
-/* "me" -- switch appearances off. */
-
-char *TS_exit_attribute_mode;
-
-/* "Co" -- number of colors. */
-
-int TN_max_colors;
-
-/* "pa" -- max. number of color pairs on screen. Not handled yet.
- Could be a problem if not equal to TN_max_colors * TN_max_colors. */
-
-int TN_max_pairs;
-
-/* "op" -- SVr4 set default pair to its original value. */
-
-char *TS_orig_pair;
-
-/* "AF"/"AB" or "Sf"/"Sb"-- set ANSI or SVr4 foreground/background color.
- 1 param, the color index. */
-
-char *TS_set_foreground, *TS_set_background;
-
-int TF_hazeltine; /* termcap hz flag. */
-int TF_insmode_motion; /* termcap mi flag: can move while in insert mode. */
-int TF_standout_motion; /* termcap mi flag: can move while in standout mode. */
-int TF_underscore; /* termcap ul flag: _ underlines if over-struck on
- non-blank position. Must clear before writing _. */
-int TF_teleray; /* termcap xt flag: many weird consequences.
- For t1061. */
-
-static int RPov; /* # chars to start a TS_repeat */
-
-static int delete_in_insert_mode; /* delete mode == insert mode */
-
-static int se_is_so; /* 1 if same string both enters and leaves
- standout mode */
-
/* internal state */
/* The largest frame width in any call to calculate_costs. */
@@ -368,33 +164,14 @@ int max_frame_cols;
int max_frame_lines;
-static int costs_set; /* Nonzero if costs have been calculated. */
-
-int insert_mode; /* Nonzero when in insert mode. */
-int standout_mode; /* Nonzero when in standout mode. */
-
-/* Size of window specified by higher levels.
- This is the number of lines, from the top of frame downwards,
- which can participate in insert-line/delete-line operations.
-
- Effectively it excludes the bottom frame_lines - specified_window_size
- lines from those operations. */
-
-int specified_window;
-
-/* Frame currently being redisplayed; 0 if not currently redisplaying.
- (Direct output does not count). */
-
-FRAME_PTR updating_frame;
+/* Non-zero if we have dropped our controlling tty and therefore
+ should not open a frame on stdout. */
+static int no_controlling_tty;
/* Provided for lisp packages. */
static int system_uses_terminfo;
-/* Flag used in tty_show/hide_cursor. */
-
-static int tty_cursor_hidden;
-
char *tparam ();
extern char *tgetstr ();
@@ -421,6 +198,9 @@ static void term_mouse_highlight (struct frame *f, int x, int y);
/* Nonzero means mouse is enabled on Linux console. */
int term_gpm = 0;
+/* The id of the terminal device for which we have gpm support. */
+int gpm_tty;
+
/* These variables describe the range of text currently shown in its
mouse-face, together with the window they apply to. As long as
the mouse stays within this range, we need not redraw anything on
@@ -436,192 +216,173 @@ static int pos_x, pos_y;
static int last_mouse_x, last_mouse_y;
#endif /* HAVE_GPM */
-void
-ring_bell ()
-{
- if (!NILP (Vring_bell_function))
- {
- Lisp_Object function;
-
- /* Temporarily set the global variable to nil
- so that if we get an error, it stays nil
- and we don't call it over and over.
-
- We don't specbind it, because that would carefully
- restore the bad value if there's an error
- and make the loop of errors happen anyway. */
-
- function = Vring_bell_function;
- Vring_bell_function = Qnil;
+/* Ring the bell on a tty. */
- call0 (function);
+static void
+tty_ring_bell (struct frame *f)
+{
+ struct tty_display_info *tty = FRAME_TTY (f);
- Vring_bell_function = function;
+ if (tty->output)
+ {
+ OUTPUT (tty, (tty->TS_visible_bell && visible_bell
+ ? tty->TS_visible_bell
+ : tty->TS_bell));
+ fflush (tty->output);
}
- else if (!FRAME_TERMCAP_P (XFRAME (selected_frame)))
- (*ring_bell_hook) ();
- else
- OUTPUT (TS_visible_bell && visible_bell ? TS_visible_bell : TS_bell);
}
+/* Set up termcap modes for Emacs. */
+
void
-set_terminal_modes ()
+tty_set_terminal_modes (struct terminal *terminal)
{
- if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
+ struct tty_display_info *tty = terminal->display_info.tty;
+
+ if (tty->output)
{
- if (TS_termcap_modes)
- OUTPUT (TS_termcap_modes);
+ if (tty->TS_termcap_modes)
+ OUTPUT (tty, tty->TS_termcap_modes);
else
- {
- /* Output enough newlines to scroll all the old screen contents
- off the screen, so it won't be overwritten and lost. */
- int i;
- for (i = 0; i < FRAME_LINES (XFRAME (selected_frame)); i++)
- putchar ('\n');
- }
-
- OUTPUT_IF (visible_cursor ? TS_cursor_visible : TS_cursor_normal);
- OUTPUT_IF (TS_keypad_mode);
- losecursor ();
+ {
+ /* Output enough newlines to scroll all the old screen contents
+ off the screen, so it won't be overwritten and lost. */
+ int i;
+ current_tty = tty;
+ for (i = 0; i < FRAME_LINES (XFRAME (selected_frame)); i++)
+ cmputc ('\n');
+ }
+
+ OUTPUT_IF (tty, tty->TS_termcap_modes);
+ OUTPUT_IF (tty, visible_cursor ? tty->TS_cursor_visible : tty->TS_cursor_normal);
+ OUTPUT_IF (tty, tty->TS_keypad_mode);
+ losecursor (tty);
+ fflush (tty->output);
}
- else
- (*set_terminal_modes_hook) ();
}
+/* Reset termcap modes before exiting Emacs. */
+
void
-reset_terminal_modes ()
+tty_reset_terminal_modes (struct terminal *terminal)
{
- if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
+ struct tty_display_info *tty = terminal->display_info.tty;
+
+ if (tty->output)
{
- turn_off_highlight ();
- turn_off_insert ();
- OUTPUT_IF (TS_end_keypad_mode);
- OUTPUT_IF (TS_cursor_normal);
- OUTPUT_IF (TS_end_termcap_modes);
- OUTPUT_IF (TS_orig_pair);
+ tty_turn_off_highlight (tty);
+ tty_turn_off_insert (tty);
+ OUTPUT_IF (tty, tty->TS_end_keypad_mode);
+ OUTPUT_IF (tty, tty->TS_cursor_normal);
+ OUTPUT_IF (tty, tty->TS_end_termcap_modes);
+ OUTPUT_IF (tty, tty->TS_orig_pair);
/* Output raw CR so kernel can track the cursor hpos. */
+ current_tty = tty;
cmputc ('\r');
+ fflush (tty->output);
}
- else if (reset_terminal_modes_hook)
- (*reset_terminal_modes_hook) ();
}
-void
-update_begin (f)
- struct frame *f;
-{
- updating_frame = f;
- if (!FRAME_TERMCAP_P (f))
- update_begin_hook (f);
-}
+/* Flag the end of a display update on a termcap terminal. */
-void
-update_end (f)
- struct frame *f;
+static void
+tty_update_end (struct frame *f)
{
- if (FRAME_TERMCAP_P (f))
- {
- if (!XWINDOW (selected_window)->cursor_off_p)
- tty_show_cursor ();
- turn_off_insert ();
- background_highlight ();
- }
- else
- update_end_hook (f);
+ struct tty_display_info *tty = FRAME_TTY (f);
- updating_frame = NULL;
+ if (!XWINDOW (selected_window)->cursor_off_p)
+ tty_show_cursor (tty);
+ tty_turn_off_insert (tty);
+ tty_background_highlight (tty);
}
-void
-set_terminal_window (size)
- int size;
+/* The implementation of set_terminal_window for termcap frames. */
+
+static void
+tty_set_terminal_window (struct frame *f, int size)
{
- if (FRAME_TERMCAP_P (updating_frame))
- {
- specified_window = size ? size : FRAME_LINES (updating_frame);
- if (scroll_region_ok)
- set_scroll_region (0, specified_window);
- }
- else
- set_terminal_window_hook (size);
+ struct tty_display_info *tty = FRAME_TTY (f);
+
+ tty->specified_window = size ? size : FRAME_LINES (f);
+ if (FRAME_SCROLL_REGION_OK (f))
+ tty_set_scroll_region (f, 0, tty->specified_window);
}
-void
-set_scroll_region (start, stop)
- int start, stop;
+static void
+tty_set_scroll_region (struct frame *f, int start, int stop)
{
char *buf;
- struct frame *sf = XFRAME (selected_frame);
-
- if (TS_set_scroll_region)
- buf = tparam (TS_set_scroll_region, 0, 0, start, stop - 1);
- else if (TS_set_scroll_region_1)
- buf = tparam (TS_set_scroll_region_1, 0, 0,
- FRAME_LINES (sf), start,
- FRAME_LINES (sf) - stop,
- FRAME_LINES (sf));
+ struct tty_display_info *tty = FRAME_TTY (f);
+
+ if (tty->TS_set_scroll_region)
+ buf = tparam (tty->TS_set_scroll_region, 0, 0, start, stop - 1);
+ else if (tty->TS_set_scroll_region_1)
+ buf = tparam (tty->TS_set_scroll_region_1, 0, 0,
+ FRAME_LINES (f), start,
+ FRAME_LINES (f) - stop,
+ FRAME_LINES (f));
else
- buf = tparam (TS_set_window, 0, 0, start, 0, stop, FRAME_COLS (sf));
+ buf = tparam (tty->TS_set_window, 0, 0, start, 0, stop, FRAME_COLS (f));
- OUTPUT (buf);
+ OUTPUT (tty, buf);
xfree (buf);
- losecursor ();
+ losecursor (tty);
}
static void
-turn_on_insert ()
+tty_turn_on_insert (struct tty_display_info *tty)
{
- if (!insert_mode)
- OUTPUT (TS_insert_mode);
- insert_mode = 1;
+ if (!tty->insert_mode)
+ OUTPUT (tty, tty->TS_insert_mode);
+ tty->insert_mode = 1;
}
void
-turn_off_insert ()
+tty_turn_off_insert (struct tty_display_info *tty)
{
- if (insert_mode)
- OUTPUT (TS_end_insert_mode);
- insert_mode = 0;
+ if (tty->insert_mode)
+ OUTPUT (tty, tty->TS_end_insert_mode);
+ tty->insert_mode = 0;
}
/* Handle highlighting. */
void
-turn_off_highlight ()
+tty_turn_off_highlight (struct tty_display_info *tty)
{
- if (standout_mode)
- OUTPUT_IF (TS_end_standout_mode);
- standout_mode = 0;
+ if (tty->standout_mode)
+ OUTPUT_IF (tty, tty->TS_end_standout_mode);
+ tty->standout_mode = 0;
}
static void
-turn_on_highlight ()
+tty_turn_on_highlight (struct tty_display_info *tty)
{
- if (!standout_mode)
- OUTPUT_IF (TS_standout_mode);
- standout_mode = 1;
+ if (!tty->standout_mode)
+ OUTPUT_IF (tty, tty->TS_standout_mode);
+ tty->standout_mode = 1;
}
static void
-toggle_highlight ()
+tty_toggle_highlight (struct tty_display_info *tty)
{
- if (standout_mode)
- turn_off_highlight ();
+ if (tty->standout_mode)
+ tty_turn_off_highlight (tty);
else
- turn_on_highlight ();
+ tty_turn_on_highlight (tty);
}
/* Make cursor invisible. */
static void
-tty_hide_cursor ()
+tty_hide_cursor (struct tty_display_info *tty)
{
- if (tty_cursor_hidden == 0)
+ if (tty->cursor_hidden == 0)
{
- tty_cursor_hidden = 1;
- OUTPUT_IF (TS_cursor_invisible);
+ tty->cursor_hidden = 1;
+ OUTPUT_IF (tty, tty->TS_cursor_invisible);
}
}
@@ -629,14 +390,14 @@ tty_hide_cursor ()
/* Ensure that cursor is visible. */
static void
-tty_show_cursor ()
+tty_show_cursor (struct tty_display_info *tty)
{
- if (tty_cursor_hidden)
+ if (tty->cursor_hidden)
{
- tty_cursor_hidden = 0;
- OUTPUT_IF (TS_cursor_normal);
+ tty->cursor_hidden = 0;
+ OUTPUT_IF (tty, tty->TS_cursor_normal);
if (visible_cursor)
- OUTPUT_IF (TS_cursor_visible);
+ OUTPUT_IF (tty, tty->TS_cursor_visible);
}
}
@@ -645,180 +406,151 @@ tty_show_cursor ()
empty space inside windows. What this is,
depends on the user option inverse-video. */
-void
-background_highlight ()
+static void
+tty_background_highlight (struct tty_display_info *tty)
{
if (inverse_video)
- turn_on_highlight ();
+ tty_turn_on_highlight (tty);
else
- turn_off_highlight ();
+ tty_turn_off_highlight (tty);
}
/* Set standout mode to the mode specified for the text to be output. */
static void
-highlight_if_desired ()
+tty_highlight_if_desired (struct tty_display_info *tty)
{
if (inverse_video)
- turn_on_highlight ();
+ tty_turn_on_highlight (tty);
else
- turn_off_highlight ();
+ tty_turn_off_highlight (tty);
}
/* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
frame-relative coordinates. */
-void
-cursor_to (vpos, hpos)
- int vpos, hpos;
+static void
+tty_cursor_to (struct frame *f, int vpos, int hpos)
{
- struct frame *f = updating_frame ? updating_frame : XFRAME (selected_frame);
-
- if (! FRAME_TERMCAP_P (f) && cursor_to_hook)
- {
- (*cursor_to_hook) (vpos, hpos);
- return;
- }
+ struct tty_display_info *tty = FRAME_TTY (f);
/* Detect the case where we are called from reset_sys_modes
and the costs have never been calculated. Do nothing. */
- if (! costs_set)
+ if (! tty->costs_set)
return;
- if (curY == vpos && curX == hpos)
+ if (curY (tty) == vpos
+ && curX (tty) == hpos)
return;
- if (!TF_standout_motion)
- background_highlight ();
- if (!TF_insmode_motion)
- turn_off_insert ();
- cmgoto (vpos, hpos);
+ if (!tty->TF_standout_motion)
+ tty_background_highlight (tty);
+ if (!tty->TF_insmode_motion)
+ tty_turn_off_insert (tty);
+ cmgoto (tty, vpos, hpos);
}
/* Similar but don't take any account of the wasted characters. */
-void
-raw_cursor_to (row, col)
- int row, col;
+static void
+tty_raw_cursor_to (struct frame *f, int row, int col)
{
- struct frame *f = updating_frame ? updating_frame : XFRAME (selected_frame);
- if (! FRAME_TERMCAP_P (f))
- {
- (*raw_cursor_to_hook) (row, col);
- return;
- }
- if (curY == row && curX == col)
+ struct tty_display_info *tty = FRAME_TTY (f);
+
+ if (curY (tty) == row
+ && curX (tty) == col)
return;
- if (!TF_standout_motion)
- background_highlight ();
- if (!TF_insmode_motion)
- turn_off_insert ();
- cmgoto (row, col);
+ if (!tty->TF_standout_motion)
+ tty_background_highlight (tty);
+ if (!tty->TF_insmode_motion)
+ tty_turn_off_insert (tty);
+ cmgoto (tty, row, col);
}
/* Erase operations */
-/* clear from cursor to end of frame */
-void
-clear_to_end ()
+/* Clear from cursor to end of frame on a termcap device. */
+
+static void
+tty_clear_to_end (struct frame *f)
{
register int i;
+ struct tty_display_info *tty = FRAME_TTY (f);
- if (clear_to_end_hook && ! FRAME_TERMCAP_P (updating_frame))
+ if (tty->TS_clr_to_bottom)
{
- (*clear_to_end_hook) ();
- return;
- }
- if (TS_clr_to_bottom)
- {
- background_highlight ();
- OUTPUT (TS_clr_to_bottom);
+ tty_background_highlight (tty);
+ OUTPUT (tty, tty->TS_clr_to_bottom);
}
else
{
- for (i = curY; i < FRAME_LINES (XFRAME (selected_frame)); i++)
+ for (i = curY (tty); i < FRAME_LINES (f); i++)
{
- cursor_to (i, 0);
- clear_end_of_line (FRAME_COLS (XFRAME (selected_frame)));
+ cursor_to (f, i, 0);
+ clear_end_of_line (f, FRAME_COLS (f));
}
}
}
-/* Clear entire frame */
+/* Clear an entire termcap frame. */
-void
-clear_frame ()
+static void
+tty_clear_frame (struct frame *f)
{
- struct frame *sf = XFRAME (selected_frame);
+ struct tty_display_info *tty = FRAME_TTY (f);
- if (clear_frame_hook
- && ! FRAME_TERMCAP_P ((updating_frame ? updating_frame : sf)))
+ if (tty->TS_clr_frame)
{
- (*clear_frame_hook) ();
- return;
- }
- if (TS_clr_frame)
- {
- background_highlight ();
- OUTPUT (TS_clr_frame);
- cmat (0, 0);
+ tty_background_highlight (tty);
+ OUTPUT (tty, tty->TS_clr_frame);
+ cmat (tty, 0, 0);
}
else
{
- cursor_to (0, 0);
- clear_to_end ();
+ cursor_to (f, 0, 0);
+ clear_to_end (f);
}
}
-/* Clear from cursor to end of line.
- Assume that the line is already clear starting at column first_unused_hpos.
+/* An implementation of clear_end_of_line for termcap frames.
Note that the cursor may be moved, on terminals lacking a `ce' string. */
-void
-clear_end_of_line (first_unused_hpos)
- int first_unused_hpos;
+static void
+tty_clear_end_of_line (struct frame *f, int first_unused_hpos)
{
register int i;
-
- if (clear_end_of_line_hook
- && ! FRAME_TERMCAP_P ((updating_frame
- ? updating_frame
- : XFRAME (selected_frame))))
- {
- (*clear_end_of_line_hook) (first_unused_hpos);
- return;
- }
+ struct tty_display_info *tty = FRAME_TTY (f);
/* Detect the case where we are called from reset_sys_modes
and the costs have never been calculated. Do nothing. */
- if (! costs_set)
+ if (! tty->costs_set)
return;
- if (curX >= first_unused_hpos)
+ if (curX (tty) >= first_unused_hpos)
return;
- background_highlight ();
- if (TS_clr_line)
+ tty_background_highlight (tty);
+ if (tty->TS_clr_line)
{
- OUTPUT1 (TS_clr_line);
+ OUTPUT1 (tty, tty->TS_clr_line);
}
else
{ /* have to do it the hard way */
- struct frame *sf = XFRAME (selected_frame);
- turn_off_insert ();
+ tty_turn_off_insert (tty);
/* Do not write in last row last col with Auto-wrap on. */
- if (AutoWrap && curY == FRAME_LINES (sf) - 1
- && first_unused_hpos == FRAME_COLS (sf))
+ if (AutoWrap (tty)
+ && curY (tty) == FrameRows (tty) - 1
+ && first_unused_hpos == FrameCols (tty))
first_unused_hpos--;
- for (i = curX; i < first_unused_hpos; i++)
+ for (i = curX (tty); i < first_unused_hpos; i++)
{
- if (termscript)
- fputc (' ', termscript);
- putchar (' ');
+ if (tty->termscript)
+ fputc (' ', tty->termscript);
+ fputc (' ', tty->output);
}
- cmplus (first_unused_hpos - curX);
+ cmplus (tty, first_unused_hpos - curX (tty));
}
}
@@ -940,43 +672,37 @@ encode_terminal_code (src, src_len, coding)
return encode_terminal_buf + nbytes;
}
-void
-write_glyphs (string, len)
- register struct glyph *string;
- register int len;
+
+/* An implementation of write_glyphs for termcap frames. */
+
+static void
+tty_write_glyphs (struct frame *f, struct glyph *string, int len)
{
- struct frame *sf = XFRAME (selected_frame);
- struct frame *f = updating_frame ? updating_frame : sf;
unsigned char *conversion_buffer;
struct coding_system *coding;
- if (write_glyphs_hook
- && ! FRAME_TERMCAP_P (f))
- {
- (*write_glyphs_hook) (string, len);
- return;
- }
+ struct tty_display_info *tty = FRAME_TTY (f);
- turn_off_insert ();
- tty_hide_cursor ();
+ tty_turn_off_insert (tty);
+ tty_hide_cursor (tty);
/* Don't dare write in last column of bottom line, if Auto-Wrap,
since that would scroll the whole frame on some terminals. */
- if (AutoWrap
- && curY + 1 == FRAME_LINES (sf)
- && (curX + len) == FRAME_COLS (sf))
+ if (AutoWrap (tty)
+ && curY (tty) + 1 == FRAME_LINES (f)
+ && (curX (tty) + len) == FRAME_COLS (f))
len --;
if (len <= 0)
return;
- cmplus (len);
+ cmplus (tty, len);
/* If terminal_coding does any conversion, use it, otherwise use
safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
because it always return 1 if the member src_multibyte is 1. */
- coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK
- ? &terminal_coding : &safe_terminal_coding);
+ coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK
+ ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding);
/* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
the tail. */
coding->mode &= ~CODING_MODE_LAST_BLOCK;
@@ -992,7 +718,7 @@ write_glyphs (string, len)
break;
/* Turn appearance modes of the face of the run on. */
- highlight_if_desired ();
+ tty_highlight_if_desired (tty);
turn_on_face (f, face_id);
if (n == len)
@@ -1002,11 +728,11 @@ write_glyphs (string, len)
if (coding->produced > 0)
{
BLOCK_INPUT;
- fwrite (conversion_buffer, 1, coding->produced, stdout);
- if (ferror (stdout))
- clearerr (stdout);
- if (termscript)
- fwrite (conversion_buffer, 1, coding->produced, termscript);
+ fwrite (conversion_buffer, 1, coding->produced, tty->output);
+ if (ferror (tty->output))
+ clearerr (tty->output);
+ if (tty->termscript)
+ fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
UNBLOCK_INPUT;
}
len -= n;
@@ -1014,49 +740,49 @@ write_glyphs (string, len)
/* Turn appearance modes off. */
turn_off_face (f, face_id);
- turn_off_highlight ();
+ tty_turn_off_highlight (tty);
}
- cmcheckmagic ();
+ cmcheckmagic (tty);
}
-void
-write_glyphs_with_face (string, len, face_id)
+static void
+tty_write_glyphs_with_face (f, string, len, face_id)
+ register struct frame *f;
register struct glyph *string;
register int len, face_id;
{
- struct frame *sf = XFRAME (selected_frame);
- struct frame *f = updating_frame ? updating_frame : sf;
unsigned char *conversion_buffer;
struct coding_system *coding;
- turn_off_insert ();
- tty_hide_cursor ();
+ struct tty_display_info *tty = FRAME_TTY (f);
+
+ tty_turn_off_insert (tty);
+ tty_hide_cursor (tty);
/* Don't dare write in last column of bottom line, if Auto-Wrap,
since that would scroll the whole frame on some terminals. */
- if (AutoWrap
- && curY + 1 == FRAME_LINES (sf)
- && (curX + len) == FRAME_COLS (sf))
+ if (AutoWrap (tty)
+ && curY (tty) + 1 == FRAME_LINES (f)
+ && (curX (tty) + len) == FRAME_COLS (f))
len --;
if (len <= 0)
return;
- cmplus (len);
+ cmplus (tty, len);
/* If terminal_coding does any conversion, use it, otherwise use
safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
because it always return 1 if the member src_multibyte is 1. */
- coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK
- ? &terminal_coding : &safe_terminal_coding);
+ coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK
+ ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding);
/* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
the tail. */
coding->mode &= ~CODING_MODE_LAST_BLOCK;
-
/* Turn appearance modes of the face. */
- highlight_if_desired ();
+ tty_highlight_if_desired (tty);
turn_on_face (f, face_id);
coding->mode |= CODING_MODE_LAST_BLOCK;
@@ -1064,59 +790,47 @@ write_glyphs_with_face (string, len, face_id)
if (coding->produced > 0)
{
BLOCK_INPUT;
- fwrite (conversion_buffer, 1, coding->produced, stdout);
- if (ferror (stdout))
- clearerr (stdout);
- if (termscript)
- fwrite (conversion_buffer, 1, coding->produced, termscript);
+ fwrite (conversion_buffer, 1, coding->produced, tty->output);
+ if (ferror (tty->output))
+ clearerr (tty->output);
+ if (tty->termscript)
+ fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
UNBLOCK_INPUT;
}
/* Turn appearance modes off. */
turn_off_face (f, face_id);
- turn_off_highlight ();
+ tty_turn_off_highlight (tty);
- cmcheckmagic ();
+ cmcheckmagic (tty);
}
-/* If start is zero, insert blanks instead of a string at start */
-void
-insert_glyphs (start, len)
- register struct glyph *start;
- register int len;
+/* An implementation of insert_glyphs for termcap frames. */
+
+static void
+tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
{
char *buf;
struct glyph *glyph = NULL;
- struct frame *f, *sf;
unsigned char *conversion_buffer;
unsigned char space[1];
struct coding_system *coding;
- if (len <= 0)
- return;
+ struct tty_display_info *tty = FRAME_TTY (f);
- if (insert_glyphs_hook)
+ if (tty->TS_ins_multi_chars)
{
- (*insert_glyphs_hook) (start, len);
- return;
- }
-
- sf = XFRAME (selected_frame);
- f = updating_frame ? updating_frame : sf;
-
- if (TS_ins_multi_chars)
- {
- buf = tparam (TS_ins_multi_chars, 0, 0, len);
- OUTPUT1 (buf);
+ buf = tparam (tty->TS_ins_multi_chars, 0, 0, len);
+ OUTPUT1 (tty, buf);
xfree (buf);
if (start)
- write_glyphs (start, len);
+ write_glyphs (f, start, len);
return;
}
- turn_on_insert ();
- cmplus (len);
+ tty_turn_on_insert (tty);
+ cmplus (tty, len);
if (! start)
space[0] = SPACEGLYPH;
@@ -1124,15 +838,15 @@ insert_glyphs (start, len)
/* If terminal_coding does any conversion, use it, otherwise use
safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
because it always return 1 if the member src_multibyte is 1. */
- coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK
- ? &terminal_coding : &safe_terminal_coding);
+ coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK
+ ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding);
/* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
the tail. */
coding->mode &= ~CODING_MODE_LAST_BLOCK;
while (len-- > 0)
{
- OUTPUT1_IF (TS_ins_char);
+ OUTPUT1_IF (tty, tty->TS_ins_char);
if (!start)
{
conversion_buffer = space;
@@ -1140,7 +854,7 @@ insert_glyphs (start, len)
}
else
{
- highlight_if_desired ();
+ tty_highlight_if_desired (tty);
turn_on_face (f, start->face_id);
glyph = start;
++start;
@@ -1148,7 +862,7 @@ insert_glyphs (start, len)
occupies more than one column. */
while (len && CHAR_GLYPH_PADDING_P (*start))
{
- OUTPUT1_IF (TS_ins_char);
+ OUTPUT1_IF (tty, tty->TS_ins_char);
start++, len--;
}
@@ -1156,89 +870,77 @@ insert_glyphs (start, len)
/* This is the last glyph. */
coding->mode |= CODING_MODE_LAST_BLOCK;
- conversion_buffer = encode_terminal_code (glyph, 1, coding);
+ conversion_buffer = encode_terminal_code (glyph, 1, coding);
}
if (coding->produced > 0)
{
BLOCK_INPUT;
- fwrite (conversion_buffer, 1, coding->produced, stdout);
- if (ferror (stdout))
- clearerr (stdout);
- if (termscript)
- fwrite (conversion_buffer, 1, coding->produced, termscript);
+ fwrite (conversion_buffer, 1, coding->produced, tty->output);
+ if (ferror (tty->output))
+ clearerr (tty->output);
+ if (tty->termscript)
+ fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
UNBLOCK_INPUT;
}
- OUTPUT1_IF (TS_pad_inserted_char);
+ OUTPUT1_IF (tty, tty->TS_pad_inserted_char);
if (start)
{
turn_off_face (f, glyph->face_id);
- turn_off_highlight ();
+ tty_turn_off_highlight (tty);
}
}
- cmcheckmagic ();
+ cmcheckmagic (tty);
}
-void
-delete_glyphs (n)
- register int n;
+/* An implementation of delete_glyphs for termcap frames. */
+
+static void
+tty_delete_glyphs (struct frame *f, int n)
{
char *buf;
register int i;
- if (delete_glyphs_hook && ! FRAME_TERMCAP_P (updating_frame))
- {
- (*delete_glyphs_hook) (n);
- return;
- }
+ struct tty_display_info *tty = FRAME_TTY (f);
- if (delete_in_insert_mode)
+ if (tty->delete_in_insert_mode)
{
- turn_on_insert ();
+ tty_turn_on_insert (tty);
}
else
{
- turn_off_insert ();
- OUTPUT_IF (TS_delete_mode);
+ tty_turn_off_insert (tty);
+ OUTPUT_IF (tty, tty->TS_delete_mode);
}
- if (TS_del_multi_chars)
+ if (tty->TS_del_multi_chars)
{
- buf = tparam (TS_del_multi_chars, 0, 0, n);
- OUTPUT1 (buf);
+ buf = tparam (tty->TS_del_multi_chars, 0, 0, n);
+ OUTPUT1 (tty, buf);
xfree (buf);
}
else
for (i = 0; i < n; i++)
- OUTPUT1 (TS_del_char);
- if (!delete_in_insert_mode)
- OUTPUT_IF (TS_end_delete_mode);
+ OUTPUT1 (tty, tty->TS_del_char);
+ if (!tty->delete_in_insert_mode)
+ OUTPUT_IF (tty, tty->TS_end_delete_mode);
}
-/* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
+/* An implementation of ins_del_lines for termcap frames. */
-void
-ins_del_lines (vpos, n)
- int vpos, n;
+static void
+tty_ins_del_lines (struct frame *f, int vpos, int n)
{
- char *multi = n > 0 ? TS_ins_multi_lines : TS_del_multi_lines;
- char *single = n > 0 ? TS_ins_line : TS_del_line;
- char *scroll = n > 0 ? TS_rev_scroll : TS_fwd_scroll;
- struct frame *sf;
+ struct tty_display_info *tty = FRAME_TTY (f);
+ char *multi = n > 0 ? tty->TS_ins_multi_lines : tty->TS_del_multi_lines;
+ char *single = n > 0 ? tty->TS_ins_line : tty->TS_del_line;
+ char *scroll = n > 0 ? tty->TS_rev_scroll : tty->TS_fwd_scroll;
register int i = n > 0 ? n : -n;
register char *buf;
- if (ins_del_lines_hook && ! FRAME_TERMCAP_P (updating_frame))
- {
- (*ins_del_lines_hook) (vpos, n);
- return;
- }
-
- sf = XFRAME (selected_frame);
-
/* If the lines below the insertion are being pushed
into the end of the window, this is the same as clearing;
and we know the lines are already clear, since the matching
@@ -1246,45 +948,49 @@ ins_del_lines (vpos, n)
/* If the lines below the deletion are blank lines coming
out of the end of the window, don't bother,
as there will be a matching inslines later that will flush them. */
- if (scroll_region_ok && vpos + i >= specified_window)
+ if (FRAME_SCROLL_REGION_OK (f)
+ && vpos + i >= tty->specified_window)
return;
- if (!memory_below_frame && vpos + i >= FRAME_LINES (sf))
+ if (!FRAME_MEMORY_BELOW_FRAME (f)
+ && vpos + i >= FRAME_LINES (f))
return;
-
+
if (multi)
{
- raw_cursor_to (vpos, 0);
- background_highlight ();
+ raw_cursor_to (f, vpos, 0);
+ tty_background_highlight (tty);
buf = tparam (multi, 0, 0, i);
- OUTPUT (buf);
+ OUTPUT (tty, buf);
xfree (buf);
}
else if (single)
{
- raw_cursor_to (vpos, 0);
- background_highlight ();
+ raw_cursor_to (f, vpos, 0);
+ tty_background_highlight (tty);
while (--i >= 0)
- OUTPUT (single);
- if (TF_teleray)
- curX = 0;
+ OUTPUT (tty, single);
+ if (tty->TF_teleray)
+ curX (tty) = 0;
}
else
{
- set_scroll_region (vpos, specified_window);
+ tty_set_scroll_region (f, vpos, tty->specified_window);
if (n < 0)
- raw_cursor_to (specified_window - 1, 0);
+ raw_cursor_to (f, tty->specified_window - 1, 0);
else
- raw_cursor_to (vpos, 0);
- background_highlight ();
+ raw_cursor_to (f, vpos, 0);
+ tty_background_highlight (tty);
while (--i >= 0)
- OUTPUTL (scroll, specified_window - vpos);
- set_scroll_region (0, specified_window);
+ OUTPUTL (tty, scroll, tty->specified_window - vpos);
+ tty_set_scroll_region (f, 0, tty->specified_window);
}
-
- if (!scroll_region_ok && memory_below_frame && n < 0)
+
+ if (!FRAME_SCROLL_REGION_OK (f)
+ && FRAME_MEMORY_BELOW_FRAME (f)
+ && n < 0)
{
- cursor_to (FRAME_LINES (sf) + n, 0);
- clear_to_end ();
+ cursor_to (f, FRAME_LINES (f) + n, 0);
+ clear_to_end (f);
}
}
@@ -1292,8 +998,7 @@ ins_del_lines (vpos, n)
not counting any line-dependent padding. */
int
-string_cost (str)
- char *str;
+string_cost (char *str)
{
cost = 0;
if (str)
@@ -1305,8 +1010,7 @@ string_cost (str)
counting any line-dependent padding at one line. */
static int
-string_cost_one_line (str)
- char *str;
+string_cost_one_line (char *str)
{
cost = 0;
if (str)
@@ -1318,8 +1022,7 @@ string_cost_one_line (str)
in tenths of characters. */
int
-per_line_cost (str)
- register char *str;
+per_line_cost (char *str)
{
cost = 0;
if (str)
@@ -1342,26 +1045,26 @@ int *char_ins_del_vector;
/* ARGSUSED */
static void
-calculate_ins_del_char_costs (frame)
- FRAME_PTR frame;
+calculate_ins_del_char_costs (struct frame *f)
{
+ struct tty_display_info *tty = FRAME_TTY (f);
int ins_startup_cost, del_startup_cost;
int ins_cost_per_char, del_cost_per_char;
register int i;
register int *p;
- if (TS_ins_multi_chars)
+ if (tty->TS_ins_multi_chars)
{
ins_cost_per_char = 0;
- ins_startup_cost = string_cost_one_line (TS_ins_multi_chars);
+ ins_startup_cost = string_cost_one_line (tty->TS_ins_multi_chars);
}
- else if (TS_ins_char || TS_pad_inserted_char
- || (TS_insert_mode && TS_end_insert_mode))
+ else if (tty->TS_ins_char || tty->TS_pad_inserted_char
+ || (tty->TS_insert_mode && tty->TS_end_insert_mode))
{
- ins_startup_cost = (30 * (string_cost (TS_insert_mode)
- + string_cost (TS_end_insert_mode))) / 100;
- ins_cost_per_char = (string_cost_one_line (TS_ins_char)
- + string_cost_one_line (TS_pad_inserted_char));
+ ins_startup_cost = (30 * (string_cost (tty->TS_insert_mode)
+ + string_cost (tty->TS_end_insert_mode))) / 100;
+ ins_cost_per_char = (string_cost_one_line (tty->TS_ins_char)
+ + string_cost_one_line (tty->TS_pad_inserted_char));
}
else
{
@@ -1369,18 +1072,18 @@ calculate_ins_del_char_costs (frame)
ins_cost_per_char = 0;
}
- if (TS_del_multi_chars)
+ if (tty->TS_del_multi_chars)
{
del_cost_per_char = 0;
- del_startup_cost = string_cost_one_line (TS_del_multi_chars);
+ del_startup_cost = string_cost_one_line (tty->TS_del_multi_chars);
}
- else if (TS_del_char)
+ else if (tty->TS_del_char)
{
- del_startup_cost = (string_cost (TS_delete_mode)
- + string_cost (TS_end_delete_mode));
- if (delete_in_insert_mode)
+ del_startup_cost = (string_cost (tty->TS_delete_mode)
+ + string_cost (tty->TS_end_delete_mode));
+ if (tty->delete_in_insert_mode)
del_startup_cost /= 2;
- del_cost_per_char = string_cost_one_line (TS_del_char);
+ del_cost_per_char = string_cost_one_line (tty->TS_del_char);
}
else
{
@@ -1389,75 +1092,80 @@ calculate_ins_del_char_costs (frame)
}
/* Delete costs are at negative offsets */
- p = &char_ins_del_cost (frame)[0];
- for (i = FRAME_COLS (frame); --i >= 0;)
+ p = &char_ins_del_cost (f)[0];
+ for (i = FRAME_COLS (f); --i >= 0;)
*--p = (del_startup_cost += del_cost_per_char);
/* Doing nothing is free */
- p = &char_ins_del_cost (frame)[0];
+ p = &char_ins_del_cost (f)[0];
*p++ = 0;
/* Insert costs are at positive offsets */
- for (i = FRAME_COLS (frame); --i >= 0;)
+ for (i = FRAME_COLS (f); --i >= 0;)
*p++ = (ins_startup_cost += ins_cost_per_char);
}
void
-calculate_costs (frame)
- FRAME_PTR frame;
+calculate_costs (struct frame *frame)
{
- register char *f = (TS_set_scroll_region
- ? TS_set_scroll_region
- : TS_set_scroll_region_1);
-
FRAME_COST_BAUD_RATE (frame) = baud_rate;
- scroll_region_cost = string_cost (f);
+ if (FRAME_TERMCAP_P (frame))
+ {
+ struct tty_display_info *tty = FRAME_TTY (frame);
+ register char *f = (tty->TS_set_scroll_region
+ ? tty->TS_set_scroll_region
+ : tty->TS_set_scroll_region_1);
- /* These variables are only used for terminal stuff. They are allocated
- once for the terminal frame of X-windows emacs, but not used afterwards.
+ FRAME_SCROLL_REGION_COST (frame) = string_cost (f);
- char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
- X turns off char_ins_del_ok. */
+ tty->costs_set = 1;
- max_frame_lines = max (max_frame_lines, FRAME_LINES (frame));
- max_frame_cols = max (max_frame_cols, FRAME_COLS (frame));
+ /* These variables are only used for terminal stuff. They are
+ allocated once for the terminal frame of X-windows emacs, but not
+ used afterwards.
- costs_set = 1;
+ char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
+ X turns off char_ins_del_ok. */
- if (char_ins_del_vector != 0)
- char_ins_del_vector
- = (int *) xrealloc (char_ins_del_vector,
- (sizeof (int)
- + 2 * max_frame_cols * sizeof (int)));
- else
- char_ins_del_vector
- = (int *) xmalloc (sizeof (int)
- + 2 * max_frame_cols * sizeof (int));
-
- bzero (char_ins_del_vector, (sizeof (int)
- + 2 * max_frame_cols * sizeof (int)));
-
- if (f && (!TS_ins_line && !TS_del_line))
- do_line_insertion_deletion_costs (frame,
- TS_rev_scroll, TS_ins_multi_lines,
- TS_fwd_scroll, TS_del_multi_lines,
- f, f, 1);
- else
- do_line_insertion_deletion_costs (frame,
- TS_ins_line, TS_ins_multi_lines,
- TS_del_line, TS_del_multi_lines,
- 0, 0, 1);
+ max_frame_lines = max (max_frame_lines, FRAME_LINES (frame));
+ max_frame_cols = max (max_frame_cols, FRAME_COLS (frame));
- calculate_ins_del_char_costs (frame);
+ if (char_ins_del_vector != 0)
+ char_ins_del_vector
+ = (int *) xrealloc (char_ins_del_vector,
+ (sizeof (int)
+ + 2 * max_frame_cols * sizeof (int)));
+ else
+ char_ins_del_vector
+ = (int *) xmalloc (sizeof (int)
+ + 2 * max_frame_cols * sizeof (int));
- /* Don't use TS_repeat if its padding is worse than sending the chars */
- if (TS_repeat && per_line_cost (TS_repeat) * baud_rate < 9000)
- RPov = string_cost (TS_repeat);
- else
- RPov = FRAME_COLS (frame) * 2;
+ bzero (char_ins_del_vector, (sizeof (int)
+ + 2 * max_frame_cols * sizeof (int)));
- cmcostinit (); /* set up cursor motion costs */
+
+ if (f && (!tty->TS_ins_line && !tty->TS_del_line))
+ do_line_insertion_deletion_costs (frame,
+ tty->TS_rev_scroll, tty->TS_ins_multi_lines,
+ tty->TS_fwd_scroll, tty->TS_del_multi_lines,
+ f, f, 1);
+ else
+ do_line_insertion_deletion_costs (frame,
+ tty->TS_ins_line, tty->TS_ins_multi_lines,
+ tty->TS_del_line, tty->TS_del_multi_lines,
+ 0, 0, 1);
+
+ calculate_ins_del_char_costs (frame);
+
+ /* Don't use TS_repeat if its padding is worse than sending the chars */
+ if (tty->TS_repeat && per_line_cost (tty->TS_repeat) * baud_rate < 9000)
+ tty->RPov = string_cost (tty->TS_repeat);
+ else
+ tty->RPov = FRAME_COLS (frame) * 2;
+
+ cmcostinit (FRAME_TTY (frame)); /* set up cursor motion costs */
+ }
}
struct fkey_table {
@@ -1567,16 +1275,18 @@ static struct fkey_table keys[] =
{"!3", "S-undo"} /*shifted undo key*/
};
-static char **term_get_fkeys_arg;
+static char **term_get_fkeys_address;
+static KBOARD *term_get_fkeys_kboard;
static Lisp_Object term_get_fkeys_1 ();
/* Find the escape codes sent by the function keys for Vfunction_key_map.
This function scans the termcap function key sequence entries, and
adds entries to Vfunction_key_map for each function key it finds. */
-void
-term_get_fkeys (address)
+static void
+term_get_fkeys (address, kboard)
char **address;
+ KBOARD *kboard;
{
/* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
errors during the call. The only errors should be from Fdefine_key
@@ -1587,7 +1297,8 @@ term_get_fkeys (address)
refusing to run at all on such a terminal. */
extern Lisp_Object Fidentity ();
- term_get_fkeys_arg = address;
+ term_get_fkeys_address = address;
+ term_get_fkeys_kboard = kboard;
internal_condition_case (term_get_fkeys_1, Qerror, Fidentity);
}
@@ -1596,17 +1307,18 @@ term_get_fkeys_1 ()
{
int i;
- char **address = term_get_fkeys_arg;
-
+ char **address = term_get_fkeys_address;
+ KBOARD *kboard = term_get_fkeys_kboard;
+
/* This can happen if CANNOT_DUMP or with strange options. */
if (!initialized)
- Vfunction_key_map = Fmake_sparse_keymap (Qnil);
+ kboard->Vlocal_function_key_map = Fmake_sparse_keymap (Qnil);
for (i = 0; i < (sizeof (keys)/sizeof (keys[0])); i++)
{
char *sequence = tgetstr (keys[i].cap, address);
if (sequence)
- Fdefine_key (Vfunction_key_map, build_string (sequence),
+ Fdefine_key (kboard->Vlocal_function_key_map, build_string (sequence),
Fmake_vector (make_number (1),
intern (keys[i].name)));
}
@@ -1626,13 +1338,13 @@ term_get_fkeys_1 ()
if (k0)
/* Define f0 first, so that f10 takes precedence in case the
key sequences happens to be the same. */
- Fdefine_key (Vfunction_key_map, build_string (k0),
+ Fdefine_key (kboard->Vlocal_function_key_map, build_string (k0),
Fmake_vector (make_number (1), intern ("f0")));
- Fdefine_key (Vfunction_key_map, build_string (k_semi),
+ Fdefine_key (kboard->Vlocal_function_key_map, build_string (k_semi),
Fmake_vector (make_number (1), intern ("f10")));
}
else if (k0)
- Fdefine_key (Vfunction_key_map, build_string (k0),
+ Fdefine_key (kboard->Vlocal_function_key_map, build_string (k0),
Fmake_vector (make_number (1), intern (k0_name)));
}
@@ -1655,7 +1367,7 @@ term_get_fkeys_1 ()
if (sequence)
{
sprintf (fkey, "f%d", i);
- Fdefine_key (Vfunction_key_map, build_string (sequence),
+ Fdefine_key (kboard->Vlocal_function_key_map, build_string (sequence),
Fmake_vector (make_number (1),
intern (fkey)));
}
@@ -1671,10 +1383,10 @@ term_get_fkeys_1 ()
if (!tgetstr (cap1, address)) \
{ \
char *sequence = tgetstr (cap2, address); \
- if (sequence) \
- Fdefine_key (Vfunction_key_map, build_string (sequence), \
- Fmake_vector (make_number (1), \
- intern (sym))); \
+ if (sequence) \
+ Fdefine_key (kboard->Vlocal_function_key_map, build_string (sequence), \
+ Fmake_vector (make_number (1), \
+ intern (sym))); \
}
/* if there's no key_next keycap, map key_npage to `next' keysym */
@@ -2030,10 +1742,10 @@ produce_special_glyphs (it, what)
from them. Some display attributes may not be used together with
color; the termcap capability `NC' specifies which ones. */
-#define MAY_USE_WITH_COLORS_P(ATTR) \
- (TN_max_colors > 0 \
- ? (TN_no_color_video & (ATTR)) == 0 \
- : 1)
+#define MAY_USE_WITH_COLORS_P(tty, ATTR) \
+ (tty->TN_max_colors > 0 \
+ ? (tty->TN_no_color_video & (ATTR)) == 0 \
+ : 1)
/* Turn appearances of face FACE_ID on tty frame F on.
FACE_ID is a realized face ID number, in the face cache. */
@@ -2046,12 +1758,13 @@ turn_on_face (f, face_id)
struct face *face = FACE_FROM_ID (f, face_id);
long fg = face->foreground;
long bg = face->background;
+ struct tty_display_info *tty = FRAME_TTY (f);
/* Do this first because TS_end_standout_mode may be the same
as TS_exit_attribute_mode, which turns all appearances off. */
- if (MAY_USE_WITH_COLORS_P (NC_REVERSE))
+ if (MAY_USE_WITH_COLORS_P (tty, NC_REVERSE))
{
- if (TN_max_colors > 0)
+ if (tty->TN_max_colors > 0)
{
if (fg >= 0 && bg >= 0)
{
@@ -2065,13 +1778,13 @@ turn_on_face (f, face_id)
{
if (fg == FACE_TTY_DEFAULT_FG_COLOR
|| bg == FACE_TTY_DEFAULT_BG_COLOR)
- toggle_highlight ();
+ tty_toggle_highlight (tty);
}
else
{
if (fg == FACE_TTY_DEFAULT_BG_COLOR
|| bg == FACE_TTY_DEFAULT_FG_COLOR)
- toggle_highlight ();
+ tty_toggle_highlight (tty);
}
}
else
@@ -2082,55 +1795,55 @@ turn_on_face (f, face_id)
{
if (fg == FACE_TTY_DEFAULT_FG_COLOR
|| bg == FACE_TTY_DEFAULT_BG_COLOR)
- toggle_highlight ();
+ tty_toggle_highlight (tty);
}
else
{
if (fg == FACE_TTY_DEFAULT_BG_COLOR
|| bg == FACE_TTY_DEFAULT_FG_COLOR)
- toggle_highlight ();
+ tty_toggle_highlight (tty);
}
}
}
if (face->tty_bold_p)
{
- if (MAY_USE_WITH_COLORS_P (NC_BOLD))
- OUTPUT1_IF (TS_enter_bold_mode);
+ if (MAY_USE_WITH_COLORS_P (tty, NC_BOLD))
+ OUTPUT1_IF (tty, tty->TS_enter_bold_mode);
}
else if (face->tty_dim_p)
- if (MAY_USE_WITH_COLORS_P (NC_DIM))
- OUTPUT1_IF (TS_enter_dim_mode);
+ if (MAY_USE_WITH_COLORS_P (tty, NC_DIM))
+ OUTPUT1_IF (tty, tty->TS_enter_dim_mode);
/* Alternate charset and blinking not yet used. */
if (face->tty_alt_charset_p
- && MAY_USE_WITH_COLORS_P (NC_ALT_CHARSET))
- OUTPUT1_IF (TS_enter_alt_charset_mode);
+ && MAY_USE_WITH_COLORS_P (tty, NC_ALT_CHARSET))
+ OUTPUT1_IF (tty, tty->TS_enter_alt_charset_mode);
if (face->tty_blinking_p
- && MAY_USE_WITH_COLORS_P (NC_BLINK))
- OUTPUT1_IF (TS_enter_blink_mode);
+ && MAY_USE_WITH_COLORS_P (tty, NC_BLINK))
+ OUTPUT1_IF (tty, tty->TS_enter_blink_mode);
- if (face->tty_underline_p && MAY_USE_WITH_COLORS_P (NC_UNDERLINE))
- OUTPUT1_IF (TS_enter_underline_mode);
+ if (face->tty_underline_p && MAY_USE_WITH_COLORS_P (tty, NC_UNDERLINE))
+ OUTPUT1_IF (tty, tty->TS_enter_underline_mode);
- if (TN_max_colors > 0)
+ if (tty->TN_max_colors > 0)
{
char *ts, *p;
- ts = standout_mode ? TS_set_background : TS_set_foreground;
+ ts = tty->standout_mode ? tty->TS_set_background : tty->TS_set_foreground;
if (fg >= 0 && ts)
{
- p = tparam (ts, NULL, 0, (int) fg);
- OUTPUT (p);
+ p = tparam (ts, NULL, 0, (int) fg);
+ OUTPUT (tty, p);
xfree (p);
}
- ts = standout_mode ? TS_set_foreground : TS_set_background;
+ ts = tty->standout_mode ? tty->TS_set_foreground : tty->TS_set_background;
if (bg >= 0 && ts)
{
- p = tparam (ts, NULL, 0, (int) bg);
- OUTPUT (p);
+ p = tparam (ts, NULL, 0, (int) bg);
+ OUTPUT (tty, p);
xfree (p);
}
}
@@ -2145,10 +1858,11 @@ turn_off_face (f, face_id)
int face_id;
{
struct face *face = FACE_FROM_ID (f, face_id);
+ struct tty_display_info *tty = FRAME_TTY (f);
xassert (face != NULL);
- if (TS_exit_attribute_mode)
+ if (tty->TS_exit_attribute_mode)
{
/* Capability "me" will turn off appearance modes double-bright,
half-bright, reverse-video, standout, underline. It may or
@@ -2160,32 +1874,32 @@ turn_off_face (f, face_id)
|| face->tty_blinking_p
|| face->tty_underline_p)
{
- OUTPUT1_IF (TS_exit_attribute_mode);
- if (strcmp (TS_exit_attribute_mode, TS_end_standout_mode) == 0)
- standout_mode = 0;
+ OUTPUT1_IF (tty, tty->TS_exit_attribute_mode);
+ if (strcmp (tty->TS_exit_attribute_mode, tty->TS_end_standout_mode) == 0)
+ tty->standout_mode = 0;
}
if (face->tty_alt_charset_p)
- OUTPUT_IF (TS_exit_alt_charset_mode);
+ OUTPUT_IF (tty, tty->TS_exit_alt_charset_mode);
}
else
{
/* If we don't have "me" we can only have those appearances
that have exit sequences defined. */
if (face->tty_alt_charset_p)
- OUTPUT_IF (TS_exit_alt_charset_mode);
+ OUTPUT_IF (tty, tty->TS_exit_alt_charset_mode);
if (face->tty_underline_p)
- OUTPUT_IF (TS_exit_underline_mode);
+ OUTPUT_IF (tty, tty->TS_exit_underline_mode);
}
/* Switch back to default colors. */
- if (TN_max_colors > 0
+ if (tty->TN_max_colors > 0
&& ((face->foreground != FACE_TTY_DEFAULT_COLOR
&& face->foreground != FACE_TTY_DEFAULT_FG_COLOR)
|| (face->background != FACE_TTY_DEFAULT_COLOR
&& face->background != FACE_TTY_DEFAULT_BG_COLOR)))
- OUTPUT1_IF (TS_orig_pair);
+ OUTPUT1_IF (tty, tty->TS_orig_pair);
}
@@ -2194,46 +1908,61 @@ turn_off_face (f, face_id)
colors FG and BG. */
int
-tty_capable_p (f, caps, fg, bg)
- struct frame *f;
+tty_capable_p (tty, caps, fg, bg)
+ struct tty_display_info *tty;
unsigned caps;
unsigned long fg, bg;
{
-#define TTY_CAPABLE_P_TRY(cap, TS, NC_bit) \
- if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(NC_bit))) \
+#define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \
+ if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \
return 0;
- TTY_CAPABLE_P_TRY (TTY_CAP_INVERSE, TS_standout_mode, NC_REVERSE);
- TTY_CAPABLE_P_TRY (TTY_CAP_UNDERLINE, TS_enter_underline_mode, NC_UNDERLINE);
- TTY_CAPABLE_P_TRY (TTY_CAP_BOLD, TS_enter_bold_mode, NC_BOLD);
- TTY_CAPABLE_P_TRY (TTY_CAP_DIM, TS_enter_dim_mode, NC_DIM);
- TTY_CAPABLE_P_TRY (TTY_CAP_BLINK, TS_enter_blink_mode, NC_BLINK);
- TTY_CAPABLE_P_TRY (TTY_CAP_ALT_CHARSET, TS_enter_alt_charset_mode, NC_ALT_CHARSET);
+ TTY_CAPABLE_P_TRY (tty, TTY_CAP_INVERSE, tty->TS_standout_mode, NC_REVERSE);
+ TTY_CAPABLE_P_TRY (tty, TTY_CAP_UNDERLINE, tty->TS_enter_underline_mode, NC_UNDERLINE);
+ TTY_CAPABLE_P_TRY (tty, TTY_CAP_BOLD, tty->TS_enter_bold_mode, NC_BOLD);
+ TTY_CAPABLE_P_TRY (tty, TTY_CAP_DIM, tty->TS_enter_dim_mode, NC_DIM);
+ TTY_CAPABLE_P_TRY (tty, TTY_CAP_BLINK, tty->TS_enter_blink_mode, NC_BLINK);
+ TTY_CAPABLE_P_TRY (tty, TTY_CAP_ALT_CHARSET, tty->TS_enter_alt_charset_mode, NC_ALT_CHARSET);
/* We can do it! */
return 1;
}
-
/* Return non-zero if the terminal is capable to display colors. */
DEFUN ("tty-display-color-p", Ftty_display_color_p, Stty_display_color_p,
0, 1, 0,
- doc: /* Return non-nil if TTY can display colors on DISPLAY. */)
- (display)
- Lisp_Object display;
+ doc: /* Return non-nil if the tty device TERMINAL can display colors.
+
+TERMINAL can be a terminal id, a frame or nil (meaning the selected
+frame's terminal). This function always returns nil if TERMINAL
+is not on a tty device. */)
+ (terminal)
+ Lisp_Object terminal;
{
- return TN_max_colors > 0 ? Qt : Qnil;
+ struct terminal *t = get_tty_terminal (terminal, 0);
+ if (!t)
+ return Qnil;
+ else
+ return t->display_info.tty->TN_max_colors > 0 ? Qt : Qnil;
}
/* Return the number of supported colors. */
DEFUN ("tty-display-color-cells", Ftty_display_color_cells,
Stty_display_color_cells, 0, 1, 0,
- doc: /* Return the number of colors supported by TTY on DISPLAY. */)
- (display)
- Lisp_Object display;
+ doc: /* Return the number of colors supported by the tty device TERMINAL.
+
+TERMINAL can be a terminal id, a frame or nil (meaning the selected
+frame's terminal). This function always returns 0 if TERMINAL
+is not on a tty device. */)
+ (terminal)
+ Lisp_Object terminal;
{
- return make_number (TN_max_colors);
+ struct terminal *t = get_tty_terminal (terminal, 0);
+ if (!t)
+ return make_number (0);
+ else
+ return make_number (t->display_info.tty->TN_max_colors);
}
#ifndef WINDOWSNT
@@ -2251,48 +1980,46 @@ static char *default_set_background;
/* Save or restore the default color-related capabilities of this
terminal. */
static void
-tty_default_color_capabilities (save)
- int save;
+tty_default_color_capabilities (struct tty_display_info *tty, int save)
{
if (save)
{
if (default_orig_pair)
xfree (default_orig_pair);
- default_orig_pair = TS_orig_pair ? xstrdup (TS_orig_pair) : NULL;
+ default_orig_pair = tty->TS_orig_pair ? xstrdup (tty->TS_orig_pair) : NULL;
if (default_set_foreground)
xfree (default_set_foreground);
- default_set_foreground = TS_set_foreground ? xstrdup (TS_set_foreground)
+ default_set_foreground = tty->TS_set_foreground ? xstrdup (tty->TS_set_foreground)
: NULL;
if (default_set_background)
xfree (default_set_background);
- default_set_background = TS_set_background ? xstrdup (TS_set_background)
+ default_set_background = tty->TS_set_background ? xstrdup (tty->TS_set_background)
: NULL;
- default_max_colors = TN_max_colors;
- default_max_pairs = TN_max_pairs;
- default_no_color_video = TN_no_color_video;
+ default_max_colors = tty->TN_max_colors;
+ default_max_pairs = tty->TN_max_pairs;
+ default_no_color_video = tty->TN_no_color_video;
}
else
{
- TS_orig_pair = default_orig_pair;
- TS_set_foreground = default_set_foreground;
- TS_set_background = default_set_background;
- TN_max_colors = default_max_colors;
- TN_max_pairs = default_max_pairs;
- TN_no_color_video = default_no_color_video;
+ tty->TS_orig_pair = default_orig_pair;
+ tty->TS_set_foreground = default_set_foreground;
+ tty->TS_set_background = default_set_background;
+ tty->TN_max_colors = default_max_colors;
+ tty->TN_max_pairs = default_max_pairs;
+ tty->TN_no_color_video = default_no_color_video;
}
}
/* Setup one of the standard tty color schemes according to MODE.
MODE's value is generally the number of colors which we want to
support; zero means set up for the default capabilities, the ones
- we saw at term_init time; -1 means turn off color support. */
-void
-tty_setup_colors (mode)
- int mode;
+ we saw at init_tty time; -1 means turn off color support. */
+static void
+tty_setup_colors (struct tty_display_info *tty, int mode)
{
/* Canonicalize all negative values of MODE. */
if (mode < -1)
@@ -2301,27 +2028,27 @@ tty_setup_colors (mode)
switch (mode)
{
case -1: /* no colors at all */
- TN_max_colors = 0;
- TN_max_pairs = 0;
- TN_no_color_video = 0;
- TS_set_foreground = TS_set_background = TS_orig_pair = NULL;
+ tty->TN_max_colors = 0;
+ tty->TN_max_pairs = 0;
+ tty->TN_no_color_video = 0;
+ tty->TS_set_foreground = tty->TS_set_background = tty->TS_orig_pair = NULL;
break;
case 0: /* default colors, if any */
default:
- tty_default_color_capabilities (0);
+ tty_default_color_capabilities (tty, 0);
break;
case 8: /* 8 standard ANSI colors */
- TS_orig_pair = "\033[0m";
+ tty->TS_orig_pair = "\033[0m";
#ifdef TERMINFO
- TS_set_foreground = "\033[3%p1%dm";
- TS_set_background = "\033[4%p1%dm";
+ tty->TS_set_foreground = "\033[3%p1%dm";
+ tty->TS_set_background = "\033[4%p1%dm";
#else
- TS_set_foreground = "\033[3%dm";
- TS_set_background = "\033[4%dm";
+ tty->TS_set_foreground = "\033[3%dm";
+ tty->TS_set_background = "\033[4%dm";
#endif
- TN_max_colors = 8;
- TN_max_pairs = 64;
- TN_no_color_video = 0;
+ tty->TN_max_colors = 8;
+ tty->TN_max_pairs = 64;
+ tty->TN_no_color_video = 0;
break;
}
}
@@ -2372,7 +2099,7 @@ set_tty_color_mode (f, val)
if (mode != old_mode)
{
- tty_setup_colors (mode);
+ tty_setup_colors (FRAME_TTY (f), mode);
/* This recomputes all the faces given the new color
definitions. */
call0 (intern ("tty-set-up-initial-frame-faces"));
@@ -2383,6 +2110,241 @@ set_tty_color_mode (f, val)
#endif /* !WINDOWSNT */
+
+/* Return the tty display object specified by TERMINAL. */
+
+struct terminal *
+get_tty_terminal (Lisp_Object terminal, int throw)
+{
+ struct terminal *t = get_terminal (terminal, throw);
+
+ if (t && t->type == output_initial)
+ return NULL;
+
+ if (t && t->type != output_termcap)
+ {
+ if (throw)
+ error ("Device %d is not a termcap terminal device", t->id);
+ else
+ return NULL;
+ }
+
+ return t;
+}
+
+/* Return an active termcap device that uses the tty device with the
+ given name.
+
+ This function ignores suspended devices.
+
+ Returns NULL if the named terminal device is not opened. */
+
+struct terminal *
+get_named_tty (name)
+ char *name;
+{
+ struct terminal *t;
+
+ if (!name)
+ abort ();
+
+ for (t = terminal_list; t; t = t->next_terminal)
+ {
+ if (t->type == output_termcap
+ && !strcmp (t->display_info.tty->name, name)
+ && TERMINAL_ACTIVE_P (t))
+ return t;
+ }
+
+ return 0;
+}
+
+
+DEFUN ("tty-type", Ftty_type, Stty_type, 0, 1, 0,
+ doc: /* Return the type of the tty device that TERMINAL uses.
+Returns nil if TERMINAL is not on a tty device.
+
+TERMINAL can be a terminal id, a frame or nil (meaning the selected
+frame's terminal). */)
+ (terminal)
+ Lisp_Object terminal;
+{
+ struct terminal *t = get_terminal (terminal, 1);
+
+ if (t->type != output_termcap)
+ return Qnil;
+
+ if (t->display_info.tty->type)
+ return build_string (t->display_info.tty->type);
+ else
+ return Qnil;
+}
+
+DEFUN ("controlling-tty-p", Fcontrolling_tty_p, Scontrolling_tty_p, 0, 1, 0,
+ doc: /* Return non-nil if TERMINAL is on the controlling tty of the Emacs process.
+
+TERMINAL can be a terminal id, a frame or nil (meaning the selected
+frame's terminal). This function always returns nil if TERMINAL
+is not on a tty device. */)
+ (terminal)
+ Lisp_Object terminal;
+{
+ struct terminal *t = get_terminal (terminal, 1);
+
+ if (t->type != output_termcap || strcmp (t->display_info.tty->name, "/dev/tty"))
+ return Qnil;
+ else
+ return Qt;
+}
+
+DEFUN ("tty-no-underline", Ftty_no_underline, Stty_no_underline, 0, 1, 0,
+ doc: /* Declare that the tty used by TERMINAL does not handle underlining.
+This is used to override the terminfo data, for certain terminals that
+do not really do underlining, but say that they do. This function has
+no effect if used on a non-tty terminal.
+
+TERMINAL can be a terminal id, a frame or nil (meaning the selected
+frame's terminal). This function always returns nil if TERMINAL
+is not on a tty device. */)
+ (terminal)
+ Lisp_Object terminal;
+{
+ struct terminal *t = get_terminal (terminal, 1);
+
+ if (t->type == output_termcap)
+ t->display_info.tty->TS_enter_underline_mode = 0;
+ return Qnil;
+}
+
+
+
+DEFUN ("suspend-tty", Fsuspend_tty, Ssuspend_tty, 0, 1, 0,
+ doc: /* Suspend the terminal device TTY.
+
+The device is restored to its default state, and Emacs ceases all
+access to the tty device. Frames that use the device are not deleted,
+but input is not read from them and if they change, their display is
+not updated.
+
+TTY may be a terminal id, a frame, or nil for the terminal device of
+the currently selected frame.
+
+This function runs `suspend-tty-functions' after suspending the
+device. The functions are run with one arg, the id of the suspended
+terminal device.
+
+`suspend-tty' does nothing if it is called on a device that is already
+suspended.
+
+A suspended tty may be resumed by calling `resume-tty' on it. */)
+ (tty)
+ Lisp_Object tty;
+{
+ struct terminal *t = get_tty_terminal (tty, 1);
+ FILE *f;
+
+ if (!t)
+ error ("Unknown tty device");
+
+ f = t->display_info.tty->input;
+
+ if (f)
+ {
+ reset_sys_modes (t->display_info.tty);
+
+ delete_keyboard_wait_descriptor (fileno (f));
+
+ fclose (f);
+ if (f != t->display_info.tty->output)
+ fclose (t->display_info.tty->output);
+
+ t->display_info.tty->input = 0;
+ t->display_info.tty->output = 0;
+
+ if (FRAMEP (t->display_info.tty->top_frame))
+ FRAME_SET_VISIBLE (XFRAME (t->display_info.tty->top_frame), 0);
+
+ /* Run `suspend-tty-functions'. */
+ if (!NILP (Vrun_hooks))
+ {
+ Lisp_Object args[2];
+ args[0] = intern ("suspend-tty-functions");
+ args[1] = make_number (t->id);
+ Frun_hook_with_args (2, args);
+ }
+ }
+
+ /* Clear display hooks to prevent further output. */
+ clear_tty_hooks (t);
+
+ return Qnil;
+}
+
+DEFUN ("resume-tty", Fresume_tty, Sresume_tty, 0, 1, 0,
+ doc: /* Resume the previously suspended terminal device TTY.
+The terminal is opened and reinitialized. Frames that are on the
+suspended terminal are revived.
+
+It is an error to resume a terminal while another terminal is active
+on the same device.
+
+This function runs `resume-tty-functions' after resuming the terminal.
+The functions are run with one arg, the id of the resumed terminal
+device.
+
+`resume-tty' does nothing if it is called on a device that is not
+suspended.
+
+TTY may be a terminal id, a frame, or nil for the terminal device of
+the currently selected frame. */)
+ (tty)
+ Lisp_Object tty;
+{
+ struct terminal *t = get_tty_terminal (tty, 1);
+ int fd;
+
+ if (!t)
+ error ("Unknown tty device");
+
+ if (!t->display_info.tty->input)
+ {
+ if (get_named_tty (t->display_info.tty->name))
+ error ("Cannot resume display while another display is active on the same device");
+
+ fd = emacs_open (t->display_info.tty->name, O_RDWR | O_NOCTTY, 0);
+
+ if (fd == -1)
+ error ("Can not reopen tty device %s: %s", t->display_info.tty->name, strerror (errno));
+
+ if (strcmp (t->display_info.tty->name, "/dev/tty"))
+ dissociate_if_controlling_tty (fd);
+
+ t->display_info.tty->output = fdopen (fd, "w+");
+ t->display_info.tty->input = t->display_info.tty->output;
+
+ add_keyboard_wait_descriptor (fd);
+
+ if (FRAMEP (t->display_info.tty->top_frame))
+ FRAME_SET_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1);
+
+ init_sys_modes (t->display_info.tty);
+
+ /* Run `suspend-tty-functions'. */
+ if (!NILP (Vrun_hooks))
+ {
+ Lisp_Object args[2];
+ args[0] = intern ("resume-tty-functions");
+ args[1] = make_number (t->id);
+ Frun_hook_with_args (2, args);
+ }
+ }
+
+ set_tty_hooks (t);
+
+ return Qnil;
+}
+
+
/***********************************************************************
Mouse
***********************************************************************/
@@ -2409,6 +2371,9 @@ term_show_mouse_face (enum draw_glyphs_face draw)
int save_x, save_y;
int i;
+ struct frame *f = XFRAME (w->frame);
+ struct tty_display_info *tty = FRAME_TTY (f);
+
if (/* If window is in the process of being destroyed, don't bother
to do anything. */
w->current_matrix != NULL
@@ -2421,8 +2386,8 @@ term_show_mouse_face (enum draw_glyphs_face draw)
the highlight region. */
/* Save current cursor co-ordinates */
- save_y = curY;
- save_x = curX;
+ save_y = curY (tty);
+ save_x = curX (tty);
/* Note that mouse_face_beg_row etc. are window relative. */
for (i = mouse_face_beg_row; i <= mouse_face_end_row; i++)
@@ -2464,17 +2429,17 @@ term_show_mouse_face (enum draw_glyphs_face draw)
pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos
+ WINDOW_LEFT_EDGE_X (w);
- cursor_to (pos_y, pos_x);
+ cursor_to (f, pos_y, pos_x);
if (draw == DRAW_MOUSE_FACE)
{
- write_glyphs_with_face (row->glyphs[TEXT_AREA] + start_hpos,
+ tty_write_glyphs_with_face (f, row->glyphs[TEXT_AREA] + start_hpos,
nglyphs, mouse_face_face_id);
}
else /* draw == DRAW_NORMAL_TEXT */
- write_glyphs (row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
+ write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
}
- cursor_to (save_y, save_x);
+ cursor_to (f, save_y, save_x);
}
}
@@ -2924,9 +2889,9 @@ term_mouse_click (struct input_event *result, Gpm_Event *event,
}
int
-handle_one_term_event (Gpm_Event *event, struct input_event* hold_quit)
+handle_one_term_event (struct tty_display_info *tty, Gpm_Event *event, struct input_event* hold_quit)
{
- struct frame *f = SELECTED_FRAME ();
+ struct frame *f = XFRAME (tty->top_frame);
int fd;
struct input_event ie;
int do_help = 0;
@@ -3002,6 +2967,7 @@ DEFUN ("term-open-connection", Fterm_open_connection, Sterm_open_connection,
doc: /* Open a connection to Gpm. */)
()
{
+ struct tty_display_info *tty = FRAME_TTY (SELECTED_FRAME ());
Gpm_Connect connection;
connection.eventMask = ~0;
@@ -3010,13 +2976,16 @@ DEFUN ("term-open-connection", Fterm_open_connection, Sterm_open_connection,
connection.minMod = 0;
gpm_zerobased = 1;
- if (Gpm_Open (&connection, 0) < 0)
+ /* We only support GPM on the controlling tty. */
+ if (term_gpm || tty->terminal->id > 1
+ || Gpm_Open (&connection, 0) < 0)
return Qnil;
else
{
term_gpm = 1;
- reset_sys_modes ();
- init_sys_modes ();
+ gpm_tty = tty->terminal->id;
+ reset_sys_modes (tty);
+ init_sys_modes (tty);
add_gpm_wait_descriptor (gpm_fd);
return Qt;
}
@@ -3039,86 +3008,358 @@ DEFUN ("term-close-connection", Fterm_close_connection, Sterm_close_connection,
Initialization
***********************************************************************/
+/* Initialize the tty-dependent part of frame F. The frame must
+ already have its device initialized. */
+
void
-term_init (terminal_type)
- char *terminal_type;
+create_tty_output (struct frame *f)
+{
+ struct tty_output *t;
+
+ if (! FRAME_TERMCAP_P (f))
+ abort ();
+
+ t = xmalloc (sizeof (struct tty_output));
+ bzero (t, sizeof (struct tty_output));
+
+ t->display_info = FRAME_TERMINAL (f)->display_info.tty;
+
+ f->output_data.tty = t;
+}
+
+/* Delete the tty-dependent part of frame F. */
+
+static void
+delete_tty_output (struct frame *f)
+{
+ if (! FRAME_TERMCAP_P (f))
+ abort ();
+
+ xfree (f->output_data.tty);
+}
+
+
+
+static void
+clear_tty_hooks (struct terminal *terminal)
+{
+ terminal->rif = 0;
+ terminal->cursor_to_hook = 0;
+ terminal->raw_cursor_to_hook = 0;
+ terminal->clear_to_end_hook = 0;
+ terminal->clear_frame_hook = 0;
+ terminal->clear_end_of_line_hook = 0;
+ terminal->ins_del_lines_hook = 0;
+ terminal->insert_glyphs_hook = 0;
+ terminal->write_glyphs_hook = 0;
+ terminal->delete_glyphs_hook = 0;
+ terminal->ring_bell_hook = 0;
+ terminal->reset_terminal_modes_hook = 0;
+ terminal->set_terminal_modes_hook = 0;
+ terminal->update_begin_hook = 0;
+ terminal->update_end_hook = 0;
+ terminal->set_terminal_window_hook = 0;
+ terminal->mouse_position_hook = 0;
+ terminal->frame_rehighlight_hook = 0;
+ terminal->frame_raise_lower_hook = 0;
+ terminal->fullscreen_hook = 0;
+ terminal->set_vertical_scroll_bar_hook = 0;
+ terminal->condemn_scroll_bars_hook = 0;
+ terminal->redeem_scroll_bar_hook = 0;
+ terminal->judge_scroll_bars_hook = 0;
+ terminal->read_socket_hook = 0;
+ terminal->frame_up_to_date_hook = 0;
+
+ /* Leave these two set, or suspended frames are not deleted
+ correctly. */
+ terminal->delete_frame_hook = &delete_tty_output;
+ terminal->delete_terminal_hook = &delete_tty;
+}
+
+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 = &delete_tty_output;
+ terminal->delete_terminal_hook = &delete_tty;
+}
+
+/* Drop the controlling terminal if fd is the same device. */
+static void
+dissociate_if_controlling_tty (int fd)
{
- char *area;
+#ifndef WINDOWSNT
+ int pgid;
+ EMACS_GET_TTY_PGRP (fd, &pgid); /* If tcgetpgrp succeeds, fd is the ctty. */
+ if (pgid != -1)
+ {
+#if defined (USG) && !defined (BSD_PGRPS)
+ setpgrp ();
+ no_controlling_tty = 1;
+#else
+#ifdef TIOCNOTTY /* Try BSD ioctls. */
+ sigblock (sigmask (SIGTTOU));
+ fd = emacs_open ("/dev/tty", O_RDWR, 0);
+ if (fd != -1 && ioctl (fd, TIOCNOTTY, 0) != -1)
+ {
+ no_controlling_tty = 1;
+ }
+ if (fd != -1)
+ emacs_close (fd);
+ sigunblock (sigmask (SIGTTOU));
+#else
+ /* Unknown system. */
+ croak ();
+#endif /* ! TIOCNOTTY */
+#endif /* ! USG */
+ }
+#endif
+}
+
+static void maybe_fatal();
+
+/* Create a termcap display on the tty device with the given name and
+ type.
+
+ If NAME is NULL, then use the controlling tty, i.e., "/dev/tty".
+ Otherwise NAME should be a path to the tty device file,
+ e.g. "/dev/pts/7".
+
+ TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
+
+ If MUST_SUCCEED is true, then all errors are fatal. */
+
+struct terminal *
+init_tty (char *name, char *terminal_type, int must_succeed)
+{
+ char *area = NULL;
char **address = &area;
char *buffer = NULL;
int buffer_size = 4096;
- register char *p;
+ register char *p = NULL;
int status;
- struct frame *sf = XFRAME (selected_frame);
+ struct tty_display_info *tty = NULL;
+ struct terminal *terminal = NULL;
+ int ctty = 0; /* 1 if asked to open controlling tty. */
+
+ if (!terminal_type)
+ maybe_fatal (must_succeed, 0, 0,
+ "Unknown terminal type",
+ "Unknown terminal type");
+
+#ifndef WINDOWSNT
+ if (name == NULL)
+ name = "/dev/tty";
+ if (!strcmp (name, "/dev/tty"))
+ ctty = 1;
+
+ /* If we already have a terminal on the given device, use that. If
+ all such terminals are suspended, create a new one instead. */
+ /* XXX Perhaps this should be made explicit by having init_tty
+ always create a new terminal and separating terminal and frame
+ creation on Lisp level. */
+ terminal = get_named_tty (name);
+ if (terminal)
+ return terminal;
+#endif
+
+ terminal = create_terminal ();
+ tty = (struct tty_display_info *) xmalloc (sizeof (struct tty_display_info));
+ bzero (tty, sizeof (struct tty_display_info));
+ tty->next = tty_list;
+ tty_list = tty;
+
+ terminal->type = output_termcap;
+ terminal->display_info.tty = tty;
+ tty->terminal = terminal;
+
+ tty->Wcm = (struct cm *) xmalloc (sizeof (struct cm));
+ Wcm_clear (tty);
+
+#ifndef WINDOWSNT
+ set_tty_hooks (terminal);
+
+ {
+ int fd;
+ FILE *file;
+
+#ifdef O_IGNORE_CTTY
+ if (!ctty)
+ /* Open the terminal device. Don't recognize it as our
+ controlling terminal, and don't make it the controlling tty
+ if we don't have one at the moment. */
+ fd = emacs_open (name, O_RDWR | O_IGNORE_CTTY | O_NOCTTY, 0);
+ else
+#else
+ /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
+ defined on Hurd. On other systems, we need to explicitly
+ dissociate ourselves from the controlling tty when we want to
+ open a frame on the same terminal. */
+ fd = emacs_open (name, O_RDWR | O_NOCTTY, 0);
+#endif /* O_IGNORE_CTTY */
+
+ if (fd < 0)
+ maybe_fatal (must_succeed, buffer, terminal,
+ "Could not open file: %s",
+ "Could not open file: %s",
+ name);
+ if (!isatty (fd))
+ {
+ close (fd);
+ maybe_fatal (must_succeed, buffer, terminal,
+ "Not a tty device: %s",
+ "Not a tty device: %s",
+ name);
+ }
+
+#ifndef O_IGNORE_CTTY
+ if (!ctty)
+ dissociate_if_controlling_tty (fd);
+#endif
+
+ file = fdopen (fd, "w+");
+ tty->name = xstrdup (name);
+ terminal->name = xstrdup (name);
+ tty->input = file;
+ tty->output = file;
+ }
+
+ tty->type = xstrdup (terminal_type);
+
+ add_keyboard_wait_descriptor (fileno (tty->input));
+
+#endif
encode_terminal_bufsize = 0;
#ifdef HAVE_GPM
- mouse_position_hook = term_mouse_position;
+ terminal->mouse_position_hook = term_mouse_position;
Qmouse_face_window = Qnil;
#endif
#ifdef WINDOWSNT
initialize_w32_display ();
- Wcm_clear ();
+ /* XXX Can this be non-null? */
+ if (name)
+ {
+ tty->name = xstrdup (name);
+ terminal->name = xstrdup (name);
+ }
+ tty->type = xstrdup (terminal_type);
+
+ /* XXX not sure if this line is correct. If it is not set then we
+ crash in update_display_1. */
+ tty->output = stdout;
+
+ Wcm_clear (tty);
- area = (char *) xmalloc (2044);
+ area = (char *) xmalloc (2044); /* XXX this seems unused. */
- FrameRows = FRAME_LINES (sf);
- FrameCols = FRAME_COLS (sf);
- specified_window = FRAME_LINES (sf);
+ {
+ struct frame *f = XFRAME (selected_frame);
- delete_in_insert_mode = 1;
+ FrameRows (tty) = FRAME_LINES (f); /* XXX */
+ FrameCols (tty) = FRAME_COLS (f); /* XXX */
+ tty->specified_window = FRAME_LINES (f); /* XXX */
- UseTabs = 0;
- scroll_region_ok = 0;
+ FRAME_CAN_HAVE_SCROLL_BARS (f) = 0; /* XXX */
+ FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none; /* XXX */
+ }
+ tty->delete_in_insert_mode = 1;
- /* Seems to insert lines when it's not supposed to, messing
- up the display. In doing a trace, it didn't seem to be
- called much, so I don't think we're losing anything by
- turning it off. */
+ UseTabs (tty) = 0;
+ terminal->scroll_region_ok = 0;
- line_ins_del_ok = 0;
- char_ins_del_ok = 1;
+ /* Seems to insert lines when it's not supposed to, messing up the
+ display. In doing a trace, it didn't seem to be called much, so I
+ don't think we're losing anything by turning it off. */
+ terminal->line_ins_del_ok = 0;
+ terminal->char_ins_del_ok = 1;
baud_rate = 19200;
- FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0;
- FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none;
- TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */
+ tty->TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */
- return;
+ return terminal;
#else /* not WINDOWSNT */
- Wcm_clear ();
+ Wcm_clear (tty);
buffer = (char *) xmalloc (buffer_size);
+
+ /* On some systems, tgetent tries to access the controlling
+ terminal. */
+ sigblock (sigmask (SIGTTOU));
status = tgetent (buffer, terminal_type);
+ sigunblock (sigmask (SIGTTOU));
+
if (status < 0)
{
#ifdef TERMINFO
- fatal ("Cannot open terminfo database file");
+ maybe_fatal (must_succeed, buffer, terminal,
+ "Cannot open terminfo database file",
+ "Cannot open terminfo database file");
#else
- fatal ("Cannot open termcap database file");
+ maybe_fatal (must_succeed, buffer, terminal,
+ "Cannot open termcap database file",
+ "Cannot open termcap database file");
#endif
}
if (status == 0)
{
#ifdef TERMINFO
- fatal ("Terminal type %s is not defined.\n\
+ maybe_fatal (must_succeed, buffer, terminal,
+ "Terminal type %s is not defined",
+ "Terminal type %s is not defined.\n\
If that is not the actual type of terminal you have,\n\
use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
`setenv TERM ...') to specify the correct type. It may be necessary\n\
to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
- terminal_type);
+ terminal_type);
#else
- fatal ("Terminal type %s is not defined.\n\
+ maybe_fatal (must_succeed, buffer, terminal,
+ "Terminal type %s is not defined",
+ "Terminal type %s is not defined.\n\
If that is not the actual type of terminal you have,\n\
use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
`setenv TERM ...') to specify the correct type. It may be necessary\n\
to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
- terminal_type);
+ terminal_type);
#endif
}
@@ -3129,219 +3370,233 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
#endif
area = (char *) xmalloc (buffer_size);
- TS_ins_line = tgetstr ("al", address);
- TS_ins_multi_lines = tgetstr ("AL", address);
- TS_bell = tgetstr ("bl", address);
- BackTab = tgetstr ("bt", address);
- TS_clr_to_bottom = tgetstr ("cd", address);
- TS_clr_line = tgetstr ("ce", address);
- TS_clr_frame = tgetstr ("cl", address);
- ColPosition = NULL; /* tgetstr ("ch", address); */
- AbsPosition = tgetstr ("cm", address);
- CR = tgetstr ("cr", address);
- TS_set_scroll_region = tgetstr ("cs", address);
- TS_set_scroll_region_1 = tgetstr ("cS", address);
- RowPosition = tgetstr ("cv", address);
- TS_del_char = tgetstr ("dc", address);
- TS_del_multi_chars = tgetstr ("DC", address);
- TS_del_line = tgetstr ("dl", address);
- TS_del_multi_lines = tgetstr ("DL", address);
- TS_delete_mode = tgetstr ("dm", address);
- TS_end_delete_mode = tgetstr ("ed", address);
- TS_end_insert_mode = tgetstr ("ei", address);
- Home = tgetstr ("ho", address);
- TS_ins_char = tgetstr ("ic", address);
- TS_ins_multi_chars = tgetstr ("IC", address);
- TS_insert_mode = tgetstr ("im", address);
- TS_pad_inserted_char = tgetstr ("ip", address);
- TS_end_keypad_mode = tgetstr ("ke", address);
- TS_keypad_mode = tgetstr ("ks", address);
- LastLine = tgetstr ("ll", address);
- Right = tgetstr ("nd", address);
- Down = tgetstr ("do", address);
- if (!Down)
- Down = tgetstr ("nl", address); /* Obsolete name for "do" */
+ tty->TS_ins_line = tgetstr ("al", address);
+ tty->TS_ins_multi_lines = tgetstr ("AL", address);
+ tty->TS_bell = tgetstr ("bl", address);
+ BackTab (tty) = tgetstr ("bt", address);
+ tty->TS_clr_to_bottom = tgetstr ("cd", address);
+ tty->TS_clr_line = tgetstr ("ce", address);
+ tty->TS_clr_frame = tgetstr ("cl", address);
+ ColPosition (tty) = NULL; /* tgetstr ("ch", address); */
+ AbsPosition (tty) = tgetstr ("cm", address);
+ CR (tty) = tgetstr ("cr", address);
+ tty->TS_set_scroll_region = tgetstr ("cs", address);
+ tty->TS_set_scroll_region_1 = tgetstr ("cS", address);
+ RowPosition (tty) = tgetstr ("cv", address);
+ tty->TS_del_char = tgetstr ("dc", address);
+ tty->TS_del_multi_chars = tgetstr ("DC", address);
+ tty->TS_del_line = tgetstr ("dl", address);
+ tty->TS_del_multi_lines = tgetstr ("DL", address);
+ tty->TS_delete_mode = tgetstr ("dm", address);
+ tty->TS_end_delete_mode = tgetstr ("ed", address);
+ tty->TS_end_insert_mode = tgetstr ("ei", address);
+ Home (tty) = tgetstr ("ho", address);
+ tty->TS_ins_char = tgetstr ("ic", address);
+ tty->TS_ins_multi_chars = tgetstr ("IC", address);
+ tty->TS_insert_mode = tgetstr ("im", address);
+ tty->TS_pad_inserted_char = tgetstr ("ip", address);
+ tty->TS_end_keypad_mode = tgetstr ("ke", address);
+ tty->TS_keypad_mode = tgetstr ("ks", address);
+ LastLine (tty) = tgetstr ("ll", address);
+ Right (tty) = tgetstr ("nd", address);
+ Down (tty) = tgetstr ("do", address);
+ if (!Down (tty))
+ Down (tty) = tgetstr ("nl", address); /* Obsolete name for "do" */
#ifdef VMS
/* VMS puts a carriage return before each linefeed,
so it is not safe to use linefeeds. */
- if (Down && Down[0] == '\n' && Down[1] == '\0')
- Down = 0;
+ if (Down (tty) && Down (tty)[0] == '\n' && Down (tty)[1] == '\0')
+ Down (tty) = 0;
#endif /* VMS */
if (tgetflag ("bs"))
- Left = "\b"; /* can't possibly be longer! */
+ Left (tty) = "\b"; /* can't possibly be longer! */
else /* (Actually, "bs" is obsolete...) */
- Left = tgetstr ("le", address);
- if (!Left)
- Left = tgetstr ("bc", address); /* Obsolete name for "le" */
- TS_pad_char = tgetstr ("pc", address);
- TS_repeat = tgetstr ("rp", address);
- TS_end_standout_mode = tgetstr ("se", address);
- TS_fwd_scroll = tgetstr ("sf", address);
- TS_standout_mode = tgetstr ("so", address);
- TS_rev_scroll = tgetstr ("sr", address);
- Wcm.cm_tab = tgetstr ("ta", address);
- TS_end_termcap_modes = tgetstr ("te", address);
- TS_termcap_modes = tgetstr ("ti", address);
- Up = tgetstr ("up", address);
- TS_visible_bell = tgetstr ("vb", address);
- TS_cursor_normal = tgetstr ("ve", address);
- TS_cursor_visible = tgetstr ("vs", address);
- TS_cursor_invisible = tgetstr ("vi", address);
- TS_set_window = tgetstr ("wi", address);
-
- TS_enter_underline_mode = tgetstr ("us", address);
- TS_exit_underline_mode = tgetstr ("ue", address);
- TS_enter_bold_mode = tgetstr ("md", address);
- TS_enter_dim_mode = tgetstr ("mh", address);
- TS_enter_blink_mode = tgetstr ("mb", address);
- TS_enter_reverse_mode = tgetstr ("mr", address);
- TS_enter_alt_charset_mode = tgetstr ("as", address);
- TS_exit_alt_charset_mode = tgetstr ("ae", address);
- TS_exit_attribute_mode = tgetstr ("me", address);
-
- MultiUp = tgetstr ("UP", address);
- MultiDown = tgetstr ("DO", address);
- MultiLeft = tgetstr ("LE", address);
- MultiRight = tgetstr ("RI", address);
+ Left (tty) = tgetstr ("le", address);
+ if (!Left (tty))
+ Left (tty) = tgetstr ("bc", address); /* Obsolete name for "le" */
+ tty->TS_pad_char = tgetstr ("pc", address);
+ tty->TS_repeat = tgetstr ("rp", address);
+ tty->TS_end_standout_mode = tgetstr ("se", address);
+ tty->TS_fwd_scroll = tgetstr ("sf", address);
+ tty->TS_standout_mode = tgetstr ("so", address);
+ tty->TS_rev_scroll = tgetstr ("sr", address);
+ tty->Wcm->cm_tab = tgetstr ("ta", address);
+ tty->TS_end_termcap_modes = tgetstr ("te", address);
+ tty->TS_termcap_modes = tgetstr ("ti", address);
+ Up (tty) = tgetstr ("up", address);
+ tty->TS_visible_bell = tgetstr ("vb", address);
+ tty->TS_cursor_normal = tgetstr ("ve", address);
+ tty->TS_cursor_visible = tgetstr ("vs", address);
+ tty->TS_cursor_invisible = tgetstr ("vi", address);
+ tty->TS_set_window = tgetstr ("wi", address);
+
+ tty->TS_enter_underline_mode = tgetstr ("us", address);
+ tty->TS_exit_underline_mode = tgetstr ("ue", address);
+ tty->TS_enter_bold_mode = tgetstr ("md", address);
+ tty->TS_enter_dim_mode = tgetstr ("mh", address);
+ tty->TS_enter_blink_mode = tgetstr ("mb", address);
+ tty->TS_enter_reverse_mode = tgetstr ("mr", address);
+ tty->TS_enter_alt_charset_mode = tgetstr ("as", address);
+ tty->TS_exit_alt_charset_mode = tgetstr ("ae", address);
+ tty->TS_exit_attribute_mode = tgetstr ("me", address);
+
+ MultiUp (tty) = tgetstr ("UP", address);
+ MultiDown (tty) = tgetstr ("DO", address);
+ MultiLeft (tty) = tgetstr ("LE", address);
+ MultiRight (tty) = tgetstr ("RI", address);
/* SVr4/ANSI color suppert. If "op" isn't available, don't support
color because we can't switch back to the default foreground and
background. */
- TS_orig_pair = tgetstr ("op", address);
- if (TS_orig_pair)
+ tty->TS_orig_pair = tgetstr ("op", address);
+ if (tty->TS_orig_pair)
{
- TS_set_foreground = tgetstr ("AF", address);
- TS_set_background = tgetstr ("AB", address);
- if (!TS_set_foreground)
+ tty->TS_set_foreground = tgetstr ("AF", address);
+ tty->TS_set_background = tgetstr ("AB", address);
+ if (!tty->TS_set_foreground)
{
/* SVr4. */
- TS_set_foreground = tgetstr ("Sf", address);
- TS_set_background = tgetstr ("Sb", address);
+ tty->TS_set_foreground = tgetstr ("Sf", address);
+ tty->TS_set_background = tgetstr ("Sb", address);
}
- TN_max_colors = tgetnum ("Co");
- TN_max_pairs = tgetnum ("pa");
+ tty->TN_max_colors = tgetnum ("Co");
+ tty->TN_max_pairs = tgetnum ("pa");
- TN_no_color_video = tgetnum ("NC");
- if (TN_no_color_video == -1)
- TN_no_color_video = 0;
+ tty->TN_no_color_video = tgetnum ("NC");
+ if (tty->TN_no_color_video == -1)
+ tty->TN_no_color_video = 0;
}
- tty_default_color_capabilities (1);
+ tty_default_color_capabilities (tty, 1);
- MagicWrap = tgetflag ("xn");
+ MagicWrap (tty) = tgetflag ("xn");
/* Since we make MagicWrap terminals look like AutoWrap, we need to have
the former flag imply the latter. */
- AutoWrap = MagicWrap || tgetflag ("am");
- memory_below_frame = tgetflag ("db");
- TF_hazeltine = tgetflag ("hz");
- must_write_spaces = tgetflag ("in");
- meta_key = tgetflag ("km") || tgetflag ("MT");
- TF_insmode_motion = tgetflag ("mi");
- TF_standout_motion = tgetflag ("ms");
- TF_underscore = tgetflag ("ul");
- TF_teleray = tgetflag ("xt");
-
- term_get_fkeys (address);
+ AutoWrap (tty) = MagicWrap (tty) || tgetflag ("am");
+ terminal->memory_below_frame = tgetflag ("db");
+ tty->TF_hazeltine = tgetflag ("hz");
+ terminal->must_write_spaces = tgetflag ("in");
+ tty->meta_key = tgetflag ("km") || tgetflag ("MT");
+ tty->TF_insmode_motion = tgetflag ("mi");
+ tty->TF_standout_motion = tgetflag ("ms");
+ tty->TF_underscore = tgetflag ("ul");
+ tty->TF_teleray = tgetflag ("xt");
+
+#ifdef MULTI_KBOARD
+ terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
+ init_kboard (terminal->kboard);
+ terminal->kboard->next_kboard = all_kboards;
+ all_kboards = terminal->kboard;
+ terminal->kboard->reference_count++;
+ /* Don't let the initial kboard remain current longer than necessary.
+ That would cause problems if a file loaded on startup tries to
+ prompt in the mini-buffer. */
+ if (current_kboard == initial_kboard)
+ current_kboard = terminal->kboard;
+ term_get_fkeys (address, terminal->kboard);
+#endif
/* Get frame size from system, or else from termcap. */
{
int height, width;
- get_frame_size (&width, &height);
- FRAME_COLS (sf) = width;
- FRAME_LINES (sf) = height;
+ get_tty_size (fileno (tty->input), &width, &height);
+ FrameCols (tty) = width;
+ FrameRows (tty) = height;
}
- if (FRAME_COLS (sf) <= 0)
- SET_FRAME_COLS (sf, tgetnum ("co"));
- else
- /* Keep width and external_width consistent */
- SET_FRAME_COLS (sf, FRAME_COLS (sf));
- if (FRAME_LINES (sf) <= 0)
- FRAME_LINES (sf) = tgetnum ("li");
+ if (FrameCols (tty) <= 0)
+ FrameCols (tty) = tgetnum ("co");
+ if (FrameRows (tty) <= 0)
+ FrameRows (tty) = tgetnum ("li");
- if (FRAME_LINES (sf) < 3 || FRAME_COLS (sf) < 3)
- fatal ("Screen size %dx%d is too small",
- FRAME_LINES (sf), FRAME_COLS (sf));
+ if (FrameRows (tty) < 3 || FrameCols (tty) < 3)
+ maybe_fatal (must_succeed, NULL, terminal,
+ "Screen size %dx%d is too small"
+ "Screen size %dx%d is too small",
+ FrameCols (tty), FrameRows (tty));
+
+#if 0 /* This is not used anywhere. */
+ tty->terminal->min_padding_speed = tgetnum ("pb");
+#endif
- min_padding_speed = tgetnum ("pb");
- TabWidth = tgetnum ("tw");
+ TabWidth (tty) = tgetnum ("tw");
#ifdef VMS
/* These capabilities commonly use ^J.
I don't know why, but sending them on VMS does not work;
it causes following spaces to be lost, sometimes.
For now, the simplest fix is to avoid using these capabilities ever. */
- if (Down && Down[0] == '\n')
- Down = 0;
+ if (Down (tty) && Down (tty)[0] == '\n')
+ Down (tty) = 0;
#endif /* VMS */
- if (!TS_bell)
- TS_bell = "\07";
+ if (!tty->TS_bell)
+ tty->TS_bell = "\07";
- if (!TS_fwd_scroll)
- TS_fwd_scroll = Down;
+ if (!tty->TS_fwd_scroll)
+ tty->TS_fwd_scroll = Down (tty);
- PC = TS_pad_char ? *TS_pad_char : 0;
+ PC = tty->TS_pad_char ? *tty->TS_pad_char : 0;
- if (TabWidth < 0)
- TabWidth = 8;
+ if (TabWidth (tty) < 0)
+ TabWidth (tty) = 8;
/* Turned off since /etc/termcap seems to have :ta= for most terminals
and newer termcap doc does not seem to say there is a default.
- if (!Wcm.cm_tab)
- Wcm.cm_tab = "\t";
+ if (!tty->Wcm->cm_tab)
+ tty->Wcm->cm_tab = "\t";
*/
/* We don't support standout modes that use `magic cookies', so
turn off any that do. */
- if (TS_standout_mode && tgetnum ("sg") >= 0)
+ if (tty->TS_standout_mode && tgetnum ("sg") >= 0)
{
- TS_standout_mode = 0;
- TS_end_standout_mode = 0;
+ tty->TS_standout_mode = 0;
+ tty->TS_end_standout_mode = 0;
}
- if (TS_enter_underline_mode && tgetnum ("ug") >= 0)
+ if (tty->TS_enter_underline_mode && tgetnum ("ug") >= 0)
{
- TS_enter_underline_mode = 0;
- TS_exit_underline_mode = 0;
+ tty->TS_enter_underline_mode = 0;
+ tty->TS_exit_underline_mode = 0;
}
/* If there's no standout mode, try to use underlining instead. */
- if (TS_standout_mode == 0)
+ if (tty->TS_standout_mode == 0)
{
- TS_standout_mode = TS_enter_underline_mode;
- TS_end_standout_mode = TS_exit_underline_mode;
+ tty->TS_standout_mode = tty->TS_enter_underline_mode;
+ tty->TS_end_standout_mode = tty->TS_exit_underline_mode;
}
/* If no `se' string, try using a `me' string instead.
If that fails, we can't use standout mode at all. */
- if (TS_end_standout_mode == 0)
+ if (tty->TS_end_standout_mode == 0)
{
char *s = tgetstr ("me", address);
if (s != 0)
- TS_end_standout_mode = s;
+ tty->TS_end_standout_mode = s;
else
- TS_standout_mode = 0;
+ tty->TS_standout_mode = 0;
}
- if (TF_teleray)
+ if (tty->TF_teleray)
{
- Wcm.cm_tab = 0;
+ tty->Wcm->cm_tab = 0;
/* We can't support standout mode, because it uses magic cookies. */
- TS_standout_mode = 0;
+ tty->TS_standout_mode = 0;
/* But that means we cannot rely on ^M to go to column zero! */
- CR = 0;
+ CR (tty) = 0;
/* LF can't be trusted either -- can alter hpos */
/* if move at column 0 thru a line with TS_standout_mode */
- Down = 0;
+ Down (tty) = 0;
}
/* Special handling for certain terminal types known to need it */
if (!strcmp (terminal_type, "supdup"))
{
- memory_below_frame = 1;
- Wcm.cm_losewrap = 1;
+ terminal->memory_below_frame = 1;
+ tty->Wcm->cm_losewrap = 1;
}
if (!strncmp (terminal_type, "c10", 3)
|| !strcmp (terminal_type, "perq"))
@@ -3358,102 +3613,139 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
It would be simpler if the :wi string could go in the termcap
entry, but it can't because it is not fully valid.
If it were in the termcap entry, it would confuse other programs. */
- if (!TS_set_window)
+ if (!tty->TS_set_window)
{
- p = TS_termcap_modes;
+ p = tty->TS_termcap_modes;
while (*p && strcmp (p, "\033v "))
p++;
if (*p)
- TS_set_window = "\033v%C %C %C %C ";
+ tty->TS_set_window = "\033v%C %C %C %C ";
}
/* Termcap entry often fails to have :in: flag */
- must_write_spaces = 1;
+ terminal->must_write_spaces = 1;
/* :ti string typically fails to have \E^G! in it */
/* This limits scope of insert-char to one line. */
- strcpy (area, TS_termcap_modes);
+ strcpy (area, tty->TS_termcap_modes);
strcat (area, "\033\007!");
- TS_termcap_modes = area;
+ tty->TS_termcap_modes = area;
area += strlen (area) + 1;
- p = AbsPosition;
+ p = AbsPosition (tty);
/* Change all %+ parameters to %C, to handle
- values above 96 correctly for the C100. */
+ values above 96 correctly for the C100. */
while (*p)
- {
- if (p[0] == '%' && p[1] == '+')
- p[1] = 'C';
- p++;
- }
+ {
+ if (p[0] == '%' && p[1] == '+')
+ p[1] = 'C';
+ p++;
+ }
}
- FrameRows = FRAME_LINES (sf);
- FrameCols = FRAME_COLS (sf);
- specified_window = FRAME_LINES (sf);
+ tty->specified_window = FrameRows (tty);
- if (Wcm_init () == -1) /* can't do cursor motion */
+ if (Wcm_init (tty) == -1) /* can't do cursor motion */
+ {
+ maybe_fatal (must_succeed, NULL, terminal,
+ "Terminal type \"%s\" is not powerful enough to run Emacs",
#ifdef VMS
- fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
+ "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
It lacks the ability to position the cursor.\n\
If that is not the actual type of terminal you have, use either the\n\
DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
- terminal_type);
#else /* not VMS */
# ifdef TERMINFO
- fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
+ "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
It lacks the ability to position the cursor.\n\
If that is not the actual type of terminal you have,\n\
use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
`setenv TERM ...') to specify the correct type. It may be necessary\n\
to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
- terminal_type);
# else /* TERMCAP */
- fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
+ "Terminal type \"%s\" is not powerful enough to run Emacs.\n\
It lacks the ability to position the cursor.\n\
If that is not the actual type of terminal you have,\n\
use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
`setenv TERM ...') to specify the correct type. It may be necessary\n\
to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
- terminal_type);
# endif /* TERMINFO */
#endif /*VMS */
- if (FRAME_LINES (sf) <= 0
- || FRAME_COLS (sf) <= 0)
- fatal ("The frame size has not been specified");
+ terminal_type);
+ }
- delete_in_insert_mode
- = TS_delete_mode && TS_insert_mode
- && !strcmp (TS_delete_mode, TS_insert_mode);
+ if (FrameRows (tty) <= 0 || FrameCols (tty) <= 0)
+ maybe_fatal (must_succeed, NULL, terminal,
+ "Could not determine the frame size",
+ "Could not determine the frame size");
- se_is_so = (TS_standout_mode
- && TS_end_standout_mode
- && !strcmp (TS_standout_mode, TS_end_standout_mode));
+ tty->delete_in_insert_mode
+ = tty->TS_delete_mode && tty->TS_insert_mode
+ && !strcmp (tty->TS_delete_mode, tty->TS_insert_mode);
- UseTabs = tabs_safe_p () && TabWidth == 8;
+ tty->se_is_so = (tty->TS_standout_mode
+ && tty->TS_end_standout_mode
+ && !strcmp (tty->TS_standout_mode, tty->TS_end_standout_mode));
- scroll_region_ok
- = (Wcm.cm_abs
- && (TS_set_window || TS_set_scroll_region || TS_set_scroll_region_1));
+ UseTabs (tty) = tabs_safe_p (fileno (tty->input)) && TabWidth (tty) == 8;
- line_ins_del_ok = (((TS_ins_line || TS_ins_multi_lines)
- && (TS_del_line || TS_del_multi_lines))
- || (scroll_region_ok && TS_fwd_scroll && TS_rev_scroll));
+ terminal->scroll_region_ok
+ = (tty->Wcm->cm_abs
+ && (tty->TS_set_window || tty->TS_set_scroll_region || tty->TS_set_scroll_region_1));
- char_ins_del_ok = ((TS_ins_char || TS_insert_mode
- || TS_pad_inserted_char || TS_ins_multi_chars)
- && (TS_del_char || TS_del_multi_chars));
+ terminal->line_ins_del_ok
+ = (((tty->TS_ins_line || tty->TS_ins_multi_lines)
+ && (tty->TS_del_line || tty->TS_del_multi_lines))
+ || (terminal->scroll_region_ok
+ && tty->TS_fwd_scroll && tty->TS_rev_scroll));
- fast_clear_end_of_line = TS_clr_line != 0;
+ terminal->char_ins_del_ok
+ = ((tty->TS_ins_char || tty->TS_insert_mode
+ || tty->TS_pad_inserted_char || tty->TS_ins_multi_chars)
+ && (tty->TS_del_char || tty->TS_del_multi_chars));
- init_baud_rate ();
- if (read_socket_hook) /* Baudrate is somewhat */
- /* meaningless in this case */
- baud_rate = 9600;
+ terminal->fast_clear_end_of_line = tty->TS_clr_line != 0;
- FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0;
- FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none;
-#endif /* WINDOWSNT */
+ init_baud_rate (fileno (tty->input));
+
+#ifdef AIXHFT
+ /* The HFT system on AIX doesn't optimize for scrolling, so it's
+ really ugly at times. */
+ terminal->line_ins_del_ok = 0;
+ terminal->char_ins_del_ok = 0;
+#endif
+
+ /* Don't do this. I think termcap may still need the buffer. */
+ /* xfree (buffer); */
+
+ /* Init system terminal modes (RAW or CBREAK, etc.). */
+ init_sys_modes (tty);
- xfree (buffer);
+ return terminal;
+#endif /* not WINDOWSNT */
+}
+
+/* Auxiliary error-handling function for init_tty.
+ Free BUFFER and delete TERMINAL, then call error or fatal
+ with str1 or str2, respectively, according to MUST_SUCCEED. */
+
+static void
+maybe_fatal (must_succeed, buffer, terminal, str1, str2, arg1, arg2)
+ int must_succeed;
+ char *buffer;
+ struct terminal *terminal;
+ char *str1, *str2, *arg1, *arg2;
+{
+ if (buffer)
+ xfree (buffer);
+
+ if (terminal)
+ delete_tty (terminal);
+
+ if (must_succeed)
+ fatal (str2, arg1, arg2);
+ else
+ error (str1, arg1, arg2);
+
+ abort ();
}
/* VARARGS 1 */
@@ -3468,16 +3760,108 @@ fatal (str, arg1, arg2)
exit (1);
}
-DEFUN ("tty-no-underline", Ftty_no_underline, Stty_no_underline, 0, 0, 0,
- doc: /* Declare that this terminal does not handle underlining.
-This is used to override the terminfo data, for certain terminals that
-do not really do underlining, but say that they do. */)
- ()
+
+
+/* Delete the given tty terminal, closing all frames on it. */
+
+static void
+delete_tty (struct terminal *terminal)
{
- TS_enter_underline_mode = 0;
- return Qnil;
+ struct tty_display_info *tty;
+ Lisp_Object tail, frame;
+ int last_terminal;
+
+ /* Protect against recursive calls. Fdelete_frame in
+ delete_terminal calls us back when it deletes our last frame. */
+ if (terminal->deleted)
+ return;
+
+ if (terminal->type != output_termcap)
+ abort ();
+
+ tty = terminal->display_info.tty;
+
+ last_terminal = 1;
+ FOR_EACH_FRAME (tail, frame)
+ {
+ struct frame *f = XFRAME (frame);
+ if (FRAME_LIVE_P (f) && (!FRAME_TERMCAP_P (f) || FRAME_TTY (f) != tty))
+ {
+ last_terminal = 0;
+ break;
+ }
+ }
+ if (last_terminal)
+ error ("Attempt to delete the sole terminal device with live frames");
+
+ if (tty == tty_list)
+ tty_list = tty->next;
+ else
+ {
+ struct tty_display_info *p;
+ for (p = tty_list; p && p->next != tty; p = p->next)
+ ;
+
+ if (! p)
+ /* This should not happen. */
+ abort ();
+
+ p->next = tty->next;
+ tty->next = 0;
+ }
+
+ /* reset_sys_modes needs a valid device, so this call needs to be
+ before delete_terminal. */
+ reset_sys_modes (tty);
+
+ delete_terminal (terminal);
+
+ if (tty->name)
+ xfree (tty->name);
+
+ if (tty->type)
+ xfree (tty->type);
+
+ if (tty->input)
+ {
+ delete_keyboard_wait_descriptor (fileno (tty->input));
+ if (tty->input != stdin)
+ fclose (tty->input);
+ }
+ if (tty->output && tty->output != stdout && tty->output != tty->input)
+ fclose (tty->output);
+ if (tty->termscript)
+ fclose (tty->termscript);
+
+ if (tty->old_tty)
+ xfree (tty->old_tty);
+
+ if (tty->Wcm)
+ xfree (tty->Wcm);
+
+ bzero (tty, sizeof (struct tty_display_info));
+ xfree (tty);
}
+
+
+/* Mark the pointers in the tty_display_info objects.
+ Called by the Fgarbage_collector. */
+
+void
+mark_ttys (void)
+{
+ struct tty_display_info *tty;
+
+ for (tty = tty_list; tty; tty = tty->next)
+ {
+ if (tty->top_frame)
+ mark_object (tty->top_frame);
+ }
+}
+
+
+
void
syms_of_term ()
{
@@ -3490,10 +3874,18 @@ This variable can be used by terminal emulator packages. */);
system_uses_terminfo = 0;
#endif
- DEFVAR_LISP ("ring-bell-function", &Vring_bell_function,
- doc: /* Non-nil means call this function to ring the bell.
-The function should accept no arguments. */);
- Vring_bell_function = Qnil;
+ DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions,
+ doc: /* Functions to be run after suspending a tty.
+The functions are run with one argument, the terminal id to be suspended.
+See `suspend-tty'. */);
+ Vsuspend_tty_functions = Qnil;
+
+
+ DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions,
+ doc: /* Functions to be run after resuming a tty.
+The functions are run with one argument, the terminal id that was revived.
+See `resume-tty'. */);
+ Vresume_tty_functions = Qnil;
DEFVAR_BOOL ("visible-cursor", &visible_cursor,
doc: /* Non-nil means to make the cursor very visible.
@@ -3505,15 +3897,19 @@ bigger, or it may make it blink, or it may do nothing at all. */);
defsubr (&Stty_display_color_p);
defsubr (&Stty_display_color_cells);
defsubr (&Stty_no_underline);
+ defsubr (&Stty_type);
+ defsubr (&Scontrolling_tty_p);
+ defsubr (&Ssuspend_tty);
+ defsubr (&Sresume_tty);
#ifdef HAVE_GPM
defsubr (&Sterm_open_connection);
defsubr (&Sterm_close_connection);
staticpro (&Qmouse_face_window);
#endif /* HAVE_GPM */
-
- fullscreen_hook = NULL;
}
+
+
/* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
(do not change this comment) */
diff --git a/src/termchar.h b/src/termchar.h
index c4bf2adb0bd..381210fd658 100644
--- a/src/termchar.h
+++ b/src/termchar.h
@@ -19,32 +19,185 @@ along with GNU Emacs; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
+/* Each termcap frame points to its own struct tty_output object in
+ the output_data.tty field. The tty_output structure contains the
+ information that is specific to termcap frames. */
-/* extern EMACS_INT baud_rate; */ /* Output speed in baud */
-extern int must_write_spaces; /* Nonzero means spaces in the text
- must actually be output; can't just skip
- over some columns to leave them blank. */
-extern int min_padding_speed; /* Speed below which no padding necessary */
-extern int fast_clear_end_of_line; /* Nonzero means terminal has
- command for this */
-
-extern int line_ins_del_ok; /* Terminal can insert and delete lines */
-extern int char_ins_del_ok; /* Terminal can insert and delete chars */
-extern int scroll_region_ok; /* Terminal supports setting the scroll
- window */
-extern int scroll_region_cost; /* Cost of setting the scroll window,
- measured in characters */
-extern int memory_below_frame; /* Terminal remembers lines scrolled
- off bottom */
-extern int fast_clear_end_of_line; /* Terminal has a `ce' string */
-
-extern int dont_calculate_costs; /* Nonzero means don't bother computing
- various cost tables; we won't use them. */
-
-/* Nonzero means no need to redraw the entire frame on resuming
- a suspended Emacs. This is useful on terminals with multiple pages,
- where one page is used for Emacs and another for all else. */
-extern int no_redraw_on_reenter;
+struct tty_output
+{
+ /* The Emacs structure for the tty device this frame is on. */
+ struct tty_display_info *display_info;
+
+ /* There is nothing else here at the moment... */
+};
+
+/* Parameters that are shared between frames on the same tty device. */
+
+struct tty_display_info
+{
+ struct tty_display_info *next; /* Chain of all tty devices. */
+
+ char *name; /* The name of the device file or 0 if
+ stdin/stdout. */
+ char *type; /* The type of the tty. */
+
+ /* Input/output */
+
+ FILE *input; /* The stream to be used for terminal input.
+ NULL if the terminal is suspended. */
+ FILE *output; /* The stream to be used for terminal output.
+ NULL if the terminal is suspended. */
+
+ FILE *termscript; /* If nonzero, send all terminal output
+ characters to this stream also. */
+
+ struct emacs_tty *old_tty; /* The initial tty mode bits */
+
+ int term_initted; /* 1 if we have been through init_sys_modes. */
+
+
+ int reference_count; /* Number of frames that are on this display. */
+
+ struct terminal *terminal; /* Points back to the generic terminal
+ structure. This is sometimes handy. */
+
+ /* Info on cursor positioning. */
+ struct cm *Wcm;
+
+ /* Redisplay. */
+
+ Lisp_Object top_frame; /* The topmost frame on this tty. */
+
+ /* The previous frame we displayed on this tty. */
+ struct frame *previous_frame;
+
+ /* Strings, numbers and flags taken from the termcap entry. */
+
+ char *TS_ins_line; /* "al" */
+ char *TS_ins_multi_lines; /* "AL" (one parameter, # lines to insert) */
+ char *TS_bell; /* "bl" */
+ char *TS_clr_to_bottom; /* "cd" */
+ char *TS_clr_line; /* "ce", clear to end of line */
+ char *TS_clr_frame; /* "cl" */
+ char *TS_set_scroll_region; /* "cs" (2 params, first line and last line) */
+ char *TS_set_scroll_region_1; /* "cS" (4 params: total lines,
+ lines above scroll region, lines below it,
+ total lines again) */
+ char *TS_del_char; /* "dc" */
+ char *TS_del_multi_chars; /* "DC" (one parameter, # chars to delete) */
+ char *TS_del_line; /* "dl" */
+ char *TS_del_multi_lines; /* "DL" (one parameter, # lines to delete) */
+ char *TS_delete_mode; /* "dm", enter character-delete mode */
+ char *TS_end_delete_mode; /* "ed", leave character-delete mode */
+ char *TS_end_insert_mode; /* "ei", leave character-insert mode */
+ char *TS_ins_char; /* "ic" */
+ char *TS_ins_multi_chars; /* "IC" (one parameter, # chars to insert) */
+ char *TS_insert_mode; /* "im", enter character-insert mode */
+ char *TS_pad_inserted_char; /* "ip". Just padding, no commands. */
+ char *TS_end_keypad_mode; /* "ke" */
+ char *TS_keypad_mode; /* "ks" */
+ char *TS_pad_char; /* "pc", char to use as padding */
+ char *TS_repeat; /* "rp" (2 params, # times to repeat
+ and character to be repeated) */
+ char *TS_end_standout_mode; /* "se" */
+ char *TS_fwd_scroll; /* "sf" */
+ char *TS_standout_mode; /* "so" */
+ char *TS_rev_scroll; /* "sr" */
+ char *TS_end_termcap_modes; /* "te" */
+ char *TS_termcap_modes; /* "ti" */
+ char *TS_visible_bell; /* "vb" */
+ char *TS_cursor_normal; /* "ve" */
+ char *TS_cursor_visible; /* "vs" */
+ char *TS_cursor_invisible; /* "vi" */
+ char *TS_set_window; /* "wi" (4 params, start and end of window,
+ each as vpos and hpos) */
+
+ char *TS_enter_bold_mode; /* "md" -- turn on bold (extra bright mode). */
+ char *TS_enter_dim_mode; /* "mh" -- turn on half-bright mode. */
+ char *TS_enter_blink_mode; /* "mb" -- enter blinking mode. */
+ char *TS_enter_reverse_mode; /* "mr" -- enter reverse video mode. */
+ char *TS_exit_underline_mode; /* "us" -- start underlining. */
+ char *TS_enter_underline_mode; /* "ue" -- end underlining. */
+
+ /* "as"/"ae" -- start/end alternate character set. Not really
+ supported, yet. */
+ char *TS_enter_alt_charset_mode;
+ char *TS_exit_alt_charset_mode;
+
+ char *TS_exit_attribute_mode; /* "me" -- switch appearances off. */
+
+ /* Value of the "NC" (no_color_video) capability, or 0 if not present. */
+ int TN_no_color_video;
+
+ int TN_max_colors; /* "Co" -- number of colors. */
+
+ /* "pa" -- max. number of color pairs on screen. Not handled yet.
+ Could be a problem if not equal to TN_max_colors * TN_max_colors. */
+ int TN_max_pairs;
+
+ /* "op" -- SVr4 set default pair to its original value. */
+ char *TS_orig_pair;
+
+ /* "AF"/"AB" or "Sf"/"Sb"-- set ANSI or SVr4 foreground/background color.
+ 1 param, the color index. */
+ char *TS_set_foreground;
+ char *TS_set_background;
+
+ int TF_hazeltine; /* termcap hz flag. */
+ int TF_insmode_motion; /* termcap mi flag: can move while in insert mode. */
+ int TF_standout_motion; /* termcap mi flag: can move while in standout mode. */
+ int TF_underscore; /* termcap ul flag: _ underlines if over-struck on
+ non-blank position. Must clear before writing _. */
+ int TF_teleray; /* termcap xt flag: many weird consequences.
+ For t1061. */
+
+ int RPov; /* # chars to start a TS_repeat */
+
+ int delete_in_insert_mode; /* delete mode == insert mode */
+
+ int se_is_so; /* 1 if same string both enters and leaves
+ standout mode */
+
+ int costs_set; /* Nonzero if costs have been calculated. */
+
+ int insert_mode; /* Nonzero when in insert mode. */
+ int standout_mode; /* Nonzero when in standout mode. */
+
+
+
+ /* 1 if should obey 0200 bit in input chars as "Meta", 2 if should
+ keep 0200 bit in input chars. 0 to ignore the 0200 bit. */
+
+ int meta_key;
+
+ /* Size of window specified by higher levels.
+ This is the number of lines, from the top of frame downwards,
+ which can participate in insert-line/delete-line operations.
+
+ Effectively it excludes the bottom frame_lines - specified_window_size
+ lines from those operations. */
+
+ int specified_window;
+
+ /* Flag used in tty_show/hide_cursor. */
+
+ int cursor_hidden;
+
+ /* Nonzero means use ^S/^Q for flow control. */
+ int flow_control;
+
+};
+
+/* A chain of structures for all tty devices currently in use. */
+extern struct tty_display_info *tty_list;
+
+
+#define FRAME_TTY(f) \
+ ((f)->output_method == output_termcap \
+ ? (f)->terminal->display_info.tty \
+ : (abort(), (struct tty_display_info *) 0))
+
+#define CURTTY() FRAME_TTY (SELECTED_FRAME())
/* arch-tag: bf9f0d49-842b-42fb-9348-ec8759b27193
(do not change this comment) */
diff --git a/src/termhooks.h b/src/termhooks.h
index eb074608e19..4124e37586b 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -1,7 +1,6 @@
-/* Hooks by which low level terminal operations
- can be made to call other routines.
- Copyright (C) 1985, 1986, 1993, 1994, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007 Free Software Foundation, Inc.
+/* Parameters and display hooks for terminal devices.
+ Copyright (C) 1985, 1986, 1993, 1994, 2002, 2003, 2004,
+ 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of GNU Emacs.
@@ -26,40 +25,11 @@ Boston, MA 02110-1301, USA. */
struct glyph;
struct frame;
-/* If nonzero, send all terminal output characters to this stream also. */
-extern FILE *termscript;
-
/* Only use prototypes when lisp.h has been included. */
#ifndef P_
#define P_(X) ()
#endif
-/* Text display hooks. */
-
-extern void (*cursor_to_hook) P_ ((int vpos, int hpos));
-extern void (*raw_cursor_to_hook) P_ ((int, int));
-
-extern void (*clear_to_end_hook) P_ ((void));
-extern void (*clear_frame_hook) P_ ((void));
-extern void (*clear_end_of_line_hook) P_ ((int));
-
-extern void (*ins_del_lines_hook) P_ ((int, int));
-
-extern void (*insert_glyphs_hook) P_ ((struct glyph *s, int n));
-extern void (*write_glyphs_hook) P_ ((struct glyph *s, int n));
-extern void (*delete_glyphs_hook) P_ ((int));
-
-extern void (*ring_bell_hook) P_ ((void));
-
-extern void (*reset_terminal_modes_hook) P_ ((void));
-extern void (*set_terminal_modes_hook) P_ ((void));
-extern void (*update_begin_hook) P_ ((struct frame *));
-extern void (*update_end_hook) P_ ((struct frame *));
-extern void (*set_terminal_window_hook) P_ ((int));
-
-
-
-/* Multi-frame and mouse support hooks. */
enum scroll_bar_part {
scroll_bar_above_handle,
@@ -73,131 +43,12 @@ enum scroll_bar_part {
scroll_bar_move_ratio
};
-/* Return the current position of the mouse.
-
- Set *f to the frame the mouse is in, or zero if the mouse is in no
- Emacs frame. If it is set to zero, all the other arguments are
- garbage.
-
- If the motion started in a scroll bar, set *bar_window to the
- scroll bar's window, *part to the part the mouse is currently over,
- *x to the position of the mouse along the scroll bar, and *y to the
- overall length of the scroll bar.
-
- Otherwise, set *bar_window to Qnil, and *x and *y to the column and
- row of the character cell the mouse is over.
-
- Set *time to the time the mouse was at the returned position.
-
- This should clear mouse_moved until the next motion
- event arrives. */
-extern void (*mouse_position_hook) P_ ((struct frame **f, int,
- Lisp_Object *bar_window,
- enum scroll_bar_part *part,
- Lisp_Object *x,
- Lisp_Object *y,
- unsigned long *time));
-
-/* The window system handling code should set this if the mouse has
- moved since the last call to the mouse_position_hook. Calling that
- hook should clear this. */
-extern int mouse_moved;
-
-/* When a frame's focus redirection is changed, this hook tells the
- window system code to re-decide where to put the highlight. Under
- X, this means that Emacs lies about where the focus is. */
-extern void (*frame_rehighlight_hook) P_ ((struct frame *));
-
-/* If we're displaying frames using a window system that can stack
- frames on top of each other, this hook allows you to bring a frame
- to the front, or bury it behind all the other windows. If this
- hook is zero, that means the device we're displaying on doesn't
- support overlapping frames, so there's no need to raise or lower
- anything.
-
- If RAISE is non-zero, F is brought to the front, before all other
- windows. If RAISE is zero, F is sent to the back, behind all other
- windows. */
-extern void (*frame_raise_lower_hook) P_ ((struct frame *f, int raise));
-
/* If the value of the frame parameter changed, whis hook is called.
For example, if going from fullscreen to not fullscreen this hook
may do something OS dependent, like extended window manager hints on X11. */
extern void (*fullscreen_hook) P_ ((struct frame *f));
-/* Scroll bar hooks. */
-
-/* The representation of scroll bars is determined by the code which
- implements them, except for one thing: they must be represented by
- lisp objects. This allows us to place references to them in
- Lisp_Windows without worrying about those references becoming
- dangling references when the scroll bar is destroyed.
-
- The window-system-independent portion of Emacs just refers to
- scroll bars via their windows, and never looks inside the scroll bar
- representation; it always uses hook functions to do all the
- scroll bar manipulation it needs.
-
- The `vertical_scroll_bar' field of a Lisp_Window refers to that
- window's scroll bar, or is nil if the window doesn't have a
- scroll bar.
-
- The `scroll_bars' and `condemned_scroll_bars' fields of a Lisp_Frame
- are free for use by the scroll bar implementation in any way it sees
- fit. They are marked by the garbage collector. */
-
-
-/* Set the vertical scroll bar for WINDOW to have its upper left corner
- at (TOP, LEFT), and be LENGTH rows high. Set its handle to
- indicate that we are displaying PORTION characters out of a total
- of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
- have a scroll bar, create one for it. */
-extern void (*set_vertical_scroll_bar_hook)
- P_ ((struct window *window,
- int portion, int whole, int position));
-
-
-/* The following three hooks are used when we're doing a thorough
- redisplay of the frame. We don't explicitly know which scroll bars
- are going to be deleted, because keeping track of when windows go
- away is a real pain - can you say set-window-configuration?
- Instead, we just assert at the beginning of redisplay that *all*
- scroll bars are to be removed, and then save scroll bars from the
- fiery pit when we actually redisplay their window. */
-
-/* Arrange for all scroll bars on FRAME to be removed at the next call
- to `*judge_scroll_bars_hook'. A scroll bar may be spared if
- `*redeem_scroll_bar_hook' is applied to its window before the judgement.
-
- This should be applied to each frame each time its window tree is
- redisplayed, even if it is not displaying scroll bars at the moment;
- if the HAS_SCROLL_BARS flag has just been turned off, only calling
- this and the judge_scroll_bars_hook will get rid of them.
-
- If non-zero, this hook should be safe to apply to any frame,
- whether or not it can support scroll bars, and whether or not it is
- currently displaying them. */
-extern void (*condemn_scroll_bars_hook) P_ ((struct frame *frame));
-
-/* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
- Note that it's okay to redeem a scroll bar that is not condemned. */
-extern void (*redeem_scroll_bar_hook) P_ ((struct window *window));
-
-/* Remove all scroll bars on FRAME that haven't been saved since the
- last call to `*condemn_scroll_bars_hook'.
-
- This should be applied to each frame after each time its window
- tree is redisplayed, even if it is not displaying scroll bars at the
- moment; if the HAS_SCROLL_BARS flag has just been turned off, only
- calling this and condemn_scroll_bars_hook will get rid of them.
-
- If non-zero, this hook should be safe to apply to any frame,
- whether or not it can support scroll bars, and whether or not it is
- currently displaying them. */
-extern void (*judge_scroll_bars_hook) P_ ((struct frame *FRAME));
-
-
/* Input queue declarations and hooks. */
/* Expedient hack: only provide the below definitions to files that
@@ -394,13 +245,6 @@ struct input_event
#define EVENT_INIT(event) bzero (&(event), sizeof (struct input_event))
-/* Called to read input events. */
-extern int (*read_socket_hook) P_ ((int, int, struct input_event *));
-
-/* Called when a frame's display becomes entirely up to date. */
-extern void (*frame_up_to_date_hook) P_ ((struct frame *));
-
-
/* Bits in the modifiers member of the input_event structure.
Note that reorder_modifiers assumes that the bits are in canonical
order.
@@ -452,14 +296,349 @@ enum {
#ifdef HAVE_GPM
#include <gpm.h>
-extern int handle_one_term_event (Gpm_Event *, struct input_event *);
+extern int handle_one_term_event (struct tty_display_info *, Gpm_Event *, struct input_event *);
extern void term_mouse_moveto (int, int);
/* Nonzero means mouse is enabled on Linux console */
extern int term_gpm;
+
+/* The id of the terminal device for which we have gpm support. */
+extern int gpm_tty;
+#endif
+
+#endif /* CONSP */
+
+
+struct mac_display_info;
+struct w32_display_info;
+
+/* Terminal-local parameters. */
+struct terminal
+{
+ /* Chain of all terminal devices. */
+ struct terminal *next_terminal;
+
+ /* Unique id for this terminal device. */
+ int id;
+
+ /* The number of frames that are on this terminal. */
+ int reference_count;
+
+ /* Nonzero while deleting this terminal. Used to protect against
+ recursive calls to delete_terminal_hook. */
+ int deleted;
+
+ /* The type of the terminal device. */
+ enum output_method type;
+
+ /* The name of the terminal device. Do not use this to uniquely
+ identify a terminal; the same device may be opened multiple
+ times. */
+ char *name;
+
+#ifdef MULTI_KBOARD
+ /* The terminal's keyboard object. */
+ struct kboard *kboard;
+#endif
+
+ /* Device-type dependent data shared amongst all frames on this terminal. */
+ union display_info
+ {
+ struct tty_display_info *tty; /* termchar.h */
+ struct x_display_info *x; /* xterm.h */
+ struct w32_display_info *w32; /* w32term.h */
+ struct mac_display_info *mac; /* macterm.h */
+ } display_info;
+
+
+ /* Coding-system to be used for encoding terminal output. This
+ structure contains information of a coding-system specified by
+ the function `set-terminal-coding-system'. Also see
+ `safe_terminal_coding' in coding.h. */
+ struct coding_system *terminal_coding;
+
+ /* Coding-system of what is sent from terminal keyboard. This
+ structure contains information of a coding-system specified by
+ the function `set-keyboard-coding-system'. */
+ struct coding_system *keyboard_coding;
+
+ /* Parameter alist of this terminal. */
+ Lisp_Object param_alist;
+
+ /* Terminal characteristics. */
+ /* XXX Are these really used on non-termcap displays? */
+
+ int must_write_spaces; /* Nonzero means spaces in the text must
+ actually be output; can't just skip over
+ some columns to leave them blank. */
+ int fast_clear_end_of_line; /* Nonzero means terminal has a `ce' string */
+
+ int line_ins_del_ok; /* Terminal can insert and delete lines */
+ int char_ins_del_ok; /* Terminal can insert and delete chars */
+ int scroll_region_ok; /* Terminal supports setting the scroll
+ window */
+ int scroll_region_cost; /* Cost of setting the scroll window,
+ measured in characters. */
+ int memory_below_frame; /* Terminal remembers lines scrolled
+ off bottom */
+
+#if 0 /* These are not used anywhere. */
+ /* EMACS_INT baud_rate; */ /* Output speed in baud */
+ int min_padding_speed; /* Speed below which no padding necessary. */
+ int dont_calculate_costs; /* Nonzero means don't bother computing
+ various cost tables; we won't use them. */
#endif
+
+ /* Window-based redisplay interface for this device (0 for tty
+ devices). */
+ struct redisplay_interface *rif;
+
+ /* Frame-based redisplay interface. */
+
+ /* Text display hooks. */
+
+ void (*cursor_to_hook) P_ ((struct frame *f, int vpos, int hpos));
+ void (*raw_cursor_to_hook) P_ ((struct frame *, int, int));
+
+ void (*clear_to_end_hook) P_ ((struct frame *));
+ void (*clear_frame_hook) P_ ((struct frame *));
+ void (*clear_end_of_line_hook) P_ ((struct frame *, int));
+
+ void (*ins_del_lines_hook) P_ ((struct frame *f, int, int));
+
+ void (*insert_glyphs_hook) P_ ((struct frame *f, struct glyph *s, int n));
+ void (*write_glyphs_hook) P_ ((struct frame *f, struct glyph *s, int n));
+ void (*delete_glyphs_hook) P_ ((struct frame *, int));
+
+ void (*ring_bell_hook) P_ ((struct frame *f));
+
+ void (*reset_terminal_modes_hook) P_ ((struct terminal *));
+ void (*set_terminal_modes_hook) P_ ((struct terminal *));
+
+ void (*update_begin_hook) P_ ((struct frame *));
+ void (*update_end_hook) P_ ((struct frame *));
+ void (*set_terminal_window_hook) P_ ((struct frame *, int));
+
+ /* Multi-frame and mouse support hooks. */
+
+ /* Return the current position of the mouse.
+
+ Set *f to the frame the mouse is in, or zero if the mouse is in no
+ Emacs frame. If it is set to zero, all the other arguments are
+ garbage.
+
+ If the motion started in a scroll bar, set *bar_window to the
+ scroll bar's window, *part to the part the mouse is currently over,
+ *x to the position of the mouse along the scroll bar, and *y to the
+ overall length of the scroll bar.
+
+ Otherwise, set *bar_window to Qnil, and *x and *y to the column and
+ row of the character cell the mouse is over.
+
+ Set *time to the time the mouse was at the returned position.
+
+ This should clear mouse_moved until the next motion
+ event arrives. */
+ void (*mouse_position_hook) P_ ((struct frame **f, int,
+ Lisp_Object *bar_window,
+ enum scroll_bar_part *part,
+ Lisp_Object *x,
+ Lisp_Object *y,
+ unsigned long *time));
+
+ /* The window system handling code should set this if the mouse has
+ moved since the last call to the mouse_position_hook. Calling that
+ hook should clear this. */
+ int mouse_moved;
+
+ /* When a frame's focus redirection is changed, this hook tells the
+ window system code to re-decide where to put the highlight. Under
+ X, this means that Emacs lies about where the focus is. */
+ void (*frame_rehighlight_hook) P_ ((struct frame *));
+
+ /* If we're displaying frames using a window system that can stack
+ frames on top of each other, this hook allows you to bring a frame
+ to the front, or bury it behind all the other windows. If this
+ hook is zero, that means the terminal we're displaying on doesn't
+ support overlapping frames, so there's no need to raise or lower
+ anything.
+
+ If RAISE is non-zero, F is brought to the front, before all other
+ windows. If RAISE is zero, F is sent to the back, behind all other
+ windows. */
+ void (*frame_raise_lower_hook) P_ ((struct frame *f, int raise));
+
+ /* If the value of the frame parameter changed, whis hook is called.
+ For example, if going from fullscreen to not fullscreen this hook
+ may do something OS dependent, like extended window manager hints on X11. */
+ void (*fullscreen_hook) P_ ((struct frame *f));
+
+
+ /* Scroll bar hooks. */
+
+ /* The representation of scroll bars is determined by the code which
+ implements them, except for one thing: they must be represented by
+ lisp objects. This allows us to place references to them in
+ Lisp_Windows without worrying about those references becoming
+ dangling references when the scroll bar is destroyed.
+
+ The window-system-independent portion of Emacs just refers to
+ scroll bars via their windows, and never looks inside the scroll bar
+ representation; it always uses hook functions to do all the
+ scroll bar manipulation it needs.
+
+ The `vertical_scroll_bar' field of a Lisp_Window refers to that
+ window's scroll bar, or is nil if the window doesn't have a
+ scroll bar.
+
+ The `scroll_bars' and `condemned_scroll_bars' fields of a Lisp_Frame
+ are free for use by the scroll bar implementation in any way it sees
+ fit. They are marked by the garbage collector. */
+
+
+ /* Set the vertical scroll bar for WINDOW to have its upper left corner
+ at (TOP, LEFT), and be LENGTH rows high. Set its handle to
+ indicate that we are displaying PORTION characters out of a total
+ of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
+ have a scroll bar, create one for it. */
+ void (*set_vertical_scroll_bar_hook) P_ ((struct window *window,
+ int portion, int whole,
+ int position));
+
+
+ /* The following three hooks are used when we're doing a thorough
+ redisplay of the frame. We don't explicitly know which scroll bars
+ are going to be deleted, because keeping track of when windows go
+ away is a real pain - can you say set-window-configuration?
+ Instead, we just assert at the beginning of redisplay that *all*
+ scroll bars are to be removed, and then save scroll bars from the
+ fiery pit when we actually redisplay their window. */
+
+ /* Arrange for all scroll bars on FRAME to be removed at the next call
+ to `*judge_scroll_bars_hook'. A scroll bar may be spared if
+ `*redeem_scroll_bar_hook' is applied to its window before the judgement.
+
+ This should be applied to each frame each time its window tree is
+ redisplayed, even if it is not displaying scroll bars at the moment;
+ if the HAS_SCROLL_BARS flag has just been turned off, only calling
+ this and the judge_scroll_bars_hook will get rid of them.
+
+ If non-zero, this hook should be safe to apply to any frame,
+ whether or not it can support scroll bars, and whether or not it is
+ currently displaying them. */
+ void (*condemn_scroll_bars_hook) P_ ((struct frame *frame));
+
+ /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
+ Note that it's okay to redeem a scroll bar that is not condemned. */
+ void (*redeem_scroll_bar_hook) P_ ((struct window *window));
+
+ /* Remove all scroll bars on FRAME that haven't been saved since the
+ last call to `*condemn_scroll_bars_hook'.
+
+ This should be applied to each frame after each time its window
+ tree is redisplayed, even if it is not displaying scroll bars at the
+ moment; if the HAS_SCROLL_BARS flag has just been turned off, only
+ calling this and condemn_scroll_bars_hook will get rid of them.
+
+ If non-zero, this hook should be safe to apply to any frame,
+ whether or not it can support scroll bars, and whether or not it is
+ currently displaying them. */
+ void (*judge_scroll_bars_hook) P_ ((struct frame *FRAME));
+
+
+ /* Called to read input events.
+
+ TERMINAL indicates which terminal device to read from. Input
+ events should be read into BUF, the size of which is given in
+ SIZE. EXPECTED is non-zero if the caller suspects that new input
+ is available.
+
+ A positive return value indicates that that many input events
+ where read into BUF.
+ Zero means no events were immediately available.
+ A value of -1 means a transient read error, while -2 indicates
+ that the device was closed (hangup), and it should be deleted.
+
+ XXX Please note that a non-zero value of EXPECTED only means that
+ there is available input on at least one of the currently opened
+ terminal devices -- but not necessarily on this device.
+ Therefore, in most cases EXPECTED should be simply ignored.
+
+ XXX This documentation needs to be updated. */
+ int (*read_socket_hook) P_ ((struct terminal *terminal,
+ int expected,
+ struct input_event *hold_quit));
+
+ /* Called when a frame's display becomes entirely up to date. */
+ void (*frame_up_to_date_hook) P_ ((struct frame *));
+
+
+ /* Called to delete the device-specific portions of a frame that is
+ on this terminal device. */
+ void (*delete_frame_hook) P_ ((struct frame *));
+
+ /* Called after the last frame on this terminal is deleted, or when
+ the display device was closed (hangup).
+
+ If this is NULL, then the generic delete_terminal is called
+ instead. Otherwise the hook must call delete_terminal itself.
+
+ The hook must check for and close any live frames that are still
+ on the terminal. Fdelete_frame ensures that there are no live
+ frames on the terminal when it calls this hook, so infinite
+ recursion is prevented. */
+ void (*delete_terminal_hook) P_ ((struct terminal *));
+};
+
+
+/* Chain of all terminal devices currently in use. */
+extern struct terminal *terminal_list;
+
+#define FRAME_MUST_WRITE_SPACES(f) ((f)->terminal->must_write_spaces)
+#define FRAME_FAST_CLEAR_END_OF_LINE(f) ((f)->terminal->fast_clear_end_of_line)
+#define FRAME_LINE_INS_DEL_OK(f) ((f)->terminal->line_ins_del_ok)
+#define FRAME_CHAR_INS_DEL_OK(f) ((f)->terminal->char_ins_del_ok)
+#define FRAME_SCROLL_REGION_OK(f) ((f)->terminal->scroll_region_ok)
+#define FRAME_SCROLL_REGION_COST(f) ((f)->terminal->scroll_region_cost)
+#define FRAME_MEMORY_BELOW_FRAME(f) ((f)->terminal->memory_below_frame)
+
+#define FRAME_TERMINAL_CODING(f) ((f)->terminal->terminal_coding)
+#define FRAME_KEYBOARD_CODING(f) ((f)->terminal->keyboard_coding)
+
+#define TERMINAL_TERMINAL_CODING(d) ((d)->terminal_coding)
+#define TERMINAL_KEYBOARD_CODING(d) ((d)->keyboard_coding)
+
+#define FRAME_RIF(f) ((f)->terminal->rif)
+
+#define FRAME_TERMINAL(f) ((f)->terminal)
+
+/* FRAME_WINDOW_P tests whether the frame is a window, and is
+ defined to be the predicate for the window system being used. */
+
+#ifdef HAVE_X_WINDOWS
+#define FRAME_WINDOW_P(f) FRAME_X_P (f)
#endif
+#ifdef HAVE_NTGUI
+#define FRAME_WINDOW_P(f) FRAME_W32_P (f)
+#endif
+#ifdef MAC_OS
+#define FRAME_WINDOW_P(f) FRAME_MAC_P (f)
+#endif
+#ifndef FRAME_WINDOW_P
+#define FRAME_WINDOW_P(f) (0)
+#endif
+
+/* Return true if the terminal device is not suspended. */
+#define TERMINAL_ACTIVE_P(d) ((d)->type != output_termcap || (d)->display_info.tty->input)
+
+extern Lisp_Object get_terminal_param P_ ((struct terminal *, Lisp_Object));
+extern struct terminal *get_terminal P_ ((Lisp_Object terminal, int));
+extern struct terminal *create_terminal P_ ((void));
+extern void delete_terminal P_ ((struct terminal *));
+
+/* The initial terminal device, created by initial_term_init. */
+extern struct terminal *initial_terminal;
/* arch-tag: 33a00ecc-52b5-4186-a410-8801ac9f087d
(do not change this comment) */
diff --git a/src/terminal.c b/src/terminal.c
new file mode 100644
index 00000000000..a02e65cd65a
--- /dev/null
+++ b/src/terminal.c
@@ -0,0 +1,629 @@
+/* Functions related to terminal devices.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+#include <config.h>
+#include <stdio.h>
+
+#include "lisp.h"
+#include "frame.h"
+#include "termchar.h"
+#include "termhooks.h"
+#include "charset.h"
+#include "coding.h"
+#include "keyboard.h"
+
+/* Chain of all terminals currently in use. */
+struct terminal *terminal_list;
+
+/* The first unallocated terminal id. */
+static int next_terminal_id;
+
+/* The initial terminal device, created by initial_term_init. */
+struct terminal *initial_terminal;
+
+/* Function to use to ring the bell. */
+Lisp_Object Vring_bell_function;
+
+static void delete_initial_terminal P_ ((struct terminal *));
+
+
+
+void
+ring_bell (struct frame *f)
+{
+ if (!NILP (Vring_bell_function))
+ {
+ Lisp_Object function;
+
+ /* Temporarily set the global variable to nil
+ so that if we get an error, it stays nil
+ and we don't call it over and over.
+
+ We don't specbind it, because that would carefully
+ restore the bad value if there's an error
+ and make the loop of errors happen anyway. */
+
+ function = Vring_bell_function;
+ Vring_bell_function = Qnil;
+
+ call0 (function);
+
+ Vring_bell_function = function;
+ }
+ else if (FRAME_TERMINAL (f)->ring_bell_hook)
+ (*FRAME_TERMINAL (f)->ring_bell_hook) (f);
+}
+
+void
+update_begin (struct frame *f)
+{
+ if (FRAME_TERMINAL (f)->update_begin_hook)
+ (*FRAME_TERMINAL (f)->update_begin_hook) (f);
+}
+
+void
+update_end (struct frame *f)
+{
+ if (FRAME_TERMINAL (f)->update_end_hook)
+ (*FRAME_TERMINAL (f)->update_end_hook) (f);
+}
+
+/* Specify how many text lines, from the top of the window,
+ should be affected by insert-lines and delete-lines operations.
+ This, and those operations, are used only within an update
+ that is bounded by calls to update_begin and update_end. */
+
+void
+set_terminal_window (struct frame *f, int size)
+{
+ if (FRAME_TERMINAL (f)->set_terminal_window_hook)
+ (*FRAME_TERMINAL (f)->set_terminal_window_hook) (f, size);
+}
+
+/* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
+ frame-relative coordinates. */
+
+void
+cursor_to (struct frame *f, int vpos, int hpos)
+{
+ if (FRAME_TERMINAL (f)->cursor_to_hook)
+ (*FRAME_TERMINAL (f)->cursor_to_hook) (f, vpos, hpos);
+}
+
+/* Similar but don't take any account of the wasted characters. */
+
+void
+raw_cursor_to (struct frame *f, int row, int col)
+{
+ if (FRAME_TERMINAL (f)->raw_cursor_to_hook)
+ (*FRAME_TERMINAL (f)->raw_cursor_to_hook) (f, row, col);
+}
+
+/* Erase operations */
+
+/* Clear from cursor to end of frame. */
+void
+clear_to_end (struct frame *f)
+{
+ if (FRAME_TERMINAL (f)->clear_to_end_hook)
+ (*FRAME_TERMINAL (f)->clear_to_end_hook) (f);
+}
+
+/* Clear entire frame */
+
+void
+clear_frame (struct frame *f)
+{
+ if (FRAME_TERMINAL (f)->clear_frame_hook)
+ (*FRAME_TERMINAL (f)->clear_frame_hook) (f);
+}
+
+/* Clear from cursor to end of line.
+ Assume that the line is already clear starting at column first_unused_hpos.
+
+ Note that the cursor may be moved, on terminals lacking a `ce' string. */
+
+void
+clear_end_of_line (struct frame *f, int first_unused_hpos)
+{
+ if (FRAME_TERMINAL (f)->clear_end_of_line_hook)
+ (*FRAME_TERMINAL (f)->clear_end_of_line_hook) (f, first_unused_hpos);
+}
+
+/* Output LEN glyphs starting at STRING at the nominal cursor position.
+ Advance the nominal cursor over the text. */
+
+void
+write_glyphs (struct frame *f, struct glyph *string, int len)
+{
+ if (FRAME_TERMINAL (f)->write_glyphs_hook)
+ (*FRAME_TERMINAL (f)->write_glyphs_hook) (f, string, len);
+}
+
+/* Insert LEN glyphs from START at the nominal cursor position.
+
+ If start is zero, insert blanks instead of a string at start */
+
+void
+insert_glyphs (struct frame *f, struct glyph *start, int len)
+{
+ if (len <= 0)
+ return;
+
+ if (FRAME_TERMINAL (f)->insert_glyphs_hook)
+ (*FRAME_TERMINAL (f)->insert_glyphs_hook) (f, start, len);
+}
+
+/* Delete N glyphs at the nominal cursor position. */
+
+void
+delete_glyphs (struct frame *f, int n)
+{
+ if (FRAME_TERMINAL (f)->delete_glyphs_hook)
+ (*FRAME_TERMINAL (f)->delete_glyphs_hook) (f, n);
+}
+
+/* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
+
+void
+ins_del_lines (struct frame *f, int vpos, int n)
+{
+ if (FRAME_TERMINAL (f)->ins_del_lines_hook)
+ (*FRAME_TERMINAL (f)->ins_del_lines_hook) (f, vpos, n);
+}
+
+
+
+
+/* Return the terminal object specified by TERMINAL. TERMINAL may be a
+ terminal id, a frame, or nil for the terminal device of the current
+ frame. If THROW is zero, return NULL for failure, otherwise throw
+ an error. */
+
+struct terminal *
+get_terminal (Lisp_Object terminal, int throw)
+{
+ struct terminal *result = NULL;
+
+ if (NILP (terminal))
+ terminal = selected_frame;
+
+ if (INTEGERP (terminal))
+ {
+ struct terminal *t;
+
+ for (t = terminal_list; t; t = t->next_terminal)
+ {
+ if (t->id == XINT (terminal))
+ {
+ result = t;
+ break;
+ }
+ }
+ }
+ else if (FRAMEP (terminal))
+ {
+ result = FRAME_TERMINAL (XFRAME (terminal));
+ }
+
+ if (result == NULL && throw)
+ wrong_type_argument (Qterminal_live_p, terminal);
+
+ return result;
+}
+
+
+
+/* Create a new terminal object and add it to the terminal list. */
+
+struct terminal *
+create_terminal (void)
+{
+ struct terminal *terminal = (struct terminal *) xmalloc (sizeof (struct terminal));
+
+ bzero (terminal, sizeof (struct terminal));
+ terminal->next_terminal = terminal_list;
+ terminal_list = terminal;
+
+ terminal->id = next_terminal_id++;
+
+ terminal->keyboard_coding =
+ (struct coding_system *) xmalloc (sizeof (struct coding_system));
+ terminal->terminal_coding =
+ (struct coding_system *) xmalloc (sizeof (struct coding_system));
+
+ setup_coding_system (Qnil, terminal->keyboard_coding);
+ setup_coding_system (Qnil, terminal->terminal_coding);
+
+ terminal->param_alist = Qnil;
+ return terminal;
+}
+
+/* Mark the Lisp pointers in the terminal objects.
+ Called by the Fgarbage_collector. */
+
+void
+mark_terminals (void)
+{
+ struct terminal *t;
+ for (t = terminal_list; t; t = t->next_terminal)
+ {
+ mark_object (t->param_alist);
+ }
+}
+
+
+/* Low-level function to close all frames on a terminal, remove it
+ from the terminal list and free its memory. */
+
+void
+delete_terminal (struct terminal *terminal)
+{
+ struct terminal **tp;
+ Lisp_Object tail, frame;
+
+ /* Protect against recursive calls. Fdelete_frame calls the
+ delete_terminal_hook when we delete our last frame. */
+ if (terminal->deleted)
+ return;
+ terminal->deleted = 1;
+
+ /* Check for live frames that are still on this terminal. */
+ FOR_EACH_FRAME (tail, frame)
+ {
+ struct frame *f = XFRAME (frame);
+ if (FRAME_LIVE_P (f) && f->terminal == terminal)
+ {
+ Fdelete_frame (frame, Qt);
+ }
+ }
+
+ for (tp = &terminal_list; *tp != terminal; tp = &(*tp)->next_terminal)
+ if (! *tp)
+ abort ();
+ *tp = terminal->next_terminal;
+
+ if (terminal->keyboard_coding)
+ xfree (terminal->keyboard_coding);
+ if (terminal->terminal_coding)
+ xfree (terminal->terminal_coding);
+ if (terminal->name)
+ xfree (terminal->name);
+
+#ifdef MULTI_KBOARD
+ if (terminal->kboard && --terminal->kboard->reference_count == 0)
+ delete_kboard (terminal->kboard);
+#endif
+
+ bzero (terminal, sizeof (struct terminal));
+ xfree (terminal);
+}
+
+DEFUN ("delete-terminal", Fdelete_terminal, Sdelete_terminal, 0, 2, 0,
+ doc: /* Delete TERMINAL by deleting all frames on it and closing the terminal.
+TERMINAL may be a terminal id, a frame, or nil (meaning the selected
+frame's terminal).
+
+Normally, you may not delete a display if all other displays are suspended,
+but if the second argument FORCE is non-nil, you may do so. */)
+ (terminal, force)
+ Lisp_Object terminal, force;
+{
+ struct terminal *t, *p;
+
+ t = get_terminal (terminal, 0);
+
+ if (!t)
+ return Qnil;
+
+ p = terminal_list;
+ while (p && (p == t || !TERMINAL_ACTIVE_P (p)))
+ p = p->next_terminal;
+
+ if (NILP (force) && !p)
+ error ("Attempt to delete the sole active display terminal");
+
+ if (t->delete_terminal_hook)
+ (*t->delete_terminal_hook) (t);
+ else
+ delete_terminal (t);
+
+ return Qnil;
+}
+
+
+DEFUN ("frame-terminal", Fframe_terminal, Sframe_terminal, 0, 1, 0,
+ doc: /* Return the terminal that FRAME is displayed on.
+If FRAME is nil, the selected frame is used.
+
+The terminal device is represented by its integer identifier. */)
+ (frame)
+ Lisp_Object frame;
+{
+ struct terminal *t;
+
+ if (NILP (frame))
+ frame = selected_frame;
+
+ CHECK_LIVE_FRAME (frame);
+
+ t = get_terminal (frame, 0);
+
+ if (!t)
+ return Qnil;
+ else
+ return make_number (t->id);
+}
+
+DEFUN ("terminal-live-p", Fterminal_live_p, Sterminal_live_p, 1, 1, 0,
+ doc: /* Return non-nil if OBJECT is a terminal which has not been deleted.
+Value is nil if OBJECT is not a live display terminal.
+If object is a live display terminal, the return value indicates what
+sort of output terminal it uses. See the documentation of `framep' for
+possible return values.
+
+Display terminals are represented by their integer identifiers. */)
+ (object)
+ Lisp_Object object;
+{
+ struct terminal *t;
+
+ if (!INTEGERP (object))
+ return Qnil;
+
+ t = get_terminal (object, 0);
+
+ if (!t)
+ return Qnil;
+
+ switch (t->type)
+ {
+ case output_initial: /* The initial frame is like a termcap frame. */
+ case output_termcap:
+ return Qt;
+ case output_x_window:
+ return Qx;
+ case output_w32:
+ return Qw32;
+ case output_msdos_raw:
+ return Qpc;
+ case output_mac:
+ return Qmac;
+ default:
+ abort ();
+ }
+}
+
+DEFUN ("terminal-list", Fterminal_list, Sterminal_list, 0, 0, 0,
+ doc: /* Return a list of all terminal devices.
+Terminal devices are represented by their integer identifiers. */)
+ ()
+{
+ Lisp_Object terminals = Qnil;
+ struct terminal *t;
+
+ for (t = terminal_list; t; t = t->next_terminal)
+ terminals = Fcons (make_number (t->id), terminals);
+
+ return terminals;
+}
+
+DEFUN ("terminal-name", Fterminal_name, Sterminal_name, 0, 1, 0,
+ doc: /* Return the name of the terminal device TERMINAL.
+It is not guaranteed that the returned value is unique among opened devices.
+
+TERMINAL may be a terminal id, a frame, or nil (meaning the
+selected frame's terminal). */)
+ (terminal)
+ Lisp_Object terminal;
+{
+ struct terminal *t = get_terminal (terminal, 1);
+
+ if (t->name)
+ return build_string (t->name);
+ else
+ return Qnil;
+}
+
+
+
+/* Return the value of terminal parameter PARAM in terminal T. */
+Lisp_Object
+get_terminal_param (t, param)
+ struct terminal *t;
+ Lisp_Object param;
+{
+ Lisp_Object tem = Fassq (param, t->param_alist);
+ if (EQ (tem, Qnil))
+ return tem;
+ return Fcdr (tem);
+}
+
+/* Set the value of terminal parameter PARAMETER in terminal D to VALUE.
+ Return the previous value. */
+
+Lisp_Object
+store_terminal_param (t, parameter, value)
+ struct terminal *t;
+ Lisp_Object parameter;
+ Lisp_Object value;
+{
+ Lisp_Object old_alist_elt = Fassq (parameter, t->param_alist);
+ if (EQ (old_alist_elt, Qnil))
+ {
+ t->param_alist = Fcons (Fcons (parameter, value), t->param_alist);
+ return Qnil;
+ }
+ else
+ {
+ Lisp_Object result = Fcdr (old_alist_elt);
+ Fsetcdr (old_alist_elt, value);
+ return result;
+ }
+}
+
+
+DEFUN ("terminal-parameters", Fterminal_parameters, Sterminal_parameters, 0, 1, 0,
+ doc: /* Return the parameter-alist of terminal TERMINAL.
+The value is a list of elements of the form (PARM . VALUE), where PARM
+is a symbol.
+
+TERMINAL can be a terminal id, a frame or nil (meaning the selected
+frame's terminal). */)
+ (terminal)
+ Lisp_Object terminal;
+{
+ struct terminal *t = get_terminal (terminal, 1);
+ return Fcopy_alist (t->param_alist);
+}
+
+DEFUN ("terminal-parameter", Fterminal_parameter, Sterminal_parameter, 2, 2, 0,
+ doc: /* Return TERMINAL's value for parameter PARAMETER.
+TERMINAL can be a terminal id, a frame or nil (meaning the selected
+frame's terminal). */)
+ (terminal, parameter)
+ Lisp_Object terminal;
+ Lisp_Object parameter;
+{
+ Lisp_Object value;
+ struct terminal *t = get_terminal (terminal, 1);
+ CHECK_SYMBOL (parameter);
+ value = Fcdr (Fassq (parameter, t->param_alist));
+ return value;
+}
+
+DEFUN ("modify-terminal-parameters", Fmodify_terminal_parameters,
+ Smodify_terminal_parameters, 2, 2, 0,
+ doc: /* Modify the parameters of terminal TERMINAL according to ALIST.
+ALIST is an alist of parameters to change and their new values.
+Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.
+
+TERMINAL can be a terminal id, a frame or nil (meaning the selected
+frame's terminal). */)
+ (terminal, alist)
+ Lisp_Object terminal;
+ Lisp_Object alist;
+{
+ Lisp_Object tail, prop, val;
+ struct terminal *t = get_terminal (terminal, 1);
+ int length = XINT (Fsafe_length (alist));
+ int i;
+ Lisp_Object *parms = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
+ Lisp_Object *values = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
+
+ /* Extract parm names and values into those vectors. */
+
+ i = 0;
+ for (tail = alist; CONSP (tail); tail = Fcdr (tail))
+ {
+ Lisp_Object elt;
+
+ elt = Fcar (tail);
+ parms[i] = Fcar (elt);
+ values[i] = Fcdr (elt);
+ i++;
+ }
+
+ /* Now process them in reverse of specified order. */
+ for (i--; i >= 0; i--)
+ {
+ prop = parms[i];
+ val = values[i];
+ store_terminal_param (t, prop, val);
+ }
+ return Qnil;
+}
+
+DEFUN ("set-terminal-parameter", Fset_terminal_parameter,
+ Sset_terminal_parameter, 3, 3, 0,
+ doc: /* Set TERMINAL's value for parameter PARAMETER to VALUE.
+Return the previous value of PARAMETER.
+
+TERMINAL can be a terminal id, a frame or nil (meaning the selected
+frame's terminal). */)
+ (terminal, parameter, value)
+ Lisp_Object terminal;
+ Lisp_Object parameter;
+ Lisp_Object value;
+{
+ struct terminal *t = get_terminal (terminal, 1);
+ return store_terminal_param (t, parameter, value);
+}
+
+
+
+/* Create the bootstrap display terminal for the initial frame.
+ Returns a terminal of type output_initial. */
+
+struct terminal *
+init_initial_terminal (void)
+{
+ if (initialized || terminal_list || tty_list)
+ abort ();
+
+ initial_terminal = create_terminal ();
+ initial_terminal->type = output_initial;
+ initial_terminal->name = xstrdup ("initial_terminal");
+#ifdef MULTI_KBOARD
+ initial_terminal->kboard = initial_kboard;
+#endif
+ initial_terminal->delete_terminal_hook = &delete_initial_terminal;
+ /* All other hooks are NULL. */
+
+ return initial_terminal;
+}
+
+/* Deletes the bootstrap terminal device.
+ Called through delete_terminal_hook. */
+
+static void
+delete_initial_terminal (struct terminal *terminal)
+{
+ if (terminal != initial_terminal)
+ abort ();
+
+ delete_terminal (terminal);
+ initial_terminal = NULL;
+}
+
+void
+syms_of_terminal ()
+{
+
+ DEFVAR_LISP ("ring-bell-function", &Vring_bell_function,
+ doc: /* Non-nil means call this function to ring the bell.
+The function should accept no arguments. */);
+ Vring_bell_function = Qnil;
+
+ defsubr (&Sdelete_terminal);
+ defsubr (&Sframe_terminal);
+ defsubr (&Sterminal_live_p);
+ defsubr (&Sterminal_list);
+ defsubr (&Sterminal_name);
+ defsubr (&Sterminal_parameters);
+ defsubr (&Sterminal_parameter);
+ defsubr (&Smodify_terminal_parameters);
+ defsubr (&Sset_terminal_parameter);
+
+ Fprovide (intern ("multi-tty"), Qnil);
+}
+
+/* arch-tag: e9af6f27-b483-47dc-bb1a-730c1c5cab03
+ (do not change this comment) */
diff --git a/src/termopts.h b/src/termopts.h
index 210236017d5..5946666654c 100644
--- a/src/termopts.h
+++ b/src/termopts.h
@@ -41,5 +41,10 @@ extern int meta_key;
/* Nonzero means truncate lines in all windows less wide than the frame */
extern int truncate_partial_width_windows;
+/* Nonzero means no need to redraw the entire frame on resuming a suspended
+ Emacs. This is useful on terminals with multiple pages, where one page is
+ used for Emacs and another for all else. */
+extern int no_redraw_on_reenter;
+
/* arch-tag: 35d4d284-dc1a-4fff-97fa-0154a21aebdb
(do not change this comment) */
diff --git a/src/w32.c b/src/w32.c
index d7e95aac7d1..dd87ef62fab 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -904,18 +904,6 @@ alarm (int seconds)
return 0;
}
-void
-unrequest_sigio (void)
-{
- return;
-}
-
-void
-request_sigio (void)
-{
- return;
-}
-
#define REG_ROOT "SOFTWARE\\GNU\\Emacs"
LPBYTE
diff --git a/src/w32console.c b/src/w32console.c
index 3afa5fb392a..d5056217bf2 100644
--- a/src/w32console.c
+++ b/src/w32console.c
@@ -35,11 +35,12 @@ Boston, MA 02110-1301, USA.
#include "charset.h"
#include "coding.h"
#include "disptab.h"
-#include "termhooks.h"
-#include "dispextern.h"
/* Disable features in frame.h that require a Window System. */
#undef HAVE_WINDOW_SYSTEM
#include "frame.h"
+#include "termhooks.h"
+#include "termchar.h"
+#include "dispextern.h"
#include "w32inevt.h"
/* from window.c */
@@ -51,21 +52,17 @@ extern int detect_input_pending ();
/* from sysdep.c */
extern int read_input_pending ();
-extern struct frame * updating_frame;
-extern int meta_key;
-
-static void w32con_move_cursor (int row, int col);
-static void w32con_clear_to_end (void);
-static void w32con_clear_frame (void);
-static void w32con_clear_end_of_line (int);
-static void w32con_ins_del_lines (int vpos, int n);
-static void w32con_insert_glyphs (struct glyph *start, int len);
-static void w32con_write_glyphs (struct glyph *string, int len);
-static void w32con_delete_glyphs (int n);
-void w32_sys_ring_bell (void);
-static void w32con_reset_terminal_modes (void);
-static void w32con_set_terminal_modes (void);
-static void w32con_set_terminal_window (int size);
+static void w32con_move_cursor (struct frame *f, int row, int col);
+static void w32con_clear_to_end (struct frame *f);
+static void w32con_clear_frame (struct frame *f);
+static void w32con_clear_end_of_line (struct frame *f, int);
+static void w32con_ins_del_lines (struct frame *f, int vpos, int n);
+static void w32con_insert_glyphs (struct frame *f, struct glyph *start, int len);
+static void w32con_write_glyphs (struct frame *f, struct glyph *string, int len);
+static void w32con_delete_glyphs (struct frame *f, int n);
+static void w32con_reset_terminal_modes (struct terminal *t);
+static void w32con_set_terminal_modes (struct terminal *t);
+static void w32con_set_terminal_window (struct frame *f, int size);
static void w32con_update_begin (struct frame * f);
static void w32con_update_end (struct frame * f);
static WORD w32_face_attributes (struct frame *f, int face_id);
@@ -99,38 +96,31 @@ ctrl_c_handler (unsigned long type)
&& (type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT));
}
-/* If we're updating a frame, use it as the current frame
- Otherwise, use the selected frame. */
-#define PICK_FRAME() (updating_frame ? updating_frame : SELECTED_FRAME ())
-/* Move the cursor to (row, col). */
+/* Move the cursor to (ROW, COL) on FRAME. */
static void
-w32con_move_cursor (int row, int col)
+w32con_move_cursor (struct frame *f, int row, int col)
{
cursor_coords.X = col;
cursor_coords.Y = row;
- if (updating_frame == (struct frame *) NULL)
- {
- SetConsoleCursorPosition (cur_screen, cursor_coords);
- }
+ /* TODO: for multi-tty support, cur_screen should be replaced with a
+ reference to the terminal for this frame. */
+ SetConsoleCursorPosition (cur_screen, cursor_coords);
}
/* Clear from cursor to end of screen. */
static void
-w32con_clear_to_end (void)
+w32con_clear_to_end (struct frame *f)
{
- struct frame * f = PICK_FRAME ();
-
- w32con_clear_end_of_line (FRAME_COLS (f) - 1);
- w32con_ins_del_lines (cursor_coords.Y, FRAME_LINES (f) - cursor_coords.Y - 1);
+ w32con_clear_end_of_line (f, FRAME_COLS (f) - 1);
+ w32con_ins_del_lines (f, cursor_coords.Y, FRAME_LINES (f) - cursor_coords.Y - 1);
}
/* Clear the frame. */
static void
-w32con_clear_frame (void)
+w32con_clear_frame (struct frame *f)
{
- struct frame * f = PICK_FRAME ();
COORD dest;
int n;
DWORD r;
@@ -145,7 +135,7 @@ w32con_clear_frame (void)
FillConsoleOutputAttribute (cur_screen, char_attr_normal, n, dest, &r);
FillConsoleOutputCharacter (cur_screen, ' ', n, dest, &r);
- w32con_move_cursor (0, 0);
+ w32con_move_cursor (f, 0, 0);
}
@@ -154,7 +144,7 @@ static BOOL ceol_initialized = FALSE;
/* Clear from Cursor to end (what's "standout marker"?). */
static void
-w32con_clear_end_of_line (int end)
+w32con_clear_end_of_line (struct frame *f, int end)
{
if (!ceol_initialized)
{
@@ -165,18 +155,17 @@ w32con_clear_end_of_line (int end)
}
ceol_initialized = TRUE;
}
- w32con_write_glyphs (glyph_base, end - cursor_coords.X); /* fencepost ? */
+ w32con_write_glyphs (f, glyph_base, end - cursor_coords.X); /* fencepost ? */
}
/* Insert n lines at vpos. if n is negative delete -n lines. */
static void
-w32con_ins_del_lines (int vpos, int n)
+w32con_ins_del_lines (struct frame *f, int vpos, int n)
{
int i, nb;
SMALL_RECT scroll;
COORD dest;
CHAR_INFO fill;
- struct frame * f = PICK_FRAME ();
if (n < 0)
{
@@ -213,8 +202,8 @@ w32con_ins_del_lines (int vpos, int n)
{
for (i = scroll.Bottom; i < dest.Y; i++)
{
- w32con_move_cursor (i, 0);
- w32con_clear_end_of_line (FRAME_COLS (f));
+ w32con_move_cursor (f, i, 0);
+ w32con_clear_end_of_line (f, FRAME_COLS (f));
}
}
}
@@ -226,8 +215,8 @@ w32con_ins_del_lines (int vpos, int n)
{
for (i = nb; i < scroll.Top; i++)
{
- w32con_move_cursor (i, 0);
- w32con_clear_end_of_line (FRAME_COLS (f));
+ w32con_move_cursor (f, i, 0);
+ w32con_clear_end_of_line (f, FRAME_COLS (f));
}
}
}
@@ -242,14 +231,13 @@ w32con_ins_del_lines (int vpos, int n)
#define RIGHT 0
static void
-scroll_line (int dist, int direction)
+scroll_line (struct frame *f, int dist, int direction)
{
/* The idea here is to implement a horizontal scroll in one line to
implement delete and half of insert. */
SMALL_RECT scroll;
COORD dest;
CHAR_INFO fill;
- struct frame * f = PICK_FRAME ();
scroll.Top = cursor_coords.Y;
scroll.Bottom = cursor_coords.Y;
@@ -277,9 +265,9 @@ scroll_line (int dist, int direction)
/* If start is zero insert blanks instead of a string at start ?. */
static void
-w32con_insert_glyphs (register struct glyph *start, register int len)
+w32con_insert_glyphs (struct frame *f, register struct glyph *start, register int len)
{
- scroll_line (len, RIGHT);
+ scroll_line (f, len, RIGHT);
/* Move len chars to the right starting at cursor_coords, fill with blanks */
if (start)
@@ -287,11 +275,11 @@ w32con_insert_glyphs (register struct glyph *start, register int len)
/* Print the first len characters of start, cursor_coords.X adjusted
by write_glyphs. */
- w32con_write_glyphs (start, len);
+ w32con_write_glyphs (f, start, len);
}
else
{
- w32con_clear_end_of_line (cursor_coords.X + len);
+ w32con_clear_end_of_line (f, cursor_coords.X + len);
}
}
@@ -299,11 +287,11 @@ extern unsigned char *encode_terminal_code P_ ((struct glyph *, int,
struct coding_system *));
static void
-w32con_write_glyphs (register struct glyph *string, register int len)
+w32con_write_glyphs (struct frame *f, register struct glyph *string,
+ register int len)
{
int produced, consumed;
DWORD r;
- struct frame * f = PICK_FRAME ();
WORD char_attr;
unsigned char *conversion_buffer;
struct coding_system *coding;
@@ -314,11 +302,11 @@ w32con_write_glyphs (register struct glyph *string, register int len)
/* If terminal_coding does any conversion, use it, otherwise use
safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
because it always return 1 if the member src_multibyte is 1. */
- coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK
- ? &terminal_coding : &safe_terminal_coding);
+ coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK
+ ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding);
/* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
the tail. */
- terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;
+ coding->mode &= ~CODING_MODE_LAST_BLOCK;
while (len > 0)
{
@@ -360,7 +348,7 @@ w32con_write_glyphs (register struct glyph *string, register int len)
}
cursor_coords.X += coding->produced;
- w32con_move_cursor (cursor_coords.Y, cursor_coords.X);
+ w32con_move_cursor (f, cursor_coords.Y, cursor_coords.X);
}
len -= n;
string += n;
@@ -369,20 +357,20 @@ w32con_write_glyphs (register struct glyph *string, register int len)
static void
-w32con_delete_glyphs (int n)
+w32con_delete_glyphs (struct frame *f, int n)
{
/* delete chars means scroll chars from cursor_coords.X + n to
cursor_coords.X, anything beyond the edge of the screen should
come out empty... */
- scroll_line (n, LEFT);
+ scroll_line (f, n, LEFT);
}
static unsigned int sound_type = 0xFFFFFFFF;
#define MB_EMACS_SILENT (0xFFFFFFFF - 1)
void
-w32_sys_ring_bell (void)
+w32_sys_ring_bell (struct frame *f)
{
if (sound_type == 0xFFFFFFFF)
{
@@ -428,7 +416,7 @@ SOUND is nil to use the normal beep. */)
}
static void
-w32con_reset_terminal_modes (void)
+w32con_reset_terminal_modes (struct terminal *t)
{
#ifdef USE_SEPARATE_SCREEN
SetConsoleActiveScreenBuffer (prev_screen);
@@ -439,7 +427,7 @@ w32con_reset_terminal_modes (void)
}
static void
-w32con_set_terminal_modes (void)
+w32con_set_terminal_modes (struct terminal *t)
{
CONSOLE_CURSOR_INFO cci;
@@ -473,7 +461,7 @@ w32con_update_end (struct frame * f)
}
static void
-w32con_set_terminal_window (int size)
+w32con_set_terminal_window (struct frame *f, int size)
{
}
@@ -546,29 +534,34 @@ vga_stdcolor_name (int idx)
typedef int (*term_hook) ();
+/* TEMPORARY HACK to get w32console compiling. To support multiple consoles,
+ this needs to go! */
+struct terminal one_and_only_w32cons;
+
void
initialize_w32_display (void)
{
CONSOLE_SCREEN_BUFFER_INFO info;
-
- cursor_to_hook = w32con_move_cursor;
- raw_cursor_to_hook = w32con_move_cursor;
- clear_to_end_hook = w32con_clear_to_end;
- clear_frame_hook = w32con_clear_frame;
- clear_end_of_line_hook = w32con_clear_end_of_line;
- ins_del_lines_hook = w32con_ins_del_lines;
- insert_glyphs_hook = w32con_insert_glyphs;
- write_glyphs_hook = w32con_write_glyphs;
- delete_glyphs_hook = w32con_delete_glyphs;
- ring_bell_hook = w32_sys_ring_bell;
- reset_terminal_modes_hook = w32con_reset_terminal_modes;
- set_terminal_modes_hook = w32con_set_terminal_modes;
- set_terminal_window_hook = w32con_set_terminal_window;
- update_begin_hook = w32con_update_begin;
- update_end_hook = w32con_update_end;
-
- read_socket_hook = w32_console_read_socket;
- mouse_position_hook = w32_console_mouse_position;
+ struct terminal *term = &one_and_only_w32cons;
+
+ term->cursor_to_hook = w32con_move_cursor;
+ term->raw_cursor_to_hook = w32con_move_cursor;
+ term->clear_to_end_hook = w32con_clear_to_end;
+ term->clear_frame_hook = w32con_clear_frame;
+ term->clear_end_of_line_hook = w32con_clear_end_of_line;
+ term->ins_del_lines_hook = w32con_ins_del_lines;
+ term->insert_glyphs_hook = w32con_insert_glyphs;
+ term->write_glyphs_hook = w32con_write_glyphs;
+ term->delete_glyphs_hook = w32con_delete_glyphs;
+ term->ring_bell_hook = w32_sys_ring_bell;
+ term->reset_terminal_modes_hook = w32con_reset_terminal_modes;
+ term->set_terminal_modes_hook = w32con_set_terminal_modes;
+ term->set_terminal_window_hook = w32con_set_terminal_window;
+ term->update_begin_hook = w32con_update_begin;
+ term->update_end_hook = w32con_update_end;
+
+ term->read_socket_hook = w32_console_read_socket;
+ term->mouse_position_hook = w32_console_mouse_position;
/* Initialize interrupt_handle. */
init_crit ();
@@ -633,7 +626,6 @@ initialize_w32_display (void)
GetConsoleScreenBufferInfo (cur_screen, &info);
- meta_key = 1;
char_attr_normal = info.wAttributes;
/* Determine if the info returned by GetConsoleScreenBufferInfo
@@ -674,6 +666,25 @@ initialize_w32_display (void)
}
+/* Initialize the tty-dependent part of frame F. The frame must
+ already have its device initialized. */
+void
+create_w32cons_output(struct frame *f)
+{
+ struct tty_output *tty;
+
+ if (! FRAME_TERMCAP_P (f))
+ abort ();
+
+ tty = xmalloc (sizeof (struct tty_output));
+ bzero (tty, sizeof (struct tty_output));
+
+ tty->display_info = FRAME_TERMINAL (f)->display_info.tty;
+ tty->display_info->meta_key = 1;
+
+ f->output_data.tty = tty;
+}
+
DEFUN ("set-screen-color", Fset_screen_color, Sset_screen_color, 2, 2, 0,
doc: /* Set screen colors. */)
(foreground, background)
diff --git a/src/w32fns.c b/src/w32fns.c
index be3570231dc..e7a4bb3d5ed 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -1818,10 +1818,8 @@ x_set_tool_bar_lines (f, value, oldval)
below the menu bar. */
if (FRAME_W32_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
{
- updating_frame = f;
- clear_frame ();
+ clear_frame (f);
clear_current_matrices (f);
- updating_frame = NULL;
}
/* If the tool bar gets smaller, the internal border below it
@@ -4180,7 +4178,7 @@ This function is an internal primitive--use `make-frame' instead. */)
display = Qnil;
dpyinfo = check_x_display_info (display);
#ifdef MULTI_KBOARD
- kb = dpyinfo->kboard;
+ kb = dpyinfo->terminal->kboard;
#else
kb = &the_only_kboard;
#endif
@@ -4228,6 +4226,9 @@ This function is an internal primitive--use `make-frame' instead. */)
/* By default, make scrollbars the system standard width. */
FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = GetSystemMetrics (SM_CXVSCROLL);
+ f->terminal = dpyinfo->terminal;
+ f->terminal->reference_count++;
+
f->output_method = output_w32;
f->output_data.w32 =
(struct w32_output *) xmalloc (sizeof (struct w32_output));
@@ -4442,6 +4443,22 @@ This function is an internal primitive--use `make-frame' instead. */)
/* Must have been Qnil. */
;
}
+
+ /* Initialize `default-minibuffer-frame' in case this is the first
+ frame on this terminal. */
+ if (FRAME_HAS_MINIBUF_P (f)
+ && (!FRAMEP (kb->Vdefault_minibuffer_frame)
+ || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
+ kb->Vdefault_minibuffer_frame = frame;
+
+ /* All remaining specified parameters, which have not been "used"
+ by x_get_arg and friends, now go in the misc. alist of the frame. */
+ for (tem = parameters; !NILP (tem); tem = XCDR (tem))
+ if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
+ f->param_alist = Fcons (XCAR (tem), f->param_alist);
+
+ store_frame_param (f, Qwindow_system, Qw32);
+
UNGCPRO;
/* Make sure windows on this frame appear in calls to next-window
@@ -6716,8 +6733,10 @@ terminate Emacs if we can't open the connection. */)
if (! NILP (xrm_string))
CHECK_STRING (xrm_string);
+#if 0
if (! EQ (Vwindow_system, intern ("w32")))
error ("Not using Microsoft Windows");
+#endif
/* Allow color mapping to be defined externally; first look in user's
HOME directory, then in Emacs etc dir for a file called rgb.txt. */
@@ -7257,6 +7276,8 @@ x_create_tip_frame (dpyinfo, parms, text)
the frame is live, as per FRAME_LIVE_P. If we get a signal
from this point on, x_destroy_window might screw up reference
counts etc. */
+ f->terminal = dpyinfo->terminal;
+ f->terminal->reference_count++;
f->output_method = output_w32;
f->output_data.w32 =
(struct w32_output *) xmalloc (sizeof (struct w32_output));
@@ -7420,6 +7441,8 @@ x_create_tip_frame (dpyinfo, parms, text)
Qnil));
}
+ Fmodify_frame_parameters (frame, Fcons (Fcons (Qwindow_system, Qw32), Qnil));
+
f->no_split = 1;
UNGCPRO;
diff --git a/src/w32inevt.c b/src/w32inevt.c
index fa2d34c2998..17cfd384400 100644
--- a/src/w32inevt.c
+++ b/src/w32inevt.c
@@ -643,7 +643,9 @@ maybe_generate_resize_event ()
}
int
-w32_console_read_socket (int sd, int expected, struct input_event *hold_quit)
+w32_console_read_socket (struct terminal *terminal,
+ int expected,
+ struct input_event *hold_quit)
{
BOOL no_events = TRUE;
int nev, ret = 0, add;
diff --git a/src/w32inevt.h b/src/w32inevt.h
index 53f36e3a348..08d85a0b2e4 100644
--- a/src/w32inevt.h
+++ b/src/w32inevt.h
@@ -22,7 +22,7 @@ Boston, MA 02110-1301, USA. */
#ifndef EMACS_W32INEVT_H
#define EMACS_W32INEVT_H
-extern int w32_console_read_socket (int sd, int numchars,
+extern int w32_console_read_socket (struct terminal *term, int numchars,
struct input_event *hold_quit);
extern void w32_console_mouse_position (FRAME_PTR *f, int insist,
Lisp_Object *bar_window,
diff --git a/src/w32menu.c b/src/w32menu.c
index f0d582d388a..e5638cc4bfd 100644
--- a/src/w32menu.c
+++ b/src/w32menu.c
@@ -20,15 +20,16 @@ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
#include <config.h>
-#include <signal.h>
+#include <signal.h>
#include <stdio.h>
#include <mbstring.h>
+
#include "lisp.h"
-#include "termhooks.h"
#include "keyboard.h"
#include "keymap.h"
#include "frame.h"
+#include "termhooks.h"
#include "window.h"
#include "blockinput.h"
#include "buffer.h"
@@ -674,8 +675,8 @@ cached information about equivalent key sequences. */)
enum scroll_bar_part part;
unsigned long time;
- if (mouse_position_hook)
- (*mouse_position_hook) (&new_f, 1, &bar_window,
+ if (FRAME_TERMINAL (new_f)->mouse_position_hook)
+ (*FRAME_TERMINAL (new_f)->mouse_position_hook) (&new_f, 1, &bar_window,
&part, &x, &y, &time);
if (new_f != 0)
XSETFRAME (window, new_f);
diff --git a/src/w32term.c b/src/w32term.c
index 6f97426d499..100af4ebc21 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -234,9 +234,9 @@ static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
int x_compute_min_glyph_bounds P_ ((struct frame *));
static void x_update_end P_ ((struct frame *));
static void w32_frame_up_to_date P_ ((struct frame *));
-static void w32_set_terminal_modes P_ ((void));
-static void w32_reset_terminal_modes P_ ((void));
-static void x_clear_frame P_ ((void));
+static void w32_set_terminal_modes P_ ((struct terminal *));
+static void w32_reset_terminal_modes P_ ((struct terminal *));
+static void x_clear_frame P_ ((struct frame *));
static void frame_highlight P_ ((struct frame *));
static void frame_unhighlight P_ ((struct frame *));
static void x_new_focus_frame P_ ((struct w32_display_info *,
@@ -848,7 +848,7 @@ w32_destroy_fringe_bitmap (which)
rarely happens). */
static void
-w32_set_terminal_modes (void)
+w32_set_terminal_modes (struct terminal *term)
{
}
@@ -856,7 +856,7 @@ w32_set_terminal_modes (void)
the W32 windows go away, and suspending requires no action. */
static void
-w32_reset_terminal_modes (void)
+w32_reset_terminal_modes (struct terminal *term)
{
}
@@ -2655,16 +2655,10 @@ w32_shift_glyphs_for_insert (f, x, y, width, height, shift_by)
for X frames. */
static void
-x_delete_glyphs (n)
+x_delete_glyphs (f, n)
+ struct frame *f;
register int n;
{
- struct frame *f;
-
- if (updating_frame)
- f = updating_frame;
- else
- f = SELECTED_FRAME ();
-
if (! FRAME_W32_P (f))
return;
@@ -2676,15 +2670,8 @@ x_delete_glyphs (n)
frame. Otherwise clear the selected frame. */
static void
-x_clear_frame ()
+x_clear_frame (struct frame *f)
{
- struct frame *f;
-
- if (updating_frame)
- f = updating_frame;
- else
- f = SELECTED_FRAME ();
-
if (! FRAME_W32_P (f))
return;
@@ -2711,18 +2698,14 @@ x_clear_frame ()
/* Make audible bell. */
static void
-w32_ring_bell (void)
+w32_ring_bell (struct frame *f)
{
- struct frame *f;
-
- f = SELECTED_FRAME ();
-
BLOCK_INPUT;
if (FRAME_W32_P (f) && visible_bell)
{
int i;
- HWND hwnd = FRAME_W32_WINDOW (SELECTED_FRAME ());
+ HWND hwnd = FRAME_W32_WINDOW (f);
for (i = 0; i < 5; i++)
{
@@ -2732,7 +2715,7 @@ w32_ring_bell (void)
FlashWindow (hwnd, FALSE);
}
else
- w32_sys_ring_bell ();
+ w32_sys_ring_bell (f);
UNBLOCK_INPUT;
}
@@ -2759,16 +2742,10 @@ w32_set_terminal_window (n)
lines or deleting -N lines at vertical position VPOS. */
static void
-x_ins_del_lines (vpos, n)
+x_ins_del_lines (f, vpos, n)
+ struct frame *f;
int vpos, n;
{
- struct frame *f;
-
- if (updating_frame)
- f = updating_frame;
- else
- f = SELECTED_FRAME ();
-
if (! FRAME_W32_P (f))
return;
@@ -5935,8 +5912,8 @@ x_free_frame_resources (f)
free_frame_menubar (f);
- unload_color (f, f->output_data.x->foreground_pixel);
- unload_color (f, f->output_data.x->background_pixel);
+ unload_color (f, FRAME_FOREGROUND_PIXEL (f));
+ unload_color (f, FRAME_BACKGROUND_PIXEL (f));
unload_color (f, f->output_data.w32->cursor_pixel);
unload_color (f, f->output_data.w32->cursor_foreground_pixel);
unload_color (f, f->output_data.w32->border_pixel);
@@ -5975,14 +5952,13 @@ x_free_frame_resources (f)
/* Destroy the window of frame F. */
-
+void
x_destroy_window (f)
struct frame *f;
{
struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
x_free_frame_resources (f);
-
dpyinfo->reference_count--;
}
@@ -6242,6 +6218,116 @@ w32_make_rdb (xrm_option)
return buffer;
}
+void
+x_flush (struct frame * f)
+{ /* Nothing to do */ }
+
+
+extern frame_parm_handler w32_frame_parm_handlers[];
+
+static struct redisplay_interface w32_redisplay_interface =
+{
+ w32_frame_parm_handlers,
+ x_produce_glyphs,
+ x_write_glyphs,
+ x_insert_glyphs,
+ x_clear_end_of_line,
+ x_scroll_run,
+ x_after_update_window_line,
+ x_update_window_begin,
+ x_update_window_end,
+ x_cursor_to,
+ x_flush,
+ 0, /* flush_display_optional */
+ x_clear_window_mouse_face,
+ w32_get_glyph_overhangs,
+ x_fix_overlapping_area,
+ w32_draw_fringe_bitmap,
+ w32_define_fringe_bitmap,
+ w32_destroy_fringe_bitmap,
+ w32_per_char_metric,
+ w32_encode_char,
+ NULL, /* w32_compute_glyph_string_overhangs */
+ x_draw_glyph_string,
+ w32_define_frame_cursor,
+ w32_clear_frame_area,
+ w32_draw_window_cursor,
+ w32_draw_vertical_window_border,
+ w32_shift_glyphs_for_insert
+};
+
+static void x_delete_terminal (struct terminal *term);
+
+static struct terminal *
+w32_create_terminal (struct w32_display_info *dpyinfo)
+{
+ struct terminal *terminal;
+
+ terminal = create_terminal ();
+
+ terminal->type = output_w32;
+ terminal->display_info.w32 = dpyinfo;
+ dpyinfo->terminal = terminal;
+
+ /* MSVC does not type K&R functions with no arguments correctly, and
+ so we must explicitly cast them. */
+ terminal->clear_frame_hook = x_clear_frame;
+ terminal->ins_del_lines_hook = x_ins_del_lines;
+ terminal->delete_glyphs_hook = x_delete_glyphs;
+ terminal->ring_bell_hook = w32_ring_bell;
+ terminal->reset_terminal_modes_hook = w32_reset_terminal_modes;
+ terminal->set_terminal_modes_hook = w32_set_terminal_modes;
+ terminal->update_begin_hook = x_update_begin;
+ terminal->update_end_hook = x_update_end;
+ terminal->set_terminal_window_hook = w32_set_terminal_window;
+ terminal->read_socket_hook = w32_read_socket;
+ terminal->frame_up_to_date_hook = w32_frame_up_to_date;
+ terminal->mouse_position_hook = w32_mouse_position;
+ terminal->frame_rehighlight_hook = w32_frame_rehighlight;
+ terminal->frame_raise_lower_hook = w32_frame_raise_lower;
+ // terminal->fullscreen_hook = XTfullscreen_hook;
+ terminal->set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar;
+ terminal->condemn_scroll_bars_hook = w32_condemn_scroll_bars;
+ terminal->redeem_scroll_bar_hook = w32_redeem_scroll_bar;
+ terminal->judge_scroll_bars_hook = w32_judge_scroll_bars;
+
+ terminal->delete_frame_hook = x_destroy_window;
+ terminal->delete_terminal_hook = x_delete_terminal;
+
+ terminal->rif = &w32_redisplay_interface;
+ terminal->scroll_region_ok = 1; /* We'll scroll partial frames. */
+ terminal->char_ins_del_ok = 1;
+ terminal->line_ins_del_ok = 1; /* We'll just blt 'em. */
+ terminal->fast_clear_end_of_line = 1; /* X does this well. */
+ terminal->memory_below_frame = 0; /* We don't remember what scrolls
+ off the bottom. */
+
+ return terminal;
+}
+
+static void
+x_delete_terminal (struct terminal *terminal)
+{
+ struct w32_display_info *dpyinfo = terminal->display_info.w32;
+ int i;
+
+ /* Protect against recursive calls. Fdelete_frame in
+ delete_terminal calls us back when it deletes our last frame. */
+ if (terminal->deleted)
+ return;
+
+ BLOCK_INPUT;
+ /* Free the fonts in the font table. */
+ for (i = 0; i < dpyinfo->n_fonts; i++)
+ if (dpyinfo->font_table[i].name)
+ {
+ DeleteObject (((XFontStruct*)(dpyinfo->font_table[i].font))->hfont);
+ }
+
+ x_delete_display (dpyinfo);
+ UNBLOCK_INPUT;
+}
+
struct w32_display_info *
w32_term_init (display_name, xrm_option, resource_name)
Lisp_Object display_name;
@@ -6249,6 +6335,7 @@ w32_term_init (display_name, xrm_option, resource_name)
char *resource_name;
{
struct w32_display_info *dpyinfo;
+ struct terminal *terminal;
HDC hdc;
BLOCK_INPUT;
@@ -6262,6 +6349,12 @@ w32_term_init (display_name, xrm_option, resource_name)
w32_initialize_display_info (display_name);
dpyinfo = &one_w32_display_info;
+ terminal = w32_create_terminal (dpyinfo);
+
+ /* Set the name of the terminal. */
+ terminal->name = (char *) xmalloc (SBYTES (display_name) + 1);
+ strncpy (terminal->name, SDATA (display_name), SBYTES (display_name));
+ terminal->name[SBYTES (display_name)] = 0;
dpyinfo->xrdb = xrm_option ? w32_make_rdb (xrm_option) : NULL;
@@ -6291,6 +6384,9 @@ w32_term_init (display_name, xrm_option, resource_name)
w32_defined_color (0, "black", &color, 1);
}
+ /* Add the default keyboard. */
+ add_keyboard_wait_descriptor (0);
+
/* Create Fringe Bitmaps and store them for later use.
On W32, bitmaps are all unsigned short, as Windows requires
@@ -6322,7 +6418,6 @@ w32_term_init (display_name, xrm_option, resource_name)
}
/* Get rid of display DPYINFO, assuming all frames are already gone. */
-
void
x_delete_display (dpyinfo)
struct w32_display_info *dpyinfo;
@@ -6373,73 +6468,9 @@ x_delete_display (dpyinfo)
DWORD WINAPI w32_msg_worker (void * arg);
-void
-x_flush (struct frame * f)
-{ /* Nothing to do */ }
-
-extern frame_parm_handler w32_frame_parm_handlers[];
-
-static struct redisplay_interface w32_redisplay_interface =
-{
- w32_frame_parm_handlers,
- x_produce_glyphs,
- x_write_glyphs,
- x_insert_glyphs,
- x_clear_end_of_line,
- x_scroll_run,
- x_after_update_window_line,
- x_update_window_begin,
- x_update_window_end,
- x_cursor_to,
- x_flush,
- 0, /* flush_display_optional */
- x_clear_window_mouse_face,
- w32_get_glyph_overhangs,
- x_fix_overlapping_area,
- w32_draw_fringe_bitmap,
- w32_define_fringe_bitmap,
- w32_destroy_fringe_bitmap,
- w32_per_char_metric,
- w32_encode_char,
- NULL, /* w32_compute_glyph_string_overhangs */
- x_draw_glyph_string,
- w32_define_frame_cursor,
- w32_clear_frame_area,
- w32_draw_window_cursor,
- w32_draw_vertical_window_border,
- w32_shift_glyphs_for_insert
-};
-
static void
w32_initialize ()
{
- rif = &w32_redisplay_interface;
-
- /* MSVC does not type K&R functions with no arguments correctly, and
- so we must explicitly cast them. */
- clear_frame_hook = (void (*)(void)) x_clear_frame;
- ring_bell_hook = (void (*)(void)) w32_ring_bell;
- update_begin_hook = x_update_begin;
- update_end_hook = x_update_end;
-
- read_socket_hook = w32_read_socket;
-
- frame_up_to_date_hook = w32_frame_up_to_date;
-
- mouse_position_hook = w32_mouse_position;
- frame_rehighlight_hook = w32_frame_rehighlight;
- frame_raise_lower_hook = w32_frame_raise_lower;
- set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar;
- condemn_scroll_bars_hook = w32_condemn_scroll_bars;
- redeem_scroll_bar_hook = w32_redeem_scroll_bar;
- judge_scroll_bars_hook = w32_judge_scroll_bars;
-
- scroll_region_ok = 1; /* we'll scroll partial frames */
- char_ins_del_ok = 1;
- line_ins_del_ok = 1; /* we'll just blt 'em */
- fast_clear_end_of_line = 1; /* X does this well */
- memory_below_frame = 0; /* we don't remember what scrolls
- off the bottom */
baud_rate = 19200;
w32_system_caret_hwnd = NULL;
diff --git a/src/w32term.h b/src/w32term.h
index b73dcfc9ee2..3e7f3a3a6a9 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -100,6 +100,9 @@ struct w32_display_info
/* Chain of all w32_display_info structures. */
struct w32_display_info *next;
+ /* The generic display parameters corresponding to this w32 display. */
+ struct terminal *terminal;
+
/* This is a cons cell of the form (NAME . FONT-LIST-CACHE).
The same cons cell also appears in x_display_name_list. */
Lisp_Object name_list_element;
@@ -272,8 +275,10 @@ extern void w32_find_ccl_program();
diffs between X and w32 code. */
struct x_output
{
+#if 0 /* These are also defined in struct frame. Use that instead. */
PIX_TYPE background_pixel;
PIX_TYPE foreground_pixel;
+#endif
/* Keep track of focus. May be EXPLICIT if we received a FocusIn for this
frame, or IMPLICIT if we received an EnterNotify.
@@ -405,8 +410,6 @@ extern struct w32_output w32term_display;
#define FRAME_W32_WINDOW(f) ((f)->output_data.w32->window_desc)
#define FRAME_X_WINDOW(f) ((f)->output_data.w32->window_desc)
-#define FRAME_FOREGROUND_PIXEL(f) ((f)->output_data.x->foreground_pixel)
-#define FRAME_BACKGROUND_PIXEL(f) ((f)->output_data.x->background_pixel)
#define FRAME_FONT(f) ((f)->output_data.w32->font)
#define FRAME_FONTSET(f) ((f)->output_data.w32->fontset)
#define FRAME_BASELINE_OFFSET(f) ((f)->output_data.w32->baseline_offset)
@@ -590,10 +593,10 @@ do { \
} while (0)
#define w32_clear_rect(f,hdc,lprect) \
-w32_fill_rect (f,hdc,f->output_data.x->background_pixel,lprect)
+ w32_fill_rect (f, hdc, FRAME_BACKGROUND_PIXEL (f), lprect)
#define w32_clear_area(f,hdc,px,py,nx,ny) \
-w32_fill_area (f,hdc,f->output_data.x->background_pixel,px,py,nx,ny)
+ w32_fill_area (f, hdc, FRAME_BACKGROUND_PIXEL (f), px, py, nx, ny)
extern struct font_info *w32_load_font ();
extern void w32_unload_font ();
@@ -688,6 +691,9 @@ extern void wait_for_sync ();
extern BOOL parse_button ();
+extern void w32_sys_ring_bell (struct frame *f);
+extern void x_delete_display (struct w32_display_info *dpyinfo);
+
/* Keypad command key support. W32 doesn't have virtual keys defined
for the function keys on the keypad (they are mapped to the standard
fuction keys), so we define our own. */
diff --git a/src/widget.c b/src/widget.c
index 714da205a67..c76cce9e328 100644
--- a/src/widget.c
+++ b/src/widget.c
@@ -659,10 +659,10 @@ update_from_various_frame_slots (ew)
struct x_output *x = f->output_data.x;
ew->core.height = FRAME_PIXEL_HEIGHT (f) - x->menubar_height;
ew->core.width = FRAME_PIXEL_WIDTH (f);
- ew->core.background_pixel = x->background_pixel;
+ ew->core.background_pixel = FRAME_BACKGROUND_PIXEL (f);
ew->emacs_frame.internal_border_width = f->internal_border_width;
ew->emacs_frame.font = x->font;
- ew->emacs_frame.foreground_pixel = x->foreground_pixel;
+ ew->emacs_frame.foreground_pixel = FRAME_FOREGROUND_PIXEL (f);
ew->emacs_frame.cursor_color = x->cursor_pixel;
ew->core.border_pixel = x->border_pixel;
}
diff --git a/src/window.c b/src/window.c
index 6fe78166ba1..3db1802a861 100644
--- a/src/window.c
+++ b/src/window.c
@@ -21,6 +21,8 @@ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
#include <config.h>
+#include <stdio.h>
+
#include "lisp.h"
#include "buffer.h"
#include "keyboard.h"
@@ -7269,7 +7271,7 @@ and scrolling positions. */)
void
init_window_once ()
{
- struct frame *f = make_terminal_frame ();
+ struct frame *f = make_initial_frame ();
XSETFRAME (selected_frame, f);
Vterminal_frame = selected_frame;
minibuf_window = f->minibuffer_window;
diff --git a/src/window.h b/src/window.h
index ea8965392c4..c9ef865c4f0 100644
--- a/src/window.h
+++ b/src/window.h
@@ -744,7 +744,7 @@ extern Lisp_Object Vminibuf_scroll_window;
/* Nil or a symbol naming the window system under which emacs is
running ('x is the only current possibility) */
-extern Lisp_Object Vwindow_system;
+extern Lisp_Object Vinitial_window_system;
/* Version number of X windows: 10, 11 or nil. */
diff --git a/src/xdisp.c b/src/xdisp.c
index d22c9a53bc3..d16e13ef722 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -580,21 +580,12 @@ Lisp_Object Vmessage_log_max;
static Lisp_Object Vmessages_buffer_name;
-/* Index 0 is the buffer that holds the current (desired) echo area message,
- or nil if none is desired right now.
-
- Index 1 is the buffer that holds the previously displayed echo area message,
- or nil to indicate no message. This is normally what's on the screen now.
-
- These two can point to the same buffer. That happens when the last
- message output by the user (or made by echoing) has been displayed. */
+/* Current, index 0, and last displayed echo area message. Either
+ buffers from echo_buffers, or nil to indicate no message. */
Lisp_Object echo_area_buffer[2];
-/* Permanent pointers to the two buffers that are used for echo area
- purposes. Once the two buffers are made, and their pointers are
- placed here, these two slots remain unchanged unless those buffers
- need to be created afresh. */
+/* The buffers referenced from echo_area_buffer. */
static Lisp_Object echo_buffer[2];
@@ -813,10 +804,6 @@ static int clear_face_cache_count;
static int clear_image_cache_count;
#endif
-/* Record the previous terminal frame we displayed. */
-
-static struct frame *previous_terminal_frame;
-
/* Non-zero while redisplay_internal is in progress. */
int redisplaying_p;
@@ -2508,7 +2495,7 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id)
XSETWINDOW (it->window, w);
it->w = w;
it->f = XFRAME (w->frame);
-
+
/* Extra space between lines (on window systems only). */
if (base_face_id == DEFAULT_FACE_ID
&& FRAME_WINDOW_P (it->f))
@@ -2525,9 +2512,9 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id)
/* If realized faces have been removed, e.g. because of face
attribute changes of named faces, recompute them. When running
- in batch mode, the face cache of Vterminal_frame is null. If
+ in batch mode, the face cache of the initial frame is null. If
we happen to get called, make a dummy face cache. */
- if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
+ if (FRAME_FACE_CACHE (it->f) == NULL)
init_frame_faces (it->f);
if (FRAME_FACE_CACHE (it->f)->used == 0)
recompute_basic_faces (it->f);
@@ -3952,7 +3939,7 @@ handle_single_display_spec (it, spec, object, position,
&& EQ (XCAR (spec), Qheight)
&& CONSP (XCDR (spec)))
{
- if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
+ if (!FRAME_WINDOW_P (it->f))
return 0;
it->font_height = XCAR (XCDR (spec));
@@ -4018,7 +4005,7 @@ handle_single_display_spec (it, spec, object, position,
&& EQ (XCAR (spec), Qspace_width)
&& CONSP (XCDR (spec)))
{
- if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
+ if (!FRAME_WINDOW_P (it->f))
return 0;
value = XCAR (XCDR (spec));
@@ -4034,7 +4021,7 @@ handle_single_display_spec (it, spec, object, position,
{
Lisp_Object tem;
- if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
+ if (!FRAME_WINDOW_P (it->f))
return 0;
if (tem = XCDR (spec), CONSP (tem))
@@ -4060,7 +4047,7 @@ handle_single_display_spec (it, spec, object, position,
&& EQ (XCAR (spec), Qraise)
&& CONSP (XCDR (spec)))
{
- if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
+ if (!FRAME_WINDOW_P (it->f))
return 0;
#ifdef HAVE_WINDOW_SYSTEM
@@ -4101,7 +4088,7 @@ handle_single_display_spec (it, spec, object, position,
int face_id = DEFAULT_FACE_ID;
int fringe_bitmap;
- if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
+ if (!FRAME_WINDOW_P (it->f))
/* If we return here, POSITION has been advanced
across the text with this property. */
return 0;
@@ -4150,7 +4137,7 @@ handle_single_display_spec (it, spec, object, position,
it->left_user_fringe_face_id = face_id;
}
else
- {
+ {
it->right_user_fringe_bitmap = fringe_bitmap;
it->right_user_fringe_face_id = face_id;
}
@@ -4195,9 +4182,9 @@ handle_single_display_spec (it, spec, object, position,
valid_p = (STRINGP (value)
#ifdef HAVE_WINDOW_SYSTEM
- || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
+ || (FRAME_WINDOW_P (it->f) && valid_image_p (value))
#endif /* not HAVE_WINDOW_SYSTEM */
- || (CONSP (value) && EQ (XCAR (value), Qspace)));
+ || (CONSP (value) && EQ (XCAR (value), Qspace)));
if (valid_p && !display_replaced_before_p)
{
@@ -4267,7 +4254,7 @@ handle_single_display_spec (it, spec, object, position,
}
-/* Check if SPEC is a display specification value whose text should be
+/* Check if SPEC is a display sub-property value whose text should be
treated as intangible. */
static int
@@ -7528,8 +7515,8 @@ message2_nolog (m, nbytes, multibyte)
do_pending_window_change (0);
echo_area_display (1);
do_pending_window_change (0);
- if (frame_up_to_date_hook != 0 && ! gc_in_progress)
- (*frame_up_to_date_hook) (f);
+ if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
+ (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
}
}
@@ -7632,8 +7619,8 @@ message3_nolog (m, nbytes, multibyte)
do_pending_window_change (0);
echo_area_display (1);
do_pending_window_change (0);
- if (frame_up_to_date_hook != 0 && ! gc_in_progress)
- (*frame_up_to_date_hook) (f);
+ if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
+ (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
}
}
@@ -7871,6 +7858,10 @@ ensure_echo_area_buffers ()
WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
suitable buffer from echo_buffer[] and clear it.
+ If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
+ that the current message becomes the last displayed one, make
+ choose a suitable buffer for echo_area_buffer[0], and clear it.
+
Value is what FN returns. */
static int
@@ -7895,6 +7886,17 @@ with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
this_one = 0, the_other = 1;
else if (which > 0)
this_one = 1, the_other = 0;
+ else
+ {
+ this_one = 0, the_other = 1;
+ clear_buffer_p = 1;
+
+ /* We need a fresh one in case the current echo buffer equals
+ the one containing the last displayed echo area message. */
+ if (!NILP (echo_area_buffer[this_one])
+ && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
+ echo_area_buffer[this_one] = Qnil;
+ }
/* Choose a suitable buffer from echo_buffer[] is we don't
have one. */
@@ -8532,7 +8534,7 @@ set_message (s, string, nbytes, multibyte_p)
= ((s && multibyte_p)
|| (STRINGP (string) && STRING_MULTIBYTE (string)));
- with_echo_area_buffer (0, 0, set_message_1,
+ with_echo_area_buffer (0, -1, set_message_1,
(EMACS_INT) s, string, nbytes, multibyte_p);
message_buf_print = 0;
help_echo_showing_p = 0;
@@ -8562,7 +8564,6 @@ set_message_1 (a1, a2, nbytes, multibyte_p)
/* Insert new message at BEG. */
TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
- Ferase_buffer ();
if (STRINGP (string))
{
@@ -8658,11 +8659,11 @@ clear_garbaged_frames ()
{
Lisp_Object tail, frame;
int changed_count = 0;
-
+
FOR_EACH_FRAME (tail, frame)
{
struct frame *f = XFRAME (frame);
-
+
if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
{
if (f->resized_p)
@@ -8676,7 +8677,7 @@ clear_garbaged_frames ()
f->resized_p = 0;
}
}
-
+
frame_garbaged = 0;
if (changed_count)
++windows_or_buffers_changed;
@@ -8709,11 +8710,10 @@ echo_area_display (update_frame_p)
/* The terminal frame is used as the first Emacs frame on the Mac OS. */
#ifndef MAC_OS8
#ifdef HAVE_WINDOW_SYSTEM
- /* When Emacs starts, selected_frame may be a visible terminal
- frame, even if we run under a window system. If we let this
- through, a message would be displayed on the terminal. */
- if (EQ (selected_frame, Vterminal_frame)
- && !NILP (Vwindow_system))
+ /* When Emacs starts, selected_frame may be the initial terminal
+ frame. If we let this through, a message would be displayed on
+ the terminal. */
+ if (FRAME_INITIAL_P (XFRAME (selected_frame)))
return 0;
#endif /* HAVE_WINDOW_SYSTEM */
#endif
@@ -8764,7 +8764,7 @@ echo_area_display (update_frame_p)
Can do with a display update of the echo area,
unless we displayed some mode lines. */
update_single_window (w, 1);
- rif->flush_display (f);
+ FRAME_RIF (f)->flush_display (f);
}
else
update_frame (f, 1, 1);
@@ -8779,8 +8779,10 @@ echo_area_display (update_frame_p)
else if (!EQ (mini_window, selected_window))
windows_or_buffers_changed++;
- /* The current message is now also the last one displayed. */
+ /* Last displayed message is now the current message. */
echo_area_buffer[1] = echo_area_buffer[0];
+ /* Inform read_char that we're not echoing. */
+ echo_message_buffer = Qnil;
/* Prevent redisplay optimization in redisplay_internal by resetting
this_line_start_pos. This is done because the mini-buffer now
@@ -9334,8 +9336,8 @@ x_cursor_to (vpos, hpos, y, x)
{
BLOCK_INPUT;
display_and_set_cursor (w, 1, hpos, vpos, x, y);
- if (rif->flush_display_optional)
- rif->flush_display_optional (SELECTED_FRAME ());
+ if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
+ FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
UNBLOCK_INPUT;
}
}
@@ -10787,6 +10789,8 @@ select_frame_for_redisplay (frame)
Lisp_Object tail, sym, val;
Lisp_Object old = selected_frame;
+ xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
+
selected_frame = frame;
for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
@@ -10924,17 +10928,16 @@ redisplay_internal (preserve_echo_area)
if (face_change_count)
++windows_or_buffers_changed;
- if (! FRAME_WINDOW_P (sf)
- && previous_terminal_frame != sf)
+ if (FRAME_TERMCAP_P (sf)
+ && FRAME_TTY (sf)->previous_frame != sf)
{
- /* Since frames on an ASCII terminal share the same display
- area, displaying a different frame means redisplay the whole
- thing. */
+ /* Since frames on a single ASCII terminal share the same
+ display area, displaying a different frame means redisplay
+ the whole thing. */
windows_or_buffers_changed++;
SET_FRAME_GARBAGED (sf);
- XSETFRAME (Vterminal_frame, sf);
+ FRAME_TTY (sf)->previous_frame = sf;
}
- previous_terminal_frame = sf;
/* Set the visible flags for all frames. Do this before checking
for resized or garbaged frames; they want to know if their frames
@@ -10956,6 +10959,7 @@ redisplay_internal (preserve_echo_area)
}
}
+
/* Notice any pending interrupt request to change frame size. */
do_pending_window_change (1);
@@ -11317,7 +11321,7 @@ redisplay_internal (preserve_echo_area)
{
struct frame *f = XFRAME (frame);
- if (FRAME_WINDOW_P (f) || f == sf)
+ if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
{
if (! EQ (frame, selected_frame))
/* Select the frame, for the sake of frame-local
@@ -11326,16 +11330,16 @@ redisplay_internal (preserve_echo_area)
/* Mark all the scroll bars to be removed; we'll redeem
the ones we want when we redisplay their windows. */
- if (condemn_scroll_bars_hook)
- condemn_scroll_bars_hook (f);
+ if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
+ FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
redisplay_windows (FRAME_ROOT_WINDOW (f));
/* Any scroll bars which redisplay_windows should have
nuked should now go away. */
- if (judge_scroll_bars_hook)
- judge_scroll_bars_hook (f);
+ if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
+ FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
/* If fonts changed, display again. */
/* ??? rms: I suspect it is a mistake to jump all the way
@@ -11382,12 +11386,12 @@ redisplay_internal (preserve_echo_area)
FOR_EACH_FRAME (tail, frame)
{
struct frame *f = XFRAME (frame);
- if (f->updated_p)
- {
- mark_window_display_accurate (f->root_window, 1);
- if (frame_up_to_date_hook)
- frame_up_to_date_hook (f);
- }
+ if (f->updated_p)
+ {
+ mark_window_display_accurate (f->root_window, 1);
+ if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
+ FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
+ }
}
}
}
@@ -11472,8 +11476,8 @@ redisplay_internal (preserve_echo_area)
/* Say overlay arrows are up to date. */
update_overlay_arrows (1);
- if (frame_up_to_date_hook != 0)
- frame_up_to_date_hook (sf);
+ if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
+ FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
}
update_mode_lines = 0;
@@ -11583,8 +11587,9 @@ redisplay_preserve_echo_area (from_where)
else
redisplay_internal (1);
- if (rif != NULL && rif->flush_display_optional)
- rif->flush_display_optional (NULL);
+ if (FRAME_RIF (SELECTED_FRAME ()) != NULL
+ && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
+ FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
}
@@ -11592,7 +11597,8 @@ redisplay_preserve_echo_area (from_where)
redisplay_internal. Reset redisplaying_p to the value it had
before redisplay_internal was called, and clear
prevent_freeing_realized_faces_p. It also selects the previously
- selected frame. */
+ selected frame, unless it has been deleted (by an X connection
+ failure during redisplay, for example). */
static Lisp_Object
unwind_redisplay (val)
@@ -11603,7 +11609,8 @@ unwind_redisplay (val)
old_redisplaying_p = XCAR (val);
redisplaying_p = XFASTINT (old_redisplaying_p);
old_frame = XCDR (val);
- if (! EQ (old_frame, selected_frame))
+ if (! EQ (old_frame, selected_frame)
+ && FRAME_LIVE_P (XFRAME (old_frame)))
select_frame_for_redisplay (old_frame);
return Qnil;
}
@@ -12752,7 +12759,9 @@ set_vertical_scroll_bar (w)
start = end = whole = 0;
/* Indicate what this scroll bar ought to be displaying now. */
- set_vertical_scroll_bar_hook (w, end - start, whole, start);
+ if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
+ (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
+ (w, end - start, whole, start);
}
@@ -13471,20 +13480,22 @@ redisplay_window (window, just_this_one_p)
display_menu_bar (w);
#ifdef HAVE_WINDOW_SYSTEM
+ if (FRAME_WINDOW_P (f))
+ {
#if defined (USE_GTK) || USE_MAC_TOOLBAR
- redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
+ redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
#else
- redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
- && (FRAME_TOOL_BAR_LINES (f) > 0
- || !NILP (Vauto_resize_tool_bars));
-
+ redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
+ && (FRAME_TOOL_BAR_LINES (f) > 0
+ || !NILP (Vauto_resize_tool_bars));
#endif
- if (redisplay_tool_bar_p && redisplay_tool_bar (f))
- {
- extern int ignore_mouse_drag_p;
- ignore_mouse_drag_p = 1;
- }
+ if (redisplay_tool_bar_p && redisplay_tool_bar (f))
+ {
+ extern int ignore_mouse_drag_p;
+ ignore_mouse_drag_p = 1;
+ }
+ }
#endif
}
@@ -13518,7 +13529,8 @@ redisplay_window (window, just_this_one_p)
/* Note that we actually used the scroll bar attached to this
window, so it shouldn't be deleted at the end of redisplay. */
- redeem_scroll_bar_hook (w);
+ if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
+ (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
}
/* Restore current_buffer and value of point in it. */
@@ -13787,10 +13799,10 @@ try_window_reusing_current_matrix (w)
if (run.height > 0 && run.current_y != run.desired_y)
{
update_begin (f);
- rif->update_window_begin_hook (w);
- rif->clear_window_mouse_face (w);
- rif->scroll_run_hook (w, &run);
- rif->update_window_end_hook (w, 0, 0);
+ FRAME_RIF (f)->update_window_begin_hook (w);
+ FRAME_RIF (f)->clear_window_mouse_face (w);
+ FRAME_RIF (f)->scroll_run_hook (w, &run);
+ FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
update_end (f);
}
@@ -13959,10 +13971,10 @@ try_window_reusing_current_matrix (w)
if (run.height)
{
update_begin (f);
- rif->update_window_begin_hook (w);
- rif->clear_window_mouse_face (w);
- rif->scroll_run_hook (w, &run);
- rif->update_window_end_hook (w, 0, 0);
+ FRAME_RIF (f)->update_window_begin_hook (w);
+ FRAME_RIF (f)->clear_window_mouse_face (w);
+ FRAME_RIF (f)->scroll_run_hook (w, &run);
+ FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
update_end (f);
}
@@ -14412,7 +14424,7 @@ try_window_id (w)
/* Window must either use window-based redisplay or be full width. */
if (!FRAME_WINDOW_P (f)
- && (!line_ins_del_ok
+ && (!FRAME_LINE_INS_DEL_OK (f)
|| !WINDOW_FULL_WIDTH_P (w)))
GIVE_UP (4);
@@ -14821,10 +14833,10 @@ try_window_id (w)
if (FRAME_WINDOW_P (f))
{
- rif->update_window_begin_hook (w);
- rif->clear_window_mouse_face (w);
- rif->scroll_run_hook (w, &run);
- rif->update_window_end_hook (w, 0, 0);
+ FRAME_RIF (f)->update_window_begin_hook (w);
+ FRAME_RIF (f)->clear_window_mouse_face (w);
+ FRAME_RIF (f)->scroll_run_hook (w, &run);
+ FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
}
else
{
@@ -14842,36 +14854,36 @@ try_window_id (w)
{
/* Scroll last_unchanged_at_beg_row to the end of the
window down dvpos lines. */
- set_terminal_window (end);
+ set_terminal_window (f, end);
/* On dumb terminals delete dvpos lines at the end
before inserting dvpos empty lines. */
- if (!scroll_region_ok)
- ins_del_lines (end - dvpos, -dvpos);
+ if (!FRAME_SCROLL_REGION_OK (f))
+ ins_del_lines (f, end - dvpos, -dvpos);
/* Insert dvpos empty lines in front of
last_unchanged_at_beg_row. */
- ins_del_lines (from, dvpos);
+ ins_del_lines (f, from, dvpos);
}
else if (dvpos < 0)
{
/* Scroll up last_unchanged_at_beg_vpos to the end of
the window to last_unchanged_at_beg_vpos - |dvpos|. */
- set_terminal_window (end);
+ set_terminal_window (f, end);
/* Delete dvpos lines in front of
last_unchanged_at_beg_vpos. ins_del_lines will set
the cursor to the given vpos and emit |dvpos| delete
line sequences. */
- ins_del_lines (from + dvpos, dvpos);
+ ins_del_lines (f, from + dvpos, dvpos);
/* On a dumb terminal insert dvpos empty lines at the
end. */
- if (!scroll_region_ok)
- ins_del_lines (end + dvpos, -dvpos);
+ if (!FRAME_SCROLL_REGION_OK (f))
+ ins_del_lines (f, end + dvpos, -dvpos);
}
- set_terminal_window (0);
+ set_terminal_window (f, 0);
}
update_end (f);
@@ -16445,7 +16457,7 @@ display_menu_bar (w)
/* Don't do all this for graphical frames. */
#ifdef HAVE_NTGUI
- if (!NILP (Vwindow_system))
+ if (FRAME_W32_P (f))
return;
#endif
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
@@ -16676,10 +16688,10 @@ display_mode_line (w, face_id, format)
/* Temporarily make frame's keyboard the current kboard so that
kboard-local variables in the mode_line_format will get the right
values. */
- push_frame_kboard (it.f);
+ push_kboard (FRAME_KBOARD (it.f));
record_unwind_save_match_data ();
display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
- pop_frame_kboard ();
+ pop_kboard ();
unbind_to (count, Qnil);
@@ -17394,9 +17406,9 @@ are the selected window and the window's buffer). */)
= (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
}
- push_frame_kboard (it.f);
+ push_kboard (FRAME_KBOARD (it.f));
display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
- pop_frame_kboard ();
+ pop_kboard ();
if (no_props)
{
@@ -18030,8 +18042,8 @@ decode_mode_spec (w, c, field_width, precision, multibyte)
{
/* No need to mention EOL here--the terminal never needs
to do EOL conversion. */
- p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
- p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
+ p = decode_mode_spec_coding (FRAME_KEYBOARD_CODING (f)->symbol, p, 0);
+ p = decode_mode_spec_coding (FRAME_TERMINAL_CODING (f)->symbol, p, 0);
}
p = decode_mode_spec_coding (b->buffer_file_coding_system,
p, eol_flag);
@@ -18544,6 +18556,8 @@ calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
if (NILP (prop))
return OK_PIXELS (0);
+ xassert (FRAME_LIVE_P (it->f));
+
if (SYMBOLP (prop))
{
if (SCHARS (SYMBOL_NAME (prop)) == 2)
@@ -18660,7 +18674,8 @@ calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
if (SYMBOLP (car))
{
#ifdef HAVE_WINDOW_SYSTEM
- if (valid_image_p (prop))
+ if (FRAME_WINDOW_P (it->f)
+ && valid_image_p (prop))
{
int id = lookup_image (it->f, prop);
struct image *img = IMAGE_FROM_ID (it->f, id);
@@ -18901,7 +18916,7 @@ get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
= FONT_INFO_FROM_ID (f, face->font_info_id);
if (font_info)
glyph->font_type
- = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
+ = FRAME_RIF (f)->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
}
}
@@ -19134,7 +19149,7 @@ x_get_glyph_overhangs (glyph, f, left, right)
font = face->font;
font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
if (font /* ++KFS: Should this be font_info ? */
- && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
+ && (pcm = FRAME_RIF (f)->per_char_metric (font, &char2b, glyph->font_type)))
{
if (pcm->rbearing > pcm->width)
*right = pcm->rbearing - pcm->width;
@@ -19302,7 +19317,7 @@ get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
struct font_info *font_info
= FONT_INFO_FROM_ID (f, face->font_info_id);
if (font_info)
- rif->encode_char (c, char2b, font_info, 0);
+ FRAME_RIF (f)->encode_char (c, char2b, font_info, 0);
}
}
@@ -19365,8 +19380,8 @@ compute_overhangs_and_x (s, x, backward_p)
{
while (s)
{
- if (rif->compute_glyph_string_overhangs)
- rif->compute_glyph_string_overhangs (s);
+ if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
+ FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
x -= s->width;
s->x = x;
s = s->prev;
@@ -19376,8 +19391,8 @@ compute_overhangs_and_x (s, x, backward_p)
{
while (s)
{
- if (rif->compute_glyph_string_overhangs)
- rif->compute_glyph_string_overhangs (s);
+ if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
+ FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
s->x = x;
x += s->width;
s = s->next;
@@ -19665,9 +19680,9 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps)
struct glyph_string *h, *t;
/* Compute overhangs for all glyph strings. */
- if (rif->compute_glyph_string_overhangs)
+ if (FRAME_RIF (f)->compute_glyph_string_overhangs)
for (s = head; s; s = s->next)
- rif->compute_glyph_string_overhangs (s);
+ FRAME_RIF (f)->compute_glyph_string_overhangs (s);
/* Prepend glyph strings for glyphs in front of the first glyph
string that are overwritten because of the first glyph
@@ -19745,7 +19760,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps)
/* Draw all strings. */
for (s = head; s; s = s->next)
- rif->draw_glyph_string (s);
+ FRAME_RIF (f)->draw_glyph_string (s);
if (area == TEXT_AREA
&& !row->full_width_p
@@ -20440,20 +20455,20 @@ x_produce_glyphs (it)
it->nglyphs = 1;
- pcm = rif->per_char_metric (font, &char2b,
- FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
-
- if (it->override_ascent >= 0)
- {
- it->ascent = it->override_ascent;
- it->descent = it->override_descent;
- boff = it->override_boff;
- }
- else
- {
- it->ascent = FONT_BASE (font) + boff;
- it->descent = FONT_DESCENT (font) - boff;
- }
+ pcm = FRAME_RIF (it->f)->per_char_metric
+ (font, &char2b, FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
+
+ if (it->override_ascent >= 0)
+ {
+ it->ascent = it->override_ascent;
+ it->descent = it->override_descent;
+ boff = it->override_boff;
+ }
+ else
+ {
+ it->ascent = FONT_BASE (font) + boff;
+ it->descent = FONT_DESCENT (font) - boff;
+ }
if (pcm)
{
@@ -20671,8 +20686,8 @@ x_produce_glyphs (it)
from the charset width; this is what old redisplay code
did. */
- pcm = rif->per_char_metric (font, &char2b,
- FONT_TYPE_FOR_MULTIBYTE (font, it->c));
+ pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
+ FONT_TYPE_FOR_MULTIBYTE (font, it->c));
if (font_not_found_p || !pcm)
{
@@ -20803,8 +20818,8 @@ x_produce_glyphs (it)
/* Initialize the bounding box. */
if (font_info
- && (pcm = rif->per_char_metric (font, &char2b,
- FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
+ && (pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
+ FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
{
width = pcm->width;
ascent = pcm->ascent;
@@ -20862,8 +20877,8 @@ x_produce_glyphs (it)
}
if (font_info
- && (pcm = rif->per_char_metric (font, &char2b,
- FONT_TYPE_FOR_MULTIBYTE (font, ch))))
+ && (pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
+ FONT_TYPE_FOR_MULTIBYTE (font, ch))))
{
width = pcm->width;
ascent = pcm->ascent;
@@ -21103,8 +21118,8 @@ x_insert_glyphs (start, len)
frame_x = window_box_left (w, updated_area) + output_cursor.x;
frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
- rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
- line_height, shift_by_width);
+ FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
+ line_height, shift_by_width);
/* Write the glyphs. */
hpos = start - row->glyphs[updated_area];
@@ -21186,8 +21201,8 @@ x_clear_end_of_line (to_x)
if (to_x > from_x && to_y > from_y)
{
BLOCK_INPUT;
- rif->clear_frame_area (f, from_x, from_y,
- to_x - from_x, to_y - from_y);
+ FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
+ to_x - from_x, to_y - from_y);
UNBLOCK_INPUT;
}
}
@@ -21700,7 +21715,7 @@ erase_phys_cursor (w)
x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
if (width > 0)
- rif->clear_frame_area (f, x, y, width, cursor_row->visible_height);
+ FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
}
/* Erase the cursor by redrawing the character underneath it. */
@@ -21797,9 +21812,9 @@ display_and_set_cursor (w, on, hpos, vpos, x, y)
w->phys_cursor.vpos = vpos;
}
- rif->draw_window_cursor (w, glyph_row, x, y,
- new_cursor_type, new_cursor_width,
- on, active_cursor);
+ FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
+ new_cursor_type, new_cursor_width,
+ on, active_cursor);
}
@@ -21948,11 +21963,11 @@ show_mouse_face (dpyinfo, draw)
/* Change the mouse cursor. */
if (draw == DRAW_NORMAL_TEXT && !EQ (dpyinfo->mouse_face_window, f->tool_bar_window))
- rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
+ FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
else if (draw == DRAW_MOUSE_FACE)
- rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
+ FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
else
- rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
+ FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
}
/* EXPORT:
@@ -22391,7 +22406,6 @@ on_hot_spot_p (hot_spot, x, y)
return inside;
}
}
- /* If we don't understand the format, pretend we're not in the hot-spot. */
return 0;
}
@@ -22471,7 +22485,7 @@ define_frame_cursor1 (f, cursor, pointer)
}
if (cursor != No_Cursor)
- rif->define_frame_cursor (f, cursor);
+ FRAME_RIF (f)->define_frame_cursor (f, cursor);
}
/* Take proper action when mouse has moved to the mode or header line
@@ -23439,8 +23453,8 @@ phys_cursor_in_rect_p (w, r)
I assume the effect is the same -- and this is portable. */
return x_intersect_rectangles (&cr, r, &result);
}
- else
- return 0;
+ /* If we don't understand the format, pretend we're not in the hot-spot. */
+ return 0;
}
@@ -23452,6 +23466,8 @@ void
x_draw_vertical_border (w)
struct window *w;
{
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
+
/* We could do better, if we knew what type of scroll-bar the adjacent
windows (on either side) have... But we don't :-(
However, I think this works ok. ++KFS 2003-04-25 */
@@ -23472,9 +23488,9 @@ x_draw_vertical_border (w)
y1 -= 1;
if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
- x1 -= 1;
+ x1 -= 1;
- rif->draw_vertical_window_border (w, x1, y0, y1);
+ FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
}
else if (!WINDOW_LEFTMOST_P (w)
&& !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
@@ -23485,9 +23501,9 @@ x_draw_vertical_border (w)
y1 -= 1;
if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
- x0 -= 1;
+ x0 -= 1;
- rif->draw_vertical_window_border (w, x0, y0, y1);
+ FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
}
}
diff --git a/src/xfaces.c b/src/xfaces.c
index ffaf2afda21..734e2eb3827 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -195,11 +195,13 @@ Boston, MA 02110-1301, USA. */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <stdio.h> /* This needs to be before termchar.h */
#include "lisp.h"
#include "charset.h"
#include "keyboard.h"
#include "frame.h"
+#include "termhooks.h"
#ifdef HAVE_WINDOW_SYSTEM
#include "fontset.h"
@@ -242,6 +244,7 @@ Boston, MA 02110-1301, USA. */
#include "blockinput.h"
#include "window.h"
#include "intervals.h"
+#include "termchar.h"
#ifdef HAVE_X_WINDOWS
@@ -3221,6 +3224,20 @@ push_named_merge_point (struct named_merge_point *new_named_merge_point,
+static Lisp_Object
+internal_resolve_face_name (nargs, args)
+ int nargs;
+ Lisp_Object *args;
+{
+ Fget (args[0], args[1]);
+}
+
+static Lisp_Object
+resolve_face_name_error (ignore)
+ Lisp_Object ignore;
+{
+ return Qnil;
+}
/* Resolve face name FACE_NAME. If FACE_NAME is a string, intern it
to make it a symbol. If FACE_NAME is an alias for another face,
@@ -6147,7 +6164,7 @@ tty_supports_face_attributes_p (f, attrs, def_face)
/* See if the capabilities we selected above are supported, with the
given colors. */
if (test_caps != 0 &&
- ! tty_capable_p (f, test_caps, fg_tty_color.pixel, bg_tty_color.pixel))
+ ! tty_capable_p (FRAME_TTY (f), test_caps, fg_tty_color.pixel, bg_tty_color.pixel))
return 0;
@@ -6951,7 +6968,8 @@ realize_basic_faces (f)
{
FRAME_FACE_CACHE (f)->menu_face_changed_p = 0;
#ifdef USE_X_TOOLKIT
- x_update_menu_appearance (f);
+ if (FRAME_WINDOW_P (f))
+ x_update_menu_appearance (f);
#endif
}
@@ -7038,7 +7056,7 @@ realize_default_face (f)
LFACE_FOREGROUND (lface) = XCDR (color);
else if (FRAME_WINDOW_P (f))
return 0;
- else if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
+ else if (FRAME_INITIAL_P (f) || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
LFACE_FOREGROUND (lface) = build_string (unspecified_fg);
else
abort ();
@@ -7053,7 +7071,7 @@ realize_default_face (f)
LFACE_BACKGROUND (lface) = XCDR (color);
else if (FRAME_WINDOW_P (f))
return 0;
- else if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
+ else if (FRAME_INITIAL_P (f) || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
LFACE_BACKGROUND (lface) = build_string (unspecified_bg);
else
abort ();
@@ -7070,17 +7088,17 @@ realize_default_face (f)
#ifdef HAVE_WINDOW_SYSTEM
#ifdef HAVE_X_WINDOWS
- if (face->font != FRAME_FONT (f))
+ if (FRAME_X_P (f) && face->font != FRAME_FONT (f))
{
/* This can happen when making a frame on a display that does
- not support the default font. */
+ not support the default font. */
if (!face->font)
- return 0;
-
+ return 0;
+
/* Otherwise, the font specified for the frame was not
- acceptable as a font for the default face (perhaps because
- auto-scaled fonts are rejected), so we must adjust the frame
- font. */
+ acceptable as a font for the default face (perhaps because
+ auto-scaled fonts are rejected), so we must adjust the frame
+ font. */
x_set_font (f, build_string (face->font_name), Qnil);
}
#endif /* HAVE_X_WINDOWS */
@@ -7160,6 +7178,11 @@ realize_face (cache, attrs, c, base_face, former_face_id)
face = realize_x_face (cache, attrs, c, base_face);
else if (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f))
face = realize_tty_face (cache, attrs, c);
+ else if (FRAME_INITIAL_P (cache->f))
+ {
+ /* Create a dummy face. */
+ face = make_realized_face (attrs);
+ }
else
abort ();
diff --git a/src/xfns.c b/src/xfns.c
index 0c06abb44d4..e49f8cb3112 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -47,6 +47,7 @@ Boston, MA 02110-1301, USA. */
#include "systime.h"
#include "termhooks.h"
#include "atimer.h"
+#include "termchar.h"
#ifdef HAVE_X_WINDOWS
@@ -255,17 +256,18 @@ check_x_frame (frame)
return f;
}
-/* Let the user specify an X display with a frame.
+/* Let the user specify an X display with a Lisp object.
+ OBJECT may be nil, a frame or a terminal id.
nil stands for the selected frame--or, if that is not an X frame,
the first X display on the list. */
struct x_display_info *
-check_x_display_info (frame)
- Lisp_Object frame;
+check_x_display_info (object)
+ Lisp_Object object;
{
struct x_display_info *dpyinfo = NULL;
- if (NILP (frame))
+ if (NILP (object))
{
struct frame *sf = XFRAME (selected_frame);
@@ -276,11 +278,20 @@ check_x_display_info (frame)
else
error ("X windows are not in use or not initialized");
}
- else if (STRINGP (frame))
- dpyinfo = x_display_info_for_name (frame);
+ else if (INTEGERP (object))
+ {
+ struct terminal *t = get_terminal (XINT (object), 1);
+
+ if (t->type != output_x_window)
+ error ("Terminal %d is not an X display", XINT (object));
+
+ dpyinfo = t->display_info.x;
+ }
+ else if (STRINGP (object))
+ dpyinfo = x_display_info_for_name (object);
else
{
- FRAME_PTR f = check_x_frame (frame);
+ FRAME_PTR f = check_x_frame (object);
dpyinfo = FRAME_X_DISPLAY_INFO (f);
}
@@ -861,8 +872,8 @@ x_set_foreground_color (f, arg, oldval)
unsigned long fg, old_fg;
fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
- old_fg = x->foreground_pixel;
- x->foreground_pixel = fg;
+ old_fg = FRAME_FOREGROUND_PIXEL (f);
+ FRAME_FOREGROUND_PIXEL (f) = fg;
if (FRAME_X_WINDOW (f) != 0)
{
@@ -899,8 +910,8 @@ x_set_background_color (f, arg, oldval)
unsigned long bg;
bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
- unload_color (f, x->background_pixel);
- x->background_pixel = bg;
+ unload_color (f, FRAME_BACKGROUND_PIXEL (f));
+ FRAME_BACKGROUND_PIXEL (f) = bg;
if (FRAME_X_WINDOW (f) != 0)
{
@@ -948,13 +959,13 @@ x_set_mouse_color (f, arg, oldval)
Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
Cursor hourglass_cursor, horizontal_drag_cursor;
unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
- unsigned long mask_color = x->background_pixel;
+ unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
/* Don't let pointers be invisible. */
if (mask_color == pixel)
{
x_free_colors (f, &pixel, 1);
- pixel = x_copy_color (f, x->foreground_pixel);
+ pixel = x_copy_color (f, FRAME_FOREGROUND_PIXEL (f));
}
unload_color (f, x->mouse_pixel);
@@ -1097,13 +1108,13 @@ x_set_cursor_color (f, arg, oldval)
fore_pixel_allocated_p = 1;
}
else
- fore_pixel = x->background_pixel;
+ fore_pixel = FRAME_BACKGROUND_PIXEL (f);
pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
pixel_allocated_p = 1;
/* Make sure that the cursor color differs from the background color. */
- if (pixel == x->background_pixel)
+ if (pixel == FRAME_BACKGROUND_PIXEL (f))
{
if (pixel_allocated_p)
{
@@ -1119,7 +1130,7 @@ x_set_cursor_color (f, arg, oldval)
x_free_colors (f, &fore_pixel, 1);
fore_pixel_allocated_p = 0;
}
- fore_pixel = x->background_pixel;
+ fore_pixel = FRAME_BACKGROUND_PIXEL (f);
}
}
@@ -1404,10 +1415,8 @@ x_set_tool_bar_lines (f, value, oldval)
below the menu bar. */
if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
{
- updating_frame = f;
- clear_frame ();
+ clear_frame (f);
clear_current_matrices (f);
- updating_frame = NULL;
}
/* If the tool bar gets smaller, the internal border below it
@@ -1458,10 +1467,10 @@ x_set_scroll_bar_foreground (f, value, oldval)
if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
{
/* Remove all scroll bars because they have wrong colors. */
- if (condemn_scroll_bars_hook)
- (*condemn_scroll_bars_hook) (f);
- if (judge_scroll_bars_hook)
- (*judge_scroll_bars_hook) (f);
+ if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
+ (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
+ if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
+ (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
update_face_from_frame_parameter (f, Qscroll_bar_foreground, value);
redraw_frame (f);
@@ -1507,10 +1516,10 @@ x_set_scroll_bar_background (f, value, oldval)
if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
{
/* Remove all scroll bars because they have wrong colors. */
- if (condemn_scroll_bars_hook)
- (*condemn_scroll_bars_hook) (f);
- if (judge_scroll_bars_hook)
- (*judge_scroll_bars_hook) (f);
+ if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
+ (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
+ if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
+ (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
update_face_from_frame_parameter (f, Qscroll_bar_background, value);
redraw_frame (f);
@@ -2738,7 +2747,7 @@ x_window (f)
XSetWindowAttributes attributes;
unsigned long attribute_mask;
- attributes.background_pixel = f->output_data.x->background_pixel;
+ attributes.background_pixel = FRAME_BACKGROUND_PIXEL (f);
attributes.border_pixel = f->output_data.x->border_pixel;
attributes.bit_gravity = StaticGravity;
attributes.backing_store = NotUseful;
@@ -2926,8 +2935,8 @@ x_make_gc (f)
/* Normal video */
gc_values.font = FRAME_FONT (f)->fid;
- gc_values.foreground = f->output_data.x->foreground_pixel;
- gc_values.background = f->output_data.x->background_pixel;
+ gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
+ gc_values.background = FRAME_BACKGROUND_PIXEL (f);
gc_values.line_width = 0; /* Means 1 using fast algorithm. */
f->output_data.x->normal_gc
= XCreateGC (FRAME_X_DISPLAY (f),
@@ -2936,8 +2945,8 @@ x_make_gc (f)
&gc_values);
/* Reverse video style. */
- gc_values.foreground = f->output_data.x->background_pixel;
- gc_values.background = f->output_data.x->foreground_pixel;
+ gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
+ gc_values.background = FRAME_FOREGROUND_PIXEL (f);
f->output_data.x->reverse_gc
= XCreateGC (FRAME_X_DISPLAY (f),
FRAME_X_WINDOW (f),
@@ -2945,7 +2954,7 @@ x_make_gc (f)
&gc_values);
/* Cursor has cursor-color background, background-color foreground. */
- gc_values.foreground = f->output_data.x->background_pixel;
+ gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
gc_values.background = f->output_data.x->cursor_pixel;
gc_values.fill_style = FillOpaqueStippled;
gc_values.stipple
@@ -2969,8 +2978,8 @@ x_make_gc (f)
= (XCreatePixmapFromBitmapData
(FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
gray_bits, gray_width, gray_height,
- f->output_data.x->foreground_pixel,
- f->output_data.x->background_pixel,
+ FRAME_FOREGROUND_PIXEL (f),
+ FRAME_BACKGROUND_PIXEL (f),
DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
UNBLOCK_INPUT;
@@ -3025,6 +3034,12 @@ unwind_create_frame (frame)
{
struct frame *f = XFRAME (frame);
+ /* If frame is already dead, nothing to do. This can happen if the
+ display is disconnected after the frame has become official, but
+ before x_create_frame removes the unwind protect. */
+ if (!FRAME_LIVE_P (f))
+ return Qnil;
+
/* If frame is ``official'', nothing to do. */
if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
{
@@ -3073,24 +3088,27 @@ This function is an internal primitive--use `make-frame' instead. */)
Lisp_Object parent;
struct kboard *kb;
- check_x ();
-
parms = Fcopy_alist (parms);
/* Use this general default value to start with
until we know if this frame has a specified name. */
Vx_resource_name = Vinvocation_name;
- display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
+ display = x_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_NUMBER);
+ if (EQ (display, Qunbound))
+ display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
if (EQ (display, Qunbound))
display = Qnil;
dpyinfo = check_x_display_info (display);
#ifdef MULTI_KBOARD
- kb = dpyinfo->kboard;
+ kb = dpyinfo->terminal->kboard;
#else
kb = &the_only_kboard;
#endif
+ if (dpyinfo->terminal->deleted)
+ error ("Terminal is being deleted, can't create new frames on it");
+
name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
if (!STRINGP (name)
&& ! EQ (name, Qunbound)
@@ -3131,6 +3149,9 @@ This function is an internal primitive--use `make-frame' instead. */)
/* Note that X Windows does support scroll bars. */
FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
+ f->terminal = dpyinfo->terminal;
+ f->terminal->reference_count++;
+
f->output_method = output_x_window;
f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output));
bzero (f->output_data.x, sizeof (struct x_output));
@@ -3157,9 +3178,6 @@ This function is an internal primitive--use `make-frame' instead. */)
image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount;
dpyinfo_refcount = dpyinfo->reference_count;
#endif /* GLYPH_DEBUG */
-#ifdef MULTI_KBOARD
- FRAME_KBOARD (f) = kb;
-#endif
/* These colors will be set anyway later, but it's important
to get the color reference counts right, so initialize them! */
@@ -3170,8 +3188,8 @@ This function is an internal primitive--use `make-frame' instead. */)
/* Function x_decode_color can signal an error. Make
sure to initialize color slots so that we won't try
to free colors we haven't allocated. */
- f->output_data.x->foreground_pixel = -1;
- f->output_data.x->background_pixel = -1;
+ FRAME_FOREGROUND_PIXEL (f) = -1;
+ FRAME_BACKGROUND_PIXEL (f) = -1;
f->output_data.x->cursor_pixel = -1;
f->output_data.x->cursor_foreground_pixel = -1;
f->output_data.x->border_pixel = -1;
@@ -3179,9 +3197,9 @@ This function is an internal primitive--use `make-frame' instead. */)
black = build_string ("black");
GCPRO1 (black);
- f->output_data.x->foreground_pixel
+ FRAME_FOREGROUND_PIXEL (f)
= x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
- f->output_data.x->background_pixel
+ FRAME_BACKGROUND_PIXEL (f)
= x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
f->output_data.x->cursor_pixel
= x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
@@ -3448,7 +3466,7 @@ This function is an internal primitive--use `make-frame' instead. */)
}
/* Initialize `default-minibuffer-frame' in case this is the first
- frame on this display device. */
+ frame on this terminal. */
if (FRAME_HAS_MINIBUF_P (f)
&& (!FRAMEP (kb->Vdefault_minibuffer_frame)
|| !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
@@ -3460,6 +3478,8 @@ This function is an internal primitive--use `make-frame' instead. */)
if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
f->param_alist = Fcons (XCAR (tem), f->param_alist);
+ store_frame_param (f, Qwindow_system, Qx);
+
UNGCPRO;
/* Make sure windows on this frame appear in calls to next-window
@@ -3554,10 +3574,10 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
doc: /* Internal function called by `display-color-p', which see. */)
- (display)
- Lisp_Object display;
+ (terminal)
+ Lisp_Object terminal;
{
- struct x_display_info *dpyinfo = check_x_display_info (display);
+ struct x_display_info *dpyinfo = check_x_display_info (terminal);
if (dpyinfo->n_planes <= 2)
return Qnil;
@@ -3579,13 +3599,13 @@ DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
0, 1, 0,
doc: /* Return t if the X display supports shades of gray.
Note that color displays do support shades of gray.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal id, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
+ (terminal)
+ Lisp_Object terminal;
{
- struct x_display_info *dpyinfo = check_x_display_info (display);
+ struct x_display_info *dpyinfo = check_x_display_info (terminal);
if (dpyinfo->n_planes <= 1)
return Qnil;
@@ -3607,56 +3627,56 @@ If omitted or nil, that stands for the selected frame's display. */)
DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
0, 1, 0,
- doc: /* Returns the width in pixels of the X display DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
+ doc: /* Returns the width in pixels of the X display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal id, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
+ (terminal)
+ Lisp_Object terminal;
{
- struct x_display_info *dpyinfo = check_x_display_info (display);
+ struct x_display_info *dpyinfo = check_x_display_info (terminal);
return make_number (dpyinfo->width);
}
DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
Sx_display_pixel_height, 0, 1, 0,
- doc: /* Returns the height in pixels of the X display DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
+ doc: /* Returns the height in pixels of the X display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal id, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
+ (terminal)
+ Lisp_Object terminal;
{
- struct x_display_info *dpyinfo = check_x_display_info (display);
+ struct x_display_info *dpyinfo = check_x_display_info (terminal);
return make_number (dpyinfo->height);
}
DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
0, 1, 0,
- doc: /* Returns the number of bitplanes of the X display DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
+ doc: /* Returns the number of bitplanes of the X display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal id, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
+ (terminal)
+ Lisp_Object terminal;
{
- struct x_display_info *dpyinfo = check_x_display_info (display);
+ struct x_display_info *dpyinfo = check_x_display_info (terminal);
return make_number (dpyinfo->n_planes);
}
DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
0, 1, 0,
- doc: /* Returns the number of color cells of the X display DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
+ doc: /* Returns the number of color cells of the X display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal id, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
+ (terminal)
+ Lisp_Object terminal;
{
- struct x_display_info *dpyinfo = check_x_display_info (display);
+ struct x_display_info *dpyinfo = check_x_display_info (terminal);
int nr_planes = DisplayPlanes (dpyinfo->display,
XScreenNumberOfScreen (dpyinfo->screen));
@@ -3674,29 +3694,29 @@ If omitted or nil, that stands for the selected frame's display. */)
DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
Sx_server_max_request_size,
0, 1, 0,
- doc: /* Returns the maximum request size of the X server of display DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
+ doc: /* Returns the maximum request size of the X server of display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal id, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
+ (terminal)
+ Lisp_Object terminal;
{
- struct x_display_info *dpyinfo = check_x_display_info (display);
+ struct x_display_info *dpyinfo = check_x_display_info (terminal);
return make_number (MAXREQUEST (dpyinfo->display));
}
DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
- doc: /* Returns the "vendor ID" string of the X server of display DISPLAY.
+ doc: /* Returns the "vendor ID" string of the X server of display TERMINAL.
\(Labelling every distributor as a "vendor" embodies the false assumption
that operating systems cannot be developed and distributed noncommercially.)
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal id, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
+ (terminal)
+ Lisp_Object terminal;
{
- struct x_display_info *dpyinfo = check_x_display_info (display);
+ struct x_display_info *dpyinfo = check_x_display_info (terminal);
char *vendor = ServerVendor (dpyinfo->display);
if (! vendor) vendor = "";
@@ -3704,18 +3724,18 @@ If omitted or nil, that stands for the selected frame's display. */)
}
DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
- doc: /* Returns the version numbers of the X server of display DISPLAY.
+ doc: /* Returns the version numbers of the X server of display TERMINAL.
The value is a list of three integers: the major and minor
version numbers of the X Protocol in use, and the distributor-specific release
number. See also the function `x-server-vendor'.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal id, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
+ (terminal)
+ Lisp_Object terminal;
{
- struct x_display_info *dpyinfo = check_x_display_info (display);
+ struct x_display_info *dpyinfo = check_x_display_info (terminal);
Display *dpy = dpyinfo->display;
return Fcons (make_number (ProtocolVersion (dpy)),
@@ -3724,55 +3744,55 @@ If omitted or nil, that stands for the selected frame's display. */)
}
DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
- doc: /* Return the number of screens on the X server of display DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
+ doc: /* Return the number of screens on the X server of display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal id, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
+ (terminal)
+ Lisp_Object terminal;
{
- struct x_display_info *dpyinfo = check_x_display_info (display);
+ struct x_display_info *dpyinfo = check_x_display_info (terminal);
return make_number (ScreenCount (dpyinfo->display));
}
DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
- doc: /* Return the height in millimeters of the X display DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
+ doc: /* Return the height in millimeters of the X display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal id, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
+ (terminal)
+ Lisp_Object terminal;
{
- struct x_display_info *dpyinfo = check_x_display_info (display);
+ struct x_display_info *dpyinfo = check_x_display_info (terminal);
return make_number (HeightMMOfScreen (dpyinfo->screen));
}
DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
- doc: /* Return the width in millimeters of the X display DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
+ doc: /* Return the width in millimeters of the X display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal id, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
+ (terminal)
+ Lisp_Object terminal;
{
- struct x_display_info *dpyinfo = check_x_display_info (display);
+ struct x_display_info *dpyinfo = check_x_display_info (terminal);
return make_number (WidthMMOfScreen (dpyinfo->screen));
}
DEFUN ("x-display-backing-store", Fx_display_backing_store,
Sx_display_backing_store, 0, 1, 0,
- doc: /* Returns an indication of whether X display DISPLAY does backing store.
+ doc: /* Returns an indication of whether X display TERMINAL does backing store.
The value may be `always', `when-mapped', or `not-useful'.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal id, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
+ (terminal)
+ Lisp_Object terminal;
{
- struct x_display_info *dpyinfo = check_x_display_info (display);
+ struct x_display_info *dpyinfo = check_x_display_info (terminal);
Lisp_Object result;
switch (DoesBackingStore (dpyinfo->screen))
@@ -3799,17 +3819,17 @@ If omitted or nil, that stands for the selected frame's display. */)
DEFUN ("x-display-visual-class", Fx_display_visual_class,
Sx_display_visual_class, 0, 1, 0,
- doc: /* Return the visual class of the X display DISPLAY.
+ doc: /* Return the visual class of the X display TERMINAL.
The value is one of the symbols `static-gray', `gray-scale',
`static-color', `pseudo-color', `true-color', or `direct-color'.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should a terminal id, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
+ (terminal)
+ Lisp_Object terminal;
{
- struct x_display_info *dpyinfo = check_x_display_info (display);
+ struct x_display_info *dpyinfo = check_x_display_info (terminal);
Lisp_Object result;
switch (dpyinfo->visual->class)
@@ -3842,14 +3862,14 @@ If omitted or nil, that stands for the selected frame's display. */)
DEFUN ("x-display-save-under", Fx_display_save_under,
Sx_display_save_under, 0, 1, 0,
- doc: /* Returns t if the X display DISPLAY supports the save-under feature.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
+ doc: /* Returns t if the X display TERMINAL supports the save-under feature.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal id, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
+ (terminal)
+ Lisp_Object terminal;
{
- struct x_display_info *dpyinfo = check_x_display_info (display);
+ struct x_display_info *dpyinfo = check_x_display_info (terminal);
if (DoesSaveUnders (dpyinfo->screen) == True)
return Qt;
@@ -4030,8 +4050,10 @@ x_display_info_for_name (name)
CHECK_STRING (name);
- if (! EQ (Vwindow_system, intern ("x")))
- error ("Not using X Windows");
+#if 0
+ if (! EQ (Vinitial_window_system, intern ("x")))
+ error ("Not using X Windows"); /* That doesn't stop us anymore. */
+#endif
for (dpyinfo = x_display_list, names = x_display_name_list;
dpyinfo;
@@ -4078,8 +4100,10 @@ terminate Emacs if we can't open the connection. */)
if (! NILP (xrm_string))
CHECK_STRING (xrm_string);
- if (! EQ (Vwindow_system, intern ("x")))
- error ("Not using X Windows");
+#if 0
+ if (! EQ (Vinitial_window_system, intern ("x")))
+ error ("Not using X Windows"); /* That doesn't stop us anymore. */
+#endif
if (! NILP (xrm_string))
xrm_option = (unsigned char *) SDATA (xrm_string);
@@ -4114,41 +4138,19 @@ An insecure way to solve the problem may be to use `xhost'.\n",
DEFUN ("x-close-connection", Fx_close_connection,
Sx_close_connection, 1, 1, 0,
- doc: /* Close the connection to DISPLAY's X server.
-For DISPLAY, specify either a frame or a display name (a string).
-If DISPLAY is nil, that stands for the selected frame's display. */)
- (display)
- Lisp_Object display;
+ doc: /* Close the connection to TERMINAL's X server.
+For TERMINAL, specify a terminal id, a frame or a display name (a
+string). If TERMINAL is nil, that stands for the selected frame's
+terminal. */)
+ (terminal)
+ Lisp_Object terminal;
{
- struct x_display_info *dpyinfo = check_x_display_info (display);
- int i;
+ struct x_display_info *dpyinfo = check_x_display_info (terminal);
if (dpyinfo->reference_count > 0)
error ("Display still has frames on it");
- BLOCK_INPUT;
- /* Free the fonts in the font table. */
- for (i = 0; i < dpyinfo->n_fonts; i++)
- if (dpyinfo->font_table[i].name)
- {
- XFreeFont (dpyinfo->display, dpyinfo->font_table[i].font);
- }
-
- x_destroy_all_bitmaps (dpyinfo);
- XSetCloseDownMode (dpyinfo->display, DestroyAll);
-
-#ifdef USE_GTK
- xg_display_close (dpyinfo->display);
-#else
-#ifdef USE_X_TOOLKIT
- XtCloseDisplay (dpyinfo->display);
-#else
- XCloseDisplay (dpyinfo->display);
-#endif
-#endif /* ! USE_GTK */
-
- x_delete_display (dpyinfo);
- UNBLOCK_INPUT;
+ x_delete_terminal (dpyinfo->terminal);
return Qnil;
}
@@ -4172,13 +4174,13 @@ If ON is nil, allow buffering of requests.
Turning on synchronization prohibits the Xlib routines from buffering
requests and seriously degrades performance, but makes debugging much
easier.
-The optional second argument DISPLAY specifies which display to act on.
-DISPLAY should be either a frame or a display name (a string).
-If DISPLAY is omitted or nil, that stands for the selected frame's display. */)
- (on, display)
- Lisp_Object display, on;
+The optional second argument TERMINAL specifies which display to act on.
+TERMINAL should be a terminal id, a frame or a display name (a string).
+If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
+ (on, terminal)
+ Lisp_Object terminal, on;
{
- struct x_display_info *dpyinfo = check_x_display_info (display);
+ struct x_display_info *dpyinfo = check_x_display_info (terminal);
XSynchronize (dpyinfo->display, !EQ (on, Qnil));
@@ -4482,10 +4484,6 @@ start_hourglass ()
EMACS_TIME delay;
int secs, usecs = 0;
- /* Don't bother for ttys. */
- if (NILP (Vwindow_system))
- return;
-
cancel_hourglass ();
if (INTEGERP (Vhourglass_delay)
@@ -4697,20 +4695,16 @@ x_create_tip_frame (dpyinfo, parms, text)
int width, height;
int count = SPECPDL_INDEX ();
struct gcpro gcpro1, gcpro2, gcpro3;
- struct kboard *kb;
int face_change_count_before = face_change_count;
Lisp_Object buffer;
struct buffer *old_buffer;
check_x ();
- parms = Fcopy_alist (parms);
+ if (dpyinfo->terminal->deleted)
+ error ("Terminal is being deleted, can't create new frames on it");
-#ifdef MULTI_KBOARD
- kb = dpyinfo->kboard;
-#else
- kb = &the_only_kboard;
-#endif
+ parms = Fcopy_alist (parms);
/* Get the name of the frame to use for resource lookup. */
name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
@@ -4738,6 +4732,9 @@ x_create_tip_frame (dpyinfo, parms, text)
FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
record_unwind_protect (unwind_create_tip_frame, frame);
+ f->terminal = dpyinfo->terminal;
+ f->terminal->reference_count++;
+
/* By setting the output method, we're essentially saying that
the frame is live, as per FRAME_LIVE_P. If we get a signal
from this point on, x_destroy_window might screw up reference
@@ -4759,9 +4756,6 @@ x_create_tip_frame (dpyinfo, parms, text)
image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount;
dpyinfo_refcount = dpyinfo->reference_count;
#endif /* GLYPH_DEBUG */
-#ifdef MULTI_KBOARD
- FRAME_KBOARD (f) = kb;
-#endif
f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
f->output_data.x->explicit_parent = 0;
@@ -4771,11 +4765,21 @@ x_create_tip_frame (dpyinfo, parms, text)
Lisp_Object black;
struct gcpro gcpro1;
+ /* Function x_decode_color can signal an error. Make
+ sure to initialize color slots so that we won't try
+ to free colors we haven't allocated. */
+ FRAME_FOREGROUND_PIXEL (f) = -1;
+ FRAME_BACKGROUND_PIXEL (f) = -1;
+ f->output_data.x->cursor_pixel = -1;
+ f->output_data.x->cursor_foreground_pixel = -1;
+ f->output_data.x->border_pixel = -1;
+ f->output_data.x->mouse_pixel = -1;
+
black = build_string ("black");
GCPRO1 (black);
- f->output_data.x->foreground_pixel
+ FRAME_FOREGROUND_PIXEL (f)
= x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
- f->output_data.x->background_pixel
+ FRAME_BACKGROUND_PIXEL (f)
= x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
f->output_data.x->cursor_pixel
= x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
@@ -4961,6 +4965,8 @@ x_create_tip_frame (dpyinfo, parms, text)
Qnil));
}
+ Fmodify_frame_parameters (frame, Fcons (Fcons (Qwindow_system, Qx), Qnil));
+
f->no_split = 1;
UNGCPRO;
diff --git a/src/xmenu.c b/src/xmenu.c
index f68f3a41e3f..bf9a9101ef0 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -41,10 +41,10 @@ Boston, MA 02110-1301, USA. */
#include <stdio.h>
#include "lisp.h"
-#include "termhooks.h"
#include "keyboard.h"
#include "keymap.h"
#include "frame.h"
+#include "termhooks.h"
#include "window.h"
#include "blockinput.h"
#include "buffer.h"
@@ -745,6 +745,9 @@ mouse_position_for_popup (f, x, y)
Window root, dummy_window;
int dummy;
+ if (! FRAME_X_P (f))
+ abort ();
+
BLOCK_INPUT;
XQueryPointer (FRAME_X_DISPLAY (f),
@@ -940,6 +943,9 @@ no quit occurs and `x-popup-menu' returns nil. */)
xpos += XINT (x);
ypos += XINT (y);
+ if (! FRAME_X_P (f))
+ error ("Can not put X menu on non-X terminal");
+
XSETFRAME (Vmenu_updating_frame, f);
}
else
@@ -1128,6 +1134,9 @@ for instance using the window manager, then this produces a quit and
but I don't want to make one now. */
CHECK_WINDOW (window);
+ if (! FRAME_X_P (f))
+ error ("Can not put X dialog on non-X terminal");
+
#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
/* Display a menu with these alternatives
in the middle of frame F. */
@@ -1309,7 +1318,7 @@ popup_get_selection (initial_event, dpyinfo, id, do_timers)
}
}
-DEFUN ("menu-bar-open", Fmenu_bar_open, Smenu_bar_open, 0, 1, "i",
+DEFUN ("x-menu-bar-open-internal", Fx_menu_bar_open_internal, Sx_menu_bar_open_internal, 0, 1, "i",
doc: /* Start key navigation of the menu bar in FRAME.
This initially opens the first menu bar item and you can then navigate with the
arrow keys, select a menu entry with the return key or cancel with the
@@ -1388,7 +1397,7 @@ If FRAME is nil or not given, use the selected frame. */)
#ifdef USE_GTK
-DEFUN ("menu-bar-open", Fmenu_bar_open, Smenu_bar_open, 0, 1, "i",
+DEFUN ("x-menu-bar-open-internal", Fx_menu_bar_open_internal, Sx_menu_bar_open_internal, 0, 1, "i",
doc: /* Start key navigation of the menu bar in FRAME.
This initially opens the first menu bar item and you can then navigate with the
arrow keys, select a menu entry with the return key or cancel with the
@@ -1464,6 +1473,9 @@ void
x_activate_menubar (f)
FRAME_PTR f;
{
+ if (! FRAME_X_P (f))
+ abort ();
+
if (!f->output_data.x->saved_menu_event->type)
return;
@@ -2098,9 +2110,14 @@ update_frame_menubar (f)
#ifdef USE_GTK
return xg_update_frame_menubar (f);
#else
- struct x_output *x = f->output_data.x;
+ struct x_output *x;
int columns, rows;
+ if (! FRAME_X_P (f))
+ abort ();
+
+ x = f->output_data.x;
+
if (!x->menubar_widget || XtIsManaged (x->menubar_widget))
return 0;
@@ -2146,7 +2163,7 @@ set_frame_menubar (f, first_time, deep_p)
int first_time;
int deep_p;
{
- xt_or_gtk_widget menubar_widget = f->output_data.x->menubar_widget;
+ xt_or_gtk_widget menubar_widget;
#ifdef USE_X_TOOLKIT
LWLIB_ID id;
#endif
@@ -2156,6 +2173,10 @@ set_frame_menubar (f, first_time, deep_p)
int *submenu_start, *submenu_end;
int *submenu_top_level_items, *submenu_n_panes;
+ if (! FRAME_X_P (f))
+ abort ();
+
+ menubar_widget = f->output_data.x->menubar_widget;
XSETFRAME (Vmenu_updating_frame, f);
@@ -2508,6 +2529,9 @@ free_frame_menubar (f)
{
Widget menubar_widget;
+ if (! FRAME_X_P (f))
+ abort ();
+
menubar_widget = f->output_data.x->menubar_widget;
f->output_data.x->menubar_height = 0;
@@ -2660,6 +2684,9 @@ create_and_show_popup_menu (f, first_wv, x, y, for_click)
struct next_popup_x_y popup_x_y;
int specpdl_count = SPECPDL_INDEX ();
+ if (! FRAME_X_P (f))
+ abort ();
+
xg_crazy_callback_abort = 1;
menu = xg_create_widget ("popup", first_wv->name, f, first_wv,
G_CALLBACK (popup_selection_callback),
@@ -2768,6 +2795,9 @@ create_and_show_popup_menu (f, first_wv, x, y, for_click)
LWLIB_ID menu_id;
Widget menu;
+ if (! FRAME_X_P (f))
+ abort ();
+
menu_id = widget_id_tick++;
menu = lw_create_widget ("popup", first_wv->name, menu_id, first_wv,
f->output_data.x->widget, 1, 0,
@@ -2844,6 +2874,9 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
int first_pane;
+ if (! FRAME_X_P (f))
+ abort ();
+
*error = NULL;
if (menu_items_used <= MENU_ITEMS_PANE_LENGTH)
@@ -3126,6 +3159,9 @@ create_and_show_dialog (f, first_wv)
{
GtkWidget *menu;
+ if (! FRAME_X_P (f))
+ abort ();
+
menu = xg_create_widget ("dialog", first_wv->name, f, first_wv,
G_CALLBACK (dialog_selection_callback),
G_CALLBACK (popup_deactivate_callback),
@@ -3175,6 +3211,9 @@ create_and_show_dialog (f, first_wv)
{
LWLIB_ID dialog_id;
+ if (!FRAME_X_P (f))
+ abort();
+
dialog_id = widget_id_tick++;
lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv,
f->output_data.x->widget, 1, 0,
@@ -3227,6 +3266,9 @@ xdialog_show (f, keymaps, title, header, error_name)
/* 1 means we've seen the boundary between left-hand elts and right-hand. */
int boundary_seen = 0;
+ if (! FRAME_X_P (f))
+ abort ();
+
*error_name = NULL;
if (menu_items_n_panes > 1)
@@ -3502,6 +3544,9 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
unsigned int dummy_uint;
int specpdl_count = SPECPDL_INDEX ();
+ if (! FRAME_X_P (f))
+ abort ();
+
*error = 0;
if (menu_items_n_panes == 0)
return Qnil;
@@ -3806,8 +3851,9 @@ syms_of_xmenu ()
defsubr (&Smenu_or_popup_active_p);
#if defined (USE_GTK) || defined (USE_X_TOOLKIT)
- defsubr (&Smenu_bar_open);
- Ffset (intern ("accelerate-menu"), intern (Smenu_bar_open.symbol_name));
+ defsubr (&Sx_menu_bar_open_internal);
+ Ffset (intern ("accelerate-menu"),
+ intern (Sx_menu_bar_open_internal.symbol_name));
#endif
#ifdef HAVE_MENUS
diff --git a/src/xselect.c b/src/xselect.c
index 33468f0d63a..b2d47bd1175 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -398,12 +398,19 @@ x_own_selection (selection_name, selection_value)
Lisp_Object selection_name, selection_value;
{
struct frame *sf = SELECTED_FRAME ();
- Window selecting_window = FRAME_X_WINDOW (sf);
- Display *display = FRAME_X_DISPLAY (sf);
+ Window selecting_window;
+ Display *display;
Time time = last_event_timestamp;
Atom selection_atom;
- struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (sf);
+ struct x_display_info *dpyinfo;
+
+ if (! FRAME_X_P (sf))
+ return;
+ selecting_window = FRAME_X_WINDOW (sf);
+ display = FRAME_X_DISPLAY (sf);
+ dpyinfo = FRAME_X_DISPLAY_INFO (sf);
+
CHECK_SYMBOL (selection_name);
selection_atom = symbol_to_x_atom (dpyinfo, display, selection_name);
@@ -671,7 +678,8 @@ some_frame_on_display (dpyinfo)
FOR_EACH_FRAME (list, frame)
{
- if (FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
+ if (FRAME_X_P (XFRAME (frame))
+ && FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
return frame;
}
@@ -1014,6 +1022,7 @@ x_handle_selection_clear (event)
TRACE0 ("x_handle_selection_clear");
+#ifdef MULTI_KBOARD
/* If the new selection owner is also Emacs,
don't clear the new selection. */
BLOCK_INPUT;
@@ -1021,7 +1030,7 @@ x_handle_selection_clear (event)
to see if this Emacs job now owns the selection
through that display. */
for (t_dpyinfo = x_display_list; t_dpyinfo; t_dpyinfo = t_dpyinfo->next)
- if (t_dpyinfo->kboard == dpyinfo->kboard)
+ if (t_dpyinfo->terminal->kboard == dpyinfo->terminal->kboard)
{
Window owner_window
= XGetSelectionOwner (t_dpyinfo->display, selection);
@@ -1032,7 +1041,8 @@ x_handle_selection_clear (event)
}
}
UNBLOCK_INPUT;
-
+#endif
+
selection_symbol = x_atom_to_symbol (display, selection);
local_selection_data = assq_no_quit (selection_symbol, Vselection_alist);
@@ -1380,17 +1390,26 @@ x_get_foreign_selection (selection_symbol, target_type, time_stamp)
Lisp_Object selection_symbol, target_type, time_stamp;
{
struct frame *sf = SELECTED_FRAME ();
- Window requestor_window = FRAME_X_WINDOW (sf);
- Display *display = FRAME_X_DISPLAY (sf);
- struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (sf);
+ Window requestor_window;
+ Display *display;
+ struct x_display_info *dpyinfo;
Time requestor_time = last_event_timestamp;
- Atom target_property = dpyinfo->Xatom_EMACS_TMP;
- Atom selection_atom = symbol_to_x_atom (dpyinfo, display, selection_symbol);
+ Atom target_property;
+ Atom selection_atom;
Atom type_atom;
int secs, usecs;
int count = SPECPDL_INDEX ();
Lisp_Object frame;
+ if (! FRAME_X_P (sf))
+ return Qnil;
+
+ requestor_window = FRAME_X_WINDOW (sf);
+ display = FRAME_X_DISPLAY (sf);
+ dpyinfo = FRAME_X_DISPLAY_INFO (sf);
+ target_property = dpyinfo->Xatom_EMACS_TMP;
+ selection_atom = symbol_to_x_atom (dpyinfo, display, selection_symbol);
+
if (CONSP (target_type))
type_atom = symbol_to_x_atom (dpyinfo, display, XCAR (target_type));
else
@@ -2206,6 +2225,9 @@ Disowning it means there is no such selection. */)
struct frame *sf = SELECTED_FRAME ();
check_x ();
+ if (! FRAME_X_P (sf))
+ return Qnil;
+
display = FRAME_X_DISPLAY (sf);
dpyinfo = FRAME_X_DISPLAY_INFO (sf);
CHECK_SYMBOL (selection);
@@ -2367,6 +2389,10 @@ DEFUN ("x-get-cut-buffer-internal", Fx_get_cut_buffer_internal,
struct frame *sf = SELECTED_FRAME ();
check_x ();
+
+ if (! FRAME_X_P (sf))
+ return Qnil;
+
display = FRAME_X_DISPLAY (sf);
dpyinfo = FRAME_X_DISPLAY_INFO (sf);
window = RootWindow (display, 0); /* Cut buffers are on screen 0 */
@@ -2407,6 +2433,10 @@ DEFUN ("x-store-cut-buffer-internal", Fx_store_cut_buffer_internal,
struct frame *sf = SELECTED_FRAME ();
check_x ();
+
+ if (! FRAME_X_P (sf))
+ return Qnil;
+
display = FRAME_X_DISPLAY (sf);
window = RootWindow (display, 0); /* Cut buffers are on screen 0 */
@@ -2463,8 +2493,12 @@ Positive means shift the values forward, negative means backward. */)
Atom props[8];
Display *display;
struct frame *sf = SELECTED_FRAME ();
-
+
check_x ();
+
+ if (! FRAME_X_P (sf))
+ return Qnil;
+
display = FRAME_X_DISPLAY (sf);
window = RootWindow (display, 0); /* Cut buffers are on screen 0 */
CHECK_NUMBER (n);
diff --git a/src/xsmfns.c b/src/xsmfns.c
index 1211c55eb03..77abf3b5072 100644
--- a/src/xsmfns.c
+++ b/src/xsmfns.c
@@ -48,6 +48,7 @@ Boston, MA 02110-1301, USA. */
#include "lisp.h"
#include "systime.h"
#include "sysselect.h"
+#include "frame.h"
#include "termhooks.h"
#include "termopts.h"
#include "xterm.h"
@@ -510,6 +511,14 @@ x_session_initialize (dpyinfo)
}
}
+/* Ensure that the session manager is not contacted again. */
+
+void
+x_session_close ()
+{
+ ice_fd = -1;
+}
+
DEFUN ("handle-save-session", Fhandle_save_session,
Shandle_save_session, 1, 1, "e",
diff --git a/src/xterm.c b/src/xterm.c
index fdff9b4f02e..0e56b04c1b0 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -54,7 +54,6 @@ Boston, MA 02110-1301, USA. */
#include <sys/ioctl.h>
#endif /* ! defined (BSD_SYSTEM) */
-#include "systty.h"
#include "systime.h"
#ifndef INCLUDED_FCNTL
@@ -322,6 +321,10 @@ static Lisp_Object Qalt, Qhyper, Qmeta, Qsuper, Qmodifier_value;
static Lisp_Object Qvendor_specific_keysyms;
static Lisp_Object Qlatin_1;
+/* Used in x_flush. */
+
+extern Lisp_Object Vinhibit_redisplay;
+
extern XrmDatabase x_load_resources P_ ((Display *, char *, char *, char *));
extern int x_bitmap_mask P_ ((FRAME_PTR, int));
@@ -331,13 +334,15 @@ static const XColor *x_color_cells P_ ((Display *, int *));
static void x_update_window_end P_ ((struct window *, int, int));
static int x_io_error_quitter P_ ((Display *));
+static struct terminal *x_create_terminal P_ ((struct x_display_info *));
+void x_delete_terminal P_ ((struct terminal *));
static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
static int x_compute_min_glyph_bounds P_ ((struct frame *));
static void x_update_end P_ ((struct frame *));
static void XTframe_up_to_date P_ ((struct frame *));
-static void XTset_terminal_modes P_ ((void));
-static void XTreset_terminal_modes P_ ((void));
-static void x_clear_frame P_ ((void));
+static void XTset_terminal_modes P_ ((struct terminal *));
+static void XTreset_terminal_modes P_ ((struct terminal *));
+static void x_clear_frame P_ ((struct frame *));
static void frame_highlight P_ ((struct frame *));
static void frame_unhighlight P_ ((struct frame *));
static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
@@ -377,12 +382,18 @@ static void
x_flush (f)
struct frame *f;
{
+ /* Don't call XFlush when it is not safe to redisplay; the X
+ connection may be broken. */
+ if (!NILP (Vinhibit_redisplay))
+ return;
+
BLOCK_INPUT;
if (f == NULL)
{
Lisp_Object rest, frame;
FOR_EACH_FRAME (rest, frame)
- x_flush (XFRAME (frame));
+ if (FRAME_X_P (XFRAME (frame)))
+ x_flush (XFRAME (frame));
}
else if (FRAME_X_P (f))
XFlush (FRAME_X_DISPLAY (f));
@@ -843,7 +854,7 @@ x_draw_fringe_bitmap (w, row, p)
rarely happens). */
static void
-XTset_terminal_modes ()
+XTset_terminal_modes (struct terminal *terminal)
{
}
@@ -851,7 +862,7 @@ XTset_terminal_modes ()
the X-windows go away, and suspending requires no action. */
static void
-XTreset_terminal_modes ()
+XTreset_terminal_modes (struct terminal *terminal)
{
}
@@ -1464,7 +1475,8 @@ x_frame_of_widget (widget)
for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail))
if (GC_FRAMEP (XCAR (tail))
&& (f = XFRAME (XCAR (tail)),
- (f->output_data.nothing != 1
+ (FRAME_X_P (f)
+ && f->output_data.nothing != 1
&& FRAME_X_DISPLAY_INFO (f) == dpyinfo))
&& f->output_data.x->widget == widget)
return f;
@@ -2843,7 +2855,8 @@ x_shift_glyphs_for_insert (f, x, y, width, height, shift_by)
for X frames. */
static void
-x_delete_glyphs (n)
+x_delete_glyphs (f, n)
+ struct frame *f;
register int n;
{
abort ();
@@ -2866,19 +2879,11 @@ x_clear_area (dpy, window, x, y, width, height, exposures)
}
-/* Clear entire frame. If updating_frame is non-null, clear that
- frame. Otherwise clear the selected frame. */
+/* Clear an entire frame. */
static void
-x_clear_frame ()
+x_clear_frame (struct frame *f)
{
- struct frame *f;
-
- if (updating_frame)
- f = updating_frame;
- else
- f = SELECTED_FRAME ();
-
/* Clearing the frame will erase any cursor, so mark them all as no
longer visible. */
mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
@@ -2957,8 +2962,8 @@ XTflash (f)
XGCValues values;
values.function = GXxor;
- values.foreground = (f->output_data.x->foreground_pixel
- ^ f->output_data.x->background_pixel);
+ values.foreground = (FRAME_FOREGROUND_PIXEL (f)
+ ^ FRAME_BACKGROUND_PIXEL (f));
gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
GCFunction | GCForeground, &values);
@@ -3124,7 +3129,8 @@ XTset_terminal_window (n)
lines or deleting -N lines at vertical position VPOS. */
static void
-x_ins_del_lines (vpos, n)
+x_ins_del_lines (f, vpos, n)
+ struct frame *f;
int vpos, n;
{
abort ();
@@ -3761,7 +3767,8 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
/* Clear the mouse-moved flag for every frame on this display. */
FOR_EACH_FRAME (tail, frame)
- if (FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp))
+ if (FRAME_X_P (XFRAME (frame))
+ && FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp))
XFRAME (frame)->mouse_moved = 0;
last_mouse_scroll_bar = Qnil;
@@ -3950,6 +3957,9 @@ x_window_to_scroll_bar (display, window_id)
if (! GC_FRAMEP (frame))
abort ();
+ if (! FRAME_X_P (XFRAME (frame)))
+ continue;
+
/* Scan this frame's scroll bar list for a scroll bar with the
right window ID. */
condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame));
@@ -3984,11 +3994,14 @@ x_window_to_menu_bar (window)
XGCTYPE (tail) == Lisp_Cons;
tail = XCDR (tail))
{
- Lisp_Object frame = XCAR (tail);
- Widget menu_bar = XFRAME (frame)->output_data.x->menubar_widget;
+ if (FRAME_X_P (XFRAME (XCAR (tail))))
+ {
+ Lisp_Object frame = XCAR (tail);
+ Widget menu_bar = XFRAME (frame)->output_data.x->menubar_widget;
- if (menu_bar && xlwmenu_window_p (menu_bar, window))
- return menu_bar;
+ if (menu_bar && xlwmenu_window_p (menu_bar, window))
+ return menu_bar;
+ }
}
return NULL;
@@ -4796,7 +4809,7 @@ x_scroll_bar_create (w, top, left, width, height)
a.background_pixel = f->output_data.x->scroll_bar_background_pixel;
if (a.background_pixel == -1)
- a.background_pixel = f->output_data.x->background_pixel;
+ a.background_pixel = FRAME_BACKGROUND_PIXEL (f);
a.event_mask = (ButtonPressMask | ButtonReleaseMask
| ButtonMotionMask | PointerMotionHintMask
@@ -4973,7 +4986,7 @@ x_scroll_bar_set_handle (bar, start, end, rebuild)
/* Restore the foreground color of the GC if we changed it above. */
if (f->output_data.x->scroll_bar_foreground_pixel != -1)
XSetForeground (FRAME_X_DISPLAY (f), gc,
- f->output_data.x->foreground_pixel);
+ FRAME_FOREGROUND_PIXEL (f));
/* Draw the empty space below the handle. Note that we can't
clear zero-height areas; that means "clear to end of window." */
@@ -5375,7 +5388,7 @@ x_scroll_bar_expose (bar, event)
/* Restore the foreground color of the GC if we changed it above. */
if (f->output_data.x->scroll_bar_foreground_pixel != -1)
XSetForeground (FRAME_X_DISPLAY (f), gc,
- f->output_data.x->foreground_pixel);
+ FRAME_FOREGROUND_PIXEL (f));
UNBLOCK_INPUT;
@@ -5775,7 +5788,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
int count = 0;
int do_help = 0;
int nbytes = 0;
- struct frame *f;
+ struct frame *f = NULL;
struct coding_system coding;
XEvent event = *eventp;
@@ -6351,19 +6364,19 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
bzero (&compose_status, sizeof (compose_status));
orig_keysym = keysym;
- /* Common for all keysym input events. */
- XSETFRAME (inev.ie.frame_or_window, f);
- inev.ie.modifiers
- = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), modifiers);
- inev.ie.timestamp = event.xkey.time;
-
- /* First deal with keysyms which have defined
- translations to characters. */
- if (keysym >= 32 && keysym < 128)
- /* Avoid explicitly decoding each ASCII character. */
- {
- inev.ie.kind = ASCII_KEYSTROKE_EVENT;
- inev.ie.code = keysym;
+ /* Common for all keysym input events. */
+ XSETFRAME (inev.ie.frame_or_window, f);
+ inev.ie.modifiers
+ = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), modifiers);
+ inev.ie.timestamp = event.xkey.time;
+
+ /* First deal with keysyms which have defined
+ translations to characters. */
+ if (keysym >= 32 && keysym < 128)
+ /* Avoid explicitly decoding each ASCII character. */
+ {
+ inev.ie.kind = ASCII_KEYSTROKE_EVENT;
+ inev.ie.code = keysym;
goto done_keysym;
}
@@ -6408,18 +6421,18 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
/* Now non-ASCII. */
if (HASH_TABLE_P (Vx_keysym_table)
&& (NATNUMP (c = Fgethash (make_number (keysym),
- Vx_keysym_table,
- Qnil))))
- {
- inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c))
- ? ASCII_KEYSTROKE_EVENT
- : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
- inev.ie.code = XFASTINT (c);
- goto done_keysym;
- }
-
- /* Random non-modifier sorts of keysyms. */
- if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
+ Vx_keysym_table,
+ Qnil))))
+ {
+ inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c))
+ ? ASCII_KEYSTROKE_EVENT
+ : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
+ inev.ie.code = XFASTINT (c);
+ goto done_keysym;
+ }
+
+ /* Random non-modifier sorts of keysyms. */
+ if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
|| keysym == XK_Delete
#ifdef XK_ISO_Left_Tab
|| (keysym >= XK_ISO_Left_Tab
@@ -7063,8 +7076,8 @@ x_dispatch_event (event, display)
EXPECTED is nonzero if the caller knows input is available. */
static int
-XTread_socket (sd, expected, hold_quit)
- register int sd;
+XTread_socket (terminal, expected, hold_quit)
+ struct terminal *terminal;
int expected;
struct input_event *hold_quit;
{
@@ -7087,6 +7100,31 @@ XTread_socket (sd, expected, hold_quit)
++handling_signal;
+#ifdef HAVE_X_SM
+ /* Only check session manager input for the primary display. */
+ if (terminal->id == 1 && x_session_have_connection ())
+ {
+ struct input_event inev;
+ BLOCK_INPUT;
+ /* We don't need to EVENT_INIT (inev) here, as
+ x_session_check_input copies an entire input_event. */
+ if (x_session_check_input (&inev))
+ {
+ kbd_buffer_store_event_hold (&inev, hold_quit);
+ count++;
+ }
+ UNBLOCK_INPUT;
+ }
+#endif
+
+ /* For debugging, this gives a way to fake an I/O error. */
+ if (terminal->display_info.x == XTread_socket_fake_io_error)
+ {
+ XTread_socket_fake_io_error = 0;
+ x_io_error_quitter (dpyinfo->display);
+ }
+
+#if 0 /* This loop is a noop now. */
/* Find the display we are supposed to read input for.
It's the one communicating on descriptor SD. */
for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
@@ -7117,52 +7155,31 @@ XTread_socket (sd, expected, hold_quit)
#endif /* HAVE_SELECT */
#endif /* SIGIO */
#endif
-
- /* For debugging, this gives a way to fake an I/O error. */
- if (dpyinfo == XTread_socket_fake_io_error)
- {
- XTread_socket_fake_io_error = 0;
- x_io_error_quitter (dpyinfo->display);
- }
-
-#ifdef HAVE_X_SM
- {
- struct input_event inev;
- BLOCK_INPUT;
- /* We don't need to EVENT_INIT (inev) here, as
- x_session_check_input copies an entire input_event. */
- if (x_session_check_input (&inev))
- {
- kbd_buffer_store_event_hold (&inev, hold_quit);
- count++;
- }
- UNBLOCK_INPUT;
- }
+ }
#endif
#ifndef USE_GTK
- while (XPending (dpyinfo->display))
- {
- int finish;
+ while (XPending (terminal->display_info.x->display))
+ {
+ int finish;
- XNextEvent (dpyinfo->display, &event);
+ XNextEvent (terminal->display_info.x->display, &event);
#ifdef HAVE_X_I18N
- /* Filter events for the current X input method. */
- if (x_filter_event (dpyinfo, &event))
- break;
+ /* Filter events for the current X input method. */
+ if (x_filter_event (terminal->display_info.x, &event))
+ break;
#endif
- event_found = 1;
+ event_found = 1;
- count += handle_one_xevent (dpyinfo, &event, &finish, hold_quit);
+ count += handle_one_xevent (terminal->display_info.x,
+ &event, &finish, hold_quit);
- if (finish == X_EVENT_GOTO_OUT)
- goto out;
- }
-#endif /* not USE_GTK */
+ if (finish == X_EVENT_GOTO_OUT)
+ goto out;
}
-#ifdef USE_GTK
+#else /* USE_GTK */
/* For GTK we must use the GTK event loop. But XEvents gets passed
to our filter function above, and then to the big event switch.
@@ -7473,8 +7490,7 @@ x_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, activ
}
#ifndef XFlush
- if (updating_frame != f)
- XFlush (FRAME_X_DISPLAY (f));
+ XFlush (FRAME_X_DISPLAY (f));
#endif
}
@@ -7712,6 +7728,8 @@ x_clear_errors (dpy)
x_error_message->string[0] = 0;
}
+#if 0 /* See comment in unwind_to_catch why calling this is a bad
+ * idea. --lorentey */
/* Close off all unclosed x_catch_errors calls. */
void
@@ -7720,6 +7738,7 @@ x_fully_uncatch_errors ()
while (x_error_message)
x_uncatch_errors ();
}
+#endif
/* Nonzero if x_catch_errors has been done and not yet canceled. */
@@ -7785,6 +7804,7 @@ x_connection_closed (dpy, error_message)
{
struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
Lisp_Object frame, tail;
+ int index = SPECPDL_INDEX ();
error_msg = (char *) alloca (strlen (error_message) + 1);
strcpy (error_msg, error_message);
@@ -7796,6 +7816,44 @@ x_connection_closed (dpy, error_message)
the original message here. */
x_catch_errors (dpy);
+ /* Inhibit redisplay while frames are being deleted. */
+ specbind (Qinhibit_redisplay, Qt);
+
+ if (dpyinfo)
+ {
+ /* Protect display from being closed when we delete the last
+ frame on it. */
+ dpyinfo->reference_count++;
+ dpyinfo->terminal->reference_count++;
+ }
+
+ /* First delete frames whose mini-buffers are on frames
+ that are on the dead display. */
+ FOR_EACH_FRAME (tail, frame)
+ {
+ Lisp_Object minibuf_frame;
+ minibuf_frame
+ = WINDOW_FRAME (XWINDOW (FRAME_MINIBUF_WINDOW (XFRAME (frame))));
+ if (FRAME_X_P (XFRAME (frame))
+ && FRAME_X_P (XFRAME (minibuf_frame))
+ && ! EQ (frame, minibuf_frame)
+ && FRAME_X_DISPLAY_INFO (XFRAME (minibuf_frame)) == dpyinfo)
+ Fdelete_frame (frame, Qt);
+ }
+
+ /* Now delete all remaining frames on the dead display.
+ We are now sure none of these is used as the mini-buffer
+ for another frame that we need to delete. */
+ FOR_EACH_FRAME (tail, frame)
+ if (FRAME_X_P (XFRAME (frame))
+ && FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
+ {
+ /* Set this to t so that Fdelete_frame won't get confused
+ trying to find a replacement. */
+ FRAME_KBOARD (XFRAME (frame))->Vdefault_minibuffer_frame = Qt;
+ Fdelete_frame (frame, Qt);
+ }
+
/* We have to close the display to inform Xt that it doesn't
exist anymore. If we don't, Xt will continue to wait for
events from the display. As a consequence, a sequence of
@@ -7828,43 +7886,23 @@ x_connection_closed (dpy, error_message)
xg_display_close (dpyinfo->display);
#endif
- /* Indicate that this display is dead. */
if (dpyinfo)
- dpyinfo->display = 0;
-
- /* First delete frames whose mini-buffers are on frames
- that are on the dead display. */
- FOR_EACH_FRAME (tail, frame)
{
- Lisp_Object minibuf_frame;
- minibuf_frame
- = WINDOW_FRAME (XWINDOW (FRAME_MINIBUF_WINDOW (XFRAME (frame))));
- if (FRAME_X_P (XFRAME (frame))
- && FRAME_X_P (XFRAME (minibuf_frame))
- && ! EQ (frame, minibuf_frame)
- && FRAME_X_DISPLAY_INFO (XFRAME (minibuf_frame)) == dpyinfo)
- Fdelete_frame (frame, Qt);
- }
+ /* Indicate that this display is dead. */
+ dpyinfo->display = 0;
- /* Now delete all remaining frames on the dead display.
- We are now sure none of these is used as the mini-buffer
- for another frame that we need to delete. */
- FOR_EACH_FRAME (tail, frame)
- if (FRAME_X_P (XFRAME (frame))
- && FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
- {
- /* Set this to t so that Fdelete_frame won't get confused
- trying to find a replacement. */
- FRAME_KBOARD (XFRAME (frame))->Vdefault_minibuffer_frame = Qt;
- Fdelete_frame (frame, Qt);
- }
+ dpyinfo->reference_count--;
+ dpyinfo->terminal->reference_count--;
+ if (dpyinfo->reference_count != 0)
+ /* We have just closed all frames on this display. */
+ abort ();
- if (dpyinfo)
- x_delete_display (dpyinfo);
+ x_delete_display (dpyinfo);
+ }
x_uncatch_errors ();
- if (x_display_list == 0)
+ if (terminal_list == 0)
{
fprintf (stderr, "%s\n", error_msg);
shut_down_emacs (0, 0, Qnil);
@@ -7878,6 +7916,7 @@ x_connection_closed (dpy, error_message)
sigunblock (sigmask (SIGALRM));
TOTALLY_UNBLOCK_INPUT;
+ unbind_to (index, Qnil);
clear_waiting_for_input ();
error ("%s", error_msg);
}
@@ -8088,7 +8127,7 @@ xim_destroy_callback (xim, client_data, call_data)
FOR_EACH_FRAME (tail, frame)
{
struct frame *f = XFRAME (frame);
- if (FRAME_X_DISPLAY_INFO (f) == dpyinfo)
+ if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo)
{
FRAME_XIC (f) = NULL;
xic_free_xfontset (f);
@@ -8187,7 +8226,8 @@ xim_instantiate_callback (display, client_data, call_data)
{
struct frame *f = XFRAME (frame);
- if (FRAME_X_DISPLAY_INFO (f) == xim_inst->dpyinfo)
+ if (FRAME_X_P (f)
+ && FRAME_X_DISPLAY_INFO (f) == xim_inst->dpyinfo)
if (FRAME_XIC (f) == NULL)
{
create_frame_xic (f);
@@ -9402,8 +9442,8 @@ x_free_frame_resources (f)
XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
#endif /* !USE_X_TOOLKIT */
- unload_color (f, f->output_data.x->foreground_pixel);
- unload_color (f, f->output_data.x->background_pixel);
+ unload_color (f, FRAME_FOREGROUND_PIXEL (f));
+ unload_color (f, FRAME_BACKGROUND_PIXEL (f));
unload_color (f, f->output_data.x->cursor_pixel);
unload_color (f, f->output_data.x->cursor_foreground_pixel);
unload_color (f, f->output_data.x->border_pixel);
@@ -10569,6 +10609,7 @@ x_term_init (display_name, xrm_option, resource_name)
{
int connection;
Display *dpy;
+ struct terminal *terminal;
struct x_display_info *dpyinfo;
XrmDatabase xrdb;
@@ -10588,14 +10629,21 @@ x_term_init (display_name, xrm_option, resource_name)
char **argv2 = argv;
GdkAtom atom;
+#ifndef HAVE_GTK_MULTIDISPLAY
+ if (!EQ (Vinitial_window_system, intern ("x")))
+ error ("Sorry, you cannot connect to X servers with the GTK toolkit");
+#endif
+
if (x_initialized++ > 1)
{
+#ifdef HAVE_GTK_MULTIDISPLAY
/* Opening another display. If xg_display_open returns less
than zero, we are probably on GTK 2.0, which can only handle
one display. GTK 2.2 or later can handle more than one. */
if (xg_display_open (SDATA (display_name), &dpy) < 0)
+#endif
error ("Sorry, this version of GTK can only handle one display");
- }
+ }
else
{
for (argc = 0; argc < NUM_ARGV; ++argc)
@@ -10699,6 +10747,8 @@ x_term_init (display_name, xrm_option, resource_name)
dpyinfo = (struct x_display_info *) xmalloc (sizeof (struct x_display_info));
bzero (dpyinfo, sizeof *dpyinfo);
+ terminal = x_create_terminal (dpyinfo);
+
#ifdef MULTI_KBOARD
{
struct x_display_info *share;
@@ -10710,30 +10760,30 @@ x_term_init (display_name, xrm_option, resource_name)
SDATA (display_name)))
break;
if (share)
- dpyinfo->kboard = share->kboard;
+ terminal->kboard = share->terminal->kboard;
else
{
- dpyinfo->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
- init_kboard (dpyinfo->kboard);
+ terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
+ init_kboard (terminal->kboard);
if (!EQ (XSYMBOL (Qvendor_specific_keysyms)->function, Qunbound))
{
char *vendor = ServerVendor (dpy);
UNBLOCK_INPUT;
- dpyinfo->kboard->Vsystem_key_alist
+ terminal->kboard->Vsystem_key_alist
= call1 (Qvendor_specific_keysyms,
vendor ? build_string (vendor) : empty_unibyte_string);
BLOCK_INPUT;
}
- dpyinfo->kboard->next_kboard = all_kboards;
- all_kboards = dpyinfo->kboard;
+ terminal->kboard->next_kboard = all_kboards;
+ all_kboards = terminal->kboard;
/* Don't let the initial kboard remain current longer than necessary.
That would cause problems if a file loaded on startup tries to
prompt in the mini-buffer. */
if (current_kboard == initial_kboard)
- current_kboard = dpyinfo->kboard;
+ current_kboard = terminal->kboard;
}
- dpyinfo->kboard->reference_count++;
+ terminal->kboard->reference_count++;
}
#endif
@@ -10748,6 +10798,11 @@ x_term_init (display_name, xrm_option, resource_name)
dpyinfo->display = dpy;
+ /* Set the name of the terminal. */
+ terminal->name = (char *) xmalloc (SBYTES (display_name) + 1);
+ strncpy (terminal->name, SDATA (display_name), SBYTES (display_name));
+ terminal->name[SBYTES (display_name)] = 0;
+
#if 0
XSetAfterFunction (x_current_display, x_trace_wire);
#endif /* ! 0 */
@@ -11043,8 +11098,10 @@ x_term_init (display_name, xrm_option, resource_name)
}
#ifdef HAVE_X_SM
- /* Only do this for the first display. */
- if (!x_session_initialized++)
+ /* Only do this for the very first display in the Emacs session.
+ Ignore X session management when Emacs was first started on a
+ tty. */
+ if (terminal->id == 1)
x_session_initialize (dpyinfo);
#endif
@@ -11053,7 +11110,7 @@ x_term_init (display_name, xrm_option, resource_name)
return dpyinfo;
}
-/* Get rid of display DPYINFO, assuming all frames are already gone,
+/* Get rid of display DPYINFO, deleting all frames on it,
and without sending any more commands to the X server. */
void
@@ -11061,6 +11118,20 @@ x_delete_display (dpyinfo)
struct x_display_info *dpyinfo;
{
int i;
+ struct terminal *t;
+
+ /* Close all frames and delete the generic struct terminal for this
+ X display. */
+ for (t = terminal_list; t; t = t->next_terminal)
+ if (t->type == output_x_window && t->display_info.x == dpyinfo)
+ {
+ /* Close X session management when we close its display. */
+ if (t->id == 1 && x_session_have_connection ())
+ x_session_close();
+
+ delete_terminal (t);
+ break;
+ }
delete_keyboard_wait_descriptor (dpyinfo->connection);
@@ -11104,10 +11175,6 @@ x_delete_display (dpyinfo)
XrmDestroyDatabase (dpyinfo->xrdb);
#endif
#endif
-#ifdef MULTI_KBOARD
- if (--dpyinfo->kboard->reference_count == 0)
- delete_kboard (dpyinfo->kboard);
-#endif
#ifdef HAVE_X_I18N
if (dpyinfo->xim)
xim_close_dpy (dpyinfo);
@@ -11189,71 +11256,129 @@ x_activate_timeout_atimer ()
extern frame_parm_handler x_frame_parm_handlers[];
static struct redisplay_interface x_redisplay_interface =
-{
- x_frame_parm_handlers,
- x_produce_glyphs,
- x_write_glyphs,
- x_insert_glyphs,
- x_clear_end_of_line,
- x_scroll_run,
- x_after_update_window_line,
- x_update_window_begin,
- x_update_window_end,
- x_cursor_to,
- x_flush,
+ {
+ x_frame_parm_handlers,
+ x_produce_glyphs,
+ x_write_glyphs,
+ x_insert_glyphs,
+ x_clear_end_of_line,
+ x_scroll_run,
+ x_after_update_window_line,
+ x_update_window_begin,
+ x_update_window_end,
+ x_cursor_to,
+ x_flush,
#ifdef XFlush
- x_flush,
+ x_flush,
#else
- 0, /* flush_display_optional */
-#endif
- x_clear_window_mouse_face,
- x_get_glyph_overhangs,
- x_fix_overlapping_area,
- x_draw_fringe_bitmap,
- 0, /* define_fringe_bitmap */
- 0, /* destroy_fringe_bitmap */
- x_per_char_metric,
- x_encode_char,
- x_compute_glyph_string_overhangs,
- x_draw_glyph_string,
- x_define_frame_cursor,
- x_clear_frame_area,
- x_draw_window_cursor,
- x_draw_vertical_window_border,
- x_shift_glyphs_for_insert
-};
+ 0, /* flush_display_optional */
+#endif
+ x_clear_window_mouse_face,
+ x_get_glyph_overhangs,
+ x_fix_overlapping_area,
+ x_draw_fringe_bitmap,
+ 0, /* define_fringe_bitmap */
+ 0, /* destroy_fringe_bitmap */
+ x_per_char_metric,
+ x_encode_char,
+ x_compute_glyph_string_overhangs,
+ x_draw_glyph_string,
+ x_define_frame_cursor,
+ x_clear_frame_area,
+ x_draw_window_cursor,
+ x_draw_vertical_window_border,
+ x_shift_glyphs_for_insert
+ };
+
+
+/* This function is called when the last frame on a display is deleted. */
+void
+x_delete_terminal (struct terminal *terminal)
+{
+ struct x_display_info *dpyinfo = terminal->display_info.x;
+ int i;
+
+ /* Protect against recursive calls. Fdelete_frame in
+ delete_terminal calls us back when it deletes our last frame. */
+ if (terminal->deleted)
+ return;
+
+ BLOCK_INPUT;
+ /* Free the fonts in the font table. */
+ for (i = 0; i < dpyinfo->n_fonts; i++)
+ if (dpyinfo->font_table[i].name)
+ {
+ XFreeFont (dpyinfo->display, dpyinfo->font_table[i].font);
+ }
+
+ x_destroy_all_bitmaps (dpyinfo);
+ XSetCloseDownMode (dpyinfo->display, DestroyAll);
+
+#ifdef USE_GTK
+ xg_display_close (dpyinfo->display);
+#else
+#ifdef USE_X_TOOLKIT
+ XtCloseDisplay (dpyinfo->display);
+#else
+ XCloseDisplay (dpyinfo->display);
+#endif
+#endif /* ! USE_GTK */
+
+ x_delete_display (dpyinfo);
+ UNBLOCK_INPUT;
+}
+
+
+static struct terminal *
+x_create_terminal (struct x_display_info *dpyinfo)
+{
+ struct terminal *terminal;
+
+ terminal = create_terminal ();
+
+ terminal->type = output_x_window;
+ terminal->display_info.x = dpyinfo;
+ dpyinfo->terminal = terminal;
+
+ /* kboard is initialized in x_term_init. */
+
+ terminal->clear_frame_hook = x_clear_frame;
+ terminal->ins_del_lines_hook = x_ins_del_lines;
+ terminal->delete_glyphs_hook = x_delete_glyphs;
+ terminal->ring_bell_hook = XTring_bell;
+ terminal->reset_terminal_modes_hook = XTreset_terminal_modes;
+ terminal->set_terminal_modes_hook = XTset_terminal_modes;
+ terminal->update_begin_hook = x_update_begin;
+ terminal->update_end_hook = x_update_end;
+ terminal->set_terminal_window_hook = XTset_terminal_window;
+ terminal->read_socket_hook = XTread_socket;
+ terminal->frame_up_to_date_hook = XTframe_up_to_date;
+ terminal->mouse_position_hook = XTmouse_position;
+ terminal->frame_rehighlight_hook = XTframe_rehighlight;
+ terminal->frame_raise_lower_hook = XTframe_raise_lower;
+ terminal->fullscreen_hook = XTfullscreen_hook;
+ terminal->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
+ terminal->condemn_scroll_bars_hook = XTcondemn_scroll_bars;
+ terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar;
+ terminal->judge_scroll_bars_hook = XTjudge_scroll_bars;
+
+ terminal->delete_frame_hook = x_destroy_window;
+ terminal->delete_terminal_hook = x_delete_terminal;
+
+ terminal->rif = &x_redisplay_interface;
+ terminal->scroll_region_ok = 1; /* We'll scroll partial frames. */
+ terminal->char_ins_del_ok = 1;
+ terminal->line_ins_del_ok = 1; /* We'll just blt 'em. */
+ terminal->fast_clear_end_of_line = 1; /* X does this well. */
+ terminal->memory_below_frame = 0; /* We don't remember what scrolls
+ off the bottom. */
+
+ return terminal;
+}
void
x_initialize ()
{
- rif = &x_redisplay_interface;
-
- clear_frame_hook = x_clear_frame;
- ins_del_lines_hook = x_ins_del_lines;
- delete_glyphs_hook = x_delete_glyphs;
- ring_bell_hook = XTring_bell;
- reset_terminal_modes_hook = XTreset_terminal_modes;
- set_terminal_modes_hook = XTset_terminal_modes;
- update_begin_hook = x_update_begin;
- update_end_hook = x_update_end;
- set_terminal_window_hook = XTset_terminal_window;
- read_socket_hook = XTread_socket;
- frame_up_to_date_hook = XTframe_up_to_date;
- mouse_position_hook = XTmouse_position;
- frame_rehighlight_hook = XTframe_rehighlight;
- frame_raise_lower_hook = XTframe_raise_lower;
- set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
- condemn_scroll_bars_hook = XTcondemn_scroll_bars;
- redeem_scroll_bar_hook = XTredeem_scroll_bar;
- judge_scroll_bars_hook = XTjudge_scroll_bars;
- fullscreen_hook = XTfullscreen_hook;
-
- scroll_region_ok = 1; /* we'll scroll partial frames */
- char_ins_del_ok = 1;
- line_ins_del_ok = 1; /* we'll just blt 'em */
- fast_clear_end_of_line = 1; /* X does this well */
- memory_below_frame = 0; /* we don't remember what scrolls
- off the bottom */
baud_rate = 19200;
x_noop_count = 0;
@@ -11269,7 +11394,7 @@ x_initialize ()
#endif
/* Try to use interrupt input; if we can't, then start polling. */
- Fset_input_mode (Qt, Qnil, Qt, Qnil);
+ Fset_input_interrupt_mode (Qt);
#ifdef USE_X_TOOLKIT
XtToolkitInitialize ();
@@ -11300,9 +11425,11 @@ x_initialize ()
XSetIOErrorHandler (x_io_error_quitter);
/* Disable Window Change signals; they are handled by X events. */
+#if 0 /* Don't. We may want to open tty frames later. */
#ifdef SIGWINCH
signal (SIGWINCH, SIG_DFL);
#endif /* SIGWINCH */
+#endif
signal (SIGPIPE, x_connection_signal);
}
diff --git a/src/xterm.h b/src/xterm.h
index edb35c199f4..c8b768f6187 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -149,6 +149,9 @@ struct x_display_info
/* Chain of all x_display_info structures. */
struct x_display_info *next;
+ /* The generic display parameters corresponding to this X display. */
+ struct terminal *terminal;
+
/* Connection number (normally a file descriptor number). */
int connection;
@@ -327,9 +330,6 @@ struct x_display_info
/* Atom used in toolkit scroll bar client messages. */
Atom Xatom_Scrollbar;
-#ifdef MULTI_KBOARD
- struct kboard *kboard;
-#endif
int cut_buffers_initialized; /* Whether we're sure they all exist */
/* The frame (if any) which has the X window that has keyboard focus.
@@ -532,8 +532,10 @@ struct x_output
/* Pixel values used for various purposes.
border_pixel may be -1 meaning use a gray tile. */
+#if 0 /* These are also defined in struct frame. Use that instead. */
unsigned long background_pixel;
unsigned long foreground_pixel;
+#endif
unsigned long cursor_pixel;
unsigned long border_pixel;
unsigned long mouse_pixel;
@@ -990,7 +992,6 @@ extern int x_had_errors_p P_ ((Display *));
extern int x_catching_errors P_ ((void));
extern void x_uncatch_errors P_ ((void));
extern void x_clear_errors P_ ((Display *));
-extern void x_fully_uncatch_errors P_ ((void));
extern void x_set_window_size P_ ((struct frame *, int, int, int));
extern void x_set_mouse_position P_ ((struct frame *, int, int));
extern void x_set_mouse_pixel_position P_ ((struct frame *, int, int));
@@ -1006,6 +1007,7 @@ extern void x_wm_set_size_hint P_ ((struct frame *, long, int));
extern void x_wm_set_window_state P_ ((struct frame *, int));
extern void x_wm_set_icon_pixmap P_ ((struct frame *, int));
extern void x_delete_display P_ ((struct x_display_info *));
+extern void x_delete_terminal P_ ((struct terminal *terminal));
extern void x_initialize P_ ((void));
extern unsigned long x_copy_color P_ ((struct frame *, unsigned long));
#ifdef USE_X_TOOLKIT
@@ -1106,6 +1108,7 @@ extern void widget_store_internal_border P_ ((Widget));
extern void x_session_initialize P_ ((struct x_display_info *dpyinfo));
extern int x_session_check_input P_ ((struct input_event *bufp));
extern int x_session_have_connection P_ ((void));
+extern void x_session_close P_ ((void));
#endif
#define FONT_TYPE_FOR_UNIBYTE(font, ch) 0