1 /* X Communication module for terminals which understand the X protocol.
2 Copyright (C) 1989, 1992 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 2, 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. */
76 #include <sys/param.h>
78 #include "dispextern.h"
79 #include "termhooks.h"
92 #define XMapWindow XMapRaised /* Raise them when mapping. */
94 #include <X/Xkeyboard.h>
95 /*#include <X/Xproto.h> */
98 /* For sending Meta-characters. Do we need this? */
101 #define min(a,b) ((a)<(b) ? (a) : (b))
102 #define max(a,b) ((a)>(b) ? (a) : (b))
104 /* Nonzero means we must reprint all windows
105 because 1) we received an ExposeWindow event
106 or 2) we received too many ExposeRegion events to record. */
108 static int expose_all_windows
;
110 /* Nonzero means we must reprint all icon windows. */
112 static int expose_all_icons
;
115 /* ExposeRegion events, when received, are copied into this queue
116 for later processing. */
118 static struct event_queue x_expose_queue
;
120 /* ButtonPressed and ButtonReleased events, when received,
121 are copied into this queue for later processing. */
123 struct event_queue x_mouse_queue
;
126 /* Nonzero after BLOCK_INPUT; prevents input events from being
127 processed until later. */
131 #if defined (SIGIO) && defined (FIONREAD)
132 int BLOCK_INPUT_mask
;
135 /* Nonzero if input events came in while x_input_blocked was nonzero.
136 UNBLOCK_INPUT checks for this. */
140 /* Nonzero if in redisplay (); prevents us from calling it recursively */
144 /* The id of a bitmap used for icon windows.
145 One such map is shared by all Emacs icon windows.
146 This is zero if we have not yet had a need to create the bitmap. */
148 static Bitmap icon_bitmap
;
150 /* Font used for text icons. */
152 static FONT_TYPE
*icon_font_info
;
154 /* Stuff for dealing with the main icon title. */
156 extern Lisp_Object Vcommand_line_args
;
157 char *hostname
, *x_id_name
;
158 Lisp_Object invocation_name
;
160 /* This is the X connection that we are using. */
162 Display
*x_current_display
;
164 /* Screen being updated by update_screen. */
165 /* This is set by XTupdate_begin and looked at by all the
166 XT functions. It is zero while not inside an update.
167 In that case, the XT functions assume that `selected_screen'
168 is the screen to apply to. */
170 static struct screen
*updating_screen
;
172 /* The screen (if any) which has the X window that has keyboard focus.
173 Zero if none. This is examined by Ffocus_screen in screen.c. */
174 struct screen
*x_focus_screen
;
176 /* The screen which currently has the visual highlight, and should get
177 keyboard input (other sorts of input have the screen encoded in the
178 event). It points to the X focus screen's selected window's
179 screen. It differs from x_focus_screen when we're using a global
181 static struct screen
*x_highlight_screen
;
183 /* From .Xdefaults, the value of "emacs.WarpMouse". If non-zero,
184 mouse is moved to inside of screen when screen is de-iconified. */
186 static int warp_mouse_on_deiconify
;
188 /* During an update, maximum vpos for ins/del line operations to affect. */
190 static int flexlines
;
192 /* During an update, nonzero if chars output now should be highlighted. */
194 static int highlight
;
196 /* Nominal cursor position -- where to draw output.
197 During an update, these are different from the cursor-box position. */
203 /* `t' if a mouse button is depressed. */
205 extern Lisp_Object Vmouse_depressed
;
207 /* Tells if a window manager is present or not. */
209 extern Lisp_Object Vx_no_window_manager
;
211 /* Timestamp that we requested selection data was made. */
212 extern Time requestor_time
;
214 /* ID of the window requesting selection data. */
215 extern Window requestor_window
;
217 /* Nonzero enables some debugging for the X interface code. */
220 #else /* X10 stuff */
222 /* Bit patterns for the mouse cursor. */
224 short MouseCursor
[] = {
225 0x0000, 0x0008, 0x0018, 0x0038,
226 0x0078, 0x00f8, 0x01f8, 0x03f8,
227 0x07f8, 0x00f8, 0x00d8, 0x0188,
228 0x0180, 0x0300, 0x0300, 0x0000};
230 short MouseMask
[] = {
231 0x000c, 0x001c, 0x003c, 0x007c,
232 0x00fc, 0x01fc, 0x03fc, 0x07fc,
233 0x0ffc, 0x0ffc, 0x01fc, 0x03dc,
234 0x03cc, 0x0780, 0x0780, 0x0300};
236 static short grey_bits
[] = {
237 0x0005, 0x000a, 0x0005, 0x000a};
239 static Pixmap GreyPixmap
= 0;
240 #endif /* X10 stuff */
242 /* From time to time we get info on an Emacs window, here. */
244 static WINDOWINFO_TYPE windowinfo
;
248 extern Display
*XOpenDisplay ();
249 extern Window
XCreateWindow ();
251 extern Cursor
XCreateCursor ();
252 extern FONT_TYPE
*XOpenFont ();
254 static void flashback ();
257 static void dumpqueue ();
261 static int XTcursor_to ();
262 static int XTclear_end_of_line ();
264 /* These hooks are called by update_screen at the beginning and end
265 of a screen update. We record in `updating_screen' the identity
266 of the screen being updated, so that the XT... functions do not
267 need to take a screen as argument. Most of the XT... functions
268 should never be called except during an update, the only exceptions
269 being XTcursor_to, XTwrite_char and XTreassert_line_highlight. */
271 extern int mouse_track_top
, mouse_track_left
, mouse_track_width
;
283 flexlines
= s
->height
;
293 static void x_do_pending_expose ();
301 if (updating_screen
== 0
302 || updating_screen
!= s
)
309 adjust_scrollbars (s
);
310 x_do_pending_expose ();
312 x_display_cursor (s
, 1);
319 /* External interface to control of standout mode.
320 Call this when about to modify line at position VPOS
321 and not change whether it is highlighted. */
323 XTreassert_line_highlight (new, vpos
)
329 /* Call this when about to modify line at position VPOS
330 and change whether it is highlighted. */
333 XTchange_line_highlight (new_highlight
, vpos
, first_unused_hpos
)
334 int new_highlight
, vpos
, first_unused_hpos
;
336 highlight
= new_highlight
;
337 XTcursor_to (vpos
, 0);
338 XTclear_end_of_line (updating_screen
->width
);
341 /* This is used when starting Emacs and when restarting after suspend.
342 When starting Emacs, no X window is mapped. And nothing must be done
343 to Emacs's own window if it is suspended (though that rarely happens). */
346 XTset_terminal_modes ()
350 /* This is called when exiting or suspending Emacs.
351 Exiting will make the X-windows go away, and suspending
352 requires no action. */
355 XTreset_terminal_modes ()
357 /* XTclear_screen (); */
360 /* Set the nominal cursor position of the screen:
361 where display update commands will take effect.
362 This does not affect the place where the cursor-box is displayed. */
365 XTcursor_to (row
, col
)
366 register int row
, col
;
374 if (updating_screen
== 0)
377 x_display_cursor (selected_screen
, 1);
383 /* Display a sequence of N glyphs found at GP.
384 WINDOW is the x-window to output to. LEFT and TOP are starting coords.
385 HL is 1 if this text is highlighted, 2 if the cursor is on it.
387 FONT is the default font to use (for glyphs whose font-code is 0). */
390 dumpglyphs (s
, left
, top
, gp
, n
, hl
, font
)
393 register GLYPH
*gp
; /* Points to first GLYPH. */
394 register int n
; /* Number of glyphs to display. */
399 Window window
= s
->display
.x
->window_desc
;
400 GC drawing_gc
= (hl
== 2 ? s
->display
.x
->cursor_gc
401 : (hl
? s
->display
.x
->reverse_gc
402 : s
->display
.x
->normal_gc
));
404 if (sizeof (GLYPH
) == sizeof (XChar2b
))
405 XDrawImageString16 (x_current_display
, window
, drawing_gc
,
406 left
, top
+ FONT_BASE (font
), (XChar2b
*) gp
, n
);
407 else if (sizeof (GLYPH
) == sizeof (unsigned char))
408 XDrawImageString (x_current_display
, window
, drawing_gc
,
409 left
, top
+ FONT_BASE (font
), (char *) gp
, n
);
411 /* What size of glyph ARE you using? And does X have a function to
418 dumpglyphs (s
, left
, top
, gp
, n
, hl
, font
)
421 register GLYPH
*gp
; /* Points to first GLYPH. */
422 register int n
; /* Number of glyphs to display. */
426 char buf
[s
->width
]; /* Holds characters to be displayed. */
427 register char *cp
; /* Steps through buf[]. */
428 register int tlen
= GLYPH_TABLE_LENGTH
;
429 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
430 Window window
= s
->display
.x
->window_desc
;
431 int cursor_pixel
= s
->display
.x
->cursor_pixel
;
432 int fg_pixel
= s
->display
.x
->foreground_pixel
;
433 int bg_pixel
= s
->display
.x
->background_pixel
;
434 int intborder
= s
->display
.x
->internal_border_width
;
438 /* Get the face-code of the next GLYPH. */
442 while (GLYPH_ALIAS_P (tbase
, tlen
, g
))
443 g
= GLYPH_ALIAS (tbase
, g
);
447 /* Find the run of consecutive glyphs with the same face-code.
448 Extract their character codes into BUF. */
453 while (GLYPH_ALIAS_P (tbase
, tlen
, g
))
454 g
= GLYPH_ALIAS (tbase
, g
);
463 /* LEN gets the length of the run. */
466 /* Now output this run of chars, with the font and pixel values
467 determined by the face code CF. */
471 GC GC_cursor
= s
->display
.x
->cursor_gc
;
472 GC GC_reverse
= s
->display
.x
->reverse_gc
;
473 GC GC_normal
= s
->display
.x
->normal_gc
;
475 XDrawImageString (x_current_display
, window
,
478 : (hl
? GC_reverse
: GC_normal
)),
479 left
, top
+ FONT_BASE (font
), buf
, len
);
481 XText (window
, left
, top
,
486 ? (cursor_pixel
== fg_pixel
? bg_pixel
: fg_pixel
)
487 : hl
? bg_pixel
: fg_pixel
),
488 (hl
== 2 ? cursor_pixel
489 : hl
? fg_pixel
: bg_pixel
));
490 #endif /* HAVE_X11 */
495 if (FACE_IS_FONT (cf
))
496 XDrawImageString (x_current_display
, s
->display
.x
->window_desc
,
498 left
, top
+ FONT_BASE (FACE_FONT (cf
)),
500 else if (FACE_IS_IMAGE (cf
))
501 XCopyPlane (x_current_display
, FACE_IMAGE (cf
),
502 s
->display
.x
->window_desc
,
503 s
->display
.x
->normal_gc
,
505 FACE_IMAGE_WIDTH (cf
),
506 FACE_IMAGE_HEIGHT (cf
), left
, top
);
510 register struct face
*fp
= x_face_table
[cf
];
512 XText (window
, left
, top
,
517 ? (cursor_pixel
== fp
->fg
? fp
->bg
: fp
->fg
)
518 : hl
? fp
->bg
: fp
->fg
),
519 (hl
== 2 ? cursor_pixel
520 : hl
? fp
->fg
: fp
->bg
));
521 #endif /* HAVE_X11 */
523 left
+= len
* FONT_WIDTH (font
);
528 /* Output some text at the nominal screen cursor position,
529 advancing the cursor over the text.
530 Output LEN glyphs at START.
532 `highlight', set up by XTreassert_line_highlight or XTchange_line_highlight,
533 controls the pixel values used for foreground and background. */
536 XTwrite_glyphs (start
, len
)
537 register GLYPH
*start
;
540 register int temp_length
;
550 /* If not within an update,
551 output at the screen's visible cursor. */
552 curs_x
= s
->cursor_x
;
553 curs_y
= s
->cursor_y
;
557 (curs_x
* FONT_WIDTH (s
->display
.x
->font
)
558 + s
->display
.x
->internal_border_width
),
559 (curs_y
* FONT_HEIGHT (s
->display
.x
->font
)
560 + s
->display
.x
->internal_border_width
),
561 start
, len
, highlight
, s
->display
.x
->font
);
563 /* If we drew on top of the cursor, note that it is turned off. */
564 if (curs_y
== s
->phys_cursor_y
565 && curs_x
<= s
->phys_cursor_x
566 && curs_x
+ len
> s
->phys_cursor_x
)
567 s
->phys_cursor_x
= -1;
569 if (updating_screen
== 0)
572 x_display_cursor (s
, 1);
581 /* Erase the current text line from the nominal cursor position (inclusive)
582 to column FIRST_UNUSED (exclusive). The idea is that everything
583 from FIRST_UNUSED onward is already erased. */
586 XTclear_end_of_line (first_unused
)
587 register int first_unused
;
589 struct screen
*s
= updating_screen
;
595 if (curs_y
< 0 || curs_y
>= s
->height
)
597 if (first_unused
<= 0)
600 if (first_unused
>= s
->width
)
601 first_unused
= s
->width
;
605 /* Notice if the cursor will be cleared by this operation. */
606 if (curs_y
== s
->phys_cursor_y
607 && curs_x
<= s
->phys_cursor_x
608 && s
->phys_cursor_x
< first_unused
)
609 s
->phys_cursor_x
= -1;
612 XClearArea (x_current_display
, s
->display
.x
->window_desc
,
613 curs_x
* FONT_WIDTH (s
->display
.x
->font
)
614 + s
->display
.x
->internal_border_width
,
615 curs_y
* FONT_HEIGHT (s
->display
.x
->font
)
616 + s
->display
.x
->internal_border_width
,
617 FONT_WIDTH (s
->display
.x
->font
) * (first_unused
- curs_x
),
618 FONT_HEIGHT (s
->display
.x
->font
), False
);
621 XPixSet (s
->display
.x
->window_desc
,
622 curs_x
* FONT_WIDTH (s
->display
.x
->font
) + s
->display
.x
->internal_border_width
,
623 curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + s
->display
.x
->internal_border_width
,
624 FONT_WIDTH (s
->display
.x
->font
) * (first_unused
- curs_x
),
625 FONT_HEIGHT (s
->display
.x
->font
),
626 s
->display
.x
->background_pixel
);
627 #endif /* HAVE_X11 */
636 struct screen
*s
= updating_screen
;
641 s
->phys_cursor_x
= -1; /* Cursor not visible. */
642 curs_x
= 0; /* Nominal cursor position is top left. */
646 XClear (s
->display
.x
->window_desc
);
654 /* Paint horzontal bars down the screen for a visible bell.
655 Note that this may be way too slow on some machines. */
660 register struct screen_glyphs
*active_screen
= SCREEN_CURRENT_GLYPHS (s
);
664 if (updating_screen
!= 0)
670 for (i
= s
->height
* FONT_HEIGHT (s
->display
.x
->font
) - 10;
672 i
-= 100) /* Should be NO LOWER than 75 for speed reasons. */
673 XFillRectangle (x_current_display
, s
->display
.x
->window_desc
,
674 s
->display
.x
->cursor_gc
,
675 0, i
, s
->width
* FONT_WIDTH (s
->display
.x
->font
)
676 + 2 * s
->display
.x
->internal_border_width
, 25);
679 x
= (s
->width
* FONT_WIDTH (s
->display
.x
->font
)) / 4;
680 y
= (s
->height
* FONT_HEIGHT (s
->display
.x
->font
)) / 4;
681 XFillRectangle (x_current_display
, s
->display
.x
->window_desc
,
682 s
->display
.x
->cursor_gc
,
684 dumpglyphs (s
, (x
+ s
->display
.x
->internal_border_width
),
685 (y
+ s
->display
.x
->internal_border_width
),
686 &active_screen
->glyphs
[(s
->height
/ 4) + 1][(s
->width
/ 4)],
687 1, 0, s
->display
.x
->font
);
690 for (i
= s
->height
* FONT_HEIGHT (s
->display
.x
->font
) - 10;
693 XPixFill (s
->display
.x
->window_desc
, 0, i
,
694 s
->width
* FONT_WIDTH (s
->display
.x
->font
)
695 + 2 * s
->display
.x
->internal_border_width
, 10,
696 WHITE_PIX_DEFAULT
, ClipModeClipped
, GXinvert
, AllPlanes
);
703 /* Flip background and forground colors of the screen. */
710 unsigned long pix_temp
;
712 x_display_cursor (s
, 0);
713 XClearWindow (x_current_display
, s
->display
.x
->window_desc
);
714 temp
= s
->display
.x
->normal_gc
;
715 s
->display
.x
->normal_gc
= s
->display
.x
->reverse_gc
;
716 s
->display
.x
->reverse_gc
= temp
;
717 pix_temp
= s
->display
.x
->foreground_pixel
;
718 s
->display
.x
->foreground_pixel
= s
->display
.x
->background_pixel
;
719 s
->display
.x
->background_pixel
= pix_temp
;
721 XSetWindowBackground (x_current_display
, s
->display
.x
->window_desc
,
722 s
->display
.x
->background_pixel
);
723 if (s
->display
.x
->background_pixel
== s
->display
.x
->cursor_pixel
)
725 s
->display
.x
->cursor_pixel
= s
->display
.x
->foreground_pixel
;
726 XSetBackground (x_current_display
, s
->display
.x
->cursor_gc
,
727 s
->display
.x
->cursor_pixel
);
728 XSetForeground (x_current_display
, s
->display
.x
->cursor_gc
,
729 s
->display
.x
->background_pixel
);
735 /* Make audible bell. */
738 #define XRINGBELL XBell(x_current_display, 0)
740 #define XRINGBELL XFeep(0);
747 XTflash (selected_screen
);
750 x_invert_screen (selected_screen
);
751 x_invert_screen (selected_screen
);
762 /* Insert and delete character are not supposed to be used
763 because we are supposed to turn off the feature of using them. */
766 XTinsert_glyphs (start
, len
)
767 register char *start
;
780 /* Specify how many text lines, from the top of the window,
781 should be affected by insert-lines and delete-lines operations.
782 This, and those operations, are used only within an update
783 that is bounded by calls to XTupdate_begin and XTupdate_end. */
786 XTset_terminal_window (n
)
789 if (updating_screen
== 0)
792 if ((n
<= 0) || (n
> updating_screen
->height
))
793 flexlines
= updating_screen
->height
;
798 /* Perform an insert-lines operation, inserting N lines
799 at a vertical position curs_y. */
805 register int topregion
, bottomregion
;
806 register int length
, newtop
, mask
;
807 register struct screen
*s
= updating_screen
;
808 int intborder
= s
->display
.x
->internal_border_width
;
810 if (curs_y
>= flexlines
)
814 bottomregion
= flexlines
- (n
+ 1);
815 newtop
= topregion
+ n
;
816 length
= (bottomregion
- topregion
) + 1;
822 if ((length
> 0) && (newtop
<= flexlines
))
825 XCopyArea (x_current_display
, s
->display
.x
->window_desc
,
826 s
->display
.x
->window_desc
, s
->display
.x
->normal_gc
,
827 intborder
, topregion
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
828 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
829 length
* FONT_HEIGHT (s
->display
.x
->font
), intborder
,
830 newtop
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
);
832 XMoveArea (s
->display
.x
->window_desc
,
833 intborder
, topregion
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
834 intborder
, newtop
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
835 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
836 length
* FONT_HEIGHT (s
->display
.x
->font
));
837 /* Now we must process any ExposeRegion events that occur
838 if the area being copied from is obscured.
839 We can't let it wait because further i/d operations
840 may want to copy this area to another area. */
842 #endif /* HAVE_X11 */
845 newtop
= min (newtop
, (flexlines
- 1));
846 length
= newtop
- topregion
;
850 XClearArea (x_current_display
, s
->display
.x
->window_desc
, intborder
,
851 topregion
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
852 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
853 n
* FONT_HEIGHT (s
->display
.x
->font
), False
);
855 XPixSet (s
->display
.x
->window_desc
,
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
),
860 s
->display
.x
->background_pixel
);
861 #endif /* HAVE_X11 */
865 /* Perform a delete-lines operation, deleting N lines
866 at a vertical position curs_y. */
873 register struct screen
*s
= updating_screen
;
874 int intborder
= s
->display
.x
->internal_border_width
;
876 if (curs_y
>= flexlines
)
883 if ((curs_y
+ n
) >= flexlines
)
885 if (flexlines
>= (curs_y
+ 1))
888 XClearArea (x_current_display
, s
->display
.x
->window_desc
, intborder
,
889 curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
890 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
891 (flexlines
- curs_y
) * FONT_HEIGHT (s
->display
.x
->font
), False
);
893 XPixSet (s
->display
.x
->window_desc
,
894 intborder
, curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
895 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
896 (flexlines
- curs_y
) * FONT_HEIGHT (s
->display
.x
->font
),
897 s
->display
.x
->background_pixel
);
898 #endif /* HAVE_X11 */
904 XCopyArea (x_current_display
, s
->display
.x
->window_desc
,
905 s
->display
.x
->window_desc
, s
->display
.x
->normal_gc
,
907 (curs_y
+ n
) * FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
908 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
909 (flexlines
- (curs_y
+ n
)) * FONT_HEIGHT (s
->display
.x
->font
),
910 intborder
, curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
);
911 XClearArea (x_current_display
, s
->display
.x
->window_desc
,
913 (flexlines
- n
) * FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
914 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
915 n
* FONT_HEIGHT (s
->display
.x
->font
), False
);
917 XMoveArea (s
->display
.x
->window_desc
,
919 (curs_y
+ n
) * FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
920 intborder
, curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
921 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
922 (flexlines
- (curs_y
+ n
)) * FONT_HEIGHT (s
->display
.x
->font
));
923 /* Now we must process any ExposeRegion events that occur
924 if the area being copied from is obscured.
925 We can't let it wait because further i/d operations
926 may want to copy this area to another area. */
928 XPixSet (s
->display
.x
->window_desc
, intborder
,
929 (flexlines
- n
) * FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
930 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
931 n
* FONT_HEIGHT (s
->display
.x
->font
), s
->display
.x
->background_pixel
);
932 #endif /* HAVE_X11 */
936 /* Perform an insert-lines or delete-lines operation,
937 inserting N lines or deleting -N lines at vertical position VPOS. */
939 XTins_del_lines (vpos
, n
)
942 if (updating_screen
== 0)
945 /* Hide the cursor. */
946 x_display_cursor (updating_screen
, 0);
948 XTcursor_to (vpos
, 0);
959 static void clear_cursor ();
961 /* Output into a rectangle of an X-window (for screen S)
962 the characters in s->phys_lines that overlap that rectangle.
963 TOP and LEFT are the position of the upper left corner of the rectangle.
964 ROWS and COLS are the size of the rectangle. */
967 dumprectangle (s
, left
, top
, cols
, rows
)
969 register int left
, top
, cols
, rows
;
971 register struct screen_glyphs
*active_screen
= SCREEN_CURRENT_GLYPHS (s
);
972 int cursor_cleared
= 0;
976 if (SCREEN_GARBAGED_P (s
))
979 top
-= s
->display
.x
->internal_border_width
;
980 left
-= s
->display
.x
->internal_border_width
;
982 /* Express rectangle as four edges, instead of position-and-size. */
986 #ifndef HAVE_X11 /* Window manger does this for X11. */
987 /* If the rectangle includes any of the internal border area,
988 redisplay the border emphasis. */
989 if (top
< 0 || left
< 0
990 || bottom
> s
->height
* FONT_HEIGHT (s
->display
.x
->font
)
991 || right
> s
->width
* FONT_WIDTH (s
->display
.x
->font
))
993 #endif /* HAVE_X11 */
995 /* Convert rectangle edges in pixels to edges in chars.
996 Round down for left and top, up for right and bottom. */
997 top
/= FONT_HEIGHT (s
->display
.x
->font
);
998 left
/= FONT_WIDTH (s
->display
.x
->font
);
999 bottom
+= (FONT_HEIGHT (s
->display
.x
->font
) - 1);
1000 right
+= (FONT_WIDTH (s
->display
.x
->font
) - 1);
1001 bottom
/= FONT_HEIGHT (s
->display
.x
->font
);
1002 right
/= FONT_WIDTH (s
->display
.x
->font
);
1004 /* Clip the rectangle to what can be visible. */
1009 if (right
> s
->width
)
1011 if (bottom
> s
->height
)
1014 /* Get size in chars of the rectangle. */
1015 cols
= right
- left
;
1016 rows
= bottom
- top
;
1018 /* If rectangle has zero area, return. */
1019 if (rows
<= 0) return;
1020 if (cols
<= 0) return;
1022 /* Turn off the cursor if it is in the rectangle.
1023 We will turn it back on afterward. */
1024 if ((s
->phys_cursor_x
>= left
) && (s
->phys_cursor_x
< right
)
1025 && (s
->phys_cursor_y
>= top
) && (s
->phys_cursor_y
< bottom
))
1031 /* Display the text in the rectangle, one text line at a time. */
1033 for (y
= top
; y
< bottom
; y
++)
1035 GLYPH
*line
= &active_screen
->glyphs
[y
][left
];
1037 if (! active_screen
->enable
[y
] || left
> active_screen
->used
[y
])
1041 (left
* FONT_WIDTH (s
->display
.x
->font
)
1042 + s
->display
.x
->internal_border_width
),
1043 (y
* FONT_HEIGHT (s
->display
.x
->font
)
1044 + s
->display
.x
->internal_border_width
),
1045 line
, min (cols
, active_screen
->used
[y
] - left
),
1046 active_screen
->highlight
[y
], s
->display
.x
->font
);
1049 /* Turn the cursor on if we turned it off. */
1052 x_display_cursor (s
, 1);
1056 /* Process all queued ExposeRegion events. */
1062 XExposeRegionEvent r
;
1064 while (dequeue_event (&r
, &x_expose_queue
))
1066 struct screen
*s
= x_window_to_screen (r
.window
);
1067 if (s
->display
.x
->icon_desc
== r
.window
)
1070 dumprectangle (s
, r
.x
, r
.y
, r
.width
, r
.height
);
1076 /* Process all expose events that are pending.
1077 Redraws the cursor if necessary on any screen that
1078 is not in the process of being updated with update_screen. */
1081 x_do_pending_expose ()
1085 Lisp_Object tail
, screen
;
1087 if (expose_all_windows
)
1089 expose_all_windows
= 0;
1090 for (tail
= Vscreen_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1092 register int temp_width
, temp_height
;
1095 screen
= XCONS (tail
)->car
;
1096 if (XTYPE (screen
) != Lisp_Screen
)
1098 s
= XSCREEN (screen
);
1099 if (! SCREEN_IS_X (s
))
1103 if (!s
->display
.x
->needs_exposure
)
1106 intborder
= s
->display
.x
->internal_border_width
;
1109 XGetWindowInfo (s
->display
.x
->window_desc
, &windowinfo
);
1110 temp_width
= ((windowinfo
.width
- 2 * intborder
1111 - s
->display
.x
->v_scrollbar_width
)
1112 / FONT_WIDTH (s
->display
.x
->font
));
1113 temp_height
= ((windowinfo
.height
- 2 * intborder
1114 - s
->display
.x
->h_scrollbar_height
)
1115 / FONT_HEIGHT (s
->display
.x
->font
));
1116 if (temp_width
!= s
->width
|| temp_height
!= s
->height
)
1118 change_screen_size (s
, max (1, temp_height
),
1119 max (1, temp_width
), 0);
1120 x_resize_scrollbars (s
);
1122 s
->display
.x
->left_pos
= windowinfo
.x
;
1123 s
->display
.x
->top_pos
= windowinfo
.y
;
1124 dumprectangle (s
, 0, 0, PIXEL_WIDTH (s
), PIXEL_HEIGHT (s
));
1128 s
->display
.x
->needs_exposure
= 0;
1129 if (updating_screen
!= s
)
1130 x_display_cursor (s
, 1);
1135 /* Handle any individual-rectangle expose events queued
1136 for various windows. */
1146 screen_highlight (screen
)
1147 struct screen
*screen
;
1149 if (! EQ (Vx_no_window_manager
, Qnil
))
1150 XSetWindowBorder (x_current_display
, screen
->display
.x
->window_desc
,
1151 screen
->display
.x
->border_pixel
);
1152 x_display_cursor (screen
, 1);
1156 screen_unhighlight (screen
)
1157 struct screen
*screen
;
1159 if (! EQ (Vx_no_window_manager
, Qnil
))
1160 XSetWindowBorderPixmap (x_current_display
, screen
->display
.x
->window_desc
,
1161 screen
->display
.x
->border_tile
);
1162 x_display_cursor (screen
, 1);
1165 /* Dump the border-emphasis of screen S.
1166 If S is selected, this is a lining of the same color as the border,
1167 just within the border, occupying a portion of the internal border.
1168 If S is not selected, it is background in the same place.
1169 If ALWAYS is 0, don't bother explicitly drawing if it's background.
1171 ALWAYS = 1 is used when a screen becomes selected or deselected.
1172 In that case, we also turn the cursor off and on again
1173 so it will appear in the proper shape (solid if selected; else hollow.) */
1176 dumpborder (s
, always
)
1180 int thickness
= s
->display
.x
->internal_border_width
/ 2;
1181 int width
= PIXEL_WIDTH (s
);
1182 int height
= PIXEL_HEIGHT (s
);
1185 if (s
!= selected_screen
)
1190 pixel
= s
->display
.x
->background_pixel
;
1194 pixel
= s
->display
.x
->border_pixel
;
1197 XPixSet (s
->display
.x
->window_desc
, 0, 0, width
, thickness
, pixel
);
1198 XPixSet (s
->display
.x
->window_desc
, 0, 0, thickness
, height
, pixel
);
1199 XPixSet (s
->display
.x
->window_desc
, 0, height
- thickness
, width
,
1201 XPixSet (s
->display
.x
->window_desc
, width
- thickness
, 0, thickness
,
1205 x_display_cursor (s
, 1);
1209 static void XTscreen_rehighlight ();
1211 /* The focus has changed. Update the screens as necessary to reflect
1212 the new situation. Note that we can't change the selected screen
1213 here, because the lisp code we are interrupting might become confused.
1214 Each event gets marked with the screen in which it occured, so the
1215 lisp code can tell when the switch took place by examining the events. */
1218 x_new_focus_screen (screen
)
1219 struct screen
*screen
;
1221 struct screen
*old_focus
= x_focus_screen
;
1222 int events_enqueued
= 0;
1224 if (screen
!= x_focus_screen
)
1226 /* Set this before calling other routines, so that they see
1227 the correct value of x_focus_screen. */
1228 x_focus_screen
= screen
;
1230 if (old_focus
&& old_focus
->auto_lower
)
1231 x_lower_screen (old_focus
);
1234 selected_screen
= screen
;
1235 XSET (XWINDOW (selected_screen
->selected_window
)->screen
,
1236 Lisp_Screen
, selected_screen
);
1237 Fselect_window (selected_screen
->selected_window
);
1238 choose_minibuf_screen ();
1241 if (x_focus_screen
&& x_focus_screen
->auto_raise
)
1242 x_raise_screen (x_focus_screen
);
1245 XTscreen_rehighlight ();
1249 /* The focus has changed, or we have make a screen's selected window
1250 point to a window on a different screen (this happens with global
1251 minibuffer screens). Shift the highlight as appropriate. */
1253 XTscreen_rehighlight ()
1255 struct screen
*old_highlight
= x_highlight_screen
;
1259 x_highlight_screen
= XSCREEN (SCREEN_FOCUS_SCREEN (x_focus_screen
));
1260 if (x_highlight_screen
->display
.nothing
== 0)
1261 XSET (SCREEN_FOCUS_SCREEN (x_focus_screen
), Lisp_Screen
,
1262 (x_highlight_screen
= x_focus_screen
));
1265 x_highlight_screen
= 0;
1267 if (x_highlight_screen
!= old_highlight
)
1270 screen_unhighlight (old_highlight
);
1271 if (x_highlight_screen
)
1272 screen_highlight (x_highlight_screen
);
1283 /* Position of the mouse in characters */
1284 unsigned int x_mouse_x
, x_mouse_y
;
1286 /* Offset in buffer of character under the pointer, or 0. */
1287 extern int mouse_buffer_offset
;
1289 extern int buffer_posn_from_coords ();
1291 /* Symbols from xfns.c to denote the different parts of a window. */
1292 extern Lisp_Object Qmodeline_part
, Qtext_part
;
1295 /* Set *RESULT to an emacs input_event corresponding to MOTION_EVENT.
1296 S is the screen in which the event occurred.
1298 WINDOW_TYPE says whether the event happened in a scrollbar window
1299 or a text window, affecting the format of the event created.
1301 PART specifies which part of the scrollbar the event happened in,
1302 if WINDOW_TYPE == scrollbar_window.
1304 If the mouse is over the same character as the last time we checked,
1305 don't return an event; set result->kind to no_event. */
1308 notice_mouse_movement (result
, motion_event
, s
, window_type
, part
)
1309 struct input_event
*result
;
1310 XMotionEvent motion_event
;
1315 int x
, y
, root_x
, root_y
, pix_x
, pix_y
;
1316 unsigned int keys_and_buttons
;
1317 Window w
, root_window
;
1319 /* Unless we decide otherwise below, return a non-event. */
1320 result
->kind
= no_event
;
1322 if (XQueryPointer (x_current_display
,
1323 s
->display
.x
->window_desc
,
1325 &root_x
, &root_y
, &pix_x
, &pix_y
,
1331 if (w
== None
) /* Mouse no longer in window. */
1335 pixel_to_glyph_translation (s
, pix_x
, pix_y
, &x
, &y
);
1336 if (x
== x_mouse_x
&& y
== x_mouse_y
)
1342 /* What sort of window are we in now? */
1343 if (window_type
== text_window
) /* Text part */
1347 Vmouse_window
= window_from_coordinates (s
, x
, y
, &modeline_p
);
1349 if (XTYPE (Vmouse_window
) == Lisp_Window
)
1351 = buffer_posn_from_coords (XWINDOW (Vmouse_window
), x
, y
);
1353 mouse_buffer_offset
= 0;
1355 if (EQ (Vmouse_window
, Qnil
))
1356 Vmouse_screen_part
= Qnil
;
1357 else if (modeline_p
)
1358 Vmouse_screen_part
= Qmodeline_part
;
1360 Vmouse_screen_part
= Qtext_part
;
1362 result
->kind
= window_sys_event
;
1363 result
->code
= Qmouse_moved
;
1367 else if (window_type
== scrollbar_window
) /* Scrollbar */
1369 Vmouse_window
= s
->selected_window
;
1370 mouse_buffer_offset
= 0;
1371 Vmouse_screen_part
= part
;
1373 result
->kind
= window_sys_event
;
1374 result
->code
= Qmouse_moved
;
1384 /* Mouse clicks and mouse movement. Rah. */
1387 /* Given a pixel position (PIX_X, PIX_Y) on the screen S, return
1388 glyph co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle
1389 that the glyph at X, Y occupies, if BOUNDS != 0. */
1391 pixel_to_glyph_coords (s
, pix_x
, pix_y
, x
, y
, bounds
)
1393 register unsigned int pix_x
, pix_y
;
1394 register int *x
, *y
;
1397 int ibw
= s
->display
.x
->internal_border_width
;
1399 FONT_TYPE
*font
= s
->display
.x
->font
;
1401 width
= FONT_WIDTH (font
);
1402 height
= FONT_HEIGHT (font
);
1404 /* What line is it on? */
1407 else if (pix_y
> s
->display
.x
->pixel_height
- ibw
)
1408 *y
= SCREEN_HEIGHT (s
) - 1;
1410 *y
= (pix_y
- ibw
) / height
;
1412 /* And what column? */
1415 else if (pix_x
> s
->display
.x
->pixel_width
- ibw
)
1416 *x
= SCREEN_WIDTH (s
) - 1;
1418 *x
= (pix_x
- ibw
) / width
;
1422 bounds
->width
= width
;
1423 bounds
->height
= height
;
1424 bounds
->x
= ibw
+ (*x
* width
);
1425 bounds
->y
= ibw
+ (*y
* height
);
1429 /* Any buttons grabbed. */
1430 unsigned int x_mouse_grabbed
;
1432 /* Convert a set of X modifier bits to the proper form for a
1433 struct input_event modifiers value. */
1436 x_convert_modifiers (state
)
1439 return ( ((state
& (ShiftMask
| LockMask
)) ? shift_modifier
: 0)
1440 | ((state
& ControlMask
) ? ctrl_modifier
: 0)
1441 | ((state
& Mod1Mask
) ? meta_modifier
: 0));
1444 extern struct screen
*x_window_to_scrollbar ();
1445 extern Lisp_Object Vmouse_event
;
1447 /* Prepare a mouse-event in *RESULT for placement in the input queue.
1449 If the event is a button press, then note that we have grabbed
1452 If PART and PREFIX are 0, then the event occurred in the text part;
1453 otherwise it happened in a scrollbar. */
1456 construct_mouse_click (result
, event
, s
, part
, prefix
)
1457 struct input_event
*result
;
1458 XButtonEvent
*event
;
1463 /* Initialize those fields text and scrollbar clicks hold in common.
1464 Make the event type no_event; we'll change that when we decide
1466 result
->kind
= no_event
;
1467 XSET (result
->code
, Lisp_Int
, event
->button
);
1468 XSET (result
->timestamp
, Lisp_Int
, event
->time
);
1469 result
->modifiers
= (x_convert_modifiers (event
->state
)
1470 | (event
->type
== ButtonRelease
? up_modifier
: 0));
1471 XSET (result
->timestamp
, Lisp_Int
, (event
->time
& 0x7fffff));
1473 /* Notice if the mouse is still grabbed. */
1474 if (event
->type
== ButtonPress
)
1476 if (! x_mouse_grabbed
)
1477 Vmouse_depressed
= Qt
;
1478 x_mouse_grabbed
|= (1 << event
->button
);
1480 else if (event
->type
== ButtonRelease
)
1482 x_mouse_grabbed
&= ~(1 << event
->button
);
1483 if (!x_mouse_grabbed
)
1484 Vmouse_depressed
= Qnil
;
1487 if (part
) /* Scrollbar event */
1491 pos
= event
->y
- (s
->display
.x
->v_scrollbar_width
- 2);
1492 XSET (x_mouse_x
, Lisp_Int
, pos
);
1493 len
= ((FONT_HEIGHT (s
->display
.x
->font
) * s
->height
)
1494 + s
->display
.x
->internal_border_width
1495 - (2 * (s
->display
.x
->v_scrollbar_width
- 2)));
1496 XSET (x_mouse_y
, Lisp_Int
, len
);
1498 result
->kind
= scrollbar_click
;
1499 result
->part
= part
;
1500 XSET (result
->x
, Lisp_Int
, (s
->display
.x
->top_pos
- event
->y
));
1501 XSET (result
->y
, Lisp_Int
, s
->display
.x
->pixel_height
);
1504 else /* Text Window Event */
1508 pixel_to_glyph_coords (s
, event
->x
, event
->y
, &column
, &row
, NULL
);
1509 result
->kind
= mouse_click
;
1517 /* Mouse movement. Rah.
1519 In order to avoid asking for motion events and then throwing most
1520 of them away or busy-polling the server for mouse positions, we ask
1521 the server for pointer motion hints. This means that we get only
1522 one event per group of mouse movements. "Groups" are delimited by
1523 other kinds of events (focus changes and button clicks, for
1524 example), or by XQueryPointer calls; when one of these happens, we
1525 get another MotionNotify event the next time the mouse moves. This
1526 is at least as efficient than getting motion events when mouse
1527 tracking is on, and I suspect only negligibly worse when tracking
1530 The silly O'Reilly & Associates Nutshell guides barely document
1531 pointer motion hints at all (I think you have to infer how they
1532 work from an example), and the description of XQueryPointer doesn't
1533 mention that calling it causes you to get another motion hint from
1534 the server, which is very important. */
1536 /* Where the mouse was last time we reported a mouse event. */
1537 static SCREEN_PTR last_mouse_screen
;
1538 static XRectangle last_mouse_glyph
;
1540 /* Function to report a mouse movement to the mainstream Emacs code.
1541 The input handler calls this.
1543 We have received a mouse movement event, which is given in *event.
1544 If the mouse is over a different glyph than it was last time, tell
1545 the mainstream emacs code by setting mouse_moved. If not, ask for
1546 another motion event, so we can check again the next time it moves. */
1548 note_mouse_position (screen
, event
)
1550 XMotionEvent
*event
;
1553 /* Has the mouse moved off the glyph it was on at the last sighting? */
1554 if (event
->x
< last_mouse_glyph
.x
1555 || event
->x
>= last_mouse_glyph
.x
+ last_mouse_glyph
.width
1556 || event
->y
< last_mouse_glyph
.y
1557 || event
->y
>= last_mouse_glyph
.y
+ last_mouse_glyph
.height
)
1561 /* It's on the same glyph. Call XQueryPointer so we'll get an
1562 event the next time the mouse moves and we can see if it's
1563 *still* on the same glyph. */
1566 XQueryPointer (event
->display
, event
->window
,
1567 (Window
*) &dummy
, (Window
*) &dummy
,
1568 &dummy
, &dummy
, &dummy
, &dummy
,
1569 (unsigned int *) &dummy
);
1573 /* Return the current position of the mouse.
1575 This clears the mouse_moved flag, so we can wait for the next mouse
1576 position. This also calls XQueryPointer, which will cause the
1577 server to give us another MotionNotify when the mouse moves again.
1581 XTmouse_position (s
, x
, y
, time
)
1587 Display
*d
= x_current_display
;
1588 Window guess
, root
, child
;
1592 /* I would like to have an X function that just told me the
1593 innermost window containing the mouse.
1595 /* There doesn't seem to be any way to just get the innermost window
1596 containing the pointer, no matter what X screen it's on; you have
1597 to guess a window, and then X will tell you which one of that
1598 window's children it's in. If the pointer isn't in any of that
1599 window's children, it gives you a root window that contains it.
1601 So we start with the selected screen's window and chase down
1602 branches under the guidance of XQueryPointer until we hit a leaf
1603 (all of the Emacs windows we care about are leaf windows). If at
1604 any time XQueryPointer returns false, that means that the current
1605 window does not contain the pointer any more (perhaps it moved),
1606 so we start with the root window XQueryPointer has given us and
1609 guess
= selected_screen
->display
.x
->window_desc
;
1611 if (XQueryPointer (d
, guess
, &root
, &child
,
1612 &dummy
, &dummy
, &ix
, &iy
, (unsigned int *) &dummy
))
1615 /* Guess is a leaf window, and it contains the pointer. */
1621 /* When XQueryPointer returns False, the pointer isn't in guess
1622 anymore, but root is the root window of the screen we should
1626 *s
= last_mouse_screen
= x_window_to_screen (guess
);
1631 pixel_to_glyph_coords (*s
, ix
, iy
, &ix
, &iy
, &last_mouse_glyph
);
1632 XSET (*x
, Lisp_Int
, ix
);
1633 XSET (*y
, Lisp_Int
, iy
);
1638 /* I don't know how to find the time for the last movement; it seems
1639 like XQueryPointer ought to return it, but it doesn't. */
1646 static char *events
[] =
1686 #define XEvent XKeyPressedEvent
1687 #endif /* HAVE_X11 */
1689 /* Timestamp of enter window event. This is only used by XTread_socket,
1690 but we have to put it out here, since static variables within functions
1691 sometimes don't work. */
1692 static Time enter_timestamp
;
1694 /* Communication with window managers. */
1695 Atom Xatom_wm_protocols
;
1697 /* Kinds of protocol things we may receive. */
1698 Atom Xatom_wm_take_focus
;
1699 Atom Xatom_wm_save_yourself
;
1700 Atom Xatom_wm_delete_window
;
1702 /* Other WM communication */
1703 Atom Xatom_wm_configure_denied
; /* When our config request is denied */
1704 Atom Xatom_wm_window_moved
; /* When the WM moves us. */
1706 /* Read events coming from the X server.
1707 This routine is called by the SIGIO handler.
1708 We return as soon as there are no more events to be read.
1710 Events representing keys are stored in buffer BUFP,
1711 which can hold up to NUMCHARS characters.
1712 We return the number of characters stored into the buffer,
1713 thus pretending to be `read'.
1715 WAITP is nonzero if we should block until input arrives.
1716 EXPECTED is nonzero if the caller knows input is available. */
1719 XTread_socket (sd
, bufp
, numchars
, waitp
, expected
)
1721 register struct input_event
*bufp
;
1722 register int numchars
;
1729 int items_pending
; /* How many items are in the X queue. */
1736 if (x_input_blocked
)
1738 x_pending_input
= 1;
1742 x_pending_input
= 0;
1746 abort (); /* Don't think this happens. */
1749 /* If available, Xlib uses FIOSNBIO to make the socket
1750 non-blocking, and then looks for EWOULDBLOCK. If O_NDELAY is set,
1751 FIOSNBIO is ignored, and instead of signalling EWOULDBLOCK,
1752 a read returns 0, which Xlib interprets as equivalent to EPIPE. */
1753 fcntl (fileno (stdin
), F_SETFL
, 0);
1758 if (! (fcntl (fileno (stdin
), F_GETFL
, 0) & O_NDELAY
))
1760 extern int read_alarm_should_throw
;
1761 read_alarm_should_throw
= 1;
1762 XPeekEvent (XDISPLAY
&event
);
1763 read_alarm_should_throw
= 0;
1768 while (XStuffPending () != 0)
1770 XNextEvent (XDISPLAY
&event
);
1778 if (event
.xclient
.message_type
== Xatom_wm_protocols
1779 && event
.xclient
.format
== 32)
1781 if (event
.xclient
.data
.l
[0] == Xatom_wm_take_focus
)
1783 s
= x_window_to_screen (event
.xclient
.window
);
1785 x_focus_on_screen (s
);
1786 /* Not certain about handling scrollbars here */
1788 else if (event
.xclient
.data
.l
[0] == Xatom_wm_save_yourself
)
1790 /* Save state modify the WM_COMMAND property to
1791 something which can reinstate us. This notifies
1792 the session manager, who's looking for such a
1793 PropertyNotify. Can restart processing when
1794 a keyboard or mouse event arrives. */
1799 else if (event
.xclient
.data
.l
[0] == Xatom_wm_delete_window
)
1801 struct screen
*s
= x_window_to_screen (event
.xclient
.window
);
1809 else if (event
.xclient
.message_type
== Xatom_wm_configure_denied
)
1812 else if (event
.xclient
.message_type
== Xatom_wm_window_moved
)
1816 new_x
= event
.xclient
.data
.s
[0];
1817 new_y
= event
.xclient
.data
.s
[1];
1822 case SelectionClear
: /* Someone has grabbed ownership. */
1823 x_disown_selection (event
.xselectionclear
.window
,
1824 event
.xselectionclear
.selection
,
1825 event
.xselectionclear
.time
);
1828 case SelectionRequest
: /* Someone wants our selection. */
1829 x_answer_selection_request (event
);
1832 case PropertyNotify
:
1833 /* If we were to do this synchronously, there'd be no worry
1834 about re-selecting. */
1835 x_send_incremental (event
);
1839 s
= x_window_to_screen (event
.xexpose
.window
);
1842 if (s
->visible
== 0)
1846 SET_SCREEN_GARBAGED (s
);
1849 dumprectangle (x_window_to_screen (event
.xexpose
.window
),
1850 event
.xexpose
.x
, event
.xexpose
.y
,
1851 event
.xexpose
.width
, event
.xexpose
.height
);
1855 case GraphicsExpose
: /* This occurs when an XCopyArea's
1856 source area was obscured or not
1858 dumprectangle (x_window_to_screen (event
.xgraphicsexpose
.drawable
),
1859 event
.xgraphicsexpose
.x
, event
.xgraphicsexpose
.y
,
1860 event
.xgraphicsexpose
.width
,
1861 event
.xgraphicsexpose
.height
);
1864 case NoExpose
: /* This occurs when an XCopyArea's
1865 source area was completely
1868 #else /* not HAVE_X11 */
1870 if (event
.subwindow
!= 0)
1871 break; /* duplicate event */
1872 s
= x_window_to_screen (event
.window
);
1873 if (event
.window
== s
->display
.x
->icon_desc
)
1878 if (event
.window
== s
->display
.x
->window_desc
)
1880 /* Say must check all windows' needs_exposure flags. */
1881 expose_all_windows
= 1;
1882 s
->display
.x
->needs_exposure
= 1;
1888 if (event
.subwindow
!= 0)
1889 break; /* duplicate event */
1890 s
= x_window_to_screen (event
.window
);
1891 if (event
.window
== s
->display
.x
->icon_desc
)
1896 /* If window already needs full redraw, ignore this rectangle. */
1897 if (expose_all_windows
&& s
->display
.x
->needs_exposure
)
1899 /* Put the event on the queue of rectangles to redraw. */
1900 if (enqueue_event (&event
, &x_expose_queue
))
1901 /* If it is full, we can't record the rectangle,
1902 so redraw this entire window. */
1904 /* Say must check all windows' needs_exposure flags. */
1905 expose_all_windows
= 1;
1906 s
->display
.x
->needs_exposure
= 1;
1911 /* This should happen only when we are expecting it,
1912 in x_read_exposes. */
1914 #endif /* not HAVE_X11 */
1921 s
= x_window_to_screen (event
.xunmap
.window
);
1922 if (s
) /* S may no longer exist if
1923 the screen was deleted. */
1925 /* While a screen is unmapped, display generation is
1926 disabled; you don't want to spend time updating a
1927 display that won't ever be seen. */
1929 x_mouse_x
= x_mouse_y
= -1;
1935 s
= x_window_to_screen (event
.xmap
.window
);
1941 /* wait_reading_process_input will notice this and update
1942 the screen's display structures. */
1943 SET_SCREEN_GARBAGED (s
);
1947 /* Turn off processing if we become fully obscured. */
1948 case VisibilityNotify
:
1953 s
= x_window_to_screen (event
.window
);
1954 if (event
.window
== s
->display
.x
->icon_desc
)
1956 if (event
.window
== s
->display
.x
->window_desc
)
1959 #endif /* HAVE_X11 */
1963 s
= x_window_to_screen (event
.xkey
.window
);
1967 XComposeStatus status
;
1968 char copy_buffer
[80];
1969 int modifiers
= event
.xkey
.state
;
1971 /* Some keyboards generate different characters
1972 depending on the state of the meta key, in an attempt
1973 to support non-English typists. It would be nice to
1974 keep this functionality somehow, but for now, we will
1975 just clear the meta-key flag to get the 'pure' character. */
1976 event
.xkey
.state
&= ~Mod1Mask
;
1978 /* This will have to go some day... */
1979 nbytes
= XLookupString (&event
.xkey
,
1985 /* Strip off the vendor-specific keysym bit, and take a shot
1986 at recognizing the codes. HP servers have extra keysyms
1987 that fit into the MiscFunctionKey category. */
1992 if (IsCursorKey (keysym
) /* 0xff50 <= x < 0xff60 */
1993 || IsMiscFunctionKey (keysym
) /* 0xff60 <= x < 0xff80 */
1994 || IsKeypadKey (keysym
) /* 0xff80 <= x < 0xffbe */
1995 || IsFunctionKey (keysym
)) /* 0xffbe <= x < 0xffe1 */
1997 bufp
->kind
= non_ascii_keystroke
;
1998 XSET (bufp
->code
, Lisp_Int
, (unsigned) keysym
- 0xff50);
1999 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
2000 bufp
->modifiers
= x_convert_modifiers (modifiers
);
2001 XSET (bufp
->timestamp
, Lisp_Int
, event
.xkey
.time
);
2006 else if (numchars
> nbytes
)
2012 if (modifiers
& Mod1Mask
)
2013 *copy_buffer
|= METABIT
;
2014 bufp
->kind
= ascii_keystroke
;
2015 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
2016 XSET (bufp
->code
, Lisp_Int
, *copy_buffer
);
2017 XSET (bufp
->timestamp
, Lisp_Int
, event
.xkey
.time
);
2021 for (i
= nbytes
- 1; i
> 1; i
--)
2023 bufp
->kind
= ascii_keystroke
;
2024 XSET (bufp
->code
, Lisp_Int
, copy_buffer
[i
]);
2025 XSET (bufp
->timestamp
, Lisp_Int
, event
.xkey
.time
);
2026 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
2039 register char *where_mapping
;
2041 s
= x_window_to_screen (event
.window
);
2042 /* Ignore keys typed on icon windows. */
2043 if (s
!= 0 && event
.window
== s
->display
.x
->icon_desc
)
2045 where_mapping
= XLookupMapping (&event
, &nbytes
);
2046 /* Nasty fix for arrow keys */
2047 if (!nbytes
&& IsCursorKey (event
.detail
& 0xff))
2049 switch (event
.detail
& 0xff)
2051 case KC_CURSOR_LEFT
:
2052 where_mapping
= "\002";
2054 case KC_CURSOR_RIGHT
:
2055 where_mapping
= "\006";
2058 where_mapping
= "\020";
2060 case KC_CURSOR_DOWN
:
2061 where_mapping
= "\016";
2066 if (numchars
- nbytes
> 0)
2070 for (i
= 0; i
< nbytes
; i
++)
2072 bufp
->kind
= ascii_keystroke
;
2073 XSET (bufp
->code
, Lisp_Int
, where_mapping
[i
]);
2074 XSET (bufp
->time
, Lisp_Int
, event
.xkey
.time
);
2075 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
2083 #endif /* HAVE_X11 */
2087 s
= x_window_to_screen (event
.xcrossing
.window
);
2089 if (event
.xcrossing
.detail
== NotifyInferior
) /* Left Scrollbar */
2091 else if (event
.xcrossing
.focus
) /* Entered Window */
2093 /* If we decide we want to generate an event to be seen
2094 by the rest of Emacs, we put it here. */
2095 struct input_event emacs_event
;
2096 emacs_event
.kind
= no_event
;
2098 /* Avoid nasty pop/raise loops. */
2099 if (s
&& (!(s
->auto_raise
)
2101 || (event
.xcrossing
.time
- enter_timestamp
) > 500))
2103 x_new_focus_screen (s
);
2104 enter_timestamp
= event
.xcrossing
.time
;
2107 else if ((s
= x_window_to_scrollbar (event
.xcrossing
.window
,
2109 /* Fake a motion event */
2110 notice_mouse_movement (&emacs_event
,
2111 event
.xmotion
, s
, scrollbar_window
,
2116 if (! EQ (Vx_send_mouse_movement_events
, Qnil
)
2118 && emacs_event
.kind
!= no_event
)
2120 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
2127 else if (s
== x_focus_screen
)
2128 x_new_focus_screen (0);
2130 else if (s
= x_window_to_screen (event
.xcrossing
.window
))
2137 s
= x_window_to_screen (event
.xfocus
.window
);
2139 x_new_focus_screen (s
);
2143 if (event
.xcrossing
.detail
!= NotifyInferior
2144 && event
.xcrossing
.subwindow
== None
2145 && event
.xcrossing
.mode
== NotifyNormal
)
2147 s
= x_window_to_screen (event
.xcrossing
.window
);
2148 if (event
.xcrossing
.focus
)
2149 x_new_focus_screen (s
);
2150 else if (s
== x_focus_screen
)
2151 x_new_focus_screen (0);
2156 s
= x_window_to_screen (event
.xfocus
.window
);
2157 if (s
&& s
== x_focus_screen
)
2158 x_new_focus_screen (0);
2161 #else /* not HAVE_X11 */
2164 if ((event
.detail
& 0xFF) == 1)
2165 break; /* Coming from our own subwindow */
2166 if (event
.subwindow
!= 0)
2167 break; /* Entering our own subwindow. */
2170 extern int waiting_for_input
;
2171 struct screen
*old_s
= x_input_screen
;
2173 s
= x_window_to_screen (event
.window
);
2176 if (waiting_for_input
&& x_focus_screen
== 0)
2177 x_new_focus_screen (s
);
2182 if ((event
.detail
& 0xFF) == 1)
2183 break; /* Entering our own subwindow */
2184 if (event
.subwindow
!= 0)
2185 break; /* Leaving our own subwindow. */
2188 if (x_focus_screen
== 0
2189 && x_input_screen
!= 0
2190 && x_input_screen
== x_window_to_screen (event
.window
)
2191 && event
.window
== x_input_screen
->display
.x
->window_desc
)
2196 screen_unhighlight (s
);
2199 #endif /* not HAVE_X11 */
2204 s
= x_window_to_screen (event
.xmotion
.window
);
2206 note_mouse_position (s
, &event
.xmotion
);
2208 else if ((s
= x_window_to_scrollbar (event
.xmotion
.window
,
2211 What should go here
?
2217 case ConfigureNotify
:
2220 s
= x_window_to_screen (event
.xconfigure
.window
);
2224 columns
= ((event
.xconfigure
.width
-
2225 (2 * s
->display
.x
->internal_border_width
)
2226 - s
->display
.x
->v_scrollbar_width
)
2227 / FONT_WIDTH (s
->display
.x
->font
));
2228 rows
= ((event
.xconfigure
.height
-
2229 (2 * s
->display
.x
->internal_border_width
)
2230 - s
->display
.x
->h_scrollbar_height
)
2231 / FONT_HEIGHT (s
->display
.x
->font
));
2233 /* Even if the number of character rows and columns has
2234 not changed, the font size may have changed, so we need
2235 to check the pixel dimensions as well. */
2236 if (columns
!= s
->width
2237 || rows
!= s
->height
2238 || event
.xconfigure
.width
!= s
->display
.x
->pixel_width
2239 || event
.xconfigure
.height
!= s
->display
.x
->pixel_height
)
2241 change_screen_size (s
, rows
, columns
, 0);
2242 x_resize_scrollbars (s
);
2243 SET_SCREEN_GARBAGED (s
);
2246 s
->display
.x
->pixel_width
= event
.xconfigure
.width
;
2247 s
->display
.x
->pixel_height
= event
.xconfigure
.height
;
2248 s
->display
.x
->left_pos
= event
.xconfigure
.x
;
2249 s
->display
.x
->top_pos
= event
.xconfigure
.y
;
2256 /* If we decide we want to generate an event to be seen
2257 by the rest of Emacs, we put it here. */
2258 struct input_event emacs_event
;
2259 emacs_event
.kind
= no_event
;
2261 s
= x_window_to_screen (event
.xbutton
.window
);
2263 if (!x_focus_screen
|| (s
== x_focus_screen
))
2264 construct_mouse_click (&emacs_event
,
2269 if ((s
= x_window_to_scrollbar (event
.xbutton
.window
,
2272 if (!x_focus_screen
|| (selected_screen
== x_focus_screen
))
2273 construct_mouse_click (&emacs_event
,
2274 &event
, s
, part
, prefix
);
2279 if (numchars
>= 1 && emacs_event
.kind
!= no_event
)
2281 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
2289 #else /* not HAVE_X11 */
2291 case ButtonReleased
:
2292 s
= x_window_to_screen (event
.window
);
2295 if (event
.window
== s
->display
.x
->icon_desc
)
2297 x_make_screen_visible (s
);
2299 if (warp_mouse_on_deiconify
)
2300 XWarpMouse (s
->display
.x
->window_desc
, 10, 10);
2303 if (event
.window
== s
->display
.x
->window_desc
)
2309 enqueue_event (&event
, &x_mouse_queue
);
2312 bufp
->kind
= ascii_keystroke
;
2313 bufp
->code
= (char) 'X' & 037; /* C-x */
2314 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
2315 XSET (bufp
->time
, Lisp_Int
, event
.xkey
.time
);
2318 bufp
->kind
= ascii_keystroke
;
2319 bufp
->code
= (char) 0; /* C-@ */
2320 bufp
->screen
= XSCREEN (SCREEN_FOCUS_SCREEN (s
));
2321 XSET (bufp
->time
, Lisp_Int
, event
.xkey
.time
);
2328 #endif /* not HAVE_X11 */
2332 case CirculateNotify
:
2334 case CirculateRequest
:
2337 #endif /* HAVE_X11 */
2340 if (event
.xmapping
.request
== MappingKeyboard
)
2341 /* Someone has changed the keyboard mapping - flush the
2343 XRefreshKeyboardMapping (&event
.xmapping
);
2353 if (expected
&& ! event_found
)
2355 /* AOJ 880406: if select returns true but XPending doesn't, it means that
2356 there is an EOF condition; in other words, that X has died.
2357 Act as if there had been a hangup. */
2359 int fd
= ConnectionNumber (x_current_display
);
2362 if (0 != select (fd
+ 1, &mask
, (long *) 0, (long *) 0,
2364 && !XStuffPending ())
2365 kill (getpid (), SIGHUP
);
2367 #endif /* HAVE_SELECT */
2370 if (updating_screen
== 0)
2371 x_do_pending_expose ();
2378 /* Read and process only Expose events
2379 until we get an ExposeCopy event; then return.
2380 This is used in insert/delete line.
2381 We assume input is already blocked. */
2387 XKeyPressedEvent event
;
2391 /* while there are more events*/
2392 XMaskEvent (ExposeWindow
| ExposeRegion
| ExposeCopy
, &event
);
2396 if (event
.subwindow
!= 0)
2397 break; /* duplicate event */
2398 s
= x_window_to_screen (event
.window
);
2399 if (event
.window
== s
->display
.x
->icon_desc
)
2404 if (event
.window
== s
->display
.x
->window_desc
)
2406 expose_all_windows
= 1;
2407 s
->display
.x
->needs_exposure
= 1;
2413 if (event
.subwindow
!= 0)
2414 break; /* duplicate event */
2415 s
= x_window_to_screen (event
.window
);
2416 if (event
.window
== s
->display
.x
->icon_desc
)
2421 /* If window already needs full redraw, ignore this rectangle. */
2422 if (expose_all_windows
&& s
->display
.x
->needs_exposure
)
2424 /* Put the event on the queue of rectangles to redraw. */
2425 if (enqueue_event (&event
, &x_expose_queue
))
2426 /* If it is full, we can't record the rectangle,
2427 so redraw this entire window. */
2429 /* Say must check all windows' needs_exposure flags. */
2430 expose_all_windows
= 1;
2431 s
->display
.x
->needs_exposure
= 1;
2440 #endif /* HAVE_X11 */
2443 /* Draw a hollow box cursor. Don't change the inside of the box. */
2449 int left
= s
->cursor_x
* FONT_WIDTH (s
->display
.x
->font
)
2450 + s
->display
.x
->internal_border_width
;
2451 int top
= s
->cursor_y
* FONT_HEIGHT (s
->display
.x
->font
)
2452 + s
->display
.x
->internal_border_width
;
2453 int width
= FONT_WIDTH (s
->display
.x
->font
);
2454 int height
= FONT_HEIGHT (s
->display
.x
->font
);
2457 /* Perhaps we should subtract 1 from width and height... */
2458 XDrawRectangle (x_current_display
, s
->display
.x
->window_desc
,
2459 s
->display
.x
->cursor_gc
,
2460 left
, top
, width
- 1, height
- 1);
2462 XPixSet (s
->display
.x
->window_desc
,
2463 left
, top
, width
, 1,
2464 s
->display
.x
->cursor_pixel
);
2466 XPixSet (s
->display
.x
->window_desc
,
2467 left
, top
, 1, height
,
2468 s
->display
.x
->cursor_pixel
);
2470 XPixSet (s
->display
.x
->window_desc
,
2471 left
+width
-1, top
, 1, height
,
2472 s
->display
.x
->cursor_pixel
);
2474 XPixSet (s
->display
.x
->window_desc
,
2475 left
, top
+height
-1, width
, 1,
2476 s
->display
.x
->cursor_pixel
);
2477 #endif /* HAVE_X11 */
2480 /* Clear the cursor of screen S to background color,
2481 and mark the cursor as not shown.
2482 This is used when the text where the cursor is
2483 is about to be rewritten. */
2492 || s
->phys_cursor_x
< 0)
2496 x_display_cursor (s
, 0);
2498 XClearArea (x_current_display
, s
->display
.x
->window_desc
,
2499 s
->phys_cursor_x
* FONT_WIDTH (s
->display
.x
->font
)
2500 + s
->display
.x
->internal_border_width
,
2501 s
->phys_cursor_y
* FONT_HEIGHT (s
->display
.x
->font
)
2502 + s
->display
.x
->internal_border_width
,
2503 FONT_WIDTH (s
->display
.x
->font
) + 1, FONT_HEIGHT (s
->display
.x
->font
) + 1, False
);
2506 XPixSet (s
->display
.x
->window_desc
,
2507 s
->phys_cursor_x
* FONT_WIDTH (s
->display
.x
->font
) + s
->display
.x
->internal_border_width
,
2508 s
->phys_cursor_y
* FONT_HEIGHT (s
->display
.x
->font
) + s
->display
.x
->internal_border_width
,
2509 FONT_WIDTH (s
->display
.x
->font
), FONT_HEIGHT (s
->display
.x
->font
),
2510 s
->display
.x
->background_pixel
);
2511 #endif /* HAVE_X11 */
2512 s
->phys_cursor_x
= -1;
2516 x_display_bar_cursor (s
, on
)
2520 register int phys_x
= s
->phys_cursor_x
;
2521 register int phys_y
= s
->phys_cursor_y
;
2526 if (! s
->visible
|| (! on
&& s
->phys_cursor_x
< 0))
2531 (!on
|| phys_x
!= s
->cursor_x
|| phys_y
!= s
->cursor_y
))
2533 x1
= phys_x
* FONT_WIDTH (s
->display
.x
->font
)
2534 + s
->display
.x
->internal_border_width
;
2535 y1
= phys_y
* FONT_HEIGHT (s
->display
.x
->font
)
2536 + s
->display
.x
->internal_border_width
- 1;
2537 y2
= y1
+ FONT_HEIGHT (s
->display
.x
->font
) + 1;
2539 XDrawLine (x_current_display
, s
->display
.x
->window_desc
,
2540 s
->display
.x
->reverse_gc
, x1
, y1
, x1
, y2
);
2542 s
->phys_cursor_x
= phys_x
= -1;
2545 if (on
&& s
== x_highlight_screen
)
2547 x1
= s
->cursor_x
* FONT_WIDTH (s
->display
.x
->font
)
2548 + s
->display
.x
->internal_border_width
;
2549 y1
= s
->cursor_y
* FONT_HEIGHT (s
->display
.x
->font
)
2550 + s
->display
.x
->internal_border_width
- 1;
2551 y2
= y1
+ FONT_HEIGHT (s
->display
.x
->font
) + 1;
2553 XDrawLine (x_current_display
, s
->display
.x
->window_desc
,
2554 s
->display
.x
->cursor_gc
, x1
, y1
, x1
, y2
);
2556 s
->phys_cursor_x
= s
->cursor_x
;
2557 s
->phys_cursor_y
= s
->cursor_y
;
2565 /* Redraw the glyph at ROW, COLUMN on screen S, in the style
2566 HIGHLIGHT. HIGHLIGHT is as defined for dumpglyphs. Return the
2570 x_draw_single_glyph (s
, row
, column
, glyph
, highlight
)
2577 (column
* FONT_WIDTH (s
->display
.x
->font
)
2578 + s
->display
.x
->internal_border_width
),
2579 (row
* FONT_HEIGHT (s
->display
.x
->font
)
2580 + s
->display
.x
->internal_border_width
),
2581 &glyph
, 1, highlight
, s
->display
.x
->font
);
2584 /* Turn the displayed cursor of screen S on or off according to ON.
2585 If ON is nonzero, where to put the cursor is specified
2586 by S->cursor_x and S->cursor_y. */
2589 x_display_box_cursor (s
, on
)
2593 struct screen_glyphs
*current_glyphs
= SCREEN_CURRENT_GLYPHS (s
);
2598 /* If cursor is off and we want it off, return quickly. */
2599 if (!on
&& s
->phys_cursor_x
< 0)
2602 /* If cursor is currently being shown and we don't want it to be
2603 or it is in the wrong place,
2604 or we want a hollow box and it's not so, (pout!)
2606 if (s
->phys_cursor_x
>= 0
2608 || s
->phys_cursor_x
!= s
->cursor_x
2609 || s
->phys_cursor_y
!= s
->cursor_y
2610 || (s
->display
.x
->text_cursor_kind
!= hollow_box_cursor
2611 && (s
!= x_highlight_screen
))))
2613 /* Erase the cursor by redrawing the character underneath it. */
2614 x_draw_single_glyph (s
, s
->phys_cursor_y
, s
->phys_cursor_x
,
2615 s
->phys_cursor_glyph
,
2616 current_glyphs
->highlight
[s
->phys_cursor_y
]);
2617 s
->phys_cursor_x
= -1;
2620 /* If we want to show a cursor,
2621 or we want a box cursor and it's not so,
2622 write it in the right place. */
2624 && (s
->phys_cursor_x
< 0
2625 || (s
->display
.x
->text_cursor_kind
!= filled_box_cursor
2626 && s
== x_highlight_screen
)))
2628 s
->phys_cursor_glyph
2629 = ((current_glyphs
->enable
[s
->cursor_y
]
2630 && s
->cursor_x
< current_glyphs
->used
[s
->cursor_y
])
2631 ? current_glyphs
->glyphs
[s
->cursor_y
][s
->cursor_x
]
2633 if (s
!= x_highlight_screen
)
2636 s
->display
.x
->text_cursor_kind
= hollow_box_cursor
;
2640 x_draw_single_glyph (s
, s
->cursor_y
, s
->cursor_x
,
2641 s
->phys_cursor_glyph
, 2);
2642 s
->display
.x
->text_cursor_kind
= filled_box_cursor
;
2645 s
->phys_cursor_x
= s
->cursor_x
;
2646 s
->phys_cursor_y
= s
->cursor_y
;
2649 if (updating_screen
!= s
)
2653 extern Lisp_Object Vbar_cursor
;
2655 x_display_cursor (s
, on
)
2659 if (EQ (Vbar_cursor
, Qnil
))
2660 x_display_box_cursor (s
, on
);
2662 x_display_bar_cursor (s
, on
);
2667 /* Refresh bitmap kitchen sink icon for screen S
2668 when we get an expose event for it. */
2674 /* Normally, the window manager handles this function. */
2678 if (s
->display
.x
->icon_bitmap_flag
)
2679 XBitmapBitsPut (s
->display
.x
->icon_desc
, 0, 0, sink_width
, sink_height
,
2680 sink_bits
, BlackPixel
, WHITE_PIX_DEFAULT
,
2681 icon_bitmap
, GXcopy
, AllPlanes
);
2684 extern struct screen
*selected_screen
;
2685 struct Lisp_String
*str
;
2686 unsigned char *string
;
2689 = XSTRING (XBUFFER (XWINDOW (s
->selected_window
)->buffer
)->name
)->data
;
2691 if (s
->display
.x
->icon_label
!= string
)
2693 s
->display
.x
->icon_label
= string
;
2694 XChangeWindow (s
->display
.x
->icon_desc
,
2695 XQueryWidth (string
, icon_font_info
->id
) + 10,
2696 icon_font_info
->height
+ 10);
2699 XText (s
->display
.x
->icon_desc
, 5, 5, string
,
2700 str
->size
, icon_font_info
->id
,
2701 BLACK_PIX_DEFAULT
, WHITE_PIX_DEFAULT
);
2704 #endif /* HAVE_X11 */
2707 /* Make the x-window of screen S use the kitchen-sink icon
2708 that's a window generated by Emacs. */
2717 if (s
->display
.x
->window_desc
== 0)
2722 XFreePixmap (x_current_display
, icon_bitmap
);
2725 XCreateBitmapFromData (x_current_display
, s
->display
.x
->window_desc
,
2726 gnu_bits
, gnu_width
, gnu_height
);
2727 x_wm_set_icon_pixmap (s
, icon_bitmap
);
2728 s
->display
.x
->icon_bitmap_flag
= 1;
2730 if (s
->display
.x
->icon_desc
)
2732 XClearIconWindow (s
->display
.x
->window_desc
);
2733 XDestroyWindow (s
->display
.x
->icon_desc
);
2736 icon_window
= XCreateWindow (s
->display
.x
->parent_desc
,
2737 0, 0, sink_width
, sink_height
,
2738 2, WhitePixmap
, (Pixmap
) NULL
);
2740 if (icon_window
== 0)
2743 XSetIconWindow (s
->display
.x
->window_desc
, icon_window
);
2744 XSelectInput (icon_window
, ExposeWindow
| UnmapWindow
);
2746 s
->display
.x
->icon_desc
= icon_window
;
2747 s
->display
.x
->icon_bitmap_flag
= 1;
2749 if (icon_bitmap
== 0)
2751 = XStoreBitmap (sink_mask_width
, sink_mask_height
, sink_mask_bits
);
2752 #endif /* HAVE_X11 */
2758 /* Make the x-window of screen S use a rectangle with text. */
2761 x_text_icon (s
, icon_name
)
2769 char *X_DefaultValue
;
2773 #define WhitePixel 1
2777 #define BlackPixel 0
2779 #endif /* not HAVE_X11 */
2781 if (s
->display
.x
->window_desc
== 0)
2784 if (icon_font_info
== 0)
2786 = XGetFont (XGetDefault (XDISPLAY
2787 (char *) XSTRING (invocation_name
)->data
,
2792 s
->display
.x
->icon_label
= icon_name
;
2794 if (! s
->display
.x
->icon_label
)
2795 s
->display
.x
->icon_label
= " *emacs* ";
2797 XSetIconName (x_current_display
, s
->display
.x
->window_desc
,
2798 (char *) s
->display
.x
->icon_label
);
2800 s
->display
.x
->icon_bitmap_flag
= 0;
2802 if (s
->display
.x
->icon_desc
)
2804 XClearIconWindow (XDISPLAY s
->display
.x
->window_desc
);
2805 XDestroyWindow (XDISPLAY s
->display
.x
->icon_desc
);
2809 s
->display
.x
->icon_label
= (unsigned char *) icon_name
;
2811 if (! s
->display
.x
->icon_label
)
2812 s
->display
.x
->icon_label
= XSTRING (s
->name
)->data
;
2814 width
= XStringWidth (s
->display
.x
->icon_label
, icon_font_info
, 0, 0);
2815 icon_window
= XCreateWindow (s
->display
.x
->parent_desc
,
2816 s
->display
.x
->left_pos
,
2817 s
->display
.x
->top_pos
,
2818 width
+ 10, icon_font_info
->height
+ 10,
2819 2, BlackPixmap
, WhitePixmap
);
2821 if (icon_window
== 0)
2824 XSetIconWindow (s
->display
.x
->window_desc
, icon_window
);
2825 XSelectInput (icon_window
, ExposeWindow
| ExposeRegion
| UnmapWindow
| ButtonPressed
);
2827 s
->display
.x
->icon_desc
= icon_window
;
2828 s
->display
.x
->icon_bitmap_flag
= 0;
2829 s
->display
.x
->icon_label
= 0;
2830 #endif /* HAVE_X11 */
2835 /* Handling X errors. */
2837 /* A handler for SIGPIPE, when it occurs on the X server's connection.
2838 This basically does an orderly shutdown of Emacs. */
2845 Fkill_emacs (make_number (70));
2848 static char *x_proto_requests
[] =
2851 "ChangeWindowAttributes",
2852 "GetWindowAttributes",
2854 "DestroySubwindows",
2871 "SetSelectionOwner",
2872 "GetSelectionOwner",
2879 "ChangeActivePointerGrab",
2899 "ListFontsWithInfo",
2908 "SetClipRectangles",
2919 "PolyFillRectangle",
2929 "CopyColormapAndFree",
2931 "UninstallColormap",
2932 "ListInstalledColormaps",
2943 "CreateGlyphCursor",
2949 "ChangeKeyboardMapping",
2950 "GetKeyboardMapping",
2951 "ChangeKeyboardControl",
2952 "GetKeyboardControl",
2954 "ChangePointerControl",
2955 "GetPointerControl",
2965 "SetPointerMapping",
2966 "GetPointerMapping",
2967 "SetModifierMapping",
2968 "GetModifierMapping",
2972 #define acceptable_x_error_p(type) ((type) == 94)
2974 x_handle_error_gracefully (event
)
2977 char error_ptr
[128];
2978 char *proto_ptr
= x_proto_requests
[event
->request_code
];
2981 XGetErrorText (x_current_display
, event
->error_code
, error_ptr
, 128);
2982 sprintf (str
, "X Protocol Error: %s on request: %s", error_ptr
, proto_ptr
);
2983 TOTALLY_UNBLOCK_INPUT
;
2988 extern int x_selection_alloc_error
;
2989 extern int x_converting_selection
;
2992 /* Handle X Errors. If the error is not traumatic,
2993 just call error (). Otherwise print a (hopefully) interesting
2996 The arg to Fkill_emacs is an exit status value
2997 and also prevents any questions. */
2999 x_error_handler (disp
, event
)
3004 #define XlibDisplayIOError (1L << 0)
3007 struct _XErrorEvent
*event
;
3010 /* Here we use the standard X handlers. */
3013 if (event
&& event
->type
== 0) /* 0 is the XError Event type. */
3017 if (event
->request_code
== BadAlloc
&& x_converting_selection
)
3018 x_selection_alloc_error
= 1;
3022 if (acceptable_x_error_p (event
->request_code
))
3023 x_handle_error_gracefully (event
);
3025 _XDefaultError (disp
, event
);
3029 disp
->flags
|= XlibDisplayIOError
;
3030 _XDefaultIOError (disp
);
3038 static unsigned int x_wire_count
;
3041 fprintf (stderr
, "Lib call: %d\n", ++x_wire_count
);
3046 /* Set the font of the x-window specified by screen S
3047 to the font named NEWNAME. This is safe to use
3048 even before S has an actual x-window. */
3052 /* A table of all the fonts we have already loaded. */
3053 static XFontStruct
**x_font_table
;
3055 /* The current capacity of x_font_table. */
3056 static int x_font_table_size
;
3058 /* The number of fonts actually stored in x_font_table.
3059 x_font_table[n] is used and valid iff 0 <= n < n_fonts.
3060 0 <= n_fonts <= x_font_table_size. */
3063 x_new_font (s
, fontname
)
3065 register char *fontname
;
3069 int n_matching_fonts
;
3070 XFontStruct
*font_info
;
3073 /* Get a list of all the fonts that match this name. Once we
3074 have a list of matching fonts, we compare them against the fonts
3075 we already have by comparing font ids. */
3076 font_names
= (char **) XListFontsWithInfo (x_current_display
, fontname
,
3077 1024, &n_matching_fonts
,
3079 /* If the server couldn't find any fonts whose named matched fontname,
3080 return an error code. */
3081 if (n_matching_fonts
== 0)
3084 /* See if we've already loaded a matching font. */
3089 for (i
= 0; i
< n_fonts
; i
++)
3090 for (j
= 0; j
< n_matching_fonts
; j
++)
3091 if (x_font_table
[i
]->fid
== font_info
[j
].fid
)
3099 /* If we have, just return it from the table. */
3101 s
->display
.x
->font
= x_font_table
[already_loaded
];
3103 /* Otherwise, load the font and add it to the table. */
3108 font
= (XFontStruct
*) XLoadQueryFont (x_current_display
, fontname
);
3112 /* Do we need to create the table? */
3113 if (x_font_table_size
== 0)
3115 x_font_table_size
= 16;
3117 = (XFontStruct
**) xmalloc (x_font_table_size
3118 * sizeof (x_font_table
[0]));
3120 /* Do we need to grow the table? */
3121 else if (n_fonts
>= x_font_table_size
)
3123 x_font_table_size
*= 2;
3125 = (XFontStruct
**) xrealloc (x_font_table
,
3127 * sizeof (x_font_table
[0])));
3130 s
->display
.x
->font
= x_font_table
[n_fonts
++] = font
;
3133 /* Free the information from XListFontsWithInfo. The data
3134 we actually retain comes from XLoadQueryFont. */
3135 XFreeFontInfo (font_names
, font_info
, n_matching_fonts
);
3137 /* Now make the screen display the given font. */
3138 if (s
->display
.x
->window_desc
!= 0)
3140 XSetFont (x_current_display
, s
->display
.x
->normal_gc
,
3141 s
->display
.x
->font
->fid
);
3142 XSetFont (x_current_display
, s
->display
.x
->reverse_gc
,
3143 s
->display
.x
->font
->fid
);
3144 XSetFont (x_current_display
, s
->display
.x
->cursor_gc
,
3145 s
->display
.x
->font
->fid
);
3147 x_set_window_size (s
, s
->width
, s
->height
);
3153 x_new_font (s
, newname
)
3155 register char *newname
;
3160 temp
= XGetFont (newname
);
3161 if (temp
== (FONT_TYPE
*) 0)
3164 if (s
->display
.x
->font
)
3165 XLoseFont (s
->display
.x
->font
);
3167 s
->display
.x
->font
= temp
;
3169 if (s
->display
.x
->window_desc
!= 0)
3170 x_set_window_size (s
, s
->width
, s
->height
);
3176 x_calc_absolute_position (s
)
3180 if (s
->display
.x
->left_pos
< 0)
3181 s
->display
.x
->left_pos
3182 = XINT (x_screen_width
) - PIXEL_WIDTH (s
) + s
->display
.x
->left_pos
;
3184 if (s
->display
.x
->top_pos
< 0)
3185 s
->display
.x
->top_pos
3186 = XINT (x_screen_height
) - PIXEL_HEIGHT (s
) + s
->display
.x
->top_pos
;
3188 WINDOWINFO_TYPE parentinfo
;
3190 XGetWindowInfo (s
->display
.x
->window_desc
, &parentinfo
);
3192 if (s
->display
.x
->left_pos
< 0)
3193 s
->display
.x
->left_pos
= parentinfo
.width
+ (s
->display
.x
->left_pos
+ 1)
3194 - PIXEL_WIDTH (s
) - 2 * s
->display
.x
->internal_border_width
;
3196 if (s
->display
.x
->top_pos
< 0)
3197 s
->display
.x
->top_pos
= parentinfo
.height
+ (s
->display
.x
->top_pos
+ 1)
3198 - PIXEL_HEIGHT (s
) - 2 * s
->display
.x
->internal_border_width
;
3202 x_set_offset (s
, xoff
, yoff
)
3204 register int xoff
, yoff
;
3206 s
->display
.x
->top_pos
= yoff
;
3207 s
->display
.x
->left_pos
= xoff
;
3208 x_calc_absolute_position (s
);
3211 XMoveWindow (XDISPLAY s
->display
.x
->window_desc
,
3212 s
->display
.x
->left_pos
, s
->display
.x
->top_pos
);
3214 x_wm_set_size_hint (s
, 0);
3219 /* Call this to change the size of screen S's x-window. */
3221 x_set_window_size (s
, cols
, rows
)
3223 register int cols
, rows
;
3225 int pixelwidth
, pixelheight
;
3227 int ibw
= s
->display
.x
->internal_border_width
;
3231 /* ??? Who DOES worry about minimum reasonable sizes? */
3232 pixelwidth
= (cols
* FONT_WIDTH (s
->display
.x
->font
) + 2 * ibw
3233 + s
->display
.x
->v_scrollbar_width
);
3234 pixelheight
= (rows
* FONT_HEIGHT (s
->display
.x
->font
) + 2 * ibw
3235 + s
->display
.x
->h_scrollbar_height
);
3238 x_wm_set_size_hint (s
, 0);
3239 #endif /* HAVE_X11 */
3240 XChangeWindowSize (s
->display
.x
->window_desc
, pixelwidth
, pixelheight
);
3246 x_set_resize_hint (s
)
3250 XSetResizeHint (s
->display
.x
->window_desc
, 2 * s
->display
.x
->internal_border_width
,
3251 2 * s
->display
.x
->internal_border_width
,
3252 FONT_WIDTH (s
->display
.x
->font
), FONT_HEIGHT (s
->display
.x
->font
));
3254 #endif /* not HAVE_X11 */
3257 x_set_mouse_position (s
, x
, y
)
3266 pix_x
= (SCREEN_WIDTH (s
)
3267 * FONT_WIDTH (s
->display
.x
->font
)
3268 + 2 * s
->display
.x
->internal_border_width
3269 + s
->display
.x
->v_scrollbar_width
) / 2;
3271 pix_x
= x
* FONT_WIDTH (s
->display
.x
->font
) + 2; /* add 2 pixels to each
3272 dimension to move the
3277 pix_y
= (SCREEN_HEIGHT (s
)
3278 * FONT_HEIGHT (s
->display
.x
->font
)
3279 + 2 * s
->display
.x
->internal_border_width
3280 + s
->display
.x
->h_scrollbar_height
) / 2;
3282 pix_y
= y
* FONT_HEIGHT (s
->display
.x
->font
) + 2;
3288 XWarpMousePointer (s
->display
.x
->window_desc
, pix_x
, pix_y
);
3293 x_focus_on_screen (s
)
3298 /* I don't think that the ICCCM allows programs to do things like this
3299 without the interaction of the window manager. Whatever you end up
3300 doing with this code, do it to x_unfocus_screen too. */
3301 XSetInputFocus (x_current_display
, s
->display
.x
->window_desc
,
3302 RevertToPointerRoot
, CurrentTime
);
3306 x_unfocus_screen (s
)
3310 /* Look at the remarks in x_focus_on_screen. */
3311 if (x_focus_screen
== s
)
3312 XSetInputFocus (x_current_display
, PointerRoot
,
3313 RevertToPointerRoot
, CurrentTime
);
3319 /* Raise screen S. */
3327 XRaiseWindow (XDISPLAY s
->display
.x
->window_desc
);
3333 /* Lower screen S. */
3341 XLowerWindow (XDISPLAY s
->display
.x
->window_desc
);
3347 /* Change from withdrawn state to mapped state. */
3349 x_make_screen_visible (s
)
3356 if (! SCREEN_VISIBLE_P (s
))
3359 if (! EQ (Vx_no_window_manager
, Qt
))
3360 x_wm_set_window_state (s
, NormalState
);
3362 XMapWindow (XDISPLAY s
->display
.x
->window_desc
);
3363 if (s
->display
.x
->v_scrollbar
!= 0 || s
->display
.x
->h_scrollbar
!= 0)
3364 XMapSubwindows (x_current_display
, s
->display
.x
->window_desc
);
3366 XMapWindow (XDISPLAY s
->display
.x
->window_desc
);
3367 if (s
->display
.x
->icon_desc
!= 0)
3368 XUnmapWindow (s
->display
.x
->icon_desc
);
3370 /* Handled by the MapNotify event for X11 */
3374 /* NOTE: this may cause problems for the first screen. */
3376 #endif /* not HAVE_X11 */
3384 /* Change from mapped state to withdrawn state. */
3386 x_make_screen_invisible (s
)
3397 if (! EQ (Vx_no_window_manager
, Qt
))
3401 unmap
.type
= UnmapNotify
;
3402 unmap
.window
= s
->display
.x
->window_desc
;
3403 unmap
.event
= DefaultRootWindow (x_current_display
);
3404 unmap
.from_configure
= False
;
3405 XSendEvent (x_current_display
, DefaultRootWindow (x_current_display
),
3406 False
, SubstructureRedirectMask
|SubstructureNotifyMask
,
3410 /* The new function below does the same as the above code, plus unmapping
3411 the window. Sending the event without actually unmapping can make
3412 the window manager start ignoring the window (i.e., no more title bar,
3413 icon manager stuff.) */
3416 /* New function available with R4 */
3417 if (! XWithdrawWindow (x_current_display
, s
->display
.x
->window_desc
,
3418 DefaultScreen (x_current_display
)))
3420 UNBLOCK_INPUT_RESIGNAL
;
3421 error ("Can't notify window manager of iconification.");
3425 XUnmapWindow (XDISPLAY s
->display
.x
->window_desc
);
3427 s
->visible
= 0; /* Handled by the UnMap event for X11 */
3428 if (s
->display
.x
->icon_desc
!= 0)
3429 XUnmapWindow (XDISPLAY s
->display
.x
->icon_desc
);
3430 #endif /* not HAVE_X11 */
3436 /* Window manager communication. Created in Fx_open_connection. */
3437 extern Atom Xatom_wm_change_state
;
3439 /* Change window state from mapped to iconified. */
3441 x_iconify_screen (s
)
3452 if (! EQ (Vx_no_window_manager
, Qt
))
3453 if (! XIconifyWindow (x_current_display
, s
->display
.x
->window_desc
,
3454 DefaultScreen (x_current_display
)))
3456 UNBLOCK_INPUT_RESIGNAL
;
3457 error ("Can't notify window manager of iconification.");
3464 XClientMessageEvent message
;
3466 message
.window
= s
->display
.x
->window_desc
;
3467 message
.type
= ClientMessage
;
3468 message
.message_type
= Xatom_wm_change_state
;
3469 message
.format
= 32;
3470 message
.data
.l
[0] = IconicState
;
3472 if (! XSendEvent (x_current_display
,
3473 DefaultRootWindow (x_current_display
),
3475 SubstructureRedirectMask
| SubstructureNotifyMask
,
3478 UNBLOCK_INPUT_RESIGNAL
;
3479 error ("Can't notify window manager of iconification.");
3484 XUnmapWindow (XDISPLAY s
->display
.x
->window_desc
);
3486 s
->visible
= 0; /* Handled in the UnMap event for X11. */
3487 if (s
->display
.x
->icon_desc
!= 0)
3489 XMapWindow (XDISPLAY s
->display
.x
->icon_desc
);
3498 /* Destroy the X window of screen S.
3499 DISPL is the former s->display (since s->display
3500 has already been nulled out). */
3502 x_destroy_window (s
, displ
)
3504 union display displ
;
3509 if (displ
.x
->icon_desc
!= 0)
3510 XDestroyWindow (XDISPLAY displ
.x
->icon_desc
);
3511 XDestroyWindow (XDISPLAY displ
.x
->window_desc
);
3516 if (s
== x_focus_screen
)
3518 if (s
== x_highlight_screen
)
3519 x_highlight_screen
= 0;
3524 /* Manage event queues.
3526 This code is only used by the X10 support.
3528 We cannot leave events in the X queue and get them when we are ready
3529 because X does not provide a subroutine to get only a certain kind
3530 of event but not block if there are no queued events of that kind.
3532 Therefore, we must examine events as they come in and copy events
3533 of certain kinds into our private queues.
3535 All ExposeRegion events are put in x_expose_queue.
3536 All ButtonPressed and ButtonReleased events are put in x_mouse_queue. */
3539 /* Write the event *P_XREP into the event queue *QUEUE.
3540 If the queue is full, do nothing, but return nonzero. */
3543 enqueue_event (p_xrep
, queue
)
3544 register XEvent
*p_xrep
;
3545 register struct event_queue
*queue
;
3547 int newindex
= queue
->windex
+ 1;
3548 if (newindex
== EVENT_BUFFER_SIZE
)
3550 if (newindex
== queue
->rindex
)
3552 queue
->xrep
[queue
->windex
] = *p_xrep
;
3553 queue
->windex
= newindex
;
3557 /* Fetch the next event from queue *QUEUE and store it in *P_XREP.
3558 If *QUEUE is empty, do nothing and return 0. */
3561 dequeue_event (p_xrep
, queue
)
3562 register XEvent
*p_xrep
;
3563 register struct event_queue
*queue
;
3565 if (queue
->windex
== queue
->rindex
)
3567 *p_xrep
= queue
->xrep
[queue
->rindex
++];
3568 if (queue
->rindex
== EVENT_BUFFER_SIZE
)
3573 /* Return the number of events buffered in *QUEUE. */
3576 queue_event_count (queue
)
3577 register struct event_queue
*queue
;
3579 int tem
= queue
->windex
- queue
->rindex
;
3582 return EVENT_BUFFER_SIZE
+ tem
;
3585 /* Return nonzero if mouse input is pending. */
3588 mouse_event_pending_p ()
3590 return queue_event_count (&x_mouse_queue
);
3596 x_wm_set_size_hint (s
, prompting
)
3600 XSizeHints size_hints
;
3601 Window window
= s
->display
.x
->window_desc
;
3603 size_hints
.flags
= PResizeInc
| PMinSize
| PMaxSize
;
3605 flexlines
= s
->height
;
3607 size_hints
.x
= s
->display
.x
->left_pos
;
3608 size_hints
.y
= s
->display
.x
->top_pos
;
3609 size_hints
.height
= PIXEL_HEIGHT (s
);
3610 size_hints
.width
= PIXEL_WIDTH (s
);
3611 size_hints
.width_inc
= FONT_WIDTH (s
->display
.x
->font
);
3612 size_hints
.height_inc
= FONT_HEIGHT (s
->display
.x
->font
);
3613 size_hints
.base_width
= (2 * s
->display
.x
->internal_border_width
)
3614 + s
->display
.x
->v_scrollbar_width
;
3615 size_hints
.base_height
= (2 * s
->display
.x
->internal_border_width
)
3616 + s
->display
.x
->h_scrollbar_height
;
3617 size_hints
.min_width
= size_hints
.base_width
+ size_hints
.width_inc
;
3618 size_hints
.min_height
= size_hints
.base_height
+ size_hints
.height_inc
;
3619 size_hints
.max_width
= x_screen_width
3620 - ((2 * s
->display
.x
->internal_border_width
)
3621 + s
->display
.x
->v_scrollbar_width
);
3622 size_hints
.max_height
= x_screen_height
3623 - ((2 * s
->display
.x
->internal_border_width
)
3624 + s
->display
.x
->h_scrollbar_height
);
3627 size_hints
.flags
|= prompting
;
3630 XSizeHints hints
; /* Sometimes I hate X Windows... */
3632 XGetNormalHints (x_current_display
, window
, &hints
);
3633 if (hints
.flags
& PSize
)
3634 size_hints
.flags
|= PSize
;
3635 if (hints
.flags
& PPosition
)
3636 size_hints
.flags
|= PPosition
;
3637 if (hints
.flags
& USPosition
)
3638 size_hints
.flags
|= USPosition
;
3639 if (hints
.flags
& USSize
)
3640 size_hints
.flags
|= USSize
;
3644 XSetNormalHints (x_current_display
, window
, &size_hints
);
3646 XSetWMNormalHints (x_current_display
, window
, &size_hints
);
3649 /* Used for IconicState or NormalState */
3650 x_wm_set_window_state (s
, state
)
3655 Window window
= s
->display
.x
->window_desc
;
3657 wm_hints
.flags
= StateHint
;
3658 wm_hints
.initial_state
= state
;
3659 XSetWMHints (x_current_display
, window
, &wm_hints
);
3662 x_wm_set_icon_pixmap (s
, icon_pixmap
)
3667 Window window
= s
->display
.x
->window_desc
;
3669 wm_hints
.flags
= IconPixmapHint
;
3670 wm_hints
.icon_pixmap
= icon_pixmap
;
3671 XSetWMHints (x_current_display
, window
, &wm_hints
);
3674 x_wm_set_icon_position (s
, icon_x
, icon_y
)
3679 Window window
= s
->display
.x
->window_desc
;
3681 wm_hints
.flags
= IconPositionHint
;
3682 wm_hints
.icon_x
= icon_x
;
3683 wm_hints
.icon_y
= icon_y
;
3684 XSetWMHints (x_current_display
, window
, &wm_hints
);
3689 x_term_init (display_name
)
3695 extern int old_fcntl_owner
;
3698 x_focus_screen
= x_highlight_screen
= 0;
3700 x_current_display
= XOpenDisplay (display_name
);
3701 if (x_current_display
== 0)
3702 fatal ("X server %s not responding; check the DISPLAY environment variable or use \"-d\"\n",
3707 int hostname_size
= MAXHOSTNAMELEN
+ 1;
3709 hostname
= (char *) xmalloc (hostname_size
);
3712 XSetAfterFunction (x_current_display
, x_trace_wire
);
3715 invocation_name
= Ffile_name_nondirectory (Fcar (Vcommand_line_args
));
3717 /* Try to get the host name; if the buffer is too short, try
3718 again. Apparently, the only indication gethostname gives of
3719 whether the buffer was large enough is the presence or absence
3720 of a '\0' in the string. Eech. */
3723 gethostname (hostname
, hostname_size
- 1);
3724 hostname
[hostname_size
- 1] = '\0';
3726 /* Was the buffer large enough for gethostname to store the '\0'? */
3727 if (strlen (hostname
) < hostname_size
- 1)
3730 hostname_size
<<= 1;
3731 hostname
= (char *) xrealloc (hostname
, hostname_size
);
3733 x_id_name
= (char *) xmalloc (XSTRING (invocation_name
)->size
3736 sprintf (x_id_name
, "%s@%s", XSTRING (invocation_name
)->data
, hostname
);
3739 dup2 (ConnectionNumber (x_current_display
), 0);
3741 #ifndef SYSV_STREAMS
3742 /* Streams somehow keeps track of which descriptor number
3743 is being used to talk to X. So it is not safe to substitute
3744 descriptor 0. But it is safe to make descriptor 0 a copy of it. */
3745 close (ConnectionNumber (x_current_display
));
3746 ConnectionNumber (x_current_display
) = 0; /* Looks a little strange?
3747 * check the def of the macro;
3748 * it is a genuine lvalue */
3749 #endif /* not SYSV_STREAMS */
3751 #endif /* HAVE_X11 */
3754 old_fcntl_owner
= fcntl (0, F_GETOWN
, 0);
3755 #ifdef F_SETOWN_SOCK_NEG
3756 fcntl (0, F_SETOWN
, -getpid ()); /* stdin is a socket here */
3758 fcntl (0, F_SETOWN
, getpid ());
3759 #endif /* F_SETOWN_SOCK_NEG */
3760 #endif /* F_SETOWN */
3766 /* Must use interrupt input because we cannot otherwise
3767 arrange for C-g to be noticed immediately.
3768 We cannot connect it to SIGINT. */
3769 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
3771 expose_all_windows
= 0;
3773 clear_screen_hook
= XTclear_screen
;
3774 clear_end_of_line_hook
= XTclear_end_of_line
;
3775 ins_del_lines_hook
= XTins_del_lines
;
3776 change_line_highlight_hook
= XTchange_line_highlight
;
3777 insert_glyphs_hook
= XTinsert_glyphs
;
3778 write_glyphs_hook
= XTwrite_glyphs
;
3779 delete_glyphs_hook
= XTdelete_glyphs
;
3780 ring_bell_hook
= XTring_bell
;
3781 reset_terminal_modes_hook
= XTreset_terminal_modes
;
3782 set_terminal_modes_hook
= XTset_terminal_modes
;
3783 update_begin_hook
= XTupdate_begin
;
3784 update_end_hook
= XTupdate_end
;
3785 set_terminal_window_hook
= XTset_terminal_window
;
3786 read_socket_hook
= XTread_socket
;
3787 cursor_to_hook
= XTcursor_to
;
3788 reassert_line_highlight_hook
= XTreassert_line_highlight
;
3789 screen_rehighlight_hook
= XTscreen_rehighlight
;
3790 mouse_position_hook
= XTmouse_position
;
3792 scroll_region_ok
= 1; /* we'll scroll partial screens */
3793 char_ins_del_ok
= 0; /* just as fast to write the line */
3794 line_ins_del_ok
= 1; /* we'll just blt 'em */
3795 fast_clear_end_of_line
= 1; /* X does this well */
3796 memory_below_screen
= 0; /* we don't remember what scrolls
3800 XHandleError (x_error_handler
);
3801 XHandleIOError (x_error_handler
);
3803 /* Disable Window Change signals; they are handled by X events. */
3805 signal (SIGWINCH
, SIG_DFL
);
3806 #endif /* SIGWINCH */
3808 signal (SIGPIPE
, x_death_handler
);
3814 staticpro (&invocation_name
);
3815 invocation_name
= Qnil
;
3817 #endif /* HAVE_X11 */
3818 #endif /* HAVE_X_WINDOWS */