diff options
| author | Karoly Lorentey | 2006-05-20 17:12:43 +0000 |
|---|---|---|
| committer | Karoly Lorentey | 2006-05-20 17:12:43 +0000 |
| commit | ab797f65de1b82ff9e96aab6989976a152385048 (patch) | |
| tree | 2622d33ce1a69cac40e5b31fa0f7f9e1faa8998b /src | |
| parent | 8cbd7bed2db718a63ed37182c566f9e059925c71 (diff) | |
| download | emacs-ab797f65de1b82ff9e96aab6989976a152385048.tar.gz emacs-ab797f65de1b82ff9e96aab6989976a152385048.zip | |
Fix C-x 5 2 on the controlling tty; fix some possible crash conditions and a memory leak.
* src/frame.c (make_terminal_frame): Don't create frames on a terminal
that is being deleted.
* src/xfns.c (Fx_create_frame, x_create_tip_frame): Ditto.
* src/keyboard.c (tty_read_avail_input): Don't read from a terminal that
is being deleted.
* src/term.c (get_named_tty): Abort if tty name is NULL. Simplify accordingly.
* src/term.c (Ftty_type): Return nil if terminal is not on a tty instead
of throwing an error. Doc update.
* src/term.c (init_tty): Set name before calling `get_named_tty'.
* src/term.c (delete_tty): Let delete_terminal delete the frames. Plug
memory leak caused by tty->name. Remove reference to `deleting_tty'.
* src/term.c (syms_of_term) <Vsuspend_tty_functions, Vresume_tty_functions>: Doc update.
* src/termhooks.h (terminal) <name>: Explain why identifying terminals by
name is a bad idea.
* src/terminal.c (delete_terminal): Doc update.
* src/xterm.c (XTread_socket): Disable loop on all X displays.
* src/xterm.c (x_delete_display): Doc update to reflect changes in
delete_terminal.
* src/xterm.c (x_delete_terminal): Don't set terminal->deleted and let
delete_terminal delete the frames on the terminal.
* src/xterm.h (x_display_info) <terminal>: Move member earlier in the struct.
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-565
Diffstat (limited to 'src')
| -rw-r--r-- | src/frame.c | 5 | ||||
| -rw-r--r-- | src/keyboard.c | 3 | ||||
| -rw-r--r-- | src/term.c | 66 | ||||
| -rw-r--r-- | src/termhooks.h | 4 | ||||
| -rw-r--r-- | src/terminal.c | 10 | ||||
| -rw-r--r-- | src/xfns.c | 6 | ||||
| -rw-r--r-- | src/xterm.c | 100 | ||||
| -rw-r--r-- | src/xterm.h | 6 |
8 files changed, 97 insertions, 103 deletions
diff --git a/src/frame.c b/src/frame.c index f29bca1796f..3fad2187ba4 100644 --- a/src/frame.c +++ b/src/frame.c | |||
| @@ -561,7 +561,10 @@ make_terminal_frame (struct terminal *terminal) | |||
| 561 | register struct frame *f; | 561 | register struct frame *f; |
| 562 | Lisp_Object frame; | 562 | Lisp_Object frame; |
| 563 | char name[20]; | 563 | char name[20]; |
| 564 | 564 | ||
| 565 | if (terminal->deleted) | ||
| 566 | error ("Terminal is being deleted, can't create new frames on it"); | ||
| 567 | |||
| 565 | f = make_frame (1); | 568 | f = make_frame (1); |
| 566 | 569 | ||
| 567 | XSETFRAME (frame, f); | 570 | XSETFRAME (frame, f); |
diff --git a/src/keyboard.c b/src/keyboard.c index 5dcd2f8f5ae..6e046aea7d6 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -6899,6 +6899,9 @@ tty_read_avail_input (struct terminal *terminal, | |||
| 6899 | struct tty_display_info *tty = terminal->display_info.tty; | 6899 | struct tty_display_info *tty = terminal->display_info.tty; |
| 6900 | int nread = 0; | 6900 | int nread = 0; |
| 6901 | 6901 | ||
| 6902 | if (terminal->deleted) /* Don't read from a deleted terminal. */ | ||
| 6903 | return; | ||
| 6904 | |||
| 6902 | if (terminal->type != output_termcap) | 6905 | if (terminal->type != output_termcap) |
| 6903 | abort (); | 6906 | abort (); |
| 6904 | 6907 | ||
diff --git a/src/term.c b/src/term.c index 3076e8939f1..924bebf5f7e 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -2029,9 +2029,8 @@ get_tty_terminal (Lisp_Object terminal, int throw) | |||
| 2029 | return t; | 2029 | return t; |
| 2030 | } | 2030 | } |
| 2031 | 2031 | ||
| 2032 | /* Return the active termcap device that uses the tty device with the | 2032 | /* Return an active termcap device that uses the tty device with the |
| 2033 | given name. If NAME is NULL, return the device corresponding to | 2033 | given name. |
| 2034 | our controlling terminal. | ||
| 2035 | 2034 | ||
| 2036 | This function ignores suspended devices. | 2035 | This function ignores suspended devices. |
| 2037 | 2036 | ||
| @@ -2043,14 +2042,16 @@ get_named_tty (name) | |||
| 2043 | { | 2042 | { |
| 2044 | struct terminal *t; | 2043 | struct terminal *t; |
| 2045 | 2044 | ||
| 2046 | for (t = terminal_list; t; t = t->next_terminal) { | 2045 | if (!name) |
| 2047 | if (t->type == output_termcap | 2046 | abort (); |
| 2048 | && ((t->display_info.tty->name == 0 && name == 0) | 2047 | |
| 2049 | || (name && t->display_info.tty->name | 2048 | for (t = terminal_list; t; t = t->next_terminal) |
| 2050 | && !strcmp (t->display_info.tty->name, name))) | 2049 | { |
| 2051 | && TERMINAL_ACTIVE_P (t)) | 2050 | if (t->type == output_termcap |
| 2052 | return t; | 2051 | && !strcmp (t->display_info.tty->name, name) |
| 2053 | }; | 2052 | && TERMINAL_ACTIVE_P (t)) |
| 2053 | return t; | ||
| 2054 | } | ||
| 2054 | 2055 | ||
| 2055 | return 0; | 2056 | return 0; |
| 2056 | } | 2057 | } |
| @@ -2058,6 +2059,7 @@ get_named_tty (name) | |||
| 2058 | 2059 | ||
| 2059 | DEFUN ("tty-type", Ftty_type, Stty_type, 0, 1, 0, | 2060 | DEFUN ("tty-type", Ftty_type, Stty_type, 0, 1, 0, |
| 2060 | doc: /* Return the type of the tty device that TERMINAL uses. | 2061 | doc: /* Return the type of the tty device that TERMINAL uses. |
| 2062 | Returns nil if TERMINAL is not on a tty device. | ||
| 2061 | 2063 | ||
| 2062 | TERMINAL can be a terminal id, a frame or nil (meaning the selected | 2064 | TERMINAL can be a terminal id, a frame or nil (meaning the selected |
| 2063 | frame's terminal). */) | 2065 | frame's terminal). */) |
| @@ -2067,8 +2069,8 @@ frame's terminal). */) | |||
| 2067 | struct terminal *t = get_terminal (terminal, 1); | 2069 | struct terminal *t = get_terminal (terminal, 1); |
| 2068 | 2070 | ||
| 2069 | if (t->type != output_termcap) | 2071 | if (t->type != output_termcap) |
| 2070 | error ("Terminal %d is not a termcap terminal", t->id); | 2072 | return Qnil; |
| 2071 | 2073 | ||
| 2072 | if (t->display_info.tty->type) | 2074 | if (t->display_info.tty->type) |
| 2073 | return build_string (t->display_info.tty->type); | 2075 | return build_string (t->display_info.tty->type); |
| 2074 | else | 2076 | else |
| @@ -2388,7 +2390,7 @@ static void maybe_fatal(); | |||
| 2388 | /* Create a termcap display on the tty device with the given name and | 2390 | /* Create a termcap display on the tty device with the given name and |
| 2389 | type. | 2391 | type. |
| 2390 | 2392 | ||
| 2391 | If NAME is NULL, then use the controlling tty, i.e., stdin/stdout. | 2393 | If NAME is NULL, then use the controlling tty, i.e., "/dev/tty". |
| 2392 | Otherwise NAME should be a path to the tty device file, | 2394 | Otherwise NAME should be a path to the tty device file, |
| 2393 | e.g. "/dev/pts/7". | 2395 | e.g. "/dev/pts/7". |
| 2394 | 2396 | ||
| @@ -2414,6 +2416,11 @@ init_tty (char *name, char *terminal_type, int must_succeed) | |||
| 2414 | "Unknown terminal type", | 2416 | "Unknown terminal type", |
| 2415 | "Unknown terminal type"); | 2417 | "Unknown terminal type"); |
| 2416 | 2418 | ||
| 2419 | if (name == NULL) | ||
| 2420 | name = "/dev/tty"; | ||
| 2421 | if (!strcmp (name, "/dev/tty")) | ||
| 2422 | ctty = 1; | ||
| 2423 | |||
| 2417 | /* If we already have a terminal on the given device, use that. If | 2424 | /* If we already have a terminal on the given device, use that. If |
| 2418 | all such terminals are suspended, create a new one instead. */ | 2425 | all such terminals are suspended, create a new one instead. */ |
| 2419 | /* XXX Perhaps this should be made explicit by having init_tty | 2426 | /* XXX Perhaps this should be made explicit by having init_tty |
| @@ -2438,11 +2445,6 @@ init_tty (char *name, char *terminal_type, int must_succeed) | |||
| 2438 | 2445 | ||
| 2439 | set_tty_hooks (terminal); | 2446 | set_tty_hooks (terminal); |
| 2440 | 2447 | ||
| 2441 | if (name == NULL) | ||
| 2442 | name = "/dev/tty"; | ||
| 2443 | if (!strcmp (name, "/dev/tty")) | ||
| 2444 | ctty = 1; | ||
| 2445 | |||
| 2446 | { | 2448 | { |
| 2447 | int fd; | 2449 | int fd; |
| 2448 | FILE *file; | 2450 | FILE *file; |
| @@ -2977,11 +2979,10 @@ delete_tty (struct terminal *terminal) | |||
| 2977 | { | 2979 | { |
| 2978 | struct tty_display_info *tty; | 2980 | struct tty_display_info *tty; |
| 2979 | Lisp_Object tail, frame; | 2981 | Lisp_Object tail, frame; |
| 2980 | char *tty_name; | ||
| 2981 | int last_terminal; | 2982 | int last_terminal; |
| 2982 | 2983 | ||
| 2983 | /* Protect against recursive calls. Fdelete_frame calls us back | 2984 | /* Protect against recursive calls. Fdelete_frame in |
| 2984 | when we delete our last frame. */ | 2985 | delete_terminal calls us back when it deletes our last frame. */ |
| 2985 | if (terminal->deleted) | 2986 | if (terminal->deleted) |
| 2986 | return; | 2987 | return; |
| 2987 | 2988 | ||
| @@ -3019,25 +3020,15 @@ delete_tty (struct terminal *terminal) | |||
| 3019 | tty->next = 0; | 3020 | tty->next = 0; |
| 3020 | } | 3021 | } |
| 3021 | 3022 | ||
| 3022 | /* We must not throw any errors below this line. */ | ||
| 3023 | terminal->deleted = 1; | ||
| 3024 | |||
| 3025 | FOR_EACH_FRAME (tail, frame) | ||
| 3026 | { | ||
| 3027 | struct frame *f = XFRAME (frame); | ||
| 3028 | if (FRAME_TERMCAP_P (f) && FRAME_LIVE_P (f) && FRAME_TTY (f) == tty) | ||
| 3029 | { | ||
| 3030 | Fdelete_frame (frame, Qt); | ||
| 3031 | } | ||
| 3032 | } | ||
| 3033 | |||
| 3034 | /* reset_sys_modes needs a valid device, so this call needs to be | 3023 | /* reset_sys_modes needs a valid device, so this call needs to be |
| 3035 | before delete_terminal. */ | 3024 | before delete_terminal. */ |
| 3036 | reset_sys_modes (tty); | 3025 | reset_sys_modes (tty); |
| 3037 | 3026 | ||
| 3038 | delete_terminal (terminal); | 3027 | delete_terminal (terminal); |
| 3039 | 3028 | ||
| 3040 | tty_name = tty->name; | 3029 | if (tty->name) |
| 3030 | xfree (tty->name); | ||
| 3031 | |||
| 3041 | if (tty->type) | 3032 | if (tty->type) |
| 3042 | xfree (tty->type); | 3033 | xfree (tty->type); |
| 3043 | 3034 | ||
| @@ -3060,7 +3051,6 @@ delete_tty (struct terminal *terminal) | |||
| 3060 | 3051 | ||
| 3061 | bzero (tty, sizeof (struct tty_display_info)); | 3052 | bzero (tty, sizeof (struct tty_display_info)); |
| 3062 | xfree (tty); | 3053 | xfree (tty); |
| 3063 | deleting_tty = 0; | ||
| 3064 | } | 3054 | } |
| 3065 | 3055 | ||
| 3066 | 3056 | ||
| @@ -3096,14 +3086,14 @@ This variable can be used by terminal emulator packages. */); | |||
| 3096 | 3086 | ||
| 3097 | DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions, | 3087 | DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions, |
| 3098 | doc: /* Functions to be run after suspending a tty. | 3088 | doc: /* Functions to be run after suspending a tty. |
| 3099 | The functions are run with one argument, the name of the tty to be suspended. | 3089 | The functions are run with one argument, the terminal id to be suspended. |
| 3100 | See `suspend-tty'. */); | 3090 | See `suspend-tty'. */); |
| 3101 | Vsuspend_tty_functions = Qnil; | 3091 | Vsuspend_tty_functions = Qnil; |
| 3102 | 3092 | ||
| 3103 | 3093 | ||
| 3104 | DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions, | 3094 | DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions, |
| 3105 | doc: /* Functions to be run after resuming a tty. | 3095 | doc: /* Functions to be run after resuming a tty. |
| 3106 | The functions are run with one argument, the name of the tty that was revived. | 3096 | The functions are run with one argument, the terminal id that was revived. |
| 3107 | See `resume-tty'. */); | 3097 | See `resume-tty'. */); |
| 3108 | Vresume_tty_functions = Qnil; | 3098 | Vresume_tty_functions = Qnil; |
| 3109 | 3099 | ||
diff --git a/src/termhooks.h b/src/termhooks.h index 46fb0c453f5..64a72acc360 100644 --- a/src/termhooks.h +++ b/src/termhooks.h | |||
| @@ -307,7 +307,9 @@ struct terminal | |||
| 307 | /* The type of the terminal device. */ | 307 | /* The type of the terminal device. */ |
| 308 | enum output_method type; | 308 | enum output_method type; |
| 309 | 309 | ||
| 310 | /* The name of the terminal device. Do not use this to identify the device. */ | 310 | /* The name of the terminal device. Do not use this to uniquely |
| 311 | identify a terminal; the same device may be opened multiple | ||
| 312 | times. */ | ||
| 311 | char *name; | 313 | char *name; |
| 312 | 314 | ||
| 313 | #ifdef MULTI_KBOARD | 315 | #ifdef MULTI_KBOARD |
diff --git a/src/terminal.c b/src/terminal.c index db75e16b6cf..f3f0a178c8d 100644 --- a/src/terminal.c +++ b/src/terminal.c | |||
| @@ -270,7 +270,8 @@ mark_terminals (void) | |||
| 270 | } | 270 | } |
| 271 | 271 | ||
| 272 | 272 | ||
| 273 | /* Remove a terminal from the terminal list and free its memory. */ | 273 | /* Low-level function to close all frames on a terminal, remove it |
| 274 | from the terminal list and free its memory. */ | ||
| 274 | 275 | ||
| 275 | void | 276 | void |
| 276 | delete_terminal (struct terminal *terminal) | 277 | delete_terminal (struct terminal *terminal) |
| @@ -278,14 +279,13 @@ delete_terminal (struct terminal *terminal) | |||
| 278 | struct terminal **tp; | 279 | struct terminal **tp; |
| 279 | Lisp_Object tail, frame; | 280 | Lisp_Object tail, frame; |
| 280 | 281 | ||
| 281 | /* Protect against recursive calls. Fdelete_frame calls us back | 282 | /* Protect against recursive calls. Fdelete_frame calls the |
| 282 | when we delete our last frame. */ | 283 | delete_terminal_hook when we delete our last frame. */ |
| 283 | if (terminal->deleted) | 284 | if (terminal->deleted) |
| 284 | return; | 285 | return; |
| 285 | terminal->deleted = 1; | 286 | terminal->deleted = 1; |
| 286 | 287 | ||
| 287 | /* Check for and close live frames that are still on this | 288 | /* Check for live frames that are still on this terminal. */ |
| 288 | terminal. */ | ||
| 289 | FOR_EACH_FRAME (tail, frame) | 289 | FOR_EACH_FRAME (tail, frame) |
| 290 | { | 290 | { |
| 291 | struct frame *f = XFRAME (frame); | 291 | struct frame *f = XFRAME (frame); |
diff --git a/src/xfns.c b/src/xfns.c index 43970439a1a..acbf22b600c 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -3039,6 +3039,9 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 3039 | kb = &the_only_kboard; | 3039 | kb = &the_only_kboard; |
| 3040 | #endif | 3040 | #endif |
| 3041 | 3041 | ||
| 3042 | if (dpyinfo->terminal->deleted) | ||
| 3043 | error ("Terminal is being deleted, can't create new frames on it"); | ||
| 3044 | |||
| 3042 | name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING); | 3045 | name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING); |
| 3043 | if (!STRINGP (name) | 3046 | if (!STRINGP (name) |
| 3044 | && ! EQ (name, Qunbound) | 3047 | && ! EQ (name, Qunbound) |
| @@ -4634,6 +4637,9 @@ x_create_tip_frame (dpyinfo, parms, text) | |||
| 4634 | 4637 | ||
| 4635 | check_x (); | 4638 | check_x (); |
| 4636 | 4639 | ||
| 4640 | if (dpyinfo->terminal->deleted) | ||
| 4641 | error ("Terminal is being deleted, can't create new frames on it"); | ||
| 4642 | |||
| 4637 | parms = Fcopy_alist (parms); | 4643 | parms = Fcopy_alist (parms); |
| 4638 | 4644 | ||
| 4639 | /* Get the name of the frame to use for resource lookup. */ | 4645 | /* Get the name of the frame to use for resource lookup. */ |
diff --git a/src/xterm.c b/src/xterm.c index 04242f2af3b..356ee3b963b 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -6981,6 +6981,31 @@ XTread_socket (terminal, expected, hold_quit) | |||
| 6981 | 6981 | ||
| 6982 | ++handling_signal; | 6982 | ++handling_signal; |
| 6983 | 6983 | ||
| 6984 | #ifdef HAVE_X_SM | ||
| 6985 | /* Only check session manager input for the primary display. */ | ||
| 6986 | if (terminal->id == 1 && x_session_have_connection ()) | ||
| 6987 | { | ||
| 6988 | struct input_event inev; | ||
| 6989 | BLOCK_INPUT; | ||
| 6990 | /* We don't need to EVENT_INIT (inev) here, as | ||
| 6991 | x_session_check_input copies an entire input_event. */ | ||
| 6992 | if (x_session_check_input (&inev)) | ||
| 6993 | { | ||
| 6994 | kbd_buffer_store_event_hold (&inev, hold_quit); | ||
| 6995 | count++; | ||
| 6996 | } | ||
| 6997 | UNBLOCK_INPUT; | ||
| 6998 | } | ||
| 6999 | #endif | ||
| 7000 | |||
| 7001 | /* For debugging, this gives a way to fake an I/O error. */ | ||
| 7002 | if (terminal->display_info.x == XTread_socket_fake_io_error) | ||
| 7003 | { | ||
| 7004 | XTread_socket_fake_io_error = 0; | ||
| 7005 | x_io_error_quitter (dpyinfo->display); | ||
| 7006 | } | ||
| 7007 | |||
| 7008 | #if 0 /* This loop is a noop now. */ | ||
| 6984 | /* Find the display we are supposed to read input for. | 7009 | /* Find the display we are supposed to read input for. |
| 6985 | It's the one communicating on descriptor SD. */ | 7010 | It's the one communicating on descriptor SD. */ |
| 6986 | for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next) | 7011 | for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next) |
| @@ -7011,54 +7036,31 @@ XTread_socket (terminal, expected, hold_quit) | |||
| 7011 | #endif /* HAVE_SELECT */ | 7036 | #endif /* HAVE_SELECT */ |
| 7012 | #endif /* SIGIO */ | 7037 | #endif /* SIGIO */ |
| 7013 | #endif | 7038 | #endif |
| 7014 | 7039 | } | |
| 7015 | /* For debugging, this gives a way to fake an I/O error. */ | ||
| 7016 | if (dpyinfo == XTread_socket_fake_io_error) | ||
| 7017 | { | ||
| 7018 | XTread_socket_fake_io_error = 0; | ||
| 7019 | x_io_error_quitter (dpyinfo->display); | ||
| 7020 | } | ||
| 7021 | |||
| 7022 | #ifdef HAVE_X_SM | ||
| 7023 | /* Only check session manager input for the primary display. */ | ||
| 7024 | if (terminal->id == 1 && x_session_have_connection ()) | ||
| 7025 | { | ||
| 7026 | struct input_event inev; | ||
| 7027 | BLOCK_INPUT; | ||
| 7028 | /* We don't need to EVENT_INIT (inev) here, as | ||
| 7029 | x_session_check_input copies an entire input_event. */ | ||
| 7030 | if (x_session_check_input (&inev)) | ||
| 7031 | { | ||
| 7032 | kbd_buffer_store_event_hold (&inev, hold_quit); | ||
| 7033 | count++; | ||
| 7034 | } | ||
| 7035 | UNBLOCK_INPUT; | ||
| 7036 | } | ||
| 7037 | #endif | 7040 | #endif |
| 7038 | 7041 | ||
| 7039 | #ifndef USE_GTK | 7042 | #ifndef USE_GTK |
| 7040 | while (XPending (dpyinfo->display)) | 7043 | while (XPending (terminal->display_info.x->display)) |
| 7041 | { | 7044 | { |
| 7042 | int finish; | 7045 | int finish; |
| 7043 | 7046 | ||
| 7044 | XNextEvent (dpyinfo->display, &event); | 7047 | XNextEvent (terminal->display_info.x->display, &event); |
| 7045 | 7048 | ||
| 7046 | #ifdef HAVE_X_I18N | 7049 | #ifdef HAVE_X_I18N |
| 7047 | /* Filter events for the current X input method. */ | 7050 | /* Filter events for the current X input method. */ |
| 7048 | if (x_filter_event (dpyinfo, &event)) | 7051 | if (x_filter_event (terminal->display_info.x, &event)) |
| 7049 | break; | 7052 | break; |
| 7050 | #endif | 7053 | #endif |
| 7051 | event_found = 1; | 7054 | event_found = 1; |
| 7052 | 7055 | ||
| 7053 | count += handle_one_xevent (dpyinfo, &event, &finish, hold_quit); | 7056 | count += handle_one_xevent (terminal->display_info.x, |
| 7057 | &event, &finish, hold_quit); | ||
| 7054 | 7058 | ||
| 7055 | if (finish == X_EVENT_GOTO_OUT) | 7059 | if (finish == X_EVENT_GOTO_OUT) |
| 7056 | goto out; | 7060 | goto out; |
| 7057 | } | ||
| 7058 | #endif /* not USE_GTK */ | ||
| 7059 | } | 7061 | } |
| 7060 | 7062 | ||
| 7061 | #ifdef USE_GTK | 7063 | #else /* USE_GTK */ |
| 7062 | 7064 | ||
| 7063 | /* For GTK we must use the GTK event loop. But XEvents gets passed | 7065 | /* For GTK we must use the GTK event loop. But XEvents gets passed |
| 7064 | to our filter function above, and then to the big event switch. | 7066 | to our filter function above, and then to the big event switch. |
| @@ -10680,7 +10682,7 @@ x_term_init (display_name, xrm_option, resource_name) | |||
| 10680 | return dpyinfo; | 10682 | return dpyinfo; |
| 10681 | } | 10683 | } |
| 10682 | 10684 | ||
| 10683 | /* Get rid of display DPYINFO, assuming all frames are already gone, | 10685 | /* Get rid of display DPYINFO, deleting all frames on it, |
| 10684 | and without sending any more commands to the X server. */ | 10686 | and without sending any more commands to the X server. */ |
| 10685 | 10687 | ||
| 10686 | void | 10688 | void |
| @@ -10690,11 +10692,12 @@ x_delete_display (dpyinfo) | |||
| 10690 | int i; | 10692 | int i; |
| 10691 | struct terminal *t; | 10693 | struct terminal *t; |
| 10692 | 10694 | ||
| 10693 | /* Delete the generic struct terminal for this X display. */ | 10695 | /* Close all frames and delete the generic struct terminal for this |
| 10696 | X display. */ | ||
| 10694 | for (t = terminal_list; t; t = t->next_terminal) | 10697 | for (t = terminal_list; t; t = t->next_terminal) |
| 10695 | if (t->type == output_x_window && t->display_info.x == dpyinfo) | 10698 | if (t->type == output_x_window && t->display_info.x == dpyinfo) |
| 10696 | { | 10699 | { |
| 10697 | /* Close X session management when we close its display. */ | 10700 | /* Close X session management when we close its display. */ |
| 10698 | if (t->id == 1 && x_session_have_connection ()) | 10701 | if (t->id == 1 && x_session_have_connection ()) |
| 10699 | x_session_close(); | 10702 | x_session_close(); |
| 10700 | 10703 | ||
| @@ -10837,24 +10840,11 @@ x_delete_terminal (struct terminal *terminal) | |||
| 10837 | { | 10840 | { |
| 10838 | struct x_display_info *dpyinfo = terminal->display_info.x; | 10841 | struct x_display_info *dpyinfo = terminal->display_info.x; |
| 10839 | int i; | 10842 | int i; |
| 10840 | Lisp_Object tail, frame; | ||
| 10841 | 10843 | ||
| 10842 | /* Protect against recursive calls. Fdelete_frame calls us back | 10844 | /* Protect against recursive calls. Fdelete_frame in |
| 10843 | when we delete our last frame. */ | 10845 | delete_terminal calls us back when it deletes our last frame. */ |
| 10844 | if (terminal->deleted) | 10846 | if (terminal->deleted) |
| 10845 | return; | 10847 | return; |
| 10846 | terminal->deleted = 1; | ||
| 10847 | |||
| 10848 | /* Check for and close live frames that are still on this | ||
| 10849 | terminal. */ | ||
| 10850 | FOR_EACH_FRAME (tail, frame) | ||
| 10851 | { | ||
| 10852 | struct frame *f = XFRAME (frame); | ||
| 10853 | if (FRAME_LIVE_P (f) && f->terminal == terminal) | ||
| 10854 | { | ||
| 10855 | Fdelete_frame (frame, Qt); | ||
| 10856 | } | ||
| 10857 | } | ||
| 10858 | 10848 | ||
| 10859 | BLOCK_INPUT; | 10849 | BLOCK_INPUT; |
| 10860 | /* Free the fonts in the font table. */ | 10850 | /* Free the fonts in the font table. */ |
diff --git a/src/xterm.h b/src/xterm.h index 5f37a23448c..b54c39f2fd0 100644 --- a/src/xterm.h +++ b/src/xterm.h | |||
| @@ -149,6 +149,9 @@ struct x_display_info | |||
| 149 | /* Chain of all x_display_info structures. */ | 149 | /* Chain of all x_display_info structures. */ |
| 150 | struct x_display_info *next; | 150 | struct x_display_info *next; |
| 151 | 151 | ||
| 152 | /* The generic display parameters corresponding to this X display. */ | ||
| 153 | struct terminal *terminal; | ||
| 154 | |||
| 152 | /* Connection number (normally a file descriptor number). */ | 155 | /* Connection number (normally a file descriptor number). */ |
| 153 | int connection; | 156 | int connection; |
| 154 | 157 | ||
| @@ -386,9 +389,6 @@ struct x_display_info | |||
| 386 | X_WMTYPE_A, | 389 | X_WMTYPE_A, |
| 387 | X_WMTYPE_B | 390 | X_WMTYPE_B |
| 388 | } wm_type; | 391 | } wm_type; |
| 389 | |||
| 390 | /* The generic display parameters corresponding to this X display. */ | ||
| 391 | struct terminal *terminal; | ||
| 392 | }; | 392 | }; |
| 393 | 393 | ||
| 394 | #ifdef HAVE_X_I18N | 394 | #ifdef HAVE_X_I18N |