1 /* X Communication module for terminals which understand the X protocol.
2 Copyright (C) 1989 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
22 Kludge: dup2 is used to put the X-connection socket into desc # 0
23 so that wait_reading_process_input will wait for it in place of
24 actual terminal input.
35 /* On 4.3 this loses if it comes after xterm.h. */
38 /* This may include sys/types.h, and that somehow loses
39 if this is not done before the other system files. */
42 /* Load sys/types.h if not already loaded.
43 In some systems loading it twice is suicidal. */
45 #include <sys/types.h>
49 #include <sys/ioctl.h>
52 #include <sys/termio.h>
56 /* Allow m- file to inhibit use of FIONREAD. */
57 #ifdef BROKEN_FIONREAD
61 /* We are unable to use interrupts if FIONREAD is not available,
62 so flush SIGIO so we won't try. */
71 #else /* not NEED_TIME_H */
74 #endif /* HAVE_TIMEVAL */
75 #endif /* not NEED_TIME_H */
83 #include <sys/param.h>
85 #include "dispextern.h"
86 #include "termhooks.h"
99 #define XMapWindow XMapRaised /* Raise them when mapping. */
101 #include <X/Xkeyboard.h>
102 /*#include <X/Xproto.h> */
103 #endif /* HAVE_X11 */
105 /* For sending Meta-characters. Do we need this? */
108 #define min(a,b) ((a)<(b) ? (a) : (b))
109 #define max(a,b) ((a)>(b) ? (a) : (b))
111 /* Nonzero means we must reprint all windows
112 because 1) we received an ExposeWindow event
113 or 2) we received too many ExposeRegion events to record. */
115 static int expose_all_windows
;
117 /* Nonzero means we must reprint all icon windows. */
119 static int expose_all_icons
;
122 /* ExposeRegion events, when received, are copied into this queue
123 for later processing. */
125 static struct event_queue x_expose_queue
;
127 /* ButtonPressed and ButtonReleased events, when received,
128 are copied into this queue for later processing. */
130 struct event_queue x_mouse_queue
;
133 /* Nonzero after BLOCK_INPUT; prevents input events from being
134 processed until later. */
138 #if defined (SIGIO) && defined (FIONREAD)
139 int BLOCK_INPUT_mask
;
142 /* Nonzero if input events came in while x_input_blocked was nonzero.
143 UNBLOCK_INPUT checks for this. */
147 /* Nonzero if in redisplay (); prevents us from calling it recursively */
151 /* The id of a bitmap used for icon windows.
152 One such map is shared by all Emacs icon windows.
153 This is zero if we have not yet had a need to create the bitmap. */
155 static Bitmap icon_bitmap
;
157 /* Font used for text icons. */
159 static FONT_TYPE
*icon_font_info
;
161 /* Stuff for dealing with the main icon title. */
163 extern Lisp_Object Vcommand_line_args
;
164 char *hostname
, *x_id_name
;
165 Lisp_Object invocation_name
;
167 /* This is the X connection that we are using. */
169 Display
*x_current_display
;
171 /* Screen being updated by update_screen. */
172 /* This is set by XTupdate_begin and looked at by all the
173 XT functions. It is zero while not inside an update.
174 In that case, the XT functions assume that `selected_screen'
175 is the screen to apply to. */
177 static struct screen
*updating_screen
;
179 /* The screen (if any) which has the X window that has keyboard focus.
180 Zero if none. This is examined by Ffocus_screen in screen.c. */
181 struct screen
*x_focus_screen
;
183 /* The screen which currently has the visual highlight, and should get
184 keyboard input (other sorts of input have the screen encoded in the
185 event). It points to the X focus screen's selected window's
186 screen. It differs from x_focus_screen when we're using a global
188 static struct screen
*x_highlight_screen
;
190 /* From .Xdefaults, the value of "emacs.WarpMouse". If non-zero,
191 mouse is moved to inside of screen when screen is de-iconified. */
193 static int warp_mouse_on_deiconify
;
195 /* During an update, maximum vpos for ins/del line operations to affect. */
197 static int flexlines
;
199 /* During an update, nonzero if chars output now should be highlighted. */
201 static int highlight
;
203 /* Nominal cursor position -- where to draw output.
204 During an update, these are different from the cursor-box position. */
210 /* `t' if a mouse button is depressed. */
212 extern Lisp_Object Vmouse_depressed
;
214 /* Tells if a window manager is present or not. */
216 extern Lisp_Object Vx_no_window_manager
;
218 /* Timestamp that we requested selection data was made. */
219 extern Time requestor_time
;
221 /* ID of the window requesting selection data. */
222 extern Window requestor_window
;
224 /* Nonzero enables some debugging for the X interface code. */
227 #else /* X10 stuff */
229 /* Bit patterns for the mouse cursor. */
231 short MouseCursor
[] = {
232 0x0000, 0x0008, 0x0018, 0x0038,
233 0x0078, 0x00f8, 0x01f8, 0x03f8,
234 0x07f8, 0x00f8, 0x00d8, 0x0188,
235 0x0180, 0x0300, 0x0300, 0x0000};
237 short MouseMask
[] = {
238 0x000c, 0x001c, 0x003c, 0x007c,
239 0x00fc, 0x01fc, 0x03fc, 0x07fc,
240 0x0ffc, 0x0ffc, 0x01fc, 0x03dc,
241 0x03cc, 0x0780, 0x0780, 0x0300};
243 static short grey_bits
[] = {
244 0x0005, 0x000a, 0x0005, 0x000a};
246 static Pixmap GreyPixmap
= 0;
247 #endif /* X10 stuff */
249 /* From time to time we get info on an Emacs window, here. */
251 static WINDOWINFO_TYPE windowinfo
;
255 extern Display
*XOpenDisplay ();
256 extern Window
XCreateWindow ();
258 extern Cursor
XCreateCursor ();
259 extern FONT_TYPE
*XOpenFont ();
261 static void flashback ();
264 static void dumpqueue ();
268 static XTcursor_to ();
269 static XTclear_end_of_line ();
271 /* These hooks are called by update_screen at the beginning and end
272 of a screen update. We record in `updating_screen' the identity
273 of the screen being updated, so that the XT... functions do not
274 need to take a screen as argument. Most of the XT... functions
275 should never be called except during an update, the only exceptions
276 being XTcursor_to, XTwrite_char and XTreassert_line_highlight. */
278 extern int mouse_track_top
, mouse_track_left
, mouse_track_width
;
290 flexlines
= s
->height
;
300 static void x_do_pending_expose ();
308 if (updating_screen
== 0
309 || updating_screen
!= s
)
316 adjust_scrollbars (s
);
317 x_do_pending_expose ();
319 x_display_cursor (s
, 1);
326 /* External interface to control of standout mode.
327 Call this when about to modify line at position VPOS
328 and not change whether it is highlighted. */
330 XTreassert_line_highlight (new, vpos
)
336 /* Call this when about to modify line at position VPOS
337 and change whether it is highlighted. */
340 XTchange_line_highlight (new_highlight
, vpos
, first_unused_hpos
)
341 int new_highlight
, vpos
, first_unused_hpos
;
343 highlight
= new_highlight
;
344 XTcursor_to (vpos
, 0);
345 XTclear_end_of_line (updating_screen
->width
);
348 /* This is used when starting Emacs and when restarting after suspend.
349 When starting Emacs, no X window is mapped. And nothing must be done
350 to Emacs's own window if it is suspended (though that rarely happens). */
353 XTset_terminal_modes ()
357 /* This is called when exiting or suspending Emacs.
358 Exiting will make the X-windows go away, and suspending
359 requires no action. */
362 XTreset_terminal_modes ()
364 /* XTclear_screen (); */
367 /* Set the nominal cursor position of the screen:
368 where display update commands will take effect.
369 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 register char *cp
= buf
;
407 Window window
= s
->display
.x
->window_desc
;
408 GC drawing_gc
= (hl
== 2 ? s
->display
.x
->cursor_gc
409 : (hl
? s
->display
.x
->reverse_gc
410 : s
->display
.x
->normal_gc
));
412 if (sizeof (GLYPH
) == sizeof (XChar2b
))
413 XDrawImageString16 (x_current_display
, window
, drawing_gc
,
414 left
, top
+ FONT_BASE (font
), (XChar2b
*) gp
, n
);
415 else if (sizeof (GLYPH
) == sizeof (unsigned char))
416 XDrawImageString (x_current_display
, window
, drawing_gc
,
417 left
, top
+ FONT_BASE (font
), (char *) gp
, n
);
419 /* What size of glyph ARE you using? And does X have a function to
426 dumpglyphs (s
, left
, top
, gp
, n
, hl
, font
)
429 register GLYPH
*gp
; /* Points to first GLYPH. */
430 register int n
; /* Number of glyphs to display. */
434 char buf
[s
->width
]; /* Holds characters to be displayed. */
435 register char *cp
; /* Steps through buf[]. */
436 register int tlen
= GLYPH_TABLE_LENGTH
;
437 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
438 Window window
= s
->display
.x
->window_desc
;
439 int cursor_pixel
= s
->display
.x
->cursor_pixel
;
440 int fg_pixel
= s
->display
.x
->foreground_pixel
;
441 int bg_pixel
= s
->display
.x
->background_pixel
;
442 int intborder
= s
->display
.x
->internal_border_width
;
446 /* Get the face-code of the next GLYPH. */
450 while (GLYPH_ALIAS_P (tbase
, tlen
, g
))
451 g
= GLYPH_ALIAS (tbase
, g
);
455 /* Find the run of consecutive glyphs with the same face-code.
456 Extract their character codes into BUF. */
461 while (GLYPH_ALIAS_P (tbase
, tlen
, g
))
462 g
= GLYPH_ALIAS (tbase
, g
);
471 /* LEN gets the length of the run. */
474 /* Now output this run of chars, with the font and pixel values
475 determined by the face code CF. */
479 GC GC_cursor
= s
->display
.x
->cursor_gc
;
480 GC GC_reverse
= s
->display
.x
->reverse_gc
;
481 GC GC_normal
= s
->display
.x
->normal_gc
;
483 XDrawImageString (x_current_display
, window
,
486 : (hl
? GC_reverse
: GC_normal
)),
487 left
, top
+ FONT_BASE (font
), buf
, len
);
489 XText (window
, left
, top
,
494 ? (cursor_pixel
== fg_pixel
? bg_pixel
: fg_pixel
)
495 : hl
? bg_pixel
: fg_pixel
),
496 (hl
== 2 ? cursor_pixel
497 : hl
? fg_pixel
: bg_pixel
));
498 #endif /* HAVE_X11 */
503 if (FACE_IS_FONT (cf
))
504 XDrawImageString (x_current_display
, s
->display
.x
->window_desc
,
506 left
, top
+ FONT_BASE (FACE_FONT (cf
)),
508 else if (FACE_IS_IMAGE (cf
))
509 XCopyPlane (x_current_display
, FACE_IMAGE (cf
),
510 s
->display
.x
->window_desc
,
511 s
->display
.x
->normal_gc
,
513 FACE_IMAGE_WIDTH (cf
),
514 FACE_IMAGE_HEIGHT (cf
), left
, top
);
518 register struct face
*fp
= x_face_table
[cf
];
520 XText (window
, left
, top
,
525 ? (cursor_pixel
== fp
->fg
? fp
->bg
: fp
->fg
)
526 : hl
? fp
->bg
: fp
->fg
),
527 (hl
== 2 ? cursor_pixel
528 : hl
? fp
->fg
: fp
->bg
));
529 #endif /* HAVE_X11 */
531 left
+= len
* FONT_WIDTH (font
);
536 /* Output some text at the nominal screen cursor position,
537 advancing the cursor over the text.
538 Output LEN glyphs at START.
540 `highlight', set up by XTreassert_line_highlight or XTchange_line_highlight,
541 controls the pixel values used for foreground and background. */
544 XTwrite_glyphs (start
, len
)
545 register GLYPH
*start
;
548 register int temp_length
;
558 /* If not within an update,
559 output at the screen's visible cursor. */
560 curs_x
= s
->cursor_x
;
561 curs_y
= s
->cursor_y
;
565 (curs_x
* FONT_WIDTH (s
->display
.x
->font
)
566 + s
->display
.x
->internal_border_width
),
567 (curs_y
* FONT_HEIGHT (s
->display
.x
->font
)
568 + s
->display
.x
->internal_border_width
),
569 start
, len
, highlight
, s
->display
.x
->font
);
571 /* If we drew on top of the cursor, note that it is turned off. */
572 if (curs_y
== s
->phys_cursor_y
573 && curs_x
<= s
->phys_cursor_x
574 && curs_x
+ len
> s
->phys_cursor_x
)
575 s
->phys_cursor_x
= -1;
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 /* Notice if the cursor will be cleared by this operation. */
614 if (curs_y
== s
->phys_cursor_y
615 && curs_x
<= s
->phys_cursor_x
616 && s
->phys_cursor_x
< first_unused
)
617 s
->phys_cursor_x
= -1;
620 XClearArea (x_current_display
, s
->display
.x
->window_desc
,
621 curs_x
* FONT_WIDTH (s
->display
.x
->font
)
622 + s
->display
.x
->internal_border_width
,
623 curs_y
* FONT_HEIGHT (s
->display
.x
->font
)
624 + s
->display
.x
->internal_border_width
,
625 FONT_WIDTH (s
->display
.x
->font
) * (first_unused
- curs_x
),
626 FONT_HEIGHT (s
->display
.x
->font
), False
);
629 XPixSet (s
->display
.x
->window_desc
,
630 curs_x
* FONT_WIDTH (s
->display
.x
->font
) + s
->display
.x
->internal_border_width
,
631 curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + s
->display
.x
->internal_border_width
,
632 FONT_WIDTH (s
->display
.x
->font
) * (first_unused
- curs_x
),
633 FONT_HEIGHT (s
->display
.x
->font
),
634 s
->display
.x
->background_pixel
);
635 #endif /* HAVE_X11 */
644 struct screen
*s
= updating_screen
;
649 s
->phys_cursor_x
= -1; /* Cursor not visible. */
650 curs_x
= 0; /* Nominal cursor position is top left. */
654 XClear (s
->display
.x
->window_desc
);
662 /* Paint horzontal bars down the screen for a visible bell.
663 Note that this may be way too slow on some machines. */
668 register struct screen_glyphs
*active_screen
= SCREEN_CURRENT_GLYPHS (s
);
672 if (updating_screen
!= 0)
678 for (i
= s
->height
* FONT_HEIGHT (s
->display
.x
->font
) - 10;
680 i
-= 100) /* Should be NO LOWER than 75 for speed reasons. */
681 XFillRectangle (x_current_display
, s
->display
.x
->window_desc
,
682 s
->display
.x
->cursor_gc
,
683 0, i
, s
->width
* FONT_WIDTH (s
->display
.x
->font
)
684 + 2 * s
->display
.x
->internal_border_width
, 25);
687 x
= (s
->width
* FONT_WIDTH (s
->display
.x
->font
)) / 4;
688 y
= (s
->height
* FONT_HEIGHT (s
->display
.x
->font
)) / 4;
689 XFillRectangle (x_current_display
, s
->display
.x
->window_desc
,
690 s
->display
.x
->cursor_gc
,
692 dumpglyphs (s
, (x
+ s
->display
.x
->internal_border_width
),
693 (y
+ s
->display
.x
->internal_border_width
),
694 &active_screen
->glyphs
[(s
->height
/ 4) + 1][(s
->width
/ 4)],
695 1, 0, s
->display
.x
->font
);
698 for (i
= s
->height
* FONT_HEIGHT (s
->display
.x
->font
) - 10;
701 XPixFill (s
->display
.x
->window_desc
, 0, i
,
702 s
->width
* FONT_WIDTH (s
->display
.x
->font
)
703 + 2 * s
->display
.x
->internal_border_width
, 10,
704 WHITE_PIX_DEFAULT
, ClipModeClipped
, GXinvert
, AllPlanes
);
711 /* Flip background and forground colors of the screen. */
718 unsigned long pix_temp
;
720 x_display_cursor (s
, 0);
721 XClearWindow (x_current_display
, s
->display
.x
->window_desc
);
722 temp
= s
->display
.x
->normal_gc
;
723 s
->display
.x
->normal_gc
= s
->display
.x
->reverse_gc
;
724 s
->display
.x
->reverse_gc
= temp
;
725 pix_temp
= s
->display
.x
->foreground_pixel
;
726 s
->display
.x
->foreground_pixel
= s
->display
.x
->background_pixel
;
727 s
->display
.x
->background_pixel
= pix_temp
;
729 XSetWindowBackground (x_current_display
, s
->display
.x
->window_desc
,
730 s
->display
.x
->background_pixel
);
731 if (s
->display
.x
->background_pixel
== s
->display
.x
->cursor_pixel
)
733 s
->display
.x
->cursor_pixel
= s
->display
.x
->foreground_pixel
;
734 XSetBackground (x_current_display
, s
->display
.x
->cursor_gc
,
735 s
->display
.x
->cursor_pixel
);
736 XSetForeground (x_current_display
, s
->display
.x
->cursor_gc
,
737 s
->display
.x
->background_pixel
);
743 /* Make audible bell. */
746 #define XRINGBELL XBell(x_current_display, 0)
748 #define XRINGBELL XFeep(0);
755 XTflash (selected_screen
);
758 x_invert_screen (selected_screen
);
759 x_invert_screen (selected_screen
);
770 /* Insert and delete character are not supposed to be used
771 because we are supposed to turn off the feature of using them. */
774 XTinsert_glyphs (start
, len
)
775 register char *start
;
788 /* Specify how many text lines, from the top of the window,
789 should be affected by insert-lines and delete-lines operations.
790 This, and those operations, are used only within an update
791 that is bounded by calls to XTupdate_begin and XTupdate_end. */
794 XTset_terminal_window (n
)
797 if (updating_screen
== 0)
800 if ((n
<= 0) || (n
> updating_screen
->height
))
801 flexlines
= updating_screen
->height
;
806 /* Perform an insert-lines operation, inserting N lines
807 at a vertical position curs_y. */
813 register int topregion
, bottomregion
;
814 register int length
, newtop
, mask
;
815 register struct screen
*s
= updating_screen
;
816 int intborder
= s
->display
.x
->internal_border_width
;
818 if (curs_y
>= flexlines
)
822 bottomregion
= flexlines
- (n
+ 1);
823 newtop
= topregion
+ n
;
824 length
= (bottomregion
- topregion
) + 1;
830 if ((length
> 0) && (newtop
<= flexlines
))
833 XCopyArea (x_current_display
, s
->display
.x
->window_desc
,
834 s
->display
.x
->window_desc
, s
->display
.x
->normal_gc
,
835 intborder
, topregion
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
836 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
837 length
* FONT_HEIGHT (s
->display
.x
->font
), intborder
,
838 newtop
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
);
840 XMoveArea (s
->display
.x
->window_desc
,
841 intborder
, topregion
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
842 intborder
, newtop
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
843 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
844 length
* FONT_HEIGHT (s
->display
.x
->font
));
845 /* Now we must process any ExposeRegion events that occur
846 if the area being copied from is obscured.
847 We can't let it wait because further i/d operations
848 may want to copy this area to another area. */
850 #endif /* HAVE_X11 */
853 newtop
= min (newtop
, (flexlines
- 1));
854 length
= newtop
- topregion
;
858 XClearArea (x_current_display
, s
->display
.x
->window_desc
, intborder
,
859 topregion
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
860 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
861 n
* FONT_HEIGHT (s
->display
.x
->font
), False
);
863 XPixSet (s
->display
.x
->window_desc
,
865 topregion
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
866 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
867 n
* FONT_HEIGHT (s
->display
.x
->font
),
868 s
->display
.x
->background_pixel
);
869 #endif /* HAVE_X11 */
873 /* Perform a delete-lines operation, deleting N lines
874 at a vertical position curs_y. */
881 register struct screen
*s
= updating_screen
;
882 int intborder
= s
->display
.x
->internal_border_width
;
884 if (curs_y
>= flexlines
)
891 if ((curs_y
+ n
) >= flexlines
)
893 if (flexlines
>= (curs_y
+ 1))
896 XClearArea (x_current_display
, s
->display
.x
->window_desc
, intborder
,
897 curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
898 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
899 (flexlines
- curs_y
) * FONT_HEIGHT (s
->display
.x
->font
), False
);
901 XPixSet (s
->display
.x
->window_desc
,
902 intborder
, curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
903 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
904 (flexlines
- curs_y
) * FONT_HEIGHT (s
->display
.x
->font
),
905 s
->display
.x
->background_pixel
);
906 #endif /* HAVE_X11 */
912 XCopyArea (x_current_display
, s
->display
.x
->window_desc
,
913 s
->display
.x
->window_desc
, s
->display
.x
->normal_gc
,
915 (curs_y
+ n
) * FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
916 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
917 (flexlines
- (curs_y
+ n
)) * FONT_HEIGHT (s
->display
.x
->font
),
918 intborder
, curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
);
919 XClearArea (x_current_display
, s
->display
.x
->window_desc
,
921 (flexlines
- n
) * FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
922 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
923 n
* FONT_HEIGHT (s
->display
.x
->font
), False
);
925 XMoveArea (s
->display
.x
->window_desc
,
927 (curs_y
+ n
) * FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
928 intborder
, curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
929 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
930 (flexlines
- (curs_y
+ n
)) * FONT_HEIGHT (s
->display
.x
->font
));
931 /* Now we must process any ExposeRegion events that occur
932 if the area being copied from is obscured.
933 We can't let it wait because further i/d operations
934 may want to copy this area to another area. */
936 XPixSet (s
->display
.x
->window_desc
, intborder
,
937 (flexlines
- n
) * FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
938 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
939 n
* FONT_HEIGHT (s
->display
.x
->font
), s
->display
.x
->background_pixel
);
940 #endif /* HAVE_X11 */
944 /* Perform an insert-lines or delete-lines operation,
945 inserting N lines or deleting -N lines at vertical position VPOS. */
947 XTins_del_lines (vpos
, n
)
950 if (updating_screen
== 0)
953 /* Hide the cursor. */
954 x_display_cursor (updating_screen
, 0);
956 XTcursor_to (vpos
, 0);
967 static void clear_cursor ();
969 /* Output into a rectangle of an X-window (for screen S)
970 the characters in s->phys_lines that overlap that rectangle.
971 TOP and LEFT are the position of the upper left corner of the rectangle.
972 ROWS and COLS are the size of the rectangle. */
975 dumprectangle (s
, left
, top
, cols
, rows
)
977 register int left
, top
, cols
, rows
;
979 register struct screen_glyphs
*active_screen
= SCREEN_CURRENT_GLYPHS (s
);
980 int cursor_cleared
= 0;
984 if (SCREEN_GARBAGED_P (s
))
987 top
-= s
->display
.x
->internal_border_width
;
988 left
-= s
->display
.x
->internal_border_width
;
990 /* Express rectangle as four edges, instead of position-and-size. */
994 #ifndef HAVE_X11 /* Window manger does this for X11. */
995 /* If the rectangle includes any of the internal border area,
996 redisplay the border emphasis. */
997 if (top
< 0 || left
< 0
998 || bottom
> s
->height
* FONT_HEIGHT (s
->display
.x
->font
)
999 || right
> s
->width
* FONT_WIDTH (s
->display
.x
->font
))
1001 #endif /* HAVE_X11 */
1003 /* Convert rectangle edges in pixels to edges in chars.
1004 Round down for left and top, up for right and bottom. */
1005 top
/= FONT_HEIGHT (s
->display
.x
->font
);
1006 left
/= FONT_WIDTH (s
->display
.x
->font
);
1007 bottom
+= (FONT_HEIGHT (s
->display
.x
->font
) - 1);
1008 right
+= (FONT_WIDTH (s
->display
.x
->font
) - 1);
1009 bottom
/= FONT_HEIGHT (s
->display
.x
->font
);
1010 right
/= FONT_WIDTH (s
->display
.x
->font
);
1012 /* Clip the rectangle to what can be visible. */
1017 if (right
> s
->width
)
1019 if (bottom
> s
->height
)
1022 /* Get size in chars of the rectangle. */
1023 cols
= right
- left
;
1024 rows
= bottom
- top
;
1026 /* If rectangle has zero area, return. */
1027 if (rows
<= 0) return;
1028 if (cols
<= 0) return;
1030 /* Turn off the cursor if it is in the rectangle.
1031 We will turn it back on afterward. */
1032 if ((s
->phys_cursor_x
>= left
) && (s
->phys_cursor_x
< right
)
1033 && (s
->phys_cursor_y
>= top
) && (s
->phys_cursor_y
< bottom
))
1039 /* Display the text in the rectangle, one text line at a time. */
1041 for (y
= top
; y
< bottom
; y
++)
1043 GLYPH
*line
= &active_screen
->glyphs
[y
][left
];
1045 if (! active_screen
->enable
[y
] || left
> active_screen
->used
[y
])
1049 (left
* FONT_WIDTH (s
->display
.x
->font
)
1050 + s
->display
.x
->internal_border_width
),
1051 (y
* FONT_HEIGHT (s
->display
.x
->font
)
1052 + s
->display
.x
->internal_border_width
),
1053 line
, min (cols
, active_screen
->used
[y
] - left
),
1054 active_screen
->highlight
[y
], s
->display
.x
->font
);
1057 /* Turn the cursor on if we turned it off. */
1060 x_display_cursor (s
, 1);
1064 /* Process all queued ExposeRegion events. */
1070 XExposeRegionEvent r
;
1072 while (dequeue_event (&r
, &x_expose_queue
))
1074 struct screen
*s
= x_window_to_screen (r
.window
);
1075 if (s
->display
.x
->icon_desc
== r
.window
)
1078 dumprectangle (s
, r
.x
, r
.y
, r
.width
, r
.height
);
1084 /* Process all expose events that are pending.
1085 Redraws the cursor if necessary on any screen that
1086 is not in the process of being updated with update_screen. */
1089 x_do_pending_expose ()
1093 Lisp_Object tail
, screen
;
1095 if (expose_all_windows
)
1097 expose_all_windows
= 0;
1098 for (tail
= Vscreen_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1100 register int temp_width
, temp_height
;
1103 screen
= XCONS (tail
)->car
;
1104 if (XTYPE (screen
) != Lisp_Screen
)
1106 s
= XSCREEN (screen
);
1107 if (! SCREEN_IS_X (s
))
1111 if (!s
->display
.x
->needs_exposure
)
1114 intborder
= s
->display
.x
->internal_border_width
;
1117 XGetWindowInfo (s
->display
.x
->window_desc
, &windowinfo
);
1118 temp_width
= ((windowinfo
.width
- 2 * intborder
1119 - s
->display
.x
->v_scrollbar_width
)
1120 / FONT_WIDTH (s
->display
.x
->font
));
1121 temp_height
= ((windowinfo
.height
- 2 * intborder
1122 - s
->display
.x
->h_scrollbar_height
)
1123 / FONT_HEIGHT (s
->display
.x
->font
));
1124 if (temp_width
!= s
->width
|| temp_height
!= s
->height
)
1126 change_screen_size (s
, max (1, temp_height
),
1127 max (1, temp_width
), 0);
1128 x_resize_scrollbars (s
);
1130 s
->display
.x
->left_pos
= windowinfo
.x
;
1131 s
->display
.x
->top_pos
= windowinfo
.y
;
1132 dumprectangle (s
, 0, 0, PIXEL_WIDTH (s
), PIXEL_HEIGHT (s
));
1136 s
->display
.x
->needs_exposure
= 0;
1137 if (updating_screen
!= s
)
1138 x_display_cursor (s
, 1);
1143 /* Handle any individual-rectangle expose events queued
1144 for various windows. */
1154 screen_highlight (screen
)
1155 struct screen
*screen
;
1157 if (! EQ (Vx_no_window_manager
, Qnil
))
1158 XSetWindowBorder (x_current_display
, screen
->display
.x
->window_desc
,
1159 screen
->display
.x
->border_pixel
);
1160 x_display_cursor (screen
, 1);
1164 screen_unhighlight (screen
)
1165 struct screen
*screen
;
1167 if (! EQ (Vx_no_window_manager
, Qnil
))
1168 XSetWindowBorderPixmap (x_current_display
, screen
->display
.x
->window_desc
,
1169 screen
->display
.x
->border_tile
);
1170 x_display_cursor (screen
, 1);
1173 /* Dump the border-emphasis of screen S.
1174 If S is selected, this is a lining of the same color as the border,
1175 just within the border, occupying a portion of the internal border.
1176 If S is not selected, it is background in the same place.
1177 If ALWAYS is 0, don't bother explicitly drawing if it's background.
1179 ALWAYS = 1 is used when a screen becomes selected or deselected.
1180 In that case, we also turn the cursor off and on again
1181 so it will appear in the proper shape (solid if selected; else hollow.) */
1184 dumpborder (s
, always
)
1188 int thickness
= s
->display
.x
->internal_border_width
/ 2;
1189 int width
= PIXEL_WIDTH (s
);
1190 int height
= PIXEL_HEIGHT (s
);
1193 if (s
!= selected_screen
)
1198 pixel
= s
->display
.x
->background_pixel
;
1202 pixel
= s
->display
.x
->border_pixel
;
1205 XPixSet (s
->display
.x
->window_desc
, 0, 0, width
, thickness
, pixel
);
1206 XPixSet (s
->display
.x
->window_desc
, 0, 0, thickness
, height
, pixel
);
1207 XPixSet (s
->display
.x
->window_desc
, 0, height
- thickness
, width
,
1209 XPixSet (s
->display
.x
->window_desc
, width
- thickness
, 0, thickness
,
1213 x_display_cursor (s
, 1);
1217 static void XTscreen_rehighlight ();
1219 /* The focus has changed. Update the screens as necessary to reflect
1220 the new situation. Note that we can't change the selected screen
1221 here, because the lisp code we are interrupting might become confused.
1222 Each event gets marked with the screen in which it occured, so the
1223 lisp code can tell when the switch took place by examining the events. */
1226 x_new_focus_screen (screen
)
1227 struct screen
*screen
;
1229 struct screen
*old_focus
= x_focus_screen
;
1230 int events_enqueued
= 0;
1232 if (screen
!= x_focus_screen
)
1234 /* Set this before calling other routines, so that they see
1235 the correct value of x_focus_screen. */
1236 x_focus_screen
= screen
;
1238 if (old_focus
&& old_focus
->auto_lower
)
1239 x_lower_screen (old_focus
);
1242 selected_screen
= screen
;
1243 XSET (XWINDOW (selected_screen
->selected_window
)->screen
,
1244 Lisp_Screen
, selected_screen
);
1245 Fselect_window (selected_screen
->selected_window
);
1246 choose_minibuf_screen ();
1249 if (x_focus_screen
&& x_focus_screen
->auto_raise
)
1250 x_raise_screen (x_focus_screen
);
1253 XTscreen_rehighlight ();
1257 /* The focus has changed, or we have make a screen's selected window
1258 point to a window on a different screen (this happens with global
1259 minibuffer screens). Shift the highlight as appropriate. */
1261 XTscreen_rehighlight ()
1263 struct screen
*old_highlight
= x_highlight_screen
;
1267 x_highlight_screen
= XSCREEN (SCREEN_FOCUS_SCREEN (x_focus_screen
));
1268 if (x_highlight_screen
->display
.nothing
== 0)
1269 XSET (SCREEN_FOCUS_SCREEN (x_focus_screen
), Lisp_Screen
,
1270 (x_highlight_screen
= x_focus_screen
));
1273 x_highlight_screen
= 0;
1275 if (x_highlight_screen
!= old_highlight
)
1278 screen_unhighlight (old_highlight
);
1279 if (x_highlight_screen
)
1280 screen_highlight (x_highlight_screen
);
1291 /* Symbol returned in input stream to indicate mouse movement. */
1292 Lisp_Object Qmouse_moved
;
1294 /* Position of the mouse in characters */
1295 unsigned int x_mouse_x
, x_mouse_y
;
1297 /* Emacs window the mouse is in, if any. */
1298 extern Lisp_Object Vmouse_window
;
1300 /* Offset in buffer of character under the pointer, or 0. */
1301 extern int mouse_buffer_offset
;
1303 /* Part of the screen the mouse is in. */
1304 extern Lisp_Object Vmouse_screen_part
;
1306 extern int buffer_posn_from_coords ();
1308 /* Symbols from xfns.c to denote the different parts of a window. */
1309 extern Lisp_Object Qmodeline_part
, Qtext_part
;
1312 /* Set *RESULT to an emacs input_event corresponding to MOTION_EVENT.
1313 S is the screen in which the event occurred.
1315 WINDOW_TYPE says whether the event happened in a scrollbar window
1316 or a text window, affecting the format of the event created.
1318 PART specifies which part of the scrollbar the event happened in,
1319 if WINDOW_TYPE == scrollbar_window.
1321 If the mouse is over the same character as the last time we checked,
1322 don't return an event; set result->kind to no_event. */
1325 notice_mouse_movement (result
, motion_event
, s
, window_type
, part
)
1326 struct input_event
*result
;
1327 XMotionEvent motion_event
;
1332 int x
, y
, root_x
, root_y
, pix_x
, pix_y
;
1333 unsigned int keys_and_buttons
;
1334 Window w
, root_window
;
1336 /* Unless we decide otherwise below, return a non-event. */
1337 result
->kind
= no_event
;
1339 if (XQueryPointer (x_current_display
,
1340 s
->display
.x
->window_desc
,
1342 &root_x
, &root_y
, &pix_x
, &pix_y
,
1348 if (w
== None
) /* Mouse no longer in window. */
1352 pixel_to_glyph_translation (s
, pix_x
, pix_y
, &x
, &y
);
1353 if (x
== x_mouse_x
&& y
== x_mouse_y
)
1359 /* What sort of window are we in now? */
1360 if (window_type
== text_window
) /* Text part */
1364 Vmouse_window
= window_from_coordinates (s
, x
, y
, &modeline_p
);
1366 if (XTYPE (Vmouse_window
) == Lisp_Window
)
1368 = buffer_posn_from_coords (XWINDOW (Vmouse_window
), x
, y
);
1370 mouse_buffer_offset
= 0;
1372 if (EQ (Vmouse_window
, Qnil
))
1373 Vmouse_screen_part
= Qnil
;
1374 else if (modeline_p
)
1375 Vmouse_screen_part
= Qmodeline_part
;
1377 Vmouse_screen_part
= Qtext_part
;
1379 result
->kind
= window_sys_event
;
1380 result
->code
= Qmouse_moved
;
1384 else if (window_type
== scrollbar_window
) /* Scrollbar */
1386 Vmouse_window
= s
->selected_window
;
1387 mouse_buffer_offset
= 0;
1388 Vmouse_screen_part
= part
;
1390 result
->kind
= window_sys_event
;
1391 result
->code
= Qmouse_moved
;
1401 /* Mouse clicks and mouse movement. Rah. */
1404 /* Given a pixel position (PIX_X, PIX_Y) on the screen S, return
1405 glyph co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle
1406 that the glyph at X, Y occupies, if BOUNDS != 0. */
1408 pixel_to_glyph_coords (s
, pix_x
, pix_y
, x
, y
, bounds
)
1410 register unsigned int pix_x
, pix_y
;
1411 register int *x
, *y
;
1414 int ibw
= s
->display
.x
->internal_border_width
;
1416 FONT_TYPE
*font
= s
->display
.x
->font
;
1418 width
= FONT_WIDTH (font
);
1419 height
= FONT_HEIGHT (font
);
1421 /* What line is it on? */
1424 else if (pix_y
> s
->display
.x
->pixel_height
- ibw
)
1425 *y
= SCREEN_HEIGHT (s
) - 1;
1427 *y
= (pix_y
- ibw
) / height
;
1429 /* And what column? */
1432 else if (pix_x
> s
->display
.x
->pixel_width
- ibw
)
1433 *x
= SCREEN_WIDTH (s
) - 1;
1435 *x
= (pix_x
- ibw
) / width
;
1439 bounds
->width
= width
;
1440 bounds
->height
= height
;
1441 bounds
->x
= ibw
+ (*x
* width
);
1442 bounds
->y
= ibw
+ (*y
* height
);
1446 /* Any buttons grabbed. */
1447 unsigned int x_mouse_grabbed
;
1449 /* Convert a set of X modifier bits to the proper form for a
1450 struct input_event modifiers value. */
1453 x_convert_modifiers (state
)
1456 return ( ((state
& (ShiftMask
| LockMask
)) ? shift_modifier
: 0)
1457 | ((state
& ControlMask
) ? ctrl_modifier
: 0)
1458 | ((state
& Mod1Mask
) ? meta_modifier
: 0));
1461 extern struct screen
*x_window_to_scrollbar ();
1462 extern Lisp_Object Vmouse_event
;
1464 /* Prepare a mouse-event in *RESULT for placement in the input queue.
1466 If the event is a button press, then note that we have grabbed
1469 If PART and PREFIX are 0, then the event occurred in the text part;
1470 otherwise it happened in a scrollbar. */
1473 construct_mouse_click (result
, event
, s
, part
, prefix
)
1474 struct input_event
*result
;
1475 XButtonEvent
*event
;
1480 /* Initialize those fields text and scrollbar clicks hold in common.
1481 Make the event type no_event; we'll change that when we decide
1483 result
->kind
= no_event
;
1484 XSET (result
->code
, Lisp_Int
, event
->button
);
1485 XSET (result
->timestamp
, Lisp_Int
, event
->time
);
1486 result
->modifiers
= (x_convert_modifiers (event
->state
)
1487 | (event
->type
== ButtonRelease
? up_modifier
: 0));
1488 XSET (result
->timestamp
, Lisp_Int
, (event
->time
& 0x7fffff));
1490 /* Notice if the mouse is still grabbed. */
1491 if (event
->type
== ButtonPress
)
1493 if (! x_mouse_grabbed
)
1494 Vmouse_depressed
= Qt
;
1495 x_mouse_grabbed
|= (1 << event
->button
);
1497 else if (event
->type
== ButtonRelease
)
1499 x_mouse_grabbed
&= ~(1 << event
->button
);
1500 if (!x_mouse_grabbed
)
1501 Vmouse_depressed
= Qnil
;
1504 if (part
) /* Scrollbar event */
1508 pos
= event
->y
- (s
->display
.x
->v_scrollbar_width
- 2);
1509 XSET (x_mouse_x
, Lisp_Int
, pos
);
1510 len
= ((FONT_HEIGHT (s
->display
.x
->font
) * s
->height
)
1511 + s
->display
.x
->internal_border_width
1512 - (2 * (s
->display
.x
->v_scrollbar_width
- 2)));
1513 XSET (x_mouse_y
, Lisp_Int
, len
);
1515 result
->kind
= scrollbar_click
;
1516 result
->part
= part
;
1517 XSET (result
->x
, Lisp_Int
, (s
->display
.x
->top_pos
- event
->y
));
1518 XSET (result
->y
, Lisp_Int
, s
->display
.x
->pixel_height
);
1521 else /* Text Window Event */
1525 pixel_to_glyph_coords (s
, event
->x
, event
->y
, &column
, &row
, NULL
);
1526 result
->kind
= mouse_click
;
1534 /* Mouse movement. Rah.
1536 In order to avoid asking for motion events and then throwing most
1537 of them away or busy-polling the server for mouse positions, we ask
1538 the server for pointer motion hints. This means that we get only
1539 one event per group of mouse movements. "Groups" are delimited by
1540 other kinds of events (focus changes and button clicks, for
1541 example), or by XQueryPointer calls; when one of these happens, we
1542 get another MotionNotify event the next time the mouse moves. This
1543 is at least as efficient than getting motion events when mouse
1544 tracking is on, and I suspect only negligibly worse when tracking
1547 The silly O'Reilly & Associates Nutshell guides barely document
1548 pointer motion hints at all (I think you have to infer how they
1549 work from an example), and the description of XQueryPointer doesn't
1550 mention that calling it causes you to get another motion hint from
1551 the server, which is very important. */
1553 /* Where the mouse was last time we reported a mouse event. */
1554 static SCREEN_PTR last_mouse_screen
;
1555 static XRectangle last_mouse_glyph
;
1557 /* Function to report a mouse movement to the mainstream Emacs code.
1558 The input handler calls this.
1560 We have received a mouse movement event, which is given in *event.
1561 If the mouse is over a different glyph than it was last time, tell
1562 the mainstream emacs code by setting mouse_moved. If not, ask for
1563 another motion event, so we can check again the next time it moves. */
1565 note_mouse_position (screen
, event
)
1567 XMotionEvent
*event
;
1570 /* Has the mouse moved off the glyph it was on at the last sighting? */
1571 if (event
->x
< last_mouse_glyph
.x
1572 || event
->x
>= last_mouse_glyph
.x
+ last_mouse_glyph
.width
1573 || event
->y
< last_mouse_glyph
.y
1574 || event
->y
>= last_mouse_glyph
.y
+ last_mouse_glyph
.height
)
1578 /* It's on the same glyph. Call XQueryPointer so we'll get an
1579 event the next time the mouse moves and we can see if it's
1580 *still* on the same glyph. */
1583 XQueryPointer (event
->display
, event
->window
,
1584 (Window
*) &dummy
, (Window
*) &dummy
,
1585 &dummy
, &dummy
, &dummy
, &dummy
,
1586 (unsigned int *) &dummy
);
1590 /* Return the current position of the mouse.
1592 This clears the mouse_moved flag, so we can wait for the next mouse
1593 position. This also calls XQueryPointer, which will cause the
1594 server to give us another MotionNotify when the mouse moves again.
1598 XTmouse_position (s
, x
, y
, time
)
1604 Display
*d
= x_current_display
;
1605 Window guess
, root
, child
;
1609 /* I would like to have an X function that just told me the
1610 innermost window containing the mouse.
1612 /* There doesn't seem to be any way to just get the innermost window
1613 containing the pointer, no matter what X screen it's on; you have
1614 to guess a window, and then X will tell you which one of that
1615 window's children it's in. If the pointer isn't in any of that
1616 window's children, it gives you a root window that contains it.
1618 So we start with the selected screen's window and chase down
1619 branches under the guidance of XQueryPointer until we hit a leaf
1620 (all of the Emacs windows we care about are leaf windows). If at
1621 any time XQueryPointer returns false, that means that the current
1622 window does not contain the pointer any more (perhaps it moved),
1623 so we start with the root window XQueryPointer has given us and
1626 guess
= selected_screen
->display
.x
->window_desc
;
1628 if (XQueryPointer (d
, guess
, &root
, &child
,
1629 &dummy
, &dummy
, &ix
, &iy
, (unsigned int *) &dummy
))
1632 /* Guess is a leaf window, and it contains the pointer. */
1638 /* When XQueryPointer returns False, the pointer isn't in guess
1639 anymore, but root is the root window of the screen we should
1643 *s
= last_mouse_screen
= x_window_to_screen (guess
);
1648 pixel_to_glyph_coords (*s
, ix
, iy
, &ix
, &iy
, &last_mouse_glyph
);
1649 XSET (*x
, Lisp_Int
, ix
);
1650 XSET (*y
, Lisp_Int
, iy
);
1655 /* I don't know how to find the time for the last movement; it seems
1656 like XQueryPointer ought to return it, but it doesn't. */
1663 static char *events
[] =
1703 #define XEvent XKeyPressedEvent
1704 #endif /* HAVE_X11 */
1706 /* Symbols returned in the input stream to indicate various X events. */
1707 Lisp_Object Qmouse_click
;
1708 Lisp_Object Qscrollbar_click
;
1710 /* Timestamp of enter window event. This is only used by XTread_socket,
1711 but we have to put it out here, since static variables within functions
1712 sometimes don't work. */
1713 static Time enter_timestamp
;
1715 /* Read events coming from the X server.
1716 This routine is called by the SIGIO handler.
1717 We return as soon as there are no more events to be read.
1719 Events representing keys are stored in buffer BUFP,
1720 which can hold up to NUMCHARS characters.
1721 We return the number of characters stored into the buffer,
1722 thus pretending to be `read'.
1724 WAITP is nonzero if we should block until input arrives.
1725 EXPECTED is nonzero if the caller knows input is available. */
1728 XTread_socket (sd
, bufp
, numchars
, waitp
, expected
)
1730 register struct input_event
*bufp
;
1731 register int numchars
;
1738 int items_pending
; /* How many items are in the X queue. */
1745 if (x_input_blocked
)
1747 x_pending_input
= 1;
1751 x_pending_input
= 0;
1755 abort (); /* Don't think this happens. */
1758 /* If available, Xlib uses FIOSNBIO to make the socket
1759 non-blocking, and then looks for EWOULDBLOCK. If O_NDELAY is set,
1760 FIOSNBIO is ignored, and instead of signalling EWOULDBLOCK,
1761 a read returns 0, which Xlib interprets as equivalent to EPIPE. */
1762 fcntl (fileno (stdin
), F_SETFL
, 0);
1767 if (! (fcntl (fileno (stdin
), F_GETFL
, 0) & O_NDELAY
))
1769 extern int read_alarm_should_throw
;
1770 read_alarm_should_throw
= 1;
1771 XPeekEvent (XDISPLAY
&event
);
1772 read_alarm_should_throw
= 0;
1777 while (XStuffPending () != 0)
1779 XNextEvent (XDISPLAY
&event
);
1786 case SelectionClear
: /* Someone has grabbed ownership. */
1787 x_disown_selection (event
.xselectionclear
.window
,
1788 event
.xselectionclear
.selection
,
1789 event
.xselectionclear
.time
);
1792 case SelectionRequest
: /* Someone wants our selection. */
1793 x_answer_selection_request (event
);
1796 case PropertyNotify
:
1797 /* If we were to do this synchronously, there'd be no worry
1798 about re-selecting. */
1799 x_send_incremental (event
);
1803 s
= x_window_to_screen (event
.xexpose
.window
);
1806 if (s
->visible
== 0)
1810 SET_SCREEN_GARBAGED (s
);
1813 dumprectangle (x_window_to_screen (event
.xexpose
.window
),
1814 event
.xexpose
.x
, event
.xexpose
.y
,
1815 event
.xexpose
.width
, event
.xexpose
.height
);
1819 case GraphicsExpose
: /* This occurs when an XCopyArea's
1820 source area was obscured or not
1822 dumprectangle (x_window_to_screen (event
.xgraphicsexpose
.drawable
),
1823 event
.xgraphicsexpose
.x
, event
.xgraphicsexpose
.y
,
1824 event
.xgraphicsexpose
.width
,
1825 event
.xgraphicsexpose
.height
);
1828 case NoExpose
: /* This occurs when an XCopyArea's
1829 source area was completely
1832 #else /* not HAVE_X11 */
1834 if (event
.subwindow
!= 0)
1835 break; /* duplicate event */
1836 s
= x_window_to_screen (event
.window
);
1837 if (event
.window
== s
->display
.x
->icon_desc
)
1842 if (event
.window
== s
->display
.x
->window_desc
)
1844 /* Say must check all windows' needs_exposure flags. */
1845 expose_all_windows
= 1;
1846 s
->display
.x
->needs_exposure
= 1;
1852 if (event
.subwindow
!= 0)
1853 break; /* duplicate event */
1854 s
= x_window_to_screen (event
.window
);
1855 if (event
.window
== s
->display
.x
->icon_desc
)
1860 /* If window already needs full redraw, ignore this rectangle. */
1861 if (expose_all_windows
&& s
->display
.x
->needs_exposure
)
1863 /* Put the event on the queue of rectangles to redraw. */
1864 if (enqueue_event (&event
, &x_expose_queue
))
1865 /* If it is full, we can't record the rectangle,
1866 so redraw this entire window. */
1868 /* Say must check all windows' needs_exposure flags. */
1869 expose_all_windows
= 1;
1870 s
->display
.x
->needs_exposure
= 1;
1875 /* This should happen only when we are expecting it,
1876 in x_read_exposes. */
1878 #endif /* not HAVE_X11 */
1885 s
= x_window_to_screen (event
.xunmap
.window
);
1886 if (s
) /* S may no longer exist if
1887 the screen was deleted. */
1889 /* While a screen is unmapped, display generation is
1890 disabled; you don't want to spend time updating a
1891 display that won't ever be seen. */
1893 Vmouse_window
= Vmouse_screen_part
= Qnil
;
1894 x_mouse_x
= x_mouse_y
= -1;
1900 s
= x_window_to_screen (event
.xmap
.window
);
1906 /* wait_reading_process_input will notice this and update
1907 the screen's display structures. */
1908 SET_SCREEN_GARBAGED (s
);
1912 /* Turn off processing if we become fully obscured. */
1913 case VisibilityNotify
:
1918 s
= x_window_to_screen (event
.window
);
1919 if (event
.window
== s
->display
.x
->icon_desc
)
1921 if (event
.window
== s
->display
.x
->window_desc
)
1924 #endif /* HAVE_X11 */
1928 s
= x_window_to_screen (event
.xkey
.window
);
1932 XComposeStatus status
;
1933 char copy_buffer
[80];
1935 /* This will have to go some day... */
1936 nbytes
= XLookupString (&event
.xkey
,
1942 /* Strip off the vendor-specific keysym bit, and take a shot
1943 at recognizing the codes. HP servers have extra keysyms
1944 that fit into the MiscFunctionKey category. */
1949 if (IsCursorKey (keysym
) /* 0xff50 <= x < 0xff60 */
1950 || IsMiscFunctionKey (keysym
) /* 0xff60 <= x < 0xff80 */
1951 || IsKeypadKey (keysym
) /* 0xff80 <= x < 0xffbe */
1952 || IsFunctionKey (keysym
)) /* 0xffbe <= x < 0xffe1 */
1954 bufp
->kind
= non_ascii_keystroke
;
1955 XSET (bufp
->code
, Lisp_Int
, (unsigned) keysym
- 0xff50);
1956 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
1957 bufp
->modifiers
= x_convert_modifiers (event
.xkey
.state
);
1958 XSET (bufp
->timestamp
, Lisp_Int
, event
.xkey
.time
);
1963 else if (numchars
> nbytes
)
1969 if (event
.xkey
.state
& Mod1Mask
)
1970 *copy_buffer
|= METABIT
;
1971 bufp
->kind
= ascii_keystroke
;
1972 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
1973 XSET (bufp
->code
, Lisp_Int
, *copy_buffer
);
1974 XSET (bufp
->timestamp
, Lisp_Int
, event
.xkey
.time
);
1978 for (i
= nbytes
- 1; i
> 1; i
--)
1980 bufp
->kind
= ascii_keystroke
;
1981 XSET (bufp
->code
, Lisp_Int
, copy_buffer
[i
]);
1982 XSET (bufp
->timestamp
, Lisp_Int
, event
.xkey
.time
);
1983 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
1996 register char *where_mapping
;
1998 s
= x_window_to_screen (event
.window
);
1999 /* Ignore keys typed on icon windows. */
2000 if (s
!= 0 && event
.window
== s
->display
.x
->icon_desc
)
2002 where_mapping
= XLookupMapping (&event
, &nbytes
);
2003 /* Nasty fix for arrow keys */
2004 if (!nbytes
&& IsCursorKey (event
.detail
& 0xff))
2006 switch (event
.detail
& 0xff)
2008 case KC_CURSOR_LEFT
:
2009 where_mapping
= "\002";
2011 case KC_CURSOR_RIGHT
:
2012 where_mapping
= "\006";
2015 where_mapping
= "\020";
2017 case KC_CURSOR_DOWN
:
2018 where_mapping
= "\016";
2023 if (numchars
- nbytes
> 0)
2027 for (i
= 0; i
< nbytes
; i
++)
2029 bufp
->kind
= ascii_keystroke
;
2030 XSET (bufp
->code
, Lisp_Int
, where_mapping
[i
]);
2031 XSET (bufp
->time
, Lisp_Int
, event
.xkey
.time
);
2032 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
2040 #endif /* HAVE_X11 */
2044 s
= x_window_to_screen (event
.xcrossing
.window
);
2046 if (event
.xcrossing
.detail
== NotifyInferior
) /* Left Scrollbar */
2048 else if (event
.xcrossing
.focus
) /* Entered Window */
2050 /* If we decide we want to generate an event to be seen
2051 by the rest of Emacs, we put it here. */
2052 struct input_event emacs_event
;
2053 emacs_event
.kind
= no_event
;
2055 /* Avoid nasty pop/raise loops. */
2056 if (s
&& (!(s
->auto_raise
)
2058 || (event
.xcrossing
.time
- enter_timestamp
) > 500))
2060 x_new_focus_screen (s
);
2061 enter_timestamp
= event
.xcrossing
.time
;
2064 else if ((s
= x_window_to_scrollbar (event
.xcrossing
.window
,
2066 /* Fake a motion event */
2067 notice_mouse_movement (&emacs_event
,
2068 event
.xmotion
, s
, scrollbar_window
,
2073 if (! EQ (Vx_send_mouse_movement_events
, Qnil
)
2075 && emacs_event
.kind
!= no_event
)
2077 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
2084 else if (s
== x_focus_screen
)
2085 x_new_focus_screen (0);
2087 else if (s
= x_window_to_screen (event
.xcrossing
.window
))
2094 s
= x_window_to_screen (event
.xfocus
.window
);
2096 x_new_focus_screen (s
);
2100 if (event
.xcrossing
.detail
!= NotifyInferior
2101 && event
.xcrossing
.subwindow
== None
2102 && event
.xcrossing
.mode
== NotifyNormal
)
2104 s
= x_window_to_screen (event
.xcrossing
.window
);
2105 if (event
.xcrossing
.focus
)
2106 x_new_focus_screen (s
);
2107 else if (s
== x_focus_screen
)
2108 x_new_focus_screen (0);
2113 s
= x_window_to_screen (event
.xfocus
.window
);
2114 if (s
&& s
== x_focus_screen
)
2115 x_new_focus_screen (0);
2118 #else /* not HAVE_X11 */
2121 if ((event
.detail
& 0xFF) == 1)
2122 break; /* Coming from our own subwindow */
2123 if (event
.subwindow
!= 0)
2124 break; /* Entering our own subwindow. */
2127 extern int waiting_for_input
;
2128 struct screen
*old_s
= x_input_screen
;
2130 s
= x_window_to_screen (event
.window
);
2133 if (waiting_for_input
&& x_focus_screen
== 0)
2134 x_new_focus_screen (s
);
2139 if ((event
.detail
& 0xFF) == 1)
2140 break; /* Entering our own subwindow */
2141 if (event
.subwindow
!= 0)
2142 break; /* Leaving our own subwindow. */
2145 if (x_focus_screen
== 0
2146 && x_input_screen
!= 0
2147 && x_input_screen
== x_window_to_screen (event
.window
)
2148 && event
.window
== x_input_screen
->display
.x
->window_desc
)
2153 screen_unhighlight (s
);
2156 #endif /* not HAVE_X11 */
2161 s
= x_window_to_screen (event
.xmotion
.window
);
2163 note_mouse_position (s
, &event
.xmotion
);
2165 else if ((s
= x_window_to_scrollbar (event
.xmotion
.window
,
2168 What should go here
?
2174 case ConfigureNotify
:
2177 s
= x_window_to_screen (event
.xconfigure
.window
);
2181 columns
= ((event
.xconfigure
.width
-
2182 (2 * s
->display
.x
->internal_border_width
)
2183 - s
->display
.x
->v_scrollbar_width
)
2184 / FONT_WIDTH (s
->display
.x
->font
));
2185 rows
= ((event
.xconfigure
.height
-
2186 (2 * s
->display
.x
->internal_border_width
)
2187 - s
->display
.x
->h_scrollbar_height
)
2188 / FONT_HEIGHT (s
->display
.x
->font
));
2190 /* Even if the number of character rows and columns has
2191 not changed, the font size may have changed, so we need
2192 to check the pixel dimensions as well. */
2193 if (columns
!= s
->width
2194 || rows
!= s
->height
2195 || event
.xconfigure
.width
!= s
->display
.x
->pixel_width
2196 || event
.xconfigure
.height
!= s
->display
.x
->pixel_height
)
2198 change_screen_size (s
, rows
, columns
, 0);
2199 x_resize_scrollbars (s
);
2200 SET_SCREEN_GARBAGED (s
);
2203 s
->display
.x
->pixel_width
= event
.xconfigure
.width
;
2204 s
->display
.x
->pixel_height
= event
.xconfigure
.height
;
2205 s
->display
.x
->left_pos
= event
.xconfigure
.x
;
2206 s
->display
.x
->top_pos
= event
.xconfigure
.y
;
2213 /* If we decide we want to generate an event to be seen
2214 by the rest of Emacs, we put it here. */
2215 struct input_event emacs_event
;
2216 emacs_event
.kind
= no_event
;
2218 s
= x_window_to_screen (event
.xbutton
.window
);
2220 if (!x_focus_screen
|| (s
== x_focus_screen
))
2221 construct_mouse_click (&emacs_event
,
2226 if ((s
= x_window_to_scrollbar (event
.xbutton
.window
,
2229 if (!x_focus_screen
|| (selected_screen
== x_focus_screen
))
2230 construct_mouse_click (&emacs_event
,
2231 &event
, s
, part
, prefix
);
2236 if (numchars
>= 1 && emacs_event
.kind
!= no_event
)
2238 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
2246 #else /* not HAVE_X11 */
2248 case ButtonReleased
:
2249 s
= x_window_to_screen (event
.window
);
2252 if (event
.window
== s
->display
.x
->icon_desc
)
2254 x_make_screen_visible (s
);
2256 if (warp_mouse_on_deiconify
)
2257 XWarpMouse (s
->display
.x
->window_desc
, 10, 10);
2260 if (event
.window
== s
->display
.x
->window_desc
)
2266 enqueue_event (&event
, &x_mouse_queue
);
2269 bufp
->kind
= ascii_keystroke
;
2270 bufp
->code
= (char) 'X' & 037; /* C-x */
2271 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
2272 XSET (bufp
->time
, Lisp_Int
, event
.xkey
.time
);
2275 bufp
->kind
= ascii_keystroke
;
2276 bufp
->code
= (char) 0; /* C-@ */
2277 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
2278 XSET (bufp
->time
, Lisp_Int
, event
.xkey
.time
);
2285 #endif /* not HAVE_X11 */
2289 case CirculateNotify
:
2291 case CirculateRequest
:
2294 #endif /* HAVE_X11 */
2297 if (event
.xmapping
.request
== MappingKeyboard
)
2298 /* Someone has changed the keyboard mapping - flush the
2300 XRefreshKeyboardMapping (&event
.xmapping
);
2310 if (expected
&& ! event_found
)
2312 /* AOJ 880406: if select returns true but XPending doesn't, it means that
2313 there is an EOF condition; in other words, that X has died.
2314 Act as if there had been a hangup. */
2316 int fd
= ConnectionNumber (x_current_display
);
2319 if (0 != select (fd
+ 1, &mask
, (long *) 0, (long *) 0,
2320 (struct timeval
*) 0)
2321 && !XStuffPending ())
2322 kill (getpid (), SIGHUP
);
2324 #endif /* HAVE_SELECT */
2327 if (updating_screen
== 0)
2328 x_do_pending_expose ();
2335 /* Read and process only Expose events
2336 until we get an ExposeCopy event; then return.
2337 This is used in insert/delete line.
2338 We assume input is already blocked. */
2344 XKeyPressedEvent event
;
2348 /* while there are more events*/
2349 XMaskEvent (ExposeWindow
| ExposeRegion
| ExposeCopy
, &event
);
2353 if (event
.subwindow
!= 0)
2354 break; /* duplicate event */
2355 s
= x_window_to_screen (event
.window
);
2356 if (event
.window
== s
->display
.x
->icon_desc
)
2361 if (event
.window
== s
->display
.x
->window_desc
)
2363 expose_all_windows
= 1;
2364 s
->display
.x
->needs_exposure
= 1;
2370 if (event
.subwindow
!= 0)
2371 break; /* duplicate event */
2372 s
= x_window_to_screen (event
.window
);
2373 if (event
.window
== s
->display
.x
->icon_desc
)
2378 /* If window already needs full redraw, ignore this rectangle. */
2379 if (expose_all_windows
&& s
->display
.x
->needs_exposure
)
2381 /* Put the event on the queue of rectangles to redraw. */
2382 if (enqueue_event (&event
, &x_expose_queue
))
2383 /* If it is full, we can't record the rectangle,
2384 so redraw this entire window. */
2386 /* Say must check all windows' needs_exposure flags. */
2387 expose_all_windows
= 1;
2388 s
->display
.x
->needs_exposure
= 1;
2397 #endif /* HAVE_X11 */
2400 /* Draw a hollow box cursor. Don't change the inside of the box. */
2406 int left
= s
->cursor_x
* FONT_WIDTH (s
->display
.x
->font
)
2407 + s
->display
.x
->internal_border_width
;
2408 int top
= s
->cursor_y
* FONT_HEIGHT (s
->display
.x
->font
)
2409 + s
->display
.x
->internal_border_width
;
2410 int width
= FONT_WIDTH (s
->display
.x
->font
);
2411 int height
= FONT_HEIGHT (s
->display
.x
->font
);
2414 /* Perhaps we should subtract 1 from width and height... */
2415 XDrawRectangle (x_current_display
, s
->display
.x
->window_desc
,
2416 s
->display
.x
->cursor_gc
,
2417 left
, top
, width
- 1, height
- 1);
2419 XPixSet (s
->display
.x
->window_desc
,
2420 left
, top
, width
, 1,
2421 s
->display
.x
->cursor_pixel
);
2423 XPixSet (s
->display
.x
->window_desc
,
2424 left
, top
, 1, height
,
2425 s
->display
.x
->cursor_pixel
);
2427 XPixSet (s
->display
.x
->window_desc
,
2428 left
+width
-1, top
, 1, height
,
2429 s
->display
.x
->cursor_pixel
);
2431 XPixSet (s
->display
.x
->window_desc
,
2432 left
, top
+height
-1, width
, 1,
2433 s
->display
.x
->cursor_pixel
);
2434 #endif /* HAVE_X11 */
2437 /* Clear the cursor of screen S to background color,
2438 and mark the cursor as not shown.
2439 This is used when the text where the cursor is
2440 is about to be rewritten. */
2449 || s
->phys_cursor_x
< 0)
2453 x_display_cursor (s
, 0);
2455 XClearArea (x_current_display
, s
->display
.x
->window_desc
,
2456 s
->phys_cursor_x
* FONT_WIDTH (s
->display
.x
->font
)
2457 + s
->display
.x
->internal_border_width
,
2458 s
->phys_cursor_y
* FONT_HEIGHT (s
->display
.x
->font
)
2459 + s
->display
.x
->internal_border_width
,
2460 FONT_WIDTH (s
->display
.x
->font
) + 1, FONT_HEIGHT (s
->display
.x
->font
) + 1, False
);
2463 XPixSet (s
->display
.x
->window_desc
,
2464 s
->phys_cursor_x
* FONT_WIDTH (s
->display
.x
->font
) + s
->display
.x
->internal_border_width
,
2465 s
->phys_cursor_y
* FONT_HEIGHT (s
->display
.x
->font
) + s
->display
.x
->internal_border_width
,
2466 FONT_WIDTH (s
->display
.x
->font
), FONT_HEIGHT (s
->display
.x
->font
),
2467 s
->display
.x
->background_pixel
);
2468 #endif /* HAVE_X11 */
2469 s
->phys_cursor_x
= -1;
2473 x_display_bar_cursor (s
, on
)
2477 register int phys_x
= s
->phys_cursor_x
;
2478 register int phys_y
= s
->phys_cursor_y
;
2483 if (! s
->visible
|| (! on
&& s
->phys_cursor_x
< 0))
2488 (!on
|| phys_x
!= s
->cursor_x
|| phys_y
!= s
->cursor_y
))
2490 x1
= phys_x
* FONT_WIDTH (s
->display
.x
->font
)
2491 + s
->display
.x
->internal_border_width
;
2492 y1
= phys_y
* FONT_HEIGHT (s
->display
.x
->font
)
2493 + s
->display
.x
->internal_border_width
- 1;
2494 y2
= y1
+ FONT_HEIGHT (s
->display
.x
->font
) + 1;
2496 XDrawLine (x_current_display
, s
->display
.x
->window_desc
,
2497 s
->display
.x
->reverse_gc
, x1
, y1
, x1
, y2
);
2499 s
->phys_cursor_x
= phys_x
= -1;
2502 if (on
&& s
== x_highlight_screen
)
2504 x1
= s
->cursor_x
* FONT_WIDTH (s
->display
.x
->font
)
2505 + s
->display
.x
->internal_border_width
;
2506 y1
= s
->cursor_y
* FONT_HEIGHT (s
->display
.x
->font
)
2507 + s
->display
.x
->internal_border_width
- 1;
2508 y2
= y1
+ FONT_HEIGHT (s
->display
.x
->font
) + 1;
2510 XDrawLine (x_current_display
, s
->display
.x
->window_desc
,
2511 s
->display
.x
->cursor_gc
, x1
, y1
, x1
, y2
);
2513 s
->phys_cursor_x
= s
->cursor_x
;
2514 s
->phys_cursor_y
= s
->cursor_y
;
2522 /* Redraw the glyph at ROW, COLUMN on screen S, in the style
2523 HIGHLIGHT. HIGHLIGHT is as defined for dumpglyphs. Return the
2527 x_draw_single_glyph (s
, row
, column
, glyph
, highlight
)
2534 (column
* FONT_WIDTH (s
->display
.x
->font
)
2535 + s
->display
.x
->internal_border_width
),
2536 (row
* FONT_HEIGHT (s
->display
.x
->font
)
2537 + s
->display
.x
->internal_border_width
),
2538 &glyph
, 1, highlight
, s
->display
.x
->font
);
2541 /* Turn the displayed cursor of screen S on or off according to ON.
2542 If ON is nonzero, where to put the cursor is specified
2543 by S->cursor_x and S->cursor_y. */
2546 x_display_box_cursor (s
, on
)
2550 struct screen_glyphs
*current_glyphs
= SCREEN_CURRENT_GLYPHS (s
);
2555 /* If cursor is off and we want it off, return quickly. */
2556 if (!on
&& s
->phys_cursor_x
< 0)
2559 /* If cursor is currently being shown and we don't want it to be
2560 or it is in the wrong place,
2561 or we want a hollow box and it's not so, (pout!)
2563 if (s
->phys_cursor_x
>= 0
2565 || s
->phys_cursor_x
!= s
->cursor_x
2566 || s
->phys_cursor_y
!= s
->cursor_y
2567 || (s
->display
.x
->text_cursor_kind
!= hollow_box_cursor
2568 && (s
!= x_highlight_screen
))))
2570 /* Erase the cursor by redrawing the character underneath it. */
2571 x_draw_single_glyph (s
, s
->phys_cursor_y
, s
->phys_cursor_x
,
2572 s
->phys_cursor_glyph
,
2573 current_glyphs
->highlight
[s
->phys_cursor_y
]);
2574 s
->phys_cursor_x
= -1;
2577 /* If we want to show a cursor,
2578 or we want a box cursor and it's not so,
2579 write it in the right place. */
2581 && (s
->phys_cursor_x
< 0
2582 || (s
->display
.x
->text_cursor_kind
!= filled_box_cursor
2583 && s
== x_highlight_screen
)))
2585 s
->phys_cursor_glyph
2586 = ((current_glyphs
->enable
[s
->cursor_y
]
2587 && s
->cursor_x
< current_glyphs
->used
[s
->cursor_y
])
2588 ? current_glyphs
->glyphs
[s
->cursor_y
][s
->cursor_x
]
2590 if (s
!= x_highlight_screen
)
2593 s
->display
.x
->text_cursor_kind
= hollow_box_cursor
;
2597 x_draw_single_glyph (s
, s
->cursor_y
, s
->cursor_x
,
2598 s
->phys_cursor_glyph
, 2);
2599 s
->display
.x
->text_cursor_kind
= filled_box_cursor
;
2602 s
->phys_cursor_x
= s
->cursor_x
;
2603 s
->phys_cursor_y
= s
->cursor_y
;
2606 if (updating_screen
!= s
)
2610 extern Lisp_Object Vbar_cursor
;
2612 x_display_cursor (s
, on
)
2616 if (EQ (Vbar_cursor
, Qnil
))
2617 x_display_box_cursor (s
, on
);
2619 x_display_bar_cursor (s
, on
);
2624 /* Refresh bitmap kitchen sink icon for screen S
2625 when we get an expose event for it. */
2631 /* Normally, the window manager handles this function. */
2635 if (s
->display
.x
->icon_bitmap_flag
)
2636 XBitmapBitsPut (s
->display
.x
->icon_desc
, 0, 0, sink_width
, sink_height
,
2637 sink_bits
, BlackPixel
, WHITE_PIX_DEFAULT
,
2638 icon_bitmap
, GXcopy
, AllPlanes
);
2641 extern struct screen
*selected_screen
;
2642 struct Lisp_String
*str
;
2643 unsigned char *string
;
2646 = XSTRING (XBUFFER (XWINDOW (s
->selected_window
)->buffer
)->name
)->data
;
2648 if (s
->display
.x
->icon_label
!= string
)
2650 s
->display
.x
->icon_label
= string
;
2651 XChangeWindow (s
->display
.x
->icon_desc
,
2652 XQueryWidth (string
, icon_font_info
->id
) + 10,
2653 icon_font_info
->height
+ 10);
2656 XText (s
->display
.x
->icon_desc
, 5, 5, string
,
2657 str
->size
, icon_font_info
->id
,
2658 BLACK_PIX_DEFAULT
, WHITE_PIX_DEFAULT
);
2661 #endif /* HAVE_X11 */
2664 /* Make the x-window of screen S use the kitchen-sink icon
2665 that's a window generated by Emacs. */
2674 if (s
->display
.x
->window_desc
== 0)
2679 XFreePixmap (x_current_display
, icon_bitmap
);
2682 XCreateBitmapFromData (x_current_display
, s
->display
.x
->window_desc
,
2683 gnu_bits
, gnu_width
, gnu_height
);
2684 x_wm_set_icon_pixmap (s
, icon_bitmap
);
2685 s
->display
.x
->icon_bitmap_flag
= 1;
2687 if (s
->display
.x
->icon_desc
)
2689 XClearIconWindow (s
->display
.x
->window_desc
);
2690 XDestroyWindow (s
->display
.x
->icon_desc
);
2693 icon_window
= XCreateWindow (s
->display
.x
->parent_desc
,
2694 0, 0, sink_width
, sink_height
,
2695 2, WhitePixmap
, (Pixmap
) NULL
);
2697 if (icon_window
== 0)
2700 XSetIconWindow (s
->display
.x
->window_desc
, icon_window
);
2701 XSelectInput (icon_window
, ExposeWindow
| UnmapWindow
);
2703 s
->display
.x
->icon_desc
= icon_window
;
2704 s
->display
.x
->icon_bitmap_flag
= 1;
2706 if (icon_bitmap
== 0)
2708 = XStoreBitmap (sink_mask_width
, sink_mask_height
, sink_mask_bits
);
2709 #endif /* HAVE_X11 */
2715 /* Make the x-window of screen S use a rectangle with text. */
2718 x_text_icon (s
, icon_name
)
2726 char *X_DefaultValue
;
2730 #define WhitePixel 1
2734 #define BlackPixel 0
2736 #endif /* not HAVE_X11 */
2738 if (s
->display
.x
->window_desc
== 0)
2741 if (icon_font_info
== 0)
2743 = XGetFont (XGetDefault (XDISPLAY
2744 (char *) XSTRING (invocation_name
)->data
,
2749 s
->display
.x
->icon_label
= icon_name
;
2751 if (! s
->display
.x
->icon_label
)
2752 s
->display
.x
->icon_label
= " *emacs* ";
2754 XSetIconName (x_current_display
, s
->display
.x
->window_desc
,
2755 (char *) s
->display
.x
->icon_label
);
2757 s
->display
.x
->icon_bitmap_flag
= 0;
2759 if (s
->display
.x
->icon_desc
)
2761 XClearIconWindow (XDISPLAY s
->display
.x
->window_desc
);
2762 XDestroyWindow (XDISPLAY s
->display
.x
->icon_desc
);
2766 s
->display
.x
->icon_label
= (unsigned char *) icon_name
;
2768 if (! s
->display
.x
->icon_label
)
2769 s
->display
.x
->icon_label
= XSTRING (s
->name
)->data
;
2771 width
= XStringWidth (s
->display
.x
->icon_label
, icon_font_info
, 0, 0);
2772 icon_window
= XCreateWindow (s
->display
.x
->parent_desc
,
2773 s
->display
.x
->left_pos
,
2774 s
->display
.x
->top_pos
,
2775 width
+ 10, icon_font_info
->height
+ 10,
2776 2, BlackPixmap
, WhitePixmap
);
2778 if (icon_window
== 0)
2781 XSetIconWindow (s
->display
.x
->window_desc
, icon_window
);
2782 XSelectInput (icon_window
, ExposeWindow
| ExposeRegion
| UnmapWindow
| ButtonPressed
);
2784 s
->display
.x
->icon_desc
= icon_window
;
2785 s
->display
.x
->icon_bitmap_flag
= 0;
2786 s
->display
.x
->icon_label
= 0;
2787 #endif /* HAVE_X11 */
2792 static char *x_proto_requests
[] =
2795 "ChangeWindowAttributes",
2796 "GetWindowAttributes",
2798 "DestroySubwindows",
2815 "SetSelectionOwner",
2816 "GetSelectionOwner",
2823 "ChangeActivePointerGrab",
2843 "ListFontsWithInfo",
2852 "SetClipRectangles",
2863 "PolyFillRectangle",
2873 "CopyColormapAndFree",
2875 "UninstallColormap",
2876 "ListInstalledColormaps",
2887 "CreateGlyphCursor",
2893 "ChangeKeyboardMapping",
2894 "GetKeyboardMapping",
2895 "ChangeKeyboardControl",
2896 "GetKeyboardControl",
2898 "ChangePointerControl",
2899 "GetPointerControl",
2909 "SetPointerMapping",
2910 "GetPointerMapping",
2911 "SetModifierMapping",
2912 "GetModifierMapping",
2916 #define acceptable_x_error_p(type) ((type) == 94)
2918 x_handle_error_gracefully (event
)
2921 char error_ptr
[128];
2922 char *proto_ptr
= x_proto_requests
[event
->request_code
];
2925 XGetErrorText (x_current_display
, event
->error_code
, error_ptr
, 128);
2926 sprintf (str
, "X Protocol Error: %s on request: %s", error_ptr
, proto_ptr
);
2927 TOTALLY_UNBLOCK_INPUT
;
2932 extern int x_selection_alloc_error
;
2933 extern int x_converting_selection
;
2936 /* Handle X Errors. If the error is not traumatic,
2937 just call error (). Otherwise print a (hopefully) interesting
2940 The arg to Fkill_emacs is an exit status value
2941 and also prevents any questions. */
2943 x_error_handler (disp
, event
)
2948 #define XlibDisplayIOError (1L << 0)
2951 struct _XErrorEvent
*event
;
2954 /* Here we use the standard X handlers. */
2957 if (event
&& event
->type
== 0) /* 0 is the XError Event type. */
2961 if (event
->request_code
== BadAlloc
&& x_converting_selection
)
2962 x_selection_alloc_error
= 1;
2966 if (acceptable_x_error_p (event
->request_code
))
2967 x_handle_error_gracefully (event
);
2969 _XDefaultError (disp
, event
);
2973 disp
->flags
|= XlibDisplayIOError
;
2974 _XDefaultIOError (disp
);
2981 Fkill_emacs (make_number (70));
2984 /* Initialize communication with the X window server. */
2987 static unsigned int x_wire_count
;
2990 fprintf (stderr
, "Lib call: %d\n", ++x_wire_count
);
2995 /* Set the font of the x-window specified by screen S
2996 to the font named NEWNAME. This is safe to use
2997 even before S has an actual x-window. */
3001 /* A table of all the fonts we have already loaded. */
3002 static XFontStruct
**x_font_table
;
3004 /* The current capacity of x_font_table. */
3005 static int x_font_table_size
;
3007 /* The number of fonts actually stored in x_font_table.
3008 x_font_table[n] is used and valid iff 0 <= n < n_fonts.
3009 0 <= n_fonts <= x_font_table_size. */
3012 x_new_font (s
, fontname
)
3014 register char *fontname
;
3018 int n_matching_fonts
;
3019 XFontStruct
*font_info
;
3022 /* Get a list of all the fonts that match this name. Once we
3023 have a list of matching fonts, we compare them against the fonts
3024 we already have by comparing font ids. */
3025 font_names
= (char **) XListFontsWithInfo (x_current_display
, fontname
,
3026 1024, &n_matching_fonts
,
3028 /* If the server couldn't find any fonts whose named matched fontname,
3029 return an error code. */
3030 if (n_matching_fonts
== 0)
3033 /* See if we've already loaded a matching font. */
3038 for (i
= 0; i
< n_fonts
; i
++)
3039 for (j
= 0; j
< n_matching_fonts
; j
++)
3040 if (x_font_table
[i
]->fid
== font_info
[j
].fid
)
3048 /* If we have, just return it from the table. */
3050 s
->display
.x
->font
= x_font_table
[already_loaded
];
3052 /* Otherwise, load the font and add it to the table. */
3057 font
= (XFontStruct
*) XLoadQueryFont (x_current_display
, fontname
);
3061 /* Do we need to create the table? */
3062 if (x_font_table_size
== 0)
3064 x_font_table_size
= 16;
3066 = (XFontStruct
**) xmalloc (x_font_table_size
3067 * sizeof (x_font_table
[0]));
3069 /* Do we need to grow the table? */
3070 else if (n_fonts
>= x_font_table_size
)
3072 x_font_table_size
*= 2;
3074 = (XFontStruct
**) xrealloc (x_font_table
,
3076 * sizeof (x_font_table
[0])));
3079 s
->display
.x
->font
= x_font_table
[n_fonts
++] = font
;
3082 /* Free the information from XListFontsWithInfo. The data
3083 we actually retain comes from XLoadQueryFont. */
3084 XFreeFontInfo (font_names
, font_info
, n_matching_fonts
);
3086 /* Now make the screen display the given font. */
3087 if (s
->display
.x
->window_desc
!= 0)
3089 XSetFont (x_current_display
, s
->display
.x
->normal_gc
,
3090 s
->display
.x
->font
->fid
);
3091 XSetFont (x_current_display
, s
->display
.x
->reverse_gc
,
3092 s
->display
.x
->font
->fid
);
3093 XSetFont (x_current_display
, s
->display
.x
->cursor_gc
,
3094 s
->display
.x
->font
->fid
);
3096 x_set_window_size (s
, s
->width
, s
->height
);
3102 x_new_font (s
, newname
)
3104 register char *newname
;
3109 temp
= XGetFont (newname
);
3110 if (temp
== (FONT_TYPE
*) 0)
3113 if (s
->display
.x
->font
)
3114 XLoseFont (s
->display
.x
->font
);
3116 s
->display
.x
->font
= temp
;
3118 if (s
->display
.x
->window_desc
!= 0)
3119 x_set_window_size (s
, s
->width
, s
->height
);
3125 x_calc_absolute_position (s
)
3129 if (s
->display
.x
->left_pos
< 0)
3130 s
->display
.x
->left_pos
3131 = XINT (x_screen_width
) - PIXEL_WIDTH (s
) + s
->display
.x
->left_pos
;
3133 if (s
->display
.x
->top_pos
< 0)
3134 s
->display
.x
->top_pos
3135 = XINT (x_screen_height
) - PIXEL_HEIGHT (s
) + s
->display
.x
->top_pos
;
3137 WINDOWINFO_TYPE parentinfo
;
3139 XGetWindowInfo (s
->display
.x
->window_desc
, &parentinfo
);
3141 if (s
->display
.x
->left_pos
< 0)
3142 s
->display
.x
->left_pos
= parentinfo
.width
+ (s
->display
.x
->left_pos
+ 1)
3143 - PIXEL_WIDTH (s
) - 2 * s
->display
.x
->internal_border_width
;
3145 if (s
->display
.x
->top_pos
< 0)
3146 s
->display
.x
->top_pos
= parentinfo
.height
+ (s
->display
.x
->top_pos
+ 1)
3147 - PIXEL_HEIGHT (s
) - 2 * s
->display
.x
->internal_border_width
;
3151 x_set_offset (s
, xoff
, yoff
)
3153 register int xoff
, yoff
;
3155 s
->display
.x
->top_pos
= yoff
;
3156 s
->display
.x
->left_pos
= xoff
;
3157 x_calc_absolute_position (s
);
3160 XMoveWindow (XDISPLAY s
->display
.x
->window_desc
,
3161 s
->display
.x
->left_pos
, s
->display
.x
->top_pos
);
3163 x_wm_set_size_hint (s
, 0);
3168 /* Call this to change the size of screen S's x-window. */
3170 x_set_window_size (s
, cols
, rows
)
3172 register int cols
, rows
;
3174 int pixelwidth
, pixelheight
;
3176 int ibw
= s
->display
.x
->internal_border_width
;
3180 /* ??? Who DOES worry about minimum reasonable sizes? */
3181 pixelwidth
= (cols
* FONT_WIDTH (s
->display
.x
->font
) + 2 * ibw
3182 + s
->display
.x
->v_scrollbar_width
);
3183 pixelheight
= (rows
* FONT_HEIGHT (s
->display
.x
->font
) + 2 * ibw
3184 + s
->display
.x
->h_scrollbar_height
);
3187 x_wm_set_size_hint (s
, 0);
3188 #endif /* HAVE_X11 */
3189 XChangeWindowSize (s
->display
.x
->window_desc
, pixelwidth
, pixelheight
);
3195 x_set_resize_hint (s
)
3199 XSetResizeHint (s
->display
.x
->window_desc
, 2 * s
->display
.x
->internal_border_width
,
3200 2 * s
->display
.x
->internal_border_width
,
3201 FONT_WIDTH (s
->display
.x
->font
), FONT_HEIGHT (s
->display
.x
->font
));
3203 #endif /* not HAVE_X11 */
3206 x_set_mouse_position (s
, x
, y
)
3215 pix_x
= (SCREEN_WIDTH (s
)
3216 * FONT_WIDTH (s
->display
.x
->font
)
3217 + 2 * s
->display
.x
->internal_border_width
3218 + s
->display
.x
->v_scrollbar_width
) / 2;
3220 pix_x
= x
* FONT_WIDTH (s
->display
.x
->font
) + 2; /* add 2 pixels to each
3221 dimension to move the
3226 pix_y
= (SCREEN_HEIGHT (s
)
3227 * FONT_HEIGHT (s
->display
.x
->font
)
3228 + 2 * s
->display
.x
->internal_border_width
3229 + s
->display
.x
->h_scrollbar_height
) / 2;
3231 pix_y
= y
* FONT_HEIGHT (s
->display
.x
->font
) + 2;
3237 XWarpMousePointer (s
->display
.x
->window_desc
, pix_x
, pix_y
);
3242 x_focus_on_screen (s
)
3247 /* I don't think that the ICCCM allows programs to do things like this
3248 without the interaction of the window manager. Whatever you end up
3249 doing with this code, do it to x_unfocus_screen too. */
3250 XSetInputFocus (x_current_display
, s
->display
.x
->window_desc
,
3251 RevertToPointerRoot
, CurrentTime
);
3255 x_unfocus_screen (s
)
3259 /* Look at the remarks in x_focus_on_screen. */
3260 if (x_focus_screen
== s
)
3261 XSetInputFocus (x_current_display
, PointerRoot
,
3262 RevertToPointerRoot
, CurrentTime
);
3268 /* Raise screen S. */
3276 XRaiseWindow (XDISPLAY s
->display
.x
->window_desc
);
3282 /* Lower screen S. */
3290 XLowerWindow (XDISPLAY s
->display
.x
->window_desc
);
3296 /* Change from withdrawn state to mapped state. */
3298 x_make_screen_visible (s
)
3305 if (! SCREEN_VISIBLE_P (s
))
3308 if (! EQ (Vx_no_window_manager
, Qt
))
3309 x_wm_set_window_state (s
, NormalState
);
3311 XMapWindow (XDISPLAY s
->display
.x
->window_desc
);
3312 if (s
->display
.x
->v_scrollbar
!= 0 || s
->display
.x
->h_scrollbar
!= 0)
3313 XMapSubwindows (x_current_display
, s
->display
.x
->window_desc
);
3315 XMapWindow (XDISPLAY s
->display
.x
->window_desc
);
3316 if (s
->display
.x
->icon_desc
!= 0)
3317 XUnmapWindow (s
->display
.x
->icon_desc
);
3319 /* Handled by the MapNotify event for X11 */
3323 /* NOTE: this may cause problems for the first screen. */
3325 #endif /* not HAVE_X11 */
3328 XRaiseWindow (XDISPLAY s
->display
.x
->window_desc
);
3334 /* Change from mapped state to withdrawn state. */
3336 x_make_screen_invisible (s
)
3347 if (! EQ (Vx_no_window_manager
, Qt
))
3351 unmap
.type
= UnmapNotify
;
3352 unmap
.window
= s
->display
.x
->window_desc
;
3353 unmap
.event
= DefaultRootWindow (x_current_display
);
3354 unmap
.from_configure
= False
;
3355 XSendEvent (x_current_display
, DefaultRootWindow (x_current_display
),
3356 False
, SubstructureRedirectMask
|SubstructureNotifyMask
,
3360 /* The new function below does the same as the above code, plus unmapping
3361 the window. Sending the event without actually unmapping can make
3362 the window manager start ignoring the window (i.e., no more title bar,
3363 icon manager stuff.) */
3366 /* New function available with R4 */
3367 if (! XWithdrawWindow (x_current_display
, s
->display
.x
->window_desc
,
3368 DefaultScreen (x_current_display
)))
3370 UNBLOCK_INPUT_RESIGNAL
;
3371 error ("Can't notify window manager of iconification.");
3375 XUnmapWindow (XDISPLAY s
->display
.x
->window_desc
);
3377 s
->visible
= 0; /* Handled by the UnMap event for X11 */
3378 if (s
->display
.x
->icon_desc
!= 0)
3379 XUnmapWindow (XDISPLAY s
->display
.x
->icon_desc
);
3380 #endif /* not HAVE_X11 */
3386 /* Window manager communication. Created in Fx_open_connection. */
3387 extern Atom Xatom_wm_change_state
;
3389 /* Change window state from mapped to iconified. */
3391 x_iconify_screen (s
)
3402 if (! EQ (Vx_no_window_manager
, Qt
))
3403 if (! XIconifyWindow (x_current_display
, s
->display
.x
->window_desc
,
3404 DefaultScreen (x_current_display
)))
3406 UNBLOCK_INPUT_RESIGNAL
;
3407 error ("Can't notify window manager of iconification.");
3414 XClientMessageEvent message
;
3416 message
.window
= s
->display
.x
->window_desc
;
3417 message
.type
= ClientMessage
;
3418 message
.message_type
= Xatom_wm_change_state
;
3419 message
.format
= 32;
3420 message
.data
.l
[0] = IconicState
;
3422 if (! XSendEvent (x_current_display
,
3423 DefaultRootWindow (x_current_display
),
3425 SubstructureRedirectMask
| SubstructureNotifyMask
,
3428 UNBLOCK_INPUT_RESIGNAL
;
3429 error ("Can't notify window manager of iconification.");
3434 XUnmapWindow (XDISPLAY s
->display
.x
->window_desc
);
3436 s
->visible
= 0; /* Handled in the UnMap event for X11. */
3437 if (s
->display
.x
->icon_desc
!= 0)
3439 XMapWindow (XDISPLAY s
->display
.x
->icon_desc
);
3448 /* Destroy the X window of screen S.
3449 DISPL is the former s->display (since s->display
3450 has already been nulled out). */
3452 x_destroy_window (s
, displ
)
3454 union display displ
;
3459 if (displ
.x
->icon_desc
!= 0)
3460 XDestroyWindow (XDISPLAY displ
.x
->icon_desc
);
3461 XDestroyWindow (XDISPLAY displ
.x
->window_desc
);
3466 if (s
== x_focus_screen
)
3468 if (s
== x_highlight_screen
)
3469 x_highlight_screen
= 0;
3474 /* Manage event queues.
3476 This code is only used by the X10 support.
3478 We cannot leave events in the X queue and get them when we are ready
3479 because X does not provide a subroutine to get only a certain kind
3480 of event but not block if there are no queued events of that kind.
3482 Therefore, we must examine events as they come in and copy events
3483 of certain kinds into our private queues.
3485 All ExposeRegion events are put in x_expose_queue.
3486 All ButtonPressed and ButtonReleased events are put in x_mouse_queue. */
3489 /* Write the event *P_XREP into the event queue *QUEUE.
3490 If the queue is full, do nothing, but return nonzero. */
3493 enqueue_event (p_xrep
, queue
)
3494 register XEvent
*p_xrep
;
3495 register struct event_queue
*queue
;
3497 int newindex
= queue
->windex
+ 1;
3498 if (newindex
== EVENT_BUFFER_SIZE
)
3500 if (newindex
== queue
->rindex
)
3502 queue
->xrep
[queue
->windex
] = *p_xrep
;
3503 queue
->windex
= newindex
;
3507 /* Fetch the next event from queue *QUEUE and store it in *P_XREP.
3508 If *QUEUE is empty, do nothing and return 0. */
3511 dequeue_event (p_xrep
, queue
)
3512 register XEvent
*p_xrep
;
3513 register struct event_queue
*queue
;
3515 if (queue
->windex
== queue
->rindex
)
3517 *p_xrep
= queue
->xrep
[queue
->rindex
++];
3518 if (queue
->rindex
== EVENT_BUFFER_SIZE
)
3523 /* Return the number of events buffered in *QUEUE. */
3526 queue_event_count (queue
)
3527 register struct event_queue
*queue
;
3529 int tem
= queue
->windex
- queue
->rindex
;
3532 return EVENT_BUFFER_SIZE
+ tem
;
3535 /* Return nonzero if mouse input is pending. */
3538 mouse_event_pending_p ()
3540 return queue_event_count (&x_mouse_queue
);
3546 x_wm_set_size_hint (s
, prompting
)
3550 XSizeHints size_hints
;
3551 Window window
= s
->display
.x
->window_desc
;
3553 size_hints
.flags
= PResizeInc
| PMinSize
| PMaxSize
;
3555 flexlines
= s
->height
;
3557 size_hints
.x
= s
->display
.x
->left_pos
;
3558 size_hints
.y
= s
->display
.x
->top_pos
;
3559 size_hints
.height
= PIXEL_HEIGHT (s
);
3560 size_hints
.width
= PIXEL_WIDTH (s
);
3561 size_hints
.width_inc
= FONT_WIDTH (s
->display
.x
->font
);
3562 size_hints
.height_inc
= FONT_HEIGHT (s
->display
.x
->font
);
3563 size_hints
.base_width
= (2 * s
->display
.x
->internal_border_width
)
3564 + s
->display
.x
->v_scrollbar_width
;
3565 size_hints
.base_height
= (2 * s
->display
.x
->internal_border_width
)
3566 + s
->display
.x
->h_scrollbar_height
;
3567 size_hints
.min_width
= size_hints
.base_width
+ size_hints
.width_inc
;
3568 size_hints
.min_height
= size_hints
.base_height
+ size_hints
.height_inc
;
3569 size_hints
.max_width
= x_screen_width
3570 - ((2 * s
->display
.x
->internal_border_width
)
3571 + s
->display
.x
->v_scrollbar_width
);
3572 size_hints
.max_height
= x_screen_height
3573 - ((2 * s
->display
.x
->internal_border_width
)
3574 + s
->display
.x
->h_scrollbar_height
);
3577 size_hints
.flags
|= prompting
;
3580 XSizeHints hints
; /* Sometimes I hate X Windows... */
3582 XGetNormalHints (x_current_display
, window
, &hints
);
3583 if (hints
.flags
& PSize
)
3584 size_hints
.flags
|= PSize
;
3585 if (hints
.flags
& PPosition
)
3586 size_hints
.flags
|= PPosition
;
3587 if (hints
.flags
& USPosition
)
3588 size_hints
.flags
|= USPosition
;
3589 if (hints
.flags
& USSize
)
3590 size_hints
.flags
|= USSize
;
3594 XSetNormalHints (x_current_display
, window
, &size_hints
);
3596 XSetWMNormalHints (x_current_display
, window
, &size_hints
);
3599 /* Used for IconicState or NormalState */
3600 x_wm_set_window_state (s
, state
)
3605 Window window
= s
->display
.x
->window_desc
;
3607 wm_hints
.flags
= StateHint
;
3608 wm_hints
.initial_state
= state
;
3609 XSetWMHints (x_current_display
, window
, &wm_hints
);
3612 x_wm_set_icon_pixmap (s
, icon_pixmap
)
3617 Window window
= s
->display
.x
->window_desc
;
3619 wm_hints
.flags
= IconPixmapHint
;
3620 wm_hints
.icon_pixmap
= icon_pixmap
;
3621 XSetWMHints (x_current_display
, window
, &wm_hints
);
3624 x_wm_set_icon_position (s
, icon_x
, icon_y
)
3629 Window window
= s
->display
.x
->window_desc
;
3631 wm_hints
.flags
= IconPositionHint
;
3632 wm_hints
.icon_x
= icon_x
;
3633 wm_hints
.icon_y
= icon_y
;
3634 XSetWMHints (x_current_display
, window
, &wm_hints
);
3639 x_term_init (display_name
)
3645 extern int old_fcntl_owner
;
3648 x_focus_screen
= x_highlight_screen
= 0;
3650 x_current_display
= XOpenDisplay (display_name
);
3651 if (x_current_display
== 0)
3652 fatal ("X server %s not responding; check the DISPLAY environment variable or use \"-d\"\n",
3657 int hostname_size
= MAXHOSTNAMELEN
+ 1;
3659 hostname
= (char *) xmalloc (hostname_size
);
3662 XSetAfterFunction (x_current_display
, x_trace_wire
);
3665 invocation_name
= Ffile_name_nondirectory (Fcar (Vcommand_line_args
));
3667 /* Try to get the host name; if the buffer is too short, try
3668 again. Apparently, the only indication gethostname gives of
3669 whether the buffer was large enough is the presence or absence
3670 of a '\0' in the string. Eech. */
3673 gethostname (hostname
, hostname_size
- 1);
3674 hostname
[hostname_size
- 1] = '\0';
3676 /* Was the buffer large enough for gethostname to store the '\0'? */
3677 if (strlen (hostname
) < hostname_size
- 1)
3680 hostname_size
<<= 1;
3681 hostname
= (char *) xrealloc (hostname
, hostname_size
);
3683 x_id_name
= (char *) xmalloc (XSTRING (invocation_name
)->size
3686 sprintf (x_id_name
, "%s@%s", XSTRING (invocation_name
)->data
, hostname
);
3689 dup2 (ConnectionNumber (x_current_display
), 0);
3691 #ifndef SYSV_STREAMS
3692 /* Streams somehow keeps track of which descriptor number
3693 is being used to talk to X. So it is not safe to substitute
3694 descriptor 0. But it is safe to make descriptor 0 a copy of it. */
3695 close (ConnectionNumber (x_current_display
));
3696 ConnectionNumber (x_current_display
) = 0; /* Looks a little strange?
3697 * check the def of the macro;
3698 * it is a genuine lvalue */
3699 #endif /* not SYSV_STREAMS */
3701 #endif /* HAVE_X11 */
3704 old_fcntl_owner
= fcntl (0, F_GETOWN
, 0);
3705 #ifdef F_SETOWN_SOCK_NEG
3706 fcntl (0, F_SETOWN
, -getpid ()); /* stdin is a socket here */
3708 fcntl (0, F_SETOWN
, getpid ());
3709 #endif /* F_SETOWN_SOCK_NEG */
3710 #endif /* F_SETOWN */
3716 /* Must use interrupt input because we cannot otherwise
3717 arrange for C-g to be noticed immediately.
3718 We cannot connect it to SIGINT. */
3719 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
3721 expose_all_windows
= 0;
3723 clear_screen_hook
= XTclear_screen
;
3724 clear_end_of_line_hook
= XTclear_end_of_line
;
3725 ins_del_lines_hook
= XTins_del_lines
;
3726 change_line_highlight_hook
= XTchange_line_highlight
;
3727 insert_glyphs_hook
= XTinsert_glyphs
;
3728 write_glyphs_hook
= XTwrite_glyphs
;
3729 delete_glyphs_hook
= XTdelete_glyphs
;
3730 ring_bell_hook
= XTring_bell
;
3731 reset_terminal_modes_hook
= XTreset_terminal_modes
;
3732 set_terminal_modes_hook
= XTset_terminal_modes
;
3733 update_begin_hook
= XTupdate_begin
;
3734 update_end_hook
= XTupdate_end
;
3735 set_terminal_window_hook
= XTset_terminal_window
;
3736 read_socket_hook
= XTread_socket
;
3737 cursor_to_hook
= XTcursor_to
;
3738 reassert_line_highlight_hook
= XTreassert_line_highlight
;
3739 screen_rehighlight_hook
= XTscreen_rehighlight
;
3740 mouse_position_hook
= XTmouse_position
;
3742 scroll_region_ok
= 1; /* we'll scroll partial screens */
3743 char_ins_del_ok
= 0; /* just as fast to write the line */
3744 line_ins_del_ok
= 1; /* we'll just blt 'em */
3745 fast_clear_end_of_line
= 1; /* X does this well */
3746 memory_below_screen
= 0; /* we don't remember what scrolls
3750 XHandleError (x_error_handler
);
3751 XHandleIOError (x_error_handler
);
3753 /* Disable Window Change signals; they are handled by X events. */
3755 signal (SIGWINCH
, SIG_DFL
);
3756 #endif /* SIGWINCH */
3758 signal (SIGPIPE
, x_error_handler
);
3764 staticpro (&invocation_name
);
3765 invocation_name
= Qnil
;
3767 Qmouse_moved
= intern ("mouse-moved");
3768 Qmouse_click
= intern ("mouse-click");
3769 Qscrollbar_click
= intern ("scrollbar-click");
3771 #endif /* HAVE_X11 */
3772 #endif /* HAVE_X_WINDOWS */