1 /* X Communication module for terminals which understand the X protocol.
2 Copyright (C) 1989 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
22 Kludge: dup2 is used to put the X-connection socket into desc # 0
23 so that wait_reading_process_input will wait for it in place of
24 actual terminal input.
35 /* On 4.3 this loses if it comes after xterm.h. */
38 /* This may include sys/types.h, and that somehow loses
39 if this is not done before the other system files. */
42 /* Load sys/types.h if not already loaded.
43 In some systems loading it twice is suicidal. */
45 #include <sys/types.h>
49 #include <sys/ioctl.h>
52 #include <sys/termio.h>
56 /* Allow m- file to inhibit use of FIONREAD. */
57 #ifdef BROKEN_FIONREAD
61 /* We are unable to use interrupts if FIONREAD is not available,
62 so flush SIGIO so we won't try. */
71 #else /* not NEED_TIME_H */
74 #endif /* HAVE_TIMEVAL */
75 #endif /* not NEED_TIME_H */
83 #include <sys/param.h>
85 #include "dispextern.h"
86 #include "termhooks.h"
99 #define XMapWindow XMapRaised /* Raise them when mapping. */
101 #include <X/Xkeyboard.h>
102 /*#include <X/Xproto.h> */
103 #endif /* HAVE_X11 */
105 /* For sending Meta-characters. Do we need this? */
108 #define min(a,b) ((a)<(b) ? (a) : (b))
109 #define max(a,b) ((a)>(b) ? (a) : (b))
111 /* Nonzero means we must reprint all windows
112 because 1) we received an ExposeWindow event
113 or 2) we received too many ExposeRegion events to record. */
115 static int expose_all_windows
;
117 /* Nonzero means we must reprint all icon windows. */
119 static int expose_all_icons
;
122 /* ExposeRegion events, when received, are copied into this queue
123 for later processing. */
125 static struct event_queue x_expose_queue
;
127 /* ButtonPressed and ButtonReleased events, when received,
128 are copied into this queue for later processing. */
130 struct event_queue x_mouse_queue
;
133 /* Nonzero after BLOCK_INPUT; prevents input events from being
134 processed until later. */
138 #if defined (SIGIO) && defined (FIONREAD)
139 int BLOCK_INPUT_mask
;
142 /* Nonzero if input events came in while x_input_blocked was nonzero.
143 UNBLOCK_INPUT checks for this. */
147 /* Nonzero if in redisplay (); prevents us from calling it recursively */
151 /* The id of a bitmap used for icon windows.
152 One such map is shared by all Emacs icon windows.
153 This is zero if we have not yet had a need to create the bitmap. */
155 static Bitmap icon_bitmap
;
157 /* Font used for text icons. */
159 static FONT_TYPE
*icon_font_info
;
161 /* Stuff for dealing with the main icon title. */
163 extern Lisp_Object Vcommand_line_args
;
164 char *hostname
, *x_id_name
;
165 Lisp_Object invocation_name
;
167 /* This is the X connection that we are using. */
169 Display
*x_current_display
;
171 /* Screen being updated by update_screen. */
172 /* This is set by XTupdate_begin and looked at by all the
173 XT functions. It is zero while not inside an update.
174 In that case, the XT functions assume that `selected_screen'
175 is the screen to apply to. */
177 static struct screen
*updating_screen
;
179 /* The screen (if any) which has the X window that has keyboard focus.
180 Zero if none. This is examined by Ffocus_screen in screen.c. */
181 struct screen
*x_focus_screen
;
183 /* The screen which currently has the visual highlight, and should get
184 keyboard input (other sorts of input have the screen encoded in the
185 event). It points to the X focus screen's selected window's
186 screen. It differs from x_focus_screen when we're using a global
188 static struct screen
*x_highlight_screen
;
190 /* From .Xdefaults, the value of "emacs.WarpMouse". If non-zero,
191 mouse is moved to inside of screen when screen is de-iconified. */
193 static int warp_mouse_on_deiconify
;
195 /* During an update, maximum vpos for ins/del line operations to affect. */
197 static int flexlines
;
199 /* During an update, nonzero if chars output now should be highlighted. */
201 static int highlight
;
203 /* Nominal cursor position -- where to draw output.
204 During an update, these are different from the cursor-box position. */
210 /* `t' if a mouse button is depressed. */
212 extern Lisp_Object Vmouse_depressed
;
214 /* Tells if a window manager is present or not. */
216 extern Lisp_Object Vx_no_window_manager
;
218 /* Timestamp that we requested selection data was made. */
219 extern Time requestor_time
;
221 /* ID of the window requesting selection data. */
222 extern Window requestor_window
;
224 /* Nonzero enables some debugging for the X interface code. */
227 #else /* X10 stuff */
229 /* Bit patterns for the mouse cursor. */
231 short MouseCursor
[] = {
232 0x0000, 0x0008, 0x0018, 0x0038,
233 0x0078, 0x00f8, 0x01f8, 0x03f8,
234 0x07f8, 0x00f8, 0x00d8, 0x0188,
235 0x0180, 0x0300, 0x0300, 0x0000};
237 short MouseMask
[] = {
238 0x000c, 0x001c, 0x003c, 0x007c,
239 0x00fc, 0x01fc, 0x03fc, 0x07fc,
240 0x0ffc, 0x0ffc, 0x01fc, 0x03dc,
241 0x03cc, 0x0780, 0x0780, 0x0300};
243 static short grey_bits
[] = {
244 0x0005, 0x000a, 0x0005, 0x000a};
246 static Pixmap GreyPixmap
= 0;
247 #endif /* X10 stuff */
249 /* From time to time we get info on an Emacs window, here. */
251 static WINDOWINFO_TYPE windowinfo
;
255 extern Lisp_Object Vglobal_minibuffer_screen
;
257 extern Display
*XOpenDisplay ();
258 extern Window
XCreateWindow ();
260 extern Cursor
XCreateCursor ();
261 extern FONT_TYPE
*XOpenFont ();
263 static void flashback ();
266 static void dumpqueue ();
270 static XTcursor_to ();
271 static XTclear_end_of_line ();
273 /* These hooks are called by update_screen at the beginning and end
274 of a screen update. We record in `updating_screen' the identity
275 of the screen being updated, so that the XT... functions do not
276 need to take a screen as argument. Most of the XT... functions
277 should never be called except during an update, the only exceptions
278 being XTcursor_to, XTwrite_char and XTreassert_line_highlight. */
280 extern int mouse_track_top
, mouse_track_left
, mouse_track_width
;
292 flexlines
= s
->height
;
299 x_display_cursor (s
, 0);
303 static void x_do_pending_expose ();
311 if (updating_screen
== 0
312 || updating_screen
!= s
)
319 adjust_scrollbars (s
);
320 x_do_pending_expose ();
322 x_display_cursor (s
, 1);
329 /* External interface to control of standout mode.
330 Call this when about to modify line at position VPOS
331 and not change whether it is highlighted. */
333 XTreassert_line_highlight (new, vpos
)
339 /* Call this when about to modify line at position VPOS
340 and change whether it is highlighted. */
343 XTchange_line_highlight (new_highlight
, vpos
, first_unused_hpos
)
344 int new_highlight
, vpos
, first_unused_hpos
;
346 highlight
= new_highlight
;
347 XTcursor_to (vpos
, 0);
348 XTclear_end_of_line (updating_screen
->width
);
351 /* This is used when starting Emacs and when restarting after suspend.
352 When starting Emacs, no X window is mapped. And nothing must be done
353 to Emacs's own window if it is suspended (though that rarely happens). */
356 XTset_terminal_modes ()
360 /* This is called when exiting or suspending Emacs.
361 Exiting will make the X-windows go away, and suspending
362 requires no action. */
365 XTreset_terminal_modes ()
367 /* XTclear_screen (); */
370 /* Set the nominal cursor position of the screen:
371 where display update commands will take effect.
372 This does not affect the place where the cursor-box is displayed. */
374 XTcursor_to (row
, col
)
375 register int row
, col
;
383 if (updating_screen
== 0)
386 x_display_cursor (selected_screen
, 1);
392 /* Display a sequence of N glyphs found at GP.
393 WINDOW is the x-window to output to. LEFT and TOP are starting coords.
394 HL is 1 if this text is highlighted, 2 if the cursor is on it.
396 FONT is the default font to use (for glyphs whose font-code is 0). */
399 dumpglyphs (s
, left
, top
, gp
, n
, hl
, font
)
402 register GLYPH
*gp
; /* Points to first GLYPH. */
403 register int n
; /* Number of glyphs to display. */
408 register char *cp
= buf
;
410 Window window
= s
->display
.x
->window_desc
;
411 GC drawing_gc
= (hl
== 2 ? s
->display
.x
->cursor_gc
412 : (hl
? s
->display
.x
->reverse_gc
413 : s
->display
.x
->normal_gc
));
415 if (sizeof (GLYPH
) == sizeof (XChar2b
))
416 XDrawImageString16 (x_current_display
, window
, drawing_gc
,
417 left
, top
+ FONT_BASE (font
), (XChar2b
*) gp
, n
);
418 else if (sizeof (GLYPH
) == sizeof (unsigned char))
419 XDrawImageString (x_current_display
, window
, drawing_gc
,
420 left
, top
+ FONT_BASE (font
), (char *) gp
, n
);
422 /* What size of glyph ARE you using? And does X have a function to
429 dumpglyphs (s
, left
, top
, gp
, n
, hl
, font
)
432 register GLYPH
*gp
; /* Points to first GLYPH. */
433 register int n
; /* Number of glyphs to display. */
437 char buf
[s
->width
]; /* Holds characters to be displayed. */
438 register char *cp
; /* Steps through buf[]. */
439 register int tlen
= GLYPH_TABLE_LENGTH
;
440 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
441 Window window
= s
->display
.x
->window_desc
;
442 int cursor_pixel
= s
->display
.x
->cursor_pixel
;
443 int fg_pixel
= s
->display
.x
->foreground_pixel
;
444 int bg_pixel
= s
->display
.x
->background_pixel
;
445 int intborder
= s
->display
.x
->internal_border_width
;
449 /* Get the face-code of the next GLYPH. */
453 while (GLYPH_ALIAS_P (tbase
, tlen
, g
))
454 g
= GLYPH_ALIAS (tbase
, g
);
458 /* Find the run of consecutive glyphs with the same face-code.
459 Extract their character codes into BUF. */
464 while (GLYPH_ALIAS_P (tbase
, tlen
, g
))
465 g
= GLYPH_ALIAS (tbase
, g
);
474 /* LEN gets the length of the run. */
477 /* Now output this run of chars, with the font and pixel values
478 determined by the face code CF. */
482 GC GC_cursor
= s
->display
.x
->cursor_gc
;
483 GC GC_reverse
= s
->display
.x
->reverse_gc
;
484 GC GC_normal
= s
->display
.x
->normal_gc
;
486 XDrawImageString (x_current_display
, window
,
489 : (hl
? GC_reverse
: GC_normal
)),
490 left
, top
+ FONT_BASE (font
), buf
, len
);
492 XText (window
, left
, top
,
497 ? (cursor_pixel
== fg_pixel
? bg_pixel
: fg_pixel
)
498 : hl
? bg_pixel
: fg_pixel
),
499 (hl
== 2 ? cursor_pixel
500 : hl
? fg_pixel
: bg_pixel
));
501 #endif /* HAVE_X11 */
506 if (FACE_IS_FONT (cf
))
507 XDrawImageString (x_current_display
, s
->display
.x
->window_desc
,
509 left
, top
+ FONT_BASE (FACE_FONT (cf
)),
511 else if (FACE_IS_IMAGE (cf
))
512 XCopyPlane (x_current_display
, FACE_IMAGE (cf
),
513 s
->display
.x
->window_desc
,
514 s
->display
.x
->normal_gc
,
516 FACE_IMAGE_WIDTH (cf
),
517 FACE_IMAGE_HEIGHT (cf
), left
, top
);
521 register struct face
*fp
= x_face_table
[cf
];
523 XText (window
, left
, top
,
528 ? (cursor_pixel
== fp
->fg
? fp
->bg
: fp
->fg
)
529 : hl
? fp
->bg
: fp
->fg
),
530 (hl
== 2 ? cursor_pixel
531 : hl
? fp
->fg
: fp
->bg
));
532 #endif /* HAVE_X11 */
534 left
+= len
* FONT_WIDTH (font
);
539 /* Output some text at the nominal screen cursor position,
540 advancing the cursor over the text.
541 Output LEN glyphs at START.
543 `highlight', set up by XTreassert_line_highlight or XTchange_line_highlight,
544 controls the pixel values used for foreground and background. */
547 XTwrite_glyphs (start
, len
)
548 register GLYPH
*start
;
551 register int temp_length
;
561 /* If not within an update,
562 output at the screen's visible cursor. */
563 curs_x
= s
->cursor_x
;
564 curs_y
= s
->cursor_y
;
567 /* Clear the cursor if it appears on this line. */
568 if (curs_y
== s
->cursor_y
)
569 x_display_cursor (s
, 0);
572 (curs_x
* FONT_WIDTH (s
->display
.x
->font
)
573 + s
->display
.x
->internal_border_width
),
574 (curs_y
* FONT_HEIGHT (s
->display
.x
->font
)
575 + s
->display
.x
->internal_border_width
),
576 start
, len
, highlight
, s
->display
.x
->font
);
578 if (updating_screen
== 0)
581 x_display_cursor (s
, 1);
590 /* Erase the current text line from the nominal cursor position (inclusive)
591 to column FIRST_UNUSED (exclusive). The idea is that everything
592 from FIRST_UNUSED onward is already erased. */
595 XTclear_end_of_line (first_unused
)
596 register int first_unused
;
598 struct screen
*s
= updating_screen
;
604 if (curs_y
< 0 || curs_y
>= s
->height
)
606 if (first_unused
<= 0)
609 if (first_unused
>= s
->width
)
610 first_unused
= s
->width
;
614 /* Clear the cursor if it appears on this line. */
615 if (curs_y
== s
->cursor_y
)
616 x_display_cursor (s
, 0);
619 XClearArea (x_current_display
, s
->display
.x
->window_desc
,
620 curs_x
* FONT_WIDTH (s
->display
.x
->font
)
621 + s
->display
.x
->internal_border_width
,
622 curs_y
* FONT_HEIGHT (s
->display
.x
->font
)
623 + s
->display
.x
->internal_border_width
,
624 FONT_WIDTH (s
->display
.x
->font
) * (first_unused
- curs_x
),
625 FONT_HEIGHT (s
->display
.x
->font
), False
);
628 XPixSet (s
->display
.x
->window_desc
,
629 curs_x
* FONT_WIDTH (s
->display
.x
->font
) + s
->display
.x
->internal_border_width
,
630 curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + s
->display
.x
->internal_border_width
,
631 FONT_WIDTH (s
->display
.x
->font
) * (first_unused
- curs_x
),
632 FONT_HEIGHT (s
->display
.x
->font
),
633 s
->display
.x
->background_pixel
);
634 #endif /* HAVE_X11 */
643 struct screen
*s
= updating_screen
;
648 s
->phys_cursor_x
= -1; /* Cursor not visible. */
649 curs_x
= 0; /* Nominal cursor position is top left. */
653 XClear (s
->display
.x
->window_desc
);
661 /* Paint horzontal bars down the screen for a visible bell.
662 Note that this may be way too slow on some machines. */
667 register struct screen_glyphs
*active_screen
= SCREEN_CURRENT_GLYPHS (s
);
671 if (updating_screen
!= 0)
677 for (i
= s
->height
* FONT_HEIGHT (s
->display
.x
->font
) - 10;
679 i
-= 100) /* Should be NO LOWER than 75 for speed reasons. */
680 XFillRectangle (x_current_display
, s
->display
.x
->window_desc
,
681 s
->display
.x
->cursor_gc
,
682 0, i
, s
->width
* FONT_WIDTH (s
->display
.x
->font
)
683 + 2 * s
->display
.x
->internal_border_width
, 25);
686 x
= (s
->width
* FONT_WIDTH (s
->display
.x
->font
)) / 4;
687 y
= (s
->height
* FONT_HEIGHT (s
->display
.x
->font
)) / 4;
688 XFillRectangle (x_current_display
, s
->display
.x
->window_desc
,
689 s
->display
.x
->cursor_gc
,
691 dumpglyphs (s
, (x
+ s
->display
.x
->internal_border_width
),
692 (y
+ s
->display
.x
->internal_border_width
),
693 &active_screen
->glyphs
[(s
->height
/ 4) + 1][(s
->width
/ 4)],
694 1, 0, s
->display
.x
->font
);
697 for (i
= s
->height
* FONT_HEIGHT (s
->display
.x
->font
) - 10;
700 XPixFill (s
->display
.x
->window_desc
, 0, i
,
701 s
->width
* FONT_WIDTH (s
->display
.x
->font
)
702 + 2 * s
->display
.x
->internal_border_width
, 10,
703 WHITE_PIX_DEFAULT
, ClipModeClipped
, GXinvert
, AllPlanes
);
710 /* Flip background and forground colors of the screen. */
717 unsigned long pix_temp
;
719 x_display_cursor (s
, 0);
720 XClearWindow (x_current_display
, s
->display
.x
->window_desc
);
721 temp
= s
->display
.x
->normal_gc
;
722 s
->display
.x
->normal_gc
= s
->display
.x
->reverse_gc
;
723 s
->display
.x
->reverse_gc
= temp
;
724 pix_temp
= s
->display
.x
->foreground_pixel
;
725 s
->display
.x
->foreground_pixel
= s
->display
.x
->background_pixel
;
726 s
->display
.x
->background_pixel
= pix_temp
;
728 XSetWindowBackground (x_current_display
, s
->display
.x
->window_desc
,
729 s
->display
.x
->background_pixel
);
730 if (s
->display
.x
->background_pixel
== s
->display
.x
->cursor_pixel
)
732 s
->display
.x
->cursor_pixel
= s
->display
.x
->foreground_pixel
;
733 XSetBackground (x_current_display
, s
->display
.x
->cursor_gc
,
734 s
->display
.x
->cursor_pixel
);
735 XSetForeground (x_current_display
, s
->display
.x
->cursor_gc
,
736 s
->display
.x
->background_pixel
);
742 /* Make audible bell. */
745 #define XRINGBELL XBell(x_current_display, 0)
747 #define XRINGBELL XFeep(0);
754 XTflash (selected_screen
);
757 x_invert_screen (selected_screen
);
758 x_invert_screen (selected_screen
);
769 /* Insert and delete character are not supposed to be used
770 because we are supposed to turn off the feature of using them. */
773 XTinsert_glyphs (start
, len
)
774 register char *start
;
787 /* Specify how many text lines, from the top of the window,
788 should be affected by insert-lines and delete-lines operations.
789 This, and those operations, are used only within an update
790 that is bounded by calls to XTupdate_begin and XTupdate_end. */
793 XTset_terminal_window (n
)
796 if (updating_screen
== 0)
799 if ((n
<= 0) || (n
> updating_screen
->height
))
800 flexlines
= updating_screen
->height
;
805 /* Perform an insert-lines operation, inserting N lines
806 at a vertical position curs_y. */
812 register int topregion
, bottomregion
;
813 register int length
, newtop
, mask
;
814 register struct screen
*s
= updating_screen
;
815 int intborder
= s
->display
.x
->internal_border_width
;
817 if (curs_y
>= flexlines
)
821 bottomregion
= flexlines
- (n
+ 1);
822 newtop
= topregion
+ n
;
823 length
= (bottomregion
- topregion
) + 1;
829 if ((length
> 0) && (newtop
<= flexlines
))
832 XCopyArea (x_current_display
, s
->display
.x
->window_desc
,
833 s
->display
.x
->window_desc
, s
->display
.x
->normal_gc
,
834 intborder
, topregion
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
835 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
836 length
* FONT_HEIGHT (s
->display
.x
->font
), intborder
,
837 newtop
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
);
839 XMoveArea (s
->display
.x
->window_desc
,
840 intborder
, topregion
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
841 intborder
, newtop
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
842 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
843 length
* FONT_HEIGHT (s
->display
.x
->font
));
844 /* Now we must process any ExposeRegion events that occur
845 if the area being copied from is obscured.
846 We can't let it wait because further i/d operations
847 may want to copy this area to another area. */
849 #endif /* HAVE_X11 */
852 newtop
= min (newtop
, (flexlines
- 1));
853 length
= newtop
- topregion
;
857 XClearArea (x_current_display
, s
->display
.x
->window_desc
, intborder
,
858 topregion
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
859 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
860 n
* FONT_HEIGHT (s
->display
.x
->font
), False
);
862 XPixSet (s
->display
.x
->window_desc
,
864 topregion
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
865 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
866 n
* FONT_HEIGHT (s
->display
.x
->font
),
867 s
->display
.x
->background_pixel
);
868 #endif /* HAVE_X11 */
872 /* Perform a delete-lines operation, deleting N lines
873 at a vertical position curs_y. */
880 register struct screen
*s
= updating_screen
;
881 int intborder
= s
->display
.x
->internal_border_width
;
883 if (curs_y
>= flexlines
)
890 if ((curs_y
+ n
) >= flexlines
)
892 if (flexlines
>= (curs_y
+ 1))
895 XClearArea (x_current_display
, s
->display
.x
->window_desc
, intborder
,
896 curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
897 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
898 (flexlines
- curs_y
) * FONT_HEIGHT (s
->display
.x
->font
), False
);
900 XPixSet (s
->display
.x
->window_desc
,
901 intborder
, curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
902 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
903 (flexlines
- curs_y
) * FONT_HEIGHT (s
->display
.x
->font
),
904 s
->display
.x
->background_pixel
);
905 #endif /* HAVE_X11 */
911 XCopyArea (x_current_display
, s
->display
.x
->window_desc
,
912 s
->display
.x
->window_desc
, s
->display
.x
->normal_gc
,
914 (curs_y
+ n
) * FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
915 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
916 (flexlines
- (curs_y
+ n
)) * FONT_HEIGHT (s
->display
.x
->font
),
917 intborder
, curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
);
918 XClearArea (x_current_display
, s
->display
.x
->window_desc
,
920 (flexlines
- n
) * FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
921 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
922 n
* FONT_HEIGHT (s
->display
.x
->font
), False
);
924 XMoveArea (s
->display
.x
->window_desc
,
926 (curs_y
+ n
) * FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
927 intborder
, curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
928 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
929 (flexlines
- (curs_y
+ n
)) * FONT_HEIGHT (s
->display
.x
->font
));
930 /* Now we must process any ExposeRegion events that occur
931 if the area being copied from is obscured.
932 We can't let it wait because further i/d operations
933 may want to copy this area to another area. */
935 XPixSet (s
->display
.x
->window_desc
, intborder
,
936 (flexlines
- n
) * FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
937 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
938 n
* FONT_HEIGHT (s
->display
.x
->font
), s
->display
.x
->background_pixel
);
939 #endif /* HAVE_X11 */
943 /* Perform an insert-lines or delete-lines operation,
944 inserting N lines or deleting -N lines at vertical position VPOS. */
946 XTins_del_lines (vpos
, n
)
949 if (updating_screen
== 0)
952 /* Clear the cursor. */
953 x_display_cursor (updating_screen
, 0);
955 XTcursor_to (vpos
, 0);
966 static void clear_cursor ();
968 /* Output into a rectangle of an X-window (for screen S)
969 the characters in s->phys_lines that overlap that rectangle.
970 TOP and LEFT are the position of the upper left corner of the rectangle.
971 ROWS and COLS are the size of the rectangle. */
974 dumprectangle (s
, left
, top
, cols
, rows
)
976 register int left
, top
, cols
, rows
;
978 register struct screen_glyphs
*active_screen
= SCREEN_CURRENT_GLYPHS (s
);
979 int cursor_cleared
= 0;
983 if (SCREEN_GARBAGED_P (s
))
986 top
-= s
->display
.x
->internal_border_width
;
987 left
-= s
->display
.x
->internal_border_width
;
989 /* Express rectangle as four edges, instead of position-and-size. */
993 #ifndef HAVE_X11 /* Window manger does this for X11. */
994 /* If the rectangle includes any of the internal border area,
995 redisplay the border emphasis. */
996 if (top
< 0 || left
< 0
997 || bottom
> s
->height
* FONT_HEIGHT (s
->display
.x
->font
)
998 || right
> s
->width
* FONT_WIDTH (s
->display
.x
->font
))
1000 #endif /* HAVE_X11 */
1002 /* Convert rectangle edges in pixels to edges in chars.
1003 Round down for left and top, up for right and bottom. */
1004 top
/= FONT_HEIGHT (s
->display
.x
->font
);
1005 left
/= FONT_WIDTH (s
->display
.x
->font
);
1006 bottom
+= (FONT_HEIGHT (s
->display
.x
->font
) - 1);
1007 right
+= (FONT_WIDTH (s
->display
.x
->font
) - 1);
1008 bottom
/= FONT_HEIGHT (s
->display
.x
->font
);
1009 right
/= FONT_WIDTH (s
->display
.x
->font
);
1011 /* Clip the rectangle to what can be visible. */
1016 if (right
> s
->width
)
1018 if (bottom
> s
->height
)
1021 /* Get size in chars of the rectangle. */
1022 cols
= right
- left
;
1023 rows
= bottom
- top
;
1025 /* If rectangle has zero area, return. */
1026 if (rows
<= 0) return;
1027 if (cols
<= 0) return;
1029 /* Turn off the cursor if it is in the rectangle.
1030 We will turn it back on afterward. */
1031 if ((s
->phys_cursor_x
>= left
) && (s
->phys_cursor_x
< right
)
1032 && (s
->phys_cursor_y
>= top
) && (s
->phys_cursor_y
< bottom
))
1038 /* Display the text in the rectangle, one text line at a time. */
1040 for (y
= top
; y
< bottom
; y
++)
1042 GLYPH
*line
= &active_screen
->glyphs
[y
][left
];
1044 if (! active_screen
->enable
[y
] || left
> active_screen
->used
[y
])
1048 (left
* FONT_WIDTH (s
->display
.x
->font
)
1049 + s
->display
.x
->internal_border_width
),
1050 (y
* FONT_HEIGHT (s
->display
.x
->font
)
1051 + s
->display
.x
->internal_border_width
),
1052 line
, min (cols
, active_screen
->used
[y
] - left
),
1053 active_screen
->highlight
[y
], s
->display
.x
->font
);
1056 /* Turn the cursor on if we turned it off. */
1059 x_display_cursor (s
, 1);
1063 /* Process all queued ExposeRegion events. */
1069 XExposeRegionEvent r
;
1071 while (dequeue_event (&r
, &x_expose_queue
))
1073 struct screen
*s
= x_window_to_screen (r
.window
);
1074 if (s
->display
.x
->icon_desc
== r
.window
)
1077 dumprectangle (s
, r
.x
, r
.y
, r
.width
, r
.height
);
1083 /* Process all expose events that are pending.
1084 Redraws the cursor if necessary on any screen that
1085 is not in the process of being updated with update_screen. */
1088 x_do_pending_expose ()
1092 Lisp_Object tail
, screen
;
1094 if (expose_all_windows
)
1096 expose_all_windows
= 0;
1097 for (tail
= Vscreen_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1099 register int temp_width
, temp_height
;
1102 screen
= XCONS (tail
)->car
;
1103 if (XTYPE (screen
) != Lisp_Screen
)
1105 s
= XSCREEN (screen
);
1106 if (s
->output_method
!= output_x_window
)
1110 if (!s
->display
.x
->needs_exposure
)
1113 intborder
= s
->display
.x
->internal_border_width
;
1116 XGetWindowInfo (s
->display
.x
->window_desc
, &windowinfo
);
1117 temp_width
= ((windowinfo
.width
- 2 * intborder
1118 - s
->display
.x
->v_scrollbar_width
)
1119 / FONT_WIDTH (s
->display
.x
->font
));
1120 temp_height
= ((windowinfo
.height
- 2 * intborder
1121 - s
->display
.x
->h_scrollbar_height
)
1122 / FONT_HEIGHT (s
->display
.x
->font
));
1123 if (temp_width
!= s
->width
|| temp_height
!= s
->height
)
1125 change_screen_size (s
, max (1, temp_height
),
1126 max (1, temp_width
), 0);
1127 x_resize_scrollbars (s
);
1129 s
->display
.x
->left_pos
= windowinfo
.x
;
1130 s
->display
.x
->top_pos
= windowinfo
.y
;
1131 dumprectangle (s
, 0, 0, PIXEL_WIDTH (s
), PIXEL_HEIGHT (s
));
1135 s
->display
.x
->needs_exposure
= 0;
1136 if (updating_screen
!= s
)
1137 x_display_cursor (s
, 1);
1142 /* Handle any individual-rectangle expose events queued
1143 for various windows. */
1153 screen_highlight (screen
)
1154 struct screen
*screen
;
1156 if (! EQ (Vx_no_window_manager
, Qnil
))
1157 XSetWindowBorder (x_current_display
, screen
->display
.x
->window_desc
,
1158 screen
->display
.x
->border_pixel
);
1159 x_display_cursor (screen
, 1);
1163 screen_unhighlight (screen
)
1164 struct screen
*screen
;
1166 if (! EQ (Vx_no_window_manager
, Qnil
))
1167 XSetWindowBorderPixmap (x_current_display
, screen
->display
.x
->window_desc
,
1168 screen
->display
.x
->border_tile
);
1169 x_display_cursor (screen
, 1);
1172 /* Dump the border-emphasis of screen S.
1173 If S is selected, this is a lining of the same color as the border,
1174 just within the border, occupying a portion of the internal border.
1175 If S is not selected, it is background in the same place.
1176 If ALWAYS is 0, don't bother explicitly drawing if it's background.
1178 ALWAYS = 1 is used when a screen becomes selected or deselected.
1179 In that case, we also turn the cursor off and on again
1180 so it will appear in the proper shape (solid if selected; else hollow.) */
1183 dumpborder (s
, always
)
1187 int thickness
= s
->display
.x
->internal_border_width
/ 2;
1188 int width
= PIXEL_WIDTH (s
);
1189 int height
= PIXEL_HEIGHT (s
);
1192 if (s
!= selected_screen
)
1197 pixel
= s
->display
.x
->background_pixel
;
1201 pixel
= s
->display
.x
->border_pixel
;
1204 XPixSet (s
->display
.x
->window_desc
, 0, 0, width
, thickness
, pixel
);
1205 XPixSet (s
->display
.x
->window_desc
, 0, 0, thickness
, height
, pixel
);
1206 XPixSet (s
->display
.x
->window_desc
, 0, height
- thickness
, width
,
1208 XPixSet (s
->display
.x
->window_desc
, width
- thickness
, 0, thickness
,
1212 x_display_cursor (s
, 1);
1216 static void XTscreen_rehighlight ();
1218 /* The focus has changed. Update the screens as necessary to reflect
1219 the new situation. Note that we can't change the selected screen
1220 here, because the lisp code we are interrupting might become confused.
1221 Each event gets marked with the screen in which it occured, so the
1222 lisp code can tell when the switch took place by examining the events. */
1225 x_new_focus_screen (screen
)
1226 struct screen
*screen
;
1228 struct screen
*old_focus
= x_focus_screen
;
1229 int events_enqueued
= 0;
1231 if (screen
!= x_focus_screen
)
1233 /* Set this before calling other routines, so that they see
1234 the correct value of x_focus_screen. */
1235 x_focus_screen
= screen
;
1237 if (old_focus
&& old_focus
->auto_lower
)
1238 x_lower_screen (old_focus
);
1241 selected_screen
= screen
;
1242 XSET (XWINDOW (selected_screen
->selected_window
)->screen
,
1243 Lisp_Screen
, selected_screen
);
1244 Fselect_window (selected_screen
->selected_window
);
1245 choose_minibuf_screen ();
1248 if (x_focus_screen
&& x_focus_screen
->auto_raise
)
1249 x_raise_screen (x_focus_screen
);
1252 XTscreen_rehighlight ();
1256 /* The focus has changed, or we have make a screen's selected window
1257 point to a window on a different screen (this happens with global
1258 minibuffer screens). Shift the highlight as appropriate. */
1260 XTscreen_rehighlight ()
1262 struct screen
*old_highlight
= x_highlight_screen
;
1266 x_highlight_screen
= XSCREEN (SCREEN_FOCUS_SCREEN (x_focus_screen
));
1267 if (x_highlight_screen
->display
.nothing
== 0)
1268 XSET (SCREEN_FOCUS_SCREEN (x_focus_screen
), Lisp_Screen
,
1269 (x_highlight_screen
= x_focus_screen
));
1272 x_highlight_screen
= 0;
1274 if (x_highlight_screen
!= old_highlight
)
1277 screen_unhighlight (old_highlight
);
1278 if (x_highlight_screen
)
1279 screen_highlight (x_highlight_screen
);
1290 /* Symbol returned in input stream to indicate mouse movement. */
1291 Lisp_Object Qmouse_moved
;
1293 /* Position of the mouse in characters */
1294 unsigned int x_mouse_x
, x_mouse_y
;
1296 /* Emacs window the mouse is in, if any. */
1297 extern Lisp_Object Vmouse_window
;
1299 /* Offset in buffer of character under the pointer, or 0. */
1300 extern int mouse_buffer_offset
;
1302 /* Part of the screen the mouse is in. */
1303 extern Lisp_Object Vmouse_screen_part
;
1305 extern void pixel_to_glyph_translation ();
1306 extern int buffer_posn_from_coords ();
1308 /* Symbols from xfns.c to denote the different parts of a window. */
1309 extern Lisp_Object Qmodeline_part
, Qtext_part
;
1312 /* Set *RESULT to an emacs input_event corresponding to MOTION_EVENT.
1313 S is the screen in which the event occurred.
1315 WINDOW_TYPE says whether the event happened in a scrollbar window
1316 or a text window, affecting the format of the event created.
1318 PART specifies which part of the scrollbar the event happened in,
1319 if WINDOW_TYPE == scrollbar_window.
1321 If the mouse is over the same character as the last time we checked,
1322 don't return an event; set result->kind to no_event. */
1325 notice_mouse_movement (result
, motion_event
, s
, window_type
, part
)
1326 struct input_event
*result
;
1327 XMotionEvent motion_event
;
1332 int x
, y
, root_x
, root_y
, pix_x
, pix_y
;
1333 unsigned int keys_and_buttons
;
1334 Window w
, root_window
;
1336 /* Unless we decide otherwise below, return a non-event. */
1337 result
->kind
= no_event
;
1339 if (XQueryPointer (x_current_display
,
1340 s
->display
.x
->window_desc
,
1342 &root_x
, &root_y
, &pix_x
, &pix_y
,
1348 if (w
== None
) /* Mouse no longer in window. */
1352 pixel_to_glyph_translation (s
, pix_x
, pix_y
, &x
, &y
);
1353 if (x
== x_mouse_x
&& y
== x_mouse_y
)
1359 /* What sort of window are we in now? */
1360 if (window_type
== text_window
) /* Text part */
1364 Vmouse_window
= window_from_coordinates (s
, x
, y
, &modeline_p
);
1366 if (XTYPE (Vmouse_window
) == Lisp_Window
)
1368 = buffer_posn_from_coords (XWINDOW (Vmouse_window
), x
, y
);
1370 mouse_buffer_offset
= 0;
1372 if (EQ (Vmouse_window
, Qnil
))
1373 Vmouse_screen_part
= Qnil
;
1374 else if (modeline_p
)
1375 Vmouse_screen_part
= Qmodeline_part
;
1377 Vmouse_screen_part
= Qtext_part
;
1379 result
->kind
= window_sys_event
;
1380 result
->code
= Qmouse_moved
;
1384 else if (window_type
== scrollbar_window
) /* Scrollbar */
1386 Vmouse_window
= s
->selected_window
;
1387 mouse_buffer_offset
= 0;
1388 Vmouse_screen_part
= part
;
1390 result
->kind
= window_sys_event
;
1391 result
->code
= Qmouse_moved
;
1400 /* Given a pixel position (pix_x, pix_y) on the screen s, return
1401 character co-ordinates in (*x, *y). */
1403 pixel_to_glyph_translation (s
, pix_x
, pix_y
, x
, y
)
1405 register unsigned int pix_x
, pix_y
;
1406 register int *x
, *y
;
1408 register struct screen_glyphs
*s_glyphs
= SCREEN_CURRENT_GLYPHS (s
);
1409 register int line
= SCREEN_HEIGHT (s
) - 1;
1410 int ibw
= s
->display
.x
->internal_border_width
;
1412 /* What line is it on? */
1413 line
= SCREEN_HEIGHT (s
) - 1;
1414 while (s_glyphs
->top_left_y
[line
] > pix_y
)
1418 /* Horizontally, is it in the border? */
1422 /* If it's off the right edge, clip it. */
1423 else if (pix_x
> s
->display
.x
->pixel_width
- ibw
)
1424 *x
= SCREEN_WIDTH (s
) - 1;
1426 /* It's in the midst of the screen; assume all the characters are
1427 the same width, and figure the column. */
1429 *x
= (pix_x
- ibw
) / FONT_WIDTH (s
->display
.x
->font
);
1434 /* Any buttons grabbed. */
1435 unsigned int x_mouse_grabbed
;
1437 /* Convert a set of X modifier bits to the proper form for a
1438 struct input_event modifiers value. */
1441 x_convert_modifiers (state
)
1444 return ( ((state
& (ShiftMask
| LockMask
)) ? shift_modifier
: 0)
1445 | ((state
& ControlMask
) ? ctrl_modifier
: 0)
1446 | ((state
& Mod1Mask
) ? meta_modifier
: 0));
1449 extern struct screen
*x_window_to_scrollbar ();
1450 extern Lisp_Object Vmouse_event
;
1452 /* Prepare a mouse-event in *RESULT for placement in the input queue.
1454 If the event is a button press, then note that we have grabbed
1457 If PART and PREFIX are 0, then the event occurred in the text part;
1458 otherwise it happened in a scrollbar. */
1461 construct_mouse_click (result
, event
, s
, part
, prefix
)
1462 struct input_event
*result
;
1463 XButtonEvent
*event
;
1468 /* Initialize those fields text and scrollbar clicks hold in common.
1469 Make the event type no_event; we'll change that when we decide
1471 result
->kind
= no_event
;
1472 XSET (result
->code
, Lisp_Int
, event
->button
);
1473 result
->modifiers
= (x_convert_modifiers (event
->state
)
1474 | (event
->type
== ButtonRelease
? up_modifier
: 0));
1475 XSET (result
->timestamp
, Lisp_Int
, (event
->time
& 0x7fffff));
1477 /* Notice if the mouse is still grabbed. */
1478 if (event
->type
== ButtonPress
)
1480 if (! x_mouse_grabbed
)
1481 Vmouse_depressed
= Qt
;
1482 x_mouse_grabbed
|= event
->button
;
1484 else if (event
->type
== ButtonRelease
)
1486 x_mouse_grabbed
&= ~(event
->button
);
1487 if (!x_mouse_grabbed
)
1488 Vmouse_depressed
= Qnil
;
1491 if (part
) /* Scrollbar event */
1495 pos
= event
->y
- (s
->display
.x
->v_scrollbar_width
- 2);
1496 XSET (x_mouse_x
, Lisp_Int
, pos
);
1497 len
= ((FONT_HEIGHT (s
->display
.x
->font
) * s
->height
)
1498 + s
->display
.x
->internal_border_width
1499 - (2 * (s
->display
.x
->v_scrollbar_width
- 2)));
1500 XSET (x_mouse_y
, Lisp_Int
, len
);
1502 result
->kind
= scrollbar_click
;
1503 result
->part
= part
;
1504 XSET (result
->x
, Lisp_Int
, (s
->display
.x
->top_pos
- event
->y
));
1505 XSET (result
->y
, Lisp_Int
, s
->display
.x
->pixel_height
);
1508 else /* Text Window Event */
1512 pixel_to_glyph_translation (s
,
1516 result
->kind
= mouse_click
;
1524 static char *events
[] =
1564 #define XEvent XKeyPressedEvent
1565 #endif /* HAVE_X11 */
1567 /* Symbols returned in the input stream to indicate various X events. */
1568 Lisp_Object Qmouse_click
;
1569 Lisp_Object Qscrollbar_click
;
1571 /* Timestamp of enter window event. This is only used by XTread_socket,
1572 but we have to put it out here, since static variables within functions
1573 sometimes don't work. */
1574 static Time enter_timestamp
;
1576 /* Read events coming from the X server.
1577 This routine is called by the SIGIO handler.
1578 We return as soon as there are no more events to be read.
1580 Events representing keys are stored in buffer BUFP,
1581 which can hold up to NUMCHARS characters.
1582 We return the number of characters stored into the buffer,
1583 thus pretending to be `read'.
1585 WAITP is nonzero if we should block until input arrives.
1586 EXPECTED is nonzero if the caller knows input is available. */
1589 XTread_socket (sd
, bufp
, numchars
, waitp
, expected
)
1591 register struct input_event
*bufp
;
1592 register int numchars
;
1599 int items_pending
; /* How many items are in the X queue. */
1606 if (x_input_blocked
)
1608 x_pending_input
= 1;
1612 x_pending_input
= 0;
1616 abort (); /* Don't think this happens. */
1619 /* If available, Xlib uses FIOSNBIO to make the socket
1620 non-blocking, and then looks for EWOULDBLOCK. If O_NDELAY is set,
1621 FIOSNBIO is ignored, and instead of signalling EWOULDBLOCK,
1622 a read returns 0, which Xlib interprets as equivalent to EPIPE. */
1623 fcntl (fileno (stdin
), F_SETFL
, 0);
1628 if (! (fcntl (fileno (stdin
), F_GETFL
, 0) & O_NDELAY
))
1630 extern int read_alarm_should_throw
;
1631 read_alarm_should_throw
= 1;
1632 XPeekEvent (XDISPLAY
&event
);
1633 read_alarm_should_throw
= 0;
1638 while (XStuffPending () != 0)
1640 XNextEvent (XDISPLAY
&event
);
1647 case SelectionClear
: /* Someone has grabbed ownership. */
1648 x_disown_selection (event
.xselectionclear
.window
,
1649 event
.xselectionclear
.selection
,
1650 event
.xselectionclear
.time
);
1653 case SelectionRequest
: /* Someone wants our selection. */
1654 x_answer_selection_request (event
);
1657 case PropertyNotify
:
1658 /* If we were to do this synchronously, there'd be no worry
1659 about re-selecting. */
1660 x_send_incremental (event
);
1664 s
= x_window_to_screen (event
.xexpose
.window
);
1667 if (s
->visible
== 0)
1671 SET_SCREEN_GARBAGED (s
);
1674 dumprectangle (x_window_to_screen (event
.xexpose
.window
),
1675 event
.xexpose
.x
, event
.xexpose
.y
,
1676 event
.xexpose
.width
, event
.xexpose
.height
);
1680 case GraphicsExpose
: /* This occurs when an XCopyArea's
1681 source area was obscured or not
1683 dumprectangle (x_window_to_screen (event
.xgraphicsexpose
.drawable
),
1684 event
.xgraphicsexpose
.x
, event
.xgraphicsexpose
.y
,
1685 event
.xgraphicsexpose
.width
,
1686 event
.xgraphicsexpose
.height
);
1689 case NoExpose
: /* This occurs when an XCopyArea's
1690 source area was completely
1693 #else /* not HAVE_X11 */
1695 if (event
.subwindow
!= 0)
1696 break; /* duplicate event */
1697 s
= x_window_to_screen (event
.window
);
1698 if (event
.window
== s
->display
.x
->icon_desc
)
1703 if (event
.window
== s
->display
.x
->window_desc
)
1705 /* Say must check all windows' needs_exposure flags. */
1706 expose_all_windows
= 1;
1707 s
->display
.x
->needs_exposure
= 1;
1713 if (event
.subwindow
!= 0)
1714 break; /* duplicate event */
1715 s
= x_window_to_screen (event
.window
);
1716 if (event
.window
== s
->display
.x
->icon_desc
)
1721 /* If window already needs full redraw, ignore this rectangle. */
1722 if (expose_all_windows
&& s
->display
.x
->needs_exposure
)
1724 /* Put the event on the queue of rectangles to redraw. */
1725 if (enqueue_event (&event
, &x_expose_queue
))
1726 /* If it is full, we can't record the rectangle,
1727 so redraw this entire window. */
1729 /* Say must check all windows' needs_exposure flags. */
1730 expose_all_windows
= 1;
1731 s
->display
.x
->needs_exposure
= 1;
1736 /* This should happen only when we are expecting it,
1737 in x_read_exposes. */
1739 #endif /* not HAVE_X11 */
1746 s
= x_window_to_screen (event
.xunmap
.window
);
1747 if (s
) /* S may no longer exist if
1748 the screen was deleted. */
1750 /* While a screen is unmapped, display generation is
1751 disabled; you don't want to spend time updating a
1752 display that won't ever be seen. */
1754 Vmouse_window
= Vmouse_screen_part
= Qnil
;
1755 x_mouse_x
= x_mouse_y
= -1;
1761 s
= x_window_to_screen (event
.xmap
.window
);
1767 /* wait_reading_process_input will notice this and update
1768 the screen's display structures. */
1769 SET_SCREEN_GARBAGED (s
);
1773 /* Turn off processing if we become fully obscured. */
1774 case VisibilityNotify
:
1779 s
= x_window_to_screen (event
.window
);
1780 if (event
.window
== s
->display
.x
->icon_desc
)
1782 if (event
.window
== s
->display
.x
->window_desc
)
1785 #endif /* HAVE_X11 */
1789 s
= x_window_to_screen (event
.xkey
.window
);
1793 XComposeStatus status
;
1794 char copy_buffer
[80];
1796 /* This will have to go some day... */
1797 nbytes
= XLookupString (&event
.xkey
,
1803 /* Strip off the vendor-specific keysym bit, and take a shot
1804 at recognizing the codes. HP servers have extra keysyms
1805 that fit into the MiscFunctionKey category. */
1810 if (IsCursorKey (keysym
) /* 0xff50 <= x < 0xff60 */
1811 || IsMiscFunctionKey (keysym
) /* 0xff60 <= x < 0xff80 */
1812 || IsKeypadKey (keysym
) /* 0xff80 <= x < 0xffbe */
1813 || IsFunctionKey (keysym
)) /* 0xffbe <= x < 0xffe1 */
1815 bufp
->kind
= non_ascii_keystroke
;
1816 bufp
->code
= (unsigned) keysym
- 0xff50;
1817 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
1818 bufp
->modifiers
= x_convert_modifiers (event
.xkey
.state
);
1823 else if (numchars
> nbytes
)
1829 if (event
.xkey
.state
& Mod1Mask
)
1830 *copy_buffer
|= METABIT
;
1831 bufp
->kind
= ascii_keystroke
;
1832 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
1833 XSET (bufp
->code
, Lisp_Int
, *copy_buffer
);
1837 for (i
= nbytes
- 1; i
> 1; i
--)
1839 bufp
->kind
= ascii_keystroke
;
1840 XSET (bufp
->code
, Lisp_Int
, copy_buffer
[i
]);
1841 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
1854 register char *where_mapping
;
1856 s
= x_window_to_screen (event
.window
);
1857 /* Ignore keys typed on icon windows. */
1858 if (s
!= 0 && event
.window
== s
->display
.x
->icon_desc
)
1860 where_mapping
= XLookupMapping (&event
, &nbytes
);
1861 /* Nasty fix for arrow keys */
1862 if (!nbytes
&& IsCursorKey (event
.detail
& 0xff))
1864 switch (event
.detail
& 0xff)
1866 case KC_CURSOR_LEFT
:
1867 where_mapping
= "\002";
1869 case KC_CURSOR_RIGHT
:
1870 where_mapping
= "\006";
1873 where_mapping
= "\020";
1875 case KC_CURSOR_DOWN
:
1876 where_mapping
= "\016";
1881 if (numchars
- nbytes
> 0)
1885 for (i
= 0; i
< nbytes
; i
++)
1887 bufp
->kind
= ascii_keystroke
;
1888 XSET (bufp
->code
, Lisp_Int
, where_mapping
[i
]);
1889 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
1897 #endif /* HAVE_X11 */
1901 s
= x_window_to_screen (event
.xcrossing
.window
);
1903 if (event
.xcrossing
.detail
== NotifyInferior
) /* Left Scrollbar */
1905 else if (event
.xcrossing
.focus
) /* Entered Window */
1907 /* If we decide we want to generate an event to be seen
1908 by the rest of Emacs, we put it here. */
1909 struct input_event emacs_event
;
1910 emacs_event
.kind
= no_event
;
1912 /* Avoid nasty pop/raise loops. */
1913 if (s
&& (!(s
->auto_raise
)
1915 || (event
.xcrossing
.time
- enter_timestamp
) > 500))
1917 x_new_focus_screen (s
);
1918 enter_timestamp
= event
.xcrossing
.time
;
1921 else if ((s
= x_window_to_scrollbar (event
.xcrossing
.window
,
1923 /* Fake a motion event */
1924 notice_mouse_movement (&emacs_event
,
1925 event
.xmotion
, s
, scrollbar_window
,
1930 if (! EQ (Vx_send_mouse_movement_events
, Qnil
)
1932 && emacs_event
.kind
!= no_event
)
1934 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
1941 else if (s
== x_focus_screen
)
1942 x_new_focus_screen (0);
1944 else if (s
= x_window_to_screen (event
.xcrossing
.window
))
1951 s
= x_window_to_screen (event
.xfocus
.window
);
1953 x_new_focus_screen (s
);
1957 if (event
.xcrossing
.detail
!= NotifyInferior
1958 && event
.xcrossing
.subwindow
== None
1959 && event
.xcrossing
.mode
== NotifyNormal
)
1961 s
= x_window_to_screen (event
.xcrossing
.window
);
1962 if (event
.xcrossing
.focus
)
1963 x_new_focus_screen (s
);
1964 else if (s
== x_focus_screen
)
1965 x_new_focus_screen (0);
1970 s
= x_window_to_screen (event
.xfocus
.window
);
1971 if (s
&& s
== x_focus_screen
)
1972 x_new_focus_screen (0);
1975 #else /* not HAVE_X11 */
1978 if ((event
.detail
& 0xFF) == 1)
1979 break; /* Coming from our own subwindow */
1980 if (event
.subwindow
!= 0)
1981 break; /* Entering our own subwindow. */
1984 extern int waiting_for_input
;
1985 struct screen
*old_s
= x_input_screen
;
1987 s
= x_window_to_screen (event
.window
);
1990 if (waiting_for_input
&& x_focus_screen
== 0)
1991 x_new_focus_screen (s
);
1996 if ((event
.detail
& 0xFF) == 1)
1997 break; /* Entering our own subwindow */
1998 if (event
.subwindow
!= 0)
1999 break; /* Leaving our own subwindow. */
2002 if (x_focus_screen
== 0
2003 && x_input_screen
!= 0
2004 && x_input_screen
== x_window_to_screen (event
.window
)
2005 && event
.window
== x_input_screen
->display
.x
->window_desc
)
2010 screen_unhighlight (s
);
2013 #endif /* not HAVE_X11 */
2018 s
= x_window_to_screen (event
.xmotion
.window
);
2023 pixel_to_glyph_translation (s
,
2024 event
.xmotion
.x
, event
.xmotion
.y
,
2027 note_mouse_position (s
, column
, row
, event
.xmotion
.time
);
2030 else if ((s
= x_window_to_scrollbar (event
.xmotion
.window
,
2033 What should go here
?
2039 case ConfigureNotify
:
2042 s
= x_window_to_screen (event
.xconfigure
.window
);
2046 columns
= ((event
.xconfigure
.width
-
2047 (2 * s
->display
.x
->internal_border_width
)
2048 - s
->display
.x
->v_scrollbar_width
)
2049 / FONT_WIDTH (s
->display
.x
->font
));
2050 rows
= ((event
.xconfigure
.height
-
2051 (2 * s
->display
.x
->internal_border_width
)
2052 - s
->display
.x
->h_scrollbar_height
)
2053 / FONT_HEIGHT (s
->display
.x
->font
));
2055 if (columns
!= s
->width
|| rows
!= s
->height
)
2057 XEvent ignored_event
;
2059 change_screen_size (s
, rows
, columns
, 0);
2060 x_resize_scrollbars (s
);
2061 SET_SCREEN_GARBAGED (s
);
2063 dumprectangle (s
, 0, 0, PIXEL_WIDTH (s
), PIXEL_HEIGHT (s
));
2064 /* Throw away the exposures generated by this reconfigure. */
2065 while (XCheckWindowEvent (x_current_display
,
2066 event
.xconfigure
.window
,
2067 ExposureMask
, &ignored_event
)
2072 s
->display
.x
->left_pos
= event
.xconfigure
.x
;
2073 s
->display
.x
->top_pos
= event
.xconfigure
.y
;
2074 s
->display
.x
->pixel_width
= event
.xconfigure
.width
;
2075 s
->display
.x
->pixel_height
= event
.xconfigure
.height
;
2082 /* If we decide we want to generate an event to be seen
2083 by the rest of Emacs, we put it here. */
2084 struct input_event emacs_event
;
2085 emacs_event
.kind
= no_event
;
2087 s
= x_window_to_screen (event
.xbutton
.window
);
2089 if (!x_focus_screen
|| (s
== x_focus_screen
))
2090 construct_mouse_click (&emacs_event
,
2095 if ((s
= x_window_to_scrollbar (event
.xbutton
.window
,
2098 if (!x_focus_screen
|| (selected_screen
== x_focus_screen
))
2099 construct_mouse_click (&emacs_event
,
2100 &event
, s
, part
, prefix
);
2105 if (numchars
>= 1 && emacs_event
.kind
!= no_event
)
2107 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
2115 #else /* not HAVE_X11 */
2117 case ButtonReleased
:
2118 s
= x_window_to_screen (event
.window
);
2121 if (event
.window
== s
->display
.x
->icon_desc
)
2123 x_make_screen_visible (s
);
2125 if (warp_mouse_on_deiconify
)
2126 XWarpMouse (s
->display
.x
->window_desc
, 10, 10);
2129 if (event
.window
== s
->display
.x
->window_desc
)
2135 enqueue_event (&event
, &x_mouse_queue
);
2138 bufp
->kind
= ascii_keystroke
;
2139 bufp
->code
= (char) 'X' & 037; /* C-x */
2140 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
2143 bufp
->kind
= ascii_keystroke
;
2144 bufp
->code
= (char) 0; /* C-@ */
2145 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
2152 #endif /* not HAVE_X11 */
2156 case CirculateNotify
:
2158 case CirculateRequest
:
2161 #endif /* HAVE_X11 */
2164 if (event
.xmapping
.request
== MappingKeyboard
)
2165 /* Someone has changed the keyboard mapping - flush the
2167 XRefreshKeyboardMapping (&event
.xmapping
);
2177 if (expected
&& ! event_found
)
2179 /* AOJ 880406: if select returns true but XPending doesn't, it means that
2180 there is an EOF condition; in other words, that X has died.
2181 Act as if there had been a hangup. */
2183 int fd
= ConnectionNumber (x_current_display
);
2186 if (0 != select (fd
+ 1, &mask
, (long *) 0, (long *) 0,
2187 (struct timeval
*) 0)
2188 && !XStuffPending ())
2189 kill (getpid (), SIGHUP
);
2191 #endif /* HAVE_SELECT */
2194 if (updating_screen
== 0)
2195 x_do_pending_expose ();
2202 /* Read and process only Expose events
2203 until we get an ExposeCopy event; then return.
2204 This is used in insert/delete line.
2205 We assume input is already blocked. */
2211 XKeyPressedEvent event
;
2215 /* while there are more events*/
2216 XMaskEvent (ExposeWindow
| ExposeRegion
| ExposeCopy
, &event
);
2220 if (event
.subwindow
!= 0)
2221 break; /* duplicate event */
2222 s
= x_window_to_screen (event
.window
);
2223 if (event
.window
== s
->display
.x
->icon_desc
)
2228 if (event
.window
== s
->display
.x
->window_desc
)
2230 expose_all_windows
= 1;
2231 s
->display
.x
->needs_exposure
= 1;
2237 if (event
.subwindow
!= 0)
2238 break; /* duplicate event */
2239 s
= x_window_to_screen (event
.window
);
2240 if (event
.window
== s
->display
.x
->icon_desc
)
2245 /* If window already needs full redraw, ignore this rectangle. */
2246 if (expose_all_windows
&& s
->display
.x
->needs_exposure
)
2248 /* Put the event on the queue of rectangles to redraw. */
2249 if (enqueue_event (&event
, &x_expose_queue
))
2250 /* If it is full, we can't record the rectangle,
2251 so redraw this entire window. */
2253 /* Say must check all windows' needs_exposure flags. */
2254 expose_all_windows
= 1;
2255 s
->display
.x
->needs_exposure
= 1;
2264 #endif /* HAVE_X11 */
2267 XTmouse_tracking_enable (enable
)
2272 /* Go through the list of screens and turn on/off mouse tracking for
2274 for (tail
= Vscreen_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
2276 if (XTYPE (XCONS (tail
)->car
) != Lisp_Screen
)
2278 if (XSCREEN (XCONS (tail
)->car
)->output_method
== output_x_window
)
2279 XSelectInput (x_current_display
,
2280 XSCREEN (XCONS (tail
)->car
)->display
.x
->window_desc
,
2282 ? (STANDARD_EVENT_SET
2284 | ButtonReleaseMask
)
2285 : STANDARD_EVENT_SET
));
2298 /* Draw a hollow box cursor. Don't change the inside of the box. */
2304 int left
= s
->cursor_x
* FONT_WIDTH (s
->display
.x
->font
)
2305 + s
->display
.x
->internal_border_width
;
2306 int top
= s
->cursor_y
* FONT_HEIGHT (s
->display
.x
->font
)
2307 + s
->display
.x
->internal_border_width
;
2308 int width
= FONT_WIDTH (s
->display
.x
->font
);
2309 int height
= FONT_HEIGHT (s
->display
.x
->font
);
2312 /* Perhaps we should subtract 1 from width and height... */
2313 XDrawRectangle (x_current_display
, s
->display
.x
->window_desc
,
2314 s
->display
.x
->cursor_gc
,
2315 left
, top
, width
- 1, height
- 1);
2317 XPixSet (s
->display
.x
->window_desc
,
2318 left
, top
, width
, 1,
2319 s
->display
.x
->cursor_pixel
);
2321 XPixSet (s
->display
.x
->window_desc
,
2322 left
, top
, 1, height
,
2323 s
->display
.x
->cursor_pixel
);
2325 XPixSet (s
->display
.x
->window_desc
,
2326 left
+width
-1, top
, 1, height
,
2327 s
->display
.x
->cursor_pixel
);
2329 XPixSet (s
->display
.x
->window_desc
,
2330 left
, top
+height
-1, width
, 1,
2331 s
->display
.x
->cursor_pixel
);
2332 #endif /* HAVE_X11 */
2335 /* Clear the cursor of screen S to background color,
2336 and mark the cursor as not shown.
2337 This is used when the text where the cursor is
2338 is about to be rewritten. */
2347 || s
->phys_cursor_x
< 0)
2351 x_display_cursor (s
, 0);
2353 XClearArea (x_current_display
, s
->display
.x
->window_desc
,
2354 s
->phys_cursor_x
* FONT_WIDTH (s
->display
.x
->font
)
2355 + s
->display
.x
->internal_border_width
,
2356 s
->phys_cursor_y
* FONT_HEIGHT (s
->display
.x
->font
)
2357 + s
->display
.x
->internal_border_width
,
2358 FONT_WIDTH (s
->display
.x
->font
) + 1, FONT_HEIGHT (s
->display
.x
->font
) + 1, False
);
2361 XPixSet (s
->display
.x
->window_desc
,
2362 s
->phys_cursor_x
* FONT_WIDTH (s
->display
.x
->font
) + s
->display
.x
->internal_border_width
,
2363 s
->phys_cursor_y
* FONT_HEIGHT (s
->display
.x
->font
) + s
->display
.x
->internal_border_width
,
2364 FONT_WIDTH (s
->display
.x
->font
), FONT_HEIGHT (s
->display
.x
->font
),
2365 s
->display
.x
->background_pixel
);
2366 #endif /* HAVE_X11 */
2367 s
->phys_cursor_x
= -1;
2370 x_display_bar_cursor (s
, on
)
2374 register int phys_x
= s
->phys_cursor_x
;
2375 register int phys_y
= s
->phys_cursor_y
;
2380 if (! s
->visible
|| (! on
&& s
->phys_cursor_x
< 0))
2385 (!on
|| phys_x
!= s
->cursor_x
|| phys_y
!= s
->cursor_y
))
2387 x1
= phys_x
* FONT_WIDTH (s
->display
.x
->font
)
2388 + s
->display
.x
->internal_border_width
;
2389 y1
= phys_y
* FONT_HEIGHT (s
->display
.x
->font
)
2390 + s
->display
.x
->internal_border_width
- 1;
2391 y2
= y1
+ FONT_HEIGHT (s
->display
.x
->font
) + 1;
2393 XDrawLine (x_current_display
, s
->display
.x
->window_desc
,
2394 s
->display
.x
->reverse_gc
, x1
, y1
, x1
, y2
);
2396 s
->phys_cursor_x
= phys_x
= -1;
2399 if (on
&& s
== x_highlight_screen
)
2401 x1
= s
->cursor_x
* FONT_WIDTH (s
->display
.x
->font
)
2402 + s
->display
.x
->internal_border_width
;
2403 y1
= s
->cursor_y
* FONT_HEIGHT (s
->display
.x
->font
)
2404 + s
->display
.x
->internal_border_width
- 1;
2405 y2
= y1
+ FONT_HEIGHT (s
->display
.x
->font
) + 1;
2407 XDrawLine (x_current_display
, s
->display
.x
->window_desc
,
2408 s
->display
.x
->cursor_gc
, x1
, y1
, x1
, y2
);
2410 s
->phys_cursor_x
= s
->cursor_x
;
2411 s
->phys_cursor_y
= s
->cursor_y
;
2419 /* Redraw the glyph at ROW, COLUMN on screen S, in the style HIGHLIGHT.
2420 If there is no character there, erase the area. HIGHLIGHT is as
2421 defined for dumpglyphs. */
2424 x_draw_single_glyph (s
, row
, column
, highlight
)
2429 register struct screen_glyphs
*current_screen
= SCREEN_CURRENT_GLYPHS (s
);
2431 /* If there is supposed to be a character there, redraw it
2432 in that line's normal video. */
2433 if (current_screen
->enable
[row
]
2434 && column
< current_screen
->used
[row
])
2436 (column
* FONT_WIDTH (s
->display
.x
->font
)
2437 + s
->display
.x
->internal_border_width
),
2438 (row
* FONT_HEIGHT (s
->display
.x
->font
)
2439 + s
->display
.x
->internal_border_width
),
2440 ¤t_screen
->glyphs
[row
][column
],
2441 1, highlight
, s
->display
.x
->font
);
2445 static GLYPH a_space_glyph
= SPACEGLYPH
;
2447 (column
* FONT_WIDTH (s
->display
.x
->font
)
2448 + s
->display
.x
->internal_border_width
),
2449 (row
* FONT_HEIGHT (s
->display
.x
->font
)
2450 + s
->display
.x
->internal_border_width
),
2451 &a_space_glyph
, 1, highlight
, s
->display
.x
->font
);
2453 XPixSet (s
->display
.x
->window_desc
,
2454 (column
* FONT_WIDTH (s
->display
.x
->font
)
2455 + s
->display
.x
->internal_border_width
),
2456 (row
* FONT_HEIGHT (s
->display
.x
->font
)
2457 + s
->display
.x
->internal_border_width
),
2458 FONT_WIDTH (s
->display
.x
->font
),
2459 FONT_HEIGHT (s
->display
.x
->font
),
2461 ? s
->display
.x
->background_pixel
2463 ? s
->display
.x
->foreground_pixel
2464 : s
->display
.x
->cursor_pixel
)));
2465 #endif /* HAVE_X11 */
2469 /* Turn the displayed cursor of screen S on or off according to ON.
2470 If ON is nonzero, where to put the cursor is specified
2471 by S->cursor_x and S->cursor_y. */
2474 x_display_box_cursor (s
, on
)
2481 /* If cursor is off and we want it off, return quickly. */
2483 if (!on
&& s
->phys_cursor_x
< 0)
2486 /* If cursor is currently being shown and we don't want it to be
2487 or it is in the wrong place,
2488 or we want a hollow box and it's not so, (pout!)
2490 if (s
->phys_cursor_x
>= 0
2492 || s
->phys_cursor_x
!= s
->cursor_x
2493 || s
->phys_cursor_y
!= s
->cursor_y
2494 || (s
->display
.x
->text_cursor_kind
!= hollow_box_cursor
2495 && (s
!= x_highlight_screen
))))
2497 /* Erase the cursor by redrawing the character underneath it. */
2498 x_draw_single_glyph (s
, s
->phys_cursor_y
, s
->phys_cursor_x
,
2499 (SCREEN_CURRENT_GLYPHS (s
)
2500 ->highlight
[s
->phys_cursor_y
]));
2502 s
->phys_cursor_x
= -1;
2505 /* If we want to show a cursor,
2506 or we want a box cursor and it's not so,
2507 write it in the right place. */
2509 && (s
->phys_cursor_x
< 0
2510 || (s
->display
.x
->text_cursor_kind
!= filled_box_cursor
2511 && s
== x_highlight_screen
)))
2513 if (s
!= x_highlight_screen
)
2516 s
->display
.x
->text_cursor_kind
= hollow_box_cursor
;
2520 x_draw_single_glyph (s
, s
->cursor_y
, s
->cursor_x
, 2);
2521 s
->display
.x
->text_cursor_kind
= filled_box_cursor
;
2524 s
->phys_cursor_x
= s
->cursor_x
;
2525 s
->phys_cursor_y
= s
->cursor_y
;
2528 if (updating_screen
!= s
)
2532 extern Lisp_Object Vbar_cursor
;
2534 x_display_cursor (s
, on
)
2538 if (EQ (Vbar_cursor
, Qnil
))
2539 x_display_box_cursor (s
, on
);
2541 x_display_bar_cursor (s
, on
);
2546 /* Refresh bitmap kitchen sink icon for screen S
2547 when we get an expose event for it. */
2553 /* Normally, the window manager handles this function. */
2557 if (s
->display
.x
->icon_bitmap_flag
)
2558 XBitmapBitsPut (s
->display
.x
->icon_desc
, 0, 0, sink_width
, sink_height
,
2559 sink_bits
, BlackPixel
, WHITE_PIX_DEFAULT
,
2560 icon_bitmap
, GXcopy
, AllPlanes
);
2563 extern struct screen
*selected_screen
;
2564 struct Lisp_String
*str
;
2565 unsigned char *string
;
2568 = XSTRING (XBUFFER (XWINDOW (s
->selected_window
)->buffer
)->name
)->data
;
2570 if (s
->display
.x
->icon_label
!= string
)
2572 s
->display
.x
->icon_label
= string
;
2573 XChangeWindow (s
->display
.x
->icon_desc
,
2574 XQueryWidth (string
, icon_font_info
->id
) + 10,
2575 icon_font_info
->height
+ 10);
2578 XText (s
->display
.x
->icon_desc
, 5, 5, string
,
2579 str
->size
, icon_font_info
->id
,
2580 BLACK_PIX_DEFAULT
, WHITE_PIX_DEFAULT
);
2583 #endif /* HAVE_X11 */
2586 /* Make the x-window of screen S use the kitchen-sink icon
2587 that's a window generated by Emacs. */
2596 if (s
->display
.x
->window_desc
== 0)
2601 XFreePixmap (x_current_display
, icon_bitmap
);
2604 XCreateBitmapFromData (x_current_display
, s
->display
.x
->window_desc
,
2605 gnu_bits
, gnu_width
, gnu_height
);
2606 x_wm_set_icon_pixmap (s
, icon_bitmap
);
2607 s
->display
.x
->icon_bitmap_flag
= 1;
2609 if (s
->display
.x
->icon_desc
)
2611 XClearIconWindow (s
->display
.x
->window_desc
);
2612 XDestroyWindow (s
->display
.x
->icon_desc
);
2615 icon_window
= XCreateWindow (s
->display
.x
->parent_desc
,
2616 0, 0, sink_width
, sink_height
,
2617 2, WhitePixmap
, (Pixmap
) NULL
);
2619 if (icon_window
== 0)
2622 XSetIconWindow (s
->display
.x
->window_desc
, icon_window
);
2623 XSelectInput (icon_window
, ExposeWindow
| UnmapWindow
);
2625 s
->display
.x
->icon_desc
= icon_window
;
2626 s
->display
.x
->icon_bitmap_flag
= 1;
2628 if (icon_bitmap
== 0)
2630 = XStoreBitmap (sink_mask_width
, sink_mask_height
, sink_mask_bits
);
2631 #endif /* HAVE_X11 */
2637 /* Make the x-window of screen S use a rectangle with text. */
2640 x_text_icon (s
, icon_name
)
2648 char *X_DefaultValue
;
2652 #define WhitePixel 1
2656 #define BlackPixel 0
2658 #endif /* not HAVE_X11 */
2660 if (s
->display
.x
->window_desc
== 0)
2663 if (icon_font_info
== 0)
2665 = XGetFont (XGetDefault (XDISPLAY
2666 (char *) XSTRING (invocation_name
)->data
,
2671 s
->display
.x
->icon_label
= icon_name
;
2673 if (! s
->display
.x
->icon_label
)
2674 s
->display
.x
->icon_label
= " *emacs* ";
2676 XSetIconName (x_current_display
, s
->display
.x
->window_desc
,
2677 (char *) s
->display
.x
->icon_label
);
2679 s
->display
.x
->icon_bitmap_flag
= 0;
2681 if (s
->display
.x
->icon_desc
)
2683 XClearIconWindow (XDISPLAY s
->display
.x
->window_desc
);
2684 XDestroyWindow (XDISPLAY s
->display
.x
->icon_desc
);
2688 s
->display
.x
->icon_label
= (unsigned char *) icon_name
;
2690 if (! s
->display
.x
->icon_label
)
2691 s
->display
.x
->icon_label
= XSTRING (s
->name
)->data
;
2693 width
= XStringWidth (s
->display
.x
->icon_label
, icon_font_info
, 0, 0);
2694 icon_window
= XCreateWindow (s
->display
.x
->parent_desc
,
2695 s
->display
.x
->left_pos
,
2696 s
->display
.x
->top_pos
,
2697 width
+ 10, icon_font_info
->height
+ 10,
2698 2, BlackPixmap
, WhitePixmap
);
2700 if (icon_window
== 0)
2703 XSetIconWindow (s
->display
.x
->window_desc
, icon_window
);
2704 XSelectInput (icon_window
, ExposeWindow
| ExposeRegion
| UnmapWindow
| ButtonPressed
);
2706 s
->display
.x
->icon_desc
= icon_window
;
2707 s
->display
.x
->icon_bitmap_flag
= 0;
2708 s
->display
.x
->icon_label
= 0;
2709 #endif /* HAVE_X11 */
2714 static char *x_proto_requests
[] =
2717 "ChangeWindowAttributes",
2718 "GetWindowAttributes",
2720 "DestroySubwindows",
2737 "SetSelectionOwner",
2738 "GetSelectionOwner",
2745 "ChangeActivePointerGrab",
2765 "ListFontsWithInfo",
2774 "SetClipRectangles",
2785 "PolyFillRectangle",
2795 "CopyColormapAndFree",
2797 "UninstallColormap",
2798 "ListInstalledColormaps",
2809 "CreateGlyphCursor",
2815 "ChangeKeyboardMapping",
2816 "GetKeyboardMapping",
2817 "ChangeKeyboardControl",
2818 "GetKeyboardControl",
2820 "ChangePointerControl",
2821 "GetPointerControl",
2831 "SetPointerMapping",
2832 "GetPointerMapping",
2833 "SetModifierMapping",
2834 "GetModifierMapping",
2838 #define acceptable_x_error_p(type) ((type) == 94)
2840 x_handle_error_gracefully (event
)
2843 char error_ptr
[128];
2844 char *proto_ptr
= x_proto_requests
[event
->request_code
];
2847 XGetErrorText (x_current_display
, event
->error_code
, error_ptr
, 128);
2848 sprintf (str
, "X Protocol Error: %s on request: %s", error_ptr
, proto_ptr
);
2849 TOTALLY_UNBLOCK_INPUT
;
2854 extern int x_selection_alloc_error
;
2855 extern int x_converting_selection
;
2858 /* Handle X Errors. If the error is not traumatic,
2859 just call error (). Otherwise print a (hopefully) interesting
2862 The arg to Fkill_emacs is an exit status value
2863 and also prevents any questions. */
2865 x_error_handler (disp
, event
)
2870 #define XlibDisplayIOError (1L << 0)
2873 struct _XErrorEvent
*event
;
2876 /* Here we use the standard X handlers. */
2879 if (event
&& event
->type
== 0) /* 0 is the XError Event type. */
2883 if (event
->request_code
== BadAlloc
&& x_converting_selection
)
2884 x_selection_alloc_error
= 1;
2888 if (acceptable_x_error_p (event
->request_code
))
2889 x_handle_error_gracefully (event
);
2891 _XDefaultError (disp
, event
);
2895 disp
->flags
|= XlibDisplayIOError
;
2896 _XDefaultIOError (disp
);
2903 Fkill_emacs (make_number (70));
2906 /* Initialize communication with the X window server. */
2909 static unsigned int x_wire_count
;
2912 fprintf (stderr
, "Lib call: %d\n", ++x_wire_count
);
2917 /* Set the font of the x-window specified by screen S
2918 to the font named NEWNAME. This is safe to use
2919 even before S has an actual x-window. */
2923 /* A table of all the fonts we have already loaded. */
2924 static XFontStruct
**x_font_table
;
2926 /* The current capacity of x_font_table. */
2927 static int x_font_table_size
;
2929 /* The number of fonts actually stored in x_font_table.
2930 x_font_table[n] is used and valid iff 0 <= n < n_fonts.
2931 0 <= n_fonts <= x_font_table_size. */
2934 x_new_font (s
, fontname
)
2936 register char *fontname
;
2940 int n_matching_fonts
;
2941 XFontStruct
*font_info
;
2944 /* Get a list of all the fonts that match this name. Once we
2945 have a list of matching fonts, we compare them against the fonts
2946 we already have by comparing font ids. */
2947 font_names
= (char **) XListFontsWithInfo (x_current_display
, fontname
,
2948 1024, &n_matching_fonts
,
2950 /* If the server couldn't find any fonts whose named matched fontname,
2951 return an error code. */
2952 if (n_matching_fonts
== 0)
2955 /* See if we've already loaded this font. */
2960 for (i
= 0; i
< n_fonts
; i
++)
2961 for (j
= 0; j
< n_matching_fonts
; j
++)
2962 if (x_font_table
[i
]->fid
== font_info
[j
].fid
)
2970 /* If we have, just return it from the table. */
2973 s
->display
.x
->font
= x_font_table
[already_loaded
];
2976 /* Otherwise, load the font and add it to the table. */
2981 font
= (XFontStruct
*) XLoadQueryFont (x_current_display
, fontname
);
2985 /* Do we need to create the table? */
2986 if (x_font_table_size
== 0)
2988 x_font_table_size
= 16;
2990 = (XFontStruct
**) xmalloc (x_font_table_size
2991 * sizeof (x_font_table
[0]));
2993 /* Do we need to grow the table? */
2994 else if (n_fonts
>= x_font_table_size
)
2996 x_font_table_size
<<= 1;
2998 = (XFontStruct
**) xrealloc (x_font_table
,
3000 * sizeof (x_font_table
[0])));
3003 s
->display
.x
->font
= x_font_table
[n_fonts
++] = font
;
3006 /* Free the information from XListFontsWithInfo. The data
3007 we actually retain comes from XLoadQueryFont. */
3008 XFreeFontInfo (font_names
, font_info
, n_matching_fonts
);
3010 /* Now make the screen display the given font. */
3011 if (s
->display
.x
->window_desc
!= 0)
3013 XSetFont (x_current_display
, s
->display
.x
->normal_gc
,
3014 s
->display
.x
->font
->fid
);
3015 XSetFont (x_current_display
, s
->display
.x
->reverse_gc
,
3016 s
->display
.x
->font
->fid
);
3017 XSetFont (x_current_display
, s
->display
.x
->cursor_gc
,
3018 s
->display
.x
->font
->fid
);
3020 x_set_window_size (s
, s
->width
, s
->height
);
3026 x_new_font (s
, newname
)
3028 register char *newname
;
3033 temp
= XGetFont (newname
);
3034 if (temp
== (FONT_TYPE
*) 0)
3037 if (s
->display
.x
->font
)
3038 XLoseFont (s
->display
.x
->font
);
3040 s
->display
.x
->font
= temp
;
3042 if (s
->display
.x
->window_desc
!= 0)
3043 x_set_window_size (s
, s
->width
, s
->height
);
3049 x_calc_absolute_position (s
)
3053 if (s
->display
.x
->left_pos
< 0)
3054 s
->display
.x
->left_pos
3055 = XINT (x_screen_width
) - PIXEL_WIDTH (s
) + s
->display
.x
->left_pos
;
3057 if (s
->display
.x
->top_pos
< 0)
3058 s
->display
.x
->top_pos
3059 = XINT (x_screen_height
) - PIXEL_HEIGHT (s
) + s
->display
.x
->top_pos
;
3061 WINDOWINFO_TYPE parentinfo
;
3063 XGetWindowInfo (s
->display
.x
->window_desc
, &parentinfo
);
3065 if (s
->display
.x
->left_pos
< 0)
3066 s
->display
.x
->left_pos
= parentinfo
.width
+ (s
->display
.x
->left_pos
+ 1)
3067 - PIXEL_WIDTH (s
) - 2 * s
->display
.x
->internal_border_width
;
3069 if (s
->display
.x
->top_pos
< 0)
3070 s
->display
.x
->top_pos
= parentinfo
.height
+ (s
->display
.x
->top_pos
+ 1)
3071 - PIXEL_HEIGHT (s
) - 2 * s
->display
.x
->internal_border_width
;
3075 x_set_offset (s
, xoff
, yoff
)
3077 register int xoff
, yoff
;
3079 s
->display
.x
->top_pos
= yoff
;
3080 s
->display
.x
->left_pos
= xoff
;
3081 x_calc_absolute_position (s
);
3084 XMoveWindow (XDISPLAY s
->display
.x
->window_desc
,
3085 s
->display
.x
->left_pos
, s
->display
.x
->top_pos
);
3087 x_wm_set_size_hint (s
, 0);
3092 /* Call this to change the size of screen S's x-window. */
3094 x_set_window_size (s
, cols
, rows
)
3096 register int cols
, rows
;
3098 int pixelwidth
, pixelheight
;
3100 int ibw
= s
->display
.x
->internal_border_width
;
3104 /* ??? Who DOES worry about minimum reasonable sizes? */
3105 pixelwidth
= (cols
* FONT_WIDTH (s
->display
.x
->font
) + 2 * ibw
3106 + s
->display
.x
->v_scrollbar_width
);
3107 pixelheight
= (rows
* FONT_HEIGHT (s
->display
.x
->font
) + 2 * ibw
3108 + s
->display
.x
->h_scrollbar_height
);
3111 x_wm_set_size_hint (s
, 0);
3112 #endif /* HAVE_X11 */
3113 XChangeWindowSize (s
->display
.x
->window_desc
, pixelwidth
, pixelheight
);
3119 x_set_resize_hint (s
)
3123 XSetResizeHint (s
->display
.x
->window_desc
, 2 * s
->display
.x
->internal_border_width
,
3124 2 * s
->display
.x
->internal_border_width
,
3125 FONT_WIDTH (s
->display
.x
->font
), FONT_HEIGHT (s
->display
.x
->font
));
3127 #endif /* not HAVE_X11 */
3130 x_set_mouse_position (s
, x
, y
)
3139 pix_x
= (SCREEN_WIDTH (s
)
3140 * FONT_WIDTH (s
->display
.x
->font
)
3141 + 2 * s
->display
.x
->internal_border_width
3142 + s
->display
.x
->v_scrollbar_width
) / 2;
3144 pix_x
= x
* FONT_WIDTH (s
->display
.x
->font
) + 2; /* add 2 pixels to each
3145 dimension to move the
3150 pix_y
= (SCREEN_HEIGHT (s
)
3151 * FONT_HEIGHT (s
->display
.x
->font
)
3152 + 2 * s
->display
.x
->internal_border_width
3153 + s
->display
.x
->h_scrollbar_height
) / 2;
3155 pix_y
= y
* FONT_HEIGHT (s
->display
.x
->font
) + 2;
3161 XWarpMousePointer (s
->display
.x
->window_desc
, pix_x
, pix_y
);
3166 x_focus_on_screen (s
)
3171 /* I don't think that the ICCCM allows programs to do things like this
3172 without the interaction of the window manager. Whatever you end up
3173 doing with this code, do it to x_unfocus_screen too. */
3174 XSetInputFocus (x_current_display
, s
->display
.x
->window_desc
,
3175 RevertToPointerRoot
, CurrentTime
);
3179 x_unfocus_screen (s
)
3183 /* Look at the remarks in x_focus_on_screen. */
3184 if (x_focus_screen
== s
)
3185 XSetInputFocus (x_current_display
, PointerRoot
,
3186 RevertToPointerRoot
, CurrentTime
);
3192 /* Raise screen S. */
3200 XRaiseWindow (XDISPLAY s
->display
.x
->window_desc
);
3206 /* Lower screen S. */
3214 XLowerWindow (XDISPLAY s
->display
.x
->window_desc
);
3220 /* Change from withdrawn state to mapped state. */
3222 x_make_screen_visible (s
)
3230 XRaiseWindow (XDISPLAY s
->display
.x
->window_desc
);
3239 if (! EQ (Vx_no_window_manager
, Qt
))
3240 x_wm_set_window_state (s
, NormalState
);
3242 XMapWindow (XDISPLAY s
->display
.x
->window_desc
);
3243 if (s
->display
.x
->v_scrollbar
!= 0 || s
->display
.x
->h_scrollbar
!= 0)
3244 XMapSubwindows (x_current_display
, s
->display
.x
->window_desc
);
3247 XMapWindow (XDISPLAY s
->display
.x
->window_desc
);
3248 if (s
->display
.x
->icon_desc
!= 0)
3249 XUnmapWindow (s
->display
.x
->icon_desc
);
3251 /* Handled by the MapNotify event for X11 */
3255 /* NOTE: this may cause problems for the first screen. */
3257 #endif /* not HAVE_X11 */
3259 XRaiseWindow (XDISPLAY s
->display
.x
->window_desc
);
3264 /* Change from mapped state to withdrawn state. */
3266 x_make_screen_invisible (s
)
3277 if (! EQ (Vx_no_window_manager
, Qt
))
3281 unmap
.type
= UnmapNotify
;
3282 unmap
.window
= s
->display
.x
->window_desc
;
3283 unmap
.event
= DefaultRootWindow (x_current_display
);
3284 unmap
.from_configure
= False
;
3285 XSendEvent (x_current_display
, DefaultRootWindow (x_current_display
),
3286 False
, SubstructureRedirectMask
|SubstructureNotifyMask
,
3290 /* The new function below does the same as the above code, plus unmapping
3291 the window. Sending the event without actually unmapping can make
3292 the window manager start ignoring the window (i.e., no more title bar,
3293 icon manager stuff.) */
3296 /* New function available with R4 */
3297 if (! XWithdrawWindow (x_current_display
, s
->display
.x
->window_desc
,
3298 DefaultScreen (x_current_display
)))
3300 UNBLOCK_INPUT_RESIGNAL
;
3301 error ("Can't notify window manager of iconification.");
3305 XUnmapWindow (XDISPLAY s
->display
.x
->window_desc
);
3307 s
->visible
= 0; /* Handled by the UnMap event for X11 */
3308 if (s
->display
.x
->icon_desc
!= 0)
3309 XUnmapWindow (XDISPLAY s
->display
.x
->icon_desc
);
3310 #endif /* not HAVE_X11 */
3316 /* Window manager communication. Created in Fx_open_connection. */
3317 extern Atom Xatom_wm_change_state
;
3319 /* Change window state from mapped to iconified. */
3321 x_iconify_screen (s
)
3332 if (! EQ (Vx_no_window_manager
, Qt
))
3333 if (! XIconifyWindow (x_current_display
, s
->display
.x
->window_desc
,
3334 DefaultScreen (x_current_display
)))
3336 UNBLOCK_INPUT_RESIGNAL
;
3337 error ("Can't notify window manager of iconification.");
3344 XClientMessageEvent message
;
3346 message
.window
= s
->display
.x
->window_desc
;
3347 message
.type
= ClientMessage
;
3348 message
.message_type
= Xatom_wm_change_state
;
3349 message
.format
= 32;
3350 message
.data
.l
[0] = IconicState
;
3352 if (! XSendEvent (x_current_display
,
3353 DefaultRootWindow (x_current_display
),
3355 SubstructureRedirectMask
| SubstructureNotifyMask
,
3358 UNBLOCK_INPUT_RESIGNAL
;
3359 error ("Can't notify window manager of iconification.");
3364 XUnmapWindow (XDISPLAY s
->display
.x
->window_desc
);
3366 s
->visible
= 0; /* Handled in the UnMap event for X11. */
3367 if (s
->display
.x
->icon_desc
!= 0)
3369 XMapWindow (XDISPLAY s
->display
.x
->icon_desc
);
3378 /* Destroy the X window of screen S.
3379 DISPL is the former s->display (since s->display
3380 has already been nulled out). */
3382 x_destroy_window (s
, displ
)
3384 union display displ
;
3389 if (displ
.x
->icon_desc
!= 0)
3390 XDestroyWindow (XDISPLAY displ
.x
->icon_desc
);
3391 XDestroyWindow (XDISPLAY displ
.x
->window_desc
);
3396 if (s
== x_focus_screen
)
3398 if (s
== x_highlight_screen
)
3399 x_highlight_screen
= 0;
3404 /* Manage event queues.
3406 This code is only used by the X10 support.
3408 We cannot leave events in the X queue and get them when we are ready
3409 because X does not provide a subroutine to get only a certain kind
3410 of event but not block if there are no queued events of that kind.
3412 Therefore, we must examine events as they come in and copy events
3413 of certain kinds into our private queues.
3415 All ExposeRegion events are put in x_expose_queue.
3416 All ButtonPressed and ButtonReleased events are put in x_mouse_queue. */
3419 /* Write the event *P_XREP into the event queue *QUEUE.
3420 If the queue is full, do nothing, but return nonzero. */
3423 enqueue_event (p_xrep
, queue
)
3424 register XEvent
*p_xrep
;
3425 register struct event_queue
*queue
;
3427 int newindex
= queue
->windex
+ 1;
3428 if (newindex
== EVENT_BUFFER_SIZE
)
3430 if (newindex
== queue
->rindex
)
3432 queue
->xrep
[queue
->windex
] = *p_xrep
;
3433 queue
->windex
= newindex
;
3437 /* Fetch the next event from queue *QUEUE and store it in *P_XREP.
3438 If *QUEUE is empty, do nothing and return 0. */
3441 dequeue_event (p_xrep
, queue
)
3442 register XEvent
*p_xrep
;
3443 register struct event_queue
*queue
;
3445 if (queue
->windex
== queue
->rindex
)
3447 *p_xrep
= queue
->xrep
[queue
->rindex
++];
3448 if (queue
->rindex
== EVENT_BUFFER_SIZE
)
3453 /* Return the number of events buffered in *QUEUE. */
3456 queue_event_count (queue
)
3457 register struct event_queue
*queue
;
3459 int tem
= queue
->windex
- queue
->rindex
;
3462 return EVENT_BUFFER_SIZE
+ tem
;
3465 /* Return nonzero if mouse input is pending. */
3468 mouse_event_pending_p ()
3470 return queue_event_count (&x_mouse_queue
);
3476 x_wm_set_size_hint (s
, prompting
)
3480 XSizeHints size_hints
;
3481 Window window
= s
->display
.x
->window_desc
;
3483 size_hints
.flags
= PResizeInc
| PMinSize
| PMaxSize
;
3485 flexlines
= s
->height
;
3487 size_hints
.x
= s
->display
.x
->left_pos
;
3488 size_hints
.y
= s
->display
.x
->top_pos
;
3489 size_hints
.height
= PIXEL_HEIGHT (s
);
3490 size_hints
.width
= PIXEL_WIDTH (s
);
3491 size_hints
.width_inc
= FONT_WIDTH (s
->display
.x
->font
);
3492 size_hints
.height_inc
= FONT_HEIGHT (s
->display
.x
->font
);
3493 size_hints
.base_width
= (2 * s
->display
.x
->internal_border_width
)
3494 + s
->display
.x
->v_scrollbar_width
;
3495 size_hints
.base_height
= (2 * s
->display
.x
->internal_border_width
)
3496 + s
->display
.x
->h_scrollbar_height
;
3497 size_hints
.min_width
= size_hints
.base_width
+ size_hints
.width_inc
;
3498 size_hints
.min_height
= size_hints
.base_height
+ size_hints
.height_inc
;
3499 size_hints
.max_width
= x_screen_width
3500 - ((2 * s
->display
.x
->internal_border_width
)
3501 + s
->display
.x
->v_scrollbar_width
);
3502 size_hints
.max_height
= x_screen_height
3503 - ((2 * s
->display
.x
->internal_border_width
)
3504 + s
->display
.x
->h_scrollbar_height
);
3507 size_hints
.flags
|= prompting
;
3510 XSizeHints hints
; /* Sometimes I hate X Windows... */
3512 XGetNormalHints (x_current_display
, window
, &hints
);
3513 if (hints
.flags
& PSize
)
3514 size_hints
.flags
|= PSize
;
3515 if (hints
.flags
& PPosition
)
3516 size_hints
.flags
|= PPosition
;
3517 if (hints
.flags
& USPosition
)
3518 size_hints
.flags
|= USPosition
;
3519 if (hints
.flags
& USSize
)
3520 size_hints
.flags
|= USSize
;
3524 XSetNormalHints (x_current_display
, window
, &size_hints
);
3526 XSetWMNormalHints (x_current_display
, window
, &size_hints
);
3529 /* Used for IconicState or NormalState */
3530 x_wm_set_window_state (s
, state
)
3535 Window window
= s
->display
.x
->window_desc
;
3537 wm_hints
.flags
= StateHint
;
3538 wm_hints
.initial_state
= state
;
3539 XSetWMHints (x_current_display
, window
, &wm_hints
);
3542 x_wm_set_icon_pixmap (s
, icon_pixmap
)
3547 Window window
= s
->display
.x
->window_desc
;
3549 wm_hints
.flags
= IconPixmapHint
;
3550 wm_hints
.icon_pixmap
= icon_pixmap
;
3551 XSetWMHints (x_current_display
, window
, &wm_hints
);
3554 x_wm_set_icon_position (s
, icon_x
, icon_y
)
3559 Window window
= s
->display
.x
->window_desc
;
3561 wm_hints
.flags
= IconPositionHint
;
3562 wm_hints
.icon_x
= icon_x
;
3563 wm_hints
.icon_y
= icon_y
;
3564 XSetWMHints (x_current_display
, window
, &wm_hints
);
3569 x_term_init (display_name
)
3575 extern int old_fcntl_owner
;
3578 x_focus_screen
= x_highlight_screen
= 0;
3580 x_current_display
= XOpenDisplay (display_name
);
3581 if (x_current_display
== 0)
3582 fatal ("X server %s not responding; check the DISPLAY environment variable or use \"-d\"\n",
3587 int hostname_size
= MAXHOSTNAMELEN
+ 1;
3589 hostname
= (char *) xmalloc (hostname_size
);
3592 XSetAfterFunction (x_current_display
, x_trace_wire
);
3595 invocation_name
= Ffile_name_nondirectory (Fcar (Vcommand_line_args
));
3597 /* Try to get the host name; if the buffer is too short, try
3598 again. Apparently, the only indication gethostname gives of
3599 whether the buffer was large enough is the presence or absence
3600 of a '\0' in the string. Eech. */
3603 gethostname (hostname
, hostname_size
- 1);
3604 hostname
[hostname_size
- 1] = '\0';
3606 /* Was the buffer large enough for gethostname to store the '\0'? */
3607 if (strlen (hostname
) < hostname_size
- 1)
3610 hostname_size
<<= 1;
3611 hostname
= (char *) xrealloc (hostname
, hostname_size
);
3613 x_id_name
= (char *) xmalloc (XSTRING (invocation_name
)->size
3616 sprintf (x_id_name
, "%s@%s", XSTRING (invocation_name
)->data
, hostname
);
3619 dup2 (ConnectionNumber (x_current_display
), 0);
3621 #ifndef SYSV_STREAMS
3622 /* Streams somehow keeps track of which descriptor number
3623 is being used to talk to X. So it is not safe to substitute
3624 descriptor 0. But it is safe to make descriptor 0 a copy of it. */
3625 close (ConnectionNumber (x_current_display
));
3626 ConnectionNumber (x_current_display
) = 0; /* Looks a little strange?
3627 * check the def of the macro;
3628 * it is a genuine lvalue */
3629 #endif /* not SYSV_STREAMS */
3631 #endif /* HAVE_X11 */
3634 old_fcntl_owner
= fcntl (0, F_GETOWN
, 0);
3635 #ifdef F_SETOWN_SOCK_NEG
3636 fcntl (0, F_SETOWN
, -getpid ()); /* stdin is a socket here */
3638 fcntl (0, F_SETOWN
, getpid ());
3639 #endif /* F_SETOWN_SOCK_NEG */
3640 #endif /* F_SETOWN */
3646 /* Must use interrupt input because we cannot otherwise
3647 arrange for C-g to be noticed immediately.
3648 We cannot connect it to SIGINT. */
3649 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
3651 expose_all_windows
= 0;
3653 clear_screen_hook
= XTclear_screen
;
3654 clear_end_of_line_hook
= XTclear_end_of_line
;
3655 ins_del_lines_hook
= XTins_del_lines
;
3656 change_line_highlight_hook
= XTchange_line_highlight
;
3657 insert_glyphs_hook
= XTinsert_glyphs
;
3658 write_glyphs_hook
= XTwrite_glyphs
;
3659 delete_glyphs_hook
= XTdelete_glyphs
;
3660 ring_bell_hook
= XTring_bell
;
3661 reset_terminal_modes_hook
= XTreset_terminal_modes
;
3662 set_terminal_modes_hook
= XTset_terminal_modes
;
3663 update_begin_hook
= XTupdate_begin
;
3664 update_end_hook
= XTupdate_end
;
3665 set_terminal_window_hook
= XTset_terminal_window
;
3666 read_socket_hook
= XTread_socket
;
3667 cursor_to_hook
= XTcursor_to
;
3668 reassert_line_highlight_hook
= XTreassert_line_highlight
;
3669 screen_rehighlight_hook
= XTscreen_rehighlight
;
3670 mouse_tracking_enable_hook
= XTmouse_tracking_enable
;
3672 scroll_region_ok
= 1; /* we'll scroll partial screens */
3673 char_ins_del_ok
= 0; /* just as fast to write the line */
3674 line_ins_del_ok
= 1; /* we'll just blt 'em */
3675 fast_clear_end_of_line
= 1; /* X does this well */
3676 memory_below_screen
= 0; /* we don't remember what scrolls
3680 XHandleError (x_error_handler
);
3681 XHandleIOError (x_error_handler
);
3683 /* Disable Window Change signals; they are handled by X events. */
3685 signal (SIGWINCH
, SIG_DFL
);
3686 #endif /* SIGWINCH */
3688 signal (SIGPIPE
, x_error_handler
);
3694 staticpro (&invocation_name
);
3695 invocation_name
= Qnil
;
3697 Qmouse_moved
= intern ("mouse-moved");
3698 Qmouse_click
= intern ("mouse-click");
3699 Qscrollbar_click
= intern ("scrollbar-click");
3701 #endif /* HAVE_X11 */
3702 #endif /* HAVE_X_WINDOWS */