aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1994-10-26 09:26:40 +0000
committerRichard M. Stallman1994-10-26 09:26:40 +0000
commit7a13e8946b124f8265adf07e28315076c7801902 (patch)
treef9ee8dc9e0fd1635ef624bc93cc6dc67906dff05 /src
parentc4ec904fd64cbfa43b47bdccf9c1841e2b93e90d (diff)
downloademacs-7a13e8946b124f8265adf07e28315076c7801902.tar.gz
emacs-7a13e8946b124f8265adf07e28315076c7801902.zip
(x_catch_errors, x_check_errors, x_had_errors_p)
(x_uncatch_errors): Make the argument a display, not a frame. (XTread_socket_fake_io_error): New variable. (XTread_socket): Obey XTread_socket_fake_io_error. (x_initialize): Init x_noop_count, x_focus_frame and x_highlight_frame here. (x_term_init): Not here. (x_term_init): Open the connection first thing; if that fails, don't allocate dpyinfo. (x_delete_display): New function. (x_connection_closed): New args dpyinfo and error_message. Delete all frames on the dead display and all frames using them for minibuffers. Call x_delete_display. Maybe signal a Lisp error. (x_term_init): Don't report error here--just return 0. (x_scroll_bar_report_motion): Store proper value in *bar_window (the Emacs window, not the X window number). (x_scroll_bar_report_motion): Don't clear *fp. (x_wm_set_icon_pixmap): Use x_bitmap_pixmap. (show_mouse_face): New arg dpyinfo. All callers changed. (clear_mouse_face): New arg dpyinfo. All callers changed. (scratch_cursor_gc): Variable deleted. (dumpglyphs): Use scratch_cursor_gc in x_display_info. (syms_of_xterm): Don't staticpro mouse_face_window. (expose_all_windows, expose_all_icons): Variables deleted. (BLOCK_INPUT_mask): Variable deleted. (x_term_init): Set up x_id_name field. (x_id_name): Variable deleted. (x_font_table, x_font_table_size, x_n_fonts): Vars deleted. (x_new_font): Use new fields. (warp_mouse_on_deiconify): Unused variable deleted. (x_term_init): Set up dpyinfo->xrdb. Set up dpyinfo->vertical_scroll_bar_cursor. (x_scroll_bar_create): Use vertical_scroll_bar_cursor slot. (x_vertical_scroll_bar_cursor): Variable deleted. (x_term_init): Really return dpyinfo. (x_term_init): Call add_keyboard_wait_descriptor, not change_keyboard_wait_descriptor. (x_term_init): Pass new arg to init_sigio. Don't set old_fcntl_owner. Don't call change_input_fd. (XTread_socket): Loop over displays and process input from each. (x_display_name_list): New variable. (syms_of_xterm): staticpro it. Don't staticpro slots in the_x_screen. (x_term_init): Update x_display_name_list along with x_display_list. Actually malloc the x_display_info. (the_x_screen): Variable deleted.
Diffstat (limited to 'src')
-rw-r--r--src/xterm.c1772
1 files changed, 918 insertions, 854 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 173cecb0c7e..e70513a24aa 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -66,6 +66,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
66#include <sys/stat.h> 66#include <sys/stat.h>
67#include <sys/param.h> 67#include <sys/param.h>
68 68
69#include "frame.h"
69#include "dispextern.h" 70#include "dispextern.h"
70#include "termhooks.h" 71#include "termhooks.h"
71#include "termopts.h" 72#include "termopts.h"
@@ -75,7 +76,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
75#include "sinkmask.h" 76#include "sinkmask.h"
76#endif /* ! 0 */ 77#endif /* ! 0 */
77#include "gnu.h" 78#include "gnu.h"
78#include "frame.h"
79#include "disptab.h" 79#include "disptab.h"
80#include "buffer.h" 80#include "buffer.h"
81#include "window.h" 81#include "window.h"
@@ -129,39 +129,18 @@ extern void _XEditResCheckMessages ();
129#define min(a,b) ((a)<(b) ? (a) : (b)) 129#define min(a,b) ((a)<(b) ? (a) : (b))
130#define max(a,b) ((a)>(b) ? (a) : (b)) 130#define max(a,b) ((a)>(b) ? (a) : (b))
131 131
132/* Nonzero means we must reprint all windows
133 because 1) we received an ExposeWindow event
134 or 2) we received too many ExposeRegion events to record.
135
136 This is never needed under X11. */
137static int expose_all_windows;
138
139/* Nonzero means we must reprint all icon windows. */
140
141static int expose_all_icons;
142
143#if defined (SIGIO) && defined (FIONREAD)
144int BLOCK_INPUT_mask;
145#endif /* ! defined (SIGIO) && defined (FIONREAD) */
146
147/* Stuff for dealing with the main icon title. */ 132/* Stuff for dealing with the main icon title. */
148 133
149extern Lisp_Object Vcommand_line_args, Vsystem_name;
150char *x_id_name; 134char *x_id_name;
151 135
152/* Initial values of argv and argc. */
153extern char **initial_argv;
154extern int initial_argc;
155
156/* For now, we have just one x_display structure since we only support
157 one X display. */
158static struct x_display_info the_x_screen;
159
160/* This is a chain of structures for all the X displays currently in use. */ 136/* This is a chain of structures for all the X displays currently in use. */
161struct x_display_info *x_display_list; 137struct x_display_info *x_display_list;
162 138
163/* The cursor to use for vertical scroll bars on x_current_display. */ 139/* This is a list of cons cells, each of the form (NAME . FONT-LIST-CACHE),
164static Cursor x_vertical_scroll_bar_cursor; 140 one for each element of x_display_list and in the same order.
141 NAME is the name of the frame.
142 FONT-LIST-CACHE records previous values returned by x-list-fonts. */
143Lisp_Object x_display_name_list;
165 144
166/* Frame being updated by update_frame. This is declared in term.c. 145/* Frame being updated by update_frame. This is declared in term.c.
167 This is set by update_begin and looked at by all the 146 This is set by update_begin and looked at by all the
@@ -193,11 +172,6 @@ struct frame *x_focus_event_frame;
193 minibuffer. */ 172 minibuffer. */
194static struct frame *x_highlight_frame; 173static struct frame *x_highlight_frame;
195 174
196/* From .Xdefaults, the value of "emacs.WarpMouse". If non-zero,
197 mouse is moved to inside of frame when frame is de-iconified. */
198
199static int warp_mouse_on_deiconify;
200
201/* During an update, maximum vpos for ins/del line operations to affect. */ 175/* During an update, maximum vpos for ins/del line operations to affect. */
202 176
203static int flexlines; 177static int flexlines;
@@ -212,9 +186,6 @@ static int highlight;
212static int curs_x; 186static int curs_x;
213static int curs_y; 187static int curs_y;
214 188
215/* Reusable Graphics Context for drawing a cursor in a non-default face. */
216static GC scratch_cursor_gc;
217
218/* Mouse movement. 189/* Mouse movement.
219 190
220 In order to avoid asking for motion events and then throwing most 191 In order to avoid asking for motion events and then throwing most
@@ -256,28 +227,6 @@ static Lisp_Object last_mouse_scroll_bar;
256 it's somewhat accurate. */ 227 it's somewhat accurate. */
257static Time last_mouse_movement_time; 228static Time last_mouse_movement_time;
258 229
259/* These variables describe the range of text currently shown
260 in its mouse-face, together with the window they apply to.
261 As long as the mouse stays within this range, we need not
262 redraw anything on its account. */
263static int mouse_face_beg_row, mouse_face_beg_col;
264static int mouse_face_end_row, mouse_face_end_col;
265static int mouse_face_past_end;
266static Lisp_Object mouse_face_window;
267static int mouse_face_face_id;
268
269/* 1 if a mouse motion event came and we didn't handle it right away because
270 gc was in progress. */
271static int mouse_face_deferred_gc;
272
273/* FRAME and X, Y position of mouse when last checked for
274 highlighting. X and Y can be negative or out of range for the frame. */
275static FRAME_PTR mouse_face_mouse_frame;
276static int mouse_face_mouse_x, mouse_face_mouse_y;
277
278/* Nonzero means defer mouse-motion highlighting. */
279static int mouse_face_defer;
280
281/* Incremented by XTread_socket whenever it really tries to read events. */ 230/* Incremented by XTread_socket whenever it really tries to read events. */
282#ifdef __STDC__ 231#ifdef __STDC__
283static int volatile input_signal_count; 232static int volatile input_signal_count;
@@ -285,35 +234,33 @@ static int volatile input_signal_count;
285static int input_signal_count; 234static int input_signal_count;
286#endif 235#endif
287 236
288/* Tells if a window manager is present or not. */ 237/* Used locally within XTread_socket. */
238static int x_noop_count;
289 239
290extern Lisp_Object Vx_no_window_manager; 240/* Initial values of argv and argc. */
241extern char **initial_argv;
242extern int initial_argc;
291 243
292/* Timestamp that we requested selection data was made. */ 244extern Lisp_Object Vcommand_line_args, Vsystem_name;
293extern Time requestor_time;
294 245
295/* ID of the window requesting selection data. */ 246/* Tells if a window manager is present or not. */
296extern Window requestor_window; 247
248extern Lisp_Object Vx_no_window_manager;
297 249
298/* Nonzero enables some debugging for the X interface code. */ 250/* Nonzero enables some debugging for the X interface code. */
299extern int _Xdebug; 251extern int _Xdebug;
300 252
301extern Lisp_Object Qface, Qmouse_face; 253extern Lisp_Object Qface, Qmouse_face;
302 254
303static int x_noop_count;
304
305extern int errno; 255extern int errno;
306 256
307/* A mask of extra modifier bits to put into every keyboard char. */ 257/* A mask of extra modifier bits to put into every keyboard char. */
308extern int extra_keyboard_modifiers; 258extern int extra_keyboard_modifiers;
309 259
310extern Display *XOpenDisplay ();
311extern Window XCreateWindow ();
312
313extern Cursor XCreateCursor ();
314extern XFontStruct *XOpenFont ();
315extern XrmDatabase x_load_resources (); 260extern XrmDatabase x_load_resources ();
316 261
262void x_delete_display ();
263
317static void flashback (); 264static void flashback ();
318static void redraw_previous_char (); 265static void redraw_previous_char ();
319static void redraw_following_char (); 266static void redraw_following_char ();
@@ -325,9 +272,9 @@ static void clear_mouse_face ();
325static void show_mouse_face (); 272static void show_mouse_face ();
326static void do_line_dance (); 273static void do_line_dance ();
327 274
328void dumpborder ();
329static int XTcursor_to (); 275static int XTcursor_to ();
330static int XTclear_end_of_line (); 276static int XTclear_end_of_line ();
277static int x_io_error_quitter ();
331 278
332/* Return the struct x_display_info corresponding to DPY. */ 279/* Return the struct x_display_info corresponding to DPY. */
333 280
@@ -353,8 +300,6 @@ x_display_info_for_display (dpy)
353 should never be called except during an update, the only exceptions 300 should never be called except during an update, the only exceptions
354 being XTcursor_to, XTwrite_glyphs and XTreassert_line_highlight. */ 301 being XTcursor_to, XTwrite_glyphs and XTreassert_line_highlight. */
355 302
356extern int mouse_track_top, mouse_track_left, mouse_track_width;
357
358static 303static
359XTupdate_begin (f) 304XTupdate_begin (f)
360 struct frame *f; 305 struct frame *f;
@@ -369,14 +314,14 @@ XTupdate_begin (f)
369 314
370 BLOCK_INPUT; 315 BLOCK_INPUT;
371 316
372 if (f == mouse_face_mouse_frame) 317 if (f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
373 { 318 {
374 /* Don't do highlighting for mouse motion during the update. */ 319 /* Don't do highlighting for mouse motion during the update. */
375 mouse_face_defer = 1; 320 FRAME_X_DISPLAY_INFO (f)->mouse_face_defer = 1;
376 if (!NILP (mouse_face_window)) 321 if (!NILP (FRAME_X_DISPLAY_INFO (f)->mouse_face_window))
377 { 322 {
378 int firstline, lastline, i; 323 int firstline, lastline, i;
379 struct window *w = XWINDOW (mouse_face_window); 324 struct window *w = XWINDOW (FRAME_X_DISPLAY_INFO (f)->mouse_face_window);
380 325
381 /* Find the first, and the last+1, lines affected by redisplay. */ 326 /* Find the first, and the last+1, lines affected by redisplay. */
382 for (firstline = 0; firstline < f->height; firstline++) 327 for (firstline = 0; firstline < f->height; firstline++)
@@ -397,7 +342,7 @@ XTupdate_begin (f)
397 if (! (firstline > (XFASTINT (w->top) + window_internal_height (w)) 342 if (! (firstline > (XFASTINT (w->top) + window_internal_height (w))
398 || lastline < XFASTINT (w->top))) 343 || lastline < XFASTINT (w->top)))
399 /* Otherwise turn off the mouse highlight now. */ 344 /* Otherwise turn off the mouse highlight now. */
400 clear_mouse_face (); 345 clear_mouse_face (FRAME_X_DISPLAY_INFO (f));
401 } 346 }
402 } 347 }
403 348
@@ -415,8 +360,8 @@ XTupdate_end (f)
415 do_line_dance (); 360 do_line_dance ();
416 x_display_cursor (f, 1); 361 x_display_cursor (f, 1);
417 362
418 if (f == mouse_face_mouse_frame) 363 if (f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
419 mouse_face_defer = 0; 364 FRAME_X_DISPLAY_INFO (f)->mouse_face_defer = 0;
420#if 0 365#if 0
421 /* This fails in the case of having updated only the echo area 366 /* This fails in the case of having updated only the echo area
422 if we have switched buffers. In that case, FRAME_CURRENT_GLYPHS 367 if we have switched buffers. In that case, FRAME_CURRENT_GLYPHS
@@ -424,8 +369,9 @@ XTupdate_end (f)
424 have no relation to the contents of the window-buffer. 369 have no relation to the contents of the window-buffer.
425 I don't know a clean way to check 370 I don't know a clean way to check
426 for that case. window_end_valid isn't set up yet. */ 371 for that case. window_end_valid isn't set up yet. */
427 if (f == mouse_face_mouse_frame) 372 if (f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
428 note_mouse_highlight (f, mouse_face_mouse_x, mouse_face_mouse_y); 373 note_mouse_highlight (f, FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_x,
374 FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_y);
429#endif 375#endif
430 376
431 XFlush (FRAME_X_DISPLAY (f)); 377 XFlush (FRAME_X_DISPLAY (f));
@@ -438,11 +384,13 @@ static
438XTframe_up_to_date (f) 384XTframe_up_to_date (f)
439 FRAME_PTR f; 385 FRAME_PTR f;
440{ 386{
441 if (mouse_face_deferred_gc || f == mouse_face_mouse_frame) 387 if (FRAME_X_DISPLAY_INFO (f)->mouse_face_deferred_gc
388 || f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
442 { 389 {
443 note_mouse_highlight (mouse_face_mouse_frame, 390 note_mouse_highlight (FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame,
444 mouse_face_mouse_x, mouse_face_mouse_y); 391 FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_x,
445 mouse_face_deferred_gc = 0; 392 FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_y);
393 FRAME_X_DISPLAY_INFO (f)->mouse_face_deferred_gc = 0;
446 } 394 }
447} 395}
448 396
@@ -583,7 +531,7 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground)
583 531
584 /* HL = 3 means use a mouse face previously chosen. */ 532 /* HL = 3 means use a mouse face previously chosen. */
585 if (hl == 3) 533 if (hl == 3)
586 cf = mouse_face_face_id; 534 cf = FRAME_X_DISPLAY_INFO (f)->mouse_face_face_id;
587 535
588 /* First look at the face of the text itself. */ 536 /* First look at the face of the text itself. */
589 if (cf != 0) 537 if (cf != 0)
@@ -658,12 +606,14 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground)
658 xgcv.font = face->font->fid; 606 xgcv.font = face->font->fid;
659 xgcv.graphics_exposures = 0; 607 xgcv.graphics_exposures = 0;
660 mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures; 608 mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
661 if (scratch_cursor_gc) 609 if (FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc)
662 XChangeGC (FRAME_X_DISPLAY (f), scratch_cursor_gc, mask, &xgcv); 610 XChangeGC (FRAME_X_DISPLAY (f),
611 FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc,
612 mask, &xgcv);
663 else 613 else
664 scratch_cursor_gc 614 FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc
665 = XCreateGC (FRAME_X_DISPLAY (f), window, mask, &xgcv); 615 = XCreateGC (FRAME_X_DISPLAY (f), window, mask, &xgcv);
666 gc = scratch_cursor_gc; 616 gc = FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc;
667#if 0 617#if 0
668/* If this code is restored, it must also reset to the default stipple 618/* If this code is restored, it must also reset to the default stipple
669 if necessary. */ 619 if necessary. */
@@ -1241,6 +1191,11 @@ XTset_terminal_window (n)
1241 flexlines = n; 1191 flexlines = n;
1242} 1192}
1243 1193
1194/* These variables need not be per frame
1195 because redisplay is done on a frame-by-frame basis
1196 and the line dance for one frame is finished before
1197 anything is done for anoter frame. */
1198
1244/* Array of line numbers from cached insert/delete operations. 1199/* Array of line numbers from cached insert/delete operations.
1245 line_dance[i] is the old position of the line that we want 1200 line_dance[i] is the old position of the line that we want
1246 to move to line i, or -1 if we want a blank line there. */ 1201 to move to line i, or -1 if we want a blank line there. */
@@ -1896,16 +1851,16 @@ note_mouse_highlight (f, x, y)
1896 if (disable_mouse_highlight) 1851 if (disable_mouse_highlight)
1897 return; 1852 return;
1898 1853
1899 mouse_face_mouse_x = x; 1854 FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_x = x;
1900 mouse_face_mouse_y = y; 1855 FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_y = y;
1901 mouse_face_mouse_frame = f; 1856 FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame = f;
1902 1857
1903 if (mouse_face_defer) 1858 if (FRAME_X_DISPLAY_INFO (f)->mouse_face_defer)
1904 return; 1859 return;
1905 1860
1906 if (gc_in_progress) 1861 if (gc_in_progress)
1907 { 1862 {
1908 mouse_face_deferred_gc = 1; 1863 FRAME_X_DISPLAY_INFO (f)->mouse_face_deferred_gc = 1;
1909 return; 1864 return;
1910 } 1865 }
1911 1866
@@ -1918,8 +1873,8 @@ note_mouse_highlight (f, x, y)
1918 w = XWINDOW (window); 1873 w = XWINDOW (window);
1919 1874
1920 /* If we were displaying active text in another window, clear that. */ 1875 /* If we were displaying active text in another window, clear that. */
1921 if (! EQ (window, mouse_face_window)) 1876 if (! EQ (window, FRAME_X_DISPLAY_INFO (f)->mouse_face_window))
1922 clear_mouse_face (); 1877 clear_mouse_face (FRAME_X_DISPLAY_INFO (f));
1923 1878
1924 /* Are we in a window whose display is up to date? 1879 /* Are we in a window whose display is up to date?
1925 And verify the buffer's text has not changed. */ 1880 And verify the buffer's text has not changed. */
@@ -1938,13 +1893,15 @@ note_mouse_highlight (f, x, y)
1938 pos = ptr[i]; 1893 pos = ptr[i];
1939 /* Is it outside the displayed active region (if any)? */ 1894 /* Is it outside the displayed active region (if any)? */
1940 if (pos <= 0) 1895 if (pos <= 0)
1941 clear_mouse_face (); 1896 clear_mouse_face (FRAME_X_DISPLAY_INFO (f));
1942 else if (! (EQ (window, mouse_face_window) 1897 else if (! (EQ (window, FRAME_X_DISPLAY_INFO (f)->mouse_face_window)
1943 && row >= mouse_face_beg_row 1898 && row >= FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row
1944 && row <= mouse_face_end_row 1899 && row <= FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row
1945 && (row > mouse_face_beg_row || column >= mouse_face_beg_col) 1900 && (row > FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row
1946 && (row < mouse_face_end_row || column < mouse_face_end_col 1901 || column >= FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_col)
1947 || mouse_face_past_end))) 1902 && (row < FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row
1903 || column < FRAME_X_DISPLAY_INFO (f)->mouse_face_end_col
1904 || FRAME_X_DISPLAY_INFO (f)->mouse_face_past_end)))
1948 { 1905 {
1949 Lisp_Object mouse_face, overlay, position; 1906 Lisp_Object mouse_face, overlay, position;
1950 Lisp_Object *overlay_vec; 1907 Lisp_Object *overlay_vec;
@@ -1966,7 +1923,7 @@ note_mouse_highlight (f, x, y)
1966 ZV = Z; 1923 ZV = Z;
1967 1924
1968 /* Yes. Clear the display of the old active region, if any. */ 1925 /* Yes. Clear the display of the old active region, if any. */
1969 clear_mouse_face (); 1926 clear_mouse_face (FRAME_X_DISPLAY_INFO (f));
1970 1927
1971 /* Is this char mouse-active? */ 1928 /* Is this char mouse-active? */
1972 XSETINT (position, pos); 1929 XSETINT (position, pos);
@@ -2007,17 +1964,20 @@ note_mouse_highlight (f, x, y)
2007 before = Foverlay_start (overlay); 1964 before = Foverlay_start (overlay);
2008 after = Foverlay_end (overlay); 1965 after = Foverlay_end (overlay);
2009 /* Record this as the current active region. */ 1966 /* Record this as the current active region. */
2010 fast_find_position (window, before, &mouse_face_beg_col, 1967 fast_find_position (window, before,
2011 &mouse_face_beg_row); 1968 &FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_col,
2012 mouse_face_past_end 1969 &FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row);
2013 = !fast_find_position (window, after, &mouse_face_end_col, 1970 FRAME_X_DISPLAY_INFO (f)->mouse_face_past_end
2014 &mouse_face_end_row); 1971 = !fast_find_position (window, after,
2015 mouse_face_window = window; 1972 &FRAME_X_DISPLAY_INFO (f)->mouse_face_end_col,
2016 mouse_face_face_id = compute_char_face (f, w, pos, 0, 0, 1973 &FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row);
2017 &ignore, pos + 1, 1); 1974 FRAME_X_DISPLAY_INFO (f)->mouse_face_window = window;
1975 FRAME_X_DISPLAY_INFO (f)->mouse_face_face_id
1976 = compute_char_face (f, w, pos, 0, 0,
1977 &ignore, pos + 1, 1);
2018 1978
2019 /* Display it as active. */ 1979 /* Display it as active. */
2020 show_mouse_face (1); 1980 show_mouse_face (FRAME_X_DISPLAY_INFO (f), 1);
2021 } 1981 }
2022 /* Handle the text property case. */ 1982 /* Handle the text property case. */
2023 else if (! NILP (mouse_face)) 1983 else if (! NILP (mouse_face))
@@ -2038,18 +1998,20 @@ note_mouse_highlight (f, x, y)
2038 = Fnext_single_property_change (position, Qmouse_face, 1998 = Fnext_single_property_change (position, Qmouse_face,
2039 w->buffer, end); 1999 w->buffer, end);
2040 /* Record this as the current active region. */ 2000 /* Record this as the current active region. */
2041 fast_find_position (window, before, &mouse_face_beg_col, 2001 fast_find_position (window, before,
2042 &mouse_face_beg_row); 2002 &FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_col,
2043 mouse_face_past_end 2003 &FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row);
2044 = !fast_find_position (window, after, &mouse_face_end_col, 2004 FRAME_X_DISPLAY_INFO (f)->mouse_face_past_end
2045 &mouse_face_end_row); 2005 = !fast_find_position (window, after,
2046 mouse_face_window = window; 2006 &FRAME_X_DISPLAY_INFO (f)->mouse_face_end_col,
2047 mouse_face_face_id 2007 &FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row);
2008 FRAME_X_DISPLAY_INFO (f)->mouse_face_window = window;
2009 FRAME_X_DISPLAY_INFO (f)->mouse_face_face_id
2048 = compute_char_face (f, w, pos, 0, 0, 2010 = compute_char_face (f, w, pos, 0, 0,
2049 &ignore, pos + 1, 1); 2011 &ignore, pos + 1, 1);
2050 2012
2051 /* Display it as active. */ 2013 /* Display it as active. */
2052 show_mouse_face (1); 2014 show_mouse_face (FRAME_X_DISPLAY_INFO (f), 1);
2053 } 2015 }
2054 BEGV = obegv; 2016 BEGV = obegv;
2055 ZV = ozv; 2017 ZV = ozv;
@@ -2122,10 +2084,11 @@ fast_find_position (window, pos, columnp, rowp)
2122 in its mouse-face if HL > 0, in its normal face if HL = 0. */ 2084 in its mouse-face if HL > 0, in its normal face if HL = 0. */
2123 2085
2124static void 2086static void
2125show_mouse_face (hl) 2087show_mouse_face (dpyinfo, hl)
2088 struct x_display_info *dpyinfo;
2126 int hl; 2089 int hl;
2127{ 2090{
2128 struct window *w = XWINDOW (mouse_face_window); 2091 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
2129 int width = window_internal_width (w); 2092 int width = window_internal_width (w);
2130 FRAME_PTR f = XFRAME (WINDOW_FRAME (w)); 2093 FRAME_PTR f = XFRAME (WINDOW_FRAME (w));
2131 int i; 2094 int i;
@@ -2139,16 +2102,22 @@ show_mouse_face (hl)
2139 curs_x = f->phys_cursor_x; 2102 curs_x = f->phys_cursor_x;
2140 curs_y = f->phys_cursor_y; 2103 curs_y = f->phys_cursor_y;
2141 2104
2142 for (i = mouse_face_beg_row; i <= mouse_face_end_row; i++) 2105 for (i = FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row;
2106 i <= FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row; i++)
2143 { 2107 {
2144 int column = (i == mouse_face_beg_row ? mouse_face_beg_col : w->left); 2108 int column = (i == FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row
2145 int endcolumn = (i == mouse_face_end_row ? mouse_face_end_col : w->left + width); 2109 ? FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_col
2110 : w->left);
2111 int endcolumn = (i == FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row
2112 ? FRAME_X_DISPLAY_INFO (f)->mouse_face_end_col
2113 : w->left + width);
2146 endcolumn = min (endcolumn, FRAME_CURRENT_GLYPHS (f)->used[i]); 2114 endcolumn = min (endcolumn, FRAME_CURRENT_GLYPHS (f)->used[i]);
2147 2115
2148 /* If the cursor's in the text we are about to rewrite, 2116 /* If the cursor's in the text we are about to rewrite,
2149 turn the cursor off. */ 2117 turn the cursor off. */
2150 if (i == curs_y 2118 if (i == curs_y
2151 && curs_x >= mouse_face_beg_col - 1 && curs_x <= mouse_face_end_col) 2119 && curs_x >= FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_col - 1
2120 && curs_x <= FRAME_X_DISPLAY_INFO (f)->mouse_face_end_col)
2152 { 2121 {
2153 x_display_cursor (f, 0); 2122 x_display_cursor (f, 0);
2154 cursor_off = 1; 2123 cursor_off = 1;
@@ -2183,14 +2152,15 @@ show_mouse_face (hl)
2183 Redraw it unhighlighted first. */ 2152 Redraw it unhighlighted first. */
2184 2153
2185static void 2154static void
2186clear_mouse_face () 2155clear_mouse_face (dpyinfo)
2156 struct x_display_info *dpyinfo;
2187{ 2157{
2188 if (! NILP (mouse_face_window)) 2158 if (! NILP (dpyinfo->mouse_face_window))
2189 show_mouse_face (0); 2159 show_mouse_face (dpyinfo, 0);
2190 2160
2191 mouse_face_beg_row = mouse_face_beg_col = -1; 2161 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
2192 mouse_face_end_row = mouse_face_end_col = -1; 2162 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
2193 mouse_face_window = Qnil; 2163 dpyinfo->mouse_face_window = Qnil;
2194} 2164}
2195 2165
2196static struct scroll_bar *x_window_to_scroll_bar (); 2166static struct scroll_bar *x_window_to_scroll_bar ();
@@ -2422,7 +2392,7 @@ x_scroll_bar_create (window, top, left, width, height)
2422 a.event_mask = (ButtonPressMask | ButtonReleaseMask 2392 a.event_mask = (ButtonPressMask | ButtonReleaseMask
2423 | ButtonMotionMask | PointerMotionHintMask 2393 | ButtonMotionMask | PointerMotionHintMask
2424 | ExposureMask); 2394 | ExposureMask);
2425 a.cursor = x_vertical_scroll_bar_cursor; 2395 a.cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
2426 2396
2427 mask = (CWBackPixel | CWEventMask | CWCursor); 2397 mask = (CWBackPixel | CWEventMask | CWCursor);
2428 2398
@@ -2976,7 +2946,7 @@ x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
2976 2946
2977 /* Mouse buttons and modifier keys. */ 2947 /* Mouse buttons and modifier keys. */
2978 &dummy_mask)) 2948 &dummy_mask))
2979 *fp = 0; 2949 ;
2980 else 2950 else
2981 { 2951 {
2982 int inside_height 2952 int inside_height
@@ -2995,7 +2965,7 @@ x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
2995 win_y = top_range; 2965 win_y = top_range;
2996 2966
2997 *fp = f; 2967 *fp = f;
2998 *bar_window = w; 2968 *bar_window = bar->window;
2999 2969
3000 if (! NILP (bar->dragging)) 2970 if (! NILP (bar->dragging))
3001 *part = scroll_bar_handle; 2971 *part = scroll_bar_handle;
@@ -3162,6 +3132,10 @@ static XComposeStatus compose_status;
3162int temp_index; 3132int temp_index;
3163short temp_buffer[100]; 3133short temp_buffer[100];
3164 3134
3135/* Set this to nonzero to fake an "X I/O error"
3136 on a particular display. */
3137struct x_display_info *XTread_socket_fake_io_error;
3138
3165/* Read events coming from the X server. 3139/* Read events coming from the X server.
3166 This routine is called by the SIGIO handler. 3140 This routine is called by the SIGIO handler.
3167 We return as soon as there are no more events to be read. 3141 We return as soon as there are no more events to be read.
@@ -3202,635 +3176,586 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
3202 interrupt_input_pending = 0; 3176 interrupt_input_pending = 0;
3203 BLOCK_INPUT; 3177 BLOCK_INPUT;
3204 3178
3205 /* Find the display we are supposed to read input for.
3206 It's the one communicating on descriptor SD. */
3207 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
3208 if (dpyinfo->connection == sd)
3209 break;
3210 if (dpyinfo == 0)
3211 abort ();
3212
3213 /* So people can tell when we have read the available input. */ 3179 /* So people can tell when we have read the available input. */
3214 input_signal_count++; 3180 input_signal_count++;
3215 3181
3216 if (numchars <= 0) 3182 if (numchars <= 0)
3217 abort (); /* Don't think this happens. */ 3183 abort (); /* Don't think this happens. */
3218 3184
3185 /* Find the display we are supposed to read input for.
3186 It's the one communicating on descriptor SD. */
3187 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
3188 {
3189#if 0 /* This ought to be unnecessary; let's verify it. */
3219#ifdef FIOSNBIO 3190#ifdef FIOSNBIO
3220 /* If available, Xlib uses FIOSNBIO to make the socket 3191 /* If available, Xlib uses FIOSNBIO to make the socket
3221 non-blocking, and then looks for EWOULDBLOCK. If O_NDELAY is set, 3192 non-blocking, and then looks for EWOULDBLOCK. If O_NDELAY is set,
3222 FIOSNBIO is ignored, and instead of signalling EWOULDBLOCK, 3193 FIOSNBIO is ignored, and instead of signalling EWOULDBLOCK,
3223 a read returns 0, which Xlib interprets as equivalent to EPIPE. */ 3194 a read returns 0, which Xlib interprets as equivalent to EPIPE. */
3224 fcntl (sd, F_SETFL, 0); 3195 fcntl (dpyinfo->connection, F_SETFL, 0);
3225#endif /* ! defined (FIOSNBIO) */ 3196#endif /* ! defined (FIOSNBIO) */
3197#endif
3226 3198
3199#if 0 /* This code can't be made to work, with multiple displays,
3200 and appears not to be used on any system any more.
3201 Also keyboard.c doesn't turn O_NDELAY on and off
3202 for X connections. */
3227#ifndef SIGIO 3203#ifndef SIGIO
3228#ifndef HAVE_SELECT 3204#ifndef HAVE_SELECT
3229 if (! (fcntl (sd, F_GETFL, 0) & O_NDELAY)) 3205 if (! (fcntl (dpyinfo->connection, F_GETFL, 0) & O_NDELAY))
3230 { 3206 {
3231 extern int read_alarm_should_throw; 3207 extern int read_alarm_should_throw;
3232 read_alarm_should_throw = 1; 3208 read_alarm_should_throw = 1;
3233 XPeekEvent (dpyinfo->display, &event); 3209 XPeekEvent (dpyinfo->display, &event);
3234 read_alarm_should_throw = 0; 3210 read_alarm_should_throw = 0;
3235 } 3211 }
3236#endif /* HAVE_SELECT */ 3212#endif /* HAVE_SELECT */
3237#endif /* SIGIO */ 3213#endif /* SIGIO */
3214#endif
3238 3215
3239 while (XPending (dpyinfo->display) != 0) 3216 /* For debugging, this gives a way to fake an I/O error. */
3240 { 3217 if (dpyinfo == XTread_socket_fake_io_error)
3241 XNextEvent (dpyinfo->display, &event); 3218 {
3242 event_found = 1; 3219 XTread_socket_fake_io_error = 0;
3220 x_io_error_quitter (dpyinfo->display);
3221 }
3243 3222
3244 switch (event.type) 3223 while (XPending (dpyinfo->display) != 0)
3245 { 3224 {
3246 case ClientMessage: 3225 XNextEvent (dpyinfo->display, &event);
3247 { 3226 event_found = 1;
3248 if (event.xclient.message_type 3227
3249 == dpyinfo->Xatom_wm_protocols 3228 switch (event.type)
3250 && event.xclient.format == 32) 3229 {
3230 case ClientMessage:
3251 { 3231 {
3252 if (event.xclient.data.l[0] 3232 if (event.xclient.message_type
3253 == dpyinfo->Xatom_wm_take_focus) 3233 == dpyinfo->Xatom_wm_protocols
3234 && event.xclient.format == 32)
3254 { 3235 {
3255 f = x_window_to_frame (event.xclient.window); 3236 if (event.xclient.data.l[0]
3256 /* Since we set WM_TAKE_FOCUS, we must call 3237 == dpyinfo->Xatom_wm_take_focus)
3257 XSetInputFocus explicitly. But not if f is null,
3258 since that might be an event for a deleted frame. */
3259 if (f)
3260 XSetInputFocus (event.xclient.display,
3261 event.xclient.window,
3262 RevertToPointerRoot,
3263 event.xclient.data.l[1]);
3264 /* Not certain about handling scroll bars here */
3265 }
3266 else if (event.xclient.data.l[0]
3267 == dpyinfo->Xatom_wm_save_yourself)
3268 {
3269 /* Save state modify the WM_COMMAND property to
3270 something which can reinstate us. This notifies
3271 the session manager, who's looking for such a
3272 PropertyNotify. Can restart processing when
3273 a keyboard or mouse event arrives. */
3274 if (numchars > 0)
3275 { 3238 {
3276 f = x_top_window_to_frame (event.xclient.window); 3239 f = x_window_to_frame (event.xclient.window);
3277 3240 /* Since we set WM_TAKE_FOCUS, we must call
3278 /* This is just so we only give real data once 3241 XSetInputFocus explicitly. But not if f is null,
3279 for a single Emacs process. */ 3242 since that might be an event for a deleted frame. */
3280 if (f == selected_frame) 3243 if (f)
3281 XSetCommand (FRAME_X_DISPLAY (f), 3244 XSetInputFocus (event.xclient.display,
3282 event.xclient.window, 3245 event.xclient.window,
3283 initial_argv, initial_argc); 3246 RevertToPointerRoot,
3284 else 3247 event.xclient.data.l[1]);
3285 XSetCommand (FRAME_X_DISPLAY (f), 3248 /* Not certain about handling scroll bars here */
3286 event.xclient.window,
3287 0, 0);
3288 } 3249 }
3289 } 3250 else if (event.xclient.data.l[0]
3290 else if (event.xclient.data.l[0] 3251 == dpyinfo->Xatom_wm_save_yourself)
3291 == dpyinfo->Xatom_wm_delete_window) 3252 {
3292 { 3253 /* Save state modify the WM_COMMAND property to
3293 struct frame *f = x_any_window_to_frame (event.xclient.window); 3254 something which can reinstate us. This notifies
3294 3255 the session manager, who's looking for such a
3295 if (f) 3256 PropertyNotify. Can restart processing when
3257 a keyboard or mouse event arrives. */
3258 if (numchars > 0)
3259 {
3260 f = x_top_window_to_frame (event.xclient.window);
3261
3262 /* This is just so we only give real data once
3263 for a single Emacs process. */
3264 if (f == selected_frame)
3265 XSetCommand (FRAME_X_DISPLAY (f),
3266 event.xclient.window,
3267 initial_argv, initial_argc);
3268 else
3269 XSetCommand (FRAME_X_DISPLAY (f),
3270 event.xclient.window,
3271 0, 0);
3272 }
3273 }
3274 else if (event.xclient.data.l[0]
3275 == dpyinfo->Xatom_wm_delete_window)
3296 { 3276 {
3297 if (numchars == 0) 3277 struct frame *f = x_any_window_to_frame (event.xclient.window);
3298 abort ();
3299 3278
3300 bufp->kind = delete_window_event; 3279 if (f)
3301 XSETFRAME (bufp->frame_or_window, f); 3280 {
3302 bufp++; 3281 if (numchars == 0)
3282 abort ();
3303 3283
3304 count += 1; 3284 bufp->kind = delete_window_event;
3305 numchars -= 1; 3285 XSETFRAME (bufp->frame_or_window, f);
3286 bufp++;
3287
3288 count += 1;
3289 numchars -= 1;
3290 }
3306 } 3291 }
3307 } 3292 }
3308 } 3293 else if (event.xclient.message_type
3309 else if (event.xclient.message_type 3294 == dpyinfo->Xatom_wm_configure_denied)
3310 == dpyinfo->Xatom_wm_configure_denied) 3295 {
3311 { 3296 }
3312 } 3297 else if (event.xclient.message_type
3313 else if (event.xclient.message_type 3298 == dpyinfo->Xatom_wm_window_moved)
3314 == dpyinfo->Xatom_wm_window_moved) 3299 {
3315 { 3300 int new_x, new_y;
3316 int new_x, new_y; 3301 struct frame *f = x_window_to_frame (event.xclient.window);
3317 struct frame *f = x_window_to_frame (event.xclient.window);
3318 3302
3319 new_x = event.xclient.data.s[0]; 3303 new_x = event.xclient.data.s[0];
3320 new_y = event.xclient.data.s[1]; 3304 new_y = event.xclient.data.s[1];
3321 3305
3322 if (f) 3306 if (f)
3323 { 3307 {
3324 f->display.x->left_pos = new_x; 3308 f->display.x->left_pos = new_x;
3325 f->display.x->top_pos = new_y; 3309 f->display.x->top_pos = new_y;
3310 }
3326 } 3311 }
3327 }
3328#if defined (USE_X_TOOLKIT) && defined (HAVE_X11R5) 3312#if defined (USE_X_TOOLKIT) && defined (HAVE_X11R5)
3329 else if (event.xclient.message_type 3313 else if (event.xclient.message_type
3330 == dpyinfo->Xatom_editres) 3314 == dpyinfo->Xatom_editres)
3331 { 3315 {
3332 struct frame *f = x_any_window_to_frame (event.xclient.window); 3316 struct frame *f = x_any_window_to_frame (event.xclient.window);
3333 _XEditResCheckMessages (f->display.x->widget, NULL, &event, NULL); 3317 _XEditResCheckMessages (f->display.x->widget, NULL, &event, NULL);
3334 } 3318 }
3335#endif /* USE_X_TOOLKIT and HAVE_X11R5 */ 3319#endif /* USE_X_TOOLKIT and HAVE_X11R5 */
3336 } 3320 }
3337 break; 3321 break;
3338 3322
3339 case SelectionNotify: 3323 case SelectionNotify:
3340#ifdef USE_X_TOOLKIT 3324#ifdef USE_X_TOOLKIT
3341 if (! x_window_to_frame (event.xselection.requestor)) 3325 if (! x_window_to_frame (event.xselection.requestor))
3342 goto OTHER; 3326 goto OTHER;
3343#endif /* not USE_X_TOOLKIT */ 3327#endif /* not USE_X_TOOLKIT */
3344 x_handle_selection_notify (&event); 3328 x_handle_selection_notify (&event);
3345 break; 3329 break;
3346 3330
3347 case SelectionClear: /* Someone has grabbed ownership. */ 3331 case SelectionClear: /* Someone has grabbed ownership. */
3348#ifdef USE_X_TOOLKIT 3332#ifdef USE_X_TOOLKIT
3349 if (! x_window_to_frame (event.xselectionclear.window)) 3333 if (! x_window_to_frame (event.xselectionclear.window))
3350 goto OTHER; 3334 goto OTHER;
3351#endif /* USE_X_TOOLKIT */ 3335#endif /* USE_X_TOOLKIT */
3352 { 3336 {
3353 XSelectionClearEvent *eventp = (XSelectionClearEvent *) &event; 3337 XSelectionClearEvent *eventp = (XSelectionClearEvent *) &event;
3354 3338
3355 if (numchars == 0) 3339 if (numchars == 0)
3356 abort (); 3340 abort ();
3357 3341
3358 bufp->kind = selection_clear_event; 3342 bufp->kind = selection_clear_event;
3359 SELECTION_EVENT_DISPLAY (bufp) = eventp->display; 3343 SELECTION_EVENT_DISPLAY (bufp) = eventp->display;
3360 SELECTION_EVENT_SELECTION (bufp) = eventp->selection; 3344 SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
3361 SELECTION_EVENT_TIME (bufp) = eventp->time; 3345 SELECTION_EVENT_TIME (bufp) = eventp->time;
3362 bufp++; 3346 bufp++;
3363 3347
3364 count += 1; 3348 count += 1;
3365 numchars -= 1; 3349 numchars -= 1;
3366 } 3350 }
3367 break; 3351 break;
3368 3352
3369 case SelectionRequest: /* Someone wants our selection. */ 3353 case SelectionRequest: /* Someone wants our selection. */
3370#ifdef USE_X_TOOLKIT 3354#ifdef USE_X_TOOLKIT
3371 if (!x_window_to_frame (event.xselectionrequest.owner)) 3355 if (!x_window_to_frame (event.xselectionrequest.owner))
3372 goto OTHER; 3356 goto OTHER;
3373#endif /* USE_X_TOOLKIT */ 3357#endif /* USE_X_TOOLKIT */
3374 if (x_queue_selection_requests) 3358 if (x_queue_selection_requests)
3375 x_queue_event (x_window_to_frame (event.xselectionrequest.owner), 3359 x_queue_event (x_window_to_frame (event.xselectionrequest.owner),
3376 &event); 3360 &event);
3377 else 3361 else
3378 { 3362 {
3379 XSelectionRequestEvent *eventp = (XSelectionRequestEvent *) &event; 3363 XSelectionRequestEvent *eventp = (XSelectionRequestEvent *) &event;
3380
3381 if (numchars == 0)
3382 abort ();
3383
3384 bufp->kind = selection_request_event;
3385 SELECTION_EVENT_DISPLAY (bufp) = eventp->display;
3386 SELECTION_EVENT_REQUESTOR (bufp) = eventp->requestor;
3387 SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
3388 SELECTION_EVENT_TARGET (bufp) = eventp->target;
3389 SELECTION_EVENT_PROPERTY (bufp) = eventp->property;
3390 SELECTION_EVENT_TIME (bufp) = eventp->time;
3391 bufp++;
3392
3393 count += 1;
3394 numchars -= 1;
3395 }
3396 break;
3397 3364
3398 case PropertyNotify: 3365 if (numchars == 0)
3366 abort ();
3367
3368 bufp->kind = selection_request_event;
3369 SELECTION_EVENT_DISPLAY (bufp) = eventp->display;
3370 SELECTION_EVENT_REQUESTOR (bufp) = eventp->requestor;
3371 SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
3372 SELECTION_EVENT_TARGET (bufp) = eventp->target;
3373 SELECTION_EVENT_PROPERTY (bufp) = eventp->property;
3374 SELECTION_EVENT_TIME (bufp) = eventp->time;
3375 bufp++;
3376
3377 count += 1;
3378 numchars -= 1;
3379 }
3380 break;
3381
3382 case PropertyNotify:
3399#ifdef USE_X_TOOLKIT 3383#ifdef USE_X_TOOLKIT
3400 if (!x_any_window_to_frame (event.xproperty.window)) 3384 if (!x_any_window_to_frame (event.xproperty.window))
3401 goto OTHER; 3385 goto OTHER;
3402#endif /* not USE_X_TOOLKIT */ 3386#endif /* not USE_X_TOOLKIT */
3403 x_handle_property_notify (&event); 3387 x_handle_property_notify (&event);
3404 break; 3388 break;
3405 3389
3406 case ReparentNotify: 3390 case ReparentNotify:
3407 f = x_top_window_to_frame (event.xreparent.window); 3391 f = x_top_window_to_frame (event.xreparent.window);
3408 if (f) 3392 if (f)
3409 { 3393 {
3410 int x, y; 3394 int x, y;
3411 f->display.x->parent_desc = event.xreparent.parent; 3395 f->display.x->parent_desc = event.xreparent.parent;
3412 x_real_positions (f, &x, &y); 3396 x_real_positions (f, &x, &y);
3413 f->display.x->left_pos = x; 3397 f->display.x->left_pos = x;
3414 f->display.x->top_pos = y; 3398 f->display.x->top_pos = y;
3415 } 3399 }
3416 break; 3400 break;
3417 3401
3418 case Expose: 3402 case Expose:
3419 f = x_window_to_frame (event.xexpose.window); 3403 f = x_window_to_frame (event.xexpose.window);
3420 if (f) 3404 if (f)
3421 {
3422 if (f->async_visible == 0)
3423 { 3405 {
3424 f->async_visible = 1; 3406 if (f->async_visible == 0)
3425 f->async_iconified = 0; 3407 {
3426 SET_FRAME_GARBAGED (f); 3408 f->async_visible = 1;
3409 f->async_iconified = 0;
3410 SET_FRAME_GARBAGED (f);
3411 }
3412 else
3413 dumprectangle (x_window_to_frame (event.xexpose.window),
3414 event.xexpose.x, event.xexpose.y,
3415 event.xexpose.width, event.xexpose.height);
3427 } 3416 }
3428 else 3417 else
3429 dumprectangle (x_window_to_frame (event.xexpose.window), 3418 {
3430 event.xexpose.x, event.xexpose.y, 3419 struct scroll_bar *bar
3431 event.xexpose.width, event.xexpose.height); 3420 = x_window_to_scroll_bar (event.xexpose.window);
3432 }
3433 else
3434 {
3435 struct scroll_bar *bar
3436 = x_window_to_scroll_bar (event.xexpose.window);
3437 3421
3438 if (bar) 3422 if (bar)
3439 x_scroll_bar_expose (bar, &event); 3423 x_scroll_bar_expose (bar, &event);
3440#ifdef USE_X_TOOLKIT 3424#ifdef USE_X_TOOLKIT
3441 else 3425 else
3442 goto OTHER; 3426 goto OTHER;
3443#endif /* USE_X_TOOLKIT */ 3427#endif /* USE_X_TOOLKIT */
3444 } 3428 }
3445 break; 3429 break;
3446 3430
3447 case GraphicsExpose: /* This occurs when an XCopyArea's 3431 case GraphicsExpose: /* This occurs when an XCopyArea's
3448 source area was obscured or not 3432 source area was obscured or not
3449 available.*/ 3433 available.*/
3450 f = x_window_to_frame (event.xgraphicsexpose.drawable); 3434 f = x_window_to_frame (event.xgraphicsexpose.drawable);
3451 if (f) 3435 if (f)
3452 { 3436 {
3453 dumprectangle (f, 3437 dumprectangle (f,
3454 event.xgraphicsexpose.x, event.xgraphicsexpose.y, 3438 event.xgraphicsexpose.x, event.xgraphicsexpose.y,
3455 event.xgraphicsexpose.width, 3439 event.xgraphicsexpose.width,
3456 event.xgraphicsexpose.height); 3440 event.xgraphicsexpose.height);
3457 } 3441 }
3458#ifdef USE_X_TOOLKIT 3442#ifdef USE_X_TOOLKIT
3459 else 3443 else
3460 goto OTHER; 3444 goto OTHER;
3461#endif /* USE_X_TOOLKIT */ 3445#endif /* USE_X_TOOLKIT */
3462 break; 3446 break;
3463 3447
3464 case NoExpose: /* This occurs when an XCopyArea's 3448 case NoExpose: /* This occurs when an XCopyArea's
3465 source area was completely 3449 source area was completely
3466 available */ 3450 available */
3467 break; 3451 break;
3468 3452
3469 case UnmapNotify: 3453 case UnmapNotify:
3470 f = x_any_window_to_frame (event.xunmap.window); 3454 f = x_any_window_to_frame (event.xunmap.window);
3471 if (f) /* F may no longer exist if 3455 if (f) /* F may no longer exist if
3472 the frame was deleted. */ 3456 the frame was deleted. */
3473 { 3457 {
3474 /* While a frame is unmapped, display generation is 3458 /* While a frame is unmapped, display generation is
3475 disabled; you don't want to spend time updating a 3459 disabled; you don't want to spend time updating a
3476 display that won't ever be seen. */ 3460 display that won't ever be seen. */
3477 f->async_visible = 0; 3461 f->async_visible = 0;
3478 /* We can't distinguish, from the event, whether the window 3462 /* We can't distinguish, from the event, whether the window
3479 has become iconified or invisible. So assume, if it 3463 has become iconified or invisible. So assume, if it
3480 was previously visible, than now it is iconified. 3464 was previously visible, than now it is iconified.
3481 We depend on x_make_frame_invisible to mark it iconified. */ 3465 We depend on x_make_frame_invisible to mark it iconified. */
3482 if (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)) 3466 if (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f))
3483 f->async_iconified = 1; 3467 f->async_iconified = 1;
3484 } 3468 }
3485#ifdef USE_X_TOOLKIT 3469#ifdef USE_X_TOOLKIT
3486 goto OTHER; 3470 goto OTHER;
3487#endif /* USE_X_TOOLKIT */ 3471#endif /* USE_X_TOOLKIT */
3488 break; 3472 break;
3489 3473
3490 case MapNotify: 3474 case MapNotify:
3491 /* We use x_top_window_to_frame because map events can come 3475 /* We use x_top_window_to_frame because map events can come
3492 for subwindows and they don't mean that the frame is visible. */ 3476 for subwindows and they don't mean that the frame is visible. */
3493 f = x_top_window_to_frame (event.xmap.window); 3477 f = x_top_window_to_frame (event.xmap.window);
3494 if (f) 3478 if (f)
3495 { 3479 {
3496 f->async_visible = 1; 3480 f->async_visible = 1;
3497 f->async_iconified = 0; 3481 f->async_iconified = 0;
3498 3482
3499 /* wait_reading_process_input will notice this and update 3483 /* wait_reading_process_input will notice this and update
3500 the frame's display structures. */ 3484 the frame's display structures. */
3501 SET_FRAME_GARBAGED (f); 3485 SET_FRAME_GARBAGED (f);
3502 } 3486 }
3503#ifdef USE_X_TOOLKIT 3487#ifdef USE_X_TOOLKIT
3504 goto OTHER; 3488 goto OTHER;
3505#endif /* USE_X_TOOLKIT */ 3489#endif /* USE_X_TOOLKIT */
3506 break; 3490 break;
3507 3491
3508 /* Turn off processing if we become fully obscured. */ 3492 /* Turn off processing if we become fully obscured. */
3509 case VisibilityNotify: 3493 case VisibilityNotify:
3510 break; 3494 break;
3511 3495
3512 case KeyPress: 3496 case KeyPress:
3513 f = x_any_window_to_frame (event.xkey.window); 3497 f = x_any_window_to_frame (event.xkey.window);
3514 3498
3515 if (f != 0) 3499 if (f != 0)
3516 { 3500 {
3517 KeySym keysym, orig_keysym; 3501 KeySym keysym, orig_keysym;
3518 /* al%imercury@uunet.uu.net says that making this 81 instead of 3502 /* al%imercury@uunet.uu.net says that making this 81 instead of
3519 80 fixed a bug whereby meta chars made his Emacs hang. */ 3503 80 fixed a bug whereby meta chars made his Emacs hang. */
3520 unsigned char copy_buffer[81]; 3504 unsigned char copy_buffer[81];
3521 int modifiers; 3505 int modifiers;
3522 3506
3523 event.xkey.state 3507 event.xkey.state
3524 |= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f), 3508 |= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f),
3525 extra_keyboard_modifiers); 3509 extra_keyboard_modifiers);
3526 modifiers = event.xkey.state; 3510 modifiers = event.xkey.state;
3527 3511
3528 /* This will have to go some day... */ 3512 /* This will have to go some day... */
3529 3513
3530 /* make_lispy_event turns chars into control chars. 3514 /* make_lispy_event turns chars into control chars.
3531 Don't do it here because XLookupString is too eager. */ 3515 Don't do it here because XLookupString is too eager. */
3532 event.xkey.state &= ~ControlMask; 3516 event.xkey.state &= ~ControlMask;
3533 nbytes = 3517 nbytes =
3534 XLookupString (&event.xkey, copy_buffer, 80, &keysym, 3518 XLookupString (&event.xkey, copy_buffer, 80, &keysym,
3535 &compose_status); 3519 &compose_status);
3536 3520
3537 orig_keysym = keysym; 3521 orig_keysym = keysym;
3538 3522
3539 if (numchars > 1) 3523 if (numchars > 1)
3540 { 3524 {
3541 if (((keysym >= XK_BackSpace && keysym <= XK_Escape) 3525 if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
3542 || keysym == XK_Delete 3526 || keysym == XK_Delete
3543 || IsCursorKey (keysym) /* 0xff50 <= x < 0xff60 */ 3527 || IsCursorKey (keysym) /* 0xff50 <= x < 0xff60 */
3544 || IsMiscFunctionKey (keysym) /* 0xff60 <= x < VARIES */ 3528 || IsMiscFunctionKey (keysym) /* 0xff60 <= x < VARIES */
3545#ifdef HPUX 3529#ifdef HPUX
3546 /* This recognizes the "extended function keys". 3530 /* This recognizes the "extended function keys".
3547 It seems there's no cleaner way. 3531 It seems there's no cleaner way.
3548 Test IsModifierKey to avoid handling mode_switch 3532 Test IsModifierKey to avoid handling mode_switch
3549 incorrectly. */ 3533 incorrectly. */
3550 || ((unsigned) (keysym) >= XK_Select 3534 || ((unsigned) (keysym) >= XK_Select
3551 && (unsigned)(keysym) < XK_KP_Space) 3535 && (unsigned)(keysym) < XK_KP_Space)
3552#endif 3536#endif
3553#ifdef XK_dead_circumflex 3537#ifdef XK_dead_circumflex
3554 || orig_keysym == XK_dead_circumflex 3538 || orig_keysym == XK_dead_circumflex
3555#endif 3539#endif
3556#ifdef XK_dead_grave 3540#ifdef XK_dead_grave
3557 || orig_keysym == XK_dead_grave 3541 || orig_keysym == XK_dead_grave
3558#endif 3542#endif
3559#ifdef XK_dead_tilde 3543#ifdef XK_dead_tilde
3560 || orig_keysym == XK_dead_tilde 3544 || orig_keysym == XK_dead_tilde
3561#endif 3545#endif
3562#ifdef XK_dead_diaeresis 3546#ifdef XK_dead_diaeresis
3563 || orig_keysym == XK_dead_diaeresis 3547 || orig_keysym == XK_dead_diaeresis
3564#endif 3548#endif
3565#ifdef XK_dead_macron 3549#ifdef XK_dead_macron
3566 || orig_keysym == XK_dead_macron 3550 || orig_keysym == XK_dead_macron
3567#endif 3551#endif
3568#ifdef XK_dead_degree 3552#ifdef XK_dead_degree
3569 || orig_keysym == XK_dead_degree 3553 || orig_keysym == XK_dead_degree
3570#endif 3554#endif
3571#ifdef XK_dead_acute 3555#ifdef XK_dead_acute
3572 || orig_keysym == XK_dead_acute 3556 || orig_keysym == XK_dead_acute
3573#endif 3557#endif
3574#ifdef XK_dead_cedilla 3558#ifdef XK_dead_cedilla
3575 || orig_keysym == XK_dead_cedilla 3559 || orig_keysym == XK_dead_cedilla
3576#endif 3560#endif
3577#ifdef XK_dead_breve 3561#ifdef XK_dead_breve
3578 || orig_keysym == XK_dead_breve 3562 || orig_keysym == XK_dead_breve
3579#endif 3563#endif
3580#ifdef XK_dead_ogonek 3564#ifdef XK_dead_ogonek
3581 || orig_keysym == XK_dead_ogonek 3565 || orig_keysym == XK_dead_ogonek
3582#endif 3566#endif
3583#ifdef XK_dead_caron 3567#ifdef XK_dead_caron
3584 || orig_keysym == XK_dead_caron 3568 || orig_keysym == XK_dead_caron
3585#endif 3569#endif
3586#ifdef XK_dead_doubleacute 3570#ifdef XK_dead_doubleacute
3587 || orig_keysym == XK_dead_doubleacute 3571 || orig_keysym == XK_dead_doubleacute
3588#endif 3572#endif
3589#ifdef XK_dead_abovedot 3573#ifdef XK_dead_abovedot
3590 || orig_keysym == XK_dead_abovedot 3574 || orig_keysym == XK_dead_abovedot
3591#endif 3575#endif
3592 || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */ 3576 || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */
3593 || IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */ 3577 || IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */
3594 /* Any "vendor-specific" key is ok. */ 3578 /* Any "vendor-specific" key is ok. */
3595 || (orig_keysym & (1 << 28))) 3579 || (orig_keysym & (1 << 28)))
3596 && ! (IsModifierKey (orig_keysym) 3580 && ! (IsModifierKey (orig_keysym)
3597#ifndef HAVE_X11R5 3581#ifndef HAVE_X11R5
3598#ifdef XK_Mode_switch 3582#ifdef XK_Mode_switch
3599 || ((unsigned)(orig_keysym) == XK_Mode_switch) 3583 || ((unsigned)(orig_keysym) == XK_Mode_switch)
3600#endif 3584#endif
3601#ifdef XK_Num_Lock 3585#ifdef XK_Num_Lock
3602 || ((unsigned)(orig_keysym) == XK_Num_Lock) 3586 || ((unsigned)(orig_keysym) == XK_Num_Lock)
3603#endif 3587#endif
3604#endif /* not HAVE_X11R5 */ 3588#endif /* not HAVE_X11R5 */
3605 )) 3589 ))
3606 {
3607 if (temp_index == sizeof temp_buffer / sizeof (short))
3608 temp_index = 0;
3609 temp_buffer[temp_index++] = keysym;
3610 bufp->kind = non_ascii_keystroke;
3611 bufp->code = keysym;
3612 XSETFRAME (bufp->frame_or_window, f);
3613 bufp->modifiers
3614 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
3615 modifiers);
3616 bufp->timestamp = event.xkey.time;
3617 bufp++;
3618 count++;
3619 numchars--;
3620 }
3621 else if (numchars > nbytes)
3622 {
3623 register int i;
3624
3625 for (i = 0; i < nbytes; i++)
3626 { 3590 {
3627 if (temp_index == sizeof temp_buffer / sizeof (short)) 3591 if (temp_index == sizeof temp_buffer / sizeof (short))
3628 temp_index = 0; 3592 temp_index = 0;
3629 temp_buffer[temp_index++] = copy_buffer[i]; 3593 temp_buffer[temp_index++] = keysym;
3630 bufp->kind = ascii_keystroke; 3594 bufp->kind = non_ascii_keystroke;
3631 bufp->code = copy_buffer[i]; 3595 bufp->code = keysym;
3632 XSETFRAME (bufp->frame_or_window, f); 3596 XSETFRAME (bufp->frame_or_window, f);
3633 bufp->modifiers 3597 bufp->modifiers
3634 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), 3598 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
3635 modifiers); 3599 modifiers);
3636 bufp->timestamp = event.xkey.time; 3600 bufp->timestamp = event.xkey.time;
3637 bufp++; 3601 bufp++;
3602 count++;
3603 numchars--;
3638 } 3604 }
3639 3605 else if (numchars > nbytes)
3640 count += nbytes; 3606 {
3641 numchars -= nbytes; 3607 register int i;
3608
3609 for (i = 0; i < nbytes; i++)
3610 {
3611 if (temp_index == sizeof temp_buffer / sizeof (short))
3612 temp_index = 0;
3613 temp_buffer[temp_index++] = copy_buffer[i];
3614 bufp->kind = ascii_keystroke;
3615 bufp->code = copy_buffer[i];
3616 XSETFRAME (bufp->frame_or_window, f);
3617 bufp->modifiers
3618 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
3619 modifiers);
3620 bufp->timestamp = event.xkey.time;
3621 bufp++;
3622 }
3623
3624 count += nbytes;
3625 numchars -= nbytes;
3626 }
3627 else
3628 abort ();
3642 } 3629 }
3643 else 3630 else
3644 abort (); 3631 abort ();
3645 } 3632 }
3646 else 3633 break;
3647 abort ();
3648 }
3649 break;
3650 3634
3651 /* Here's a possible interpretation of the whole 3635 /* Here's a possible interpretation of the whole
3652 FocusIn-EnterNotify FocusOut-LeaveNotify mess. If you get a 3636 FocusIn-EnterNotify FocusOut-LeaveNotify mess. If you get a
3653 FocusIn event, you have to get a FocusOut event before you 3637 FocusIn event, you have to get a FocusOut event before you
3654 relinquish the focus. If you haven't received a FocusIn event, 3638 relinquish the focus. If you haven't received a FocusIn event,
3655 then a mere LeaveNotify is enough to free you. */ 3639 then a mere LeaveNotify is enough to free you. */
3656 3640
3657 case EnterNotify: 3641 case EnterNotify:
3658 f = x_any_window_to_frame (event.xcrossing.window); 3642 f = x_any_window_to_frame (event.xcrossing.window);
3659 3643
3660 if (event.xcrossing.focus) /* Entered Window */ 3644 if (event.xcrossing.focus) /* Entered Window */
3661 {
3662 /* Avoid nasty pop/raise loops. */
3663 if (f && (!(f->auto_raise)
3664 || !(f->auto_lower)
3665 || (event.xcrossing.time - enter_timestamp) > 500))
3666 { 3645 {
3667 x_new_focus_frame (f); 3646 /* Avoid nasty pop/raise loops. */
3668 enter_timestamp = event.xcrossing.time; 3647 if (f && (!(f->auto_raise)
3648 || !(f->auto_lower)
3649 || (event.xcrossing.time - enter_timestamp) > 500))
3650 {
3651 x_new_focus_frame (f);
3652 enter_timestamp = event.xcrossing.time;
3653 }
3669 } 3654 }
3670 } 3655 else if (f == x_focus_frame)
3671 else if (f == x_focus_frame) 3656 x_new_focus_frame (0);
3672 x_new_focus_frame (0); 3657 /* EnterNotify counts as mouse movement,
3673 /* EnterNotify counts as mouse movement, 3658 so update things that depend on mouse position. */
3674 so update things that depend on mouse position. */ 3659 if (f)
3675 if (f) 3660 note_mouse_movement (f, &event.xmotion);
3676 note_mouse_movement (f, &event.xmotion);
3677#ifdef USE_X_TOOLKIT 3661#ifdef USE_X_TOOLKIT
3678 goto OTHER; 3662 goto OTHER;
3679#endif /* USE_X_TOOLKIT */ 3663#endif /* USE_X_TOOLKIT */
3680 break; 3664 break;
3681 3665
3682 case FocusIn: 3666 case FocusIn:
3683 f = x_any_window_to_frame (event.xfocus.window); 3667 f = x_any_window_to_frame (event.xfocus.window);
3684 if (event.xfocus.detail != NotifyPointer) 3668 if (event.xfocus.detail != NotifyPointer)
3685 x_focus_event_frame = f; 3669 x_focus_event_frame = f;
3686 if (f) 3670 if (f)
3687 x_new_focus_frame (f); 3671 x_new_focus_frame (f);
3688#ifdef USE_X_TOOLKIT 3672#ifdef USE_X_TOOLKIT
3689 goto OTHER; 3673 goto OTHER;
3690#endif /* USE_X_TOOLKIT */ 3674#endif /* USE_X_TOOLKIT */
3691 break; 3675 break;
3692
3693 3676
3694 case LeaveNotify:
3695 f = x_top_window_to_frame (event.xcrossing.window);
3696 if (f)
3697 {
3698 if (f == mouse_face_mouse_frame)
3699 /* If we move outside the frame,
3700 then we're certainly no longer on any text in the frame. */
3701 clear_mouse_face ();
3702 3677
3703 if (event.xcrossing.focus) 3678 case LeaveNotify:
3679 f = x_top_window_to_frame (event.xcrossing.window);
3680 if (f)
3704 { 3681 {
3705 if (! x_focus_event_frame) 3682 if (f == dpyinfo->mouse_face_mouse_frame)
3706 x_new_focus_frame (0); 3683 /* If we move outside the frame,
3684 then we're certainly no longer on any text in the frame. */
3685 clear_mouse_face (dpyinfo);
3686
3687 if (event.xcrossing.focus)
3688 {
3689 if (! x_focus_event_frame)
3690 x_new_focus_frame (0);
3691 else
3692 x_new_focus_frame (f);
3693 }
3707 else 3694 else
3708 x_new_focus_frame (f); 3695 {
3709 } 3696 if (f == x_focus_event_frame)
3710 else 3697 x_focus_event_frame = 0;
3711 { 3698 if (f == x_focus_frame)
3712 if (f == x_focus_event_frame) 3699 x_new_focus_frame (0);
3713 x_focus_event_frame = 0; 3700 }
3714 if (f == x_focus_frame)
3715 x_new_focus_frame (0);
3716 } 3701 }
3717 }
3718#ifdef USE_X_TOOLKIT 3702#ifdef USE_X_TOOLKIT
3719 goto OTHER; 3703 goto OTHER;
3720#endif /* USE_X_TOOLKIT */ 3704#endif /* USE_X_TOOLKIT */
3721 break; 3705 break;
3722 3706
3723 case FocusOut: 3707 case FocusOut:
3724 f = x_any_window_to_frame (event.xfocus.window); 3708 f = x_any_window_to_frame (event.xfocus.window);
3725 if (event.xfocus.detail != NotifyPointer 3709 if (event.xfocus.detail != NotifyPointer
3726 && f == x_focus_event_frame) 3710 && f == x_focus_event_frame)
3727 x_focus_event_frame = 0; 3711 x_focus_event_frame = 0;
3728 if (f && f == x_focus_frame) 3712 if (f && f == x_focus_frame)
3729 x_new_focus_frame (0); 3713 x_new_focus_frame (0);
3730#ifdef USE_X_TOOLKIT 3714#ifdef USE_X_TOOLKIT
3731 goto OTHER; 3715 goto OTHER;
3732#endif /* USE_X_TOOLKIT */ 3716#endif /* USE_X_TOOLKIT */
3733 break; 3717 break;
3734 3718
3735 case MotionNotify: 3719 case MotionNotify:
3736 {
3737 if (dpyinfo->grabbed && last_mouse_frame
3738 && FRAME_LIVE_P (last_mouse_frame))
3739 f = last_mouse_frame;
3740 else
3741 f = x_window_to_frame (event.xmotion.window);
3742 if (f)
3743 note_mouse_movement (f, &event.xmotion);
3744 else
3745 { 3720 {
3746 struct scroll_bar *bar 3721 if (dpyinfo->grabbed && last_mouse_frame
3747 = x_window_to_scroll_bar (event.xmotion.window); 3722 && FRAME_LIVE_P (last_mouse_frame))
3723 f = last_mouse_frame;
3724 else
3725 f = x_window_to_frame (event.xmotion.window);
3726 if (f)
3727 note_mouse_movement (f, &event.xmotion);
3728 else
3729 {
3730 struct scroll_bar *bar
3731 = x_window_to_scroll_bar (event.xmotion.window);
3748 3732
3749 if (bar) 3733 if (bar)
3750 x_scroll_bar_note_movement (bar, &event); 3734 x_scroll_bar_note_movement (bar, &event);
3751 3735
3752 /* If we move outside the frame, 3736 /* If we move outside the frame,
3753 then we're certainly no longer on any text in the frame. */ 3737 then we're certainly no longer on any text in the frame. */
3754 clear_mouse_face (); 3738 clear_mouse_face (dpyinfo);
3739 }
3755 } 3740 }
3756 }
3757#if 0 /* This should be unnecessary, since the toolkit has no use 3741#if 0 /* This should be unnecessary, since the toolkit has no use
3758 for motion events that happen outside of the menu event loop, 3742 for motion events that happen outside of the menu event loop,
3759 and it seems to cause the bug that mouse events stop coming 3743 and it seems to cause the bug that mouse events stop coming
3760 after a while. */ 3744 after a while. */
3761#ifdef USE_X_TOOLKIT 3745#ifdef USE_X_TOOLKIT
3762 goto OTHER; 3746 goto OTHER;
3763#endif /* USE_X_TOOLKIT */ 3747#endif /* USE_X_TOOLKIT */
3764#endif 3748#endif
3765 break; 3749 break;
3766 3750
3767 case ConfigureNotify: 3751 case ConfigureNotify:
3768 f = x_any_window_to_frame (event.xconfigure.window); 3752 f = x_any_window_to_frame (event.xconfigure.window);
3769#ifdef USE_X_TOOLKIT 3753#ifdef USE_X_TOOLKIT
3770 if (f 3754 if (f
3771#if 0 3755#if 0
3772 && ! event.xconfigure.send_event 3756 && ! event.xconfigure.send_event
3773#endif 3757#endif
3774 && (event.xconfigure.window == XtWindow (f->display.x->widget))) 3758 && (event.xconfigure.window == XtWindow (f->display.x->widget)))
3775 {
3776 Window win, child;
3777 int win_x, win_y;
3778
3779 /* Find the position of the outside upper-left corner of
3780 the window, in the root coordinate system. Don't
3781 refer to the parent window here; we may be processing
3782 this event after the window manager has changed our
3783 parent, but before we have reached the ReparentNotify. */
3784 XTranslateCoordinates (FRAME_X_DISPLAY (f),
3785
3786 /* From-window, to-window. */
3787 XtWindow (f->display.x->widget),
3788 FRAME_X_DISPLAY_INFO (f)->root_window,
3789
3790 /* From-position, to-position. */
3791 -event.xconfigure.border_width,
3792 -event.xconfigure.border_width,
3793 &win_x, &win_y,
3794
3795 /* Child of win. */
3796 &child);
3797 event.xconfigure.x = win_x;
3798 event.xconfigure.y = win_y;
3799
3800 f->display.x->pixel_width = event.xconfigure.width;
3801 f->display.x->pixel_height = event.xconfigure.height;
3802 f->display.x->left_pos = event.xconfigure.x;
3803 f->display.x->top_pos = event.xconfigure.y;
3804
3805 /* What we have now is the position of Emacs's own window.
3806 Convert that to the position of the window manager window. */
3807 {
3808 int x, y;
3809 x_real_positions (f, &x, &y);
3810 f->display.x->left_pos = x;
3811 f->display.x->top_pos = y;
3812 }
3813 }
3814 goto OTHER;
3815#else /* not USE_X_TOOLKIT */
3816 if (f)
3817 {
3818 int rows = PIXEL_TO_CHAR_HEIGHT (f, event.xconfigure.height);
3819 int columns = PIXEL_TO_CHAR_WIDTH (f, event.xconfigure.width);
3820
3821 /* Even if the number of character rows and columns has
3822 not changed, the font size may have changed, so we need
3823 to check the pixel dimensions as well. */
3824 if (columns != f->width
3825 || rows != f->height
3826 || event.xconfigure.width != f->display.x->pixel_width
3827 || event.xconfigure.height != f->display.x->pixel_height)
3828 {
3829 change_frame_size (f, rows, columns, 0, 1);
3830 SET_FRAME_GARBAGED (f);
3831 }
3832
3833 if (! event.xconfigure.send_event)
3834 { 3759 {
3835 Window win, child; 3760 Window win, child;
3836 int win_x, win_y; 3761 int win_x, win_y;
@@ -3843,7 +3768,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
3843 XTranslateCoordinates (FRAME_X_DISPLAY (f), 3768 XTranslateCoordinates (FRAME_X_DISPLAY (f),
3844 3769
3845 /* From-window, to-window. */ 3770 /* From-window, to-window. */
3846 f->display.x->window_desc, 3771 XtWindow (f->display.x->widget),
3847 FRAME_X_DISPLAY_INFO (f)->root_window, 3772 FRAME_X_DISPLAY_INFO (f)->root_window,
3848 3773
3849 /* From-position, to-position. */ 3774 /* From-position, to-position. */
@@ -3855,119 +3780,179 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
3855 &child); 3780 &child);
3856 event.xconfigure.x = win_x; 3781 event.xconfigure.x = win_x;
3857 event.xconfigure.y = win_y; 3782 event.xconfigure.y = win_y;
3783
3784 f->display.x->pixel_width = event.xconfigure.width;
3785 f->display.x->pixel_height = event.xconfigure.height;
3786 f->display.x->left_pos = event.xconfigure.x;
3787 f->display.x->top_pos = event.xconfigure.y;
3788
3789 /* What we have now is the position of Emacs's own window.
3790 Convert that to the position of the window manager window. */
3791 {
3792 int x, y;
3793 x_real_positions (f, &x, &y);
3794 f->display.x->left_pos = x;
3795 f->display.x->top_pos = y;
3796 }
3858 } 3797 }
3798 goto OTHER;
3799#else /* not USE_X_TOOLKIT */
3800 if (f)
3801 {
3802 int rows = PIXEL_TO_CHAR_HEIGHT (f, event.xconfigure.height);
3803 int columns = PIXEL_TO_CHAR_WIDTH (f, event.xconfigure.width);
3804
3805 /* Even if the number of character rows and columns has
3806 not changed, the font size may have changed, so we need
3807 to check the pixel dimensions as well. */
3808 if (columns != f->width
3809 || rows != f->height
3810 || event.xconfigure.width != f->display.x->pixel_width
3811 || event.xconfigure.height != f->display.x->pixel_height)
3812 {
3813 change_frame_size (f, rows, columns, 0, 1);
3814 SET_FRAME_GARBAGED (f);
3815 }
3859 3816
3860 f->display.x->pixel_width = event.xconfigure.width; 3817 if (! event.xconfigure.send_event)
3861 f->display.x->pixel_height = event.xconfigure.height; 3818 {
3862 f->display.x->left_pos = event.xconfigure.x; 3819 Window win, child;
3863 f->display.x->top_pos = event.xconfigure.y; 3820 int win_x, win_y;
3821
3822 /* Find the position of the outside upper-left corner of
3823 the window, in the root coordinate system. Don't
3824 refer to the parent window here; we may be processing
3825 this event after the window manager has changed our
3826 parent, but before we have reached the ReparentNotify. */
3827 XTranslateCoordinates (FRAME_X_DISPLAY (f),
3828
3829 /* From-window, to-window. */
3830 f->display.x->window_desc,
3831 FRAME_X_DISPLAY_INFO (f)->root_window,
3832
3833 /* From-position, to-position. */
3834 -event.xconfigure.border_width,
3835 -event.xconfigure.border_width,
3836 &win_x, &win_y,
3837
3838 /* Child of win. */
3839 &child);
3840 event.xconfigure.x = win_x;
3841 event.xconfigure.y = win_y;
3842 }
3864 3843
3865 /* What we have now is the position of Emacs's own window. 3844 f->display.x->pixel_width = event.xconfigure.width;
3866 Convert that to the position of the window manager window. */ 3845 f->display.x->pixel_height = event.xconfigure.height;
3867 { 3846 f->display.x->left_pos = event.xconfigure.x;
3868 int x, y; 3847 f->display.x->top_pos = event.xconfigure.y;
3869 x_real_positions (f, &x, &y); 3848
3870 f->display.x->left_pos = x; 3849 /* What we have now is the position of Emacs's own window.
3871 f->display.x->top_pos = y; 3850 Convert that to the position of the window manager window. */
3872 if (y != event.xconfigure.y)
3873 { 3851 {
3874 /* Since the WM decorations come below top_pos now, 3852 int x, y;
3875 we must put them below top_pos in the future. */ 3853 x_real_positions (f, &x, &y);
3876 f->display.x->win_gravity = NorthWestGravity; 3854 f->display.x->left_pos = x;
3877 x_wm_set_size_hint (f, 0, 0); 3855 f->display.x->top_pos = y;
3856 if (y != event.xconfigure.y)
3857 {
3858 /* Since the WM decorations come below top_pos now,
3859 we must put them below top_pos in the future. */
3860 f->display.x->win_gravity = NorthWestGravity;
3861 x_wm_set_size_hint (f, 0, 0);
3862 }
3878 } 3863 }
3879 } 3864 }
3880 }
3881#endif /* not USE_X_TOOLKIT */ 3865#endif /* not USE_X_TOOLKIT */
3882 break; 3866 break;
3883 3867
3884 case ButtonPress: 3868 case ButtonPress:
3885 case ButtonRelease: 3869 case ButtonRelease:
3886 { 3870 {
3887 /* If we decide we want to generate an event to be seen 3871 /* If we decide we want to generate an event to be seen
3888 by the rest of Emacs, we put it here. */ 3872 by the rest of Emacs, we put it here. */
3889 struct input_event emacs_event; 3873 struct input_event emacs_event;
3890 emacs_event.kind = no_event; 3874 emacs_event.kind = no_event;
3891 3875
3892 bzero (&compose_status, sizeof (compose_status)); 3876 bzero (&compose_status, sizeof (compose_status));
3893 3877
3894 f = x_window_to_frame (event.xbutton.window); 3878 f = x_window_to_frame (event.xbutton.window);
3895 if (f) 3879 if (f)
3896 { 3880 {
3897 if (!x_focus_frame || (f == x_focus_frame)) 3881 if (!x_focus_frame || (f == x_focus_frame))
3898 construct_mouse_click (&emacs_event, &event, f); 3882 construct_mouse_click (&emacs_event, &event, f);
3899 } 3883 }
3900 else 3884 else
3901 { 3885 {
3902 struct scroll_bar *bar 3886 struct scroll_bar *bar
3903 = x_window_to_scroll_bar (event.xbutton.window); 3887 = x_window_to_scroll_bar (event.xbutton.window);
3904 3888
3905 if (bar) 3889 if (bar)
3906 x_scroll_bar_handle_click (bar, &event, &emacs_event); 3890 x_scroll_bar_handle_click (bar, &event, &emacs_event);
3907#ifdef USE_X_TOOLKIT 3891#ifdef USE_X_TOOLKIT
3892 else
3893 {
3894 /* Assume we have a menubar button press. A bad
3895 assumption should behave benignly. */
3896 popup_get_selection (&event);
3897 break;
3898 }
3899#endif /* USE_X_TOOLKIT */
3900 }
3901
3902 if (event.type == ButtonPress)
3903 {
3904 dpyinfo->grabbed |= (1 << event.xbutton.button);
3905 last_mouse_frame = f;
3906 }
3908 else 3907 else
3909 { 3908 {
3910 /* Assume we have a menubar button press. A bad 3909 dpyinfo->grabbed &= ~(1 << event.xbutton.button);
3911 assumption should behave benignly. */
3912 popup_get_selection (&event);
3913 break;
3914 } 3910 }
3915#endif /* USE_X_TOOLKIT */
3916 }
3917
3918 if (event.type == ButtonPress)
3919 {
3920 dpyinfo->grabbed |= (1 << event.xbutton.button);
3921 last_mouse_frame = f;
3922 }
3923 else
3924 {
3925 dpyinfo->grabbed &= ~(1 << event.xbutton.button);
3926 }
3927 3911
3928 if (numchars >= 1 && emacs_event.kind != no_event) 3912 if (numchars >= 1 && emacs_event.kind != no_event)
3929 { 3913 {
3930 bcopy (&emacs_event, bufp, sizeof (struct input_event)); 3914 bcopy (&emacs_event, bufp, sizeof (struct input_event));
3931 bufp++; 3915 bufp++;
3932 count++; 3916 count++;
3933 numchars--; 3917 numchars--;
3934 } 3918 }
3935 3919
3936#ifdef USE_X_TOOLKIT 3920#ifdef USE_X_TOOLKIT
3937 goto OTHER; 3921 goto OTHER;
3938#endif /* USE_X_TOOLKIT */ 3922#endif /* USE_X_TOOLKIT */
3939 } 3923 }
3940 break; 3924 break;
3941 3925
3942 case CirculateNotify: 3926 case CirculateNotify:
3943 break; 3927 break;
3944 case CirculateRequest: 3928 case CirculateRequest:
3945 break; 3929 break;
3946 3930
3947 case MappingNotify: 3931 case MappingNotify:
3948 /* Someone has changed the keyboard mapping - update the 3932 /* Someone has changed the keyboard mapping - update the
3949 local cache. */ 3933 local cache. */
3950 switch (event.xmapping.request) 3934 switch (event.xmapping.request)
3951 { 3935 {
3952 case MappingModifier: 3936 case MappingModifier:
3953 x_find_modifier_meanings (dpyinfo); 3937 x_find_modifier_meanings (dpyinfo);
3954 /* This is meant to fall through. */ 3938 /* This is meant to fall through. */
3955 case MappingKeyboard: 3939 case MappingKeyboard:
3956 XRefreshKeyboardMapping (&event.xmapping); 3940 XRefreshKeyboardMapping (&event.xmapping);
3957 } 3941 }
3958#ifdef USE_X_TOOLKIT 3942#ifdef USE_X_TOOLKIT
3959 goto OTHER; 3943 goto OTHER;
3960#endif /* USE_X_TOOLKIT */ 3944#endif /* USE_X_TOOLKIT */
3961 break; 3945 break;
3962 3946
3963 default: 3947 default:
3964#ifdef USE_X_TOOLKIT 3948#ifdef USE_X_TOOLKIT
3965 OTHER: 3949 OTHER:
3966 BLOCK_INPUT; 3950 BLOCK_INPUT;
3967 XtDispatchEvent (&event); 3951 XtDispatchEvent (&event);
3968 UNBLOCK_INPUT; 3952 UNBLOCK_INPUT;
3969#endif /* USE_X_TOOLKIT */ 3953#endif /* USE_X_TOOLKIT */
3970 break; 3954 break;
3955 }
3971 } 3956 }
3972 } 3957 }
3973 3958
@@ -3982,7 +3967,8 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
3982 if (x_noop_count >= 100) 3967 if (x_noop_count >= 100)
3983 { 3968 {
3984 x_noop_count=0; 3969 x_noop_count=0;
3985 XNoOp (dpyinfo->display); 3970 /* Use the first display in the list. Why not? */
3971 XNoOp (x_display_list->display);
3986 } 3972 }
3987 } 3973 }
3988 3974
@@ -4015,6 +4001,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
4015 4001
4016 /* If the focus was just given to an autoraising frame, 4002 /* If the focus was just given to an autoraising frame,
4017 raise it now. */ 4003 raise it now. */
4004 /* ??? This ought to be able to handle more than one such frame. */
4018 if (pending_autoraise_frame) 4005 if (pending_autoraise_frame)
4019 { 4006 {
4020 x_raise_frame (pending_autoraise_frame); 4007 x_raise_frame (pending_autoraise_frame);
@@ -4189,15 +4176,15 @@ x_display_box_cursor (f, on)
4189 4176
4190 /* If the cursor is in the mouse face area, redisplay that when 4177 /* If the cursor is in the mouse face area, redisplay that when
4191 we clear the cursor. */ 4178 we clear the cursor. */
4192 if (f == mouse_face_mouse_frame 4179 if (f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame
4193 && 4180 &&
4194 (f->phys_cursor_y > mouse_face_beg_row 4181 (f->phys_cursor_y > FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row
4195 || (f->phys_cursor_y == mouse_face_beg_row 4182 || (f->phys_cursor_y == FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row
4196 && f->phys_cursor_x >= mouse_face_beg_col)) 4183 && f->phys_cursor_x >= FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_col))
4197 && 4184 &&
4198 (f->phys_cursor_y < mouse_face_end_row 4185 (f->phys_cursor_y < FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row
4199 || (f->phys_cursor_y == mouse_face_end_row 4186 || (f->phys_cursor_y == FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row
4200 && f->phys_cursor_x < mouse_face_end_col))) 4187 && f->phys_cursor_x < FRAME_X_DISPLAY_INFO (f)->mouse_face_end_col)))
4201 mouse_face_here = 1; 4188 mouse_face_here = 1;
4202 4189
4203 /* If the font is not as tall as a whole line, 4190 /* If the font is not as tall as a whole line,
@@ -4353,65 +4340,91 @@ x_text_icon (f, icon_name)
4353 4340
4354/* Handling X errors. */ 4341/* Handling X errors. */
4355 4342
4356/* Shut down Emacs in an orderly fashion, because of a SIGPIPE on the 4343/* Handle the loss of connection to display DISPLAY. */
4357 X server's connection, or an error reported via the X protocol. */
4358 4344
4359static SIGTYPE 4345static SIGTYPE
4360x_connection_closed () 4346x_connection_closed (display, error_message)
4347 Display *display;
4348 char *error_message;
4361{ 4349{
4350 struct x_display_info *dpyinfo = x_display_info_for_display (display);
4351 Lisp_Object frame, tail;
4352
4362 if (_Xdebug) 4353 if (_Xdebug)
4363 abort (); 4354 abort ();
4364 4355
4365 shut_down_emacs (0, 1, Qnil); 4356 /* First delete frames whose minibuffers are on frames
4357 that are on the dead display. */
4358 FOR_EACH_FRAME (tail, frame)
4359 {
4360 Lisp_Object minibuf_frame;
4361 minibuf_frame
4362 = WINDOW_FRAME (XWINDOW (FRAME_MINIBUF_WINDOW (XFRAME (frame))));
4363 if (! EQ (frame, minibuf_frame)
4364 && FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
4365 Fdelete_frame (frame, Qt);
4366 }
4367
4368 /* Now delete all remaining frames on the dead display.
4369 We are now sure none of these is used as the minibuffer
4370 for another frame that we need to delete. */
4371 FOR_EACH_FRAME (tail, frame)
4372 if (FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
4373 Fdelete_frame (frame, Qt);
4374
4375 x_delete_display (dpyinfo);
4376
4377 if (x_display_list == 0)
4378 {
4379 fprintf (stderr, "%s", error_message);
4380 shut_down_emacs (0, 0, Qnil);
4381 exit (70);
4382 }
4366 4383
4367 exit (70); 4384 /* Ordinary stack unwind doesn't deal with these. */
4385#ifdef SIGIO
4386 sigunblock (sigmask (SIGIO));
4387#endif
4388 sigunblock (sigmask (SIGALRM));
4389 TOTALLY_UNBLOCK_INPUT;
4390
4391 error ("%s", error_message);
4368} 4392}
4369 4393
4370/* An X error handler which prints an error message and then kills 4394/* This is the usual handler for X protocol errors.
4371 Emacs. This is what's normally installed as Xlib's handler for 4395 It kills all frames on the display that we got the error for.
4372 protocol errors. */ 4396 If that was the only one, it prints an error message and kills Emacs. */
4397
4373static int 4398static int
4374x_error_quitter (display, error) 4399x_error_quitter (display, error)
4375 Display *display; 4400 Display *display;
4376 XErrorEvent *error; 4401 XErrorEvent *error;
4377{ 4402{
4378 char buf[256]; 4403 char buf[256], buf1[356];
4379 4404
4380 /* Note that there is no real way portable across R3/R4 to get the 4405 /* Note that there is no real way portable across R3/R4 to get the
4381 original error handler. */ 4406 original error handler. */
4382 4407
4383 XGetErrorText (display, error->error_code, buf, sizeof (buf)); 4408 XGetErrorText (display, error->error_code, buf, sizeof (buf));
4384 fprintf (stderr, "X protocol error: %s on protocol request %d\n", 4409 sprintf (buf1, "X protocol error: %s on protocol request %d",
4385 buf, error->request_code); 4410 buf, error->request_code);
4386 4411 x_connection_closed (display, buf1);
4387#if 0
4388 /* While we're testing Emacs 19, we'll just dump core whenever we
4389 get an X error, so we can figure out why it happened. */
4390 abort ();
4391#endif
4392
4393 x_connection_closed ();
4394} 4412}
4395 4413
4396/* A handler for X IO errors which prints an error message and then 4414/* This is the handler for X IO errors, always.
4397 kills Emacs. This is what is always installed as Xlib's handler 4415 It kills all frames on the display that we lost touch with.
4398 for I/O errors. */ 4416 If that was the only one, it prints an error message and kills Emacs. */
4417
4399static int 4418static int
4400x_io_error_quitter (display) 4419x_io_error_quitter (display)
4401 Display *display; 4420 Display *display;
4402{ 4421{
4403 fprintf (stderr, "Connection to X server %s lost.\n", 4422 char buf[256];
4404 XDisplayName (DisplayString (display)));
4405
4406#if 0
4407 /* While we're testing Emacs 19, we'll just dump core whenever we
4408 get an X error, so we can figure out why it happened. */
4409 abort ();
4410#endif
4411 4423
4412 x_connection_closed (); 4424 sprintf (buf, "Connection lost to X server `%s'", DisplayString (display));
4425 x_connection_closed (display, buf);
4413} 4426}
4414 4427
4415/* A buffer for storing X error messages. */ 4428/* A buffer for storing X error messages. */
4416static char *x_caught_error_message; 4429static char *x_caught_error_message;
4417#define X_CAUGHT_ERROR_MESSAGE_SIZE 200 4430#define X_CAUGHT_ERROR_MESSAGE_SIZE 200
@@ -4419,6 +4432,7 @@ static char *x_caught_error_message;
4419/* An X error handler which stores the error message in 4432/* An X error handler which stores the error message in
4420 x_caught_error_message. This is what's installed when 4433 x_caught_error_message. This is what's installed when
4421 x_catch_errors is in effect. */ 4434 x_catch_errors is in effect. */
4435
4422static int 4436static int
4423x_error_catcher (display, error) 4437x_error_catcher (display, error)
4424 Display *display; 4438 Display *display;
@@ -4429,9 +4443,9 @@ x_error_catcher (display, error)
4429} 4443}
4430 4444
4431 4445
4432/* Begin trapping X errors for frame F. 4446/* Begin trapping X errors for display DPY. Actually we trap X errors
4433 Actually we trap X errors for all frames, but F should be the frame 4447 for all displays, but DPY should be the display you are actually
4434 you are actually operating on. 4448 operating on.
4435 4449
4436 After calling this function, X protocol errors no longer cause 4450 After calling this function, X protocol errors no longer cause
4437 Emacs to exit; instead, they are recorded in x_cfc_error_message. 4451 Emacs to exit; instead, they are recorded in x_cfc_error_message.
@@ -4444,11 +4458,11 @@ x_error_catcher (display, error)
4444void x_catch_errors (), x_check_errors (), x_uncatch_errors (); 4458void x_catch_errors (), x_check_errors (), x_uncatch_errors ();
4445 4459
4446void 4460void
4447x_catch_errors (f) 4461x_catch_errors (dpy)
4448 FRAME_PTR f; 4462 Display *dpy;
4449{ 4463{
4450 /* Make sure any errors from previous requests have been dealt with. */ 4464 /* Make sure any errors from previous requests have been dealt with. */
4451 XSync (FRAME_X_DISPLAY (f), False); 4465 XSync (dpy, False);
4452 4466
4453 /* Set up the error buffer. */ 4467 /* Set up the error buffer. */
4454 x_caught_error_message 4468 x_caught_error_message
@@ -4464,19 +4478,19 @@ x_catch_errors (f)
4464 sprintf (a buffer, FORMAT, the x error message text) as the text. */ 4478 sprintf (a buffer, FORMAT, the x error message text) as the text. */
4465 4479
4466void 4480void
4467x_check_errors (f, format) 4481x_check_errors (dpy, format)
4468 FRAME_PTR f; 4482 Display *dpy;
4469 char *format; 4483 char *format;
4470{ 4484{
4471 /* Make sure to catch any errors incurred so far. */ 4485 /* Make sure to catch any errors incurred so far. */
4472 XSync (FRAME_X_DISPLAY (f), False); 4486 XSync (dpy, False);
4473 4487
4474 if (x_caught_error_message[0]) 4488 if (x_caught_error_message[0])
4475 { 4489 {
4476 char buf[X_CAUGHT_ERROR_MESSAGE_SIZE + 56]; 4490 char buf[X_CAUGHT_ERROR_MESSAGE_SIZE + 56];
4477 4491
4478 sprintf (buf, format, x_caught_error_message); 4492 sprintf (buf, format, x_caught_error_message);
4479 x_uncatch_errors (f); 4493 x_uncatch_errors (dpy);
4480 error (buf); 4494 error (buf);
4481 } 4495 }
4482} 4496}
@@ -4484,11 +4498,11 @@ x_check_errors (f, format)
4484/* Nonzero if we had any X protocol errors since we did x_catch_errors. */ 4498/* Nonzero if we had any X protocol errors since we did x_catch_errors. */
4485 4499
4486int 4500int
4487x_had_errors_p (f) 4501x_had_errors_p (dpy)
4488 FRAME_PTR f; 4502 Display *dpy;
4489{ 4503{
4490 /* Make sure to catch any errors incurred so far. */ 4504 /* Make sure to catch any errors incurred so far. */
4491 XSync (FRAME_X_DISPLAY (f), False); 4505 XSync (dpy, False);
4492 4506
4493 return x_caught_error_message[0] != 0; 4507 return x_caught_error_message[0] != 0;
4494} 4508}
@@ -4496,8 +4510,8 @@ x_had_errors_p (f)
4496/* Stop catching X protocol errors and let them make Emacs die. */ 4510/* Stop catching X protocol errors and let them make Emacs die. */
4497 4511
4498void 4512void
4499x_uncatch_errors (f) 4513x_uncatch_errors (dpy)
4500 FRAME_PTR f; 4514 Display *dpy;
4501{ 4515{
4502 xfree (x_caught_error_message); 4516 xfree (x_caught_error_message);
4503 x_caught_error_message = 0; 4517 x_caught_error_message = 0;
@@ -4515,28 +4529,6 @@ x_trace_wire ()
4515 4529
4516/* Changing the font of the frame. */ 4530/* Changing the font of the frame. */
4517 4531
4518/* Set the font of the x-window specified by frame F
4519 to the font named NEWNAME. This is safe to use
4520 even before F has an actual x-window. */
4521
4522struct font_info
4523{
4524 XFontStruct *font;
4525 char *name;
4526 char *full_name;
4527};
4528
4529/* A table of all the fonts we have already loaded. */
4530static struct font_info *x_font_table;
4531
4532/* The current capacity of x_font_table. */
4533static int x_font_table_size;
4534
4535/* The number of fonts actually stored in x_font_table.
4536 x_font_table[n] is used and valid iff 0 <= n < n_fonts.
4537 0 <= n_fonts <= x_font_table_size. */
4538static int n_fonts;
4539
4540/* Give frame F the font named FONTNAME as its default font, and 4532/* Give frame F the font named FONTNAME as its default font, and
4541 return the full name of that font. FONTNAME may be a wildcard 4533 return the full name of that font. FONTNAME may be a wildcard
4542 pattern; in that case, we choose some font that fits the pattern. 4534 pattern; in that case, we choose some font that fits the pattern.
@@ -4572,13 +4564,13 @@ x_new_font (f, fontname)
4572 { 4564 {
4573 int i, j; 4565 int i, j;
4574 4566
4575 for (i = 0; i < n_fonts; i++) 4567 for (i = 0; i < FRAME_X_DISPLAY_INFO (f)->n_fonts; i++)
4576 for (j = 0; j < n_matching_fonts; j++) 4568 for (j = 0; j < n_matching_fonts; j++)
4577 if (!strcmp (x_font_table[i].name, font_names[j]) 4569 if (!strcmp (FRAME_X_DISPLAY_INFO (f)->font_table[i].name, font_names[j])
4578 || !strcmp (x_font_table[i].full_name, font_names[j])) 4570 || !strcmp (FRAME_X_DISPLAY_INFO (f)->font_table[i].full_name, font_names[j]))
4579 { 4571 {
4580 already_loaded = i; 4572 already_loaded = i;
4581 fontname = x_font_table[i].full_name; 4573 fontname = FRAME_X_DISPLAY_INFO (f)->font_table[i].full_name;
4582 goto found_font; 4574 goto found_font;
4583 } 4575 }
4584 } 4576 }
@@ -4586,13 +4578,14 @@ x_new_font (f, fontname)
4586 4578
4587 /* If we have, just return it from the table. */ 4579 /* If we have, just return it from the table. */
4588 if (already_loaded >= 0) 4580 if (already_loaded >= 0)
4589 f->display.x->font = x_font_table[already_loaded].font; 4581 f->display.x->font = FRAME_X_DISPLAY_INFO (f)->font_table[already_loaded].font;
4590 /* Otherwise, load the font and add it to the table. */ 4582 /* Otherwise, load the font and add it to the table. */
4591 else 4583 else
4592 { 4584 {
4593 int i; 4585 int i;
4594 char *full_name; 4586 char *full_name;
4595 XFontStruct *font; 4587 XFontStruct *font;
4588 int n_fonts;
4596 4589
4597 /* Try to find a character-cell font in the list. */ 4590 /* Try to find a character-cell font in the list. */
4598#if 0 4591#if 0
@@ -4618,21 +4611,22 @@ x_new_font (f, fontname)
4618 } 4611 }
4619 4612
4620 /* Do we need to create the table? */ 4613 /* Do we need to create the table? */
4621 if (x_font_table_size == 0) 4614 if (FRAME_X_DISPLAY_INFO (f)->font_table_size == 0)
4622 { 4615 {
4623 x_font_table_size = 16; 4616 FRAME_X_DISPLAY_INFO (f)->font_table_size = 16;
4624 x_font_table 4617 FRAME_X_DISPLAY_INFO (f)->font_table
4625 = (struct font_info *) xmalloc (x_font_table_size 4618 = (struct font_info *) xmalloc (FRAME_X_DISPLAY_INFO (f)->font_table_size
4626 * sizeof (x_font_table[0])); 4619 * sizeof (struct font_info));
4627 } 4620 }
4628 /* Do we need to grow the table? */ 4621 /* Do we need to grow the table? */
4629 else if (n_fonts >= x_font_table_size) 4622 else if (FRAME_X_DISPLAY_INFO (f)->n_fonts
4623 >= FRAME_X_DISPLAY_INFO (f)->font_table_size)
4630 { 4624 {
4631 x_font_table_size *= 2; 4625 FRAME_X_DISPLAY_INFO (f)->font_table_size *= 2;
4632 x_font_table 4626 FRAME_X_DISPLAY_INFO (f)->font_table
4633 = (struct font_info *) xrealloc (x_font_table, 4627 = (struct font_info *) xrealloc (FRAME_X_DISPLAY_INFO (f)->font_table,
4634 (x_font_table_size 4628 (FRAME_X_DISPLAY_INFO (f)->font_table_size
4635 * sizeof (x_font_table[0]))); 4629 * sizeof (struct font_info)));
4636 } 4630 }
4637 4631
4638 /* Try to get the full name of FONT. Put it in full_name. */ 4632 /* Try to get the full name of FONT. Put it in full_name. */
@@ -4669,13 +4663,15 @@ x_new_font (f, fontname)
4669 XFree (atom); 4663 XFree (atom);
4670 } 4664 }
4671 4665
4672 x_font_table[n_fonts].name = (char *) xmalloc (strlen (fontname) + 1); 4666 n_fonts = FRAME_X_DISPLAY_INFO (f)->n_fonts;
4673 bcopy (fontname, x_font_table[n_fonts].name, strlen (fontname) + 1); 4667 FRAME_X_DISPLAY_INFO (f)->font_table[n_fonts].name = (char *) xmalloc (strlen (fontname) + 1);
4668 bcopy (fontname, FRAME_X_DISPLAY_INFO (f)->font_table[n_fonts].name, strlen (fontname) + 1);
4674 if (full_name != 0) 4669 if (full_name != 0)
4675 x_font_table[n_fonts].full_name = full_name; 4670 FRAME_X_DISPLAY_INFO (f)->font_table[n_fonts].full_name = full_name;
4676 else 4671 else
4677 x_font_table[n_fonts].full_name = x_font_table[n_fonts].name; 4672 FRAME_X_DISPLAY_INFO (f)->font_table[n_fonts].full_name = FRAME_X_DISPLAY_INFO (f)->font_table[n_fonts].name;
4678 f->display.x->font = x_font_table[n_fonts++].font = font; 4673 f->display.x->font = FRAME_X_DISPLAY_INFO (f)->font_table[n_fonts].font = font;
4674 FRAME_X_DISPLAY_INFO (f)->n_fonts++;
4679 4675
4680 if (full_name) 4676 if (full_name)
4681 fontname = full_name; 4677 fontname = full_name;
@@ -5295,11 +5291,13 @@ x_destroy_window (f)
5295 if (f == x_highlight_frame) 5291 if (f == x_highlight_frame)
5296 x_highlight_frame = 0; 5292 x_highlight_frame = 0;
5297 5293
5298 if (f == mouse_face_mouse_frame) 5294 if (f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
5299 { 5295 {
5300 mouse_face_beg_row = mouse_face_beg_col = -1; 5296 FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row
5301 mouse_face_end_row = mouse_face_end_col = -1; 5297 = FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_col = -1;
5302 mouse_face_window = Qnil; 5298 FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row
5299 = FRAME_X_DISPLAY_INFO (f)->mouse_face_end_col = -1;
5300 FRAME_X_DISPLAY_INFO (f)->mouse_face_window = Qnil;
5303 } 5301 }
5304 5302
5305 UNBLOCK_INPUT; 5303 UNBLOCK_INPUT;
@@ -5463,7 +5461,7 @@ x_wm_set_icon_pixmap (f, pixmap_id)
5463 5461
5464 if (pixmap_id > 0) 5462 if (pixmap_id > 0)
5465 { 5463 {
5466 Pixmap icon_pixmap = x_lookup_pixmap (pixmap_id); 5464 Pixmap icon_pixmap = x_bitmap_pixmap (f, pixmap_id);
5467 f->display.x->wm_hints.icon_pixmap = icon_pixmap; 5465 f->display.x->wm_hints.icon_pixmap = icon_pixmap;
5468 f->display.x->wm_hints.flags |= IconPixmapHint; 5466 f->display.x->wm_hints.flags |= IconPixmapHint;
5469 } 5467 }
@@ -5515,6 +5513,8 @@ static XrmOptionDescRec emacs_options[] = {
5515}; 5513};
5516#endif /* USE_X_TOOLKIT */ 5514#endif /* USE_X_TOOLKIT */
5517 5515
5516static int x_initialized;
5517
5518struct x_display_info * 5518struct x_display_info *
5519x_term_init (display_name, xrm_option, resource_name) 5519x_term_init (display_name, xrm_option, resource_name)
5520 Lisp_Object display_name; 5520 Lisp_Object display_name;
@@ -5526,26 +5526,15 @@ x_term_init (display_name, xrm_option, resource_name)
5526 int argc = 0; 5526 int argc = 0;
5527 char** argv = 0; 5527 char** argv = 0;
5528 int connection; 5528 int connection;
5529 Display *dpy;
5529 struct x_display_info *dpyinfo; 5530 struct x_display_info *dpyinfo;
5530 XrmDatabase xrdb; 5531 XrmDatabase xrdb;
5531 5532
5532#ifndef F_SETOWN_BUG 5533 if (!x_initialized)
5533#ifdef F_SETOWN 5534 {
5534 extern int old_fcntl_owner; 5535 x_initialize ();
5535#endif /* ! defined (F_SETOWN) */ 5536 x_initialized = 1;
5536#endif /* F_SETOWN_BUG */ 5537 }
5537
5538 dpyinfo = &the_x_screen;
5539
5540 /* Put our one and only display on the chain. */
5541 x_display_list = dpyinfo;
5542 dpyinfo->next = 0;
5543
5544 dpyinfo->name = display_name;
5545
5546 x_noop_count = 0;
5547
5548 x_focus_frame = x_highlight_frame = 0;
5549 5538
5550#ifdef USE_X_TOOLKIT 5539#ifdef USE_X_TOOLKIT
5551#ifdef HAVE_X11R5 5540#ifdef HAVE_X11R5
@@ -5570,44 +5559,52 @@ x_term_init (display_name, xrm_option, resource_name)
5570 &argc, argv, 5559 &argc, argv,
5571 NULL, NULL, 0); 5560 NULL, NULL, 0);
5572 XtFree ((char *)argv); 5561 XtFree ((char *)argv);
5573 dpyinfo->display = XtDisplay (Xt_app_shell); 5562 dpy = XtDisplay (Xt_app_shell);
5574 5563
5575#else /* not USE_X_TOOLKIT */ 5564#else /* not USE_X_TOOLKIT */
5576#ifdef HAVE_X11R5 5565#ifdef HAVE_X11R5
5577 XSetLocaleModifiers (""); 5566 XSetLocaleModifiers ("");
5578#endif 5567#endif
5579 dpyinfo->display = XOpenDisplay (XSTRING (display_name)->data); 5568 dpy = XOpenDisplay (XSTRING (display_name)->data);
5580#endif /* not USE_X_TOOLKIT */ 5569#endif /* not USE_X_TOOLKIT */
5581 5570
5582 if (dpyinfo->display == 0) 5571 /* Detect failure. */
5583 fatal ("X server %s not responding.\n\ 5572 if (dpy == 0)
5584Check the DISPLAY environment variable or use \"-d\"\n", 5573 return 0;
5585 XSTRING (display_name)->data); 5574
5575 /* We have definitely succeeded. Record the new connection. */
5576
5577 dpyinfo = (struct x_display_info *) xmalloc (sizeof (struct x_display_info));
5578
5579 /* Put this display on the chain. */
5580 dpyinfo->next = x_display_list;
5581 x_display_list = dpyinfo;
5582
5583 /* Put it on x_display_name_list as well, to keep them parallel. */
5584 x_display_name_list = Fcons (Fcons (display_name, Qnil),
5585 x_display_name_list);
5586 dpyinfo->name_list_element = XCONS (x_display_name_list)->car;
5587
5588 dpyinfo->display = dpy;
5586 5589
5587 {
5588#if 0 5590#if 0
5589 XSetAfterFunction (x_current_display, x_trace_wire); 5591 XSetAfterFunction (x_current_display, x_trace_wire);
5590#endif /* ! 0 */ 5592#endif /* ! 0 */
5591 x_id_name = (char *) xmalloc (XSTRING (Vinvocation_name)->size 5593
5592 + XSTRING (Vsystem_name)->size 5594 dpyinfo->x_id_name
5593 + 2); 5595 = (char *) xmalloc (XSTRING (Vinvocation_name)->size
5594 sprintf (x_id_name, "%s@%s", 5596 + XSTRING (Vsystem_name)->size
5595 XSTRING (Vinvocation_name)->data, XSTRING (Vsystem_name)->data); 5597 + 2);
5596 } 5598 sprintf (dpyinfo->x_id_name, "%s@%s",
5599 XSTRING (Vinvocation_name)->data, XSTRING (Vsystem_name)->data);
5597 5600
5598 /* Figure out which modifier bits mean what. */ 5601 /* Figure out which modifier bits mean what. */
5599 x_find_modifier_meanings (dpyinfo); 5602 x_find_modifier_meanings (dpyinfo);
5600 5603
5601 /* Get the scroll bar cursor. */ 5604 /* Get the scroll bar cursor. */
5602 x_vertical_scroll_bar_cursor 5605 dpyinfo->vertical_scroll_bar_cursor
5603 = XCreateFontCursor (dpyinfo->display, XC_sb_v_double_arrow); 5606 = XCreateFontCursor (dpyinfo->display, XC_sb_v_double_arrow);
5604 5607
5605#if 0
5606 /* Watch for PropertyNotify events on the root window; we use them
5607 to figure out when to invalidate our cache of the cut buffers. */
5608 x_watch_cut_buffer_cache ();
5609#endif
5610
5611 xrdb = x_load_resources (dpyinfo->display, xrm_option, 5608 xrdb = x_load_resources (dpyinfo->display, xrm_option,
5612 resource_name, EMACS_CLASS); 5609 resource_name, EMACS_CLASS);
5613#ifdef HAVE_XRMSETDATABASE 5610#ifdef HAVE_XRMSETDATABASE
@@ -5615,6 +5612,9 @@ Check the DISPLAY environment variable or use \"-d\"\n",
5615#else 5612#else
5616 dpyinfo->display->db = xrdb; 5613 dpyinfo->display->db = xrdb;
5617#endif 5614#endif
5615 /* Put thr rdb where we can find it in a way that works on
5616 all versions. */
5617 dpyinfo->xrdb = xrdb;
5618 5618
5619 dpyinfo->screen = ScreenOfDisplay (dpyinfo->display, 5619 dpyinfo->screen = ScreenOfDisplay (dpyinfo->display,
5620 DefaultScreen (dpyinfo->display)); 5620 DefaultScreen (dpyinfo->display));
@@ -5626,6 +5626,20 @@ Check the DISPLAY environment variable or use \"-d\"\n",
5626 dpyinfo->grabbed = 0; 5626 dpyinfo->grabbed = 0;
5627 dpyinfo->reference_count = 0; 5627 dpyinfo->reference_count = 0;
5628 dpyinfo->icon_bitmap_id = -1; 5628 dpyinfo->icon_bitmap_id = -1;
5629 dpyinfo->n_fonts = 0;
5630 dpyinfo->font_table_size = 0;
5631 dpyinfo->bitmaps = 0;
5632 dpyinfo->bitmaps_size = 0;
5633 dpyinfo->bitmaps_last = 0;
5634 dpyinfo->scratch_cursor_gc = 0;
5635 dpyinfo->mouse_face_mouse_frame = 0;
5636 dpyinfo->mouse_face_deferred_gc = 0;
5637 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
5638 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
5639 dpyinfo->mouse_face_face_id = 0;
5640 dpyinfo->mouse_face_window = Qnil;
5641 dpyinfo->mouse_face_mouse_x = dpyinfo->mouse_face_mouse_y = 0;
5642 dpyinfo->mouse_face_defer = 0;
5629 5643
5630 dpyinfo->Xatom_wm_protocols 5644 dpyinfo->Xatom_wm_protocols
5631 = XInternAtom (dpyinfo->display, "WM_PROTOCOLS", False); 5645 = XInternAtom (dpyinfo->display, "WM_PROTOCOLS", False);
@@ -5670,13 +5684,11 @@ Check the DISPLAY environment variable or use \"-d\"\n",
5670#ifdef subprocesses 5684#ifdef subprocesses
5671 /* This is only needed for distinguishing keyboard and process input. */ 5685 /* This is only needed for distinguishing keyboard and process input. */
5672 if (connection != 0) 5686 if (connection != 0)
5673 change_keyboard_wait_descriptor (connection); 5687 add_keyboard_wait_descriptor (connection);
5674#endif 5688#endif
5675 change_input_fd (connection);
5676 5689
5677#ifndef F_SETOWN_BUG 5690#ifndef F_SETOWN_BUG
5678#ifdef F_SETOWN 5691#ifdef F_SETOWN
5679 old_fcntl_owner = fcntl (connection, F_GETOWN, 0);
5680#ifdef F_SETOWN_SOCK_NEG 5692#ifdef F_SETOWN_SOCK_NEG
5681 /* stdin is a socket here */ 5693 /* stdin is a socket here */
5682 fcntl (connection, F_SETOWN, -getpid ()); 5694 fcntl (connection, F_SETOWN, -getpid ());
@@ -5687,11 +5699,63 @@ Check the DISPLAY environment variable or use \"-d\"\n",
5687#endif /* F_SETOWN_BUG */ 5699#endif /* F_SETOWN_BUG */
5688 5700
5689#ifdef SIGIO 5701#ifdef SIGIO
5690 init_sigio (); 5702 init_sigio (connection);
5691#endif /* ! defined (SIGIO) */ 5703#endif /* ! defined (SIGIO) */
5692 5704
5693 expose_all_windows = 0; 5705 return dpyinfo;
5706}
5707
5708/* Get rid of display DPYINFO, assuming all frames are already gone,
5709 and without sending any more commands to the X server. */
5694 5710
5711void
5712x_delete_display (dpyinfo)
5713 struct x_display_info *dpyinfo;
5714{
5715 delete_keyboard_wait_descriptor (dpyinfo->connection);
5716
5717 /* Discard this display from x_display_name_list and x_display_list.
5718 We can't use Fdelq because that can quit. */
5719 if (! NILP (x_display_name_list)
5720 && EQ (XCONS (x_display_name_list)->car, dpyinfo->name_list_element))
5721 x_display_name_list = XCONS (x_display_name_list)->cdr;
5722 else
5723 {
5724 Lisp_Object tail;
5725
5726 tail = x_display_name_list;
5727 while (CONSP (tail) && CONSP (XCONS (tail)->cdr))
5728 {
5729 if (EQ (XCONS (XCONS (tail)->cdr)->car,
5730 dpyinfo->name_list_element))
5731 {
5732 XCONS (tail)->cdr = XCONS (XCONS (tail)->cdr)->cdr;
5733 break;
5734 }
5735 tail = XCONS (tail)->cdr;
5736 }
5737 }
5738
5739 if (x_display_list == dpyinfo)
5740 x_display_list = dpyinfo->next;
5741 {
5742 struct x_display_info *tail;
5743
5744 for (tail = x_display_list; tail; tail = tail->next)
5745 if (tail->next == dpyinfo)
5746 tail->next = tail->next->next;
5747 }
5748
5749 /* ??? Should free the xrdb slot somehow? */
5750 free (dpyinfo->font_table);
5751 free (dpyinfo->x_id_name);
5752 free (dpyinfo);
5753}
5754
5755/* Set up use of X before we make the first connection. */
5756
5757x_initialize ()
5758{
5695 clear_frame_hook = XTclear_frame; 5759 clear_frame_hook = XTclear_frame;
5696 clear_end_of_line_hook = XTclear_end_of_line; 5760 clear_end_of_line_hook = XTclear_end_of_line;
5697 ins_del_lines_hook = XTins_del_lines; 5761 ins_del_lines_hook = XTins_del_lines;
@@ -5725,6 +5789,10 @@ Check the DISPLAY environment variable or use \"-d\"\n",
5725 off the bottom */ 5789 off the bottom */
5726 baud_rate = 19200; 5790 baud_rate = 19200;
5727 5791
5792 x_noop_count = 0;
5793
5794 x_focus_frame = x_highlight_frame = 0;
5795
5728 /* Try to use interrupt input; if we can't, then start polling. */ 5796 /* Try to use interrupt input; if we can't, then start polling. */
5729 Fset_input_mode (Qt, Qnil, Qt, Qnil); 5797 Fset_input_mode (Qt, Qnil, Qt, Qnil);
5730 5798
@@ -5744,14 +5812,10 @@ Check the DISPLAY environment variable or use \"-d\"\n",
5744void 5812void
5745syms_of_xterm () 5813syms_of_xterm ()
5746{ 5814{
5747 the_x_screen.font_list_cache = Qnil; 5815 staticpro (&x_display_name_list);
5748 the_x_screen.name = Qnil; 5816 x_display_name_list = Qnil;
5749 staticpro (&the_x_screen.font_list_cache);
5750 staticpro (&the_x_screen.name);
5751 5817
5752 staticpro (&last_mouse_scroll_bar); 5818 staticpro (&last_mouse_scroll_bar);
5753 last_mouse_scroll_bar = Qnil; 5819 last_mouse_scroll_bar = Qnil;
5754 staticpro (&mouse_face_window);
5755 mouse_face_window = Qnil;
5756} 5820}
5757#endif /* ! defined (HAVE_X_WINDOWS) */ 5821#endif /* ! defined (HAVE_X_WINDOWS) */