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"
101 #define XMapWindow XMapRaised /* Raise them when mapping. */
103 #include <X/Xkeyboard.h>
104 /*#include <X/Xproto.h> */
105 #endif /* HAVE_X11 */
107 /* For sending Meta-characters. Do we need this? */
110 #define min(a,b) ((a)<(b) ? (a) : (b))
111 #define max(a,b) ((a)>(b) ? (a) : (b))
113 /* Nonzero means we must reprint all windows
114 because 1) we received an ExposeWindow event
115 or 2) we received too many ExposeRegion events to record. */
117 static int expose_all_windows
;
119 /* Nonzero means we must reprint all icon windows. */
121 static int expose_all_icons
;
124 /* ExposeRegion events, when received, are copied into this queue
125 for later processing. */
127 static struct event_queue x_expose_queue
;
129 /* ButtonPressed and ButtonReleased events, when received,
130 are copied into this queue for later processing. */
132 struct event_queue x_mouse_queue
;
135 /* Nonzero after BLOCK_INPUT; prevents input events from being
136 processed until later. */
140 #if defined (SIGIO) && defined (FIONREAD)
141 int BLOCK_INPUT_mask
;
144 /* Nonzero if input events came in while x_input_blocked was nonzero.
145 UNBLOCK_INPUT checks for this. */
149 /* Nonzero if in redisplay (); prevents us from calling it recursively */
153 /* The id of a bitmap used for icon windows.
154 One such map is shared by all Emacs icon windows.
155 This is zero if we have not yet had a need to create the bitmap. */
157 static Bitmap icon_bitmap
;
159 /* Font used for text icons. */
161 static FONT_TYPE
*icon_font_info
;
163 /* Stuff for dealing with the main icon title. */
165 extern Lisp_Object Vcommand_line_args
;
166 char *hostname
, *id_name
, *invocation_name
;
168 /* This is the X connection that we are using. */
170 Display
*x_current_display
;
172 /* Screen being updated by update_screen. */
173 /* This is set by XTupdate_begin and looked at by all the
174 XT functions. It is zero while not inside an update.
175 In that case, the XT functions assume that `selected_screen'
176 is the screen to apply to. */
178 static struct screen
*updating_screen
;
180 /* The screen (if any) which has the X window that has keyboard focus.
181 Zero if none. This is examined by Ffocus_screen in screen.c */
183 struct screen
*x_focus_screen
;
185 /* From .Xdefaults, the value of "emacs.WarpMouse". If non-zero,
186 mouse is moved to inside of screen when screen is de-iconified. */
188 static int warp_mouse_on_deiconify
;
190 /* During an update, maximum vpos for ins/del line operations to affect. */
192 static int flexlines
;
194 /* During an update, nonzero if chars output now should be highlighted. */
196 static int highlight
;
198 /* Nominal cursor position -- where to draw output.
199 During an update, these are different from the cursor-box position. */
205 /* `t' if a mouse button is depressed. */
207 extern Lisp_Object Vmouse_depressed
;
209 /* Tells if a window manager is present or not. */
211 extern Lisp_Object Vx_no_window_manager
;
213 /* Timestamp that we requested selection data was made. */
214 extern Time requestor_time
;
216 /* ID of the window requesting selection data. */
217 extern Window requestor_window
;
219 /* Nonzero enables some debugging for the X interface code. */
222 #else /* X10 stuff */
224 /* Bit patterns for the mouse cursor. */
226 short MouseCursor
[] = {
227 0x0000, 0x0008, 0x0018, 0x0038,
228 0x0078, 0x00f8, 0x01f8, 0x03f8,
229 0x07f8, 0x00f8, 0x00d8, 0x0188,
230 0x0180, 0x0300, 0x0300, 0x0000};
232 short MouseMask
[] = {
233 0x000c, 0x001c, 0x003c, 0x007c,
234 0x00fc, 0x01fc, 0x03fc, 0x07fc,
235 0x0ffc, 0x0ffc, 0x01fc, 0x03dc,
236 0x03cc, 0x0780, 0x0780, 0x0300};
238 static short grey_bits
[] = {
239 0x0005, 0x000a, 0x0005, 0x000a};
241 static Pixmap GreyPixmap
= 0;
242 #endif /* X10 stuff */
244 /* From time to time we get info on an Emacs window, here. */
246 static WINDOWINFO_TYPE windowinfo
;
250 extern Lisp_Object Vglobal_minibuffer_screen
;
252 extern Display
*XOpenDisplay ();
253 extern Window
XCreateWindow ();
255 extern Cursor
XCreateCursor ();
256 extern FONT_TYPE
*XOpenFont ();
258 static void flashback ();
261 static void dumpqueue ();
265 static XTcursor_to ();
266 static XTclear_end_of_line ();
268 /* These hooks are called by update_screen at the beginning and end
269 of a screen update. We record in `updating_screen' the identity
270 of the screen being updated, so that the XT... functions do not
271 need to take a screen as argument. Most of the XT... functions
272 should never be called except during an update, the only exceptions
273 being XTcursor_to, XTwrite_char and XTreassert_line_highlight. */
275 extern int mouse_track_top
, mouse_track_left
, mouse_track_width
;
287 flexlines
= s
->height
;
291 if (mouse_track_width
!= 0)
293 x_rectangle (s
, s
->display
.x
->reverse_gc
,
294 mouse_track_top
, mouse_track_left
, mouse_track_width
, 1);
295 mouse_track_width
= 0;
305 static void x_do_pending_expose ();
313 if (updating_screen
== 0
314 || updating_screen
!= s
)
321 adjust_scrollbars (s
);
322 x_do_pending_expose ();
324 x_display_cursor (s
, 1);
331 /* External interface to control of standout mode.
332 Call this when about to modify line at position VPOS
333 and not change whether it is highlighted. */
335 XTreassert_line_highlight (new, vpos
)
341 /* Call this when about to modify line at position VPOS
342 and change whether it is highlighted. */
345 XTchange_line_highlight (new_highlight
, vpos
, first_unused_hpos
)
346 int new_highlight
, vpos
, first_unused_hpos
;
348 highlight
= new_highlight
;
349 XTcursor_to (vpos
, 0);
350 XTclear_end_of_line (updating_screen
->width
);
353 /* This is used when starting Emacs and when restarting after suspend.
354 When starting Emacs, no X window is mapped. And nothing must be done
355 to Emacs's own window if it is suspended (though that rarely happens). */
358 XTset_terminal_modes ()
362 /* This is called when exiting or suspending Emacs.
363 Exiting will make the X-windows go away, and suspending
364 requires no action. */
367 XTreset_terminal_modes ()
369 /* XTclear_screen (); */
372 /* Set the nominal cursor position of the screen:
373 where display update commands will take effect.
374 This does not affect the place where the cursor-box is displayed. */
376 XTcursor_to (row
, col
)
377 register int row
, col
;
385 if (updating_screen
== 0)
388 x_display_cursor (selected_screen
, 1);
394 /* Display a sequence of N glyphs found at GP.
395 WINDOW is the x-window to output to. LEFT and TOP are starting coords.
396 HL is 1 if this text is highlighted, 2 if the cursor is on it.
398 FONT is the default font to use (for glyphs whose font-code is 0). */
401 dumpglyphs (s
, left
, top
, gp
, n
, hl
, font
)
404 register GLYPH
*gp
; /* Points to first GLYPH. */
405 register int n
; /* Number of glyphs to display. */
410 register char *cp
= buf
;
412 Window window
= s
->display
.x
->window_desc
;
413 GC drawing_gc
= (hl
== 2 ? s
->display
.x
->cursor_gc
414 : (hl
? s
->display
.x
->reverse_gc
415 : s
->display
.x
->normal_gc
));
417 if (sizeof (GLYPH
) == sizeof (XChar2b
))
418 XDrawImageString16 (x_current_display
, window
, drawing_gc
,
419 left
, top
+ FONT_BASE (font
), (XChar2b
*) gp
, n
);
420 else if (sizeof (GLYPH
) == sizeof (unsigned char))
421 XDrawImageString (x_current_display
, window
, drawing_gc
,
422 left
, top
+ FONT_BASE (font
), (char *) gp
, n
);
424 /* What size of glyph ARE you using? And does X have a function to
431 dumpglyphs (s
, left
, top
, gp
, n
, hl
, font
)
434 register GLYPH
*gp
; /* Points to first GLYPH. */
435 register int n
; /* Number of glyphs to display. */
439 char buf
[s
->width
]; /* Holds characters to be displayed. */
440 register char *cp
; /* Steps through buf[]. */
441 register int tlen
= GLYPH_TABLE_LENGTH
;
442 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
443 Window window
= s
->display
.x
->window_desc
;
444 int cursor_pixel
= s
->display
.x
->cursor_pixel
;
445 int fg_pixel
= s
->display
.x
->foreground_pixel
;
446 int bg_pixel
= s
->display
.x
->background_pixel
;
447 int intborder
= s
->display
.x
->internal_border_width
;
451 /* Get the face-code of the next GLYPH. */
455 while (GLYPH_ALIAS_P (tbase
, tlen
, g
))
456 g
= GLYPH_ALIAS (tbase
, g
);
460 /* Find the run of consecutive glyphs with the same face-code.
461 Extract their character codes into BUF. */
466 while (GLYPH_ALIAS_P (tbase
, tlen
, g
))
467 g
= GLYPH_ALIAS (tbase
, g
);
476 /* LEN gets the length of the run. */
479 /* Now output this run of chars, with the font and pixel values
480 determined by the face code CF. */
484 GC GC_cursor
= s
->display
.x
->cursor_gc
;
485 GC GC_reverse
= s
->display
.x
->reverse_gc
;
486 GC GC_normal
= s
->display
.x
->normal_gc
;
488 XDrawImageString (x_current_display
, window
,
491 : (hl
? GC_reverse
: GC_normal
)),
492 left
, top
+ FONT_BASE (font
), buf
, len
);
494 XText (window
, left
, top
,
499 ? (cursor_pixel
== fg_pixel
? bg_pixel
: fg_pixel
)
500 : hl
? bg_pixel
: fg_pixel
),
501 (hl
== 2 ? cursor_pixel
502 : hl
? fg_pixel
: bg_pixel
));
503 #endif /* HAVE_X11 */
508 if (FACE_IS_FONT (cf
))
509 XDrawImageString (x_current_display
, s
->display
.x
->window_desc
,
511 left
, top
+ FONT_BASE (FACE_FONT (cf
)),
513 else if (FACE_IS_IMAGE (cf
))
514 XCopyPlane (x_current_display
, FACE_IMAGE (cf
),
515 s
->display
.x
->window_desc
,
516 s
->display
.x
->normal_gc
,
518 FACE_IMAGE_WIDTH (cf
),
519 FACE_IMAGE_HEIGHT (cf
), left
, top
);
523 register struct face
*fp
= x_face_table
[cf
];
525 XText (window
, left
, top
,
530 ? (cursor_pixel
== fp
->fg
? fp
->bg
: fp
->fg
)
531 : hl
? fp
->bg
: fp
->fg
),
532 (hl
== 2 ? cursor_pixel
533 : hl
? fp
->fg
: fp
->bg
));
534 #endif /* HAVE_X11 */
536 left
+= len
* FONT_WIDTH (font
);
541 /* Output some text at the nominal screen cursor position,
542 advancing the cursor over the text.
543 Output LEN glyphs at START.
545 `highlight', set up by XTreassert_line_highlight or XTchange_line_highlight,
546 controls the pixel values used for foreground and background. */
549 XTwrite_glyphs (start
, len
)
550 register GLYPH
*start
;
553 register int temp_length
;
563 /* If not within an update,
564 output at the screen's visible cursor. */
565 curs_x
= s
->cursor_x
;
566 curs_y
= s
->cursor_y
;
569 /* Clear the cursor if it appears on this line. */
570 if (curs_y
== s
->cursor_y
)
571 x_display_cursor (s
, 0);
574 (curs_x
* FONT_WIDTH (s
->display
.x
->font
)
575 + s
->display
.x
->internal_border_width
),
576 (curs_y
* FONT_HEIGHT (s
->display
.x
->font
)
577 + s
->display
.x
->internal_border_width
),
578 start
, len
, highlight
, s
->display
.x
->font
);
580 if (updating_screen
== 0)
583 x_display_cursor (s
, 1);
592 /* Erase the current text line from the nominal cursor position (inclusive)
593 to column FIRST_UNUSED (exclusive). The idea is that everything
594 from FIRST_UNUSED onward is already erased. */
597 XTclear_end_of_line (first_unused
)
598 register int first_unused
;
600 struct screen
*s
= updating_screen
;
606 if (curs_y
< 0 || curs_y
>= s
->height
)
608 if (first_unused
<= 0)
611 if (first_unused
>= s
->width
)
612 first_unused
= s
->width
;
616 /* Clear the cursor if it appears on this line. */
617 if (curs_y
== s
->cursor_y
)
618 x_display_cursor (s
, 0);
621 XClearArea (x_current_display
, s
->display
.x
->window_desc
,
622 curs_x
* FONT_WIDTH (s
->display
.x
->font
)
623 + s
->display
.x
->internal_border_width
,
624 curs_y
* FONT_HEIGHT (s
->display
.x
->font
)
625 + s
->display
.x
->internal_border_width
,
626 FONT_WIDTH (s
->display
.x
->font
) * (first_unused
- curs_x
),
627 FONT_HEIGHT (s
->display
.x
->font
), False
);
630 XPixSet (s
->display
.x
->window_desc
,
631 curs_x
* FONT_WIDTH (s
->display
.x
->font
) + s
->display
.x
->internal_border_width
,
632 curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + s
->display
.x
->internal_border_width
,
633 FONT_WIDTH (s
->display
.x
->font
) * (first_unused
- curs_x
),
634 FONT_HEIGHT (s
->display
.x
->font
),
635 s
->display
.x
->background_pixel
);
636 #endif /* HAVE_X11 */
645 struct screen
*s
= updating_screen
;
650 s
->phys_cursor_x
= -1; /* Cursor not visible. */
651 curs_x
= 0; /* Nominal cursor position is top left. */
655 XClear (s
->display
.x
->window_desc
);
663 /* Paint horzontal bars down the screen for a visible bell.
664 Note that this may be way too slow on some machines. */
669 register struct screen_glyphs
*active_screen
= SCREEN_CURRENT_GLYPHS (s
);
673 if (updating_screen
!= 0)
679 for (i
= s
->height
* FONT_HEIGHT (s
->display
.x
->font
) - 10;
681 i
-= 100) /* Should be NO LOWER than 75 for speed reasons. */
682 XFillRectangle (x_current_display
, s
->display
.x
->window_desc
,
683 s
->display
.x
->cursor_gc
,
684 0, i
, s
->width
* FONT_WIDTH (s
->display
.x
->font
)
685 + 2 * s
->display
.x
->internal_border_width
, 25);
688 x
= (s
->width
* FONT_WIDTH (s
->display
.x
->font
)) / 4;
689 y
= (s
->height
* FONT_HEIGHT (s
->display
.x
->font
)) / 4;
690 XFillRectangle (x_current_display
, s
->display
.x
->window_desc
,
691 s
->display
.x
->cursor_gc
,
693 dumpglyphs (s
, (x
+ s
->display
.x
->internal_border_width
),
694 (y
+ s
->display
.x
->internal_border_width
),
695 &active_screen
->glyphs
[(s
->height
/ 4) + 1][(s
->width
/ 4)],
696 1, 0, s
->display
.x
->font
);
699 for (i
= s
->height
* FONT_HEIGHT (s
->display
.x
->font
) - 10;
702 XPixFill (s
->display
.x
->window_desc
, 0, i
,
703 s
->width
* FONT_WIDTH (s
->display
.x
->font
)
704 + 2 * s
->display
.x
->internal_border_width
, 10,
705 WHITE_PIX_DEFAULT
, ClipModeClipped
, GXinvert
, AllPlanes
);
712 /* Flip background and forground colors of the screen. */
719 unsigned long pix_temp
;
721 x_display_cursor (s
, 0);
722 XClearWindow (x_current_display
, s
->display
.x
->window_desc
);
723 temp
= s
->display
.x
->normal_gc
;
724 s
->display
.x
->normal_gc
= s
->display
.x
->reverse_gc
;
725 s
->display
.x
->reverse_gc
= temp
;
726 pix_temp
= s
->display
.x
->foreground_pixel
;
727 s
->display
.x
->foreground_pixel
= s
->display
.x
->background_pixel
;
728 s
->display
.x
->background_pixel
= pix_temp
;
730 XSetWindowBackground (x_current_display
, s
->display
.x
->window_desc
,
731 s
->display
.x
->background_pixel
);
732 if (s
->display
.x
->background_pixel
== s
->display
.x
->cursor_pixel
)
734 s
->display
.x
->cursor_pixel
= s
->display
.x
->foreground_pixel
;
735 XSetBackground (x_current_display
, s
->display
.x
->cursor_gc
,
736 s
->display
.x
->cursor_pixel
);
737 XSetForeground (x_current_display
, s
->display
.x
->cursor_gc
,
738 s
->display
.x
->background_pixel
);
744 /* Make audible bell. */
747 #define XRINGBELL XBell(x_current_display, 0)
749 #define XRINGBELL XFeep(0);
756 XTflash (selected_screen
);
759 x_invert_screen (selected_screen
);
760 x_invert_screen (selected_screen
);
771 /* Insert and delete character are not supposed to be used
772 because we are supposed to turn off the feature of using them. */
775 XTinsert_glyphs (start
, len
)
776 register char *start
;
789 /* Specify how many text lines, from the top of the window,
790 should be affected by insert-lines and delete-lines operations.
791 This, and those operations, are used only within an update
792 that is bounded by calls to XTupdate_begin and XTupdate_end. */
795 XTset_terminal_window (n
)
798 if (updating_screen
== 0)
801 if ((n
<= 0) || (n
> updating_screen
->height
))
802 flexlines
= updating_screen
->height
;
807 /* Perform an insert-lines operation, inserting N lines
808 at a vertical position curs_y. */
814 register int topregion
, bottomregion
;
815 register int length
, newtop
, mask
;
816 register struct screen
*s
= updating_screen
;
817 int intborder
= s
->display
.x
->internal_border_width
;
819 if (curs_y
>= flexlines
)
823 bottomregion
= flexlines
- (n
+ 1);
824 newtop
= topregion
+ n
;
825 length
= (bottomregion
- topregion
) + 1;
831 if ((length
> 0) && (newtop
<= flexlines
))
834 XCopyArea (x_current_display
, s
->display
.x
->window_desc
,
835 s
->display
.x
->window_desc
, s
->display
.x
->normal_gc
,
836 intborder
, topregion
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
837 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
838 length
* FONT_HEIGHT (s
->display
.x
->font
), intborder
,
839 newtop
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
);
841 XMoveArea (s
->display
.x
->window_desc
,
842 intborder
, topregion
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
843 intborder
, newtop
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
844 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
845 length
* FONT_HEIGHT (s
->display
.x
->font
));
846 /* Now we must process any ExposeRegion events that occur
847 if the area being copied from is obscured.
848 We can't let it wait because further i/d operations
849 may want to copy this area to another area. */
851 #endif /* HAVE_X11 */
854 newtop
= min (newtop
, (flexlines
- 1));
855 length
= newtop
- topregion
;
859 XClearArea (x_current_display
, s
->display
.x
->window_desc
, intborder
,
860 topregion
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
861 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
862 n
* FONT_HEIGHT (s
->display
.x
->font
), False
);
864 XPixSet (s
->display
.x
->window_desc
,
866 topregion
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
867 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
868 n
* FONT_HEIGHT (s
->display
.x
->font
),
869 s
->display
.x
->background_pixel
);
870 #endif /* HAVE_X11 */
874 /* Perform a delete-lines operation, deleting N lines
875 at a vertical position curs_y. */
882 register struct screen
*s
= updating_screen
;
883 int intborder
= s
->display
.x
->internal_border_width
;
885 if (curs_y
>= flexlines
)
892 if ((curs_y
+ n
) >= flexlines
)
894 if (flexlines
>= (curs_y
+ 1))
897 XClearArea (x_current_display
, s
->display
.x
->window_desc
, intborder
,
898 curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
899 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
900 (flexlines
- curs_y
) * FONT_HEIGHT (s
->display
.x
->font
), False
);
902 XPixSet (s
->display
.x
->window_desc
,
903 intborder
, curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
904 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
905 (flexlines
- curs_y
) * FONT_HEIGHT (s
->display
.x
->font
),
906 s
->display
.x
->background_pixel
);
907 #endif /* HAVE_X11 */
913 XCopyArea (x_current_display
, s
->display
.x
->window_desc
,
914 s
->display
.x
->window_desc
, s
->display
.x
->normal_gc
,
916 (curs_y
+ n
) * FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
917 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
918 (flexlines
- (curs_y
+ n
)) * FONT_HEIGHT (s
->display
.x
->font
),
919 intborder
, curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
);
920 XClearArea (x_current_display
, s
->display
.x
->window_desc
,
922 (flexlines
- n
) * FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
923 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
924 n
* FONT_HEIGHT (s
->display
.x
->font
), False
);
926 XMoveArea (s
->display
.x
->window_desc
,
928 (curs_y
+ n
) * FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
929 intborder
, curs_y
* FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
930 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
931 (flexlines
- (curs_y
+ n
)) * FONT_HEIGHT (s
->display
.x
->font
));
932 /* Now we must process any ExposeRegion events that occur
933 if the area being copied from is obscured.
934 We can't let it wait because further i/d operations
935 may want to copy this area to another area. */
937 XPixSet (s
->display
.x
->window_desc
, intborder
,
938 (flexlines
- n
) * FONT_HEIGHT (s
->display
.x
->font
) + intborder
,
939 s
->width
* FONT_WIDTH (s
->display
.x
->font
),
940 n
* FONT_HEIGHT (s
->display
.x
->font
), s
->display
.x
->background_pixel
);
941 #endif /* HAVE_X11 */
945 /* Perform an insert-lines or delete-lines operation,
946 inserting N lines or deleting -N lines at vertical position VPOS. */
948 XTins_del_lines (vpos
, n
)
951 if (updating_screen
== 0)
954 /* Clear the cursor. */
955 x_display_cursor (updating_screen
, 0);
957 XTcursor_to (vpos
, 0);
968 static void clear_cursor ();
970 /* Output into a rectangle of an X-window (for screen S)
971 the characters in s->phys_lines that overlap that rectangle.
972 TOP and LEFT are the position of the upper left corner of the rectangle.
973 ROWS and COLS are the size of the rectangle. */
976 dumprectangle (s
, left
, top
, cols
, rows
)
978 register int left
, top
, cols
, rows
;
980 register struct screen_glyphs
*active_screen
= SCREEN_CURRENT_GLYPHS (s
);
981 int cursor_cleared
= 0;
985 if (SCREEN_GARBAGED_P (s
))
988 top
-= s
->display
.x
->internal_border_width
;
989 left
-= s
->display
.x
->internal_border_width
;
991 /* Express rectangle as four edges, instead of position-and-size. */
995 #ifndef HAVE_X11 /* Window manger does this for X11. */
996 /* If the rectangle includes any of the internal border area,
997 redisplay the border emphasis. */
998 if (top
< 0 || left
< 0
999 || bottom
> s
->height
* FONT_HEIGHT (s
->display
.x
->font
)
1000 || right
> s
->width
* FONT_WIDTH (s
->display
.x
->font
))
1002 #endif /* HAVE_X11 */
1004 /* Convert rectangle edges in pixels to edges in chars.
1005 Round down for left and top, up for right and bottom. */
1006 top
/= FONT_HEIGHT (s
->display
.x
->font
);
1007 left
/= FONT_WIDTH (s
->display
.x
->font
);
1008 bottom
+= (FONT_HEIGHT (s
->display
.x
->font
) - 1);
1009 right
+= (FONT_WIDTH (s
->display
.x
->font
) - 1);
1010 bottom
/= FONT_HEIGHT (s
->display
.x
->font
);
1011 right
/= FONT_WIDTH (s
->display
.x
->font
);
1013 /* Clip the rectangle to what can be visible. */
1018 if (right
> s
->width
)
1020 if (bottom
> s
->height
)
1023 /* Get size in chars of the rectangle. */
1024 cols
= right
- left
;
1025 rows
= bottom
- top
;
1027 /* If rectangle has zero area, return. */
1028 if (rows
<= 0) return;
1029 if (cols
<= 0) return;
1031 /* Turn off the cursor if it is in the rectangle.
1032 We will turn it back on afterward. */
1033 if ((s
->phys_cursor_x
>= left
) && (s
->phys_cursor_x
< right
)
1034 && (s
->phys_cursor_y
>= top
) && (s
->phys_cursor_y
< bottom
))
1040 /* Display the text in the rectangle, one text line at a time. */
1042 for (y
= top
; y
< bottom
; y
++)
1044 GLYPH
*line
= &active_screen
->glyphs
[y
][left
];
1046 if (! active_screen
->enable
[y
] || left
> active_screen
->used
[y
])
1050 (left
* FONT_WIDTH (s
->display
.x
->font
)
1051 + s
->display
.x
->internal_border_width
),
1052 (y
* FONT_HEIGHT (s
->display
.x
->font
)
1053 + s
->display
.x
->internal_border_width
),
1054 line
, min (cols
, active_screen
->used
[y
] - left
),
1055 active_screen
->highlight
[y
], s
->display
.x
->font
);
1058 /* Turn the cursor on if we turned it off. */
1061 x_display_cursor (s
, 1);
1065 /* Process all queued ExposeRegion events. */
1071 XExposeRegionEvent r
;
1073 while (dequeue_event (&r
, &x_expose_queue
))
1075 struct screen
*s
= x_window_to_screen (r
.window
);
1076 if (s
->display
.x
->icon_desc
== r
.window
)
1079 dumprectangle (s
, r
.x
, r
.y
, r
.width
, r
.height
);
1085 /* Process all expose events that are pending.
1086 Redraws the cursor if necessary on any screen that
1087 is not in the process of being updated with update_screen. */
1090 x_do_pending_expose ()
1094 Lisp_Object tail
, screen
;
1096 if (expose_all_windows
)
1098 expose_all_windows
= 0;
1099 for (tail
= Vscreen_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1101 register int temp_width
, temp_height
;
1104 screen
= XCONS (tail
)->car
;
1105 if (XTYPE (screen
) != Lisp_Screen
)
1107 s
= XSCREEN (screen
);
1108 if (s
->output_method
!= output_x_window
)
1112 if (!s
->display
.x
->needs_exposure
)
1115 intborder
= s
->display
.x
->internal_border_width
;
1118 XGetWindowInfo (s
->display
.x
->window_desc
, &windowinfo
);
1119 temp_width
= ((windowinfo
.width
- 2 * intborder
1120 - s
->display
.x
->v_scrollbar_width
)
1121 / FONT_WIDTH (s
->display
.x
->font
));
1122 temp_height
= ((windowinfo
.height
- 2 * intborder
1123 - s
->display
.x
->h_scrollbar_height
)
1124 / FONT_HEIGHT (s
->display
.x
->font
));
1125 if (temp_width
!= s
->width
|| temp_height
!= s
->height
)
1127 change_screen_size (s
, max (1, temp_height
),
1128 max (1, temp_width
), 0);
1129 x_resize_scrollbars (s
);
1131 s
->display
.x
->left_pos
= windowinfo
.x
;
1132 s
->display
.x
->top_pos
= windowinfo
.y
;
1133 dumprectangle (s
, 0, 0, PIXEL_WIDTH (s
), PIXEL_HEIGHT (s
));
1137 s
->display
.x
->needs_exposure
= 0;
1138 if (updating_screen
!= s
)
1139 x_display_cursor (s
, 1);
1144 /* Handle any individual-rectangle expose events queued
1145 for various windows. */
1155 screen_highlight (screen
)
1156 struct screen
*screen
;
1158 if (! EQ (Vx_no_window_manager
, Qnil
))
1159 XSetWindowBorder (x_current_display
, screen
->display
.x
->window_desc
,
1160 screen
->display
.x
->border_pixel
);
1161 x_display_cursor (screen
, 1);
1165 screen_unhighlight (screen
)
1166 struct screen
*screen
;
1168 if (! EQ (Vx_no_window_manager
, Qnil
))
1169 XSetWindowBorderPixmap (x_current_display
, screen
->display
.x
->window_desc
,
1170 screen
->display
.x
->border_tile
);
1171 x_display_cursor (screen
, 1);
1174 /* Dump the border-emphasis of screen S.
1175 If S is selected, this is a lining of the same color as the border,
1176 just within the border, occupying a portion of the internal border.
1177 If S is not selected, it is background in the same place.
1178 If ALWAYS is 0, don't bother explicitly drawing if it's background.
1180 ALWAYS = 1 is used when a screen becomes selected or deselected.
1181 In that case, we also turn the cursor off and on again
1182 so it will appear in the proper shape (solid if selected; else hollow.) */
1185 dumpborder (s
, always
)
1189 int thickness
= s
->display
.x
->internal_border_width
/ 2;
1190 int width
= PIXEL_WIDTH (s
);
1191 int height
= PIXEL_HEIGHT (s
);
1194 if (s
!= selected_screen
)
1199 pixel
= s
->display
.x
->background_pixel
;
1203 pixel
= s
->display
.x
->border_pixel
;
1206 XPixSet (s
->display
.x
->window_desc
, 0, 0, width
, thickness
, pixel
);
1207 XPixSet (s
->display
.x
->window_desc
, 0, 0, thickness
, height
, pixel
);
1208 XPixSet (s
->display
.x
->window_desc
, 0, height
- thickness
, width
,
1210 XPixSet (s
->display
.x
->window_desc
, width
- thickness
, 0, thickness
,
1214 x_display_cursor (s
, 1);
1218 /* The focus has changed. Update the screens as necessary to reflect
1219 the new situation. Note that we can't change the selected screen
1220 here, because the lisp code we are interrupting might become confused.
1221 For that, we enqueue a screen_selected event.
1223 Return the number of events stored at bufp. */
1225 x_new_focus_screen (screen
, bufp
, buf_free
)
1226 struct screen
*screen
;
1227 struct input_event
*bufp
;
1230 struct screen
*old_focus
= x_focus_screen
;
1231 int events_enqueued
= 0;
1233 if (screen
== x_focus_screen
)
1236 /* Set this before calling screen_{un,}highlight, so that they see
1237 the correct value of x_focus_screen. */
1238 x_focus_screen
= screen
;
1242 if (old_focus
->auto_lower
)
1243 x_lower_screen (old_focus
);
1244 screen_unhighlight (old_focus
);
1248 selected_screen
= screen
;
1249 XSET (XWINDOW (selected_screen
->selected_window
)->screen
,
1250 Lisp_Screen
, selected_screen
);
1251 Fselect_window (selected_screen
->selected_window
);
1252 choose_minibuf_screen ();
1257 if (x_focus_screen
->auto_raise
)
1258 x_raise_screen (x_focus_screen
);
1259 screen_highlight (x_focus_screen
);
1261 /* Enqueue an event. It's kind of important not to drop these
1262 events, but the event queue's fixed size is a real pain
1266 bufp
->kind
= screen_selected
;
1267 bufp
->screen
= screen
;
1272 return events_enqueued
;
1282 /* Symbol returned in input stream to indicate mouse movement. */
1283 Lisp_Object Qmouse_moved
;
1285 /* Position of the mouse in characters */
1286 unsigned int x_mouse_x
, x_mouse_y
;
1288 /* Emacs window the mouse is in, if any. */
1289 extern Lisp_Object Vmouse_window
;
1291 /* Offset in buffer of character under the pointer, or 0. */
1292 extern int mouse_buffer_offset
;
1294 /* Part of the screen the mouse is in. */
1295 extern Lisp_Object Vmouse_screen_part
;
1297 extern void pixel_to_glyph_translation ();
1298 extern int buffer_posn_from_coords ();
1300 /* Symbols from xfns.c to denote the different parts of a window. */
1301 extern Lisp_Object Qmodeline_part
, Qtext_part
;
1304 /* Set *RESULT to an emacs input_event corresponding to MOTION_EVENT.
1305 S is the screen in which the event occurred.
1307 WINDOW_TYPE says whether the event happened in a scrollbar window
1308 or a text window, affecting the format of the event created.
1310 PART specifies which part of the scrollbar the event happened in,
1311 if WINDOW_TYPE == scrollbar_window.
1313 If the mouse is over the same character as the last time we checked,
1314 don't return an event; set result->kind to no_event. */
1317 notice_mouse_movement (result
, motion_event
, s
, window_type
, part
)
1318 struct input_event
*result
;
1319 XMotionEvent motion_event
;
1324 int x
, y
, root_x
, root_y
, pix_x
, pix_y
;
1325 unsigned int keys_and_buttons
;
1326 Window w
, root_window
;
1328 /* Unless we decide otherwise below, return a non-event. */
1329 result
->kind
= no_event
;
1331 if (XQueryPointer (x_current_display
,
1332 s
->display
.x
->window_desc
,
1334 &root_x
, &root_y
, &pix_x
, &pix_y
,
1340 if (w
== None
) /* Mouse no longer in window. */
1344 pixel_to_glyph_translation (s
, pix_x
, pix_y
, &x
, &y
);
1345 if (x
== x_mouse_x
&& y
== x_mouse_y
)
1351 /* What sort of window are we in now? */
1352 if (window_type
== text_window
) /* Text part */
1356 Vmouse_window
= window_from_coordinates (s
, x
, y
, &modeline_p
);
1358 if (XTYPE (Vmouse_window
) == Lisp_Window
)
1360 = buffer_posn_from_coords (XWINDOW (Vmouse_window
), x
, y
);
1362 mouse_buffer_offset
= 0;
1364 if (EQ (Vmouse_window
, Qnil
))
1365 Vmouse_screen_part
= Qnil
;
1366 else if (modeline_p
)
1367 Vmouse_screen_part
= Qmodeline_part
;
1369 Vmouse_screen_part
= Qtext_part
;
1371 result
->kind
= window_sys_event
;
1372 result
->code
= Qmouse_moved
;
1376 else if (window_type
== scrollbar_window
) /* Scrollbar */
1378 Vmouse_window
= s
->selected_window
;
1379 mouse_buffer_offset
= 0;
1380 Vmouse_screen_part
= part
;
1382 result
->kind
= window_sys_event
;
1383 result
->code
= Qmouse_moved
;
1392 /* Given a pixel position (pix_x, pix_y) on the screen s, return
1393 character co-ordinates in (*x, *y). */
1395 pixel_to_glyph_translation (s
, pix_x
, pix_y
, x
, y
)
1397 register unsigned int pix_x
, pix_y
;
1398 register int *x
, *y
;
1400 register struct screen_glyphs
*s_glyphs
= SCREEN_CURRENT_GLYPHS (s
);
1401 register int line
= SCREEN_HEIGHT (s
) - 1;
1402 int ibw
= s
->display
.x
->internal_border_width
;
1404 /* What line is it on? */
1405 line
= SCREEN_HEIGHT (s
) - 1;
1406 while (s_glyphs
->top_left_y
[line
] > pix_y
)
1410 /* Horizontally, is it in the border? */
1414 /* If it's off the right edge, clip it. */
1415 else if (pix_x
> s
->display
.x
->pixel_width
- ibw
)
1416 *x
= SCREEN_WIDTH (s
) - 1;
1418 /* It's in the midst of the screen; assume all the characters are
1419 the same width, and figure the column. */
1421 *x
= (pix_x
- ibw
) / FONT_WIDTH (s
->display
.x
->font
);
1426 /* Any buttons grabbed. */
1427 unsigned int x_mouse_grabbed
;
1429 /* Convert a set of X modifier bits to the proper form for a
1430 struct input_event modifiers value. */
1433 x_convert_modifiers (state
)
1436 return ( ((state
& (ShiftMask
| LockMask
)) ? shift_modifier
: 0)
1437 | ((state
& ControlMask
) ? ctrl_modifier
: 0)
1438 | ((state
& Mod1Mask
) ? meta_modifier
: 0));
1441 extern struct screen
*x_window_to_scrollbar ();
1442 extern Lisp_Object Vmouse_event
;
1444 /* Prepare a mouse-event in *RESULT for placement in the input queue.
1446 If the event is a button press, then note that we have grabbed
1449 If PART and PREFIX are 0, then the event occurred in the text part;
1450 otherwise it happened in a scrollbar. */
1453 construct_mouse_click (result
, event
, s
, part
, prefix
)
1454 struct input_event
*result
;
1455 XButtonEvent
*event
;
1460 /* Initialize those fields text and scrollbar clicks hold in common.
1461 Make the event type no_event; we'll change that when we decide
1463 result
->kind
= no_event
;
1464 XSET (result
->code
, Lisp_Int
, event
->button
);
1465 result
->modifiers
= (x_convert_modifiers (event
->state
)
1466 | (event
->type
== ButtonRelease
? up_modifier
: 0));
1467 XSET (result
->timestamp
, Lisp_Int
, (event
->time
& 0x7fffff));
1469 /* Notice if the mouse is still grabbed. */
1470 if (event
->type
== ButtonPress
)
1472 if (! x_mouse_grabbed
)
1473 Vmouse_depressed
= Qt
;
1474 x_mouse_grabbed
|= event
->button
;
1476 else if (event
->type
== ButtonRelease
)
1478 x_mouse_grabbed
&= ~(event
->button
);
1479 if (!x_mouse_grabbed
)
1480 Vmouse_depressed
= Qnil
;
1483 if (part
) /* Scrollbar event */
1487 pos
= event
->y
- (s
->display
.x
->v_scrollbar_width
- 2);
1488 XSET (x_mouse_x
, Lisp_Int
, pos
);
1489 len
= ((FONT_HEIGHT (s
->display
.x
->font
) * s
->height
)
1490 + s
->display
.x
->internal_border_width
1491 - (2 * (s
->display
.x
->v_scrollbar_width
- 2)));
1492 XSET (x_mouse_y
, Lisp_Int
, len
);
1494 result
->kind
= scrollbar_click
;
1495 result
->part
= part
;
1496 XSET (result
->x
, Lisp_Int
, (s
->display
.x
->top_pos
- event
->y
));
1497 XSET (result
->y
, Lisp_Int
, s
->display
.x
->pixel_height
);
1500 else /* Text Window Event */
1504 pixel_to_glyph_translation (s
,
1508 result
->kind
= mouse_click
;
1516 static char *events
[] =
1556 #define XEvent XKeyPressedEvent
1557 #endif /* HAVE_X11 */
1559 /* Symbols returned in the input stream to indicate various X events. */
1560 Lisp_Object Qmapped_screen
;
1561 Lisp_Object Qunmapped_screen
;
1562 Lisp_Object Qexited_scrollbar
;
1563 Lisp_Object Qexited_window
;
1564 Lisp_Object Qredraw_screen
;
1565 Lisp_Object Qmouse_click
;
1566 Lisp_Object Qscrollbar_click
;
1568 /* Timestamp of enter window event. This is only used by XTread_socket,
1569 but we have to put it out here, since static variables within functions
1570 sometimes don't work. */
1571 static Time enter_timestamp
;
1573 /* Read events coming from the X server.
1574 This routine is called by the SIGIO handler.
1575 We return as soon as there are no more events to be read.
1577 Events representing keys are stored in buffer BUFP,
1578 which can hold up to NUMCHARS characters.
1579 We return the number of characters stored into the buffer,
1580 thus pretending to be `read'.
1582 WAITP is nonzero if we should block until input arrives.
1583 EXPECTED is nonzero if the caller knows input is available. */
1586 XTread_socket (sd
, bufp
, numchars
, waitp
, expected
)
1588 register struct input_event
*bufp
;
1589 register int numchars
;
1596 int items_pending
; /* How many items are in the X queue. */
1603 if (x_input_blocked
)
1605 x_pending_input
= 1;
1609 x_pending_input
= 0;
1613 abort (); /* Don't think this happens. */
1616 /* If available, Xlib uses FIOSNBIO to make the socket
1617 non-blocking, and then looks for EWOULDBLOCK. If O_NDELAY is set,
1618 FIOSNBIO is ignored, and instead of signalling EWOULDBLOCK,
1619 a read returns 0, which Xlib interprets as equivalent to EPIPE. */
1620 fcntl (fileno (stdin
), F_SETFL
, 0);
1625 if (! (fcntl (fileno (stdin
), F_GETFL
, 0) & O_NDELAY
))
1627 extern int read_alarm_should_throw
;
1628 read_alarm_should_throw
= 1;
1629 XPeekEvent (XDISPLAY
&event
);
1630 read_alarm_should_throw
= 0;
1635 while (XStuffPending () != 0)
1637 XNextEvent (XDISPLAY
&event
);
1644 case SelectionClear
: /* Someone has grabbed ownership. */
1645 x_disown_selection (event
.xselectionclear
.window
,
1646 event
.xselectionclear
.selection
,
1647 event
.xselectionclear
.time
);
1650 case SelectionRequest
: /* Someone wants our selection. */
1651 x_answer_selection_request (event
);
1654 case PropertyNotify
:
1655 /* If we were to do this synchronously, there'd be no worry
1656 about re-selecting. */
1657 x_send_incremental (event
);
1661 s
= x_window_to_screen (event
.xexpose
.window
);
1664 if (s
->visible
== 0)
1668 SET_SCREEN_GARBAGED (s
);
1671 dumprectangle (x_window_to_screen (event
.xexpose
.window
),
1672 event
.xexpose
.x
, event
.xexpose
.y
,
1673 event
.xexpose
.width
, event
.xexpose
.height
);
1677 case GraphicsExpose
: /* This occurs when an XCopyArea's
1678 source area was obscured or not
1680 dumprectangle (x_window_to_screen (event
.xgraphicsexpose
.drawable
),
1681 event
.xgraphicsexpose
.x
, event
.xgraphicsexpose
.y
,
1682 event
.xgraphicsexpose
.width
,
1683 event
.xgraphicsexpose
.height
);
1686 case NoExpose
: /* This occurs when an XCopyArea's
1687 source area was completely
1690 #else /* not HAVE_X11 */
1692 if (event
.subwindow
!= 0)
1693 break; /* duplicate event */
1694 s
= x_window_to_screen (event
.window
);
1695 if (event
.window
== s
->display
.x
->icon_desc
)
1700 if (event
.window
== s
->display
.x
->window_desc
)
1702 /* Say must check all windows' needs_exposure flags. */
1703 expose_all_windows
= 1;
1704 s
->display
.x
->needs_exposure
= 1;
1710 if (event
.subwindow
!= 0)
1711 break; /* duplicate event */
1712 s
= x_window_to_screen (event
.window
);
1713 if (event
.window
== s
->display
.x
->icon_desc
)
1718 /* If window already needs full redraw, ignore this rectangle. */
1719 if (expose_all_windows
&& s
->display
.x
->needs_exposure
)
1721 /* Put the event on the queue of rectangles to redraw. */
1722 if (enqueue_event (&event
, &x_expose_queue
))
1723 /* If it is full, we can't record the rectangle,
1724 so redraw this entire window. */
1726 /* Say must check all windows' needs_exposure flags. */
1727 expose_all_windows
= 1;
1728 s
->display
.x
->needs_exposure
= 1;
1733 /* This should happen only when we are expecting it,
1734 in x_read_exposes. */
1736 #endif /* not HAVE_X11 */
1743 s
= x_window_to_screen (event
.xunmap
.window
);
1744 if (s
) /* S may no longer exist if
1745 the screen was deleted. */
1747 /* While a screen is unmapped, display generation is
1748 disabled; you don't want to spend time updating a
1749 display that won't ever be seen. */
1751 Vmouse_window
= Vmouse_screen_part
= Qnil
;
1752 x_mouse_x
= x_mouse_y
= -1;
1758 s
= x_window_to_screen (event
.xmap
.window
);
1764 /* wait_reading_process_input will notice this and update
1765 the screen's display structures. */
1766 SET_SCREEN_GARBAGED (s
);
1770 /* Turn off processing if we become fully obscured. */
1771 case VisibilityNotify
:
1776 s
= x_window_to_screen (event
.window
);
1777 if (event
.window
== s
->display
.x
->icon_desc
)
1779 if (event
.window
== s
->display
.x
->window_desc
)
1782 #endif /* HAVE_X11 */
1786 s
= x_window_to_screen (event
.xkey
.window
);
1790 XComposeStatus status
;
1791 char copy_buffer
[80];
1793 /* This will have to go some day... */
1794 nbytes
= XLookupString (&event
.xkey
,
1802 if (IsCursorKey (keysym
) /* >= 0xff50 < 0xff60 */
1803 || IsMiscFunctionKey (keysym
) /* >= 0xff60 < 0xff80 */
1804 || IsKeypadKey (keysym
) /* >= 0xff80 <= 0xffbd */
1805 || IsFunctionKey (keysym
)) /* >= 0xffbe <= 0xffe0 */
1807 bufp
->kind
= non_ascii_keystroke
;
1808 bufp
->code
= (unsigned) keysym
- 0xff50;
1809 bufp
->modifiers
= x_convert_modifiers (event
.xkey
.state
);
1814 else if (numchars
> nbytes
)
1820 if (event
.xkey
.state
& Mod1Mask
)
1821 *copy_buffer
|= METABIT
;
1822 bufp
->kind
= ascii_keystroke
;
1823 XSET (bufp
->code
, Lisp_Int
, *copy_buffer
);
1827 for (i
= nbytes
- 1; i
> 1; i
--)
1829 bufp
->kind
= ascii_keystroke
;
1830 XSET (bufp
->code
, Lisp_Int
, copy_buffer
[i
]);
1843 register char *where_mapping
;
1845 s
= x_window_to_screen (event
.window
);
1846 /* Ignore keys typed on icon windows. */
1847 if (s
!= 0 && event
.window
== s
->display
.x
->icon_desc
)
1849 where_mapping
= XLookupMapping (&event
, &nbytes
);
1850 /* Nasty fix for arrow keys */
1851 if (!nbytes
&& IsCursorKey (event
.detail
& 0xff))
1853 switch (event
.detail
& 0xff)
1855 case KC_CURSOR_LEFT
:
1856 where_mapping
= "\002";
1858 case KC_CURSOR_RIGHT
:
1859 where_mapping
= "\006";
1862 where_mapping
= "\020";
1864 case KC_CURSOR_DOWN
:
1865 where_mapping
= "\016";
1870 if (numchars
- nbytes
> 0)
1874 for (i
= 0; i
< nbytes
; i
++)
1876 bufp
->kind
= ascii_keystroke
;
1877 XSET (bufp
->code
, Lisp_Int
, where_mapping
[i
]);
1885 #endif /* HAVE_X11 */
1889 if (event
.xcrossing
.detail
== NotifyInferior
) /* Left Scrollbar */
1891 else if (event
.xcrossing
.focus
) /* Entered Window */
1893 /* If we decide we want to generate an event to be seen
1894 by the rest of Emacs, we put it here. */
1895 struct input_event emacs_event
;
1896 emacs_event
.kind
= no_event
;
1898 s
= x_window_to_screen (event
.xcrossing
.window
);
1900 /* Avoid nasty pop/raise loops. */
1901 if (s
&& (!(s
->auto_raise
)
1903 || (event
.xcrossing
.time
- enter_timestamp
) > 500))
1905 int n
= x_new_focus_screen (s
, bufp
, numchars
);
1909 enter_timestamp
= event
.xcrossing
.time
;
1912 else if ((s
= x_window_to_scrollbar (event
.xcrossing
.window
,
1914 /* Fake a motion event */
1915 notice_mouse_movement (&emacs_event
,
1916 event
.xmotion
, s
, scrollbar_window
,
1921 if (! EQ (Vx_send_mouse_movement_events
, Qnil
)
1923 && emacs_event
.kind
!= no_event
)
1925 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
1933 else if (s
= x_window_to_screen (event
.xcrossing
.window
))
1940 s
= x_window_to_screen (event
.xfocus
.window
);
1943 int n
= x_new_focus_screen (s
, bufp
, numchars
);
1951 if (event
.xcrossing
.detail
!= NotifyInferior
1952 && event
.xcrossing
.subwindow
== None
1953 && event
.xcrossing
.mode
== NotifyNormal
)
1955 if (event
.xcrossing
.focus
)
1958 s
= x_window_to_screen (event
.xcrossing
.window
);
1959 n
= x_new_focus_screen (s
, bufp
, numchars
);
1968 s
= x_window_to_screen (event
.xfocus
.window
);
1969 if (s
&& s
== x_focus_screen
)
1971 int n
= x_new_focus_screen (0, bufp
, numchars
);
1978 #else /* not HAVE_X11 */
1981 if ((event
.detail
& 0xFF) == 1)
1982 break; /* Coming from our own subwindow */
1983 if (event
.subwindow
!= 0)
1984 break; /* Entering our own subwindow. */
1987 extern int waiting_for_input
;
1988 struct screen
*old_s
= x_input_screen
;
1990 s
= x_window_to_screen (event
.window
);
1993 if (waiting_for_input
&& x_focus_screen
== 0)
1994 x_new_selected_screen (s
);
1999 if ((event
.detail
& 0xFF) == 1)
2000 break; /* Entering our own subwindow */
2001 if (event
.subwindow
!= 0)
2002 break; /* Leaving our own subwindow. */
2005 if (x_focus_screen
== 0
2006 && x_input_screen
!= 0
2007 && x_input_screen
== x_window_to_screen (event
.window
)
2008 && event
.window
== x_input_screen
->display
.x
->window_desc
)
2013 screen_unhighlight (s
);
2016 #endif /* not HAVE_X11 */
2021 s
= x_window_to_screen (event
.xmotion
.window
);
2026 pixel_to_glyph_translation (s
,
2027 event
.xmotion
.x
, event
.xmotion
.y
,
2030 note_mouse_position (s
, column
, row
, event
.xmotion
.time
);
2033 else if ((s
= x_window_to_scrollbar (event
.xmotion
.window
,
2036 What should go here
?
2042 case ConfigureNotify
:
2045 s
= x_window_to_screen (event
.xconfigure
.window
);
2049 columns
= ((event
.xconfigure
.width
-
2050 (2 * s
->display
.x
->internal_border_width
)
2051 - s
->display
.x
->v_scrollbar_width
)
2052 / FONT_WIDTH (s
->display
.x
->font
));
2053 rows
= ((event
.xconfigure
.height
-
2054 (2 * s
->display
.x
->internal_border_width
)
2055 - s
->display
.x
->h_scrollbar_height
)
2056 / FONT_HEIGHT (s
->display
.x
->font
));
2058 if (columns
!= s
->width
|| rows
!= s
->height
)
2060 XEvent ignored_event
;
2062 change_screen_size (s
, rows
, columns
, 0);
2063 x_resize_scrollbars (s
);
2064 SET_SCREEN_GARBAGED (s
);
2066 dumprectangle (s
, 0, 0, PIXEL_WIDTH (s
), PIXEL_HEIGHT (s
));
2067 /* Throw away the exposures generated by this reconfigure. */
2068 while (XCheckWindowEvent (x_current_display
,
2069 event
.xconfigure
.window
,
2070 ExposureMask
, &ignored_event
)
2075 s
->display
.x
->left_pos
= event
.xconfigure
.x
;
2076 s
->display
.x
->top_pos
= event
.xconfigure
.y
;
2077 s
->display
.x
->pixel_width
= event
.xconfigure
.width
;
2078 s
->display
.x
->pixel_height
= event
.xconfigure
.height
;
2085 /* If we decide we want to generate an event to be seen
2086 by the rest of Emacs, we put it here. */
2087 struct input_event emacs_event
;
2088 emacs_event
.kind
= no_event
;
2090 s
= x_window_to_screen (event
.xbutton
.window
);
2092 if (!x_focus_screen
|| (s
== x_focus_screen
))
2093 construct_mouse_click (&emacs_event
,
2098 if ((s
= x_window_to_scrollbar (event
.xbutton
.window
,
2101 if (!x_focus_screen
|| (selected_screen
== x_focus_screen
))
2102 construct_mouse_click (&emacs_event
,
2103 &event
, s
, part
, prefix
);
2108 if (numchars
>= 1 && emacs_event
.kind
!= no_event
)
2110 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
2118 #else /* not HAVE_X11 */
2120 case ButtonReleased
:
2121 s
= x_window_to_screen (event
.window
);
2124 if (event
.window
== s
->display
.x
->icon_desc
)
2126 x_make_screen_visible (s
);
2128 if (warp_mouse_on_deiconify
)
2129 XWarpMouse (s
->display
.x
->window_desc
, 10, 10);
2132 if (event
.window
== s
->display
.x
->window_desc
)
2138 enqueue_event (&event
, &x_mouse_queue
);
2141 bufp
->kind
= ascii_keystroke
;
2142 bufp
->code
= (char) 'X' & 037; /* C-x */
2145 bufp
->kind
= ascii_keystroke
;
2146 bufp
->code
= (char) 0; /* C-@ */
2153 #endif /* not HAVE_X11 */
2157 case CirculateNotify
:
2159 case CirculateRequest
:
2162 #endif /* HAVE_X11 */
2165 if (event
.xmapping
.request
== MappingKeyboard
)
2166 /* Someone has changed the keyboard mapping - flush the
2168 XRefreshKeyboardMapping (&event
.xmapping
);
2178 if (expected
&& ! event_found
)
2180 /* AOJ 880406: if select returns true but XPending doesn't, it means that
2181 there is an EOF condition; in other words, that X has died.
2182 Act as if there had been a hangup. */
2184 int fd
= ConnectionNumber (x_current_display
);
2187 if (0 != select (fd
+ 1, &mask
, (long *) 0, (long *) 0,
2188 (struct timeval
*) 0)
2189 && !XStuffPending ())
2190 kill (getpid (), SIGHUP
);
2192 #endif /* HAVE_SELECT */
2195 if (updating_screen
== 0)
2196 x_do_pending_expose ();
2203 /* Read and process only Expose events
2204 until we get an ExposeCopy event; then return.
2205 This is used in insert/delete line.
2206 We assume input is already blocked. */
2212 XKeyPressedEvent event
;
2216 /* while there are more events*/
2217 XMaskEvent (ExposeWindow
| ExposeRegion
| ExposeCopy
, &event
);
2221 if (event
.subwindow
!= 0)
2222 break; /* duplicate event */
2223 s
= x_window_to_screen (event
.window
);
2224 if (event
.window
== s
->display
.x
->icon_desc
)
2229 if (event
.window
== s
->display
.x
->window_desc
)
2231 expose_all_windows
= 1;
2232 s
->display
.x
->needs_exposure
= 1;
2238 if (event
.subwindow
!= 0)
2239 break; /* duplicate event */
2240 s
= x_window_to_screen (event
.window
);
2241 if (event
.window
== s
->display
.x
->icon_desc
)
2246 /* If window already needs full redraw, ignore this rectangle. */
2247 if (expose_all_windows
&& s
->display
.x
->needs_exposure
)
2249 /* Put the event on the queue of rectangles to redraw. */
2250 if (enqueue_event (&event
, &x_expose_queue
))
2251 /* If it is full, we can't record the rectangle,
2252 so redraw this entire window. */
2254 /* Say must check all windows' needs_exposure flags. */
2255 expose_all_windows
= 1;
2256 s
->display
.x
->needs_exposure
= 1;
2265 #endif /* HAVE_X11 */
2268 XTmouse_tracking_enable (enable
)
2273 /* Go through the list of screens and turn on/off mouse tracking for
2275 for (tail
= Vscreen_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
2277 if (XTYPE (XCONS (tail
)->car
) != Lisp_Screen
)
2279 if (XSCREEN (XCONS (tail
)->car
)->output_method
== output_x_window
)
2280 XSelectInput (x_current_display
,
2281 XSCREEN (XCONS (tail
)->car
)->display
.x
->window_desc
,
2283 ? (STANDARD_EVENT_SET
2285 | ButtonReleaseMask
)
2286 : STANDARD_EVENT_SET
));
2299 /* Draw a hollow box cursor. Don't change the inside of the box. */
2305 int left
= s
->cursor_x
* FONT_WIDTH (s
->display
.x
->font
)
2306 + s
->display
.x
->internal_border_width
;
2307 int top
= s
->cursor_y
* FONT_HEIGHT (s
->display
.x
->font
)
2308 + s
->display
.x
->internal_border_width
;
2309 int width
= FONT_WIDTH (s
->display
.x
->font
);
2310 int height
= FONT_HEIGHT (s
->display
.x
->font
);
2313 /* Perhaps we should subtract 1 from width and height... */
2314 XDrawRectangle (x_current_display
, s
->display
.x
->window_desc
,
2315 s
->display
.x
->cursor_gc
,
2316 left
, top
, width
- 1, height
- 1);
2318 XPixSet (s
->display
.x
->window_desc
,
2319 left
, top
, width
, 1,
2320 s
->display
.x
->cursor_pixel
);
2322 XPixSet (s
->display
.x
->window_desc
,
2323 left
, top
, 1, height
,
2324 s
->display
.x
->cursor_pixel
);
2326 XPixSet (s
->display
.x
->window_desc
,
2327 left
+width
-1, top
, 1, height
,
2328 s
->display
.x
->cursor_pixel
);
2330 XPixSet (s
->display
.x
->window_desc
,
2331 left
, top
+height
-1, width
, 1,
2332 s
->display
.x
->cursor_pixel
);
2333 #endif /* HAVE_X11 */
2336 /* Clear the cursor of screen S to background color,
2337 and mark the cursor as not shown.
2338 This is used when the text where the cursor is
2339 is about to be rewritten. */
2348 || s
->phys_cursor_x
< 0)
2352 x_display_cursor (s
, 0);
2354 XClearArea (x_current_display
, s
->display
.x
->window_desc
,
2355 s
->phys_cursor_x
* FONT_WIDTH (s
->display
.x
->font
)
2356 + s
->display
.x
->internal_border_width
,
2357 s
->phys_cursor_y
* FONT_HEIGHT (s
->display
.x
->font
)
2358 + s
->display
.x
->internal_border_width
,
2359 FONT_WIDTH (s
->display
.x
->font
) + 1, FONT_HEIGHT (s
->display
.x
->font
) + 1, False
);
2362 XPixSet (s
->display
.x
->window_desc
,
2363 s
->phys_cursor_x
* FONT_WIDTH (s
->display
.x
->font
) + s
->display
.x
->internal_border_width
,
2364 s
->phys_cursor_y
* FONT_HEIGHT (s
->display
.x
->font
) + s
->display
.x
->internal_border_width
,
2365 FONT_WIDTH (s
->display
.x
->font
), FONT_HEIGHT (s
->display
.x
->font
),
2366 s
->display
.x
->background_pixel
);
2367 #endif /* HAVE_X11 */
2368 s
->phys_cursor_x
= -1;
2371 x_display_bar_cursor (s
, on
)
2375 register int phys_x
= s
->phys_cursor_x
;
2376 register int phys_y
= s
->phys_cursor_y
;
2381 if (! s
->visible
|| (! on
&& s
->phys_cursor_x
< 0))
2386 (!on
|| phys_x
!= s
->cursor_x
|| phys_y
!= s
->cursor_y
))
2388 x1
= phys_x
* FONT_WIDTH (s
->display
.x
->font
)
2389 + s
->display
.x
->internal_border_width
;
2390 y1
= phys_y
* FONT_HEIGHT (s
->display
.x
->font
)
2391 + s
->display
.x
->internal_border_width
- 1;
2392 y2
= y1
+ FONT_HEIGHT (s
->display
.x
->font
) + 1;
2394 XDrawLine (x_current_display
, s
->display
.x
->window_desc
,
2395 s
->display
.x
->reverse_gc
, x1
, y1
, x1
, y2
);
2397 s
->phys_cursor_x
= phys_x
= -1;
2400 if (on
&& s
== x_focus_screen
)
2402 x1
= s
->cursor_x
* FONT_WIDTH (s
->display
.x
->font
)
2403 + s
->display
.x
->internal_border_width
;
2404 y1
= s
->cursor_y
* FONT_HEIGHT (s
->display
.x
->font
)
2405 + s
->display
.x
->internal_border_width
- 1;
2406 y2
= y1
+ FONT_HEIGHT (s
->display
.x
->font
) + 1;
2408 XDrawLine (x_current_display
, s
->display
.x
->window_desc
,
2409 s
->display
.x
->cursor_gc
, x1
, y1
, x1
, y2
);
2411 s
->phys_cursor_x
= s
->cursor_x
;
2412 s
->phys_cursor_y
= s
->cursor_y
;
2420 /* Redraw the glyph at ROW, COLUMN on screen S, in the style HIGHLIGHT.
2421 If there is no character there, erase the area. HIGHLIGHT is as
2422 defined for dumpglyphs. */
2425 x_draw_single_glyph (s
, row
, column
, highlight
)
2430 register struct screen_glyphs
*current_screen
= SCREEN_CURRENT_GLYPHS (s
);
2432 /* If there is supposed to be a character there, redraw it
2433 in that line's normal video. */
2434 if (current_screen
->enable
[row
]
2435 && column
< current_screen
->used
[row
])
2437 (column
* FONT_WIDTH (s
->display
.x
->font
)
2438 + s
->display
.x
->internal_border_width
),
2439 (row
* FONT_HEIGHT (s
->display
.x
->font
)
2440 + s
->display
.x
->internal_border_width
),
2441 ¤t_screen
->glyphs
[row
][column
],
2442 1, highlight
, s
->display
.x
->font
);
2446 static GLYPH a_space_glyph
= SPACEGLYPH
;
2448 (column
* FONT_WIDTH (s
->display
.x
->font
)
2449 + s
->display
.x
->internal_border_width
),
2450 (row
* FONT_HEIGHT (s
->display
.x
->font
)
2451 + s
->display
.x
->internal_border_width
),
2452 &a_space_glyph
, 1, highlight
, s
->display
.x
->font
);
2454 XPixSet (s
->display
.x
->window_desc
,
2455 (column
* FONT_WIDTH (s
->display
.x
->font
)
2456 + s
->display
.x
->internal_border_width
),
2457 (row
* FONT_HEIGHT (s
->display
.x
->font
)
2458 + s
->display
.x
->internal_border_width
),
2459 FONT_WIDTH (s
->display
.x
->font
),
2460 FONT_HEIGHT (s
->display
.x
->font
),
2462 ? s
->display
.x
->background_pixel
2464 ? s
->display
.x
->foreground_pixel
2465 : s
->display
.x
->cursor_pixel
)));
2466 #endif /* HAVE_X11 */
2470 /* Turn the displayed cursor of screen S on or off according to ON.
2471 If ON is nonzero, where to put the cursor is specified
2472 by S->cursor_x and S->cursor_y. */
2475 x_display_box_cursor (s
, on
)
2482 /* If cursor is off and we want it off, return quickly. */
2484 if (!on
&& s
->phys_cursor_x
< 0)
2487 /* If cursor is currently being shown and we don't want it to be
2488 or it is in the wrong place,
2489 or we want a hollow box and it's not so, (pout!)
2491 if (s
->phys_cursor_x
>= 0
2493 || s
->phys_cursor_x
!= s
->cursor_x
2494 || s
->phys_cursor_y
!= s
->cursor_y
2495 || (s
->display
.x
->text_cursor_kind
!= hollow_box_cursor
2496 && (s
!= x_focus_screen
))))
2498 /* Erase the cursor by redrawing the character underneath it. */
2499 x_draw_single_glyph (s
, s
->phys_cursor_y
, s
->phys_cursor_x
,
2500 (SCREEN_CURRENT_GLYPHS (s
)
2501 ->highlight
[s
->phys_cursor_y
]));
2503 s
->phys_cursor_x
= -1;
2506 /* If we want to show a cursor,
2507 or we want a box cursor and it's not so,
2508 write it in the right place. */
2510 && (s
->phys_cursor_x
< 0
2511 || (s
->display
.x
->text_cursor_kind
!= filled_box_cursor
2512 && s
== x_focus_screen
)))
2514 if (s
!= x_focus_screen
)
2517 s
->display
.x
->text_cursor_kind
= hollow_box_cursor
;
2521 x_draw_single_glyph (s
, s
->cursor_y
, s
->cursor_x
, 2);
2522 s
->display
.x
->text_cursor_kind
= filled_box_cursor
;
2525 s
->phys_cursor_x
= s
->cursor_x
;
2526 s
->phys_cursor_y
= s
->cursor_y
;
2529 if (updating_screen
!= s
)
2533 extern Lisp_Object Vbar_cursor
;
2535 x_display_cursor (s
, on
)
2539 if (EQ (Vbar_cursor
, Qnil
))
2540 x_display_box_cursor (s
, on
);
2542 x_display_bar_cursor (s
, on
);
2547 /* Refresh bitmap kitchen sink icon for screen S
2548 when we get an expose event for it. */
2554 /* Normally, the window manager handles this function. */
2558 if (s
->display
.x
->icon_bitmap_flag
)
2559 XBitmapBitsPut (s
->display
.x
->icon_desc
, 0, 0, sink_width
, sink_height
,
2560 sink_bits
, BlackPixel
, WHITE_PIX_DEFAULT
,
2561 icon_bitmap
, GXcopy
, AllPlanes
);
2564 extern struct screen
*selected_screen
;
2565 struct Lisp_String
*str
;
2566 unsigned char *string
;
2569 = XSTRING (XBUFFER (XWINDOW (s
->selected_window
)->buffer
)->name
)->data
;
2571 if (s
->display
.x
->icon_label
!= string
)
2573 s
->display
.x
->icon_label
= string
;
2574 XChangeWindow (s
->display
.x
->icon_desc
,
2575 XQueryWidth (string
, icon_font_info
->id
) + 10,
2576 icon_font_info
->height
+ 10);
2579 XText (s
->display
.x
->icon_desc
, 5, 5, string
,
2580 str
->size
, icon_font_info
->id
,
2581 BLACK_PIX_DEFAULT
, WHITE_PIX_DEFAULT
);
2584 #endif /* HAVE_X11 */
2587 /* Make the x-window of screen S use the kitchen-sink icon
2588 that's a window generated by Emacs. */
2597 if (s
->display
.x
->window_desc
== 0)
2602 XFreePixmap (x_current_display
, icon_bitmap
);
2605 XCreateBitmapFromData (x_current_display
, s
->display
.x
->window_desc
,
2606 gnu_bits
, gnu_width
, gnu_height
);
2607 x_wm_set_icon_pixmap (s
, icon_bitmap
);
2608 s
->display
.x
->icon_bitmap_flag
= 1;
2610 if (s
->display
.x
->icon_desc
)
2612 XClearIconWindow (s
->display
.x
->window_desc
);
2613 XDestroyWindow (s
->display
.x
->icon_desc
);
2616 icon_window
= XCreateWindow (s
->display
.x
->parent_desc
,
2617 0, 0, sink_width
, sink_height
,
2618 2, WhitePixmap
, (Pixmap
) NULL
);
2620 if (icon_window
== 0)
2623 XSetIconWindow (s
->display
.x
->window_desc
, icon_window
);
2624 XSelectInput (icon_window
, ExposeWindow
| UnmapWindow
);
2626 s
->display
.x
->icon_desc
= icon_window
;
2627 s
->display
.x
->icon_bitmap_flag
= 1;
2629 if (icon_bitmap
== 0)
2631 = XStoreBitmap (sink_mask_width
, sink_mask_height
, sink_mask_bits
);
2632 #endif /* HAVE_X11 */
2638 /* Make the x-window of screen S use a rectangle with text. */
2641 x_text_icon (s
, icon_name
)
2649 char *X_DefaultValue
;
2652 #if 0 /* This doesn't seem to be used, but I can't quite believe it. */
2653 static Pixmap grey_pixmap
;
2657 #define WhitePixel 1
2661 #define BlackPixel 0
2663 #endif /* not HAVE_X11 */
2665 if (s
->display
.x
->window_desc
== 0)
2668 if (icon_font_info
== 0)
2670 = XGetFont (XGetDefault (XDISPLAY invocation_name
, "BodyFont"));
2674 s
->display
.x
->icon_label
= icon_name
;
2676 if (! s
->display
.x
->icon_label
)
2677 s
->display
.x
->icon_label
= " *emacs* ";
2679 XSetIconName (x_current_display
, s
->display
.x
->window_desc
,
2680 (char *) s
->display
.x
->icon_label
);
2682 s
->display
.x
->icon_bitmap_flag
= 0;
2684 if (s
->display
.x
->icon_desc
)
2686 XClearIconWindow (XDISPLAY s
->display
.x
->window_desc
);
2687 XDestroyWindow (XDISPLAY s
->display
.x
->icon_desc
);
2691 s
->display
.x
->icon_label
= (unsigned char *) icon_name
;
2693 if (! s
->display
.x
->icon_label
)
2694 s
->display
.x
->icon_label
= XSTRING (s
->name
)->data
;
2696 width
= XStringWidth (s
->display
.x
->icon_label
, icon_font_info
, 0, 0);
2697 icon_window
= XCreateWindow (s
->display
.x
->parent_desc
,
2698 s
->display
.x
->left_pos
,
2699 s
->display
.x
->top_pos
,
2700 width
+ 10, icon_font_info
->height
+ 10,
2701 2, BlackPixmap
, WhitePixmap
);
2703 if (icon_window
== 0)
2706 XSetIconWindow (s
->display
.x
->window_desc
, icon_window
);
2707 XSelectInput (icon_window
, ExposeWindow
| ExposeRegion
| UnmapWindow
| ButtonPressed
);
2709 s
->display
.x
->icon_desc
= icon_window
;
2710 s
->display
.x
->icon_bitmap_flag
= 0;
2711 s
->display
.x
->icon_label
= 0;
2712 #endif /* HAVE_X11 */
2717 static char *x_proto_requests
[] =
2720 "ChangeWindowAttributes",
2721 "GetWindowAttributes",
2723 "DestroySubwindows",
2740 "SetSelectionOwner",
2741 "GetSelectionOwner",
2748 "ChangeActivePointerGrab",
2768 "ListFontsWithInfo",
2777 "SetClipRectangles",
2788 "PolyFillRectangle",
2798 "CopyColormapAndFree",
2800 "UninstallColormap",
2801 "ListInstalledColormaps",
2812 "CreateGlyphCursor",
2818 "ChangeKeyboardMapping",
2819 "GetKeyboardMapping",
2820 "ChangeKeyboardControl",
2821 "GetKeyboardControl",
2823 "ChangePointerControl",
2824 "GetPointerControl",
2834 "SetPointerMapping",
2835 "GetPointerMapping",
2836 "SetModifierMapping",
2837 "GetModifierMapping",
2841 #define acceptable_x_error_p(type) ((type) == 94)
2843 x_handle_error_gracefully (event
)
2846 char error_ptr
[128];
2847 char *proto_ptr
= x_proto_requests
[event
->request_code
];
2850 XGetErrorText (x_current_display
, event
->error_code
, error_ptr
, 128);
2851 sprintf (str
, "X Protocol Error: %s on request: %s", error_ptr
, proto_ptr
);
2852 TOTALLY_UNBLOCK_INPUT
;
2857 extern int x_selection_alloc_error
;
2858 extern int x_converting_selection
;
2861 /* Handle X Errors. If the error is not traumatic,
2862 just call error (). Otherwise print a (hopefully) interesting
2865 The arg to Fkill_emacs is an exit status value
2866 and also prevents any questions. */
2868 x_error_handler (disp
, event
)
2873 #define XlibDisplayIOError (1L << 0)
2876 struct _XErrorEvent
*event
;
2879 /* Here we use the standard X handlers. */
2882 if (event
&& event
->type
== 0) /* 0 is the XError Event type. */
2886 if (event
->request_code
== BadAlloc
&& x_converting_selection
)
2887 x_selection_alloc_error
= 1;
2891 if (acceptable_x_error_p (event
->request_code
))
2892 x_handle_error_gracefully (event
);
2894 _XDefaultError (disp
, event
);
2898 disp
->flags
|= XlibDisplayIOError
;
2899 _XDefaultIOError (disp
);
2906 Fkill_emacs (make_number (70));
2909 /* Initialize communication with the X window server. */
2912 static unsigned int x_wire_count
;
2915 fprintf (stderr
, "Lib call: %d\n", ++x_wire_count
);
2920 /* Set the font of the x-window specified by screen S
2921 to the font named NEWNAME. This is safe to use
2922 even before S has an actual x-window. */
2926 /* A table of all the fonts we have already loaded. */
2927 static XFontStruct
**x_font_table
;
2929 /* The current capacity of x_font_table. */
2930 static int x_font_table_size
;
2932 /* The number of fonts actually stored in x_font_table.
2933 x_font_table[n] is used and valid iff 0 <= n < n_fonts.
2934 0 <= n_fonts <= x_font_table_size. */
2937 x_new_font (s
, fontname
)
2939 register char *fontname
;
2943 int n_matching_fonts
;
2944 XFontStruct
*font_info
;
2947 /* Get a list of all the fonts that match this name. Once we
2948 have a list of matching fonts, we compare them against the fonts
2949 we already have by comparing font ids. */
2950 font_names
= (char **) XListFontsWithInfo (x_current_display
, fontname
,
2951 1024, &n_matching_fonts
,
2953 /* If the server couldn't find any fonts whose named matched fontname,
2954 return an error code. */
2955 if (n_matching_fonts
== 0)
2958 /* See if we've already loaded this font. */
2963 for (i
= 0; i
< n_fonts
; i
++)
2964 for (j
= 0; j
< n_matching_fonts
; j
++)
2965 if (x_font_table
[i
]->fid
== font_info
[j
].fid
)
2973 /* If we have, just return it from the table. */
2976 s
->display
.x
->font
= x_font_table
[already_loaded
];
2979 /* Otherwise, load the font and add it to the table. */
2984 font
= (XFontStruct
*) XLoadQueryFont (x_current_display
, fontname
);
2988 /* Do we need to create the table? */
2989 if (x_font_table_size
== 0)
2991 x_font_table_size
= 16;
2993 = (XFontStruct
**) xmalloc (x_font_table_size
2994 * sizeof (x_font_table
[0]));
2996 /* Do we need to grow the table? */
2997 else if (n_fonts
>= x_font_table_size
)
2999 x_font_table_size
<<= 1;
3001 = (XFontStruct
**) xrealloc (x_font_table
,
3003 * sizeof (x_font_table
[0])));
3006 s
->display
.x
->font
= x_font_table
[n_fonts
++] = font
;
3009 /* Free the information from XListFontsWithInfo. The data
3010 we actually retain comes from XLoadQueryFont. */
3011 XFreeFontInfo (font_names
, font_info
, n_matching_fonts
);
3013 /* Now make the screen display the given font. */
3014 if (s
->display
.x
->window_desc
!= 0)
3016 XSetFont (x_current_display
, s
->display
.x
->normal_gc
,
3017 s
->display
.x
->font
->fid
);
3018 XSetFont (x_current_display
, s
->display
.x
->reverse_gc
,
3019 s
->display
.x
->font
->fid
);
3020 XSetFont (x_current_display
, s
->display
.x
->cursor_gc
,
3021 s
->display
.x
->font
->fid
);
3023 x_set_window_size (s
, s
->width
, s
->height
);
3029 x_new_font (s
, newname
)
3031 register char *newname
;
3036 temp
= XGetFont (newname
);
3037 if (temp
== (FONT_TYPE
*) 0)
3040 if (s
->display
.x
->font
)
3041 XLoseFont (s
->display
.x
->font
);
3043 s
->display
.x
->font
= temp
;
3045 if (s
->display
.x
->window_desc
!= 0)
3046 x_set_window_size (s
, s
->width
, s
->height
);
3052 x_calc_absolute_position (s
)
3056 if (s
->display
.x
->left_pos
< 0)
3057 s
->display
.x
->left_pos
3058 = XINT (x_screen_width
) - PIXEL_WIDTH (s
) + s
->display
.x
->left_pos
;
3060 if (s
->display
.x
->top_pos
< 0)
3061 s
->display
.x
->top_pos
3062 = XINT (x_screen_height
) - PIXEL_HEIGHT (s
) + s
->display
.x
->top_pos
;
3064 WINDOWINFO_TYPE parentinfo
;
3066 XGetWindowInfo (s
->display
.x
->window_desc
, &parentinfo
);
3068 if (s
->display
.x
->left_pos
< 0)
3069 s
->display
.x
->left_pos
= parentinfo
.width
+ (s
->display
.x
->left_pos
+ 1)
3070 - PIXEL_WIDTH (s
) - 2 * s
->display
.x
->internal_border_width
;
3072 if (s
->display
.x
->top_pos
< 0)
3073 s
->display
.x
->top_pos
= parentinfo
.height
+ (s
->display
.x
->top_pos
+ 1)
3074 - PIXEL_HEIGHT (s
) - 2 * s
->display
.x
->internal_border_width
;
3078 x_set_offset (s
, xoff
, yoff
)
3080 register int xoff
, yoff
;
3082 s
->display
.x
->top_pos
= yoff
;
3083 s
->display
.x
->left_pos
= xoff
;
3084 x_calc_absolute_position (s
);
3087 XMoveWindow (XDISPLAY s
->display
.x
->window_desc
,
3088 s
->display
.x
->left_pos
, s
->display
.x
->top_pos
);
3090 x_wm_set_size_hint (s
, 0);
3095 /* Call this to change the size of screen S's x-window. */
3097 x_set_window_size (s
, cols
, rows
)
3099 register int cols
, rows
;
3101 int pixelwidth
, pixelheight
;
3103 int ibw
= s
->display
.x
->internal_border_width
;
3107 /* ??? Who DOES worry about minimum reasonable sizes? */
3108 pixelwidth
= (cols
* FONT_WIDTH (s
->display
.x
->font
) + 2 * ibw
3109 + s
->display
.x
->v_scrollbar_width
);
3110 pixelheight
= (rows
* FONT_HEIGHT (s
->display
.x
->font
) + 2 * ibw
3111 + s
->display
.x
->h_scrollbar_height
);
3114 x_wm_set_size_hint (s
, 0);
3115 #endif /* HAVE_X11 */
3116 XChangeWindowSize (s
->display
.x
->window_desc
, pixelwidth
, pixelheight
);
3122 x_set_resize_hint (s
)
3126 XSetResizeHint (s
->display
.x
->window_desc
, 2 * s
->display
.x
->internal_border_width
,
3127 2 * s
->display
.x
->internal_border_width
,
3128 FONT_WIDTH (s
->display
.x
->font
), FONT_HEIGHT (s
->display
.x
->font
));
3130 #endif /* not HAVE_X11 */
3133 x_set_mouse_position (s
, x
, y
)
3142 pix_x
= (SCREEN_WIDTH (s
)
3143 * FONT_WIDTH (s
->display
.x
->font
)
3144 + 2 * s
->display
.x
->internal_border_width
3145 + s
->display
.x
->v_scrollbar_width
) / 2;
3147 pix_x
= x
* FONT_WIDTH (s
->display
.x
->font
) + 2; /* add 2 pixels to each
3148 dimension to move the
3153 pix_y
= (SCREEN_HEIGHT (s
)
3154 * FONT_HEIGHT (s
->display
.x
->font
)
3155 + 2 * s
->display
.x
->internal_border_width
3156 + s
->display
.x
->h_scrollbar_height
) / 2;
3158 pix_y
= y
* FONT_HEIGHT (s
->display
.x
->font
) + 2;
3164 XWarpMousePointer (s
->display
.x
->window_desc
, pix_x
, pix_y
);
3169 x_focus_on_screen (s
)
3173 XSetInputFocus (x_current_display
, s
->display
.x
->window_desc
,
3174 RevertToPointerRoot
, CurrentTime
);
3177 x_unfocus_screen (s
)
3180 if (x_focus_screen
== s
)
3181 XSetInputFocus (x_current_display
, PointerRoot
,
3182 RevertToPointerRoot
, CurrentTime
);
3187 /* Raise screen S. */
3195 XRaiseWindow (XDISPLAY s
->display
.x
->window_desc
);
3201 /* Lower screen S. */
3209 XLowerWindow (XDISPLAY s
->display
.x
->window_desc
);
3215 /* Change from withdrawn state to mapped state. */
3217 x_make_screen_visible (s
)
3225 XRaiseWindow (XDISPLAY s
->display
.x
->window_desc
);
3234 if (! EQ (Vx_no_window_manager
, Qt
))
3235 x_wm_set_window_state (s
, NormalState
);
3237 XMapWindow (XDISPLAY s
->display
.x
->window_desc
);
3238 if (s
->display
.x
->v_scrollbar
!= 0 || s
->display
.x
->h_scrollbar
!= 0)
3239 XMapSubwindows (x_current_display
, s
->display
.x
->window_desc
);
3242 XMapWindow (XDISPLAY s
->display
.x
->window_desc
);
3243 if (s
->display
.x
->icon_desc
!= 0)
3244 XUnmapWindow (s
->display
.x
->icon_desc
);
3246 /* Handled by the MapNotify event for X11 */
3250 /* NOTE: this may cause problems for the first screen. */
3252 #endif /* not HAVE_X11 */
3254 XRaiseWindow (XDISPLAY s
->display
.x
->window_desc
);
3259 /* Change from mapped state to withdrawn state. */
3261 x_make_screen_invisible (s
)
3272 if (! EQ (Vx_no_window_manager
, Qt
))
3276 unmap
.type
= UnmapNotify
;
3277 unmap
.window
= s
->display
.x
->window_desc
;
3278 unmap
.event
= DefaultRootWindow (x_current_display
);
3279 unmap
.from_configure
= False
;
3280 XSendEvent (x_current_display
, DefaultRootWindow (x_current_display
),
3281 False
, SubstructureRedirectMask
|SubstructureNotifyMask
,
3285 /* The new function below does the same as the above code, plus unmapping
3286 the window. Sending the event without actually unmapping can make
3287 the window manager start ignoring the window (i.e., no more title bar,
3288 icon manager stuff.) */
3291 /* New function available with R4 */
3292 if (! XWithdrawWindow (x_current_display
, s
->display
.x
->window_desc
,
3293 DefaultScreen (x_current_display
)))
3295 UNBLOCK_INPUT_RESIGNAL
;
3296 error ("Can't notify window manager of iconification.");
3300 XUnmapWindow (XDISPLAY s
->display
.x
->window_desc
);
3302 s
->visible
= 0; /* Handled by the UnMap event for X11 */
3303 if (s
->display
.x
->icon_desc
!= 0)
3304 XUnmapWindow (XDISPLAY s
->display
.x
->icon_desc
);
3305 #endif /* not HAVE_X11 */
3311 /* Window manager communication. Created in Fx_open_connection. */
3312 extern Atom Xatom_wm_change_state
;
3314 /* Change window state from mapped to iconified. */
3316 x_iconify_screen (s
)
3327 if (! EQ (Vx_no_window_manager
, Qt
))
3328 if (! XIconifyWindow (x_current_display
, s
->display
.x
->window_desc
,
3329 DefaultScreen (x_current_display
)))
3331 UNBLOCK_INPUT_RESIGNAL
;
3332 error ("Can't notify window manager of iconification.");
3339 XClientMessageEvent message
;
3341 message
.window
= s
->display
.x
->window_desc
;
3342 message
.type
= ClientMessage
;
3343 message
.message_type
= Xatom_wm_change_state
;
3344 message
.format
= 32;
3345 message
.data
.l
[0] = IconicState
;
3347 if (! XSendEvent (x_current_display
,
3348 DefaultRootWindow (x_current_display
),
3350 SubstructureRedirectMask
| SubstructureNotifyMask
,
3353 UNBLOCK_INPUT_RESIGNAL
;
3354 error ("Can't notify window manager of iconification.");
3359 XUnmapWindow (XDISPLAY s
->display
.x
->window_desc
);
3361 s
->visible
= 0; /* Handled in the UnMap event for X11. */
3362 if (s
->display
.x
->icon_desc
!= 0)
3364 XMapWindow (XDISPLAY s
->display
.x
->icon_desc
);
3373 /* Destroy the X window of screen S.
3374 DISPL is the former s->display (since s->display
3375 has already been nulled out). */
3377 x_destroy_window (s
, displ
)
3379 union display displ
;
3384 if (displ
.x
->icon_desc
!= 0)
3385 XDestroyWindow (XDISPLAY displ
.x
->icon_desc
);
3386 XDestroyWindow (XDISPLAY displ
.x
->window_desc
);
3391 if (s
== x_focus_screen
)
3397 /* Manage event queues.
3399 This code is only used by the X10 support.
3401 We cannot leave events in the X queue and get them when we are ready
3402 because X does not provide a subroutine to get only a certain kind
3403 of event but not block if there are no queued events of that kind.
3405 Therefore, we must examine events as they come in and copy events
3406 of certain kinds into our private queues.
3408 All ExposeRegion events are put in x_expose_queue.
3409 All ButtonPressed and ButtonReleased events are put in x_mouse_queue. */
3412 /* Write the event *P_XREP into the event queue *QUEUE.
3413 If the queue is full, do nothing, but return nonzero. */
3416 enqueue_event (p_xrep
, queue
)
3417 register XEvent
*p_xrep
;
3418 register struct event_queue
*queue
;
3420 int newindex
= queue
->windex
+ 1;
3421 if (newindex
== EVENT_BUFFER_SIZE
)
3423 if (newindex
== queue
->rindex
)
3425 queue
->xrep
[queue
->windex
] = *p_xrep
;
3426 queue
->windex
= newindex
;
3430 /* Fetch the next event from queue *QUEUE and store it in *P_XREP.
3431 If *QUEUE is empty, do nothing and return 0. */
3434 dequeue_event (p_xrep
, queue
)
3435 register XEvent
*p_xrep
;
3436 register struct event_queue
*queue
;
3438 if (queue
->windex
== queue
->rindex
)
3440 *p_xrep
= queue
->xrep
[queue
->rindex
++];
3441 if (queue
->rindex
== EVENT_BUFFER_SIZE
)
3446 /* Return the number of events buffered in *QUEUE. */
3449 queue_event_count (queue
)
3450 register struct event_queue
*queue
;
3452 int tem
= queue
->windex
- queue
->rindex
;
3455 return EVENT_BUFFER_SIZE
+ tem
;
3458 /* Return nonzero if mouse input is pending. */
3461 mouse_event_pending_p ()
3463 return queue_event_count (&x_mouse_queue
);
3469 x_wm_set_size_hint (s
, prompting
)
3473 XSizeHints size_hints
;
3474 Window window
= s
->display
.x
->window_desc
;
3476 size_hints
.flags
= PResizeInc
| PMinSize
| PMaxSize
;
3478 flexlines
= s
->height
;
3480 size_hints
.x
= s
->display
.x
->left_pos
;
3481 size_hints
.y
= s
->display
.x
->top_pos
;
3482 size_hints
.height
= PIXEL_HEIGHT (s
);
3483 size_hints
.width
= PIXEL_WIDTH (s
);
3484 size_hints
.width_inc
= FONT_WIDTH (s
->display
.x
->font
);
3485 size_hints
.height_inc
= FONT_HEIGHT (s
->display
.x
->font
);
3486 size_hints
.base_width
= (2 * s
->display
.x
->internal_border_width
)
3487 + s
->display
.x
->v_scrollbar_width
;
3488 size_hints
.base_height
= (2 * s
->display
.x
->internal_border_width
)
3489 + s
->display
.x
->h_scrollbar_height
;
3490 size_hints
.min_width
= size_hints
.base_width
+ size_hints
.width_inc
;
3491 size_hints
.min_height
= size_hints
.base_height
+ size_hints
.height_inc
;
3492 size_hints
.max_width
= x_screen_width
3493 - ((2 * s
->display
.x
->internal_border_width
)
3494 + s
->display
.x
->v_scrollbar_width
);
3495 size_hints
.max_height
= x_screen_height
3496 - ((2 * s
->display
.x
->internal_border_width
)
3497 + s
->display
.x
->h_scrollbar_height
);
3500 size_hints
.flags
|= prompting
;
3503 XSizeHints hints
; /* Sometimes I hate X Windows... */
3505 XGetNormalHints (x_current_display
, window
, &hints
);
3506 if (hints
.flags
& PSize
)
3507 size_hints
.flags
|= PSize
;
3508 if (hints
.flags
& PPosition
)
3509 size_hints
.flags
|= PPosition
;
3510 if (hints
.flags
& USPosition
)
3511 size_hints
.flags
|= USPosition
;
3512 if (hints
.flags
& USSize
)
3513 size_hints
.flags
|= USSize
;
3517 XSetNormalHints (x_current_display
, window
, &size_hints
);
3519 XSetWMNormalHints (x_current_display
, window
, &size_hints
);
3522 /* Used for IconicState or NormalState */
3523 x_wm_set_window_state (s
, state
)
3528 Window window
= s
->display
.x
->window_desc
;
3530 wm_hints
.flags
= StateHint
;
3531 wm_hints
.initial_state
= state
;
3532 XSetWMHints (x_current_display
, window
, &wm_hints
);
3535 x_wm_set_icon_pixmap (s
, icon_pixmap
)
3540 Window window
= s
->display
.x
->window_desc
;
3542 wm_hints
.flags
= IconPixmapHint
;
3543 wm_hints
.icon_pixmap
= icon_pixmap
;
3544 XSetWMHints (x_current_display
, window
, &wm_hints
);
3547 x_wm_set_icon_position (s
, icon_x
, icon_y
)
3552 Window window
= s
->display
.x
->window_desc
;
3554 wm_hints
.flags
= IconPositionHint
;
3555 wm_hints
.icon_x
= icon_x
;
3556 wm_hints
.icon_y
= icon_y
;
3557 XSetWMHints (x_current_display
, window
, &wm_hints
);
3562 init_input_symbols ()
3564 Qmapped_screen
= intern ("mapped-screen");
3565 Qunmapped_screen
= intern ("unmapped-screen");
3566 Qexited_scrollbar
= intern ("exited-scrollbar");
3567 Qexited_window
= intern ("exited-window");
3568 Qredraw_screen
= intern ("redraw-screen");
3569 Qmouse_moved
= intern ("mouse-moved");
3570 Qmouse_click
= intern ("mouse-click");
3571 Qscrollbar_click
= intern ("scrollbar-click");
3575 x_term_init (display_name
)
3581 extern int old_fcntl_owner
;
3584 x_current_display
= XOpenDisplay (display_name
);
3585 if (x_current_display
== 0)
3586 fatal ("X server %s not responding; check the DISPLAY environment variable or use \"-d\"\n",
3591 int hostname_size
= MAXHOSTNAMELEN
+ 1;
3593 hostname
= (char *) xmalloc (hostname_size
);
3596 XSetAfterFunction (x_current_display
, x_trace_wire
);
3599 invocation_name
= (char *)
3600 XSTRING (Ffile_name_nondirectory (Fcar (Vcommand_line_args
)))->data
;
3602 /* Try to get the host name; if the buffer is too short, try
3603 again. Apparently, the only indication gethostname gives of
3604 whether the buffer was large enough is the presence or absence
3605 of a '\0' in the string. Eech. */
3608 gethostname (hostname
, hostname_size
- 1);
3609 hostname
[hostname_size
- 1] = '\0';
3611 /* Was the buffer large enough for gethostname to store the '\0'? */
3612 if (strlen (hostname
) < hostname_size
- 1)
3615 hostname_size
<<= 1;
3616 hostname
= (char *) xrealloc (hostname
, hostname_size
);
3618 id_name
= (char *) xmalloc (strlen (invocation_name
)
3621 sprintf (id_name
, "%s@%s", invocation_name
, hostname
);
3624 dup2 (ConnectionNumber (x_current_display
), 0);
3625 close (ConnectionNumber (x_current_display
));
3626 ConnectionNumber (x_current_display
) = 0;
3627 #endif /* HAVE_X11 */
3630 old_fcntl_owner
= fcntl (0, F_GETOWN
, 0);
3631 #ifdef F_SETOWN_SOCK_NEG
3632 fcntl (0, F_SETOWN
, -getpid ()); /* stdin is a socket here */
3634 fcntl (0, F_SETOWN
, getpid ());
3635 #endif /* F_SETOWN_SOCK_NEG */
3636 #endif /* F_SETOWN */
3642 /* Must use interrupt input because we cannot otherwise
3643 arrange for C-g to be noticed immediately.
3644 We cannot connect it to SIGINT. */
3645 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
3647 expose_all_windows
= 0;
3649 clear_screen_hook
= XTclear_screen
;
3650 clear_end_of_line_hook
= XTclear_end_of_line
;
3651 ins_del_lines_hook
= XTins_del_lines
;
3652 change_line_highlight_hook
= XTchange_line_highlight
;
3653 insert_glyphs_hook
= XTinsert_glyphs
;
3654 write_glyphs_hook
= XTwrite_glyphs
;
3655 delete_glyphs_hook
= XTdelete_glyphs
;
3656 ring_bell_hook
= XTring_bell
;
3657 reset_terminal_modes_hook
= XTreset_terminal_modes
;
3658 set_terminal_modes_hook
= XTset_terminal_modes
;
3659 update_begin_hook
= XTupdate_begin
;
3660 update_end_hook
= XTupdate_end
;
3661 set_terminal_window_hook
= XTset_terminal_window
;
3662 read_socket_hook
= XTread_socket
;
3663 cursor_to_hook
= XTcursor_to
;
3664 reassert_line_highlight_hook
= XTreassert_line_highlight
;
3665 mouse_tracking_enable_hook
= XTmouse_tracking_enable
;
3667 scroll_region_ok
= 1; /* we'll scroll partial screens */
3668 char_ins_del_ok
= 0; /* just as fast to write the line */
3669 line_ins_del_ok
= 1; /* we'll just blt 'em */
3670 fast_clear_end_of_line
= 1; /* X does this well */
3671 memory_below_screen
= 0; /* we don't remember what scrolls
3675 init_input_symbols ();
3677 XHandleError (x_error_handler
);
3678 XHandleIOError (x_error_handler
);
3680 /* Disable Window Change signals; they are handled by X events. */
3682 signal (SIGWINCH
, SIG_DFL
);
3683 #endif /* SIGWINCH */
3685 signal (SIGPIPE
, x_error_handler
);
3687 #endif /* HAVE_X11 */
3688 #endif /* HAVE_X_WINDOWS */