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
, *id_name
, *invocation_name
;
166 /* This is the X connection that we are using. */
168 Display
*x_current_display
;
170 /* Screen being updated by update_screen. */
171 /* This is set by XTupdate_begin and looked at by all the
172 XT functions. It is zero while not inside an update.
173 In that case, the XT functions assume that `selected_screen'
174 is the screen to apply to. */
176 static struct screen
*updating_screen
;
178 /* The screen (if any) which has the X window that has keyboard focus.
179 Zero if none. This is examined by Ffocus_screen in screen.c. */
180 struct screen
*x_focus_screen
;
182 /* The screen which currently has the visual highlight, and should get
183 keyboard input (other sorts of input have the screen encoded in the
184 event). It points to the X focus screen's selected window's
185 screen. It differs from x_focus_screen when we're using a global
187 static struct screen
*x_highlight_screen
;
189 /* From .Xdefaults, the value of "emacs.WarpMouse". If non-zero,
190 mouse is moved to inside of screen when screen is de-iconified. */
192 static int warp_mouse_on_deiconify
;
194 /* During an update, maximum vpos for ins/del line operations to affect. */
196 static int flexlines
;
198 /* During an update, nonzero if chars output now should be highlighted. */
200 static int highlight
;
202 /* Nominal cursor position -- where to draw output.
203 During an update, these are different from the cursor-box position. */
209 /* `t' if a mouse button is depressed. */
211 extern Lisp_Object Vmouse_depressed
;
213 /* Tells if a window manager is present or not. */
215 extern Lisp_Object Vx_no_window_manager
;
217 /* Timestamp that we requested selection data was made. */
218 extern Time requestor_time
;
220 /* ID of the window requesting selection data. */
221 extern Window requestor_window
;
223 /* Nonzero enables some debugging for the X interface code. */
226 #else /* X10 stuff */
228 /* Bit patterns for the mouse cursor. */
230 short MouseCursor
[] = {
231 0x0000, 0x0008, 0x0018, 0x0038,
232 0x0078, 0x00f8, 0x01f8, 0x03f8,
233 0x07f8, 0x00f8, 0x00d8, 0x0188,
234 0x0180, 0x0300, 0x0300, 0x0000};
236 short MouseMask
[] = {
237 0x000c, 0x001c, 0x003c, 0x007c,
238 0x00fc, 0x01fc, 0x03fc, 0x07fc,
239 0x0ffc, 0x0ffc, 0x01fc, 0x03dc,
240 0x03cc, 0x0780, 0x0780, 0x0300};
242 static short grey_bits
[] = {
243 0x0005, 0x000a, 0x0005, 0x000a};
245 static Pixmap GreyPixmap
= 0;
246 #endif /* X10 stuff */
248 /* From time to time we get info on an Emacs window, here. */
250 static WINDOWINFO_TYPE windowinfo
;
254 extern Lisp_Object Vglobal_minibuffer_screen
;
256 extern Display
*XOpenDisplay ();
257 extern Window
XCreateWindow ();
259 extern Cursor
XCreateCursor ();
260 extern FONT_TYPE
*XOpenFont ();
262 static void flashback ();
265 static void dumpqueue ();
269 static XTcursor_to ();
270 static XTclear_end_of_line ();
272 /* These hooks are called by update_screen at the beginning and end
273 of a screen update. We record in `updating_screen' the identity
274 of the screen being updated, so that the XT... functions do not
275 need to take a screen as argument. Most of the XT... functions
276 should never be called except during an update, the only exceptions
277 being XTcursor_to, XTwrite_char and XTreassert_line_highlight. */
279 extern int mouse_track_top
, mouse_track_left
, mouse_track_width
;
291 flexlines
= s
->height
;
298 x_display_cursor (s
, 0);
302 static void x_do_pending_expose ();
310 if (updating_screen
== 0
311 || updating_screen
!= s
)
318 adjust_scrollbars (s
);
319 x_do_pending_expose ();
321 x_display_cursor (s
, 1);
328 /* External interface to control of standout mode.
329 Call this when about to modify line at position VPOS
330 and not change whether it is highlighted. */
332 XTreassert_line_highlight (new, vpos
)
338 /* Call this when about to modify line at position VPOS
339 and change whether it is highlighted. */
342 XTchange_line_highlight (new_highlight
, vpos
, first_unused_hpos
)
343 int new_highlight
, vpos
, first_unused_hpos
;
345 highlight
= new_highlight
;
346 XTcursor_to (vpos
, 0);
347 XTclear_end_of_line (updating_screen
->width
);
350 /* This is used when starting Emacs and when restarting after suspend.
351 When starting Emacs, no X window is mapped. And nothing must be done
352 to Emacs's own window if it is suspended (though that rarely happens). */
355 XTset_terminal_modes ()
359 /* This is called when exiting or suspending Emacs.
360 Exiting will make the X-windows go away, and suspending
361 requires no action. */
364 XTreset_terminal_modes ()
366 /* XTclear_screen (); */
369 /* Set the nominal cursor position of the screen:
370 where display update commands will take effect.
371 This does not affect the place where the cursor-box is displayed. */
373 XTcursor_to (row
, col
)
374 register int row
, col
;
382 if (updating_screen
== 0)
385 x_display_cursor (selected_screen
, 1);
391 /* Display a sequence of N glyphs found at GP.
392 WINDOW is the x-window to output to. LEFT and TOP are starting coords.
393 HL is 1 if this text is highlighted, 2 if the cursor is on it.
395 FONT is the default font to use (for glyphs whose font-code is 0). */
398 dumpglyphs (s
, left
, top
, gp
, n
, hl
, font
)
401 register GLYPH
*gp
; /* Points to first GLYPH. */
402 register int n
; /* Number of glyphs to display. */
407 register char *cp
= buf
;
409 Window window
= s
->display
.x
->window_desc
;
410 GC drawing_gc
= (hl
== 2 ? s
->display
.x
->cursor_gc
411 : (hl
? s
->display
.x
->reverse_gc
412 : s
->display
.x
->normal_gc
));
414 if (sizeof (GLYPH
) == sizeof (XChar2b
))
415 XDrawImageString16 (x_current_display
, window
, drawing_gc
,
416 left
, top
+ FONT_BASE (font
), (XChar2b
*) gp
, n
);
417 else if (sizeof (GLYPH
) == sizeof (unsigned char))
418 XDrawImageString (x_current_display
, window
, drawing_gc
,
419 left
, top
+ FONT_BASE (font
), (char *) gp
, n
);
421 /* What size of glyph ARE you using? And does X have a function to
428 dumpglyphs (s
, left
, top
, gp
, n
, hl
, font
)
431 register GLYPH
*gp
; /* Points to first GLYPH. */
432 register int n
; /* Number of glyphs to display. */
436 char buf
[s
->width
]; /* Holds characters to be displayed. */
437 register char *cp
; /* Steps through buf[]. */
438 register int tlen
= GLYPH_TABLE_LENGTH
;
439 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
440 Window window
= s
->display
.x
->window_desc
;
441 int cursor_pixel
= s
->display
.x
->cursor_pixel
;
442 int fg_pixel
= s
->display
.x
->foreground_pixel
;
443 int bg_pixel
= s
->display
.x
->background_pixel
;
444 int intborder
= s
->display
.x
->internal_border_width
;
448 /* Get the face-code of the next GLYPH. */
452 while (GLYPH_ALIAS_P (tbase
, tlen
, g
))
453 g
= GLYPH_ALIAS (tbase
, g
);
457 /* Find the run of consecutive glyphs with the same face-code.
458 Extract their character codes into BUF. */
463 while (GLYPH_ALIAS_P (tbase
, tlen
, g
))
464 g
= GLYPH_ALIAS (tbase
, g
);
473 /* LEN gets the length of the run. */
476 /* Now output this run of chars, with the font and pixel values
477 determined by the face code CF. */
481 GC GC_cursor
= s
->display
.x
->cursor_gc
;
482 GC GC_reverse
= s
->display
.x
->reverse_gc
;
483 GC GC_normal
= s
->display
.x
->normal_gc
;
485 XDrawImageString (x_current_display
, window
,
488 : (hl
? GC_reverse
: GC_normal
)),
489 left
, top
+ FONT_BASE (font
), buf
, len
);
491 XText (window
, left
, top
,
496 ? (cursor_pixel
== fg_pixel
? bg_pixel
: fg_pixel
)
497 : hl
? bg_pixel
: fg_pixel
),
498 (hl
== 2 ? cursor_pixel
499 : hl
? fg_pixel
: bg_pixel
));
500 #endif /* HAVE_X11 */
505 if (FACE_IS_FONT (cf
))
506 XDrawImageString (x_current_display
, s
->display
.x
->window_desc
,
508 left
, top
+ FONT_BASE (FACE_FONT (cf
)),
510 else if (FACE_IS_IMAGE (cf
))
511 XCopyPlane (x_current_display
, FACE_IMAGE (cf
),
512 s
->display
.x
->window_desc
,
513 s
->display
.x
->normal_gc
,
515 FACE_IMAGE_WIDTH (cf
),
516 FACE_IMAGE_HEIGHT (cf
), left
, top
);
520 register struct face
*fp
= x_face_table
[cf
];
522 XText (window
, left
, top
,
527 ? (cursor_pixel
== fp
->fg
? fp
->bg
: fp
->fg
)
528 : hl
? fp
->bg
: fp
->fg
),
529 (hl
== 2 ? cursor_pixel
530 : hl
? fp
->fg
: fp
->bg
));
531 #endif /* HAVE_X11 */
533 left
+= len
* FONT_WIDTH (font
);
538 /* Output some text at the nominal screen cursor position,
539 advancing the cursor over the text.
540 Output LEN glyphs at START.
542 `highlight', set up by XTreassert_line_highlight or XTchange_line_highlight,
543 controls the pixel values used for foreground and background. */
546 XTwrite_glyphs (start
, len
)
547 register GLYPH
*start
;
550 register int temp_length
;
560 /* If not within an update,
561 output at the screen's visible cursor. */
562 curs_x
= s
->cursor_x
;
563 curs_y
= s
->cursor_y
;
566 /* Clear the cursor if it appears on this line. */
567 if (curs_y
== s
->cursor_y
)
568 x_display_cursor (s
, 0);
571 (curs_x
* FONT_WIDTH (s
->display
.x
->font
)
572 + s
->display
.x
->internal_border_width
),
573 (curs_y
* FONT_HEIGHT (s
->display
.x
->font
)
574 + s
->display
.x
->internal_border_width
),
575 start
, len
, highlight
, s
->display
.x
->font
);
577 if (updating_screen
== 0)
580 x_display_cursor (s
, 1);
589 /* Erase the current text line from the nominal cursor position (inclusive)
590 to column FIRST_UNUSED (exclusive). The idea is that everything
591 from FIRST_UNUSED onward is already erased. */
594 XTclear_end_of_line (first_unused
)
595 register int first_unused
;
597 struct screen
*s
= updating_screen
;
603 if (curs_y
< 0 || curs_y
>= s
->height
)
605 if (first_unused
<= 0)
608 if (first_unused
>= s
->width
)
609 first_unused
= s
->width
;
613 /* Clear the cursor if it appears on this line. */
614 if (curs_y
== s
->cursor_y
)
615 x_display_cursor (s
, 0);
618 XClearArea (x_current_display
, s
->display
.x
->window_desc
,
619 curs_x
* FONT_WIDTH (s
->display
.x
->font
)
620 + s
->display
.x
->internal_border_width
,
621 curs_y
* FONT_HEIGHT (s
->display
.x
->font
)
622 + s
->display
.x
->internal_border_width
,
623 FONT_WIDTH (s
->display
.x
->font
) * (first_unused
- curs_x
),
624 FONT_HEIGHT (s
->display
.x
->font
), False
);
627 XPixSet (s
->display
.x
->window_desc
,
628 curs_x
* FONT_WIDTH (s
->display
.x
->font
) + s
->display
.x
->internal_border_width
,
629 curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + s
->display
.x
->internal_border_width
,
630 FONT_WIDTH (s
->display
.x
->font
) * (first_unused
- curs_x
),
631 FONT_HEIGHT (s
->display
.x
->font
),
632 s
->display
.x
->background_pixel
);
633 #endif /* HAVE_X11 */
642 struct screen
*s
= updating_screen
;
647 s
->phys_cursor_x
= -1; /* Cursor not visible. */
648 curs_x
= 0; /* Nominal cursor position is top left. */
652 XClear (s
->display
.x
->window_desc
);
660 /* Paint horzontal bars down the screen for a visible bell.
661 Note that this may be way too slow on some machines. */
666 register struct screen_glyphs
*active_screen
= SCREEN_CURRENT_GLYPHS (s
);
670 if (updating_screen
!= 0)
676 for (i
= s
->height
* FONT_HEIGHT (s
->display
.x
->font
) - 10;
678 i
-= 100) /* Should be NO LOWER than 75 for speed reasons. */
679 XFillRectangle (x_current_display
, s
->display
.x
->window_desc
,
680 s
->display
.x
->cursor_gc
,
681 0, i
, s
->width
* FONT_WIDTH (s
->display
.x
->font
)
682 + 2 * s
->display
.x
->internal_border_width
, 25);
685 x
= (s
->width
* FONT_WIDTH (s
->display
.x
->font
)) / 4;
686 y
= (s
->height
* FONT_HEIGHT (s
->display
.x
->font
)) / 4;
687 XFillRectangle (x_current_display
, s
->display
.x
->window_desc
,
688 s
->display
.x
->cursor_gc
,
690 dumpglyphs (s
, (x
+ s
->display
.x
->internal_border_width
),
691 (y
+ s
->display
.x
->internal_border_width
),
692 &active_screen
->glyphs
[(s
->height
/ 4) + 1][(s
->width
/ 4)],
693 1, 0, s
->display
.x
->font
);
696 for (i
= s
->height
* FONT_HEIGHT (s
->display
.x
->font
) - 10;
699 XPixFill (s
->display
.x
->window_desc
, 0, i
,
700 s
->width
* FONT_WIDTH (s
->display
.x
->font
)
701 + 2 * s
->display
.x
->internal_border_width
, 10,
702 WHITE_PIX_DEFAULT
, ClipModeClipped
, GXinvert
, AllPlanes
);
709 /* Flip background and forground colors of the screen. */
716 unsigned long pix_temp
;
718 x_display_cursor (s
, 0);
719 XClearWindow (x_current_display
, s
->display
.x
->window_desc
);
720 temp
= s
->display
.x
->normal_gc
;
721 s
->display
.x
->normal_gc
= s
->display
.x
->reverse_gc
;
722 s
->display
.x
->reverse_gc
= temp
;
723 pix_temp
= s
->display
.x
->foreground_pixel
;
724 s
->display
.x
->foreground_pixel
= s
->display
.x
->background_pixel
;
725 s
->display
.x
->background_pixel
= pix_temp
;
727 XSetWindowBackground (x_current_display
, s
->display
.x
->window_desc
,
728 s
->display
.x
->background_pixel
);
729 if (s
->display
.x
->background_pixel
== s
->display
.x
->cursor_pixel
)
731 s
->display
.x
->cursor_pixel
= s
->display
.x
->foreground_pixel
;
732 XSetBackground (x_current_display
, s
->display
.x
->cursor_gc
,
733 s
->display
.x
->cursor_pixel
);
734 XSetForeground (x_current_display
, s
->display
.x
->cursor_gc
,
735 s
->display
.x
->background_pixel
);
741 /* Make audible bell. */
744 #define XRINGBELL XBell(x_current_display, 0)
746 #define XRINGBELL XFeep(0);
753 XTflash (selected_screen
);
756 x_invert_screen (selected_screen
);
757 x_invert_screen (selected_screen
);
768 /* Insert and delete character are not supposed to be used
769 because we are supposed to turn off the feature of using them. */
772 XTinsert_glyphs (start
, len
)
773 register char *start
;
786 /* Specify how many text lines, from the top of the window,
787 should be affected by insert-lines and delete-lines operations.
788 This, and those operations, are used only within an update
789 that is bounded by calls to XTupdate_begin and XTupdate_end. */
792 XTset_terminal_window (n
)
795 if (updating_screen
== 0)
798 if ((n
<= 0) || (n
> updating_screen
->height
))
799 flexlines
= updating_screen
->height
;
804 /* Perform an insert-lines operation, inserting N lines
805 at a vertical position curs_y. */
811 register int topregion
, bottomregion
;
812 register int length
, newtop
, mask
;
813 register struct screen
*s
= updating_screen
;
814 int intborder
= s
->display
.x
->internal_border_width
;
816 if (curs_y
>= flexlines
)
820 bottomregion
= flexlines
- (n
+ 1);
821 newtop
= topregion
+ n
;
822 length
= (bottomregion
- topregion
) + 1;
828 if ((length
> 0) && (newtop
<= flexlines
))
831 XCopyArea (x_current_display
, s
->display
.x
->window_desc
,
832 s
->display
.x
->window_desc
, s
->display
.x
->normal_gc
,
833 intborder
, topregion
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
834 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
835 length
* FONT_HEIGHT (s
->display
.x
->font
), intborder
,
836 newtop
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
);
838 XMoveArea (s
->display
.x
->window_desc
,
839 intborder
, topregion
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
840 intborder
, newtop
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
841 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
842 length
* FONT_HEIGHT (s
->display
.x
->font
));
843 /* Now we must process any ExposeRegion events that occur
844 if the area being copied from is obscured.
845 We can't let it wait because further i/d operations
846 may want to copy this area to another area. */
848 #endif /* HAVE_X11 */
851 newtop
= min (newtop
, (flexlines
- 1));
852 length
= newtop
- topregion
;
856 XClearArea (x_current_display
, s
->display
.x
->window_desc
, intborder
,
857 topregion
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
858 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
859 n
* FONT_HEIGHT (s
->display
.x
->font
), False
);
861 XPixSet (s
->display
.x
->window_desc
,
863 topregion
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
864 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
865 n
* FONT_HEIGHT (s
->display
.x
->font
),
866 s
->display
.x
->background_pixel
);
867 #endif /* HAVE_X11 */
871 /* Perform a delete-lines operation, deleting N lines
872 at a vertical position curs_y. */
879 register struct screen
*s
= updating_screen
;
880 int intborder
= s
->display
.x
->internal_border_width
;
882 if (curs_y
>= flexlines
)
889 if ((curs_y
+ n
) >= flexlines
)
891 if (flexlines
>= (curs_y
+ 1))
894 XClearArea (x_current_display
, s
->display
.x
->window_desc
, intborder
,
895 curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
896 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
897 (flexlines
- curs_y
) * FONT_HEIGHT (s
->display
.x
->font
), False
);
899 XPixSet (s
->display
.x
->window_desc
,
900 intborder
, curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
901 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
902 (flexlines
- curs_y
) * FONT_HEIGHT (s
->display
.x
->font
),
903 s
->display
.x
->background_pixel
);
904 #endif /* HAVE_X11 */
910 XCopyArea (x_current_display
, s
->display
.x
->window_desc
,
911 s
->display
.x
->window_desc
, s
->display
.x
->normal_gc
,
913 (curs_y
+ n
) * FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
914 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
915 (flexlines
- (curs_y
+ n
)) * FONT_HEIGHT (s
->display
.x
->font
),
916 intborder
, curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
);
917 XClearArea (x_current_display
, s
->display
.x
->window_desc
,
919 (flexlines
- n
) * FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
920 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
921 n
* FONT_HEIGHT (s
->display
.x
->font
), False
);
923 XMoveArea (s
->display
.x
->window_desc
,
925 (curs_y
+ n
) * FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
926 intborder
, curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
927 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
928 (flexlines
- (curs_y
+ n
)) * FONT_HEIGHT (s
->display
.x
->font
));
929 /* Now we must process any ExposeRegion events that occur
930 if the area being copied from is obscured.
931 We can't let it wait because further i/d operations
932 may want to copy this area to another area. */
934 XPixSet (s
->display
.x
->window_desc
, intborder
,
935 (flexlines
- n
) * FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
936 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
937 n
* FONT_HEIGHT (s
->display
.x
->font
), s
->display
.x
->background_pixel
);
938 #endif /* HAVE_X11 */
942 /* Perform an insert-lines or delete-lines operation,
943 inserting N lines or deleting -N lines at vertical position VPOS. */
945 XTins_del_lines (vpos
, n
)
948 if (updating_screen
== 0)
951 /* Clear the cursor. */
952 x_display_cursor (updating_screen
, 0);
954 XTcursor_to (vpos
, 0);
965 static void clear_cursor ();
967 /* Output into a rectangle of an X-window (for screen S)
968 the characters in s->phys_lines that overlap that rectangle.
969 TOP and LEFT are the position of the upper left corner of the rectangle.
970 ROWS and COLS are the size of the rectangle. */
973 dumprectangle (s
, left
, top
, cols
, rows
)
975 register int left
, top
, cols
, rows
;
977 register struct screen_glyphs
*active_screen
= SCREEN_CURRENT_GLYPHS (s
);
978 int cursor_cleared
= 0;
982 if (SCREEN_GARBAGED_P (s
))
985 top
-= s
->display
.x
->internal_border_width
;
986 left
-= s
->display
.x
->internal_border_width
;
988 /* Express rectangle as four edges, instead of position-and-size. */
992 #ifndef HAVE_X11 /* Window manger does this for X11. */
993 /* If the rectangle includes any of the internal border area,
994 redisplay the border emphasis. */
995 if (top
< 0 || left
< 0
996 || bottom
> s
->height
* FONT_HEIGHT (s
->display
.x
->font
)
997 || right
> s
->width
* FONT_WIDTH (s
->display
.x
->font
))
999 #endif /* HAVE_X11 */
1001 /* Convert rectangle edges in pixels to edges in chars.
1002 Round down for left and top, up for right and bottom. */
1003 top
/= FONT_HEIGHT (s
->display
.x
->font
);
1004 left
/= FONT_WIDTH (s
->display
.x
->font
);
1005 bottom
+= (FONT_HEIGHT (s
->display
.x
->font
) - 1);
1006 right
+= (FONT_WIDTH (s
->display
.x
->font
) - 1);
1007 bottom
/= FONT_HEIGHT (s
->display
.x
->font
);
1008 right
/= FONT_WIDTH (s
->display
.x
->font
);
1010 /* Clip the rectangle to what can be visible. */
1015 if (right
> s
->width
)
1017 if (bottom
> s
->height
)
1020 /* Get size in chars of the rectangle. */
1021 cols
= right
- left
;
1022 rows
= bottom
- top
;
1024 /* If rectangle has zero area, return. */
1025 if (rows
<= 0) return;
1026 if (cols
<= 0) return;
1028 /* Turn off the cursor if it is in the rectangle.
1029 We will turn it back on afterward. */
1030 if ((s
->phys_cursor_x
>= left
) && (s
->phys_cursor_x
< right
)
1031 && (s
->phys_cursor_y
>= top
) && (s
->phys_cursor_y
< bottom
))
1037 /* Display the text in the rectangle, one text line at a time. */
1039 for (y
= top
; y
< bottom
; y
++)
1041 GLYPH
*line
= &active_screen
->glyphs
[y
][left
];
1043 if (! active_screen
->enable
[y
] || left
> active_screen
->used
[y
])
1047 (left
* FONT_WIDTH (s
->display
.x
->font
)
1048 + s
->display
.x
->internal_border_width
),
1049 (y
* FONT_HEIGHT (s
->display
.x
->font
)
1050 + s
->display
.x
->internal_border_width
),
1051 line
, min (cols
, active_screen
->used
[y
] - left
),
1052 active_screen
->highlight
[y
], s
->display
.x
->font
);
1055 /* Turn the cursor on if we turned it off. */
1058 x_display_cursor (s
, 1);
1062 /* Process all queued ExposeRegion events. */
1068 XExposeRegionEvent r
;
1070 while (dequeue_event (&r
, &x_expose_queue
))
1072 struct screen
*s
= x_window_to_screen (r
.window
);
1073 if (s
->display
.x
->icon_desc
== r
.window
)
1076 dumprectangle (s
, r
.x
, r
.y
, r
.width
, r
.height
);
1082 /* Process all expose events that are pending.
1083 Redraws the cursor if necessary on any screen that
1084 is not in the process of being updated with update_screen. */
1087 x_do_pending_expose ()
1091 Lisp_Object tail
, screen
;
1093 if (expose_all_windows
)
1095 expose_all_windows
= 0;
1096 for (tail
= Vscreen_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1098 register int temp_width
, temp_height
;
1101 screen
= XCONS (tail
)->car
;
1102 if (XTYPE (screen
) != Lisp_Screen
)
1104 s
= XSCREEN (screen
);
1105 if (s
->output_method
!= output_x_window
)
1109 if (!s
->display
.x
->needs_exposure
)
1112 intborder
= s
->display
.x
->internal_border_width
;
1115 XGetWindowInfo (s
->display
.x
->window_desc
, &windowinfo
);
1116 temp_width
= ((windowinfo
.width
- 2 * intborder
1117 - s
->display
.x
->v_scrollbar_width
)
1118 / FONT_WIDTH (s
->display
.x
->font
));
1119 temp_height
= ((windowinfo
.height
- 2 * intborder
1120 - s
->display
.x
->h_scrollbar_height
)
1121 / FONT_HEIGHT (s
->display
.x
->font
));
1122 if (temp_width
!= s
->width
|| temp_height
!= s
->height
)
1124 change_screen_size (s
, max (1, temp_height
),
1125 max (1, temp_width
), 0);
1126 x_resize_scrollbars (s
);
1128 s
->display
.x
->left_pos
= windowinfo
.x
;
1129 s
->display
.x
->top_pos
= windowinfo
.y
;
1130 dumprectangle (s
, 0, 0, PIXEL_WIDTH (s
), PIXEL_HEIGHT (s
));
1134 s
->display
.x
->needs_exposure
= 0;
1135 if (updating_screen
!= s
)
1136 x_display_cursor (s
, 1);
1141 /* Handle any individual-rectangle expose events queued
1142 for various windows. */
1152 screen_highlight (screen
)
1153 struct screen
*screen
;
1155 if (! EQ (Vx_no_window_manager
, Qnil
))
1156 XSetWindowBorder (x_current_display
, screen
->display
.x
->window_desc
,
1157 screen
->display
.x
->border_pixel
);
1158 x_display_cursor (screen
, 1);
1162 screen_unhighlight (screen
)
1163 struct screen
*screen
;
1165 if (! EQ (Vx_no_window_manager
, Qnil
))
1166 XSetWindowBorderPixmap (x_current_display
, screen
->display
.x
->window_desc
,
1167 screen
->display
.x
->border_tile
);
1168 x_display_cursor (screen
, 1);
1171 /* Dump the border-emphasis of screen S.
1172 If S is selected, this is a lining of the same color as the border,
1173 just within the border, occupying a portion of the internal border.
1174 If S is not selected, it is background in the same place.
1175 If ALWAYS is 0, don't bother explicitly drawing if it's background.
1177 ALWAYS = 1 is used when a screen becomes selected or deselected.
1178 In that case, we also turn the cursor off and on again
1179 so it will appear in the proper shape (solid if selected; else hollow.) */
1182 dumpborder (s
, always
)
1186 int thickness
= s
->display
.x
->internal_border_width
/ 2;
1187 int width
= PIXEL_WIDTH (s
);
1188 int height
= PIXEL_HEIGHT (s
);
1191 if (s
!= selected_screen
)
1196 pixel
= s
->display
.x
->background_pixel
;
1200 pixel
= s
->display
.x
->border_pixel
;
1203 XPixSet (s
->display
.x
->window_desc
, 0, 0, width
, thickness
, pixel
);
1204 XPixSet (s
->display
.x
->window_desc
, 0, 0, thickness
, height
, pixel
);
1205 XPixSet (s
->display
.x
->window_desc
, 0, height
- thickness
, width
,
1207 XPixSet (s
->display
.x
->window_desc
, width
- thickness
, 0, thickness
,
1211 x_display_cursor (s
, 1);
1215 static void XTscreen_rehighlight ();
1217 /* The focus has changed. Update the screens as necessary to reflect
1218 the new situation. Note that we can't change the selected screen
1219 here, because the lisp code we are interrupting might become confused.
1220 Each event gets marked with the screen in which it occured, so the
1221 lisp code can tell when the switch took place by examining the events. */
1224 x_new_focus_screen (screen
)
1225 struct screen
*screen
;
1227 struct screen
*old_focus
= x_focus_screen
;
1228 int events_enqueued
= 0;
1230 if (screen
!= x_focus_screen
)
1232 /* Set this before calling other routines, so that they see
1233 the correct value of x_focus_screen. */
1234 x_focus_screen
= screen
;
1236 if (old_focus
&& old_focus
->auto_lower
)
1237 x_lower_screen (old_focus
);
1240 selected_screen
= screen
;
1241 XSET (XWINDOW (selected_screen
->selected_window
)->screen
,
1242 Lisp_Screen
, selected_screen
);
1243 Fselect_window (selected_screen
->selected_window
);
1244 choose_minibuf_screen ();
1247 if (x_focus_screen
&& x_focus_screen
->auto_raise
)
1248 x_raise_screen (x_focus_screen
);
1251 XTscreen_rehighlight ();
1255 /* The focus has changed, or we have make a screen's selected window
1256 point to a window on a different screen (this happens with global
1257 minibuffer screens). Shift the highlight as appropriate. */
1259 XTscreen_rehighlight ()
1261 struct screen
*old_highlight
= x_highlight_screen
;
1265 x_highlight_screen
= XSCREEN (SCREEN_FOCUS_SCREEN (x_focus_screen
));
1266 if (x_highlight_screen
->display
.nothing
== 0)
1267 XSET (SCREEN_FOCUS_SCREEN (x_focus_screen
), Lisp_Screen
,
1268 (x_highlight_screen
= x_focus_screen
));
1271 x_highlight_screen
= 0;
1273 if (x_highlight_screen
!= old_highlight
)
1276 screen_unhighlight (old_highlight
);
1277 if (x_highlight_screen
)
1278 screen_highlight (x_highlight_screen
);
1289 /* Symbol returned in input stream to indicate mouse movement. */
1290 Lisp_Object Qmouse_moved
;
1292 /* Position of the mouse in characters */
1293 unsigned int x_mouse_x
, x_mouse_y
;
1295 /* Emacs window the mouse is in, if any. */
1296 extern Lisp_Object Vmouse_window
;
1298 /* Offset in buffer of character under the pointer, or 0. */
1299 extern int mouse_buffer_offset
;
1301 /* Part of the screen the mouse is in. */
1302 extern Lisp_Object Vmouse_screen_part
;
1304 extern void pixel_to_glyph_translation ();
1305 extern int buffer_posn_from_coords ();
1307 /* Symbols from xfns.c to denote the different parts of a window. */
1308 extern Lisp_Object Qmodeline_part
, Qtext_part
;
1311 /* Set *RESULT to an emacs input_event corresponding to MOTION_EVENT.
1312 S is the screen in which the event occurred.
1314 WINDOW_TYPE says whether the event happened in a scrollbar window
1315 or a text window, affecting the format of the event created.
1317 PART specifies which part of the scrollbar the event happened in,
1318 if WINDOW_TYPE == scrollbar_window.
1320 If the mouse is over the same character as the last time we checked,
1321 don't return an event; set result->kind to no_event. */
1324 notice_mouse_movement (result
, motion_event
, s
, window_type
, part
)
1325 struct input_event
*result
;
1326 XMotionEvent motion_event
;
1331 int x
, y
, root_x
, root_y
, pix_x
, pix_y
;
1332 unsigned int keys_and_buttons
;
1333 Window w
, root_window
;
1335 /* Unless we decide otherwise below, return a non-event. */
1336 result
->kind
= no_event
;
1338 if (XQueryPointer (x_current_display
,
1339 s
->display
.x
->window_desc
,
1341 &root_x
, &root_y
, &pix_x
, &pix_y
,
1347 if (w
== None
) /* Mouse no longer in window. */
1351 pixel_to_glyph_translation (s
, pix_x
, pix_y
, &x
, &y
);
1352 if (x
== x_mouse_x
&& y
== x_mouse_y
)
1358 /* What sort of window are we in now? */
1359 if (window_type
== text_window
) /* Text part */
1363 Vmouse_window
= window_from_coordinates (s
, x
, y
, &modeline_p
);
1365 if (XTYPE (Vmouse_window
) == Lisp_Window
)
1367 = buffer_posn_from_coords (XWINDOW (Vmouse_window
), x
, y
);
1369 mouse_buffer_offset
= 0;
1371 if (EQ (Vmouse_window
, Qnil
))
1372 Vmouse_screen_part
= Qnil
;
1373 else if (modeline_p
)
1374 Vmouse_screen_part
= Qmodeline_part
;
1376 Vmouse_screen_part
= Qtext_part
;
1378 result
->kind
= window_sys_event
;
1379 result
->code
= Qmouse_moved
;
1383 else if (window_type
== scrollbar_window
) /* Scrollbar */
1385 Vmouse_window
= s
->selected_window
;
1386 mouse_buffer_offset
= 0;
1387 Vmouse_screen_part
= part
;
1389 result
->kind
= window_sys_event
;
1390 result
->code
= Qmouse_moved
;
1399 /* Given a pixel position (pix_x, pix_y) on the screen s, return
1400 character co-ordinates in (*x, *y). */
1402 pixel_to_glyph_translation (s
, pix_x
, pix_y
, x
, y
)
1404 register unsigned int pix_x
, pix_y
;
1405 register int *x
, *y
;
1407 register struct screen_glyphs
*s_glyphs
= SCREEN_CURRENT_GLYPHS (s
);
1408 register int line
= SCREEN_HEIGHT (s
) - 1;
1409 int ibw
= s
->display
.x
->internal_border_width
;
1411 /* What line is it on? */
1412 line
= SCREEN_HEIGHT (s
) - 1;
1413 while (s_glyphs
->top_left_y
[line
] > pix_y
)
1417 /* Horizontally, is it in the border? */
1421 /* If it's off the right edge, clip it. */
1422 else if (pix_x
> s
->display
.x
->pixel_width
- ibw
)
1423 *x
= SCREEN_WIDTH (s
) - 1;
1425 /* It's in the midst of the screen; assume all the characters are
1426 the same width, and figure the column. */
1428 *x
= (pix_x
- ibw
) / FONT_WIDTH (s
->display
.x
->font
);
1433 /* Any buttons grabbed. */
1434 unsigned int x_mouse_grabbed
;
1436 /* Convert a set of X modifier bits to the proper form for a
1437 struct input_event modifiers value. */
1440 x_convert_modifiers (state
)
1443 return ( ((state
& (ShiftMask
| LockMask
)) ? shift_modifier
: 0)
1444 | ((state
& ControlMask
) ? ctrl_modifier
: 0)
1445 | ((state
& Mod1Mask
) ? meta_modifier
: 0));
1448 extern struct screen
*x_window_to_scrollbar ();
1449 extern Lisp_Object Vmouse_event
;
1451 /* Prepare a mouse-event in *RESULT for placement in the input queue.
1453 If the event is a button press, then note that we have grabbed
1456 If PART and PREFIX are 0, then the event occurred in the text part;
1457 otherwise it happened in a scrollbar. */
1460 construct_mouse_click (result
, event
, s
, part
, prefix
)
1461 struct input_event
*result
;
1462 XButtonEvent
*event
;
1467 /* Initialize those fields text and scrollbar clicks hold in common.
1468 Make the event type no_event; we'll change that when we decide
1470 result
->kind
= no_event
;
1471 XSET (result
->code
, Lisp_Int
, event
->button
);
1472 result
->modifiers
= (x_convert_modifiers (event
->state
)
1473 | (event
->type
== ButtonRelease
? up_modifier
: 0));
1474 XSET (result
->timestamp
, Lisp_Int
, (event
->time
& 0x7fffff));
1476 /* Notice if the mouse is still grabbed. */
1477 if (event
->type
== ButtonPress
)
1479 if (! x_mouse_grabbed
)
1480 Vmouse_depressed
= Qt
;
1481 x_mouse_grabbed
|= event
->button
;
1483 else if (event
->type
== ButtonRelease
)
1485 x_mouse_grabbed
&= ~(event
->button
);
1486 if (!x_mouse_grabbed
)
1487 Vmouse_depressed
= Qnil
;
1490 if (part
) /* Scrollbar event */
1494 pos
= event
->y
- (s
->display
.x
->v_scrollbar_width
- 2);
1495 XSET (x_mouse_x
, Lisp_Int
, pos
);
1496 len
= ((FONT_HEIGHT (s
->display
.x
->font
) * s
->height
)
1497 + s
->display
.x
->internal_border_width
1498 - (2 * (s
->display
.x
->v_scrollbar_width
- 2)));
1499 XSET (x_mouse_y
, Lisp_Int
, len
);
1501 result
->kind
= scrollbar_click
;
1502 result
->part
= part
;
1503 XSET (result
->x
, Lisp_Int
, (s
->display
.x
->top_pos
- event
->y
));
1504 XSET (result
->y
, Lisp_Int
, s
->display
.x
->pixel_height
);
1507 else /* Text Window Event */
1511 pixel_to_glyph_translation (s
,
1515 result
->kind
= mouse_click
;
1523 static char *events
[] =
1563 #define XEvent XKeyPressedEvent
1564 #endif /* HAVE_X11 */
1566 /* Symbols returned in the input stream to indicate various X events. */
1567 Lisp_Object Qmapped_screen
;
1568 Lisp_Object Qunmapped_screen
;
1569 Lisp_Object Qexited_scrollbar
;
1570 Lisp_Object Qexited_window
;
1571 Lisp_Object Qredraw_screen
;
1572 Lisp_Object Qmouse_click
;
1573 Lisp_Object Qscrollbar_click
;
1575 /* Timestamp of enter window event. This is only used by XTread_socket,
1576 but we have to put it out here, since static variables within functions
1577 sometimes don't work. */
1578 static Time enter_timestamp
;
1580 /* Read events coming from the X server.
1581 This routine is called by the SIGIO handler.
1582 We return as soon as there are no more events to be read.
1584 Events representing keys are stored in buffer BUFP,
1585 which can hold up to NUMCHARS characters.
1586 We return the number of characters stored into the buffer,
1587 thus pretending to be `read'.
1589 WAITP is nonzero if we should block until input arrives.
1590 EXPECTED is nonzero if the caller knows input is available. */
1593 XTread_socket (sd
, bufp
, numchars
, waitp
, expected
)
1595 register struct input_event
*bufp
;
1596 register int numchars
;
1603 int items_pending
; /* How many items are in the X queue. */
1610 if (x_input_blocked
)
1612 x_pending_input
= 1;
1616 x_pending_input
= 0;
1620 abort (); /* Don't think this happens. */
1623 /* If available, Xlib uses FIOSNBIO to make the socket
1624 non-blocking, and then looks for EWOULDBLOCK. If O_NDELAY is set,
1625 FIOSNBIO is ignored, and instead of signalling EWOULDBLOCK,
1626 a read returns 0, which Xlib interprets as equivalent to EPIPE. */
1627 fcntl (fileno (stdin
), F_SETFL
, 0);
1632 if (! (fcntl (fileno (stdin
), F_GETFL
, 0) & O_NDELAY
))
1634 extern int read_alarm_should_throw
;
1635 read_alarm_should_throw
= 1;
1636 XPeekEvent (XDISPLAY
&event
);
1637 read_alarm_should_throw
= 0;
1642 while (XStuffPending () != 0)
1644 XNextEvent (XDISPLAY
&event
);
1651 case SelectionClear
: /* Someone has grabbed ownership. */
1652 x_disown_selection (event
.xselectionclear
.window
,
1653 event
.xselectionclear
.selection
,
1654 event
.xselectionclear
.time
);
1657 case SelectionRequest
: /* Someone wants our selection. */
1658 x_answer_selection_request (event
);
1661 case PropertyNotify
:
1662 /* If we were to do this synchronously, there'd be no worry
1663 about re-selecting. */
1664 x_send_incremental (event
);
1668 s
= x_window_to_screen (event
.xexpose
.window
);
1671 if (s
->visible
== 0)
1675 SET_SCREEN_GARBAGED (s
);
1678 dumprectangle (x_window_to_screen (event
.xexpose
.window
),
1679 event
.xexpose
.x
, event
.xexpose
.y
,
1680 event
.xexpose
.width
, event
.xexpose
.height
);
1684 case GraphicsExpose
: /* This occurs when an XCopyArea's
1685 source area was obscured or not
1687 dumprectangle (x_window_to_screen (event
.xgraphicsexpose
.drawable
),
1688 event
.xgraphicsexpose
.x
, event
.xgraphicsexpose
.y
,
1689 event
.xgraphicsexpose
.width
,
1690 event
.xgraphicsexpose
.height
);
1693 case NoExpose
: /* This occurs when an XCopyArea's
1694 source area was completely
1697 #else /* not HAVE_X11 */
1699 if (event
.subwindow
!= 0)
1700 break; /* duplicate event */
1701 s
= x_window_to_screen (event
.window
);
1702 if (event
.window
== s
->display
.x
->icon_desc
)
1707 if (event
.window
== s
->display
.x
->window_desc
)
1709 /* Say must check all windows' needs_exposure flags. */
1710 expose_all_windows
= 1;
1711 s
->display
.x
->needs_exposure
= 1;
1717 if (event
.subwindow
!= 0)
1718 break; /* duplicate event */
1719 s
= x_window_to_screen (event
.window
);
1720 if (event
.window
== s
->display
.x
->icon_desc
)
1725 /* If window already needs full redraw, ignore this rectangle. */
1726 if (expose_all_windows
&& s
->display
.x
->needs_exposure
)
1728 /* Put the event on the queue of rectangles to redraw. */
1729 if (enqueue_event (&event
, &x_expose_queue
))
1730 /* If it is full, we can't record the rectangle,
1731 so redraw this entire window. */
1733 /* Say must check all windows' needs_exposure flags. */
1734 expose_all_windows
= 1;
1735 s
->display
.x
->needs_exposure
= 1;
1740 /* This should happen only when we are expecting it,
1741 in x_read_exposes. */
1743 #endif /* not HAVE_X11 */
1750 s
= x_window_to_screen (event
.xunmap
.window
);
1751 if (s
) /* S may no longer exist if
1752 the screen was deleted. */
1754 /* While a screen is unmapped, display generation is
1755 disabled; you don't want to spend time updating a
1756 display that won't ever be seen. */
1758 Vmouse_window
= Vmouse_screen_part
= Qnil
;
1759 x_mouse_x
= x_mouse_y
= -1;
1765 s
= x_window_to_screen (event
.xmap
.window
);
1771 /* wait_reading_process_input will notice this and update
1772 the screen's display structures. */
1773 SET_SCREEN_GARBAGED (s
);
1777 /* Turn off processing if we become fully obscured. */
1778 case VisibilityNotify
:
1783 s
= x_window_to_screen (event
.window
);
1784 if (event
.window
== s
->display
.x
->icon_desc
)
1786 if (event
.window
== s
->display
.x
->window_desc
)
1789 #endif /* HAVE_X11 */
1793 s
= x_window_to_screen (event
.xkey
.window
);
1797 XComposeStatus status
;
1798 char copy_buffer
[80];
1800 /* This will have to go some day... */
1801 nbytes
= XLookupString (&event
.xkey
,
1809 if (IsCursorKey (keysym
) /* >= 0xff50 < 0xff60 */
1810 || IsMiscFunctionKey (keysym
) /* >= 0xff60 < 0xff80 */
1811 || IsKeypadKey (keysym
) /* >= 0xff80 <= 0xffbd */
1812 || IsFunctionKey (keysym
)) /* >= 0xffbe <= 0xffe0 */
1814 bufp
->kind
= non_ascii_keystroke
;
1815 bufp
->code
= (unsigned) keysym
- 0xff50;
1816 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
1817 bufp
->modifiers
= x_convert_modifiers (event
.xkey
.state
);
1822 else if (numchars
> nbytes
)
1828 if (event
.xkey
.state
& Mod1Mask
)
1829 *copy_buffer
|= METABIT
;
1830 bufp
->kind
= ascii_keystroke
;
1831 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
1832 XSET (bufp
->code
, Lisp_Int
, *copy_buffer
);
1836 for (i
= nbytes
- 1; i
> 1; i
--)
1838 bufp
->kind
= ascii_keystroke
;
1839 XSET (bufp
->code
, Lisp_Int
, copy_buffer
[i
]);
1840 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
1853 register char *where_mapping
;
1855 s
= x_window_to_screen (event
.window
);
1856 /* Ignore keys typed on icon windows. */
1857 if (s
!= 0 && event
.window
== s
->display
.x
->icon_desc
)
1859 where_mapping
= XLookupMapping (&event
, &nbytes
);
1860 /* Nasty fix for arrow keys */
1861 if (!nbytes
&& IsCursorKey (event
.detail
& 0xff))
1863 switch (event
.detail
& 0xff)
1865 case KC_CURSOR_LEFT
:
1866 where_mapping
= "\002";
1868 case KC_CURSOR_RIGHT
:
1869 where_mapping
= "\006";
1872 where_mapping
= "\020";
1874 case KC_CURSOR_DOWN
:
1875 where_mapping
= "\016";
1880 if (numchars
- nbytes
> 0)
1884 for (i
= 0; i
< nbytes
; i
++)
1886 bufp
->kind
= ascii_keystroke
;
1887 XSET (bufp
->code
, Lisp_Int
, where_mapping
[i
]);
1888 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
1896 #endif /* HAVE_X11 */
1900 s
= x_window_to_screen (event
.xcrossing
.window
);
1902 if (event
.xcrossing
.detail
== NotifyInferior
) /* Left Scrollbar */
1904 else if (event
.xcrossing
.focus
) /* Entered Window */
1906 /* If we decide we want to generate an event to be seen
1907 by the rest of Emacs, we put it here. */
1908 struct input_event emacs_event
;
1909 emacs_event
.kind
= no_event
;
1911 /* Avoid nasty pop/raise loops. */
1912 if (s
&& (!(s
->auto_raise
)
1914 || (event
.xcrossing
.time
- enter_timestamp
) > 500))
1916 x_new_focus_screen (s
);
1917 enter_timestamp
= event
.xcrossing
.time
;
1920 else if ((s
= x_window_to_scrollbar (event
.xcrossing
.window
,
1922 /* Fake a motion event */
1923 notice_mouse_movement (&emacs_event
,
1924 event
.xmotion
, s
, scrollbar_window
,
1929 if (! EQ (Vx_send_mouse_movement_events
, Qnil
)
1931 && emacs_event
.kind
!= no_event
)
1933 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
1940 else if (s
== x_focus_screen
)
1941 x_new_focus_screen (0);
1943 else if (s
= x_window_to_screen (event
.xcrossing
.window
))
1950 s
= x_window_to_screen (event
.xfocus
.window
);
1952 x_new_focus_screen (s
);
1956 if (event
.xcrossing
.detail
!= NotifyInferior
1957 && event
.xcrossing
.subwindow
== None
1958 && event
.xcrossing
.mode
== NotifyNormal
)
1960 s
= x_window_to_screen (event
.xcrossing
.window
);
1961 if (event
.xcrossing
.focus
)
1962 x_new_focus_screen (s
);
1963 else if (s
== x_focus_screen
)
1964 x_new_focus_screen (0);
1969 s
= x_window_to_screen (event
.xfocus
.window
);
1970 if (s
&& s
== x_focus_screen
)
1971 x_new_focus_screen (0);
1974 #else /* not HAVE_X11 */
1977 if ((event
.detail
& 0xFF) == 1)
1978 break; /* Coming from our own subwindow */
1979 if (event
.subwindow
!= 0)
1980 break; /* Entering our own subwindow. */
1983 extern int waiting_for_input
;
1984 struct screen
*old_s
= x_input_screen
;
1986 s
= x_window_to_screen (event
.window
);
1989 if (waiting_for_input
&& x_focus_screen
== 0)
1990 x_new_focus_screen (s
);
1995 if ((event
.detail
& 0xFF) == 1)
1996 break; /* Entering our own subwindow */
1997 if (event
.subwindow
!= 0)
1998 break; /* Leaving our own subwindow. */
2001 if (x_focus_screen
== 0
2002 && x_input_screen
!= 0
2003 && x_input_screen
== x_window_to_screen (event
.window
)
2004 && event
.window
== x_input_screen
->display
.x
->window_desc
)
2009 screen_unhighlight (s
);
2012 #endif /* not HAVE_X11 */
2017 s
= x_window_to_screen (event
.xmotion
.window
);
2022 pixel_to_glyph_translation (s
,
2023 event
.xmotion
.x
, event
.xmotion
.y
,
2026 note_mouse_position (s
, column
, row
, event
.xmotion
.time
);
2029 else if ((s
= x_window_to_scrollbar (event
.xmotion
.window
,
2032 What should go here
?
2038 case ConfigureNotify
:
2041 s
= x_window_to_screen (event
.xconfigure
.window
);
2045 columns
= ((event
.xconfigure
.width
-
2046 (2 * s
->display
.x
->internal_border_width
)
2047 - s
->display
.x
->v_scrollbar_width
)
2048 / FONT_WIDTH (s
->display
.x
->font
));
2049 rows
= ((event
.xconfigure
.height
-
2050 (2 * s
->display
.x
->internal_border_width
)
2051 - s
->display
.x
->h_scrollbar_height
)
2052 / FONT_HEIGHT (s
->display
.x
->font
));
2054 if (columns
!= s
->width
|| rows
!= s
->height
)
2056 XEvent ignored_event
;
2058 change_screen_size (s
, rows
, columns
, 0);
2059 x_resize_scrollbars (s
);
2060 SET_SCREEN_GARBAGED (s
);
2062 dumprectangle (s
, 0, 0, PIXEL_WIDTH (s
), PIXEL_HEIGHT (s
));
2063 /* Throw away the exposures generated by this reconfigure. */
2064 while (XCheckWindowEvent (x_current_display
,
2065 event
.xconfigure
.window
,
2066 ExposureMask
, &ignored_event
)
2071 s
->display
.x
->left_pos
= event
.xconfigure
.x
;
2072 s
->display
.x
->top_pos
= event
.xconfigure
.y
;
2073 s
->display
.x
->pixel_width
= event
.xconfigure
.width
;
2074 s
->display
.x
->pixel_height
= event
.xconfigure
.height
;
2081 /* If we decide we want to generate an event to be seen
2082 by the rest of Emacs, we put it here. */
2083 struct input_event emacs_event
;
2084 emacs_event
.kind
= no_event
;
2086 s
= x_window_to_screen (event
.xbutton
.window
);
2088 if (!x_focus_screen
|| (s
== x_focus_screen
))
2089 construct_mouse_click (&emacs_event
,
2094 if ((s
= x_window_to_scrollbar (event
.xbutton
.window
,
2097 if (!x_focus_screen
|| (selected_screen
== x_focus_screen
))
2098 construct_mouse_click (&emacs_event
,
2099 &event
, s
, part
, prefix
);
2104 if (numchars
>= 1 && emacs_event
.kind
!= no_event
)
2106 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
2114 #else /* not HAVE_X11 */
2116 case ButtonReleased
:
2117 s
= x_window_to_screen (event
.window
);
2120 if (event
.window
== s
->display
.x
->icon_desc
)
2122 x_make_screen_visible (s
);
2124 if (warp_mouse_on_deiconify
)
2125 XWarpMouse (s
->display
.x
->window_desc
, 10, 10);
2128 if (event
.window
== s
->display
.x
->window_desc
)
2134 enqueue_event (&event
, &x_mouse_queue
);
2137 bufp
->kind
= ascii_keystroke
;
2138 bufp
->code
= (char) 'X' & 037; /* C-x */
2139 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
2142 bufp
->kind
= ascii_keystroke
;
2143 bufp
->code
= (char) 0; /* C-@ */
2144 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
2151 #endif /* not HAVE_X11 */
2155 case CirculateNotify
:
2157 case CirculateRequest
:
2160 #endif /* HAVE_X11 */
2163 if (event
.xmapping
.request
== MappingKeyboard
)
2164 /* Someone has changed the keyboard mapping - flush the
2166 XRefreshKeyboardMapping (&event
.xmapping
);
2176 if (expected
&& ! event_found
)
2178 /* AOJ 880406: if select returns true but XPending doesn't, it means that
2179 there is an EOF condition; in other words, that X has died.
2180 Act as if there had been a hangup. */
2182 int fd
= ConnectionNumber (x_current_display
);
2185 if (0 != select (fd
+ 1, &mask
, (long *) 0, (long *) 0,
2186 (struct timeval
*) 0)
2187 && !XStuffPending ())
2188 kill (getpid (), SIGHUP
);
2190 #endif /* HAVE_SELECT */
2193 if (updating_screen
== 0)
2194 x_do_pending_expose ();
2201 /* Read and process only Expose events
2202 until we get an ExposeCopy event; then return.
2203 This is used in insert/delete line.
2204 We assume input is already blocked. */
2210 XKeyPressedEvent event
;
2214 /* while there are more events*/
2215 XMaskEvent (ExposeWindow
| ExposeRegion
| ExposeCopy
, &event
);
2219 if (event
.subwindow
!= 0)
2220 break; /* duplicate event */
2221 s
= x_window_to_screen (event
.window
);
2222 if (event
.window
== s
->display
.x
->icon_desc
)
2227 if (event
.window
== s
->display
.x
->window_desc
)
2229 expose_all_windows
= 1;
2230 s
->display
.x
->needs_exposure
= 1;
2236 if (event
.subwindow
!= 0)
2237 break; /* duplicate event */
2238 s
= x_window_to_screen (event
.window
);
2239 if (event
.window
== s
->display
.x
->icon_desc
)
2244 /* If window already needs full redraw, ignore this rectangle. */
2245 if (expose_all_windows
&& s
->display
.x
->needs_exposure
)
2247 /* Put the event on the queue of rectangles to redraw. */
2248 if (enqueue_event (&event
, &x_expose_queue
))
2249 /* If it is full, we can't record the rectangle,
2250 so redraw this entire window. */
2252 /* Say must check all windows' needs_exposure flags. */
2253 expose_all_windows
= 1;
2254 s
->display
.x
->needs_exposure
= 1;
2263 #endif /* HAVE_X11 */
2266 XTmouse_tracking_enable (enable
)
2271 /* Go through the list of screens and turn on/off mouse tracking for
2273 for (tail
= Vscreen_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
2275 if (XTYPE (XCONS (tail
)->car
) != Lisp_Screen
)
2277 if (XSCREEN (XCONS (tail
)->car
)->output_method
== output_x_window
)
2278 XSelectInput (x_current_display
,
2279 XSCREEN (XCONS (tail
)->car
)->display
.x
->window_desc
,
2281 ? (STANDARD_EVENT_SET
2283 | ButtonReleaseMask
)
2284 : STANDARD_EVENT_SET
));
2297 /* Draw a hollow box cursor. Don't change the inside of the box. */
2303 int left
= s
->cursor_x
* FONT_WIDTH (s
->display
.x
->font
)
2304 + s
->display
.x
->internal_border_width
;
2305 int top
= s
->cursor_y
* FONT_HEIGHT (s
->display
.x
->font
)
2306 + s
->display
.x
->internal_border_width
;
2307 int width
= FONT_WIDTH (s
->display
.x
->font
);
2308 int height
= FONT_HEIGHT (s
->display
.x
->font
);
2311 /* Perhaps we should subtract 1 from width and height... */
2312 XDrawRectangle (x_current_display
, s
->display
.x
->window_desc
,
2313 s
->display
.x
->cursor_gc
,
2314 left
, top
, width
- 1, height
- 1);
2316 XPixSet (s
->display
.x
->window_desc
,
2317 left
, top
, width
, 1,
2318 s
->display
.x
->cursor_pixel
);
2320 XPixSet (s
->display
.x
->window_desc
,
2321 left
, top
, 1, height
,
2322 s
->display
.x
->cursor_pixel
);
2324 XPixSet (s
->display
.x
->window_desc
,
2325 left
+width
-1, top
, 1, height
,
2326 s
->display
.x
->cursor_pixel
);
2328 XPixSet (s
->display
.x
->window_desc
,
2329 left
, top
+height
-1, width
, 1,
2330 s
->display
.x
->cursor_pixel
);
2331 #endif /* HAVE_X11 */
2334 /* Clear the cursor of screen S to background color,
2335 and mark the cursor as not shown.
2336 This is used when the text where the cursor is
2337 is about to be rewritten. */
2346 || s
->phys_cursor_x
< 0)
2350 x_display_cursor (s
, 0);
2352 XClearArea (x_current_display
, s
->display
.x
->window_desc
,
2353 s
->phys_cursor_x
* FONT_WIDTH (s
->display
.x
->font
)
2354 + s
->display
.x
->internal_border_width
,
2355 s
->phys_cursor_y
* FONT_HEIGHT (s
->display
.x
->font
)
2356 + s
->display
.x
->internal_border_width
,
2357 FONT_WIDTH (s
->display
.x
->font
) + 1, FONT_HEIGHT (s
->display
.x
->font
) + 1, False
);
2360 XPixSet (s
->display
.x
->window_desc
,
2361 s
->phys_cursor_x
* FONT_WIDTH (s
->display
.x
->font
) + s
->display
.x
->internal_border_width
,
2362 s
->phys_cursor_y
* FONT_HEIGHT (s
->display
.x
->font
) + s
->display
.x
->internal_border_width
,
2363 FONT_WIDTH (s
->display
.x
->font
), FONT_HEIGHT (s
->display
.x
->font
),
2364 s
->display
.x
->background_pixel
);
2365 #endif /* HAVE_X11 */
2366 s
->phys_cursor_x
= -1;
2369 x_display_bar_cursor (s
, on
)
2373 register int phys_x
= s
->phys_cursor_x
;
2374 register int phys_y
= s
->phys_cursor_y
;
2379 if (! s
->visible
|| (! on
&& s
->phys_cursor_x
< 0))
2384 (!on
|| phys_x
!= s
->cursor_x
|| phys_y
!= s
->cursor_y
))
2386 x1
= phys_x
* FONT_WIDTH (s
->display
.x
->font
)
2387 + s
->display
.x
->internal_border_width
;
2388 y1
= phys_y
* FONT_HEIGHT (s
->display
.x
->font
)
2389 + s
->display
.x
->internal_border_width
- 1;
2390 y2
= y1
+ FONT_HEIGHT (s
->display
.x
->font
) + 1;
2392 XDrawLine (x_current_display
, s
->display
.x
->window_desc
,
2393 s
->display
.x
->reverse_gc
, x1
, y1
, x1
, y2
);
2395 s
->phys_cursor_x
= phys_x
= -1;
2398 if (on
&& s
== x_highlight_screen
)
2400 x1
= s
->cursor_x
* FONT_WIDTH (s
->display
.x
->font
)
2401 + s
->display
.x
->internal_border_width
;
2402 y1
= s
->cursor_y
* FONT_HEIGHT (s
->display
.x
->font
)
2403 + s
->display
.x
->internal_border_width
- 1;
2404 y2
= y1
+ FONT_HEIGHT (s
->display
.x
->font
) + 1;
2406 XDrawLine (x_current_display
, s
->display
.x
->window_desc
,
2407 s
->display
.x
->cursor_gc
, x1
, y1
, x1
, y2
);
2409 s
->phys_cursor_x
= s
->cursor_x
;
2410 s
->phys_cursor_y
= s
->cursor_y
;
2418 /* Redraw the glyph at ROW, COLUMN on screen S, in the style HIGHLIGHT.
2419 If there is no character there, erase the area. HIGHLIGHT is as
2420 defined for dumpglyphs. */
2423 x_draw_single_glyph (s
, row
, column
, highlight
)
2428 register struct screen_glyphs
*current_screen
= SCREEN_CURRENT_GLYPHS (s
);
2430 /* If there is supposed to be a character there, redraw it
2431 in that line's normal video. */
2432 if (current_screen
->enable
[row
]
2433 && column
< current_screen
->used
[row
])
2435 (column
* FONT_WIDTH (s
->display
.x
->font
)
2436 + s
->display
.x
->internal_border_width
),
2437 (row
* FONT_HEIGHT (s
->display
.x
->font
)
2438 + s
->display
.x
->internal_border_width
),
2439 ¤t_screen
->glyphs
[row
][column
],
2440 1, highlight
, s
->display
.x
->font
);
2444 static GLYPH a_space_glyph
= SPACEGLYPH
;
2446 (column
* FONT_WIDTH (s
->display
.x
->font
)
2447 + s
->display
.x
->internal_border_width
),
2448 (row
* FONT_HEIGHT (s
->display
.x
->font
)
2449 + s
->display
.x
->internal_border_width
),
2450 &a_space_glyph
, 1, highlight
, s
->display
.x
->font
);
2452 XPixSet (s
->display
.x
->window_desc
,
2453 (column
* FONT_WIDTH (s
->display
.x
->font
)
2454 + s
->display
.x
->internal_border_width
),
2455 (row
* FONT_HEIGHT (s
->display
.x
->font
)
2456 + s
->display
.x
->internal_border_width
),
2457 FONT_WIDTH (s
->display
.x
->font
),
2458 FONT_HEIGHT (s
->display
.x
->font
),
2460 ? s
->display
.x
->background_pixel
2462 ? s
->display
.x
->foreground_pixel
2463 : s
->display
.x
->cursor_pixel
)));
2464 #endif /* HAVE_X11 */
2468 /* Turn the displayed cursor of screen S on or off according to ON.
2469 If ON is nonzero, where to put the cursor is specified
2470 by S->cursor_x and S->cursor_y. */
2473 x_display_box_cursor (s
, on
)
2480 /* If cursor is off and we want it off, return quickly. */
2482 if (!on
&& s
->phys_cursor_x
< 0)
2485 /* If cursor is currently being shown and we don't want it to be
2486 or it is in the wrong place,
2487 or we want a hollow box and it's not so, (pout!)
2489 if (s
->phys_cursor_x
>= 0
2491 || s
->phys_cursor_x
!= s
->cursor_x
2492 || s
->phys_cursor_y
!= s
->cursor_y
2493 || (s
->display
.x
->text_cursor_kind
!= hollow_box_cursor
2494 && (s
!= x_highlight_screen
))))
2496 /* Erase the cursor by redrawing the character underneath it. */
2497 x_draw_single_glyph (s
, s
->phys_cursor_y
, s
->phys_cursor_x
,
2498 (SCREEN_CURRENT_GLYPHS (s
)
2499 ->highlight
[s
->phys_cursor_y
]));
2501 s
->phys_cursor_x
= -1;
2504 /* If we want to show a cursor,
2505 or we want a box cursor and it's not so,
2506 write it in the right place. */
2508 && (s
->phys_cursor_x
< 0
2509 || (s
->display
.x
->text_cursor_kind
!= filled_box_cursor
2510 && s
== x_highlight_screen
)))
2512 if (s
!= x_highlight_screen
)
2515 s
->display
.x
->text_cursor_kind
= hollow_box_cursor
;
2519 x_draw_single_glyph (s
, s
->cursor_y
, s
->cursor_x
, 2);
2520 s
->display
.x
->text_cursor_kind
= filled_box_cursor
;
2523 s
->phys_cursor_x
= s
->cursor_x
;
2524 s
->phys_cursor_y
= s
->cursor_y
;
2527 if (updating_screen
!= s
)
2531 extern Lisp_Object Vbar_cursor
;
2533 x_display_cursor (s
, on
)
2537 if (EQ (Vbar_cursor
, Qnil
))
2538 x_display_box_cursor (s
, on
);
2540 x_display_bar_cursor (s
, on
);
2545 /* Refresh bitmap kitchen sink icon for screen S
2546 when we get an expose event for it. */
2552 /* Normally, the window manager handles this function. */
2556 if (s
->display
.x
->icon_bitmap_flag
)
2557 XBitmapBitsPut (s
->display
.x
->icon_desc
, 0, 0, sink_width
, sink_height
,
2558 sink_bits
, BlackPixel
, WHITE_PIX_DEFAULT
,
2559 icon_bitmap
, GXcopy
, AllPlanes
);
2562 extern struct screen
*selected_screen
;
2563 struct Lisp_String
*str
;
2564 unsigned char *string
;
2567 = XSTRING (XBUFFER (XWINDOW (s
->selected_window
)->buffer
)->name
)->data
;
2569 if (s
->display
.x
->icon_label
!= string
)
2571 s
->display
.x
->icon_label
= string
;
2572 XChangeWindow (s
->display
.x
->icon_desc
,
2573 XQueryWidth (string
, icon_font_info
->id
) + 10,
2574 icon_font_info
->height
+ 10);
2577 XText (s
->display
.x
->icon_desc
, 5, 5, string
,
2578 str
->size
, icon_font_info
->id
,
2579 BLACK_PIX_DEFAULT
, WHITE_PIX_DEFAULT
);
2582 #endif /* HAVE_X11 */
2585 /* Make the x-window of screen S use the kitchen-sink icon
2586 that's a window generated by Emacs. */
2595 if (s
->display
.x
->window_desc
== 0)
2600 XFreePixmap (x_current_display
, icon_bitmap
);
2603 XCreateBitmapFromData (x_current_display
, s
->display
.x
->window_desc
,
2604 gnu_bits
, gnu_width
, gnu_height
);
2605 x_wm_set_icon_pixmap (s
, icon_bitmap
);
2606 s
->display
.x
->icon_bitmap_flag
= 1;
2608 if (s
->display
.x
->icon_desc
)
2610 XClearIconWindow (s
->display
.x
->window_desc
);
2611 XDestroyWindow (s
->display
.x
->icon_desc
);
2614 icon_window
= XCreateWindow (s
->display
.x
->parent_desc
,
2615 0, 0, sink_width
, sink_height
,
2616 2, WhitePixmap
, (Pixmap
) NULL
);
2618 if (icon_window
== 0)
2621 XSetIconWindow (s
->display
.x
->window_desc
, icon_window
);
2622 XSelectInput (icon_window
, ExposeWindow
| UnmapWindow
);
2624 s
->display
.x
->icon_desc
= icon_window
;
2625 s
->display
.x
->icon_bitmap_flag
= 1;
2627 if (icon_bitmap
== 0)
2629 = XStoreBitmap (sink_mask_width
, sink_mask_height
, sink_mask_bits
);
2630 #endif /* HAVE_X11 */
2636 /* Make the x-window of screen S use a rectangle with text. */
2639 x_text_icon (s
, icon_name
)
2647 char *X_DefaultValue
;
2650 #if 0 /* This doesn't seem to be used, but I can't quite believe it. */
2651 static Pixmap grey_pixmap
;
2655 #define WhitePixel 1
2659 #define BlackPixel 0
2661 #endif /* not HAVE_X11 */
2663 if (s
->display
.x
->window_desc
== 0)
2666 if (icon_font_info
== 0)
2668 = XGetFont (XGetDefault (XDISPLAY invocation_name
, "BodyFont"));
2672 s
->display
.x
->icon_label
= icon_name
;
2674 if (! s
->display
.x
->icon_label
)
2675 s
->display
.x
->icon_label
= " *emacs* ";
2677 XSetIconName (x_current_display
, s
->display
.x
->window_desc
,
2678 (char *) s
->display
.x
->icon_label
);
2680 s
->display
.x
->icon_bitmap_flag
= 0;
2682 if (s
->display
.x
->icon_desc
)
2684 XClearIconWindow (XDISPLAY s
->display
.x
->window_desc
);
2685 XDestroyWindow (XDISPLAY s
->display
.x
->icon_desc
);
2689 s
->display
.x
->icon_label
= (unsigned char *) icon_name
;
2691 if (! s
->display
.x
->icon_label
)
2692 s
->display
.x
->icon_label
= XSTRING (s
->name
)->data
;
2694 width
= XStringWidth (s
->display
.x
->icon_label
, icon_font_info
, 0, 0);
2695 icon_window
= XCreateWindow (s
->display
.x
->parent_desc
,
2696 s
->display
.x
->left_pos
,
2697 s
->display
.x
->top_pos
,
2698 width
+ 10, icon_font_info
->height
+ 10,
2699 2, BlackPixmap
, WhitePixmap
);
2701 if (icon_window
== 0)
2704 XSetIconWindow (s
->display
.x
->window_desc
, icon_window
);
2705 XSelectInput (icon_window
, ExposeWindow
| ExposeRegion
| UnmapWindow
| ButtonPressed
);
2707 s
->display
.x
->icon_desc
= icon_window
;
2708 s
->display
.x
->icon_bitmap_flag
= 0;
2709 s
->display
.x
->icon_label
= 0;
2710 #endif /* HAVE_X11 */
2715 static char *x_proto_requests
[] =
2718 "ChangeWindowAttributes",
2719 "GetWindowAttributes",
2721 "DestroySubwindows",
2738 "SetSelectionOwner",
2739 "GetSelectionOwner",
2746 "ChangeActivePointerGrab",
2766 "ListFontsWithInfo",
2775 "SetClipRectangles",
2786 "PolyFillRectangle",
2796 "CopyColormapAndFree",
2798 "UninstallColormap",
2799 "ListInstalledColormaps",
2810 "CreateGlyphCursor",
2816 "ChangeKeyboardMapping",
2817 "GetKeyboardMapping",
2818 "ChangeKeyboardControl",
2819 "GetKeyboardControl",
2821 "ChangePointerControl",
2822 "GetPointerControl",
2832 "SetPointerMapping",
2833 "GetPointerMapping",
2834 "SetModifierMapping",
2835 "GetModifierMapping",
2839 #define acceptable_x_error_p(type) ((type) == 94)
2841 x_handle_error_gracefully (event
)
2844 char error_ptr
[128];
2845 char *proto_ptr
= x_proto_requests
[event
->request_code
];
2848 XGetErrorText (x_current_display
, event
->error_code
, error_ptr
, 128);
2849 sprintf (str
, "X Protocol Error: %s on request: %s", error_ptr
, proto_ptr
);
2850 TOTALLY_UNBLOCK_INPUT
;
2855 extern int x_selection_alloc_error
;
2856 extern int x_converting_selection
;
2859 /* Handle X Errors. If the error is not traumatic,
2860 just call error (). Otherwise print a (hopefully) interesting
2863 The arg to Fkill_emacs is an exit status value
2864 and also prevents any questions. */
2866 x_error_handler (disp
, event
)
2871 #define XlibDisplayIOError (1L << 0)
2874 struct _XErrorEvent
*event
;
2877 /* Here we use the standard X handlers. */
2880 if (event
&& event
->type
== 0) /* 0 is the XError Event type. */
2884 if (event
->request_code
== BadAlloc
&& x_converting_selection
)
2885 x_selection_alloc_error
= 1;
2889 if (acceptable_x_error_p (event
->request_code
))
2890 x_handle_error_gracefully (event
);
2892 _XDefaultError (disp
, event
);
2896 disp
->flags
|= XlibDisplayIOError
;
2897 _XDefaultIOError (disp
);
2904 Fkill_emacs (make_number (70));
2907 /* Initialize communication with the X window server. */
2910 static unsigned int x_wire_count
;
2913 fprintf (stderr
, "Lib call: %d\n", ++x_wire_count
);
2918 /* Set the font of the x-window specified by screen S
2919 to the font named NEWNAME. This is safe to use
2920 even before S has an actual x-window. */
2924 /* A table of all the fonts we have already loaded. */
2925 static XFontStruct
**x_font_table
;
2927 /* The current capacity of x_font_table. */
2928 static int x_font_table_size
;
2930 /* The number of fonts actually stored in x_font_table.
2931 x_font_table[n] is used and valid iff 0 <= n < n_fonts.
2932 0 <= n_fonts <= x_font_table_size. */
2935 x_new_font (s
, fontname
)
2937 register char *fontname
;
2941 int n_matching_fonts
;
2942 XFontStruct
*font_info
;
2945 /* Get a list of all the fonts that match this name. Once we
2946 have a list of matching fonts, we compare them against the fonts
2947 we already have by comparing font ids. */
2948 font_names
= (char **) XListFontsWithInfo (x_current_display
, fontname
,
2949 1024, &n_matching_fonts
,
2951 /* If the server couldn't find any fonts whose named matched fontname,
2952 return an error code. */
2953 if (n_matching_fonts
== 0)
2956 /* See if we've already loaded this font. */
2961 for (i
= 0; i
< n_fonts
; i
++)
2962 for (j
= 0; j
< n_matching_fonts
; j
++)
2963 if (x_font_table
[i
]->fid
== font_info
[j
].fid
)
2971 /* If we have, just return it from the table. */
2974 s
->display
.x
->font
= x_font_table
[already_loaded
];
2977 /* Otherwise, load the font and add it to the table. */
2982 font
= (XFontStruct
*) XLoadQueryFont (x_current_display
, fontname
);
2986 /* Do we need to create the table? */
2987 if (x_font_table_size
== 0)
2989 x_font_table_size
= 16;
2991 = (XFontStruct
**) xmalloc (x_font_table_size
2992 * sizeof (x_font_table
[0]));
2994 /* Do we need to grow the table? */
2995 else if (n_fonts
>= x_font_table_size
)
2997 x_font_table_size
<<= 1;
2999 = (XFontStruct
**) xrealloc (x_font_table
,
3001 * sizeof (x_font_table
[0])));
3004 s
->display
.x
->font
= x_font_table
[n_fonts
++] = font
;
3007 /* Free the information from XListFontsWithInfo. The data
3008 we actually retain comes from XLoadQueryFont. */
3009 XFreeFontInfo (font_names
, font_info
, n_matching_fonts
);
3011 /* Now make the screen display the given font. */
3012 if (s
->display
.x
->window_desc
!= 0)
3014 XSetFont (x_current_display
, s
->display
.x
->normal_gc
,
3015 s
->display
.x
->font
->fid
);
3016 XSetFont (x_current_display
, s
->display
.x
->reverse_gc
,
3017 s
->display
.x
->font
->fid
);
3018 XSetFont (x_current_display
, s
->display
.x
->cursor_gc
,
3019 s
->display
.x
->font
->fid
);
3021 x_set_window_size (s
, s
->width
, s
->height
);
3027 x_new_font (s
, newname
)
3029 register char *newname
;
3034 temp
= XGetFont (newname
);
3035 if (temp
== (FONT_TYPE
*) 0)
3038 if (s
->display
.x
->font
)
3039 XLoseFont (s
->display
.x
->font
);
3041 s
->display
.x
->font
= temp
;
3043 if (s
->display
.x
->window_desc
!= 0)
3044 x_set_window_size (s
, s
->width
, s
->height
);
3050 x_calc_absolute_position (s
)
3054 if (s
->display
.x
->left_pos
< 0)
3055 s
->display
.x
->left_pos
3056 = XINT (x_screen_width
) - PIXEL_WIDTH (s
) + s
->display
.x
->left_pos
;
3058 if (s
->display
.x
->top_pos
< 0)
3059 s
->display
.x
->top_pos
3060 = XINT (x_screen_height
) - PIXEL_HEIGHT (s
) + s
->display
.x
->top_pos
;
3062 WINDOWINFO_TYPE parentinfo
;
3064 XGetWindowInfo (s
->display
.x
->window_desc
, &parentinfo
);
3066 if (s
->display
.x
->left_pos
< 0)
3067 s
->display
.x
->left_pos
= parentinfo
.width
+ (s
->display
.x
->left_pos
+ 1)
3068 - PIXEL_WIDTH (s
) - 2 * s
->display
.x
->internal_border_width
;
3070 if (s
->display
.x
->top_pos
< 0)
3071 s
->display
.x
->top_pos
= parentinfo
.height
+ (s
->display
.x
->top_pos
+ 1)
3072 - PIXEL_HEIGHT (s
) - 2 * s
->display
.x
->internal_border_width
;
3076 x_set_offset (s
, xoff
, yoff
)
3078 register int xoff
, yoff
;
3080 s
->display
.x
->top_pos
= yoff
;
3081 s
->display
.x
->left_pos
= xoff
;
3082 x_calc_absolute_position (s
);
3085 XMoveWindow (XDISPLAY s
->display
.x
->window_desc
,
3086 s
->display
.x
->left_pos
, s
->display
.x
->top_pos
);
3088 x_wm_set_size_hint (s
, 0);
3093 /* Call this to change the size of screen S's x-window. */
3095 x_set_window_size (s
, cols
, rows
)
3097 register int cols
, rows
;
3099 int pixelwidth
, pixelheight
;
3101 int ibw
= s
->display
.x
->internal_border_width
;
3105 /* ??? Who DOES worry about minimum reasonable sizes? */
3106 pixelwidth
= (cols
* FONT_WIDTH (s
->display
.x
->font
) + 2 * ibw
3107 + s
->display
.x
->v_scrollbar_width
);
3108 pixelheight
= (rows
* FONT_HEIGHT (s
->display
.x
->font
) + 2 * ibw
3109 + s
->display
.x
->h_scrollbar_height
);
3112 x_wm_set_size_hint (s
, 0);
3113 #endif /* HAVE_X11 */
3114 XChangeWindowSize (s
->display
.x
->window_desc
, pixelwidth
, pixelheight
);
3120 x_set_resize_hint (s
)
3124 XSetResizeHint (s
->display
.x
->window_desc
, 2 * s
->display
.x
->internal_border_width
,
3125 2 * s
->display
.x
->internal_border_width
,
3126 FONT_WIDTH (s
->display
.x
->font
), FONT_HEIGHT (s
->display
.x
->font
));
3128 #endif /* not HAVE_X11 */
3131 x_set_mouse_position (s
, x
, y
)
3140 pix_x
= (SCREEN_WIDTH (s
)
3141 * FONT_WIDTH (s
->display
.x
->font
)
3142 + 2 * s
->display
.x
->internal_border_width
3143 + s
->display
.x
->v_scrollbar_width
) / 2;
3145 pix_x
= x
* FONT_WIDTH (s
->display
.x
->font
) + 2; /* add 2 pixels to each
3146 dimension to move the
3151 pix_y
= (SCREEN_HEIGHT (s
)
3152 * FONT_HEIGHT (s
->display
.x
->font
)
3153 + 2 * s
->display
.x
->internal_border_width
3154 + s
->display
.x
->h_scrollbar_height
) / 2;
3156 pix_y
= y
* FONT_HEIGHT (s
->display
.x
->font
) + 2;
3162 XWarpMousePointer (s
->display
.x
->window_desc
, pix_x
, pix_y
);
3167 x_focus_on_screen (s
)
3172 /* I don't think that the ICCCM allows programs to do things like this
3173 without the interaction of the window manager. Whatever you end up
3174 doing with this code, do it to x_unfocus_screen too. */
3175 XSetInputFocus (x_current_display
, s
->display
.x
->window_desc
,
3176 RevertToPointerRoot
, CurrentTime
);
3180 x_unfocus_screen (s
)
3184 /* Look at the remarks in x_focus_on_screen. */
3185 if (x_focus_screen
== s
)
3186 XSetInputFocus (x_current_display
, PointerRoot
,
3187 RevertToPointerRoot
, CurrentTime
);
3193 /* Raise screen S. */
3201 XRaiseWindow (XDISPLAY s
->display
.x
->window_desc
);
3207 /* Lower screen S. */
3215 XLowerWindow (XDISPLAY s
->display
.x
->window_desc
);
3221 /* Change from withdrawn state to mapped state. */
3223 x_make_screen_visible (s
)
3231 XRaiseWindow (XDISPLAY s
->display
.x
->window_desc
);
3240 if (! EQ (Vx_no_window_manager
, Qt
))
3241 x_wm_set_window_state (s
, NormalState
);
3243 XMapWindow (XDISPLAY s
->display
.x
->window_desc
);
3244 if (s
->display
.x
->v_scrollbar
!= 0 || s
->display
.x
->h_scrollbar
!= 0)
3245 XMapSubwindows (x_current_display
, s
->display
.x
->window_desc
);
3248 XMapWindow (XDISPLAY s
->display
.x
->window_desc
);
3249 if (s
->display
.x
->icon_desc
!= 0)
3250 XUnmapWindow (s
->display
.x
->icon_desc
);
3252 /* Handled by the MapNotify event for X11 */
3256 /* NOTE: this may cause problems for the first screen. */
3258 #endif /* not HAVE_X11 */
3260 XRaiseWindow (XDISPLAY s
->display
.x
->window_desc
);
3265 /* Change from mapped state to withdrawn state. */
3267 x_make_screen_invisible (s
)
3278 if (! EQ (Vx_no_window_manager
, Qt
))
3282 unmap
.type
= UnmapNotify
;
3283 unmap
.window
= s
->display
.x
->window_desc
;
3284 unmap
.event
= DefaultRootWindow (x_current_display
);
3285 unmap
.from_configure
= False
;
3286 XSendEvent (x_current_display
, DefaultRootWindow (x_current_display
),
3287 False
, SubstructureRedirectMask
|SubstructureNotifyMask
,
3291 /* The new function below does the same as the above code, plus unmapping
3292 the window. Sending the event without actually unmapping can make
3293 the window manager start ignoring the window (i.e., no more title bar,
3294 icon manager stuff.) */
3297 /* New function available with R4 */
3298 if (! XWithdrawWindow (x_current_display
, s
->display
.x
->window_desc
,
3299 DefaultScreen (x_current_display
)))
3301 UNBLOCK_INPUT_RESIGNAL
;
3302 error ("Can't notify window manager of iconification.");
3306 XUnmapWindow (XDISPLAY s
->display
.x
->window_desc
);
3308 s
->visible
= 0; /* Handled by the UnMap event for X11 */
3309 if (s
->display
.x
->icon_desc
!= 0)
3310 XUnmapWindow (XDISPLAY s
->display
.x
->icon_desc
);
3311 #endif /* not HAVE_X11 */
3317 /* Window manager communication. Created in Fx_open_connection. */
3318 extern Atom Xatom_wm_change_state
;
3320 /* Change window state from mapped to iconified. */
3322 x_iconify_screen (s
)
3333 if (! EQ (Vx_no_window_manager
, Qt
))
3334 if (! XIconifyWindow (x_current_display
, s
->display
.x
->window_desc
,
3335 DefaultScreen (x_current_display
)))
3337 UNBLOCK_INPUT_RESIGNAL
;
3338 error ("Can't notify window manager of iconification.");
3345 XClientMessageEvent message
;
3347 message
.window
= s
->display
.x
->window_desc
;
3348 message
.type
= ClientMessage
;
3349 message
.message_type
= Xatom_wm_change_state
;
3350 message
.format
= 32;
3351 message
.data
.l
[0] = IconicState
;
3353 if (! XSendEvent (x_current_display
,
3354 DefaultRootWindow (x_current_display
),
3356 SubstructureRedirectMask
| SubstructureNotifyMask
,
3359 UNBLOCK_INPUT_RESIGNAL
;
3360 error ("Can't notify window manager of iconification.");
3365 XUnmapWindow (XDISPLAY s
->display
.x
->window_desc
);
3367 s
->visible
= 0; /* Handled in the UnMap event for X11. */
3368 if (s
->display
.x
->icon_desc
!= 0)
3370 XMapWindow (XDISPLAY s
->display
.x
->icon_desc
);
3379 /* Destroy the X window of screen S.
3380 DISPL is the former s->display (since s->display
3381 has already been nulled out). */
3383 x_destroy_window (s
, displ
)
3385 union display displ
;
3390 if (displ
.x
->icon_desc
!= 0)
3391 XDestroyWindow (XDISPLAY displ
.x
->icon_desc
);
3392 XDestroyWindow (XDISPLAY displ
.x
->window_desc
);
3397 if (s
== x_focus_screen
)
3399 if (s
== x_highlight_screen
)
3400 x_highlight_screen
= 0;
3405 /* Manage event queues.
3407 This code is only used by the X10 support.
3409 We cannot leave events in the X queue and get them when we are ready
3410 because X does not provide a subroutine to get only a certain kind
3411 of event but not block if there are no queued events of that kind.
3413 Therefore, we must examine events as they come in and copy events
3414 of certain kinds into our private queues.
3416 All ExposeRegion events are put in x_expose_queue.
3417 All ButtonPressed and ButtonReleased events are put in x_mouse_queue. */
3420 /* Write the event *P_XREP into the event queue *QUEUE.
3421 If the queue is full, do nothing, but return nonzero. */
3424 enqueue_event (p_xrep
, queue
)
3425 register XEvent
*p_xrep
;
3426 register struct event_queue
*queue
;
3428 int newindex
= queue
->windex
+ 1;
3429 if (newindex
== EVENT_BUFFER_SIZE
)
3431 if (newindex
== queue
->rindex
)
3433 queue
->xrep
[queue
->windex
] = *p_xrep
;
3434 queue
->windex
= newindex
;
3438 /* Fetch the next event from queue *QUEUE and store it in *P_XREP.
3439 If *QUEUE is empty, do nothing and return 0. */
3442 dequeue_event (p_xrep
, queue
)
3443 register XEvent
*p_xrep
;
3444 register struct event_queue
*queue
;
3446 if (queue
->windex
== queue
->rindex
)
3448 *p_xrep
= queue
->xrep
[queue
->rindex
++];
3449 if (queue
->rindex
== EVENT_BUFFER_SIZE
)
3454 /* Return the number of events buffered in *QUEUE. */
3457 queue_event_count (queue
)
3458 register struct event_queue
*queue
;
3460 int tem
= queue
->windex
- queue
->rindex
;
3463 return EVENT_BUFFER_SIZE
+ tem
;
3466 /* Return nonzero if mouse input is pending. */
3469 mouse_event_pending_p ()
3471 return queue_event_count (&x_mouse_queue
);
3477 x_wm_set_size_hint (s
, prompting
)
3481 XSizeHints size_hints
;
3482 Window window
= s
->display
.x
->window_desc
;
3484 size_hints
.flags
= PResizeInc
| PMinSize
| PMaxSize
;
3486 flexlines
= s
->height
;
3488 size_hints
.x
= s
->display
.x
->left_pos
;
3489 size_hints
.y
= s
->display
.x
->top_pos
;
3490 size_hints
.height
= PIXEL_HEIGHT (s
);
3491 size_hints
.width
= PIXEL_WIDTH (s
);
3492 size_hints
.width_inc
= FONT_WIDTH (s
->display
.x
->font
);
3493 size_hints
.height_inc
= FONT_HEIGHT (s
->display
.x
->font
);
3494 size_hints
.base_width
= (2 * s
->display
.x
->internal_border_width
)
3495 + s
->display
.x
->v_scrollbar_width
;
3496 size_hints
.base_height
= (2 * s
->display
.x
->internal_border_width
)
3497 + s
->display
.x
->h_scrollbar_height
;
3498 size_hints
.min_width
= size_hints
.base_width
+ size_hints
.width_inc
;
3499 size_hints
.min_height
= size_hints
.base_height
+ size_hints
.height_inc
;
3500 size_hints
.max_width
= x_screen_width
3501 - ((2 * s
->display
.x
->internal_border_width
)
3502 + s
->display
.x
->v_scrollbar_width
);
3503 size_hints
.max_height
= x_screen_height
3504 - ((2 * s
->display
.x
->internal_border_width
)
3505 + s
->display
.x
->h_scrollbar_height
);
3508 size_hints
.flags
|= prompting
;
3511 XSizeHints hints
; /* Sometimes I hate X Windows... */
3513 XGetNormalHints (x_current_display
, window
, &hints
);
3514 if (hints
.flags
& PSize
)
3515 size_hints
.flags
|= PSize
;
3516 if (hints
.flags
& PPosition
)
3517 size_hints
.flags
|= PPosition
;
3518 if (hints
.flags
& USPosition
)
3519 size_hints
.flags
|= USPosition
;
3520 if (hints
.flags
& USSize
)
3521 size_hints
.flags
|= USSize
;
3525 XSetNormalHints (x_current_display
, window
, &size_hints
);
3527 XSetWMNormalHints (x_current_display
, window
, &size_hints
);
3530 /* Used for IconicState or NormalState */
3531 x_wm_set_window_state (s
, state
)
3536 Window window
= s
->display
.x
->window_desc
;
3538 wm_hints
.flags
= StateHint
;
3539 wm_hints
.initial_state
= state
;
3540 XSetWMHints (x_current_display
, window
, &wm_hints
);
3543 x_wm_set_icon_pixmap (s
, icon_pixmap
)
3548 Window window
= s
->display
.x
->window_desc
;
3550 wm_hints
.flags
= IconPixmapHint
;
3551 wm_hints
.icon_pixmap
= icon_pixmap
;
3552 XSetWMHints (x_current_display
, window
, &wm_hints
);
3555 x_wm_set_icon_position (s
, icon_x
, icon_y
)
3560 Window window
= s
->display
.x
->window_desc
;
3562 wm_hints
.flags
= IconPositionHint
;
3563 wm_hints
.icon_x
= icon_x
;
3564 wm_hints
.icon_y
= icon_y
;
3565 XSetWMHints (x_current_display
, window
, &wm_hints
);
3570 init_input_symbols ()
3572 Qmapped_screen
= intern ("mapped-screen");
3573 Qunmapped_screen
= intern ("unmapped-screen");
3574 Qexited_scrollbar
= intern ("exited-scrollbar");
3575 Qexited_window
= intern ("exited-window");
3576 Qredraw_screen
= intern ("redraw-screen");
3577 Qmouse_moved
= intern ("mouse-moved");
3578 Qmouse_click
= intern ("mouse-click");
3579 Qscrollbar_click
= intern ("scrollbar-click");
3583 x_term_init (display_name
)
3589 extern int old_fcntl_owner
;
3592 x_focus_screen
= x_highlight_screen
= 0;
3594 x_current_display
= XOpenDisplay (display_name
);
3595 if (x_current_display
== 0)
3596 fatal ("X server %s not responding; check the DISPLAY environment variable or use \"-d\"\n",
3601 int hostname_size
= MAXHOSTNAMELEN
+ 1;
3603 hostname
= (char *) xmalloc (hostname_size
);
3606 XSetAfterFunction (x_current_display
, x_trace_wire
);
3609 invocation_name
= (char *)
3610 XSTRING (Ffile_name_nondirectory (Fcar (Vcommand_line_args
)))->data
;
3612 /* Try to get the host name; if the buffer is too short, try
3613 again. Apparently, the only indication gethostname gives of
3614 whether the buffer was large enough is the presence or absence
3615 of a '\0' in the string. Eech. */
3618 gethostname (hostname
, hostname_size
- 1);
3619 hostname
[hostname_size
- 1] = '\0';
3621 /* Was the buffer large enough for gethostname to store the '\0'? */
3622 if (strlen (hostname
) < hostname_size
- 1)
3625 hostname_size
<<= 1;
3626 hostname
= (char *) xrealloc (hostname
, hostname_size
);
3628 id_name
= (char *) xmalloc (strlen (invocation_name
)
3631 sprintf (id_name
, "%s@%s", invocation_name
, hostname
);
3634 dup2 (ConnectionNumber (x_current_display
), 0);
3636 #ifndef SYSV_STREAMS
3637 /* Streams somehow keeps track of which descriptor number
3638 is being used to talk to X. So it is not safe to substitute
3639 descriptor 0. But it is safe to make descriptor 0 a copy of it. */
3640 close (ConnectionNumber (x_current_display
));
3641 ConnectionNumber (x_current_display
) = 0; /* Looks a little strange?
3642 * check the def of the macro;
3643 * it is a genuine lvalue */
3644 #endif /* not SYSV_STREAMS */
3646 #endif /* HAVE_X11 */
3649 old_fcntl_owner
= fcntl (0, F_GETOWN
, 0);
3650 #ifdef F_SETOWN_SOCK_NEG
3651 fcntl (0, F_SETOWN
, -getpid ()); /* stdin is a socket here */
3653 fcntl (0, F_SETOWN
, getpid ());
3654 #endif /* F_SETOWN_SOCK_NEG */
3655 #endif /* F_SETOWN */
3661 /* Must use interrupt input because we cannot otherwise
3662 arrange for C-g to be noticed immediately.
3663 We cannot connect it to SIGINT. */
3664 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
3666 expose_all_windows
= 0;
3668 clear_screen_hook
= XTclear_screen
;
3669 clear_end_of_line_hook
= XTclear_end_of_line
;
3670 ins_del_lines_hook
= XTins_del_lines
;
3671 change_line_highlight_hook
= XTchange_line_highlight
;
3672 insert_glyphs_hook
= XTinsert_glyphs
;
3673 write_glyphs_hook
= XTwrite_glyphs
;
3674 delete_glyphs_hook
= XTdelete_glyphs
;
3675 ring_bell_hook
= XTring_bell
;
3676 reset_terminal_modes_hook
= XTreset_terminal_modes
;
3677 set_terminal_modes_hook
= XTset_terminal_modes
;
3678 update_begin_hook
= XTupdate_begin
;
3679 update_end_hook
= XTupdate_end
;
3680 set_terminal_window_hook
= XTset_terminal_window
;
3681 read_socket_hook
= XTread_socket
;
3682 cursor_to_hook
= XTcursor_to
;
3683 reassert_line_highlight_hook
= XTreassert_line_highlight
;
3684 screen_rehighlight_hook
= XTscreen_rehighlight
;
3685 mouse_tracking_enable_hook
= XTmouse_tracking_enable
;
3687 scroll_region_ok
= 1; /* we'll scroll partial screens */
3688 char_ins_del_ok
= 0; /* just as fast to write the line */
3689 line_ins_del_ok
= 1; /* we'll just blt 'em */
3690 fast_clear_end_of_line
= 1; /* X does this well */
3691 memory_below_screen
= 0; /* we don't remember what scrolls
3695 init_input_symbols ();
3697 XHandleError (x_error_handler
);
3698 XHandleIOError (x_error_handler
);
3700 /* Disable Window Change signals; they are handled by X events. */
3702 signal (SIGWINCH
, SIG_DFL
);
3703 #endif /* SIGWINCH */
3705 signal (SIGPIPE
, x_error_handler
);
3707 #endif /* HAVE_X11 */
3708 #endif /* HAVE_X_WINDOWS */