From e4a92752ad38859db378dd0c3011c1994494009c Mon Sep 17 00:00:00 2001 From: Karoly Lorentey Date: Sun, 27 Mar 2005 18:53:41 +0000 Subject: [PATCH] Fix some aspects of X display shutdown. * src/xterm.c (x_delete_frame_display): Call xg_display_close under GTK. (x_connection_closed): Don't close the display before its frames are deleted. Protect against the last frame calling the display delete hook. git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-320 --- src/xterm.c | 83 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 32 deletions(-) diff --git a/src/xterm.c b/src/xterm.c index c64a73d8aa6..0c1f7ddab74 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -7677,6 +7677,44 @@ x_connection_closed (dpy, error_message) the original message here. */ count = 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->frame_display->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 @@ -7709,42 +7747,19 @@ x_connection_closed (dpy, error_message) xg_display_close (dpyinfo->display); #endif - /* Indicate that this display is dead. */ if (dpyinfo) - dpyinfo->display = 0; - - /* Inhibit redisplay while frames are being deleted. */ - specbind (Qinhibit_redisplay, Qt); - - /* 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->frame_display->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 (dpy, count); @@ -10782,8 +10797,12 @@ x_delete_frame_display (struct display *display) #ifdef USE_X_TOOLKIT XtCloseDisplay (dpyinfo->display); +#else +#ifdef USE_GTK + xg_display_close (dpyinfo->display); #else XCloseDisplay (dpyinfo->display); +#endif #endif x_delete_display (dpyinfo); -- 2.39.5