diff options
| author | Karoly Lorentey | 2004-02-28 01:23:39 +0000 |
|---|---|---|
| committer | Karoly Lorentey | 2004-02-28 01:23:39 +0000 |
| commit | 0b0d3e0bcefdde298893aaad2e816e1503cef222 (patch) | |
| tree | 439342044857514ad784de0470f5546eb9c3ef9a /src/term.c | |
| parent | 2fc0cf2aefa777e5fe48596e2d43774b28051931 (diff) | |
| download | emacs-0b0d3e0bcefdde298893aaad2e816e1503cef222.tar.gz emacs-0b0d3e0bcefdde298893aaad2e816e1503cef222.zip | |
Implemented suspending of emacsclient frames.
lib-src/emacsclient.c (quote_file_name): Renamed to quote_argument.
(unquote_argument, handle_sigcont, handle_sigtstp): New functions.
(out, in): New global variables for communicating with the Emacs process.
(init_signals): Set up handlers for SIGCONT, SIGTSTP and SIGTTOU.
(main): Changed out and in to global variables. Prepend `-eval' or
'-file' to each argument. Use fsync to force sending the strings to Emacs.
Removed obsolete -bad-version code. Support the -suspend command.
Cleaned up newline handling.
lisp/frame.el (suspend-frame): New function.
Substitute key definition of suspend-emacs with suspend-frame.
lisp/server.el (server-log): Cosmetic change in log format.
(server-handle-delete-tty, server-handle-delete-frame): Added logging.
(server-handle-suspend-tty, server-quote-arg): New functions.
(server-start): Install server-handle-suspend-tty.
(server-process-filter): Reorganized source code for clarity.
Implemented -resume, -suspend and -ignore commands.
lisp/term/x-win.el (x-initialize-window-system): Don't change the
binding of C-z.
src/cm.c: Replaced TTY_INPUT, TTY_OUTPUT, TTY_TERMSCRIPT calls with
their macro expansion.
src/dispnew.c: Ditto.
src/frame.c: Ditto.
src/keyboard.c: Ditto.
src/sysdep.c: Ditto.
src/keyboard.c (tty_read_avail_input): Don't read if the terminal is
suspended.
src/sysdep.c (discard_tty_input, init_sys_modes, reset_sys_modes): Ditto.
src/term.c (tty_set_terminal_modes, tty_reset_terminal_modes): Ditto.
src/term.c (Vsuspend_tty_functions, Vresume_tty_functions): New hooks.
(syms_of_term): Defvar them.
(term_init): Don't allow opening a new frame on a suspended tty device.
(Fsuspend_tty, Fresume_tty): New functions.
(syms_of_term): Defsubr them.
src/termchar.c (struct tty_display_info): Update documentation of
input and output.
(TTY_INPUT, TTY_OUTPUT, TTY_TERMSCRIPT): Removed.
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-105
Diffstat (limited to 'src/term.c')
| -rw-r--r-- | src/term.c | 234 |
1 files changed, 197 insertions, 37 deletions
diff --git a/src/term.c b/src/term.c index e3b176c51ea..785f2a3bb33 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -106,9 +106,15 @@ void delete_tty_output P_ ((struct frame *)); | |||
| 106 | 106 | ||
| 107 | Lisp_Object Vring_bell_function; | 107 | Lisp_Object Vring_bell_function; |
| 108 | 108 | ||
| 109 | /* Functions to call after a tty was deleted. */ | 109 | /* Functions to call after deleting a tty. */ |
| 110 | Lisp_Object Vdelete_tty_after_functions; | 110 | Lisp_Object Vdelete_tty_after_functions; |
| 111 | 111 | ||
| 112 | /* Functions to call after suspending a tty. */ | ||
| 113 | Lisp_Object Vsuspend_tty_functions; | ||
| 114 | |||
| 115 | /* Functions to call after resuming a tty. */ | ||
| 116 | Lisp_Object Vresume_tty_functions; | ||
| 117 | |||
| 112 | /* Chain of all displays currently in use. */ | 118 | /* Chain of all displays currently in use. */ |
| 113 | struct display *display_list; | 119 | struct display *display_list; |
| 114 | 120 | ||
| @@ -231,10 +237,13 @@ tty_set_terminal_modes (struct display *display) | |||
| 231 | { | 237 | { |
| 232 | struct tty_display_info *tty = display->display_info.tty; | 238 | struct tty_display_info *tty = display->display_info.tty; |
| 233 | 239 | ||
| 234 | OUTPUT_IF (tty, tty->TS_termcap_modes); | 240 | if (tty->output) |
| 235 | OUTPUT_IF (tty, tty->TS_cursor_visible); | 241 | { |
| 236 | OUTPUT_IF (tty, tty->TS_keypad_mode); | 242 | OUTPUT_IF (tty, tty->TS_termcap_modes); |
| 237 | losecursor (tty); | 243 | OUTPUT_IF (tty, tty->TS_cursor_visible); |
| 244 | OUTPUT_IF (tty, tty->TS_keypad_mode); | ||
| 245 | losecursor (tty); | ||
| 246 | } | ||
| 238 | } | 247 | } |
| 239 | 248 | ||
| 240 | /* Reset termcap modes before exiting Emacs. */ | 249 | /* Reset termcap modes before exiting Emacs. */ |
| @@ -243,16 +252,19 @@ void | |||
| 243 | tty_reset_terminal_modes (struct display *display) | 252 | tty_reset_terminal_modes (struct display *display) |
| 244 | { | 253 | { |
| 245 | struct tty_display_info *tty = display->display_info.tty; | 254 | struct tty_display_info *tty = display->display_info.tty; |
| 246 | 255 | ||
| 247 | turn_off_highlight (tty); | 256 | if (tty->output) |
| 248 | turn_off_insert (tty); | 257 | { |
| 249 | OUTPUT_IF (tty, tty->TS_end_keypad_mode); | 258 | turn_off_highlight (tty); |
| 250 | OUTPUT_IF (tty, tty->TS_cursor_normal); | 259 | turn_off_insert (tty); |
| 251 | OUTPUT_IF (tty, tty->TS_end_termcap_modes); | 260 | OUTPUT_IF (tty, tty->TS_end_keypad_mode); |
| 252 | OUTPUT_IF (tty, tty->TS_orig_pair); | 261 | OUTPUT_IF (tty, tty->TS_cursor_normal); |
| 253 | /* Output raw CR so kernel can track the cursor hpos. */ | 262 | OUTPUT_IF (tty, tty->TS_end_termcap_modes); |
| 254 | current_tty = tty; | 263 | OUTPUT_IF (tty, tty->TS_orig_pair); |
| 255 | cmputc ('\r'); | 264 | /* Output raw CR so kernel can track the cursor hpos. */ |
| 265 | current_tty = tty; | ||
| 266 | cmputc ('\r'); | ||
| 267 | } | ||
| 256 | } | 268 | } |
| 257 | 269 | ||
| 258 | void | 270 | void |
| @@ -619,9 +631,9 @@ tty_clear_end_of_line (int first_unused_hpos) | |||
| 619 | 631 | ||
| 620 | for (i = curX (tty); i < first_unused_hpos; i++) | 632 | for (i = curX (tty); i < first_unused_hpos; i++) |
| 621 | { | 633 | { |
| 622 | if (TTY_TERMSCRIPT (tty)) | 634 | if (tty->termscript) |
| 623 | fputc (' ', TTY_TERMSCRIPT (tty)); | 635 | fputc (' ', tty->termscript); |
| 624 | fputc (' ', TTY_OUTPUT (tty)); | 636 | fputc (' ', tty->output); |
| 625 | } | 637 | } |
| 626 | cmplus (tty, first_unused_hpos - curX (tty)); | 638 | cmplus (tty, first_unused_hpos - curX (tty)); |
| 627 | } | 639 | } |
| @@ -807,12 +819,12 @@ tty_write_glyphs (struct glyph *string, int len) | |||
| 807 | if (produced > 0) | 819 | if (produced > 0) |
| 808 | { | 820 | { |
| 809 | fwrite (conversion_buffer, 1, produced, | 821 | fwrite (conversion_buffer, 1, produced, |
| 810 | TTY_OUTPUT (tty)); | 822 | tty->output); |
| 811 | if (ferror (TTY_OUTPUT (tty))) | 823 | if (ferror (tty->output)) |
| 812 | clearerr (TTY_OUTPUT (tty)); | 824 | clearerr (tty->output); |
| 813 | if (TTY_TERMSCRIPT (tty)) | 825 | if (tty->termscript) |
| 814 | fwrite (conversion_buffer, 1, produced, | 826 | fwrite (conversion_buffer, 1, produced, |
| 815 | TTY_TERMSCRIPT (tty)); | 827 | tty->termscript); |
| 816 | } | 828 | } |
| 817 | len -= consumed; | 829 | len -= consumed; |
| 818 | n -= consumed; | 830 | n -= consumed; |
| @@ -833,12 +845,12 @@ tty_write_glyphs (struct glyph *string, int len) | |||
| 833 | if (terminal_coding.produced > 0) | 845 | if (terminal_coding.produced > 0) |
| 834 | { | 846 | { |
| 835 | fwrite (conversion_buffer, 1, terminal_coding.produced, | 847 | fwrite (conversion_buffer, 1, terminal_coding.produced, |
| 836 | TTY_OUTPUT (tty)); | 848 | tty->output); |
| 837 | if (ferror (TTY_OUTPUT (tty))) | 849 | if (ferror (tty->output)) |
| 838 | clearerr (TTY_OUTPUT (tty)); | 850 | clearerr (tty->output); |
| 839 | if (TTY_TERMSCRIPT (tty)) | 851 | if (tty->termscript) |
| 840 | fwrite (conversion_buffer, 1, terminal_coding.produced, | 852 | fwrite (conversion_buffer, 1, terminal_coding.produced, |
| 841 | TTY_TERMSCRIPT (tty)); | 853 | tty->termscript); |
| 842 | } | 854 | } |
| 843 | } | 855 | } |
| 844 | 856 | ||
| @@ -927,12 +939,12 @@ tty_insert_glyphs (struct glyph *start, int len) | |||
| 927 | if (produced > 0) | 939 | if (produced > 0) |
| 928 | { | 940 | { |
| 929 | fwrite (conversion_buffer, 1, produced, | 941 | fwrite (conversion_buffer, 1, produced, |
| 930 | TTY_OUTPUT (tty)); | 942 | tty->output); |
| 931 | if (ferror (TTY_OUTPUT (tty))) | 943 | if (ferror (tty->output)) |
| 932 | clearerr (TTY_OUTPUT (tty)); | 944 | clearerr (tty->output); |
| 933 | if (TTY_TERMSCRIPT (tty)) | 945 | if (tty->termscript) |
| 934 | fwrite (conversion_buffer, 1, produced, | 946 | fwrite (conversion_buffer, 1, produced, |
| 935 | TTY_TERMSCRIPT (tty)); | 947 | tty->termscript); |
| 936 | } | 948 | } |
| 937 | 949 | ||
| 938 | OUTPUT1_IF (tty, tty->TS_pad_inserted_char); | 950 | OUTPUT1_IF (tty, tty->TS_pad_inserted_char); |
| @@ -2240,7 +2252,11 @@ term_init (char *name, char *terminal_type, int must_succeed) | |||
| 2240 | 2252 | ||
| 2241 | display = get_named_tty_display (name); | 2253 | display = get_named_tty_display (name); |
| 2242 | if (display) | 2254 | if (display) |
| 2243 | return display; /* We have already opened a display there. */ | 2255 | { |
| 2256 | if (! display->display_info.tty->input) | ||
| 2257 | error ("%s already has a suspended frame on it, can't open it twice", name); | ||
| 2258 | return display; | ||
| 2259 | } | ||
| 2244 | 2260 | ||
| 2245 | display = create_display (); | 2261 | display = create_display (); |
| 2246 | tty = (struct tty_display_info *) xmalloc (sizeof (struct tty_display_info)); | 2262 | tty = (struct tty_display_info *) xmalloc (sizeof (struct tty_display_info)); |
| @@ -2550,7 +2566,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", | |||
| 2550 | /* Get frame size from system, or else from termcap. */ | 2566 | /* Get frame size from system, or else from termcap. */ |
| 2551 | { | 2567 | { |
| 2552 | int height, width; | 2568 | int height, width; |
| 2553 | get_tty_size (fileno (TTY_INPUT (tty)), &width, &height); | 2569 | get_tty_size (fileno (tty->input), &width, &height); |
| 2554 | FrameCols (tty) = width; | 2570 | FrameCols (tty) = width; |
| 2555 | FrameRows (tty) = height; | 2571 | FrameRows (tty) = height; |
| 2556 | } | 2572 | } |
| @@ -2735,7 +2751,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", | |||
| 2735 | && tty->TS_end_standout_mode | 2751 | && tty->TS_end_standout_mode |
| 2736 | && !strcmp (tty->TS_standout_mode, tty->TS_end_standout_mode)); | 2752 | && !strcmp (tty->TS_standout_mode, tty->TS_end_standout_mode)); |
| 2737 | 2753 | ||
| 2738 | UseTabs (tty) = tabs_safe_p (fileno (TTY_INPUT (tty))) && TabWidth (tty) == 8; | 2754 | UseTabs (tty) = tabs_safe_p (fileno (tty->input)) && TabWidth (tty) == 8; |
| 2739 | 2755 | ||
| 2740 | display->scroll_region_ok | 2756 | display->scroll_region_ok |
| 2741 | = (tty->Wcm->cm_abs | 2757 | = (tty->Wcm->cm_abs |
| @@ -2754,7 +2770,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", | |||
| 2754 | 2770 | ||
| 2755 | display->fast_clear_end_of_line = tty->TS_clr_line != 0; | 2771 | display->fast_clear_end_of_line = tty->TS_clr_line != 0; |
| 2756 | 2772 | ||
| 2757 | init_baud_rate (fileno (TTY_INPUT (tty))); | 2773 | init_baud_rate (fileno (tty->input)); |
| 2758 | 2774 | ||
| 2759 | #ifdef AIXHFT | 2775 | #ifdef AIXHFT |
| 2760 | /* The HFT system on AIX doesn't optimize for scrolling, so it's | 2776 | /* The HFT system on AIX doesn't optimize for scrolling, so it's |
| @@ -3067,6 +3083,134 @@ delete_display (struct display *dev) | |||
| 3067 | xfree (dev); | 3083 | xfree (dev); |
| 3068 | } | 3084 | } |
| 3069 | 3085 | ||
| 3086 | |||
| 3087 | |||
| 3088 | DEFUN ("suspend-tty", Fsuspend_tty, Ssuspend_tty, 0, 1, 0, | ||
| 3089 | doc: /* Suspend the terminal device TTY. | ||
| 3090 | The terminal is restored to its default state, and Emacs closes all | ||
| 3091 | access to the terminal device. Frames that use the device are not | ||
| 3092 | deleted, but input is not read from them and if they change, their | ||
| 3093 | display is not updated. | ||
| 3094 | |||
| 3095 | TTY may a string (a device name), a frame, or nil for the display | ||
| 3096 | device of the currently selected frame. | ||
| 3097 | |||
| 3098 | This function runs `suspend-tty-functions' after suspending the | ||
| 3099 | device. The functions are run with one arg, the name of the terminal | ||
| 3100 | device. | ||
| 3101 | |||
| 3102 | `suspend-tty' does nothing if it is called on an already suspended | ||
| 3103 | device. | ||
| 3104 | |||
| 3105 | A suspended terminal device may be resumed by calling `resume-tty' on | ||
| 3106 | it. */) | ||
| 3107 | (tty) | ||
| 3108 | Lisp_Object tty; | ||
| 3109 | { | ||
| 3110 | struct display *d = get_tty_display (tty); | ||
| 3111 | FILE *f; | ||
| 3112 | |||
| 3113 | if (!d) | ||
| 3114 | error ("Unknown tty device"); | ||
| 3115 | |||
| 3116 | f = d->display_info.tty->input; | ||
| 3117 | |||
| 3118 | if (f) | ||
| 3119 | { | ||
| 3120 | reset_sys_modes (d->display_info.tty); | ||
| 3121 | |||
| 3122 | delete_keyboard_wait_descriptor (fileno (f)); | ||
| 3123 | |||
| 3124 | fclose (f); | ||
| 3125 | if (f != d->display_info.tty->output) | ||
| 3126 | fclose (d->display_info.tty->output); | ||
| 3127 | |||
| 3128 | d->display_info.tty->input = 0; | ||
| 3129 | d->display_info.tty->output = 0; | ||
| 3130 | |||
| 3131 | if (FRAMEP (d->display_info.tty->top_frame)) | ||
| 3132 | FRAME_SET_VISIBLE (XFRAME (d->display_info.tty->top_frame), 0); | ||
| 3133 | |||
| 3134 | /* Run `suspend-tty-functions'. */ | ||
| 3135 | if (!NILP (Vrun_hooks)) | ||
| 3136 | { | ||
| 3137 | Lisp_Object args[2]; | ||
| 3138 | args[0] = intern ("suspend-tty-functions"); | ||
| 3139 | if (d->display_info.tty->name) | ||
| 3140 | { | ||
| 3141 | args[1] = build_string (d->display_info.tty->name); | ||
| 3142 | } | ||
| 3143 | else | ||
| 3144 | args[1] = Qnil; | ||
| 3145 | Frun_hook_with_args (2, args); | ||
| 3146 | } | ||
| 3147 | } | ||
| 3148 | |||
| 3149 | return Qnil; | ||
| 3150 | } | ||
| 3151 | |||
| 3152 | |||
| 3153 | DEFUN ("resume-tty", Fresume_tty, Sresume_tty, 0, 1, 0, | ||
| 3154 | doc: /* Resume the previously suspended terminal device TTY. | ||
| 3155 | The terminal is opened and reinitialized. Frames that used the | ||
| 3156 | suspended device are revived. | ||
| 3157 | |||
| 3158 | This function runs `resume-tty-functions' after resuming the device. | ||
| 3159 | The functions are run with one arg, the name of the terminal device. | ||
| 3160 | |||
| 3161 | `resume-tty' does nothing if it is called on a device that is not | ||
| 3162 | suspended. | ||
| 3163 | |||
| 3164 | TTY may a string (a device name), a frame, or nil for the display | ||
| 3165 | device of the currently selected frame. */) | ||
| 3166 | (tty) | ||
| 3167 | Lisp_Object tty; | ||
| 3168 | { | ||
| 3169 | struct display *d = get_tty_display (tty); | ||
| 3170 | int fd; | ||
| 3171 | |||
| 3172 | if (!d) | ||
| 3173 | error ("Unknown tty device"); | ||
| 3174 | |||
| 3175 | if (!d->display_info.tty->input) | ||
| 3176 | { | ||
| 3177 | fd = emacs_open (d->display_info.tty->name, O_RDWR | O_NOCTTY, 0); | ||
| 3178 | |||
| 3179 | #ifdef TIOCNOTTY | ||
| 3180 | /* Drop our controlling tty if it is the same device. */ | ||
| 3181 | if (ioctl (fd, TIOCNOTTY, 0) != -1) | ||
| 3182 | { | ||
| 3183 | no_controlling_tty = 1; | ||
| 3184 | } | ||
| 3185 | #endif | ||
| 3186 | |||
| 3187 | d->display_info.tty->output = fdopen (fd, "w+"); | ||
| 3188 | d->display_info.tty->input = d->display_info.tty->output; | ||
| 3189 | |||
| 3190 | add_keyboard_wait_descriptor (fd); | ||
| 3191 | |||
| 3192 | if (FRAMEP (d->display_info.tty->top_frame)) | ||
| 3193 | FRAME_SET_VISIBLE (XFRAME (d->display_info.tty->top_frame), 1); | ||
| 3194 | |||
| 3195 | init_sys_modes (d->display_info.tty); | ||
| 3196 | |||
| 3197 | /* Run `suspend-tty-functions'. */ | ||
| 3198 | if (!NILP (Vrun_hooks)) | ||
| 3199 | { | ||
| 3200 | Lisp_Object args[2]; | ||
| 3201 | args[0] = intern ("resume-tty-functions"); | ||
| 3202 | if (d->display_info.tty->name) | ||
| 3203 | { | ||
| 3204 | args[1] = build_string (d->display_info.tty->name); | ||
| 3205 | } | ||
| 3206 | else | ||
| 3207 | args[1] = Qnil; | ||
| 3208 | Frun_hook_with_args (2, args); | ||
| 3209 | } | ||
| 3210 | } | ||
| 3211 | |||
| 3212 | return Qnil; | ||
| 3213 | } | ||
| 3070 | 3214 | ||
| 3071 | 3215 | ||
| 3072 | void | 3216 | void |
| @@ -3092,6 +3236,20 @@ The functions are run with one argument, the name of the tty to be deleted. | |||
| 3092 | See `delete-tty'. */); | 3236 | See `delete-tty'. */); |
| 3093 | Vdelete_tty_after_functions = Qnil; | 3237 | Vdelete_tty_after_functions = Qnil; |
| 3094 | 3238 | ||
| 3239 | |||
| 3240 | DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions, | ||
| 3241 | doc: /* Functions to be run after suspending a tty. | ||
| 3242 | The functions are run with one argument, the name of the tty to be suspended. | ||
| 3243 | See `suspend-tty'. */); | ||
| 3244 | Vsuspend_tty_functions = Qnil; | ||
| 3245 | |||
| 3246 | |||
| 3247 | DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions, | ||
| 3248 | doc: /* Functions to be run after resuming a tty. | ||
| 3249 | The functions are run with one argument, the name of the tty that was revived. | ||
| 3250 | See `resume-tty'. */); | ||
| 3251 | Vresume_tty_functions = Qnil; | ||
| 3252 | |||
| 3095 | Qframe_tty_name = intern ("frame-tty-name"); | 3253 | Qframe_tty_name = intern ("frame-tty-name"); |
| 3096 | staticpro (&Qframe_tty_name); | 3254 | staticpro (&Qframe_tty_name); |
| 3097 | 3255 | ||
| @@ -3103,6 +3261,8 @@ See `delete-tty'. */); | |||
| 3103 | defsubr (&Sframe_tty_name); | 3261 | defsubr (&Sframe_tty_name); |
| 3104 | defsubr (&Sframe_tty_type); | 3262 | defsubr (&Sframe_tty_type); |
| 3105 | defsubr (&Sdelete_tty); | 3263 | defsubr (&Sdelete_tty); |
| 3264 | defsubr (&Ssuspend_tty); | ||
| 3265 | defsubr (&Sresume_tty); | ||
| 3106 | 3266 | ||
| 3107 | Fprovide (intern ("multi-tty"), Qnil); | 3267 | Fprovide (intern ("multi-tty"), Qnil); |
| 3108 | 3268 | ||