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.
34 /* On 4.3 this loses if it comes after xterm.h. */
37 /* This may include sys/types.h, and that somehow loses
38 if this is not done before the other system files. */
41 /* Load sys/types.h if not already loaded.
42 In some systems loading it twice is suicidal. */
44 #include <sys/types.h>
48 #include <sys/ioctl.h>
51 #include <sys/termio.h>
55 /* Allow m- file to inhibit use of FIONREAD. */
56 #ifdef BROKEN_FIONREAD
60 /* We are unable to use interrupts if FIONREAD is not available,
61 so flush SIGIO so we won't try. */
70 #else /* not NEED_TIME_H */
73 #endif /* HAVE_TIMEVAL */
74 #endif /* not NEED_TIME_H */
82 #include <sys/param.h>
84 #include "dispextern.h"
85 #include "termhooks.h"
98 #define XMapWindow XMapRaised /* Raise them when mapping. */
100 #include <X/Xkeyboard.h>
101 /*#include <X/Xproto.h> */
102 #endif /* HAVE_X11 */
104 /* For sending Meta-characters. Do we need this? */
107 #define min(a,b) ((a)<(b) ? (a) : (b))
108 #define max(a,b) ((a)>(b) ? (a) : (b))
110 /* Nonzero means we must reprint all windows
111 because 1) we received an ExposeWindow event
112 or 2) we received too many ExposeRegion events to record. */
114 static int expose_all_windows
;
116 /* Nonzero means we must reprint all icon windows. */
118 static int expose_all_icons
;
121 /* ExposeRegion events, when received, are copied into this queue
122 for later processing. */
124 static struct event_queue x_expose_queue
;
126 /* ButtonPressed and ButtonReleased events, when received,
127 are copied into this queue for later processing. */
129 struct event_queue x_mouse_queue
;
132 /* Nonzero after BLOCK_INPUT; prevents input events from being
133 processed until later. */
137 #if defined (SIGIO) && defined (FIONREAD)
138 int BLOCK_INPUT_mask
;
141 /* Nonzero if input events came in while x_input_blocked was nonzero.
142 UNBLOCK_INPUT checks for this. */
146 /* Nonzero if in redisplay (); prevents us from calling it recursively */
150 /* The id of a bitmap used for icon windows.
151 One such map is shared by all Emacs icon windows.
152 This is zero if we have not yet had a need to create the bitmap. */
154 static Bitmap icon_bitmap
;
156 /* Font used for text icons. */
158 static FONT_TYPE
*icon_font_info
;
160 /* Stuff for dealing with the main icon title. */
162 extern Lisp_Object Vcommand_line_args
;
163 char *hostname
, *x_id_name
;
164 Lisp_Object 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 Display
*XOpenDisplay ();
255 extern Window
XCreateWindow ();
257 extern Cursor
XCreateCursor ();
258 extern FONT_TYPE
*XOpenFont ();
260 static void flashback ();
263 static void dumpqueue ();
267 static XTcursor_to ();
268 static XTclear_end_of_line ();
270 /* These hooks are called by update_screen at the beginning and end
271 of a screen update. We record in `updating_screen' the identity
272 of the screen being updated, so that the XT... functions do not
273 need to take a screen as argument. Most of the XT... functions
274 should never be called except during an update, the only exceptions
275 being XTcursor_to, XTwrite_char and XTreassert_line_highlight. */
277 extern int mouse_track_top
, mouse_track_left
, mouse_track_width
;
289 flexlines
= s
->height
;
299 static void x_do_pending_expose ();
307 if (updating_screen
== 0
308 || updating_screen
!= s
)
315 adjust_scrollbars (s
);
316 x_do_pending_expose ();
318 x_display_cursor (s
, 1);
325 /* External interface to control of standout mode.
326 Call this when about to modify line at position VPOS
327 and not change whether it is highlighted. */
329 XTreassert_line_highlight (new, vpos
)
335 /* Call this when about to modify line at position VPOS
336 and change whether it is highlighted. */
339 XTchange_line_highlight (new_highlight
, vpos
, first_unused_hpos
)
340 int new_highlight
, vpos
, first_unused_hpos
;
342 highlight
= new_highlight
;
343 XTcursor_to (vpos
, 0);
344 XTclear_end_of_line (updating_screen
->width
);
347 /* This is used when starting Emacs and when restarting after suspend.
348 When starting Emacs, no X window is mapped. And nothing must be done
349 to Emacs's own window if it is suspended (though that rarely happens). */
352 XTset_terminal_modes ()
356 /* This is called when exiting or suspending Emacs.
357 Exiting will make the X-windows go away, and suspending
358 requires no action. */
361 XTreset_terminal_modes ()
363 /* XTclear_screen (); */
366 /* Set the nominal cursor position of the screen:
367 where display update commands will take effect.
368 This does not affect the place where the cursor-box is displayed. */
371 XTcursor_to (row
, col
)
372 register int row
, col
;
380 if (updating_screen
== 0)
383 x_display_cursor (selected_screen
, 1);
389 /* Display a sequence of N glyphs found at GP.
390 WINDOW is the x-window to output to. LEFT and TOP are starting coords.
391 HL is 1 if this text is highlighted, 2 if the cursor is on it.
393 FONT is the default font to use (for glyphs whose font-code is 0). */
396 dumpglyphs (s
, left
, top
, gp
, n
, hl
, font
)
399 register GLYPH
*gp
; /* Points to first GLYPH. */
400 register int n
; /* Number of glyphs to display. */
405 Window window
= s
->display
.x
->window_desc
;
406 GC drawing_gc
= (hl
== 2 ? s
->display
.x
->cursor_gc
407 : (hl
? s
->display
.x
->reverse_gc
408 : s
->display
.x
->normal_gc
));
410 if (sizeof (GLYPH
) == sizeof (XChar2b
))
411 XDrawImageString16 (x_current_display
, window
, drawing_gc
,
412 left
, top
+ FONT_BASE (font
), (XChar2b
*) gp
, n
);
413 else if (sizeof (GLYPH
) == sizeof (unsigned char))
414 XDrawImageString (x_current_display
, window
, drawing_gc
,
415 left
, top
+ FONT_BASE (font
), (char *) gp
, n
);
417 /* What size of glyph ARE you using? And does X have a function to
424 dumpglyphs (s
, left
, top
, gp
, n
, hl
, font
)
427 register GLYPH
*gp
; /* Points to first GLYPH. */
428 register int n
; /* Number of glyphs to display. */
432 char buf
[s
->width
]; /* Holds characters to be displayed. */
433 register char *cp
; /* Steps through buf[]. */
434 register int tlen
= GLYPH_TABLE_LENGTH
;
435 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
436 Window window
= s
->display
.x
->window_desc
;
437 int cursor_pixel
= s
->display
.x
->cursor_pixel
;
438 int fg_pixel
= s
->display
.x
->foreground_pixel
;
439 int bg_pixel
= s
->display
.x
->background_pixel
;
440 int intborder
= s
->display
.x
->internal_border_width
;
444 /* Get the face-code of the next GLYPH. */
448 while (GLYPH_ALIAS_P (tbase
, tlen
, g
))
449 g
= GLYPH_ALIAS (tbase
, g
);
453 /* Find the run of consecutive glyphs with the same face-code.
454 Extract their character codes into BUF. */
459 while (GLYPH_ALIAS_P (tbase
, tlen
, g
))
460 g
= GLYPH_ALIAS (tbase
, g
);
469 /* LEN gets the length of the run. */
472 /* Now output this run of chars, with the font and pixel values
473 determined by the face code CF. */
477 GC GC_cursor
= s
->display
.x
->cursor_gc
;
478 GC GC_reverse
= s
->display
.x
->reverse_gc
;
479 GC GC_normal
= s
->display
.x
->normal_gc
;
481 XDrawImageString (x_current_display
, window
,
484 : (hl
? GC_reverse
: GC_normal
)),
485 left
, top
+ FONT_BASE (font
), buf
, len
);
487 XText (window
, left
, top
,
492 ? (cursor_pixel
== fg_pixel
? bg_pixel
: fg_pixel
)
493 : hl
? bg_pixel
: fg_pixel
),
494 (hl
== 2 ? cursor_pixel
495 : hl
? fg_pixel
: bg_pixel
));
496 #endif /* HAVE_X11 */
501 if (FACE_IS_FONT (cf
))
502 XDrawImageString (x_current_display
, s
->display
.x
->window_desc
,
504 left
, top
+ FONT_BASE (FACE_FONT (cf
)),
506 else if (FACE_IS_IMAGE (cf
))
507 XCopyPlane (x_current_display
, FACE_IMAGE (cf
),
508 s
->display
.x
->window_desc
,
509 s
->display
.x
->normal_gc
,
511 FACE_IMAGE_WIDTH (cf
),
512 FACE_IMAGE_HEIGHT (cf
), left
, top
);
516 register struct face
*fp
= x_face_table
[cf
];
518 XText (window
, left
, top
,
523 ? (cursor_pixel
== fp
->fg
? fp
->bg
: fp
->fg
)
524 : hl
? fp
->bg
: fp
->fg
),
525 (hl
== 2 ? cursor_pixel
526 : hl
? fp
->fg
: fp
->bg
));
527 #endif /* HAVE_X11 */
529 left
+= len
* FONT_WIDTH (font
);
534 /* Output some text at the nominal screen cursor position,
535 advancing the cursor over the text.
536 Output LEN glyphs at START.
538 `highlight', set up by XTreassert_line_highlight or XTchange_line_highlight,
539 controls the pixel values used for foreground and background. */
542 XTwrite_glyphs (start
, len
)
543 register GLYPH
*start
;
546 register int temp_length
;
556 /* If not within an update,
557 output at the screen's visible cursor. */
558 curs_x
= s
->cursor_x
;
559 curs_y
= s
->cursor_y
;
563 (curs_x
* FONT_WIDTH (s
->display
.x
->font
)
564 + s
->display
.x
->internal_border_width
),
565 (curs_y
* FONT_HEIGHT (s
->display
.x
->font
)
566 + s
->display
.x
->internal_border_width
),
567 start
, len
, highlight
, s
->display
.x
->font
);
569 /* If we drew on top of the cursor, note that it is turned off. */
570 if (curs_y
== s
->phys_cursor_y
571 && curs_x
<= s
->phys_cursor_x
572 && curs_x
+ len
> s
->phys_cursor_x
)
573 s
->phys_cursor_x
= -1;
575 if (updating_screen
== 0)
578 x_display_cursor (s
, 1);
587 /* Erase the current text line from the nominal cursor position (inclusive)
588 to column FIRST_UNUSED (exclusive). The idea is that everything
589 from FIRST_UNUSED onward is already erased. */
592 XTclear_end_of_line (first_unused
)
593 register int first_unused
;
595 struct screen
*s
= updating_screen
;
601 if (curs_y
< 0 || curs_y
>= s
->height
)
603 if (first_unused
<= 0)
606 if (first_unused
>= s
->width
)
607 first_unused
= s
->width
;
611 /* Notice if the cursor will be cleared by this operation. */
612 if (curs_y
== s
->phys_cursor_y
613 && curs_x
<= s
->phys_cursor_x
614 && s
->phys_cursor_x
< first_unused
)
615 s
->phys_cursor_x
= -1;
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 /* Hide 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 (! SCREEN_IS_X (s
))
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 /* Position of the mouse in characters */
1290 unsigned int x_mouse_x
, x_mouse_y
;
1292 /* Offset in buffer of character under the pointer, or 0. */
1293 extern int mouse_buffer_offset
;
1295 extern int buffer_posn_from_coords ();
1297 /* Symbols from xfns.c to denote the different parts of a window. */
1298 extern Lisp_Object Qmodeline_part
, Qtext_part
;
1301 /* Set *RESULT to an emacs input_event corresponding to MOTION_EVENT.
1302 S is the screen in which the event occurred.
1304 WINDOW_TYPE says whether the event happened in a scrollbar window
1305 or a text window, affecting the format of the event created.
1307 PART specifies which part of the scrollbar the event happened in,
1308 if WINDOW_TYPE == scrollbar_window.
1310 If the mouse is over the same character as the last time we checked,
1311 don't return an event; set result->kind to no_event. */
1314 notice_mouse_movement (result
, motion_event
, s
, window_type
, part
)
1315 struct input_event
*result
;
1316 XMotionEvent motion_event
;
1321 int x
, y
, root_x
, root_y
, pix_x
, pix_y
;
1322 unsigned int keys_and_buttons
;
1323 Window w
, root_window
;
1325 /* Unless we decide otherwise below, return a non-event. */
1326 result
->kind
= no_event
;
1328 if (XQueryPointer (x_current_display
,
1329 s
->display
.x
->window_desc
,
1331 &root_x
, &root_y
, &pix_x
, &pix_y
,
1337 if (w
== None
) /* Mouse no longer in window. */
1341 pixel_to_glyph_translation (s
, pix_x
, pix_y
, &x
, &y
);
1342 if (x
== x_mouse_x
&& y
== x_mouse_y
)
1348 /* What sort of window are we in now? */
1349 if (window_type
== text_window
) /* Text part */
1353 Vmouse_window
= window_from_coordinates (s
, x
, y
, &modeline_p
);
1355 if (XTYPE (Vmouse_window
) == Lisp_Window
)
1357 = buffer_posn_from_coords (XWINDOW (Vmouse_window
), x
, y
);
1359 mouse_buffer_offset
= 0;
1361 if (EQ (Vmouse_window
, Qnil
))
1362 Vmouse_screen_part
= Qnil
;
1363 else if (modeline_p
)
1364 Vmouse_screen_part
= Qmodeline_part
;
1366 Vmouse_screen_part
= Qtext_part
;
1368 result
->kind
= window_sys_event
;
1369 result
->code
= Qmouse_moved
;
1373 else if (window_type
== scrollbar_window
) /* Scrollbar */
1375 Vmouse_window
= s
->selected_window
;
1376 mouse_buffer_offset
= 0;
1377 Vmouse_screen_part
= part
;
1379 result
->kind
= window_sys_event
;
1380 result
->code
= Qmouse_moved
;
1390 /* Mouse clicks and mouse movement. Rah. */
1393 /* Given a pixel position (PIX_X, PIX_Y) on the screen S, return
1394 glyph co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle
1395 that the glyph at X, Y occupies, if BOUNDS != 0. */
1397 pixel_to_glyph_coords (s
, pix_x
, pix_y
, x
, y
, bounds
)
1399 register unsigned int pix_x
, pix_y
;
1400 register int *x
, *y
;
1403 int ibw
= s
->display
.x
->internal_border_width
;
1405 FONT_TYPE
*font
= s
->display
.x
->font
;
1407 width
= FONT_WIDTH (font
);
1408 height
= FONT_HEIGHT (font
);
1410 /* What line is it on? */
1413 else if (pix_y
> s
->display
.x
->pixel_height
- ibw
)
1414 *y
= SCREEN_HEIGHT (s
) - 1;
1416 *y
= (pix_y
- ibw
) / height
;
1418 /* And what column? */
1421 else if (pix_x
> s
->display
.x
->pixel_width
- ibw
)
1422 *x
= SCREEN_WIDTH (s
) - 1;
1424 *x
= (pix_x
- ibw
) / width
;
1428 bounds
->width
= width
;
1429 bounds
->height
= height
;
1430 bounds
->x
= ibw
+ (*x
* width
);
1431 bounds
->y
= ibw
+ (*y
* height
);
1435 /* Any buttons grabbed. */
1436 unsigned int x_mouse_grabbed
;
1438 /* Convert a set of X modifier bits to the proper form for a
1439 struct input_event modifiers value. */
1442 x_convert_modifiers (state
)
1445 return ( ((state
& (ShiftMask
| LockMask
)) ? shift_modifier
: 0)
1446 | ((state
& ControlMask
) ? ctrl_modifier
: 0)
1447 | ((state
& Mod1Mask
) ? meta_modifier
: 0));
1450 extern struct screen
*x_window_to_scrollbar ();
1451 extern Lisp_Object Vmouse_event
;
1453 /* Prepare a mouse-event in *RESULT for placement in the input queue.
1455 If the event is a button press, then note that we have grabbed
1458 If PART and PREFIX are 0, then the event occurred in the text part;
1459 otherwise it happened in a scrollbar. */
1462 construct_mouse_click (result
, event
, s
, part
, prefix
)
1463 struct input_event
*result
;
1464 XButtonEvent
*event
;
1469 /* Initialize those fields text and scrollbar clicks hold in common.
1470 Make the event type no_event; we'll change that when we decide
1472 result
->kind
= no_event
;
1473 XSET (result
->code
, Lisp_Int
, event
->button
);
1474 XSET (result
->timestamp
, Lisp_Int
, event
->time
);
1475 result
->modifiers
= (x_convert_modifiers (event
->state
)
1476 | (event
->type
== ButtonRelease
? up_modifier
: 0));
1477 XSET (result
->timestamp
, Lisp_Int
, (event
->time
& 0x7fffff));
1479 /* Notice if the mouse is still grabbed. */
1480 if (event
->type
== ButtonPress
)
1482 if (! x_mouse_grabbed
)
1483 Vmouse_depressed
= Qt
;
1484 x_mouse_grabbed
|= (1 << event
->button
);
1486 else if (event
->type
== ButtonRelease
)
1488 x_mouse_grabbed
&= ~(1 << event
->button
);
1489 if (!x_mouse_grabbed
)
1490 Vmouse_depressed
= Qnil
;
1493 if (part
) /* Scrollbar event */
1497 pos
= event
->y
- (s
->display
.x
->v_scrollbar_width
- 2);
1498 XSET (x_mouse_x
, Lisp_Int
, pos
);
1499 len
= ((FONT_HEIGHT (s
->display
.x
->font
) * s
->height
)
1500 + s
->display
.x
->internal_border_width
1501 - (2 * (s
->display
.x
->v_scrollbar_width
- 2)));
1502 XSET (x_mouse_y
, Lisp_Int
, len
);
1504 result
->kind
= scrollbar_click
;
1505 result
->part
= part
;
1506 XSET (result
->x
, Lisp_Int
, (s
->display
.x
->top_pos
- event
->y
));
1507 XSET (result
->y
, Lisp_Int
, s
->display
.x
->pixel_height
);
1510 else /* Text Window Event */
1514 pixel_to_glyph_coords (s
, event
->x
, event
->y
, &column
, &row
, NULL
);
1515 result
->kind
= mouse_click
;
1523 /* Mouse movement. Rah.
1525 In order to avoid asking for motion events and then throwing most
1526 of them away or busy-polling the server for mouse positions, we ask
1527 the server for pointer motion hints. This means that we get only
1528 one event per group of mouse movements. "Groups" are delimited by
1529 other kinds of events (focus changes and button clicks, for
1530 example), or by XQueryPointer calls; when one of these happens, we
1531 get another MotionNotify event the next time the mouse moves. This
1532 is at least as efficient than getting motion events when mouse
1533 tracking is on, and I suspect only negligibly worse when tracking
1536 The silly O'Reilly & Associates Nutshell guides barely document
1537 pointer motion hints at all (I think you have to infer how they
1538 work from an example), and the description of XQueryPointer doesn't
1539 mention that calling it causes you to get another motion hint from
1540 the server, which is very important. */
1542 /* Where the mouse was last time we reported a mouse event. */
1543 static SCREEN_PTR last_mouse_screen
;
1544 static XRectangle last_mouse_glyph
;
1546 /* Function to report a mouse movement to the mainstream Emacs code.
1547 The input handler calls this.
1549 We have received a mouse movement event, which is given in *event.
1550 If the mouse is over a different glyph than it was last time, tell
1551 the mainstream emacs code by setting mouse_moved. If not, ask for
1552 another motion event, so we can check again the next time it moves. */
1554 note_mouse_position (screen
, event
)
1556 XMotionEvent
*event
;
1559 /* Has the mouse moved off the glyph it was on at the last sighting? */
1560 if (event
->x
< last_mouse_glyph
.x
1561 || event
->x
>= last_mouse_glyph
.x
+ last_mouse_glyph
.width
1562 || event
->y
< last_mouse_glyph
.y
1563 || event
->y
>= last_mouse_glyph
.y
+ last_mouse_glyph
.height
)
1567 /* It's on the same glyph. Call XQueryPointer so we'll get an
1568 event the next time the mouse moves and we can see if it's
1569 *still* on the same glyph. */
1572 XQueryPointer (event
->display
, event
->window
,
1573 (Window
*) &dummy
, (Window
*) &dummy
,
1574 &dummy
, &dummy
, &dummy
, &dummy
,
1575 (unsigned int *) &dummy
);
1579 /* Return the current position of the mouse.
1581 This clears the mouse_moved flag, so we can wait for the next mouse
1582 position. This also calls XQueryPointer, which will cause the
1583 server to give us another MotionNotify when the mouse moves again.
1587 XTmouse_position (s
, x
, y
, time
)
1593 Display
*d
= x_current_display
;
1594 Window guess
, root
, child
;
1598 /* I would like to have an X function that just told me the
1599 innermost window containing the mouse.
1601 /* There doesn't seem to be any way to just get the innermost window
1602 containing the pointer, no matter what X screen it's on; you have
1603 to guess a window, and then X will tell you which one of that
1604 window's children it's in. If the pointer isn't in any of that
1605 window's children, it gives you a root window that contains it.
1607 So we start with the selected screen's window and chase down
1608 branches under the guidance of XQueryPointer until we hit a leaf
1609 (all of the Emacs windows we care about are leaf windows). If at
1610 any time XQueryPointer returns false, that means that the current
1611 window does not contain the pointer any more (perhaps it moved),
1612 so we start with the root window XQueryPointer has given us and
1615 guess
= selected_screen
->display
.x
->window_desc
;
1617 if (XQueryPointer (d
, guess
, &root
, &child
,
1618 &dummy
, &dummy
, &ix
, &iy
, (unsigned int *) &dummy
))
1621 /* Guess is a leaf window, and it contains the pointer. */
1627 /* When XQueryPointer returns False, the pointer isn't in guess
1628 anymore, but root is the root window of the screen we should
1632 *s
= last_mouse_screen
= x_window_to_screen (guess
);
1637 pixel_to_glyph_coords (*s
, ix
, iy
, &ix
, &iy
, &last_mouse_glyph
);
1638 XSET (*x
, Lisp_Int
, ix
);
1639 XSET (*y
, Lisp_Int
, iy
);
1644 /* I don't know how to find the time for the last movement; it seems
1645 like XQueryPointer ought to return it, but it doesn't. */
1652 static char *events
[] =
1692 #define XEvent XKeyPressedEvent
1693 #endif /* HAVE_X11 */
1695 /* Timestamp of enter window event. This is only used by XTread_socket,
1696 but we have to put it out here, since static variables within functions
1697 sometimes don't work. */
1698 static Time enter_timestamp
;
1700 /* Read events coming from the X server.
1701 This routine is called by the SIGIO handler.
1702 We return as soon as there are no more events to be read.
1704 Events representing keys are stored in buffer BUFP,
1705 which can hold up to NUMCHARS characters.
1706 We return the number of characters stored into the buffer,
1707 thus pretending to be `read'.
1709 WAITP is nonzero if we should block until input arrives.
1710 EXPECTED is nonzero if the caller knows input is available. */
1713 XTread_socket (sd
, bufp
, numchars
, waitp
, expected
)
1715 register struct input_event
*bufp
;
1716 register int numchars
;
1723 int items_pending
; /* How many items are in the X queue. */
1730 if (x_input_blocked
)
1732 x_pending_input
= 1;
1736 x_pending_input
= 0;
1740 abort (); /* Don't think this happens. */
1743 /* If available, Xlib uses FIOSNBIO to make the socket
1744 non-blocking, and then looks for EWOULDBLOCK. If O_NDELAY is set,
1745 FIOSNBIO is ignored, and instead of signalling EWOULDBLOCK,
1746 a read returns 0, which Xlib interprets as equivalent to EPIPE. */
1747 fcntl (fileno (stdin
), F_SETFL
, 0);
1752 if (! (fcntl (fileno (stdin
), F_GETFL
, 0) & O_NDELAY
))
1754 extern int read_alarm_should_throw
;
1755 read_alarm_should_throw
= 1;
1756 XPeekEvent (XDISPLAY
&event
);
1757 read_alarm_should_throw
= 0;
1762 while (XStuffPending () != 0)
1764 XNextEvent (XDISPLAY
&event
);
1771 case SelectionClear
: /* Someone has grabbed ownership. */
1772 x_disown_selection (event
.xselectionclear
.window
,
1773 event
.xselectionclear
.selection
,
1774 event
.xselectionclear
.time
);
1777 case SelectionRequest
: /* Someone wants our selection. */
1778 x_answer_selection_request (event
);
1781 case PropertyNotify
:
1782 /* If we were to do this synchronously, there'd be no worry
1783 about re-selecting. */
1784 x_send_incremental (event
);
1788 s
= x_window_to_screen (event
.xexpose
.window
);
1791 if (s
->visible
== 0)
1795 SET_SCREEN_GARBAGED (s
);
1798 dumprectangle (x_window_to_screen (event
.xexpose
.window
),
1799 event
.xexpose
.x
, event
.xexpose
.y
,
1800 event
.xexpose
.width
, event
.xexpose
.height
);
1804 case GraphicsExpose
: /* This occurs when an XCopyArea's
1805 source area was obscured or not
1807 dumprectangle (x_window_to_screen (event
.xgraphicsexpose
.drawable
),
1808 event
.xgraphicsexpose
.x
, event
.xgraphicsexpose
.y
,
1809 event
.xgraphicsexpose
.width
,
1810 event
.xgraphicsexpose
.height
);
1813 case NoExpose
: /* This occurs when an XCopyArea's
1814 source area was completely
1817 #else /* not HAVE_X11 */
1819 if (event
.subwindow
!= 0)
1820 break; /* duplicate event */
1821 s
= x_window_to_screen (event
.window
);
1822 if (event
.window
== s
->display
.x
->icon_desc
)
1827 if (event
.window
== s
->display
.x
->window_desc
)
1829 /* Say must check all windows' needs_exposure flags. */
1830 expose_all_windows
= 1;
1831 s
->display
.x
->needs_exposure
= 1;
1837 if (event
.subwindow
!= 0)
1838 break; /* duplicate event */
1839 s
= x_window_to_screen (event
.window
);
1840 if (event
.window
== s
->display
.x
->icon_desc
)
1845 /* If window already needs full redraw, ignore this rectangle. */
1846 if (expose_all_windows
&& s
->display
.x
->needs_exposure
)
1848 /* Put the event on the queue of rectangles to redraw. */
1849 if (enqueue_event (&event
, &x_expose_queue
))
1850 /* If it is full, we can't record the rectangle,
1851 so redraw this entire window. */
1853 /* Say must check all windows' needs_exposure flags. */
1854 expose_all_windows
= 1;
1855 s
->display
.x
->needs_exposure
= 1;
1860 /* This should happen only when we are expecting it,
1861 in x_read_exposes. */
1863 #endif /* not HAVE_X11 */
1870 s
= x_window_to_screen (event
.xunmap
.window
);
1871 if (s
) /* S may no longer exist if
1872 the screen was deleted. */
1874 /* While a screen is unmapped, display generation is
1875 disabled; you don't want to spend time updating a
1876 display that won't ever be seen. */
1878 x_mouse_x
= x_mouse_y
= -1;
1884 s
= x_window_to_screen (event
.xmap
.window
);
1890 /* wait_reading_process_input will notice this and update
1891 the screen's display structures. */
1892 SET_SCREEN_GARBAGED (s
);
1896 /* Turn off processing if we become fully obscured. */
1897 case VisibilityNotify
:
1902 s
= x_window_to_screen (event
.window
);
1903 if (event
.window
== s
->display
.x
->icon_desc
)
1905 if (event
.window
== s
->display
.x
->window_desc
)
1908 #endif /* HAVE_X11 */
1912 s
= x_window_to_screen (event
.xkey
.window
);
1916 XComposeStatus status
;
1917 char copy_buffer
[80];
1919 /* This will have to go some day... */
1920 nbytes
= XLookupString (&event
.xkey
,
1926 /* Strip off the vendor-specific keysym bit, and take a shot
1927 at recognizing the codes. HP servers have extra keysyms
1928 that fit into the MiscFunctionKey category. */
1933 if (IsCursorKey (keysym
) /* 0xff50 <= x < 0xff60 */
1934 || IsMiscFunctionKey (keysym
) /* 0xff60 <= x < 0xff80 */
1935 || IsKeypadKey (keysym
) /* 0xff80 <= x < 0xffbe */
1936 || IsFunctionKey (keysym
)) /* 0xffbe <= x < 0xffe1 */
1938 bufp
->kind
= non_ascii_keystroke
;
1939 XSET (bufp
->code
, Lisp_Int
, (unsigned) keysym
- 0xff50);
1940 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
1941 bufp
->modifiers
= x_convert_modifiers (event
.xkey
.state
);
1942 XSET (bufp
->timestamp
, Lisp_Int
, event
.xkey
.time
);
1947 else if (numchars
> nbytes
)
1953 if (event
.xkey
.state
& Mod1Mask
)
1954 *copy_buffer
|= METABIT
;
1955 bufp
->kind
= ascii_keystroke
;
1956 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
1957 XSET (bufp
->code
, Lisp_Int
, *copy_buffer
);
1958 XSET (bufp
->timestamp
, Lisp_Int
, event
.xkey
.time
);
1962 for (i
= nbytes
- 1; i
> 1; i
--)
1964 bufp
->kind
= ascii_keystroke
;
1965 XSET (bufp
->code
, Lisp_Int
, copy_buffer
[i
]);
1966 XSET (bufp
->timestamp
, Lisp_Int
, event
.xkey
.time
);
1967 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
1980 register char *where_mapping
;
1982 s
= x_window_to_screen (event
.window
);
1983 /* Ignore keys typed on icon windows. */
1984 if (s
!= 0 && event
.window
== s
->display
.x
->icon_desc
)
1986 where_mapping
= XLookupMapping (&event
, &nbytes
);
1987 /* Nasty fix for arrow keys */
1988 if (!nbytes
&& IsCursorKey (event
.detail
& 0xff))
1990 switch (event
.detail
& 0xff)
1992 case KC_CURSOR_LEFT
:
1993 where_mapping
= "\002";
1995 case KC_CURSOR_RIGHT
:
1996 where_mapping
= "\006";
1999 where_mapping
= "\020";
2001 case KC_CURSOR_DOWN
:
2002 where_mapping
= "\016";
2007 if (numchars
- nbytes
> 0)
2011 for (i
= 0; i
< nbytes
; i
++)
2013 bufp
->kind
= ascii_keystroke
;
2014 XSET (bufp
->code
, Lisp_Int
, where_mapping
[i
]);
2015 XSET (bufp
->time
, Lisp_Int
, event
.xkey
.time
);
2016 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
2024 #endif /* HAVE_X11 */
2028 s
= x_window_to_screen (event
.xcrossing
.window
);
2030 if (event
.xcrossing
.detail
== NotifyInferior
) /* Left Scrollbar */
2032 else if (event
.xcrossing
.focus
) /* Entered Window */
2034 /* If we decide we want to generate an event to be seen
2035 by the rest of Emacs, we put it here. */
2036 struct input_event emacs_event
;
2037 emacs_event
.kind
= no_event
;
2039 /* Avoid nasty pop/raise loops. */
2040 if (s
&& (!(s
->auto_raise
)
2042 || (event
.xcrossing
.time
- enter_timestamp
) > 500))
2044 x_new_focus_screen (s
);
2045 enter_timestamp
= event
.xcrossing
.time
;
2048 else if ((s
= x_window_to_scrollbar (event
.xcrossing
.window
,
2050 /* Fake a motion event */
2051 notice_mouse_movement (&emacs_event
,
2052 event
.xmotion
, s
, scrollbar_window
,
2057 if (! EQ (Vx_send_mouse_movement_events
, Qnil
)
2059 && emacs_event
.kind
!= no_event
)
2061 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
2068 else if (s
== x_focus_screen
)
2069 x_new_focus_screen (0);
2071 else if (s
= x_window_to_screen (event
.xcrossing
.window
))
2078 s
= x_window_to_screen (event
.xfocus
.window
);
2080 x_new_focus_screen (s
);
2084 if (event
.xcrossing
.detail
!= NotifyInferior
2085 && event
.xcrossing
.subwindow
== None
2086 && event
.xcrossing
.mode
== NotifyNormal
)
2088 s
= x_window_to_screen (event
.xcrossing
.window
);
2089 if (event
.xcrossing
.focus
)
2090 x_new_focus_screen (s
);
2091 else if (s
== x_focus_screen
)
2092 x_new_focus_screen (0);
2097 s
= x_window_to_screen (event
.xfocus
.window
);
2098 if (s
&& s
== x_focus_screen
)
2099 x_new_focus_screen (0);
2102 #else /* not HAVE_X11 */
2105 if ((event
.detail
& 0xFF) == 1)
2106 break; /* Coming from our own subwindow */
2107 if (event
.subwindow
!= 0)
2108 break; /* Entering our own subwindow. */
2111 extern int waiting_for_input
;
2112 struct screen
*old_s
= x_input_screen
;
2114 s
= x_window_to_screen (event
.window
);
2117 if (waiting_for_input
&& x_focus_screen
== 0)
2118 x_new_focus_screen (s
);
2123 if ((event
.detail
& 0xFF) == 1)
2124 break; /* Entering our own subwindow */
2125 if (event
.subwindow
!= 0)
2126 break; /* Leaving our own subwindow. */
2129 if (x_focus_screen
== 0
2130 && x_input_screen
!= 0
2131 && x_input_screen
== x_window_to_screen (event
.window
)
2132 && event
.window
== x_input_screen
->display
.x
->window_desc
)
2137 screen_unhighlight (s
);
2140 #endif /* not HAVE_X11 */
2145 s
= x_window_to_screen (event
.xmotion
.window
);
2147 note_mouse_position (s
, &event
.xmotion
);
2149 else if ((s
= x_window_to_scrollbar (event
.xmotion
.window
,
2152 What should go here
?
2158 case ConfigureNotify
:
2161 s
= x_window_to_screen (event
.xconfigure
.window
);
2165 columns
= ((event
.xconfigure
.width
-
2166 (2 * s
->display
.x
->internal_border_width
)
2167 - s
->display
.x
->v_scrollbar_width
)
2168 / FONT_WIDTH (s
->display
.x
->font
));
2169 rows
= ((event
.xconfigure
.height
-
2170 (2 * s
->display
.x
->internal_border_width
)
2171 - s
->display
.x
->h_scrollbar_height
)
2172 / FONT_HEIGHT (s
->display
.x
->font
));
2174 /* Even if the number of character rows and columns has
2175 not changed, the font size may have changed, so we need
2176 to check the pixel dimensions as well. */
2177 if (columns
!= s
->width
2178 || rows
!= s
->height
2179 || event
.xconfigure
.width
!= s
->display
.x
->pixel_width
2180 || event
.xconfigure
.height
!= s
->display
.x
->pixel_height
)
2182 change_screen_size (s
, rows
, columns
, 0);
2183 x_resize_scrollbars (s
);
2184 SET_SCREEN_GARBAGED (s
);
2187 s
->display
.x
->pixel_width
= event
.xconfigure
.width
;
2188 s
->display
.x
->pixel_height
= event
.xconfigure
.height
;
2189 s
->display
.x
->left_pos
= event
.xconfigure
.x
;
2190 s
->display
.x
->top_pos
= event
.xconfigure
.y
;
2197 /* If we decide we want to generate an event to be seen
2198 by the rest of Emacs, we put it here. */
2199 struct input_event emacs_event
;
2200 emacs_event
.kind
= no_event
;
2202 s
= x_window_to_screen (event
.xbutton
.window
);
2204 if (!x_focus_screen
|| (s
== x_focus_screen
))
2205 construct_mouse_click (&emacs_event
,
2210 if ((s
= x_window_to_scrollbar (event
.xbutton
.window
,
2213 if (!x_focus_screen
|| (selected_screen
== x_focus_screen
))
2214 construct_mouse_click (&emacs_event
,
2215 &event
, s
, part
, prefix
);
2220 if (numchars
>= 1 && emacs_event
.kind
!= no_event
)
2222 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
2230 #else /* not HAVE_X11 */
2232 case ButtonReleased
:
2233 s
= x_window_to_screen (event
.window
);
2236 if (event
.window
== s
->display
.x
->icon_desc
)
2238 x_make_screen_visible (s
);
2240 if (warp_mouse_on_deiconify
)
2241 XWarpMouse (s
->display
.x
->window_desc
, 10, 10);
2244 if (event
.window
== s
->display
.x
->window_desc
)
2250 enqueue_event (&event
, &x_mouse_queue
);
2253 bufp
->kind
= ascii_keystroke
;
2254 bufp
->code
= (char) 'X' & 037; /* C-x */
2255 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
2256 XSET (bufp
->time
, Lisp_Int
, event
.xkey
.time
);
2259 bufp
->kind
= ascii_keystroke
;
2260 bufp
->code
= (char) 0; /* C-@ */
2261 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
2262 XSET (bufp
->time
, Lisp_Int
, event
.xkey
.time
);
2269 #endif /* not HAVE_X11 */
2273 case CirculateNotify
:
2275 case CirculateRequest
:
2278 #endif /* HAVE_X11 */
2281 if (event
.xmapping
.request
== MappingKeyboard
)
2282 /* Someone has changed the keyboard mapping - flush the
2284 XRefreshKeyboardMapping (&event
.xmapping
);
2294 if (expected
&& ! event_found
)
2296 /* AOJ 880406: if select returns true but XPending doesn't, it means that
2297 there is an EOF condition; in other words, that X has died.
2298 Act as if there had been a hangup. */
2300 int fd
= ConnectionNumber (x_current_display
);
2303 if (0 != select (fd
+ 1, &mask
, (long *) 0, (long *) 0,
2304 (struct timeval
*) 0)
2305 && !XStuffPending ())
2306 kill (getpid (), SIGHUP
);
2308 #endif /* HAVE_SELECT */
2311 if (updating_screen
== 0)
2312 x_do_pending_expose ();
2319 /* Read and process only Expose events
2320 until we get an ExposeCopy event; then return.
2321 This is used in insert/delete line.
2322 We assume input is already blocked. */
2328 XKeyPressedEvent event
;
2332 /* while there are more events*/
2333 XMaskEvent (ExposeWindow
| ExposeRegion
| ExposeCopy
, &event
);
2337 if (event
.subwindow
!= 0)
2338 break; /* duplicate event */
2339 s
= x_window_to_screen (event
.window
);
2340 if (event
.window
== s
->display
.x
->icon_desc
)
2345 if (event
.window
== s
->display
.x
->window_desc
)
2347 expose_all_windows
= 1;
2348 s
->display
.x
->needs_exposure
= 1;
2354 if (event
.subwindow
!= 0)
2355 break; /* duplicate event */
2356 s
= x_window_to_screen (event
.window
);
2357 if (event
.window
== s
->display
.x
->icon_desc
)
2362 /* If window already needs full redraw, ignore this rectangle. */
2363 if (expose_all_windows
&& s
->display
.x
->needs_exposure
)
2365 /* Put the event on the queue of rectangles to redraw. */
2366 if (enqueue_event (&event
, &x_expose_queue
))
2367 /* If it is full, we can't record the rectangle,
2368 so redraw this entire window. */
2370 /* Say must check all windows' needs_exposure flags. */
2371 expose_all_windows
= 1;
2372 s
->display
.x
->needs_exposure
= 1;
2381 #endif /* HAVE_X11 */
2384 /* Draw a hollow box cursor. Don't change the inside of the box. */
2390 int left
= s
->cursor_x
* FONT_WIDTH (s
->display
.x
->font
)
2391 + s
->display
.x
->internal_border_width
;
2392 int top
= s
->cursor_y
* FONT_HEIGHT (s
->display
.x
->font
)
2393 + s
->display
.x
->internal_border_width
;
2394 int width
= FONT_WIDTH (s
->display
.x
->font
);
2395 int height
= FONT_HEIGHT (s
->display
.x
->font
);
2398 /* Perhaps we should subtract 1 from width and height... */
2399 XDrawRectangle (x_current_display
, s
->display
.x
->window_desc
,
2400 s
->display
.x
->cursor_gc
,
2401 left
, top
, width
- 1, height
- 1);
2403 XPixSet (s
->display
.x
->window_desc
,
2404 left
, top
, width
, 1,
2405 s
->display
.x
->cursor_pixel
);
2407 XPixSet (s
->display
.x
->window_desc
,
2408 left
, top
, 1, height
,
2409 s
->display
.x
->cursor_pixel
);
2411 XPixSet (s
->display
.x
->window_desc
,
2412 left
+width
-1, top
, 1, height
,
2413 s
->display
.x
->cursor_pixel
);
2415 XPixSet (s
->display
.x
->window_desc
,
2416 left
, top
+height
-1, width
, 1,
2417 s
->display
.x
->cursor_pixel
);
2418 #endif /* HAVE_X11 */
2421 /* Clear the cursor of screen S to background color,
2422 and mark the cursor as not shown.
2423 This is used when the text where the cursor is
2424 is about to be rewritten. */
2433 || s
->phys_cursor_x
< 0)
2437 x_display_cursor (s
, 0);
2439 XClearArea (x_current_display
, s
->display
.x
->window_desc
,
2440 s
->phys_cursor_x
* FONT_WIDTH (s
->display
.x
->font
)
2441 + s
->display
.x
->internal_border_width
,
2442 s
->phys_cursor_y
* FONT_HEIGHT (s
->display
.x
->font
)
2443 + s
->display
.x
->internal_border_width
,
2444 FONT_WIDTH (s
->display
.x
->font
) + 1, FONT_HEIGHT (s
->display
.x
->font
) + 1, False
);
2447 XPixSet (s
->display
.x
->window_desc
,
2448 s
->phys_cursor_x
* FONT_WIDTH (s
->display
.x
->font
) + s
->display
.x
->internal_border_width
,
2449 s
->phys_cursor_y
* FONT_HEIGHT (s
->display
.x
->font
) + s
->display
.x
->internal_border_width
,
2450 FONT_WIDTH (s
->display
.x
->font
), FONT_HEIGHT (s
->display
.x
->font
),
2451 s
->display
.x
->background_pixel
);
2452 #endif /* HAVE_X11 */
2453 s
->phys_cursor_x
= -1;
2457 x_display_bar_cursor (s
, on
)
2461 register int phys_x
= s
->phys_cursor_x
;
2462 register int phys_y
= s
->phys_cursor_y
;
2467 if (! s
->visible
|| (! on
&& s
->phys_cursor_x
< 0))
2472 (!on
|| phys_x
!= s
->cursor_x
|| phys_y
!= s
->cursor_y
))
2474 x1
= phys_x
* FONT_WIDTH (s
->display
.x
->font
)
2475 + s
->display
.x
->internal_border_width
;
2476 y1
= phys_y
* FONT_HEIGHT (s
->display
.x
->font
)
2477 + s
->display
.x
->internal_border_width
- 1;
2478 y2
= y1
+ FONT_HEIGHT (s
->display
.x
->font
) + 1;
2480 XDrawLine (x_current_display
, s
->display
.x
->window_desc
,
2481 s
->display
.x
->reverse_gc
, x1
, y1
, x1
, y2
);
2483 s
->phys_cursor_x
= phys_x
= -1;
2486 if (on
&& s
== x_highlight_screen
)
2488 x1
= s
->cursor_x
* FONT_WIDTH (s
->display
.x
->font
)
2489 + s
->display
.x
->internal_border_width
;
2490 y1
= s
->cursor_y
* FONT_HEIGHT (s
->display
.x
->font
)
2491 + s
->display
.x
->internal_border_width
- 1;
2492 y2
= y1
+ FONT_HEIGHT (s
->display
.x
->font
) + 1;
2494 XDrawLine (x_current_display
, s
->display
.x
->window_desc
,
2495 s
->display
.x
->cursor_gc
, x1
, y1
, x1
, y2
);
2497 s
->phys_cursor_x
= s
->cursor_x
;
2498 s
->phys_cursor_y
= s
->cursor_y
;
2506 /* Redraw the glyph at ROW, COLUMN on screen S, in the style
2507 HIGHLIGHT. HIGHLIGHT is as defined for dumpglyphs. Return the
2511 x_draw_single_glyph (s
, row
, column
, glyph
, highlight
)
2518 (column
* FONT_WIDTH (s
->display
.x
->font
)
2519 + s
->display
.x
->internal_border_width
),
2520 (row
* FONT_HEIGHT (s
->display
.x
->font
)
2521 + s
->display
.x
->internal_border_width
),
2522 &glyph
, 1, highlight
, s
->display
.x
->font
);
2525 /* Turn the displayed cursor of screen S on or off according to ON.
2526 If ON is nonzero, where to put the cursor is specified
2527 by S->cursor_x and S->cursor_y. */
2530 x_display_box_cursor (s
, on
)
2534 struct screen_glyphs
*current_glyphs
= SCREEN_CURRENT_GLYPHS (s
);
2539 /* If cursor is off and we want it off, return quickly. */
2540 if (!on
&& s
->phys_cursor_x
< 0)
2543 /* If cursor is currently being shown and we don't want it to be
2544 or it is in the wrong place,
2545 or we want a hollow box and it's not so, (pout!)
2547 if (s
->phys_cursor_x
>= 0
2549 || s
->phys_cursor_x
!= s
->cursor_x
2550 || s
->phys_cursor_y
!= s
->cursor_y
2551 || (s
->display
.x
->text_cursor_kind
!= hollow_box_cursor
2552 && (s
!= x_highlight_screen
))))
2554 /* Erase the cursor by redrawing the character underneath it. */
2555 x_draw_single_glyph (s
, s
->phys_cursor_y
, s
->phys_cursor_x
,
2556 s
->phys_cursor_glyph
,
2557 current_glyphs
->highlight
[s
->phys_cursor_y
]);
2558 s
->phys_cursor_x
= -1;
2561 /* If we want to show a cursor,
2562 or we want a box cursor and it's not so,
2563 write it in the right place. */
2565 && (s
->phys_cursor_x
< 0
2566 || (s
->display
.x
->text_cursor_kind
!= filled_box_cursor
2567 && s
== x_highlight_screen
)))
2569 s
->phys_cursor_glyph
2570 = ((current_glyphs
->enable
[s
->cursor_y
]
2571 && s
->cursor_x
< current_glyphs
->used
[s
->cursor_y
])
2572 ? current_glyphs
->glyphs
[s
->cursor_y
][s
->cursor_x
]
2574 if (s
!= x_highlight_screen
)
2577 s
->display
.x
->text_cursor_kind
= hollow_box_cursor
;
2581 x_draw_single_glyph (s
, s
->cursor_y
, s
->cursor_x
,
2582 s
->phys_cursor_glyph
, 2);
2583 s
->display
.x
->text_cursor_kind
= filled_box_cursor
;
2586 s
->phys_cursor_x
= s
->cursor_x
;
2587 s
->phys_cursor_y
= s
->cursor_y
;
2590 if (updating_screen
!= s
)
2594 extern Lisp_Object Vbar_cursor
;
2596 x_display_cursor (s
, on
)
2600 if (EQ (Vbar_cursor
, Qnil
))
2601 x_display_box_cursor (s
, on
);
2603 x_display_bar_cursor (s
, on
);
2608 /* Refresh bitmap kitchen sink icon for screen S
2609 when we get an expose event for it. */
2615 /* Normally, the window manager handles this function. */
2619 if (s
->display
.x
->icon_bitmap_flag
)
2620 XBitmapBitsPut (s
->display
.x
->icon_desc
, 0, 0, sink_width
, sink_height
,
2621 sink_bits
, BlackPixel
, WHITE_PIX_DEFAULT
,
2622 icon_bitmap
, GXcopy
, AllPlanes
);
2625 extern struct screen
*selected_screen
;
2626 struct Lisp_String
*str
;
2627 unsigned char *string
;
2630 = XSTRING (XBUFFER (XWINDOW (s
->selected_window
)->buffer
)->name
)->data
;
2632 if (s
->display
.x
->icon_label
!= string
)
2634 s
->display
.x
->icon_label
= string
;
2635 XChangeWindow (s
->display
.x
->icon_desc
,
2636 XQueryWidth (string
, icon_font_info
->id
) + 10,
2637 icon_font_info
->height
+ 10);
2640 XText (s
->display
.x
->icon_desc
, 5, 5, string
,
2641 str
->size
, icon_font_info
->id
,
2642 BLACK_PIX_DEFAULT
, WHITE_PIX_DEFAULT
);
2645 #endif /* HAVE_X11 */
2648 /* Make the x-window of screen S use the kitchen-sink icon
2649 that's a window generated by Emacs. */
2658 if (s
->display
.x
->window_desc
== 0)
2663 XFreePixmap (x_current_display
, icon_bitmap
);
2666 XCreateBitmapFromData (x_current_display
, s
->display
.x
->window_desc
,
2667 gnu_bits
, gnu_width
, gnu_height
);
2668 x_wm_set_icon_pixmap (s
, icon_bitmap
);
2669 s
->display
.x
->icon_bitmap_flag
= 1;
2671 if (s
->display
.x
->icon_desc
)
2673 XClearIconWindow (s
->display
.x
->window_desc
);
2674 XDestroyWindow (s
->display
.x
->icon_desc
);
2677 icon_window
= XCreateWindow (s
->display
.x
->parent_desc
,
2678 0, 0, sink_width
, sink_height
,
2679 2, WhitePixmap
, (Pixmap
) NULL
);
2681 if (icon_window
== 0)
2684 XSetIconWindow (s
->display
.x
->window_desc
, icon_window
);
2685 XSelectInput (icon_window
, ExposeWindow
| UnmapWindow
);
2687 s
->display
.x
->icon_desc
= icon_window
;
2688 s
->display
.x
->icon_bitmap_flag
= 1;
2690 if (icon_bitmap
== 0)
2692 = XStoreBitmap (sink_mask_width
, sink_mask_height
, sink_mask_bits
);
2693 #endif /* HAVE_X11 */
2699 /* Make the x-window of screen S use a rectangle with text. */
2702 x_text_icon (s
, icon_name
)
2710 char *X_DefaultValue
;
2714 #define WhitePixel 1
2718 #define BlackPixel 0
2720 #endif /* not HAVE_X11 */
2722 if (s
->display
.x
->window_desc
== 0)
2725 if (icon_font_info
== 0)
2727 = XGetFont (XGetDefault (XDISPLAY
2728 (char *) XSTRING (invocation_name
)->data
,
2733 s
->display
.x
->icon_label
= icon_name
;
2735 if (! s
->display
.x
->icon_label
)
2736 s
->display
.x
->icon_label
= " *emacs* ";
2738 XSetIconName (x_current_display
, s
->display
.x
->window_desc
,
2739 (char *) s
->display
.x
->icon_label
);
2741 s
->display
.x
->icon_bitmap_flag
= 0;
2743 if (s
->display
.x
->icon_desc
)
2745 XClearIconWindow (XDISPLAY s
->display
.x
->window_desc
);
2746 XDestroyWindow (XDISPLAY s
->display
.x
->icon_desc
);
2750 s
->display
.x
->icon_label
= (unsigned char *) icon_name
;
2752 if (! s
->display
.x
->icon_label
)
2753 s
->display
.x
->icon_label
= XSTRING (s
->name
)->data
;
2755 width
= XStringWidth (s
->display
.x
->icon_label
, icon_font_info
, 0, 0);
2756 icon_window
= XCreateWindow (s
->display
.x
->parent_desc
,
2757 s
->display
.x
->left_pos
,
2758 s
->display
.x
->top_pos
,
2759 width
+ 10, icon_font_info
->height
+ 10,
2760 2, BlackPixmap
, WhitePixmap
);
2762 if (icon_window
== 0)
2765 XSetIconWindow (s
->display
.x
->window_desc
, icon_window
);
2766 XSelectInput (icon_window
, ExposeWindow
| ExposeRegion
| UnmapWindow
| ButtonPressed
);
2768 s
->display
.x
->icon_desc
= icon_window
;
2769 s
->display
.x
->icon_bitmap_flag
= 0;
2770 s
->display
.x
->icon_label
= 0;
2771 #endif /* HAVE_X11 */
2776 static char *x_proto_requests
[] =
2779 "ChangeWindowAttributes",
2780 "GetWindowAttributes",
2782 "DestroySubwindows",
2799 "SetSelectionOwner",
2800 "GetSelectionOwner",
2807 "ChangeActivePointerGrab",
2827 "ListFontsWithInfo",
2836 "SetClipRectangles",
2847 "PolyFillRectangle",
2857 "CopyColormapAndFree",
2859 "UninstallColormap",
2860 "ListInstalledColormaps",
2871 "CreateGlyphCursor",
2877 "ChangeKeyboardMapping",
2878 "GetKeyboardMapping",
2879 "ChangeKeyboardControl",
2880 "GetKeyboardControl",
2882 "ChangePointerControl",
2883 "GetPointerControl",
2893 "SetPointerMapping",
2894 "GetPointerMapping",
2895 "SetModifierMapping",
2896 "GetModifierMapping",
2900 #define acceptable_x_error_p(type) ((type) == 94)
2902 x_handle_error_gracefully (event
)
2905 char error_ptr
[128];
2906 char *proto_ptr
= x_proto_requests
[event
->request_code
];
2909 XGetErrorText (x_current_display
, event
->error_code
, error_ptr
, 128);
2910 sprintf (str
, "X Protocol Error: %s on request: %s", error_ptr
, proto_ptr
);
2911 TOTALLY_UNBLOCK_INPUT
;
2916 extern int x_selection_alloc_error
;
2917 extern int x_converting_selection
;
2920 /* Handle X Errors. If the error is not traumatic,
2921 just call error (). Otherwise print a (hopefully) interesting
2924 The arg to Fkill_emacs is an exit status value
2925 and also prevents any questions. */
2927 x_error_handler (disp
, event
)
2932 #define XlibDisplayIOError (1L << 0)
2935 struct _XErrorEvent
*event
;
2938 /* Here we use the standard X handlers. */
2941 if (event
&& event
->type
== 0) /* 0 is the XError Event type. */
2945 if (event
->request_code
== BadAlloc
&& x_converting_selection
)
2946 x_selection_alloc_error
= 1;
2950 if (acceptable_x_error_p (event
->request_code
))
2951 x_handle_error_gracefully (event
);
2953 _XDefaultError (disp
, event
);
2957 disp
->flags
|= XlibDisplayIOError
;
2958 _XDefaultIOError (disp
);
2965 Fkill_emacs (make_number (70));
2968 /* Initialize communication with the X window server. */
2971 static unsigned int x_wire_count
;
2974 fprintf (stderr
, "Lib call: %d\n", ++x_wire_count
);
2979 /* Set the font of the x-window specified by screen S
2980 to the font named NEWNAME. This is safe to use
2981 even before S has an actual x-window. */
2985 /* A table of all the fonts we have already loaded. */
2986 static XFontStruct
**x_font_table
;
2988 /* The current capacity of x_font_table. */
2989 static int x_font_table_size
;
2991 /* The number of fonts actually stored in x_font_table.
2992 x_font_table[n] is used and valid iff 0 <= n < n_fonts.
2993 0 <= n_fonts <= x_font_table_size. */
2996 x_new_font (s
, fontname
)
2998 register char *fontname
;
3002 int n_matching_fonts
;
3003 XFontStruct
*font_info
;
3006 /* Get a list of all the fonts that match this name. Once we
3007 have a list of matching fonts, we compare them against the fonts
3008 we already have by comparing font ids. */
3009 font_names
= (char **) XListFontsWithInfo (x_current_display
, fontname
,
3010 1024, &n_matching_fonts
,
3012 /* If the server couldn't find any fonts whose named matched fontname,
3013 return an error code. */
3014 if (n_matching_fonts
== 0)
3017 /* See if we've already loaded a matching font. */
3022 for (i
= 0; i
< n_fonts
; i
++)
3023 for (j
= 0; j
< n_matching_fonts
; j
++)
3024 if (x_font_table
[i
]->fid
== font_info
[j
].fid
)
3032 /* If we have, just return it from the table. */
3034 s
->display
.x
->font
= x_font_table
[already_loaded
];
3036 /* Otherwise, load the font and add it to the table. */
3041 font
= (XFontStruct
*) XLoadQueryFont (x_current_display
, fontname
);
3045 /* Do we need to create the table? */
3046 if (x_font_table_size
== 0)
3048 x_font_table_size
= 16;
3050 = (XFontStruct
**) xmalloc (x_font_table_size
3051 * sizeof (x_font_table
[0]));
3053 /* Do we need to grow the table? */
3054 else if (n_fonts
>= x_font_table_size
)
3056 x_font_table_size
*= 2;
3058 = (XFontStruct
**) xrealloc (x_font_table
,
3060 * sizeof (x_font_table
[0])));
3063 s
->display
.x
->font
= x_font_table
[n_fonts
++] = font
;
3066 /* Free the information from XListFontsWithInfo. The data
3067 we actually retain comes from XLoadQueryFont. */
3068 XFreeFontInfo (font_names
, font_info
, n_matching_fonts
);
3070 /* Now make the screen display the given font. */
3071 if (s
->display
.x
->window_desc
!= 0)
3073 XSetFont (x_current_display
, s
->display
.x
->normal_gc
,
3074 s
->display
.x
->font
->fid
);
3075 XSetFont (x_current_display
, s
->display
.x
->reverse_gc
,
3076 s
->display
.x
->font
->fid
);
3077 XSetFont (x_current_display
, s
->display
.x
->cursor_gc
,
3078 s
->display
.x
->font
->fid
);
3080 x_set_window_size (s
, s
->width
, s
->height
);
3086 x_new_font (s
, newname
)
3088 register char *newname
;
3093 temp
= XGetFont (newname
);
3094 if (temp
== (FONT_TYPE
*) 0)
3097 if (s
->display
.x
->font
)
3098 XLoseFont (s
->display
.x
->font
);
3100 s
->display
.x
->font
= temp
;
3102 if (s
->display
.x
->window_desc
!= 0)
3103 x_set_window_size (s
, s
->width
, s
->height
);
3109 x_calc_absolute_position (s
)
3113 if (s
->display
.x
->left_pos
< 0)
3114 s
->display
.x
->left_pos
3115 = XINT (x_screen_width
) - PIXEL_WIDTH (s
) + s
->display
.x
->left_pos
;
3117 if (s
->display
.x
->top_pos
< 0)
3118 s
->display
.x
->top_pos
3119 = XINT (x_screen_height
) - PIXEL_HEIGHT (s
) + s
->display
.x
->top_pos
;
3121 WINDOWINFO_TYPE parentinfo
;
3123 XGetWindowInfo (s
->display
.x
->window_desc
, &parentinfo
);
3125 if (s
->display
.x
->left_pos
< 0)
3126 s
->display
.x
->left_pos
= parentinfo
.width
+ (s
->display
.x
->left_pos
+ 1)
3127 - PIXEL_WIDTH (s
) - 2 * s
->display
.x
->internal_border_width
;
3129 if (s
->display
.x
->top_pos
< 0)
3130 s
->display
.x
->top_pos
= parentinfo
.height
+ (s
->display
.x
->top_pos
+ 1)
3131 - PIXEL_HEIGHT (s
) - 2 * s
->display
.x
->internal_border_width
;
3135 x_set_offset (s
, xoff
, yoff
)
3137 register int xoff
, yoff
;
3139 s
->display
.x
->top_pos
= yoff
;
3140 s
->display
.x
->left_pos
= xoff
;
3141 x_calc_absolute_position (s
);
3144 XMoveWindow (XDISPLAY s
->display
.x
->window_desc
,
3145 s
->display
.x
->left_pos
, s
->display
.x
->top_pos
);
3147 x_wm_set_size_hint (s
, 0);
3152 /* Call this to change the size of screen S's x-window. */
3154 x_set_window_size (s
, cols
, rows
)
3156 register int cols
, rows
;
3158 int pixelwidth
, pixelheight
;
3160 int ibw
= s
->display
.x
->internal_border_width
;
3164 /* ??? Who DOES worry about minimum reasonable sizes? */
3165 pixelwidth
= (cols
* FONT_WIDTH (s
->display
.x
->font
) + 2 * ibw
3166 + s
->display
.x
->v_scrollbar_width
);
3167 pixelheight
= (rows
* FONT_HEIGHT (s
->display
.x
->font
) + 2 * ibw
3168 + s
->display
.x
->h_scrollbar_height
);
3171 x_wm_set_size_hint (s
, 0);
3172 #endif /* HAVE_X11 */
3173 XChangeWindowSize (s
->display
.x
->window_desc
, pixelwidth
, pixelheight
);
3179 x_set_resize_hint (s
)
3183 XSetResizeHint (s
->display
.x
->window_desc
, 2 * s
->display
.x
->internal_border_width
,
3184 2 * s
->display
.x
->internal_border_width
,
3185 FONT_WIDTH (s
->display
.x
->font
), FONT_HEIGHT (s
->display
.x
->font
));
3187 #endif /* not HAVE_X11 */
3190 x_set_mouse_position (s
, x
, y
)
3199 pix_x
= (SCREEN_WIDTH (s
)
3200 * FONT_WIDTH (s
->display
.x
->font
)
3201 + 2 * s
->display
.x
->internal_border_width
3202 + s
->display
.x
->v_scrollbar_width
) / 2;
3204 pix_x
= x
* FONT_WIDTH (s
->display
.x
->font
) + 2; /* add 2 pixels to each
3205 dimension to move the
3210 pix_y
= (SCREEN_HEIGHT (s
)
3211 * FONT_HEIGHT (s
->display
.x
->font
)
3212 + 2 * s
->display
.x
->internal_border_width
3213 + s
->display
.x
->h_scrollbar_height
) / 2;
3215 pix_y
= y
* FONT_HEIGHT (s
->display
.x
->font
) + 2;
3221 XWarpMousePointer (s
->display
.x
->window_desc
, pix_x
, pix_y
);
3226 x_focus_on_screen (s
)
3231 /* I don't think that the ICCCM allows programs to do things like this
3232 without the interaction of the window manager. Whatever you end up
3233 doing with this code, do it to x_unfocus_screen too. */
3234 XSetInputFocus (x_current_display
, s
->display
.x
->window_desc
,
3235 RevertToPointerRoot
, CurrentTime
);
3239 x_unfocus_screen (s
)
3243 /* Look at the remarks in x_focus_on_screen. */
3244 if (x_focus_screen
== s
)
3245 XSetInputFocus (x_current_display
, PointerRoot
,
3246 RevertToPointerRoot
, CurrentTime
);
3252 /* Raise screen S. */
3260 XRaiseWindow (XDISPLAY s
->display
.x
->window_desc
);
3266 /* Lower screen S. */
3274 XLowerWindow (XDISPLAY s
->display
.x
->window_desc
);
3280 /* Change from withdrawn state to mapped state. */
3282 x_make_screen_visible (s
)
3289 if (! SCREEN_VISIBLE_P (s
))
3292 if (! EQ (Vx_no_window_manager
, Qt
))
3293 x_wm_set_window_state (s
, NormalState
);
3295 XMapWindow (XDISPLAY s
->display
.x
->window_desc
);
3296 if (s
->display
.x
->v_scrollbar
!= 0 || s
->display
.x
->h_scrollbar
!= 0)
3297 XMapSubwindows (x_current_display
, s
->display
.x
->window_desc
);
3299 XMapWindow (XDISPLAY s
->display
.x
->window_desc
);
3300 if (s
->display
.x
->icon_desc
!= 0)
3301 XUnmapWindow (s
->display
.x
->icon_desc
);
3303 /* Handled by the MapNotify event for X11 */
3307 /* NOTE: this may cause problems for the first screen. */
3309 #endif /* not HAVE_X11 */
3317 /* Change from mapped state to withdrawn state. */
3319 x_make_screen_invisible (s
)
3330 if (! EQ (Vx_no_window_manager
, Qt
))
3334 unmap
.type
= UnmapNotify
;
3335 unmap
.window
= s
->display
.x
->window_desc
;
3336 unmap
.event
= DefaultRootWindow (x_current_display
);
3337 unmap
.from_configure
= False
;
3338 XSendEvent (x_current_display
, DefaultRootWindow (x_current_display
),
3339 False
, SubstructureRedirectMask
|SubstructureNotifyMask
,
3343 /* The new function below does the same as the above code, plus unmapping
3344 the window. Sending the event without actually unmapping can make
3345 the window manager start ignoring the window (i.e., no more title bar,
3346 icon manager stuff.) */
3349 /* New function available with R4 */
3350 if (! XWithdrawWindow (x_current_display
, s
->display
.x
->window_desc
,
3351 DefaultScreen (x_current_display
)))
3353 UNBLOCK_INPUT_RESIGNAL
;
3354 error ("Can't notify window manager of iconification.");
3358 XUnmapWindow (XDISPLAY s
->display
.x
->window_desc
);
3360 s
->visible
= 0; /* Handled by the UnMap event for X11 */
3361 if (s
->display
.x
->icon_desc
!= 0)
3362 XUnmapWindow (XDISPLAY s
->display
.x
->icon_desc
);
3363 #endif /* not HAVE_X11 */
3369 /* Window manager communication. Created in Fx_open_connection. */
3370 extern Atom Xatom_wm_change_state
;
3372 /* Change window state from mapped to iconified. */
3374 x_iconify_screen (s
)
3385 if (! EQ (Vx_no_window_manager
, Qt
))
3386 if (! XIconifyWindow (x_current_display
, s
->display
.x
->window_desc
,
3387 DefaultScreen (x_current_display
)))
3389 UNBLOCK_INPUT_RESIGNAL
;
3390 error ("Can't notify window manager of iconification.");
3397 XClientMessageEvent message
;
3399 message
.window
= s
->display
.x
->window_desc
;
3400 message
.type
= ClientMessage
;
3401 message
.message_type
= Xatom_wm_change_state
;
3402 message
.format
= 32;
3403 message
.data
.l
[0] = IconicState
;
3405 if (! XSendEvent (x_current_display
,
3406 DefaultRootWindow (x_current_display
),
3408 SubstructureRedirectMask
| SubstructureNotifyMask
,
3411 UNBLOCK_INPUT_RESIGNAL
;
3412 error ("Can't notify window manager of iconification.");
3417 XUnmapWindow (XDISPLAY s
->display
.x
->window_desc
);
3419 s
->visible
= 0; /* Handled in the UnMap event for X11. */
3420 if (s
->display
.x
->icon_desc
!= 0)
3422 XMapWindow (XDISPLAY s
->display
.x
->icon_desc
);
3431 /* Destroy the X window of screen S.
3432 DISPL is the former s->display (since s->display
3433 has already been nulled out). */
3435 x_destroy_window (s
, displ
)
3437 union display displ
;
3442 if (displ
.x
->icon_desc
!= 0)
3443 XDestroyWindow (XDISPLAY displ
.x
->icon_desc
);
3444 XDestroyWindow (XDISPLAY displ
.x
->window_desc
);
3449 if (s
== x_focus_screen
)
3451 if (s
== x_highlight_screen
)
3452 x_highlight_screen
= 0;
3457 /* Manage event queues.
3459 This code is only used by the X10 support.
3461 We cannot leave events in the X queue and get them when we are ready
3462 because X does not provide a subroutine to get only a certain kind
3463 of event but not block if there are no queued events of that kind.
3465 Therefore, we must examine events as they come in and copy events
3466 of certain kinds into our private queues.
3468 All ExposeRegion events are put in x_expose_queue.
3469 All ButtonPressed and ButtonReleased events are put in x_mouse_queue. */
3472 /* Write the event *P_XREP into the event queue *QUEUE.
3473 If the queue is full, do nothing, but return nonzero. */
3476 enqueue_event (p_xrep
, queue
)
3477 register XEvent
*p_xrep
;
3478 register struct event_queue
*queue
;
3480 int newindex
= queue
->windex
+ 1;
3481 if (newindex
== EVENT_BUFFER_SIZE
)
3483 if (newindex
== queue
->rindex
)
3485 queue
->xrep
[queue
->windex
] = *p_xrep
;
3486 queue
->windex
= newindex
;
3490 /* Fetch the next event from queue *QUEUE and store it in *P_XREP.
3491 If *QUEUE is empty, do nothing and return 0. */
3494 dequeue_event (p_xrep
, queue
)
3495 register XEvent
*p_xrep
;
3496 register struct event_queue
*queue
;
3498 if (queue
->windex
== queue
->rindex
)
3500 *p_xrep
= queue
->xrep
[queue
->rindex
++];
3501 if (queue
->rindex
== EVENT_BUFFER_SIZE
)
3506 /* Return the number of events buffered in *QUEUE. */
3509 queue_event_count (queue
)
3510 register struct event_queue
*queue
;
3512 int tem
= queue
->windex
- queue
->rindex
;
3515 return EVENT_BUFFER_SIZE
+ tem
;
3518 /* Return nonzero if mouse input is pending. */
3521 mouse_event_pending_p ()
3523 return queue_event_count (&x_mouse_queue
);
3529 x_wm_set_size_hint (s
, prompting
)
3533 XSizeHints size_hints
;
3534 Window window
= s
->display
.x
->window_desc
;
3536 size_hints
.flags
= PResizeInc
| PMinSize
| PMaxSize
;
3538 flexlines
= s
->height
;
3540 size_hints
.x
= s
->display
.x
->left_pos
;
3541 size_hints
.y
= s
->display
.x
->top_pos
;
3542 size_hints
.height
= PIXEL_HEIGHT (s
);
3543 size_hints
.width
= PIXEL_WIDTH (s
);
3544 size_hints
.width_inc
= FONT_WIDTH (s
->display
.x
->font
);
3545 size_hints
.height_inc
= FONT_HEIGHT (s
->display
.x
->font
);
3546 size_hints
.base_width
= (2 * s
->display
.x
->internal_border_width
)
3547 + s
->display
.x
->v_scrollbar_width
;
3548 size_hints
.base_height
= (2 * s
->display
.x
->internal_border_width
)
3549 + s
->display
.x
->h_scrollbar_height
;
3550 size_hints
.min_width
= size_hints
.base_width
+ size_hints
.width_inc
;
3551 size_hints
.min_height
= size_hints
.base_height
+ size_hints
.height_inc
;
3552 size_hints
.max_width
= x_screen_width
3553 - ((2 * s
->display
.x
->internal_border_width
)
3554 + s
->display
.x
->v_scrollbar_width
);
3555 size_hints
.max_height
= x_screen_height
3556 - ((2 * s
->display
.x
->internal_border_width
)
3557 + s
->display
.x
->h_scrollbar_height
);
3560 size_hints
.flags
|= prompting
;
3563 XSizeHints hints
; /* Sometimes I hate X Windows... */
3565 XGetNormalHints (x_current_display
, window
, &hints
);
3566 if (hints
.flags
& PSize
)
3567 size_hints
.flags
|= PSize
;
3568 if (hints
.flags
& PPosition
)
3569 size_hints
.flags
|= PPosition
;
3570 if (hints
.flags
& USPosition
)
3571 size_hints
.flags
|= USPosition
;
3572 if (hints
.flags
& USSize
)
3573 size_hints
.flags
|= USSize
;
3577 XSetNormalHints (x_current_display
, window
, &size_hints
);
3579 XSetWMNormalHints (x_current_display
, window
, &size_hints
);
3582 /* Used for IconicState or NormalState */
3583 x_wm_set_window_state (s
, state
)
3588 Window window
= s
->display
.x
->window_desc
;
3590 wm_hints
.flags
= StateHint
;
3591 wm_hints
.initial_state
= state
;
3592 XSetWMHints (x_current_display
, window
, &wm_hints
);
3595 x_wm_set_icon_pixmap (s
, icon_pixmap
)
3600 Window window
= s
->display
.x
->window_desc
;
3602 wm_hints
.flags
= IconPixmapHint
;
3603 wm_hints
.icon_pixmap
= icon_pixmap
;
3604 XSetWMHints (x_current_display
, window
, &wm_hints
);
3607 x_wm_set_icon_position (s
, icon_x
, icon_y
)
3612 Window window
= s
->display
.x
->window_desc
;
3614 wm_hints
.flags
= IconPositionHint
;
3615 wm_hints
.icon_x
= icon_x
;
3616 wm_hints
.icon_y
= icon_y
;
3617 XSetWMHints (x_current_display
, window
, &wm_hints
);
3622 x_term_init (display_name
)
3628 extern int old_fcntl_owner
;
3631 x_focus_screen
= x_highlight_screen
= 0;
3633 x_current_display
= XOpenDisplay (display_name
);
3634 if (x_current_display
== 0)
3635 fatal ("X server %s not responding; check the DISPLAY environment variable or use \"-d\"\n",
3640 int hostname_size
= MAXHOSTNAMELEN
+ 1;
3642 hostname
= (char *) xmalloc (hostname_size
);
3645 XSetAfterFunction (x_current_display
, x_trace_wire
);
3648 invocation_name
= Ffile_name_nondirectory (Fcar (Vcommand_line_args
));
3650 /* Try to get the host name; if the buffer is too short, try
3651 again. Apparently, the only indication gethostname gives of
3652 whether the buffer was large enough is the presence or absence
3653 of a '\0' in the string. Eech. */
3656 gethostname (hostname
, hostname_size
- 1);
3657 hostname
[hostname_size
- 1] = '\0';
3659 /* Was the buffer large enough for gethostname to store the '\0'? */
3660 if (strlen (hostname
) < hostname_size
- 1)
3663 hostname_size
<<= 1;
3664 hostname
= (char *) xrealloc (hostname
, hostname_size
);
3666 x_id_name
= (char *) xmalloc (XSTRING (invocation_name
)->size
3669 sprintf (x_id_name
, "%s@%s", XSTRING (invocation_name
)->data
, hostname
);
3672 dup2 (ConnectionNumber (x_current_display
), 0);
3674 #ifndef SYSV_STREAMS
3675 /* Streams somehow keeps track of which descriptor number
3676 is being used to talk to X. So it is not safe to substitute
3677 descriptor 0. But it is safe to make descriptor 0 a copy of it. */
3678 close (ConnectionNumber (x_current_display
));
3679 ConnectionNumber (x_current_display
) = 0; /* Looks a little strange?
3680 * check the def of the macro;
3681 * it is a genuine lvalue */
3682 #endif /* not SYSV_STREAMS */
3684 #endif /* HAVE_X11 */
3687 old_fcntl_owner
= fcntl (0, F_GETOWN
, 0);
3688 #ifdef F_SETOWN_SOCK_NEG
3689 fcntl (0, F_SETOWN
, -getpid ()); /* stdin is a socket here */
3691 fcntl (0, F_SETOWN
, getpid ());
3692 #endif /* F_SETOWN_SOCK_NEG */
3693 #endif /* F_SETOWN */
3699 /* Must use interrupt input because we cannot otherwise
3700 arrange for C-g to be noticed immediately.
3701 We cannot connect it to SIGINT. */
3702 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
3704 expose_all_windows
= 0;
3706 clear_screen_hook
= XTclear_screen
;
3707 clear_end_of_line_hook
= XTclear_end_of_line
;
3708 ins_del_lines_hook
= XTins_del_lines
;
3709 change_line_highlight_hook
= XTchange_line_highlight
;
3710 insert_glyphs_hook
= XTinsert_glyphs
;
3711 write_glyphs_hook
= XTwrite_glyphs
;
3712 delete_glyphs_hook
= XTdelete_glyphs
;
3713 ring_bell_hook
= XTring_bell
;
3714 reset_terminal_modes_hook
= XTreset_terminal_modes
;
3715 set_terminal_modes_hook
= XTset_terminal_modes
;
3716 update_begin_hook
= XTupdate_begin
;
3717 update_end_hook
= XTupdate_end
;
3718 set_terminal_window_hook
= XTset_terminal_window
;
3719 read_socket_hook
= XTread_socket
;
3720 cursor_to_hook
= XTcursor_to
;
3721 reassert_line_highlight_hook
= XTreassert_line_highlight
;
3722 screen_rehighlight_hook
= XTscreen_rehighlight
;
3723 mouse_position_hook
= XTmouse_position
;
3725 scroll_region_ok
= 1; /* we'll scroll partial screens */
3726 char_ins_del_ok
= 0; /* just as fast to write the line */
3727 line_ins_del_ok
= 1; /* we'll just blt 'em */
3728 fast_clear_end_of_line
= 1; /* X does this well */
3729 memory_below_screen
= 0; /* we don't remember what scrolls
3733 XHandleError (x_error_handler
);
3734 XHandleIOError (x_error_handler
);
3736 /* Disable Window Change signals; they are handled by X events. */
3738 signal (SIGWINCH
, SIG_DFL
);
3739 #endif /* SIGWINCH */
3741 signal (SIGPIPE
, x_error_handler
);
3747 staticpro (&invocation_name
);
3748 invocation_name
= Qnil
;
3750 #endif /* HAVE_X11 */
3751 #endif /* HAVE_X_WINDOWS */