diff options
Diffstat (limited to 'src/xterm.c')
| -rw-r--r-- | src/xterm.c | 537 |
1 files changed, 332 insertions, 205 deletions
diff --git a/src/xterm.c b/src/xterm.c index 4f77e22ac59..8b0078d6af6 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -54,7 +54,6 @@ Boston, MA 02110-1301, USA. */ | |||
| 54 | #include <sys/ioctl.h> | 54 | #include <sys/ioctl.h> |
| 55 | #endif /* ! defined (BSD_SYSTEM) */ | 55 | #endif /* ! defined (BSD_SYSTEM) */ |
| 56 | 56 | ||
| 57 | #include "systty.h" | ||
| 58 | #include "systime.h" | 57 | #include "systime.h" |
| 59 | 58 | ||
| 60 | #ifndef INCLUDED_FCNTL | 59 | #ifndef INCLUDED_FCNTL |
| @@ -322,6 +321,10 @@ static Lisp_Object Qalt, Qhyper, Qmeta, Qsuper, Qmodifier_value; | |||
| 322 | static Lisp_Object Qvendor_specific_keysyms; | 321 | static Lisp_Object Qvendor_specific_keysyms; |
| 323 | static Lisp_Object Qlatin_1; | 322 | static Lisp_Object Qlatin_1; |
| 324 | 323 | ||
| 324 | /* Used in x_flush. */ | ||
| 325 | |||
| 326 | extern Lisp_Object Vinhibit_redisplay; | ||
| 327 | |||
| 325 | extern XrmDatabase x_load_resources P_ ((Display *, char *, char *, char *)); | 328 | extern XrmDatabase x_load_resources P_ ((Display *, char *, char *, char *)); |
| 326 | extern int x_bitmap_mask P_ ((FRAME_PTR, int)); | 329 | extern int x_bitmap_mask P_ ((FRAME_PTR, int)); |
| 327 | 330 | ||
| @@ -331,13 +334,15 @@ static const XColor *x_color_cells P_ ((Display *, int *)); | |||
| 331 | static void x_update_window_end P_ ((struct window *, int, int)); | 334 | static void x_update_window_end P_ ((struct window *, int, int)); |
| 332 | 335 | ||
| 333 | static int x_io_error_quitter P_ ((Display *)); | 336 | static int x_io_error_quitter P_ ((Display *)); |
| 337 | static struct terminal *x_create_terminal P_ ((struct x_display_info *)); | ||
| 338 | void x_delete_terminal P_ ((struct terminal *)); | ||
| 334 | static void x_font_min_bounds P_ ((XFontStruct *, int *, int *)); | 339 | static void x_font_min_bounds P_ ((XFontStruct *, int *, int *)); |
| 335 | static int x_compute_min_glyph_bounds P_ ((struct frame *)); | 340 | static int x_compute_min_glyph_bounds P_ ((struct frame *)); |
| 336 | static void x_update_end P_ ((struct frame *)); | 341 | static void x_update_end P_ ((struct frame *)); |
| 337 | static void XTframe_up_to_date P_ ((struct frame *)); | 342 | static void XTframe_up_to_date P_ ((struct frame *)); |
| 338 | static void XTset_terminal_modes P_ ((void)); | 343 | static void XTset_terminal_modes P_ ((struct terminal *)); |
| 339 | static void XTreset_terminal_modes P_ ((void)); | 344 | static void XTreset_terminal_modes P_ ((struct terminal *)); |
| 340 | static void x_clear_frame P_ ((void)); | 345 | static void x_clear_frame P_ ((struct frame *)); |
| 341 | static void frame_highlight P_ ((struct frame *)); | 346 | static void frame_highlight P_ ((struct frame *)); |
| 342 | static void frame_unhighlight P_ ((struct frame *)); | 347 | static void frame_unhighlight P_ ((struct frame *)); |
| 343 | static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *)); | 348 | static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *)); |
| @@ -375,12 +380,18 @@ static void | |||
| 375 | x_flush (f) | 380 | x_flush (f) |
| 376 | struct frame *f; | 381 | struct frame *f; |
| 377 | { | 382 | { |
| 383 | /* Don't call XFlush when it is not safe to redisplay; the X | ||
| 384 | connection may be broken. */ | ||
| 385 | if (!NILP (Vinhibit_redisplay)) | ||
| 386 | return; | ||
| 387 | |||
| 378 | BLOCK_INPUT; | 388 | BLOCK_INPUT; |
| 379 | if (f == NULL) | 389 | if (f == NULL) |
| 380 | { | 390 | { |
| 381 | Lisp_Object rest, frame; | 391 | Lisp_Object rest, frame; |
| 382 | FOR_EACH_FRAME (rest, frame) | 392 | FOR_EACH_FRAME (rest, frame) |
| 383 | x_flush (XFRAME (frame)); | 393 | if (FRAME_X_P (XFRAME (frame))) |
| 394 | x_flush (XFRAME (frame)); | ||
| 384 | } | 395 | } |
| 385 | else if (FRAME_X_P (f)) | 396 | else if (FRAME_X_P (f)) |
| 386 | XFlush (FRAME_X_DISPLAY (f)); | 397 | XFlush (FRAME_X_DISPLAY (f)); |
| @@ -792,7 +803,7 @@ x_draw_fringe_bitmap (w, row, p) | |||
| 792 | rarely happens). */ | 803 | rarely happens). */ |
| 793 | 804 | ||
| 794 | static void | 805 | static void |
| 795 | XTset_terminal_modes () | 806 | XTset_terminal_modes (struct terminal *terminal) |
| 796 | { | 807 | { |
| 797 | } | 808 | } |
| 798 | 809 | ||
| @@ -800,7 +811,7 @@ XTset_terminal_modes () | |||
| 800 | the X-windows go away, and suspending requires no action. */ | 811 | the X-windows go away, and suspending requires no action. */ |
| 801 | 812 | ||
| 802 | static void | 813 | static void |
| 803 | XTreset_terminal_modes () | 814 | XTreset_terminal_modes (struct terminal *terminal) |
| 804 | { | 815 | { |
| 805 | } | 816 | } |
| 806 | 817 | ||
| @@ -1413,7 +1424,8 @@ x_frame_of_widget (widget) | |||
| 1413 | for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail)) | 1424 | for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail)) |
| 1414 | if (GC_FRAMEP (XCAR (tail)) | 1425 | if (GC_FRAMEP (XCAR (tail)) |
| 1415 | && (f = XFRAME (XCAR (tail)), | 1426 | && (f = XFRAME (XCAR (tail)), |
| 1416 | (f->output_data.nothing != 1 | 1427 | (FRAME_X_P (f) |
| 1428 | && f->output_data.nothing != 1 | ||
| 1417 | && FRAME_X_DISPLAY_INFO (f) == dpyinfo)) | 1429 | && FRAME_X_DISPLAY_INFO (f) == dpyinfo)) |
| 1418 | && f->output_data.x->widget == widget) | 1430 | && f->output_data.x->widget == widget) |
| 1419 | return f; | 1431 | return f; |
| @@ -2790,7 +2802,8 @@ x_shift_glyphs_for_insert (f, x, y, width, height, shift_by) | |||
| 2790 | for X frames. */ | 2802 | for X frames. */ |
| 2791 | 2803 | ||
| 2792 | static void | 2804 | static void |
| 2793 | x_delete_glyphs (n) | 2805 | x_delete_glyphs (f, n) |
| 2806 | struct frame *f; | ||
| 2794 | register int n; | 2807 | register int n; |
| 2795 | { | 2808 | { |
| 2796 | abort (); | 2809 | abort (); |
| @@ -2813,19 +2826,11 @@ x_clear_area (dpy, window, x, y, width, height, exposures) | |||
| 2813 | } | 2826 | } |
| 2814 | 2827 | ||
| 2815 | 2828 | ||
| 2816 | /* Clear entire frame. If updating_frame is non-null, clear that | 2829 | /* Clear an entire frame. */ |
| 2817 | frame. Otherwise clear the selected frame. */ | ||
| 2818 | 2830 | ||
| 2819 | static void | 2831 | static void |
| 2820 | x_clear_frame () | 2832 | x_clear_frame (struct frame *f) |
| 2821 | { | 2833 | { |
| 2822 | struct frame *f; | ||
| 2823 | |||
| 2824 | if (updating_frame) | ||
| 2825 | f = updating_frame; | ||
| 2826 | else | ||
| 2827 | f = SELECTED_FRAME (); | ||
| 2828 | |||
| 2829 | /* Clearing the frame will erase any cursor, so mark them all as no | 2834 | /* Clearing the frame will erase any cursor, so mark them all as no |
| 2830 | longer visible. */ | 2835 | longer visible. */ |
| 2831 | mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f))); | 2836 | mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f))); |
| @@ -2904,8 +2909,8 @@ XTflash (f) | |||
| 2904 | XGCValues values; | 2909 | XGCValues values; |
| 2905 | 2910 | ||
| 2906 | values.function = GXxor; | 2911 | values.function = GXxor; |
| 2907 | values.foreground = (f->output_data.x->foreground_pixel | 2912 | values.foreground = (FRAME_FOREGROUND_PIXEL (f) |
| 2908 | ^ f->output_data.x->background_pixel); | 2913 | ^ FRAME_BACKGROUND_PIXEL (f)); |
| 2909 | 2914 | ||
| 2910 | gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 2915 | gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 2911 | GCFunction | GCForeground, &values); | 2916 | GCFunction | GCForeground, &values); |
| @@ -3071,7 +3076,8 @@ XTset_terminal_window (n) | |||
| 3071 | lines or deleting -N lines at vertical position VPOS. */ | 3076 | lines or deleting -N lines at vertical position VPOS. */ |
| 3072 | 3077 | ||
| 3073 | static void | 3078 | static void |
| 3074 | x_ins_del_lines (vpos, n) | 3079 | x_ins_del_lines (f, vpos, n) |
| 3080 | struct frame *f; | ||
| 3075 | int vpos, n; | 3081 | int vpos, n; |
| 3076 | { | 3082 | { |
| 3077 | abort (); | 3083 | abort (); |
| @@ -3708,7 +3714,8 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time) | |||
| 3708 | 3714 | ||
| 3709 | /* Clear the mouse-moved flag for every frame on this display. */ | 3715 | /* Clear the mouse-moved flag for every frame on this display. */ |
| 3710 | FOR_EACH_FRAME (tail, frame) | 3716 | FOR_EACH_FRAME (tail, frame) |
| 3711 | if (FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp)) | 3717 | if (FRAME_X_P (XFRAME (frame)) |
| 3718 | && FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp)) | ||
| 3712 | XFRAME (frame)->mouse_moved = 0; | 3719 | XFRAME (frame)->mouse_moved = 0; |
| 3713 | 3720 | ||
| 3714 | last_mouse_scroll_bar = Qnil; | 3721 | last_mouse_scroll_bar = Qnil; |
| @@ -3897,6 +3904,9 @@ x_window_to_scroll_bar (display, window_id) | |||
| 3897 | if (! GC_FRAMEP (frame)) | 3904 | if (! GC_FRAMEP (frame)) |
| 3898 | abort (); | 3905 | abort (); |
| 3899 | 3906 | ||
| 3907 | if (! FRAME_X_P (XFRAME (frame))) | ||
| 3908 | continue; | ||
| 3909 | |||
| 3900 | /* Scan this frame's scroll bar list for a scroll bar with the | 3910 | /* Scan this frame's scroll bar list for a scroll bar with the |
| 3901 | right window ID. */ | 3911 | right window ID. */ |
| 3902 | condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame)); | 3912 | condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame)); |
| @@ -3931,11 +3941,14 @@ x_window_to_menu_bar (window) | |||
| 3931 | XGCTYPE (tail) == Lisp_Cons; | 3941 | XGCTYPE (tail) == Lisp_Cons; |
| 3932 | tail = XCDR (tail)) | 3942 | tail = XCDR (tail)) |
| 3933 | { | 3943 | { |
| 3934 | Lisp_Object frame = XCAR (tail); | 3944 | if (FRAME_X_P (XFRAME (XCAR (tail)))) |
| 3935 | Widget menu_bar = XFRAME (frame)->output_data.x->menubar_widget; | 3945 | { |
| 3946 | Lisp_Object frame = XCAR (tail); | ||
| 3947 | Widget menu_bar = XFRAME (frame)->output_data.x->menubar_widget; | ||
| 3936 | 3948 | ||
| 3937 | if (menu_bar && xlwmenu_window_p (menu_bar, window)) | 3949 | if (menu_bar && xlwmenu_window_p (menu_bar, window)) |
| 3938 | return menu_bar; | 3950 | return menu_bar; |
| 3951 | } | ||
| 3939 | } | 3952 | } |
| 3940 | 3953 | ||
| 3941 | return NULL; | 3954 | return NULL; |
| @@ -4743,7 +4756,7 @@ x_scroll_bar_create (w, top, left, width, height) | |||
| 4743 | 4756 | ||
| 4744 | a.background_pixel = f->output_data.x->scroll_bar_background_pixel; | 4757 | a.background_pixel = f->output_data.x->scroll_bar_background_pixel; |
| 4745 | if (a.background_pixel == -1) | 4758 | if (a.background_pixel == -1) |
| 4746 | a.background_pixel = f->output_data.x->background_pixel; | 4759 | a.background_pixel = FRAME_BACKGROUND_PIXEL (f); |
| 4747 | 4760 | ||
| 4748 | a.event_mask = (ButtonPressMask | ButtonReleaseMask | 4761 | a.event_mask = (ButtonPressMask | ButtonReleaseMask |
| 4749 | | ButtonMotionMask | PointerMotionHintMask | 4762 | | ButtonMotionMask | PointerMotionHintMask |
| @@ -4917,7 +4930,7 @@ x_scroll_bar_set_handle (bar, start, end, rebuild) | |||
| 4917 | /* Restore the foreground color of the GC if we changed it above. */ | 4930 | /* Restore the foreground color of the GC if we changed it above. */ |
| 4918 | if (f->output_data.x->scroll_bar_foreground_pixel != -1) | 4931 | if (f->output_data.x->scroll_bar_foreground_pixel != -1) |
| 4919 | XSetForeground (FRAME_X_DISPLAY (f), gc, | 4932 | XSetForeground (FRAME_X_DISPLAY (f), gc, |
| 4920 | f->output_data.x->foreground_pixel); | 4933 | FRAME_FOREGROUND_PIXEL (f)); |
| 4921 | 4934 | ||
| 4922 | /* Draw the empty space below the handle. Note that we can't | 4935 | /* Draw the empty space below the handle. Note that we can't |
| 4923 | clear zero-height areas; that means "clear to end of window." */ | 4936 | clear zero-height areas; that means "clear to end of window." */ |
| @@ -5295,7 +5308,7 @@ x_scroll_bar_expose (bar, event) | |||
| 5295 | /* Restore the foreground color of the GC if we changed it above. */ | 5308 | /* Restore the foreground color of the GC if we changed it above. */ |
| 5296 | if (f->output_data.x->scroll_bar_foreground_pixel != -1) | 5309 | if (f->output_data.x->scroll_bar_foreground_pixel != -1) |
| 5297 | XSetForeground (FRAME_X_DISPLAY (f), gc, | 5310 | XSetForeground (FRAME_X_DISPLAY (f), gc, |
| 5298 | f->output_data.x->foreground_pixel); | 5311 | FRAME_FOREGROUND_PIXEL (f)); |
| 5299 | 5312 | ||
| 5300 | UNBLOCK_INPUT; | 5313 | UNBLOCK_INPUT; |
| 5301 | 5314 | ||
| @@ -5695,7 +5708,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 5695 | int count = 0; | 5708 | int count = 0; |
| 5696 | int do_help = 0; | 5709 | int do_help = 0; |
| 5697 | int nbytes = 0; | 5710 | int nbytes = 0; |
| 5698 | struct frame *f; | 5711 | struct frame *f = NULL; |
| 5699 | struct coding_system coding; | 5712 | struct coding_system coding; |
| 5700 | XEvent event = *eventp; | 5713 | XEvent event = *eventp; |
| 5701 | 5714 | ||
| @@ -6271,19 +6284,19 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 6271 | bzero (&compose_status, sizeof (compose_status)); | 6284 | bzero (&compose_status, sizeof (compose_status)); |
| 6272 | orig_keysym = keysym; | 6285 | orig_keysym = keysym; |
| 6273 | 6286 | ||
| 6274 | /* Common for all keysym input events. */ | 6287 | /* Common for all keysym input events. */ |
| 6275 | XSETFRAME (inev.ie.frame_or_window, f); | 6288 | XSETFRAME (inev.ie.frame_or_window, f); |
| 6276 | inev.ie.modifiers | 6289 | inev.ie.modifiers |
| 6277 | = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), modifiers); | 6290 | = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), modifiers); |
| 6278 | inev.ie.timestamp = event.xkey.time; | 6291 | inev.ie.timestamp = event.xkey.time; |
| 6279 | 6292 | ||
| 6280 | /* First deal with keysyms which have defined | 6293 | /* First deal with keysyms which have defined |
| 6281 | translations to characters. */ | 6294 | translations to characters. */ |
| 6282 | if (keysym >= 32 && keysym < 128) | 6295 | if (keysym >= 32 && keysym < 128) |
| 6283 | /* Avoid explicitly decoding each ASCII character. */ | 6296 | /* Avoid explicitly decoding each ASCII character. */ |
| 6284 | { | 6297 | { |
| 6285 | inev.ie.kind = ASCII_KEYSTROKE_EVENT; | 6298 | inev.ie.kind = ASCII_KEYSTROKE_EVENT; |
| 6286 | inev.ie.code = keysym; | 6299 | inev.ie.code = keysym; |
| 6287 | goto done_keysym; | 6300 | goto done_keysym; |
| 6288 | } | 6301 | } |
| 6289 | 6302 | ||
| @@ -6328,18 +6341,18 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 6328 | /* Now non-ASCII. */ | 6341 | /* Now non-ASCII. */ |
| 6329 | if (HASH_TABLE_P (Vx_keysym_table) | 6342 | if (HASH_TABLE_P (Vx_keysym_table) |
| 6330 | && (NATNUMP (c = Fgethash (make_number (keysym), | 6343 | && (NATNUMP (c = Fgethash (make_number (keysym), |
| 6331 | Vx_keysym_table, | 6344 | Vx_keysym_table, |
| 6332 | Qnil)))) | 6345 | Qnil)))) |
| 6333 | { | 6346 | { |
| 6334 | inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c)) | 6347 | inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c)) |
| 6335 | ? ASCII_KEYSTROKE_EVENT | 6348 | ? ASCII_KEYSTROKE_EVENT |
| 6336 | : MULTIBYTE_CHAR_KEYSTROKE_EVENT); | 6349 | : MULTIBYTE_CHAR_KEYSTROKE_EVENT); |
| 6337 | inev.ie.code = XFASTINT (c); | 6350 | inev.ie.code = XFASTINT (c); |
| 6338 | goto done_keysym; | 6351 | goto done_keysym; |
| 6339 | } | 6352 | } |
| 6340 | 6353 | ||
| 6341 | /* Random non-modifier sorts of keysyms. */ | 6354 | /* Random non-modifier sorts of keysyms. */ |
| 6342 | if (((keysym >= XK_BackSpace && keysym <= XK_Escape) | 6355 | if (((keysym >= XK_BackSpace && keysym <= XK_Escape) |
| 6343 | || keysym == XK_Delete | 6356 | || keysym == XK_Delete |
| 6344 | #ifdef XK_ISO_Left_Tab | 6357 | #ifdef XK_ISO_Left_Tab |
| 6345 | || (keysym >= XK_ISO_Left_Tab | 6358 | || (keysym >= XK_ISO_Left_Tab |
| @@ -6987,8 +7000,8 @@ x_dispatch_event (event, display) | |||
| 6987 | EXPECTED is nonzero if the caller knows input is available. */ | 7000 | EXPECTED is nonzero if the caller knows input is available. */ |
| 6988 | 7001 | ||
| 6989 | static int | 7002 | static int |
| 6990 | XTread_socket (sd, expected, hold_quit) | 7003 | XTread_socket (terminal, expected, hold_quit) |
| 6991 | register int sd; | 7004 | struct terminal *terminal; |
| 6992 | int expected; | 7005 | int expected; |
| 6993 | struct input_event *hold_quit; | 7006 | struct input_event *hold_quit; |
| 6994 | { | 7007 | { |
| @@ -7011,6 +7024,31 @@ XTread_socket (sd, expected, hold_quit) | |||
| 7011 | 7024 | ||
| 7012 | ++handling_signal; | 7025 | ++handling_signal; |
| 7013 | 7026 | ||
| 7027 | #ifdef HAVE_X_SM | ||
| 7028 | /* Only check session manager input for the primary display. */ | ||
| 7029 | if (terminal->id == 1 && x_session_have_connection ()) | ||
| 7030 | { | ||
| 7031 | struct input_event inev; | ||
| 7032 | BLOCK_INPUT; | ||
| 7033 | /* We don't need to EVENT_INIT (inev) here, as | ||
| 7034 | x_session_check_input copies an entire input_event. */ | ||
| 7035 | if (x_session_check_input (&inev)) | ||
| 7036 | { | ||
| 7037 | kbd_buffer_store_event_hold (&inev, hold_quit); | ||
| 7038 | count++; | ||
| 7039 | } | ||
| 7040 | UNBLOCK_INPUT; | ||
| 7041 | } | ||
| 7042 | #endif | ||
| 7043 | |||
| 7044 | /* For debugging, this gives a way to fake an I/O error. */ | ||
| 7045 | if (terminal->display_info.x == XTread_socket_fake_io_error) | ||
| 7046 | { | ||
| 7047 | XTread_socket_fake_io_error = 0; | ||
| 7048 | x_io_error_quitter (dpyinfo->display); | ||
| 7049 | } | ||
| 7050 | |||
| 7051 | #if 0 /* This loop is a noop now. */ | ||
| 7014 | /* Find the display we are supposed to read input for. | 7052 | /* Find the display we are supposed to read input for. |
| 7015 | It's the one communicating on descriptor SD. */ | 7053 | It's the one communicating on descriptor SD. */ |
| 7016 | for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next) | 7054 | for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next) |
| @@ -7041,52 +7079,31 @@ XTread_socket (sd, expected, hold_quit) | |||
| 7041 | #endif /* HAVE_SELECT */ | 7079 | #endif /* HAVE_SELECT */ |
| 7042 | #endif /* SIGIO */ | 7080 | #endif /* SIGIO */ |
| 7043 | #endif | 7081 | #endif |
| 7044 | 7082 | } | |
| 7045 | /* For debugging, this gives a way to fake an I/O error. */ | ||
| 7046 | if (dpyinfo == XTread_socket_fake_io_error) | ||
| 7047 | { | ||
| 7048 | XTread_socket_fake_io_error = 0; | ||
| 7049 | x_io_error_quitter (dpyinfo->display); | ||
| 7050 | } | ||
| 7051 | |||
| 7052 | #ifdef HAVE_X_SM | ||
| 7053 | { | ||
| 7054 | struct input_event inev; | ||
| 7055 | BLOCK_INPUT; | ||
| 7056 | /* We don't need to EVENT_INIT (inev) here, as | ||
| 7057 | x_session_check_input copies an entire input_event. */ | ||
| 7058 | if (x_session_check_input (&inev)) | ||
| 7059 | { | ||
| 7060 | kbd_buffer_store_event_hold (&inev, hold_quit); | ||
| 7061 | count++; | ||
| 7062 | } | ||
| 7063 | UNBLOCK_INPUT; | ||
| 7064 | } | ||
| 7065 | #endif | 7083 | #endif |
| 7066 | 7084 | ||
| 7067 | #ifndef USE_GTK | 7085 | #ifndef USE_GTK |
| 7068 | while (XPending (dpyinfo->display)) | 7086 | while (XPending (terminal->display_info.x->display)) |
| 7069 | { | 7087 | { |
| 7070 | int finish; | 7088 | int finish; |
| 7071 | 7089 | ||
| 7072 | XNextEvent (dpyinfo->display, &event); | 7090 | XNextEvent (terminal->display_info.x->display, &event); |
| 7073 | 7091 | ||
| 7074 | #ifdef HAVE_X_I18N | 7092 | #ifdef HAVE_X_I18N |
| 7075 | /* Filter events for the current X input method. */ | 7093 | /* Filter events for the current X input method. */ |
| 7076 | if (x_filter_event (dpyinfo, &event)) | 7094 | if (x_filter_event (terminal->display_info.x, &event)) |
| 7077 | break; | 7095 | break; |
| 7078 | #endif | 7096 | #endif |
| 7079 | event_found = 1; | 7097 | event_found = 1; |
| 7080 | 7098 | ||
| 7081 | count += handle_one_xevent (dpyinfo, &event, &finish, hold_quit); | 7099 | count += handle_one_xevent (terminal->display_info.x, |
| 7100 | &event, &finish, hold_quit); | ||
| 7082 | 7101 | ||
| 7083 | if (finish == X_EVENT_GOTO_OUT) | 7102 | if (finish == X_EVENT_GOTO_OUT) |
| 7084 | goto out; | 7103 | goto out; |
| 7085 | } | ||
| 7086 | #endif /* not USE_GTK */ | ||
| 7087 | } | 7104 | } |
| 7088 | 7105 | ||
| 7089 | #ifdef USE_GTK | 7106 | #else /* USE_GTK */ |
| 7090 | 7107 | ||
| 7091 | /* For GTK we must use the GTK event loop. But XEvents gets passed | 7108 | /* For GTK we must use the GTK event loop. But XEvents gets passed |
| 7092 | to our filter function above, and then to the big event switch. | 7109 | to our filter function above, and then to the big event switch. |
| @@ -7397,8 +7414,7 @@ x_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, activ | |||
| 7397 | } | 7414 | } |
| 7398 | 7415 | ||
| 7399 | #ifndef XFlush | 7416 | #ifndef XFlush |
| 7400 | if (updating_frame != f) | 7417 | XFlush (FRAME_X_DISPLAY (f)); |
| 7401 | XFlush (FRAME_X_DISPLAY (f)); | ||
| 7402 | #endif | 7418 | #endif |
| 7403 | } | 7419 | } |
| 7404 | 7420 | ||
| @@ -7636,6 +7652,8 @@ x_clear_errors (dpy) | |||
| 7636 | x_error_message->string[0] = 0; | 7652 | x_error_message->string[0] = 0; |
| 7637 | } | 7653 | } |
| 7638 | 7654 | ||
| 7655 | #if 0 /* See comment in unwind_to_catch why calling this is a bad | ||
| 7656 | * idea. --lorentey */ | ||
| 7639 | /* Close off all unclosed x_catch_errors calls. */ | 7657 | /* Close off all unclosed x_catch_errors calls. */ |
| 7640 | 7658 | ||
| 7641 | void | 7659 | void |
| @@ -7644,6 +7662,7 @@ x_fully_uncatch_errors () | |||
| 7644 | while (x_error_message) | 7662 | while (x_error_message) |
| 7645 | x_uncatch_errors (); | 7663 | x_uncatch_errors (); |
| 7646 | } | 7664 | } |
| 7665 | #endif | ||
| 7647 | 7666 | ||
| 7648 | /* Nonzero if x_catch_errors has been done and not yet canceled. */ | 7667 | /* Nonzero if x_catch_errors has been done and not yet canceled. */ |
| 7649 | 7668 | ||
| @@ -7709,6 +7728,7 @@ x_connection_closed (dpy, error_message) | |||
| 7709 | { | 7728 | { |
| 7710 | struct x_display_info *dpyinfo = x_display_info_for_display (dpy); | 7729 | struct x_display_info *dpyinfo = x_display_info_for_display (dpy); |
| 7711 | Lisp_Object frame, tail; | 7730 | Lisp_Object frame, tail; |
| 7731 | int index = SPECPDL_INDEX (); | ||
| 7712 | 7732 | ||
| 7713 | error_msg = (char *) alloca (strlen (error_message) + 1); | 7733 | error_msg = (char *) alloca (strlen (error_message) + 1); |
| 7714 | strcpy (error_msg, error_message); | 7734 | strcpy (error_msg, error_message); |
| @@ -7720,6 +7740,44 @@ x_connection_closed (dpy, error_message) | |||
| 7720 | the original message here. */ | 7740 | the original message here. */ |
| 7721 | x_catch_errors (dpy); | 7741 | x_catch_errors (dpy); |
| 7722 | 7742 | ||
| 7743 | /* Inhibit redisplay while frames are being deleted. */ | ||
| 7744 | specbind (Qinhibit_redisplay, Qt); | ||
| 7745 | |||
| 7746 | if (dpyinfo) | ||
| 7747 | { | ||
| 7748 | /* Protect display from being closed when we delete the last | ||
| 7749 | frame on it. */ | ||
| 7750 | dpyinfo->reference_count++; | ||
| 7751 | dpyinfo->terminal->reference_count++; | ||
| 7752 | } | ||
| 7753 | |||
| 7754 | /* First delete frames whose mini-buffers are on frames | ||
| 7755 | that are on the dead display. */ | ||
| 7756 | FOR_EACH_FRAME (tail, frame) | ||
| 7757 | { | ||
| 7758 | Lisp_Object minibuf_frame; | ||
| 7759 | minibuf_frame | ||
| 7760 | = WINDOW_FRAME (XWINDOW (FRAME_MINIBUF_WINDOW (XFRAME (frame)))); | ||
| 7761 | if (FRAME_X_P (XFRAME (frame)) | ||
| 7762 | && FRAME_X_P (XFRAME (minibuf_frame)) | ||
| 7763 | && ! EQ (frame, minibuf_frame) | ||
| 7764 | && FRAME_X_DISPLAY_INFO (XFRAME (minibuf_frame)) == dpyinfo) | ||
| 7765 | Fdelete_frame (frame, Qt); | ||
| 7766 | } | ||
| 7767 | |||
| 7768 | /* Now delete all remaining frames on the dead display. | ||
| 7769 | We are now sure none of these is used as the mini-buffer | ||
| 7770 | for another frame that we need to delete. */ | ||
| 7771 | FOR_EACH_FRAME (tail, frame) | ||
| 7772 | if (FRAME_X_P (XFRAME (frame)) | ||
| 7773 | && FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo) | ||
| 7774 | { | ||
| 7775 | /* Set this to t so that Fdelete_frame won't get confused | ||
| 7776 | trying to find a replacement. */ | ||
| 7777 | FRAME_KBOARD (XFRAME (frame))->Vdefault_minibuffer_frame = Qt; | ||
| 7778 | Fdelete_frame (frame, Qt); | ||
| 7779 | } | ||
| 7780 | |||
| 7723 | /* We have to close the display to inform Xt that it doesn't | 7781 | /* We have to close the display to inform Xt that it doesn't |
| 7724 | exist anymore. If we don't, Xt will continue to wait for | 7782 | exist anymore. If we don't, Xt will continue to wait for |
| 7725 | events from the display. As a consequence, a sequence of | 7783 | events from the display. As a consequence, a sequence of |
| @@ -7752,43 +7810,23 @@ x_connection_closed (dpy, error_message) | |||
| 7752 | xg_display_close (dpyinfo->display); | 7810 | xg_display_close (dpyinfo->display); |
| 7753 | #endif | 7811 | #endif |
| 7754 | 7812 | ||
| 7755 | /* Indicate that this display is dead. */ | ||
| 7756 | if (dpyinfo) | 7813 | if (dpyinfo) |
| 7757 | dpyinfo->display = 0; | ||
| 7758 | |||
| 7759 | /* First delete frames whose mini-buffers are on frames | ||
| 7760 | that are on the dead display. */ | ||
| 7761 | FOR_EACH_FRAME (tail, frame) | ||
| 7762 | { | 7814 | { |
| 7763 | Lisp_Object minibuf_frame; | 7815 | /* Indicate that this display is dead. */ |
| 7764 | minibuf_frame | 7816 | dpyinfo->display = 0; |
| 7765 | = WINDOW_FRAME (XWINDOW (FRAME_MINIBUF_WINDOW (XFRAME (frame)))); | ||
| 7766 | if (FRAME_X_P (XFRAME (frame)) | ||
| 7767 | && FRAME_X_P (XFRAME (minibuf_frame)) | ||
| 7768 | && ! EQ (frame, minibuf_frame) | ||
| 7769 | && FRAME_X_DISPLAY_INFO (XFRAME (minibuf_frame)) == dpyinfo) | ||
| 7770 | Fdelete_frame (frame, Qt); | ||
| 7771 | } | ||
| 7772 | 7817 | ||
| 7773 | /* Now delete all remaining frames on the dead display. | 7818 | dpyinfo->reference_count--; |
| 7774 | We are now sure none of these is used as the mini-buffer | 7819 | dpyinfo->terminal->reference_count--; |
| 7775 | for another frame that we need to delete. */ | 7820 | if (dpyinfo->reference_count != 0) |
| 7776 | FOR_EACH_FRAME (tail, frame) | 7821 | /* We have just closed all frames on this display. */ |
| 7777 | if (FRAME_X_P (XFRAME (frame)) | 7822 | abort (); |
| 7778 | && FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo) | ||
| 7779 | { | ||
| 7780 | /* Set this to t so that Fdelete_frame won't get confused | ||
| 7781 | trying to find a replacement. */ | ||
| 7782 | FRAME_KBOARD (XFRAME (frame))->Vdefault_minibuffer_frame = Qt; | ||
| 7783 | Fdelete_frame (frame, Qt); | ||
| 7784 | } | ||
| 7785 | 7823 | ||
| 7786 | if (dpyinfo) | 7824 | x_delete_display (dpyinfo); |
| 7787 | x_delete_display (dpyinfo); | 7825 | } |
| 7788 | 7826 | ||
| 7789 | x_uncatch_errors (); | 7827 | x_uncatch_errors (); |
| 7790 | 7828 | ||
| 7791 | if (x_display_list == 0) | 7829 | if (terminal_list == 0) |
| 7792 | { | 7830 | { |
| 7793 | fprintf (stderr, "%s\n", error_msg); | 7831 | fprintf (stderr, "%s\n", error_msg); |
| 7794 | shut_down_emacs (0, 0, Qnil); | 7832 | shut_down_emacs (0, 0, Qnil); |
| @@ -7802,6 +7840,7 @@ x_connection_closed (dpy, error_message) | |||
| 7802 | sigunblock (sigmask (SIGALRM)); | 7840 | sigunblock (sigmask (SIGALRM)); |
| 7803 | TOTALLY_UNBLOCK_INPUT; | 7841 | TOTALLY_UNBLOCK_INPUT; |
| 7804 | 7842 | ||
| 7843 | unbind_to (index, Qnil); | ||
| 7805 | clear_waiting_for_input (); | 7844 | clear_waiting_for_input (); |
| 7806 | error ("%s", error_msg); | 7845 | error ("%s", error_msg); |
| 7807 | } | 7846 | } |
| @@ -8012,7 +8051,7 @@ xim_destroy_callback (xim, client_data, call_data) | |||
| 8012 | FOR_EACH_FRAME (tail, frame) | 8051 | FOR_EACH_FRAME (tail, frame) |
| 8013 | { | 8052 | { |
| 8014 | struct frame *f = XFRAME (frame); | 8053 | struct frame *f = XFRAME (frame); |
| 8015 | if (FRAME_X_DISPLAY_INFO (f) == dpyinfo) | 8054 | if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo) |
| 8016 | { | 8055 | { |
| 8017 | FRAME_XIC (f) = NULL; | 8056 | FRAME_XIC (f) = NULL; |
| 8018 | xic_free_xfontset (f); | 8057 | xic_free_xfontset (f); |
| @@ -8111,7 +8150,8 @@ xim_instantiate_callback (display, client_data, call_data) | |||
| 8111 | { | 8150 | { |
| 8112 | struct frame *f = XFRAME (frame); | 8151 | struct frame *f = XFRAME (frame); |
| 8113 | 8152 | ||
| 8114 | if (FRAME_X_DISPLAY_INFO (f) == xim_inst->dpyinfo) | 8153 | if (FRAME_X_P (f) |
| 8154 | && FRAME_X_DISPLAY_INFO (f) == xim_inst->dpyinfo) | ||
| 8115 | if (FRAME_XIC (f) == NULL) | 8155 | if (FRAME_XIC (f) == NULL) |
| 8116 | { | 8156 | { |
| 8117 | create_frame_xic (f); | 8157 | create_frame_xic (f); |
| @@ -9328,8 +9368,8 @@ x_free_frame_resources (f) | |||
| 9328 | XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); | 9368 | XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); |
| 9329 | #endif /* !USE_X_TOOLKIT */ | 9369 | #endif /* !USE_X_TOOLKIT */ |
| 9330 | 9370 | ||
| 9331 | unload_color (f, f->output_data.x->foreground_pixel); | 9371 | unload_color (f, FRAME_FOREGROUND_PIXEL (f)); |
| 9332 | unload_color (f, f->output_data.x->background_pixel); | 9372 | unload_color (f, FRAME_BACKGROUND_PIXEL (f)); |
| 9333 | unload_color (f, f->output_data.x->cursor_pixel); | 9373 | unload_color (f, f->output_data.x->cursor_pixel); |
| 9334 | unload_color (f, f->output_data.x->cursor_foreground_pixel); | 9374 | unload_color (f, f->output_data.x->cursor_foreground_pixel); |
| 9335 | unload_color (f, f->output_data.x->border_pixel); | 9375 | unload_color (f, f->output_data.x->border_pixel); |
| @@ -10495,6 +10535,7 @@ x_term_init (display_name, xrm_option, resource_name) | |||
| 10495 | { | 10535 | { |
| 10496 | int connection; | 10536 | int connection; |
| 10497 | Display *dpy; | 10537 | Display *dpy; |
| 10538 | struct terminal *terminal; | ||
| 10498 | struct x_display_info *dpyinfo; | 10539 | struct x_display_info *dpyinfo; |
| 10499 | XrmDatabase xrdb; | 10540 | XrmDatabase xrdb; |
| 10500 | 10541 | ||
| @@ -10514,14 +10555,21 @@ x_term_init (display_name, xrm_option, resource_name) | |||
| 10514 | char **argv2 = argv; | 10555 | char **argv2 = argv; |
| 10515 | GdkAtom atom; | 10556 | GdkAtom atom; |
| 10516 | 10557 | ||
| 10558 | #ifndef HAVE_GTK_MULTIDISPLAY | ||
| 10559 | if (!EQ (Vinitial_window_system, intern ("x"))) | ||
| 10560 | error ("Sorry, you cannot connect to X servers with the GTK toolkit"); | ||
| 10561 | #endif | ||
| 10562 | |||
| 10517 | if (x_initialized++ > 1) | 10563 | if (x_initialized++ > 1) |
| 10518 | { | 10564 | { |
| 10565 | #ifdef HAVE_GTK_MULTIDISPLAY | ||
| 10519 | /* Opening another display. If xg_display_open returns less | 10566 | /* Opening another display. If xg_display_open returns less |
| 10520 | than zero, we are probably on GTK 2.0, which can only handle | 10567 | than zero, we are probably on GTK 2.0, which can only handle |
| 10521 | one display. GTK 2.2 or later can handle more than one. */ | 10568 | one display. GTK 2.2 or later can handle more than one. */ |
| 10522 | if (xg_display_open (SDATA (display_name), &dpy) < 0) | 10569 | if (xg_display_open (SDATA (display_name), &dpy) < 0) |
| 10570 | #endif | ||
| 10523 | error ("Sorry, this version of GTK can only handle one display"); | 10571 | error ("Sorry, this version of GTK can only handle one display"); |
| 10524 | } | 10572 | } |
| 10525 | else | 10573 | else |
| 10526 | { | 10574 | { |
| 10527 | for (argc = 0; argc < NUM_ARGV; ++argc) | 10575 | for (argc = 0; argc < NUM_ARGV; ++argc) |
| @@ -10625,6 +10673,8 @@ x_term_init (display_name, xrm_option, resource_name) | |||
| 10625 | dpyinfo = (struct x_display_info *) xmalloc (sizeof (struct x_display_info)); | 10673 | dpyinfo = (struct x_display_info *) xmalloc (sizeof (struct x_display_info)); |
| 10626 | bzero (dpyinfo, sizeof *dpyinfo); | 10674 | bzero (dpyinfo, sizeof *dpyinfo); |
| 10627 | 10675 | ||
| 10676 | terminal = x_create_terminal (dpyinfo); | ||
| 10677 | |||
| 10628 | #ifdef MULTI_KBOARD | 10678 | #ifdef MULTI_KBOARD |
| 10629 | { | 10679 | { |
| 10630 | struct x_display_info *share; | 10680 | struct x_display_info *share; |
| @@ -10636,30 +10686,30 @@ x_term_init (display_name, xrm_option, resource_name) | |||
| 10636 | SDATA (display_name))) | 10686 | SDATA (display_name))) |
| 10637 | break; | 10687 | break; |
| 10638 | if (share) | 10688 | if (share) |
| 10639 | dpyinfo->kboard = share->kboard; | 10689 | terminal->kboard = share->terminal->kboard; |
| 10640 | else | 10690 | else |
| 10641 | { | 10691 | { |
| 10642 | dpyinfo->kboard = (KBOARD *) xmalloc (sizeof (KBOARD)); | 10692 | terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD)); |
| 10643 | init_kboard (dpyinfo->kboard); | 10693 | init_kboard (terminal->kboard); |
| 10644 | if (!EQ (XSYMBOL (Qvendor_specific_keysyms)->function, Qunbound)) | 10694 | if (!EQ (XSYMBOL (Qvendor_specific_keysyms)->function, Qunbound)) |
| 10645 | { | 10695 | { |
| 10646 | char *vendor = ServerVendor (dpy); | 10696 | char *vendor = ServerVendor (dpy); |
| 10647 | UNBLOCK_INPUT; | 10697 | UNBLOCK_INPUT; |
| 10648 | dpyinfo->kboard->Vsystem_key_alist | 10698 | terminal->kboard->Vsystem_key_alist |
| 10649 | = call1 (Qvendor_specific_keysyms, | 10699 | = call1 (Qvendor_specific_keysyms, |
| 10650 | build_string (vendor ? vendor : "")); | 10700 | build_string (vendor ? vendor : "")); |
| 10651 | BLOCK_INPUT; | 10701 | BLOCK_INPUT; |
| 10652 | } | 10702 | } |
| 10653 | 10703 | ||
| 10654 | dpyinfo->kboard->next_kboard = all_kboards; | 10704 | terminal->kboard->next_kboard = all_kboards; |
| 10655 | all_kboards = dpyinfo->kboard; | 10705 | all_kboards = terminal->kboard; |
| 10656 | /* Don't let the initial kboard remain current longer than necessary. | 10706 | /* Don't let the initial kboard remain current longer than necessary. |
| 10657 | That would cause problems if a file loaded on startup tries to | 10707 | That would cause problems if a file loaded on startup tries to |
| 10658 | prompt in the mini-buffer. */ | 10708 | prompt in the mini-buffer. */ |
| 10659 | if (current_kboard == initial_kboard) | 10709 | if (current_kboard == initial_kboard) |
| 10660 | current_kboard = dpyinfo->kboard; | 10710 | current_kboard = terminal->kboard; |
| 10661 | } | 10711 | } |
| 10662 | dpyinfo->kboard->reference_count++; | 10712 | terminal->kboard->reference_count++; |
| 10663 | } | 10713 | } |
| 10664 | #endif | 10714 | #endif |
| 10665 | 10715 | ||
| @@ -10674,6 +10724,11 @@ x_term_init (display_name, xrm_option, resource_name) | |||
| 10674 | 10724 | ||
| 10675 | dpyinfo->display = dpy; | 10725 | dpyinfo->display = dpy; |
| 10676 | 10726 | ||
| 10727 | /* Set the name of the terminal. */ | ||
| 10728 | terminal->name = (char *) xmalloc (SBYTES (display_name) + 1); | ||
| 10729 | strncpy (terminal->name, SDATA (display_name), SBYTES (display_name)); | ||
| 10730 | terminal->name[SBYTES (display_name)] = 0; | ||
| 10731 | |||
| 10677 | #if 0 | 10732 | #if 0 |
| 10678 | XSetAfterFunction (x_current_display, x_trace_wire); | 10733 | XSetAfterFunction (x_current_display, x_trace_wire); |
| 10679 | #endif /* ! 0 */ | 10734 | #endif /* ! 0 */ |
| @@ -10969,8 +11024,10 @@ x_term_init (display_name, xrm_option, resource_name) | |||
| 10969 | } | 11024 | } |
| 10970 | 11025 | ||
| 10971 | #ifdef HAVE_X_SM | 11026 | #ifdef HAVE_X_SM |
| 10972 | /* Only do this for the first display. */ | 11027 | /* Only do this for the very first display in the Emacs session. |
| 10973 | if (!x_session_initialized++) | 11028 | Ignore X session management when Emacs was first started on a |
| 11029 | tty. */ | ||
| 11030 | if (terminal->id == 1) | ||
| 10974 | x_session_initialize (dpyinfo); | 11031 | x_session_initialize (dpyinfo); |
| 10975 | #endif | 11032 | #endif |
| 10976 | 11033 | ||
| @@ -10979,7 +11036,7 @@ x_term_init (display_name, xrm_option, resource_name) | |||
| 10979 | return dpyinfo; | 11036 | return dpyinfo; |
| 10980 | } | 11037 | } |
| 10981 | 11038 | ||
| 10982 | /* Get rid of display DPYINFO, assuming all frames are already gone, | 11039 | /* Get rid of display DPYINFO, deleting all frames on it, |
| 10983 | and without sending any more commands to the X server. */ | 11040 | and without sending any more commands to the X server. */ |
| 10984 | 11041 | ||
| 10985 | void | 11042 | void |
| @@ -10987,6 +11044,20 @@ x_delete_display (dpyinfo) | |||
| 10987 | struct x_display_info *dpyinfo; | 11044 | struct x_display_info *dpyinfo; |
| 10988 | { | 11045 | { |
| 10989 | int i; | 11046 | int i; |
| 11047 | struct terminal *t; | ||
| 11048 | |||
| 11049 | /* Close all frames and delete the generic struct terminal for this | ||
| 11050 | X display. */ | ||
| 11051 | for (t = terminal_list; t; t = t->next_terminal) | ||
| 11052 | if (t->type == output_x_window && t->display_info.x == dpyinfo) | ||
| 11053 | { | ||
| 11054 | /* Close X session management when we close its display. */ | ||
| 11055 | if (t->id == 1 && x_session_have_connection ()) | ||
| 11056 | x_session_close(); | ||
| 11057 | |||
| 11058 | delete_terminal (t); | ||
| 11059 | break; | ||
| 11060 | } | ||
| 10990 | 11061 | ||
| 10991 | delete_keyboard_wait_descriptor (dpyinfo->connection); | 11062 | delete_keyboard_wait_descriptor (dpyinfo->connection); |
| 10992 | 11063 | ||
| @@ -11030,10 +11101,6 @@ x_delete_display (dpyinfo) | |||
| 11030 | XrmDestroyDatabase (dpyinfo->xrdb); | 11101 | XrmDestroyDatabase (dpyinfo->xrdb); |
| 11031 | #endif | 11102 | #endif |
| 11032 | #endif | 11103 | #endif |
| 11033 | #ifdef MULTI_KBOARD | ||
| 11034 | if (--dpyinfo->kboard->reference_count == 0) | ||
| 11035 | delete_kboard (dpyinfo->kboard); | ||
| 11036 | #endif | ||
| 11037 | #ifdef HAVE_X_I18N | 11104 | #ifdef HAVE_X_I18N |
| 11038 | if (dpyinfo->xim) | 11105 | if (dpyinfo->xim) |
| 11039 | xim_close_dpy (dpyinfo); | 11106 | xim_close_dpy (dpyinfo); |
| @@ -11115,71 +11182,129 @@ x_activate_timeout_atimer () | |||
| 11115 | extern frame_parm_handler x_frame_parm_handlers[]; | 11182 | extern frame_parm_handler x_frame_parm_handlers[]; |
| 11116 | 11183 | ||
| 11117 | static struct redisplay_interface x_redisplay_interface = | 11184 | static struct redisplay_interface x_redisplay_interface = |
| 11118 | { | 11185 | { |
| 11119 | x_frame_parm_handlers, | 11186 | x_frame_parm_handlers, |
| 11120 | x_produce_glyphs, | 11187 | x_produce_glyphs, |
| 11121 | x_write_glyphs, | 11188 | x_write_glyphs, |
| 11122 | x_insert_glyphs, | 11189 | x_insert_glyphs, |
| 11123 | x_clear_end_of_line, | 11190 | x_clear_end_of_line, |
| 11124 | x_scroll_run, | 11191 | x_scroll_run, |
| 11125 | x_after_update_window_line, | 11192 | x_after_update_window_line, |
| 11126 | x_update_window_begin, | 11193 | x_update_window_begin, |
| 11127 | x_update_window_end, | 11194 | x_update_window_end, |
| 11128 | x_cursor_to, | 11195 | x_cursor_to, |
| 11129 | x_flush, | 11196 | x_flush, |
| 11130 | #ifdef XFlush | 11197 | #ifdef XFlush |
| 11131 | x_flush, | 11198 | x_flush, |
| 11132 | #else | 11199 | #else |
| 11133 | 0, /* flush_display_optional */ | 11200 | 0, /* flush_display_optional */ |
| 11134 | #endif | 11201 | #endif |
| 11135 | x_clear_window_mouse_face, | 11202 | x_clear_window_mouse_face, |
| 11136 | x_get_glyph_overhangs, | 11203 | x_get_glyph_overhangs, |
| 11137 | x_fix_overlapping_area, | 11204 | x_fix_overlapping_area, |
| 11138 | x_draw_fringe_bitmap, | 11205 | x_draw_fringe_bitmap, |
| 11139 | 0, /* define_fringe_bitmap */ | 11206 | 0, /* define_fringe_bitmap */ |
| 11140 | 0, /* destroy_fringe_bitmap */ | 11207 | 0, /* destroy_fringe_bitmap */ |
| 11141 | x_per_char_metric, | 11208 | x_per_char_metric, |
| 11142 | x_encode_char, | 11209 | x_encode_char, |
| 11143 | x_compute_glyph_string_overhangs, | 11210 | x_compute_glyph_string_overhangs, |
| 11144 | x_draw_glyph_string, | 11211 | x_draw_glyph_string, |
| 11145 | x_define_frame_cursor, | 11212 | x_define_frame_cursor, |
| 11146 | x_clear_frame_area, | 11213 | x_clear_frame_area, |
| 11147 | x_draw_window_cursor, | 11214 | x_draw_window_cursor, |
| 11148 | x_draw_vertical_window_border, | 11215 | x_draw_vertical_window_border, |
| 11149 | x_shift_glyphs_for_insert | 11216 | x_shift_glyphs_for_insert |
| 11150 | }; | 11217 | }; |
| 11218 | |||
| 11219 | |||
| 11220 | /* This function is called when the last frame on a display is deleted. */ | ||
| 11221 | void | ||
| 11222 | x_delete_terminal (struct terminal *terminal) | ||
| 11223 | { | ||
| 11224 | struct x_display_info *dpyinfo = terminal->display_info.x; | ||
| 11225 | int i; | ||
| 11226 | |||
| 11227 | /* Protect against recursive calls. Fdelete_frame in | ||
| 11228 | delete_terminal calls us back when it deletes our last frame. */ | ||
| 11229 | if (terminal->deleted) | ||
| 11230 | return; | ||
| 11231 | |||
| 11232 | BLOCK_INPUT; | ||
| 11233 | /* Free the fonts in the font table. */ | ||
| 11234 | for (i = 0; i < dpyinfo->n_fonts; i++) | ||
| 11235 | if (dpyinfo->font_table[i].name) | ||
| 11236 | { | ||
| 11237 | XFreeFont (dpyinfo->display, dpyinfo->font_table[i].font); | ||
| 11238 | } | ||
| 11239 | |||
| 11240 | x_destroy_all_bitmaps (dpyinfo); | ||
| 11241 | XSetCloseDownMode (dpyinfo->display, DestroyAll); | ||
| 11242 | |||
| 11243 | #ifdef USE_GTK | ||
| 11244 | xg_display_close (dpyinfo->display); | ||
| 11245 | #else | ||
| 11246 | #ifdef USE_X_TOOLKIT | ||
| 11247 | XtCloseDisplay (dpyinfo->display); | ||
| 11248 | #else | ||
| 11249 | XCloseDisplay (dpyinfo->display); | ||
| 11250 | #endif | ||
| 11251 | #endif /* ! USE_GTK */ | ||
| 11252 | |||
| 11253 | x_delete_display (dpyinfo); | ||
| 11254 | UNBLOCK_INPUT; | ||
| 11255 | } | ||
| 11256 | |||
| 11257 | |||
| 11258 | static struct terminal * | ||
| 11259 | x_create_terminal (struct x_display_info *dpyinfo) | ||
| 11260 | { | ||
| 11261 | struct terminal *terminal; | ||
| 11262 | |||
| 11263 | terminal = create_terminal (); | ||
| 11264 | |||
| 11265 | terminal->type = output_x_window; | ||
| 11266 | terminal->display_info.x = dpyinfo; | ||
| 11267 | dpyinfo->terminal = terminal; | ||
| 11268 | |||
| 11269 | /* kboard is initialized in x_term_init. */ | ||
| 11270 | |||
| 11271 | terminal->clear_frame_hook = x_clear_frame; | ||
| 11272 | terminal->ins_del_lines_hook = x_ins_del_lines; | ||
| 11273 | terminal->delete_glyphs_hook = x_delete_glyphs; | ||
| 11274 | terminal->ring_bell_hook = XTring_bell; | ||
| 11275 | terminal->reset_terminal_modes_hook = XTreset_terminal_modes; | ||
| 11276 | terminal->set_terminal_modes_hook = XTset_terminal_modes; | ||
| 11277 | terminal->update_begin_hook = x_update_begin; | ||
| 11278 | terminal->update_end_hook = x_update_end; | ||
| 11279 | terminal->set_terminal_window_hook = XTset_terminal_window; | ||
| 11280 | terminal->read_socket_hook = XTread_socket; | ||
| 11281 | terminal->frame_up_to_date_hook = XTframe_up_to_date; | ||
| 11282 | terminal->mouse_position_hook = XTmouse_position; | ||
| 11283 | terminal->frame_rehighlight_hook = XTframe_rehighlight; | ||
| 11284 | terminal->frame_raise_lower_hook = XTframe_raise_lower; | ||
| 11285 | terminal->fullscreen_hook = XTfullscreen_hook; | ||
| 11286 | terminal->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar; | ||
| 11287 | terminal->condemn_scroll_bars_hook = XTcondemn_scroll_bars; | ||
| 11288 | terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar; | ||
| 11289 | terminal->judge_scroll_bars_hook = XTjudge_scroll_bars; | ||
| 11290 | |||
| 11291 | terminal->delete_frame_hook = x_destroy_window; | ||
| 11292 | terminal->delete_terminal_hook = x_delete_terminal; | ||
| 11293 | |||
| 11294 | terminal->rif = &x_redisplay_interface; | ||
| 11295 | terminal->scroll_region_ok = 1; /* We'll scroll partial frames. */ | ||
| 11296 | terminal->char_ins_del_ok = 1; | ||
| 11297 | terminal->line_ins_del_ok = 1; /* We'll just blt 'em. */ | ||
| 11298 | terminal->fast_clear_end_of_line = 1; /* X does this well. */ | ||
| 11299 | terminal->memory_below_frame = 0; /* We don't remember what scrolls | ||
| 11300 | off the bottom. */ | ||
| 11301 | |||
| 11302 | return terminal; | ||
| 11303 | } | ||
| 11151 | 11304 | ||
| 11152 | void | 11305 | void |
| 11153 | x_initialize () | 11306 | x_initialize () |
| 11154 | { | 11307 | { |
| 11155 | rif = &x_redisplay_interface; | ||
| 11156 | |||
| 11157 | clear_frame_hook = x_clear_frame; | ||
| 11158 | ins_del_lines_hook = x_ins_del_lines; | ||
| 11159 | delete_glyphs_hook = x_delete_glyphs; | ||
| 11160 | ring_bell_hook = XTring_bell; | ||
| 11161 | reset_terminal_modes_hook = XTreset_terminal_modes; | ||
| 11162 | set_terminal_modes_hook = XTset_terminal_modes; | ||
| 11163 | update_begin_hook = x_update_begin; | ||
| 11164 | update_end_hook = x_update_end; | ||
| 11165 | set_terminal_window_hook = XTset_terminal_window; | ||
| 11166 | read_socket_hook = XTread_socket; | ||
| 11167 | frame_up_to_date_hook = XTframe_up_to_date; | ||
| 11168 | mouse_position_hook = XTmouse_position; | ||
| 11169 | frame_rehighlight_hook = XTframe_rehighlight; | ||
| 11170 | frame_raise_lower_hook = XTframe_raise_lower; | ||
| 11171 | set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar; | ||
| 11172 | condemn_scroll_bars_hook = XTcondemn_scroll_bars; | ||
| 11173 | redeem_scroll_bar_hook = XTredeem_scroll_bar; | ||
| 11174 | judge_scroll_bars_hook = XTjudge_scroll_bars; | ||
| 11175 | fullscreen_hook = XTfullscreen_hook; | ||
| 11176 | |||
| 11177 | scroll_region_ok = 1; /* we'll scroll partial frames */ | ||
| 11178 | char_ins_del_ok = 1; | ||
| 11179 | line_ins_del_ok = 1; /* we'll just blt 'em */ | ||
| 11180 | fast_clear_end_of_line = 1; /* X does this well */ | ||
| 11181 | memory_below_frame = 0; /* we don't remember what scrolls | ||
| 11182 | off the bottom */ | ||
| 11183 | baud_rate = 19200; | 11308 | baud_rate = 19200; |
| 11184 | 11309 | ||
| 11185 | x_noop_count = 0; | 11310 | x_noop_count = 0; |
| @@ -11195,7 +11320,7 @@ x_initialize () | |||
| 11195 | #endif | 11320 | #endif |
| 11196 | 11321 | ||
| 11197 | /* Try to use interrupt input; if we can't, then start polling. */ | 11322 | /* Try to use interrupt input; if we can't, then start polling. */ |
| 11198 | Fset_input_mode (Qt, Qnil, Qt, Qnil); | 11323 | Fset_input_interrupt_mode (Qt); |
| 11199 | 11324 | ||
| 11200 | #ifdef USE_X_TOOLKIT | 11325 | #ifdef USE_X_TOOLKIT |
| 11201 | XtToolkitInitialize (); | 11326 | XtToolkitInitialize (); |
| @@ -11226,9 +11351,11 @@ x_initialize () | |||
| 11226 | XSetIOErrorHandler (x_io_error_quitter); | 11351 | XSetIOErrorHandler (x_io_error_quitter); |
| 11227 | 11352 | ||
| 11228 | /* Disable Window Change signals; they are handled by X events. */ | 11353 | /* Disable Window Change signals; they are handled by X events. */ |
| 11354 | #if 0 /* Don't. We may want to open tty frames later. */ | ||
| 11229 | #ifdef SIGWINCH | 11355 | #ifdef SIGWINCH |
| 11230 | signal (SIGWINCH, SIG_DFL); | 11356 | signal (SIGWINCH, SIG_DFL); |
| 11231 | #endif /* SIGWINCH */ | 11357 | #endif /* SIGWINCH */ |
| 11358 | #endif | ||
| 11232 | 11359 | ||
| 11233 | signal (SIGPIPE, x_connection_signal); | 11360 | signal (SIGPIPE, x_connection_signal); |
| 11234 | } | 11361 | } |