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. */
42 /* Load sys/types.h if not already loaded.
43 In some systems loading it twice is suicidal. */
45 #include <sys/types.h>
50 #include <sys/ioctl.h>
52 #else /* ! defined (BSD) */
53 #include <sys/termio.h>
55 #endif /* ! defined (BSD) */
57 /* Allow m- file to inhibit use of FIONREAD. */
58 #ifdef BROKEN_FIONREAD
60 #endif /* ! defined (BROKEN_FIONREAD) */
62 /* We are unable to use interrupts if FIONREAD is not available,
63 so flush SIGIO so we won't try. */
67 #endif /* ! defined (SIGIO) */
78 #include <sys/param.h>
80 #include "dispextern.h"
81 #include "termhooks.h"
94 #define XMapWindow XMapRaised /* Raise them when mapping. */
95 #else /* ! defined (HAVE_X11) */
96 #include <X/Xkeyboard.h>
97 /*#include <X/Xproto.h> */
98 #endif /* ! defined (HAVE_X11) */
100 /* For sending Meta-characters. Do we need this? */
103 #define min(a,b) ((a)<(b) ? (a) : (b))
104 #define max(a,b) ((a)>(b) ? (a) : (b))
106 /* Nonzero means we must reprint all windows
107 because 1) we received an ExposeWindow event
108 or 2) we received too many ExposeRegion events to record. */
110 static int expose_all_windows
;
112 /* Nonzero means we must reprint all icon windows. */
114 static int expose_all_icons
;
117 /* ExposeRegion events, when received, are copied into this queue
118 for later processing. */
120 static struct event_queue x_expose_queue
;
122 /* ButtonPressed and ButtonReleased events, when received,
123 are copied into this queue for later processing. */
125 struct event_queue x_mouse_queue
;
126 #endif /* HAVE_X11 */
128 /* Nonzero after BLOCK_INPUT; prevents input events from being
129 processed until later. */
133 #if defined (SIGIO) && defined (FIONREAD)
134 int BLOCK_INPUT_mask
;
135 #endif /* ! defined (SIGIO) && defined (FIONREAD) */
137 /* Nonzero if input events came in while x_input_blocked was nonzero.
138 UNBLOCK_INPUT checks for this. */
142 /* The id of a bitmap used for icon windows.
143 One such map is shared by all Emacs icon windows.
144 This is zero if we have not yet had a need to create the bitmap. */
146 static Bitmap icon_bitmap
;
148 /* Font used for text icons. */
150 static FONT_TYPE
*icon_font_info
;
152 /* Stuff for dealing with the main icon title. */
154 extern Lisp_Object Vcommand_line_args
;
155 char *hostname
, *x_id_name
;
156 Lisp_Object invocation_name
;
158 /* This is the X connection that we are using. */
160 Display
*x_current_display
;
162 /* Frame being updated by update_frame. */
163 /* This is set by XTupdate_begin and looked at by all the
164 XT functions. It is zero while not inside an update.
165 In that case, the XT functions assume that `selected_frame'
166 is the frame to apply to. */
168 static struct frame
*updating_frame
;
170 /* The frame (if any) which has the X window that has keyboard focus.
171 Zero if none. This is examined by Ffocus_frame in frame.c. */
172 struct frame
*x_focus_frame
;
174 /* The frame which currently has the visual highlight, and should get
175 keyboard input (other sorts of input have the frame encoded in the
176 event). It points to the X focus frame's selected window's
177 frame. It differs from x_focus_frame when we're using a global
179 static struct frame
*x_highlight_frame
;
181 /* From .Xdefaults, the value of "emacs.WarpMouse". If non-zero,
182 mouse is moved to inside of frame when frame is de-iconified. */
184 static int warp_mouse_on_deiconify
;
186 /* During an update, maximum vpos for ins/del line operations to affect. */
188 static int flexlines
;
190 /* During an update, nonzero if chars output now should be highlighted. */
192 static int highlight
;
194 /* Nominal cursor position -- where to draw output.
195 During an update, these are different from the cursor-box position. */
201 /* `t' if a mouse button is depressed. */
203 extern Lisp_Object Vmouse_depressed
;
205 /* Tells if a window manager is present or not. */
207 extern Lisp_Object Vx_no_window_manager
;
209 /* Timestamp that we requested selection data was made. */
210 extern Time requestor_time
;
212 /* ID of the window requesting selection data. */
213 extern Window requestor_window
;
215 /* Nonzero enables some debugging for the X interface code. */
218 #else /* ! defined (HAVE_X11) */
220 /* Bit patterns for the mouse cursor. */
222 short MouseCursor
[] = {
223 0x0000, 0x0008, 0x0018, 0x0038,
224 0x0078, 0x00f8, 0x01f8, 0x03f8,
225 0x07f8, 0x00f8, 0x00d8, 0x0188,
226 0x0180, 0x0300, 0x0300, 0x0000};
228 short MouseMask
[] = {
229 0x000c, 0x001c, 0x003c, 0x007c,
230 0x00fc, 0x01fc, 0x03fc, 0x07fc,
231 0x0ffc, 0x0ffc, 0x01fc, 0x03dc,
232 0x03cc, 0x0780, 0x0780, 0x0300};
234 static short grey_bits
[] = {
235 0x0005, 0x000a, 0x0005, 0x000a};
237 static Pixmap GreyPixmap
= 0;
238 #endif /* ! defined (HAVE_X11) */
240 /* From time to time we get info on an Emacs window, here. */
242 static WINDOWINFO_TYPE windowinfo
;
246 extern Display
*XOpenDisplay ();
247 extern Window
XCreateWindow ();
249 extern Cursor
XCreateCursor ();
250 extern FONT_TYPE
*XOpenFont ();
252 static void flashback ();
255 static void dumpqueue ();
256 #endif /* HAVE_X11 */
259 static int XTcursor_to ();
260 static int XTclear_end_of_line ();
263 /* These hooks are called by update_frame at the beginning and end
264 of a frame update. We record in `updating_frame' the identity
265 of the frame being updated, so that the XT... functions do not
266 need to take a frame as argument. Most of the XT... functions
267 should never be called except during an update, the only exceptions
268 being XTcursor_to, XTwrite_char and XTreassert_line_highlight. */
270 extern int mouse_track_top
, mouse_track_left
, mouse_track_width
;
282 flexlines
= f
->height
;
288 #endif /* HAVE_X11 */
292 static void x_do_pending_expose ();
300 if (updating_frame
== 0
301 || updating_frame
!= f
)
307 #endif /* HAVE_X11 */
308 adjust_scrollbars (f
);
309 x_do_pending_expose ();
311 x_display_cursor (f
, 1);
318 /* External interface to control of standout mode.
319 Call this when about to modify line at position VPOS
320 and not change whether it is highlighted. */
322 XTreassert_line_highlight (new, vpos
)
328 /* Call this when about to modify line at position VPOS
329 and change whether it is highlighted. */
332 XTchange_line_highlight (new_highlight
, vpos
, first_unused_hpos
)
333 int new_highlight
, vpos
, first_unused_hpos
;
335 highlight
= new_highlight
;
336 XTcursor_to (vpos
, 0);
337 XTclear_end_of_line (updating_frame
->width
);
340 /* This is used when starting Emacs and when restarting after suspend.
341 When starting Emacs, no X window is mapped. And nothing must be done
342 to Emacs's own window if it is suspended (though that rarely happens). */
345 XTset_terminal_modes ()
349 /* This is called when exiting or suspending Emacs.
350 Exiting will make the X-windows go away, and suspending
351 requires no action. */
354 XTreset_terminal_modes ()
356 /* XTclear_frame (); */
359 /* Set the nominal cursor position of the frame:
360 where display update commands will take effect.
361 This does not affect the place where the cursor-box is displayed. */
364 XTcursor_to (row
, col
)
365 register int row
, col
;
373 if (updating_frame
== 0)
376 x_display_cursor (selected_frame
, 1);
382 /* Display a sequence of N glyphs found at GP.
383 WINDOW is the x-window to output to. LEFT and TOP are starting coords.
384 HL is 1 if this text is highlighted, 2 if the cursor is on it.
386 FONT is the default font to use (for glyphs whose font-code is 0). */
389 dumpglyphs (f
, left
, top
, gp
, n
, hl
, font
)
392 register GLYPH
*gp
; /* Points to first GLYPH. */
393 register int n
; /* Number of glyphs to display. */
398 Window window
= FRAME_X_WINDOW (f
);
399 GC drawing_gc
= (hl
== 2 ? f
->display
.x
->cursor_gc
400 : (hl
? f
->display
.x
->reverse_gc
401 : f
->display
.x
->normal_gc
));
403 if (sizeof (GLYPH
) == sizeof (XChar2b
))
404 XDrawImageString16 (x_current_display
, window
, drawing_gc
,
405 left
, top
+ FONT_BASE (font
), (XChar2b
*) gp
, n
);
406 else if (sizeof (GLYPH
) == sizeof (unsigned char))
407 XDrawImageString (x_current_display
, window
, drawing_gc
,
408 left
, top
+ FONT_BASE (font
), (char *) gp
, n
);
410 /* What size of glyph ARE you using? And does X have a function to
417 dumpglyphs (f
, left
, top
, gp
, n
, hl
, font
)
420 register GLYPH
*gp
; /* Points to first GLYPH. */
421 register int n
; /* Number of glyphs to display. */
425 char buf
[f
->width
]; /* Holds characters to be displayed. */
426 register char *cp
; /* Steps through buf[]. */
427 register int tlen
= GLYPH_TABLE_LENGTH
;
428 register Lisp_Object
*tbase
= GLYPH_TABLE_BASE
;
429 Window window
= FRAME_X_WINDOW (f
);
430 int cursor_pixel
= f
->display
.x
->cursor_pixel
;
431 int fg_pixel
= f
->display
.x
->foreground_pixel
;
432 int bg_pixel
= f
->display
.x
->background_pixel
;
433 int intborder
= f
->display
.x
->internal_border_width
;
437 /* Get the face-code of the next GLYPH. */
441 while (GLYPH_ALIAS_P (tbase
, tlen
, g
))
442 g
= GLYPH_ALIAS (tbase
, g
);
446 /* Find the run of consecutive glyphs with the same face-code.
447 Extract their character codes into BUF. */
452 while (GLYPH_ALIAS_P (tbase
, tlen
, g
))
453 g
= GLYPH_ALIAS (tbase
, g
);
462 /* LEN gets the length of the run. */
465 /* Now output this run of chars, with the font and pixel values
466 determined by the face code CF. */
470 GC GC_cursor
= f
->display
.x
->cursor_gc
;
471 GC GC_reverse
= f
->display
.x
->reverse_gc
;
472 GC GC_normal
= f
->display
.x
->normal_gc
;
474 XDrawImageString (x_current_display
, window
,
477 : (hl
? GC_reverse
: GC_normal
)),
478 left
, top
+ FONT_BASE (font
), buf
, len
);
479 #else /* ! defined (HAVE_X11) */
480 XText (window
, left
, top
,
485 ? (cursor_pixel
== fg_pixel
? bg_pixel
: fg_pixel
)
486 : hl
? bg_pixel
: fg_pixel
),
487 (hl
== 2 ? cursor_pixel
488 : hl
? fg_pixel
: bg_pixel
));
489 #endif /* ! defined (HAVE_X11) */
494 if (FACE_IS_FONT (cf
))
495 XDrawImageString (x_current_display
, FRAME_X_WINDOW (f
),
497 left
, top
+ FONT_BASE (FACE_FONT (cf
)),
499 else if (FACE_IS_IMAGE (cf
))
500 XCopyPlane (x_current_display
, FACE_IMAGE (cf
),
502 f
->display
.x
->normal_gc
,
504 FACE_IMAGE_WIDTH (cf
),
505 FACE_IMAGE_HEIGHT (cf
), left
, top
);
508 #else /* ! defined (HAVE_X11) */
509 register struct face
*fp
= x_face_table
[cf
];
511 XText (window
, left
, top
,
516 ? (cursor_pixel
== fp
->fg
? fp
->bg
: fp
->fg
)
517 : hl
? fp
->bg
: fp
->fg
),
518 (hl
== 2 ? cursor_pixel
519 : hl
? fp
->fg
: fp
->bg
));
520 #endif /* ! defined (HAVE_X11) */
522 left
+= len
* FONT_WIDTH (font
);
527 /* Output some text at the nominal frame cursor position,
528 advancing the cursor over the text.
529 Output LEN glyphs at START.
531 `highlight', set up by XTreassert_line_highlight or XTchange_line_highlight,
532 controls the pixel values used for foreground and background. */
535 XTwrite_glyphs (start
, len
)
536 register GLYPH
*start
;
539 register int temp_length
;
549 /* If not within an update,
550 output at the frame's visible cursor. */
551 curs_x
= f
->cursor_x
;
552 curs_y
= f
->cursor_y
;
556 (curs_x
* FONT_WIDTH (f
->display
.x
->font
)
557 + f
->display
.x
->internal_border_width
),
558 (curs_y
* FONT_HEIGHT (f
->display
.x
->font
)
559 + f
->display
.x
->internal_border_width
),
560 start
, len
, highlight
, f
->display
.x
->font
);
562 /* If we drew on top of the cursor, note that it is turned off. */
563 if (curs_y
== f
->phys_cursor_y
564 && curs_x
<= f
->phys_cursor_x
565 && curs_x
+ len
> f
->phys_cursor_x
)
566 f
->phys_cursor_x
= -1;
568 if (updating_frame
== 0)
571 x_display_cursor (f
, 1);
580 /* Erase the current text line from the nominal cursor position (inclusive)
581 to column FIRST_UNUSED (exclusive). The idea is that everything
582 from FIRST_UNUSED onward is already erased. */
585 XTclear_end_of_line (first_unused
)
586 register int first_unused
;
588 struct frame
*f
= updating_frame
;
594 if (curs_y
< 0 || curs_y
>= f
->height
)
596 if (first_unused
<= 0)
599 if (first_unused
>= f
->width
)
600 first_unused
= f
->width
;
604 /* Notice if the cursor will be cleared by this operation. */
605 if (curs_y
== f
->phys_cursor_y
606 && curs_x
<= f
->phys_cursor_x
607 && f
->phys_cursor_x
< first_unused
)
608 f
->phys_cursor_x
= -1;
611 XClearArea (x_current_display
, FRAME_X_WINDOW (f
),
612 curs_x
* FONT_WIDTH (f
->display
.x
->font
)
613 + f
->display
.x
->internal_border_width
,
614 curs_y
* FONT_HEIGHT (f
->display
.x
->font
)
615 + f
->display
.x
->internal_border_width
,
616 FONT_WIDTH (f
->display
.x
->font
) * (first_unused
- curs_x
),
617 FONT_HEIGHT (f
->display
.x
->font
), False
);
619 #else /* ! defined (HAVE_X11) */
620 XPixSet (FRAME_X_WINDOW (f
),
621 curs_x
* FONT_WIDTH (f
->display
.x
->font
) + f
->display
.x
->internal_border_width
,
622 curs_y
* FONT_HEIGHT (f
->display
.x
->font
) + f
->display
.x
->internal_border_width
,
623 FONT_WIDTH (f
->display
.x
->font
) * (first_unused
- curs_x
),
624 FONT_HEIGHT (f
->display
.x
->font
),
625 f
->display
.x
->background_pixel
);
626 #endif /* ! defined (HAVE_X11) */
635 struct frame
*f
= updating_frame
;
640 f
->phys_cursor_x
= -1; /* Cursor not visible. */
641 curs_x
= 0; /* Nominal cursor position is top left. */
645 XClear (FRAME_X_WINDOW (f
));
648 #endif /* HAVE_X11 */
653 /* Paint horzontal bars down the frame for a visible bell.
654 Note that this may be way too slow on some machines. */
659 register struct frame_glyphs
*active_frame
= FRAME_CURRENT_GLYPHS (f
);
663 if (updating_frame
!= 0)
669 for (i
= f
->height
* FONT_HEIGHT (f
->display
.x
->font
) - 10;
671 i
-= 100) /* Should be NO LOWER than 75 for speed reasons. */
672 XFillRectangle (x_current_display
, FRAME_X_WINDOW (f
),
673 f
->display
.x
->cursor_gc
,
674 0, i
, f
->width
* FONT_WIDTH (f
->display
.x
->font
)
675 + 2 * f
->display
.x
->internal_border_width
, 25);
678 x
= (f
->width
* FONT_WIDTH (f
->display
.x
->font
)) / 4;
679 y
= (f
->height
* FONT_HEIGHT (f
->display
.x
->font
)) / 4;
680 XFillRectangle (x_current_display
, FRAME_X_WINDOW (f
),
681 f
->display
.x
->cursor_gc
,
683 dumpglyphs (f
, (x
+ f
->display
.x
->internal_border_width
),
684 (y
+ f
->display
.x
->internal_border_width
),
685 &active_frame
->glyphs
[(f
->height
/ 4) + 1][(f
->width
/ 4)],
686 1, 0, f
->display
.x
->font
);
688 #else /* ! defined (HAVE_X11) */
689 for (i
= f
->height
* FONT_HEIGHT (f
->display
.x
->font
) - 10;
692 XPixFill (FRAME_X_WINDOW (f
), 0, i
,
693 f
->width
* FONT_WIDTH (f
->display
.x
->font
)
694 + 2 * f
->display
.x
->internal_border_width
, 10,
695 WHITE_PIX_DEFAULT
, ClipModeClipped
, GXinvert
, AllPlanes
);
696 #endif /* ! defined (HAVE_X11) */
702 /* Flip background and forground colors of the frame. */
709 unsigned long pix_temp
;
711 x_display_cursor (f
, 0);
712 XClearWindow (x_current_display
, FRAME_X_WINDOW (f
));
713 temp
= f
->display
.x
->normal_gc
;
714 f
->display
.x
->normal_gc
= f
->display
.x
->reverse_gc
;
715 f
->display
.x
->reverse_gc
= temp
;
716 pix_temp
= f
->display
.x
->foreground_pixel
;
717 f
->display
.x
->foreground_pixel
= f
->display
.x
->background_pixel
;
718 f
->display
.x
->background_pixel
= pix_temp
;
720 XSetWindowBackground (x_current_display
, FRAME_X_WINDOW (f
),
721 f
->display
.x
->background_pixel
);
722 if (f
->display
.x
->background_pixel
== f
->display
.x
->cursor_pixel
)
724 f
->display
.x
->cursor_pixel
= f
->display
.x
->foreground_pixel
;
725 XSetBackground (x_current_display
, f
->display
.x
->cursor_gc
,
726 f
->display
.x
->cursor_pixel
);
727 XSetForeground (x_current_display
, f
->display
.x
->cursor_gc
,
728 f
->display
.x
->background_pixel
);
731 #endif /* ! defined (HAVE_X11) */
734 /* Make audible bell. */
737 #define XRINGBELL XBell(x_current_display, 0)
738 #else /* ! defined (HAVE_X11) */
739 #define XRINGBELL XFeep(0);
740 #endif /* ! defined (HAVE_X11) */
746 XTflash (selected_frame
);
749 x_invert_frame (selected_frame
);
750 x_invert_frame (selected_frame
);
761 /* Insert and delete character are not supposed to be used
762 because we are supposed to turn off the feature of using them. */
765 XTinsert_glyphs (start
, len
)
766 register char *start
;
779 /* Specify how many text lines, from the top of the window,
780 should be affected by insert-lines and delete-lines operations.
781 This, and those operations, are used only within an update
782 that is bounded by calls to XTupdate_begin and XTupdate_end. */
785 XTset_terminal_window (n
)
788 if (updating_frame
== 0)
791 if ((n
<= 0) || (n
> updating_frame
->height
))
792 flexlines
= updating_frame
->height
;
797 /* Perform an insert-lines operation, inserting N lines
798 at a vertical position curs_y. */
804 register int topregion
, bottomregion
;
805 register int length
, newtop
, mask
;
806 register struct frame
*f
= updating_frame
;
807 int intborder
= f
->display
.x
->internal_border_width
;
809 if (curs_y
>= flexlines
)
813 bottomregion
= flexlines
- (n
+ 1);
814 newtop
= topregion
+ n
;
815 length
= (bottomregion
- topregion
) + 1;
819 #endif /* HAVE_X11 */
821 if ((length
> 0) && (newtop
<= flexlines
))
824 XCopyArea (x_current_display
, FRAME_X_WINDOW (f
),
825 FRAME_X_WINDOW (f
), f
->display
.x
->normal_gc
,
826 intborder
, topregion
* FONT_HEIGHT (f
->display
.x
->font
) + intborder
,
827 f
->width
* FONT_WIDTH (f
->display
.x
->font
),
828 length
* FONT_HEIGHT (f
->display
.x
->font
), intborder
,
829 newtop
* FONT_HEIGHT (f
->display
.x
->font
) + intborder
);
830 #else /* ! defined (HAVE_X11) */
831 XMoveArea (FRAME_X_WINDOW (f
),
832 intborder
, topregion
* FONT_HEIGHT (f
->display
.x
->font
) + intborder
,
833 intborder
, newtop
* FONT_HEIGHT (f
->display
.x
->font
) + intborder
,
834 f
->width
* FONT_WIDTH (f
->display
.x
->font
),
835 length
* FONT_HEIGHT (f
->display
.x
->font
));
836 /* Now we must process any ExposeRegion events that occur
837 if the area being copied from is obscured.
838 We can't let it wait because further i/d operations
839 may want to copy this area to another area. */
841 #endif /* ! defined (HAVE_X11) */
844 newtop
= min (newtop
, (flexlines
- 1));
845 length
= newtop
- topregion
;
849 XClearArea (x_current_display
, FRAME_X_WINDOW (f
), intborder
,
850 topregion
* FONT_HEIGHT (f
->display
.x
->font
) + intborder
,
851 f
->width
* FONT_WIDTH (f
->display
.x
->font
),
852 n
* FONT_HEIGHT (f
->display
.x
->font
), False
);
853 #else /* ! defined (HAVE_X11) */
854 XPixSet (FRAME_X_WINDOW (f
),
856 topregion
* FONT_HEIGHT (f
->display
.x
->font
) + intborder
,
857 f
->width
* FONT_WIDTH (f
->display
.x
->font
),
858 n
* FONT_HEIGHT (f
->display
.x
->font
),
859 f
->display
.x
->background_pixel
);
860 #endif /* ! defined (HAVE_X11) */
864 /* Perform a delete-lines operation, deleting N lines
865 at a vertical position curs_y. */
872 register struct frame
*f
= updating_frame
;
873 int intborder
= f
->display
.x
->internal_border_width
;
875 if (curs_y
>= flexlines
)
880 #endif /* HAVE_X11 */
882 if ((curs_y
+ n
) >= flexlines
)
884 if (flexlines
>= (curs_y
+ 1))
887 XClearArea (x_current_display
, FRAME_X_WINDOW (f
), intborder
,
888 curs_y
* FONT_HEIGHT (f
->display
.x
->font
) + intborder
,
889 f
->width
* FONT_WIDTH (f
->display
.x
->font
),
890 (flexlines
- curs_y
) * FONT_HEIGHT (f
->display
.x
->font
), False
);
891 #else /* ! defined (HAVE_X11) */
892 XPixSet (FRAME_X_WINDOW (f
),
893 intborder
, curs_y
* FONT_HEIGHT (f
->display
.x
->font
) + intborder
,
894 f
->width
* FONT_WIDTH (f
->display
.x
->font
),
895 (flexlines
- curs_y
) * FONT_HEIGHT (f
->display
.x
->font
),
896 f
->display
.x
->background_pixel
);
897 #endif /* ! defined (HAVE_X11) */
903 XCopyArea (x_current_display
, FRAME_X_WINDOW (f
),
904 FRAME_X_WINDOW (f
), f
->display
.x
->normal_gc
,
906 (curs_y
+ n
) * FONT_HEIGHT (f
->display
.x
->font
) + intborder
,
907 f
->width
* FONT_WIDTH (f
->display
.x
->font
),
908 (flexlines
- (curs_y
+ n
)) * FONT_HEIGHT (f
->display
.x
->font
),
909 intborder
, curs_y
* FONT_HEIGHT (f
->display
.x
->font
) + intborder
);
910 XClearArea (x_current_display
, FRAME_X_WINDOW (f
),
912 (flexlines
- n
) * FONT_HEIGHT (f
->display
.x
->font
) + intborder
,
913 f
->width
* FONT_WIDTH (f
->display
.x
->font
),
914 n
* FONT_HEIGHT (f
->display
.x
->font
), False
);
915 #else /* ! defined (HAVE_X11) */
916 XMoveArea (FRAME_X_WINDOW (f
),
918 (curs_y
+ n
) * FONT_HEIGHT (f
->display
.x
->font
) + intborder
,
919 intborder
, curs_y
* FONT_HEIGHT (f
->display
.x
->font
) + intborder
,
920 f
->width
* FONT_WIDTH (f
->display
.x
->font
),
921 (flexlines
- (curs_y
+ n
)) * FONT_HEIGHT (f
->display
.x
->font
));
922 /* Now we must process any ExposeRegion events that occur
923 if the area being copied from is obscured.
924 We can't let it wait because further i/d operations
925 may want to copy this area to another area. */
927 XPixSet (FRAME_X_WINDOW (f
), intborder
,
928 (flexlines
- n
) * FONT_HEIGHT (f
->display
.x
->font
) + intborder
,
929 f
->width
* FONT_WIDTH (f
->display
.x
->font
),
930 n
* FONT_HEIGHT (f
->display
.x
->font
), f
->display
.x
->background_pixel
);
931 #endif /* ! defined (HAVE_X11) */
935 /* Perform an insert-lines or delete-lines operation,
936 inserting N lines or deleting -N lines at vertical position VPOS. */
938 XTins_del_lines (vpos
, n
)
941 if (updating_frame
== 0)
944 /* Hide the cursor. */
945 x_display_cursor (updating_frame
, 0);
947 XTcursor_to (vpos
, 0);
958 static void clear_cursor ();
960 /* Output into a rectangle of an X-window (for frame F)
961 the characters in f->phys_lines that overlap that rectangle.
962 TOP and LEFT are the position of the upper left corner of the rectangle.
963 ROWS and COLS are the size of the rectangle. */
966 dumprectangle (f
, left
, top
, cols
, rows
)
968 register int left
, top
, cols
, rows
;
970 register struct frame_glyphs
*active_frame
= FRAME_CURRENT_GLYPHS (f
);
971 int cursor_cleared
= 0;
975 if (FRAME_GARBAGED_P (f
))
978 top
-= f
->display
.x
->internal_border_width
;
979 left
-= f
->display
.x
->internal_border_width
;
981 /* Express rectangle as four edges, instead of position-and-size. */
985 #ifndef HAVE_X11 /* Window manger does this for X11. */
986 /* If the rectangle includes any of the internal border area,
987 redisplay the border emphasis. */
988 if (top
< 0 || left
< 0
989 || bottom
> f
->height
* FONT_HEIGHT (f
->display
.x
->font
)
990 || right
> f
->width
* FONT_WIDTH (f
->display
.x
->font
))
992 #endif /* HAVE_X11 /* Window manger does this for X11. */ */
994 /* Convert rectangle edges in pixels to edges in chars.
995 Round down for left and top, up for right and bottom. */
996 top
/= FONT_HEIGHT (f
->display
.x
->font
);
997 left
/= FONT_WIDTH (f
->display
.x
->font
);
998 bottom
+= (FONT_HEIGHT (f
->display
.x
->font
) - 1);
999 right
+= (FONT_WIDTH (f
->display
.x
->font
) - 1);
1000 bottom
/= FONT_HEIGHT (f
->display
.x
->font
);
1001 right
/= FONT_WIDTH (f
->display
.x
->font
);
1003 /* Clip the rectangle to what can be visible. */
1008 if (right
> f
->width
)
1010 if (bottom
> f
->height
)
1013 /* Get size in chars of the rectangle. */
1014 cols
= right
- left
;
1015 rows
= bottom
- top
;
1017 /* If rectangle has zero area, return. */
1018 if (rows
<= 0) return;
1019 if (cols
<= 0) return;
1021 /* Turn off the cursor if it is in the rectangle.
1022 We will turn it back on afterward. */
1023 if ((f
->phys_cursor_x
>= left
) && (f
->phys_cursor_x
< right
)
1024 && (f
->phys_cursor_y
>= top
) && (f
->phys_cursor_y
< bottom
))
1030 /* Display the text in the rectangle, one text line at a time. */
1032 for (y
= top
; y
< bottom
; y
++)
1034 GLYPH
*line
= &active_frame
->glyphs
[y
][left
];
1036 if (! active_frame
->enable
[y
] || left
> active_frame
->used
[y
])
1040 (left
* FONT_WIDTH (f
->display
.x
->font
)
1041 + f
->display
.x
->internal_border_width
),
1042 (y
* FONT_HEIGHT (f
->display
.x
->font
)
1043 + f
->display
.x
->internal_border_width
),
1044 line
, min (cols
, active_frame
->used
[y
] - left
),
1045 active_frame
->highlight
[y
], f
->display
.x
->font
);
1048 /* Turn the cursor on if we turned it off. */
1051 x_display_cursor (f
, 1);
1055 /* Process all queued ExposeRegion events. */
1061 XExposeRegionEvent r
;
1063 while (dequeue_event (&r
, &x_expose_queue
))
1065 struct frame
*f
= x_window_to_frame (r
.window
);
1066 if (f
->display
.x
->icon_desc
== r
.window
)
1069 dumprectangle (f
, r
.x
, r
.y
, r
.width
, r
.height
);
1073 #endif /* HAVE_X11 */
1075 /* Process all expose events that are pending.
1076 Redraws the cursor if necessary on any frame that
1077 is not in the process of being updated with update_frame. */
1080 x_do_pending_expose ()
1084 Lisp_Object tail
, frame
;
1086 if (expose_all_windows
)
1088 expose_all_windows
= 0;
1089 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1091 register int temp_width
, temp_height
;
1094 frame
= XCONS (tail
)->car
;
1095 if (XTYPE (frame
) != Lisp_Frame
)
1098 if (! FRAME_X_P (f
))
1102 if (!f
->display
.x
->needs_exposure
)
1105 intborder
= f
->display
.x
->internal_border_width
;
1108 XGetWindowInfo (FRAME_X_WINDOW (f
), &windowinfo
);
1109 temp_width
= ((windowinfo
.width
- 2 * intborder
1110 - f
->display
.x
->v_scrollbar_width
)
1111 / FONT_WIDTH (f
->display
.x
->font
));
1112 temp_height
= ((windowinfo
.height
- 2 * intborder
1113 - f
->display
.x
->h_scrollbar_height
)
1114 / FONT_HEIGHT (f
->display
.x
->font
));
1115 if (temp_width
!= f
->width
|| temp_height
!= f
->height
)
1117 change_frame_size (f
, max (1, temp_height
),
1118 max (1, temp_width
), 0, 1);
1119 x_resize_scrollbars (f
);
1121 f
->display
.x
->left_pos
= windowinfo
.x
;
1122 f
->display
.x
->top_pos
= windowinfo
.y
;
1123 dumprectangle (f
, 0, 0, PIXEL_WIDTH (f
), PIXEL_HEIGHT (f
));
1127 f
->display
.x
->needs_exposure
= 0;
1128 if (updating_frame
!= f
)
1129 x_display_cursor (f
, 1);
1134 /* Handle any individual-rectangle expose events queued
1135 for various windows. */
1138 #else /* ! defined (HAVE_X11) */
1140 #endif /* ! defined (HAVE_X11) */
1145 frame_highlight (frame
)
1146 struct frame
*frame
;
1148 if (! EQ (Vx_no_window_manager
, Qnil
))
1149 XSetWindowBorder (x_current_display
, FRAME_X_WINDOW (frame
),
1150 frame
->display
.x
->border_pixel
);
1151 x_display_cursor (frame
, 1);
1155 frame_unhighlight (frame
)
1156 struct frame
*frame
;
1158 if (! EQ (Vx_no_window_manager
, Qnil
))
1159 XSetWindowBorderPixmap (x_current_display
, FRAME_X_WINDOW (frame
),
1160 frame
->display
.x
->border_tile
);
1161 x_display_cursor (frame
, 1);
1163 #else /* ! defined (HAVE_X11) */
1164 /* Dump the border-emphasis of frame F.
1165 If F is selected, this is a lining of the same color as the border,
1166 just within the border, occupying a portion of the internal border.
1167 If F is not selected, it is background in the same place.
1168 If ALWAYS is 0, don't bother explicitly drawing if it's background.
1170 ALWAYS = 1 is used when a frame becomes selected or deselected.
1171 In that case, we also turn the cursor off and on again
1172 so it will appear in the proper shape (solid if selected; else hollow.) */
1175 dumpborder (f
, always
)
1179 int thickness
= f
->display
.x
->internal_border_width
/ 2;
1180 int width
= PIXEL_WIDTH (f
);
1181 int height
= PIXEL_HEIGHT (f
);
1184 if (f
!= selected_frame
)
1189 pixel
= f
->display
.x
->background_pixel
;
1193 pixel
= f
->display
.x
->border_pixel
;
1196 XPixSet (FRAME_X_WINDOW (f
), 0, 0, width
, thickness
, pixel
);
1197 XPixSet (FRAME_X_WINDOW (f
), 0, 0, thickness
, height
, pixel
);
1198 XPixSet (FRAME_X_WINDOW (f
), 0, height
- thickness
, width
,
1200 XPixSet (FRAME_X_WINDOW (f
), width
- thickness
, 0, thickness
,
1204 x_display_cursor (f
, 1);
1206 #endif /* ! defined (HAVE_X11) */
1208 static void XTframe_rehighlight ();
1210 /* The focus has changed. Update the frames as necessary to reflect
1211 the new situation. Note that we can't change the selected frame
1212 here, because the lisp code we are interrupting might become confused.
1213 Each event gets marked with the frame in which it occured, so the
1214 lisp code can tell when the switch took place by examining the events. */
1217 x_new_focus_frame (frame
)
1218 struct frame
*frame
;
1220 struct frame
*old_focus
= x_focus_frame
;
1221 int events_enqueued
= 0;
1223 if (frame
!= x_focus_frame
)
1225 /* Set this before calling other routines, so that they see
1226 the correct value of x_focus_frame. */
1227 x_focus_frame
= frame
;
1229 if (old_focus
&& old_focus
->auto_lower
)
1230 x_lower_frame (old_focus
);
1233 selected_frame
= frame
;
1234 XSET (XWINDOW (selected_frame
->selected_window
)->frame
,
1235 Lisp_Frame
, selected_frame
);
1236 Fselect_window (selected_frame
->selected_window
);
1237 choose_minibuf_frame ();
1240 if (x_focus_frame
&& x_focus_frame
->auto_raise
)
1241 x_raise_frame (x_focus_frame
);
1244 XTframe_rehighlight ();
1248 /* The focus has changed, or we have make a frame's selected window
1249 point to a window on a different frame (this happens with global
1250 minibuffer frames). Shift the highlight as appropriate. */
1252 XTframe_rehighlight ()
1254 struct frame
*old_highlight
= x_highlight_frame
;
1258 x_highlight_frame
= XFRAME (FRAME_FOCUS_FRAME (x_focus_frame
));
1259 if (x_highlight_frame
->display
.nothing
== 0)
1260 XSET (FRAME_FOCUS_FRAME (x_focus_frame
), Lisp_Frame
,
1261 (x_highlight_frame
= x_focus_frame
));
1264 x_highlight_frame
= 0;
1266 if (x_highlight_frame
!= old_highlight
)
1269 frame_unhighlight (old_highlight
);
1270 if (x_highlight_frame
)
1271 frame_highlight (x_highlight_frame
);
1282 /* Position of the mouse in characters */
1283 unsigned int x_mouse_x
, x_mouse_y
;
1285 /* Offset in buffer of character under the pointer, or 0. */
1286 extern int mouse_buffer_offset
;
1288 extern int buffer_posn_from_coords ();
1290 /* Symbols from xfns.c to denote the different parts of a window. */
1291 extern Lisp_Object Qmodeline_part
, Qtext_part
;
1294 /* Set *RESULT to an emacs input_event corresponding to MOTION_EVENT.
1295 F is the frame in which the event occurred.
1297 WINDOW_TYPE says whether the event happened in a scrollbar window
1298 or a text window, affecting the format of the event created.
1300 PART specifies which part of the scrollbar the event happened in,
1301 if WINDOW_TYPE == scrollbar_window.
1303 If the mouse is over the same character as the last time we checked,
1304 don't return an event; set result->kind to no_event. */
1307 notice_mouse_movement (result
, motion_event
, f
, window_type
, part
)
1308 struct input_event
*result
;
1309 XMotionEvent motion_event
;
1314 int x
, y
, root_x
, root_y
, pix_x
, pix_y
;
1315 unsigned int keys_and_buttons
;
1316 Window w
, root_window
;
1318 /* Unless we decide otherwise below, return a non-event. */
1319 result
->kind
= no_event
;
1321 if (XQueryPointer (x_current_display
,
1324 &root_x
, &root_y
, &pix_x
, &pix_y
,
1330 if (w
== None
) /* Mouse no longer in window. */
1334 pixel_to_glyph_translation (f
, pix_x
, pix_y
, &x
, &y
);
1335 if (x
== x_mouse_x
&& y
== x_mouse_y
)
1341 /* What sort of window are we in now? */
1342 if (window_type
== text_window
) /* Text part */
1346 Vmouse_window
= window_from_coordinates (f
, x
, y
, &modeline_p
);
1348 if (XTYPE (Vmouse_window
) == Lisp_Window
)
1350 = buffer_posn_from_coords (XWINDOW (Vmouse_window
), x
, y
);
1352 mouse_buffer_offset
= 0;
1354 if (EQ (Vmouse_window
, Qnil
))
1355 Vmouse_frame_part
= Qnil
;
1356 else if (modeline_p
)
1357 Vmouse_frame_part
= Qmodeline_part
;
1359 Vmouse_frame_part
= Qtext_part
;
1361 result
->kind
= window_sys_event
;
1362 result
->code
= Qmouse_moved
;
1366 else if (window_type
== scrollbar_window
) /* Scrollbar */
1368 Vmouse_window
= f
->selected_window
;
1369 mouse_buffer_offset
= 0;
1370 Vmouse_frame_part
= part
;
1372 result
->kind
= window_sys_event
;
1373 result
->code
= Qmouse_moved
;
1383 /* Mouse clicks and mouse movement. Rah. */
1386 /* Given a pixel position (PIX_X, PIX_Y) on the frame F, return
1387 glyph co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle
1388 that the glyph at X, Y occupies, if BOUNDS != 0. */
1390 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
)
1392 register unsigned int pix_x
, pix_y
;
1393 register int *x
, *y
;
1396 int ibw
= f
->display
.x
->internal_border_width
;
1398 FONT_TYPE
*font
= f
->display
.x
->font
;
1400 width
= FONT_WIDTH (font
);
1401 height
= FONT_HEIGHT (font
);
1403 /* What line is it on? */
1406 else if (pix_y
> f
->display
.x
->pixel_height
- ibw
)
1407 *y
= FRAME_HEIGHT (f
) - 1;
1409 *y
= (pix_y
- ibw
) / height
;
1411 /* And what column? */
1414 else if (pix_x
> f
->display
.x
->pixel_width
- ibw
)
1415 *x
= FRAME_WIDTH (f
) - 1;
1417 *x
= (pix_x
- ibw
) / width
;
1421 bounds
->width
= width
;
1422 bounds
->height
= height
;
1423 bounds
->x
= ibw
+ (*x
* width
);
1424 bounds
->y
= ibw
+ (*y
* height
);
1428 /* Any buttons grabbed. */
1429 unsigned int x_mouse_grabbed
;
1431 /* Convert a set of X modifier bits to the proper form for a
1432 struct input_event modifiers value. */
1435 x_convert_modifiers (state
)
1438 return ( ((state
& (ShiftMask
| LockMask
)) ? shift_modifier
: 0)
1439 | ((state
& ControlMask
) ? ctrl_modifier
: 0)
1440 | ((state
& Mod1Mask
) ? meta_modifier
: 0));
1443 extern struct frame
*x_window_to_scrollbar ();
1444 extern Lisp_Object Vmouse_event
;
1446 /* Prepare a mouse-event in *RESULT for placement in the input queue.
1448 If the event is a button press, then note that we have grabbed
1451 If PART and PREFIX are 0, then the event occurred in the text part;
1452 otherwise it happened in a scrollbar. */
1455 construct_mouse_click (result
, event
, f
, part
, prefix
)
1456 struct input_event
*result
;
1457 XButtonEvent
*event
;
1462 /* Initialize those fields text and scrollbar clicks hold in common.
1463 Make the event type no_event; we'll change that when we decide
1465 result
->kind
= no_event
;
1466 XSET (result
->code
, Lisp_Int
, event
->button
);
1467 result
->timestamp
= event
->time
;
1468 result
->modifiers
= (x_convert_modifiers (event
->state
)
1469 | (event
->type
== ButtonRelease
? up_modifier
: 0));
1471 /* Notice if the mouse is still grabbed. */
1472 if (event
->type
== ButtonPress
)
1474 if (! x_mouse_grabbed
)
1475 Vmouse_depressed
= Qt
;
1476 x_mouse_grabbed
|= (1 << event
->button
);
1478 else if (event
->type
== ButtonRelease
)
1480 x_mouse_grabbed
&= ~(1 << event
->button
);
1481 if (!x_mouse_grabbed
)
1482 Vmouse_depressed
= Qnil
;
1485 if (part
) /* Scrollbar event */
1489 pos
= event
->y
- (f
->display
.x
->v_scrollbar_width
- 2);
1490 XSET (x_mouse_x
, Lisp_Int
, pos
);
1491 len
= ((FONT_HEIGHT (f
->display
.x
->font
) * f
->height
)
1492 + f
->display
.x
->internal_border_width
1493 - (2 * (f
->display
.x
->v_scrollbar_width
- 2)));
1494 XSET (x_mouse_y
, Lisp_Int
, len
);
1496 result
->kind
= scrollbar_click
;
1497 result
->part
= part
;
1498 XSET (result
->x
, Lisp_Int
, (f
->display
.x
->top_pos
- event
->y
));
1499 XSET (result
->y
, Lisp_Int
, f
->display
.x
->pixel_height
);
1502 else /* Text Window Event */
1506 pixel_to_glyph_coords (f
, event
->x
, event
->y
, &column
, &row
, NULL
);
1507 result
->kind
= mouse_click
;
1515 /* Mouse movement. Rah.
1517 In order to avoid asking for motion events and then throwing most
1518 of them away or busy-polling the server for mouse positions, we ask
1519 the server for pointer motion hints. This means that we get only
1520 one event per group of mouse movements. "Groups" are delimited by
1521 other kinds of events (focus changes and button clicks, for
1522 example), or by XQueryPointer calls; when one of these happens, we
1523 get another MotionNotify event the next time the mouse moves. This
1524 is at least as efficient as getting motion events when mouse
1525 tracking is on, and I suspect only negligibly worse when tracking
1528 The silly O'Reilly & Associates Nutshell guides barely document
1529 pointer motion hints at all (I think you have to infer how they
1530 work from an example), and the description of XQueryPointer doesn't
1531 mention that calling it causes you to get another motion hint from
1532 the server, which is very important. */
1534 /* Where the mouse was last time we reported a mouse event. */
1535 static FRAME_PTR last_mouse_frame
;
1536 static XRectangle last_mouse_glyph
;
1538 /* This is a hack. We would really prefer that XTmouse_position would
1539 return the time associated with the position it returns, but there
1540 doesn't seem to be any way to wrest the timestamp from the server
1541 along with the position query. So, we just keep track of the time
1542 of the last movement we received, and return that in hopes that
1543 it's somewhat accurate. */
1544 static Time last_mouse_movement_time
;
1546 /* Function to report a mouse movement to the mainstream Emacs code.
1547 The input handler calls this.
1549 We have received a mouse movement event, which is given in *event.
1550 If the mouse is over a different glyph than it was last time, tell
1551 the mainstream emacs code by setting mouse_moved. If not, ask for
1552 another motion event, so we can check again the next time it moves. */
1554 note_mouse_position (frame
, event
)
1556 XMotionEvent
*event
;
1559 last_mouse_movement_time
= event
->time
;
1561 /* Has the mouse moved off the glyph it was on at the last sighting? */
1562 if (event
->x
< last_mouse_glyph
.x
1563 || event
->x
>= last_mouse_glyph
.x
+ last_mouse_glyph
.width
1564 || event
->y
< last_mouse_glyph
.y
1565 || event
->y
>= last_mouse_glyph
.y
+ last_mouse_glyph
.height
)
1569 /* It's on the same glyph. Call XQueryPointer so we'll get an
1570 event the next time the mouse moves and we can see if it's
1571 *still* on the same glyph. */
1574 XQueryPointer (event
->display
, event
->window
,
1575 (Window
*) &dummy
, (Window
*) &dummy
,
1576 &dummy
, &dummy
, &dummy
, &dummy
,
1577 (unsigned int *) &dummy
);
1581 /* Return the current position of the mouse.
1583 This clears the mouse_moved flag, so we can wait for the next mouse
1584 position. This also calls XQueryPointer, which will cause the
1585 server to give us another MotionNotify when the mouse moves again.
1589 XTmouse_position (f
, x
, y
, time
)
1592 unsigned long *time
;
1595 Display
*d
= x_current_display
;
1596 Window guess
, root
, child
;
1600 /* I would like to have an X function that just told me the
1601 innermost window containing the mouse.
1603 /* There doesn't seem to be any way to just get the innermost window
1604 containing the pointer, no matter what X frame it's on; you have
1605 to guess a window, and then X will tell you which one of that
1606 window's children it's in. If the pointer isn't in any of that
1607 window's children, it gives you a root window that contains it.
1609 So we start with the selected frame's window and chase down
1610 branches under the guidance of XQueryPointer until we hit a leaf
1611 (all of the Emacs windows we care about are leaf windows). If at
1612 any time XQueryPointer returns false, that means that the current
1613 window does not contain the pointer any more (perhaps it moved),
1614 so we start with the root window XQueryPointer has given us and
1617 guess
= FRAME_X_WINDOW (selected_frame
);
1619 if (XQueryPointer (d
, guess
, &root
, &child
,
1620 &dummy
, &dummy
, &ix
, &iy
, (unsigned int *) &dummy
))
1623 /* Guess is a leaf window, and it contains the pointer. */
1629 /* When XQueryPointer returns False, the pointer isn't in guess
1630 anymore, but root is the root window of the frame we should
1634 *f
= last_mouse_frame
= x_window_to_frame (guess
);
1639 pixel_to_glyph_coords (*f
, ix
, iy
, &ix
, &iy
, &last_mouse_glyph
);
1640 XSET (*x
, Lisp_Int
, ix
);
1641 XSET (*y
, Lisp_Int
, iy
);
1646 /* I don't know how to find the time for the last movement; it seems
1647 like XQueryPointer ought to return it, but it doesn't. So, we'll
1648 return the time of the last MotionNotify event we received. Note
1649 that the use of motion hints means that this isn't guaranteed to
1650 be accurate at all. */
1651 *time
= last_mouse_movement_time
;
1656 #else /* ! defined (HAVE_X11) */
1657 #define XEvent XKeyPressedEvent
1658 #endif /* ! defined (HAVE_X11) */
1661 /* Timestamp of enter window event. This is only used by XTread_socket,
1662 but we have to put it out here, since static variables within functions
1663 sometimes don't work. */
1664 static Time enter_timestamp
;
1666 /* Communication with window managers. */
1667 Atom Xatom_wm_protocols
;
1669 /* Kinds of protocol things we may receive. */
1670 Atom Xatom_wm_take_focus
;
1671 Atom Xatom_wm_save_yourself
;
1672 Atom Xatom_wm_delete_window
;
1674 /* Other WM communication */
1675 Atom Xatom_wm_configure_denied
; /* When our config request is denied */
1676 Atom Xatom_wm_window_moved
; /* When the WM moves us. */
1678 /* Read events coming from the X server.
1679 This routine is called by the SIGIO handler.
1680 We return as soon as there are no more events to be read.
1682 Events representing keys are stored in buffer BUFP,
1683 which can hold up to NUMCHARS characters.
1684 We return the number of characters stored into the buffer,
1685 thus pretending to be `read'.
1687 WAITP is nonzero if we should block until input arrives.
1688 EXPECTED is nonzero if the caller knows input is available. */
1691 XTread_socket (sd
, bufp
, numchars
, waitp
, expected
)
1693 register struct input_event
*bufp
;
1694 register int numchars
;
1701 int items_pending
; /* How many items are in the X queue. */
1708 if (x_input_blocked
)
1710 x_pending_input
= 1;
1714 x_pending_input
= 0;
1718 abort (); /* Don't think this happens. */
1721 /* If available, Xlib uses FIOSNBIO to make the socket
1722 non-blocking, and then looks for EWOULDBLOCK. If O_NDELAY is set,
1723 FIOSNBIO is ignored, and instead of signalling EWOULDBLOCK,
1724 a read returns 0, which Xlib interprets as equivalent to EPIPE. */
1725 fcntl (fileno (stdin
), F_SETFL
, 0);
1726 #endif /* ! defined (FIOSNBIO) */
1730 if (! (fcntl (fileno (stdin
), F_GETFL
, 0) & O_NDELAY
))
1732 extern int read_alarm_should_throw
;
1733 read_alarm_should_throw
= 1;
1734 XPeekEvent (XDISPLAY
&event
);
1735 read_alarm_should_throw
= 0;
1737 #endif /* HAVE_SELECT */
1740 while (XStuffPending () != 0)
1742 XNextEvent (XDISPLAY
&event
);
1750 if (event
.xclient
.message_type
== Xatom_wm_protocols
1751 && event
.xclient
.format
== 32)
1753 if (event
.xclient
.data
.l
[0] == Xatom_wm_take_focus
)
1755 f
= x_window_to_frame (event
.xclient
.window
);
1757 x_focus_on_frame (f
);
1758 /* Not certain about handling scrollbars here */
1760 else if (event
.xclient
.data
.l
[0] == Xatom_wm_save_yourself
)
1762 /* Save state modify the WM_COMMAND property to
1763 something which can reinstate us. This notifies
1764 the session manager, who's looking for such a
1765 PropertyNotify. Can restart processing when
1766 a keyboard or mouse event arrives. */
1771 else if (event
.xclient
.data
.l
[0] == Xatom_wm_delete_window
)
1773 struct frame
*f
= x_window_to_frame (event
.xclient
.window
);
1781 else if (event
.xclient
.message_type
== Xatom_wm_configure_denied
)
1784 else if (event
.xclient
.message_type
== Xatom_wm_window_moved
)
1788 new_x
= event
.xclient
.data
.s
[0];
1789 new_y
= event
.xclient
.data
.s
[1];
1794 case SelectionClear
: /* Someone has grabbed ownership. */
1795 x_disown_selection (event
.xselectionclear
.window
,
1796 event
.xselectionclear
.selection
,
1797 event
.xselectionclear
.time
);
1800 case SelectionRequest
: /* Someone wants our selection. */
1801 x_answer_selection_request (event
);
1804 case PropertyNotify
:
1805 /* If we were to do this synchronously, there'd be no worry
1806 about re-selecting. */
1807 x_send_incremental (event
);
1811 f
= x_window_to_frame (event
.xexpose
.window
);
1814 if (f
->visible
== 0)
1818 SET_FRAME_GARBAGED (f
);
1821 dumprectangle (x_window_to_frame (event
.xexpose
.window
),
1822 event
.xexpose
.x
, event
.xexpose
.y
,
1823 event
.xexpose
.width
, event
.xexpose
.height
);
1827 case GraphicsExpose
: /* This occurs when an XCopyArea's
1828 source area was obscured or not
1830 dumprectangle (x_window_to_frame (event
.xgraphicsexpose
.drawable
),
1831 event
.xgraphicsexpose
.x
, event
.xgraphicsexpose
.y
,
1832 event
.xgraphicsexpose
.width
,
1833 event
.xgraphicsexpose
.height
);
1836 case NoExpose
: /* This occurs when an XCopyArea's
1837 source area was completely
1840 #else /* ! defined (HAVE_X11) */
1842 if (event
.subwindow
!= 0)
1843 break; /* duplicate event */
1844 f
= x_window_to_frame (event
.window
);
1845 if (event
.window
== f
->display
.x
->icon_desc
)
1850 if (event
.window
== FRAME_X_WINDOW (f
))
1852 /* Say must check all windows' needs_exposure flags. */
1853 expose_all_windows
= 1;
1854 f
->display
.x
->needs_exposure
= 1;
1860 if (event
.subwindow
!= 0)
1861 break; /* duplicate event */
1862 f
= x_window_to_frame (event
.window
);
1863 if (event
.window
== f
->display
.x
->icon_desc
)
1868 /* If window already needs full redraw, ignore this rectangle. */
1869 if (expose_all_windows
&& f
->display
.x
->needs_exposure
)
1871 /* Put the event on the queue of rectangles to redraw. */
1872 if (enqueue_event (&event
, &x_expose_queue
))
1873 /* If it is full, we can't record the rectangle,
1874 so redraw this entire window. */
1876 /* Say must check all windows' needs_exposure flags. */
1877 expose_all_windows
= 1;
1878 f
->display
.x
->needs_exposure
= 1;
1883 /* This should happen only when we are expecting it,
1884 in x_read_exposes. */
1886 #endif /* ! defined (HAVE_X11) */
1893 f
= x_window_to_frame (event
.xunmap
.window
);
1894 if (f
) /* F may no longer exist if
1895 the frame was deleted. */
1897 /* While a frame is unmapped, display generation is
1898 disabled; you don't want to spend time updating a
1899 display that won't ever be seen. */
1901 x_mouse_x
= x_mouse_y
= -1;
1907 f
= x_window_to_frame (event
.xmap
.window
);
1913 /* wait_reading_process_input will notice this and update
1914 the frame's display structures. */
1915 SET_FRAME_GARBAGED (f
);
1919 /* Turn off processing if we become fully obscured. */
1920 case VisibilityNotify
:
1923 #else /* ! defined (HAVE_X11) */
1925 f
= x_window_to_frame (event
.window
);
1926 if (event
.window
== f
->display
.x
->icon_desc
)
1928 if (event
.window
== FRAME_X_WINDOW (f
))
1931 #endif /* ! defined (HAVE_X11) */
1935 f
= x_window_to_frame (event
.xkey
.window
);
1939 XComposeStatus status
;
1940 char copy_buffer
[80];
1941 int modifiers
= event
.xkey
.state
;
1943 /* Some keyboards generate different characters
1944 depending on the state of the meta key, in an attempt
1945 to support non-English typists. It would be nice to
1946 keep this functionality somehow, but for now, we will
1947 just clear the meta-key flag to get the 'pure' character. */
1948 event
.xkey
.state
&= ~Mod1Mask
;
1950 /* This will have to go some day... */
1951 nbytes
= XLookupString (&event
.xkey
,
1957 /* Strip off the vendor-specific keysym bit, and take a shot
1958 at recognizing the codes. HP servers have extra keysyms
1959 that fit into the MiscFunctionKey category. */
1964 if (IsCursorKey (keysym
) /* 0xff50 <= x < 0xff60 */
1965 || IsMiscFunctionKey (keysym
) /* 0xff60 <= x < 0xff80 */
1966 || IsKeypadKey (keysym
) /* 0xff80 <= x < 0xffbe */
1967 || IsFunctionKey (keysym
)) /* 0xffbe <= x < 0xffe1 */
1969 bufp
->kind
= non_ascii_keystroke
;
1970 XSET (bufp
->code
, Lisp_Int
, (unsigned) keysym
- 0xff50);
1972 bufp
->modifiers
= x_convert_modifiers (modifiers
);
1973 bufp
->timestamp
= event
.xkey
.time
;
1978 else if (numchars
> nbytes
)
1984 if (modifiers
& Mod1Mask
)
1985 *copy_buffer
|= METABIT
;
1986 bufp
->kind
= ascii_keystroke
;
1987 XSET (bufp
->code
, Lisp_Int
, *copy_buffer
);
1989 bufp
->timestamp
= event
.xkey
.time
;
1993 for (i
= nbytes
- 1; i
> 1; i
--)
1995 bufp
->kind
= ascii_keystroke
;
1996 XSET (bufp
->code
, Lisp_Int
, copy_buffer
[i
]);
1998 bufp
->timestamp
= event
.xkey
.time
;
2008 #else /* ! defined (HAVE_X11) */
2011 register char *where_mapping
;
2013 f
= x_window_to_frame (event
.window
);
2014 /* Ignore keys typed on icon windows. */
2015 if (f
!= 0 && event
.window
== f
->display
.x
->icon_desc
)
2017 where_mapping
= XLookupMapping (&event
, &nbytes
);
2018 /* Nasty fix for arrow keys */
2019 if (!nbytes
&& IsCursorKey (event
.detail
& 0xff))
2021 switch (event
.detail
& 0xff)
2023 case KC_CURSOR_LEFT
:
2024 where_mapping
= "\002";
2026 case KC_CURSOR_RIGHT
:
2027 where_mapping
= "\006";
2030 where_mapping
= "\020";
2032 case KC_CURSOR_DOWN
:
2033 where_mapping
= "\016";
2038 if (numchars
- nbytes
> 0)
2042 for (i
= 0; i
< nbytes
; i
++)
2044 bufp
->kind
= ascii_keystroke
;
2045 XSET (bufp
->code
, Lisp_Int
, where_mapping
[i
]);
2046 XSET (bufp
->time
, Lisp_Int
, event
.xkey
.time
);
2055 #endif /* ! defined (HAVE_X11) */
2059 f
= x_window_to_frame (event
.xcrossing
.window
);
2061 if (event
.xcrossing
.detail
== NotifyInferior
) /* Left Scrollbar */
2063 else if (event
.xcrossing
.focus
) /* Entered Window */
2065 /* If we decide we want to generate an event to be seen
2066 by the rest of Emacs, we put it here. */
2067 struct input_event emacs_event
;
2068 emacs_event
.kind
= no_event
;
2070 /* Avoid nasty pop/raise loops. */
2071 if (f
&& (!(f
->auto_raise
)
2073 || (event
.xcrossing
.time
- enter_timestamp
) > 500))
2075 x_new_focus_frame (f
);
2076 enter_timestamp
= event
.xcrossing
.time
;
2079 else if ((f
= x_window_to_scrollbar (event
.xcrossing
.window
,
2081 /* Fake a motion event */
2082 notice_mouse_movement (&emacs_event
,
2083 event
.xmotion
, f
, scrollbar_window
,
2088 if (! EQ (Vx_send_mouse_movement_events
, Qnil
)
2090 && emacs_event
.kind
!= no_event
)
2092 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
2099 else if (f
== x_focus_frame
)
2100 x_new_focus_frame (0);
2102 else if (f
= x_window_to_frame (event
.xcrossing
.window
))
2109 f
= x_window_to_frame (event
.xfocus
.window
);
2111 x_new_focus_frame (f
);
2115 if (event
.xcrossing
.detail
!= NotifyInferior
2116 && event
.xcrossing
.subwindow
== None
2117 && event
.xcrossing
.mode
== NotifyNormal
)
2119 f
= x_window_to_frame (event
.xcrossing
.window
);
2121 if (event
.xcrossing
.focus
)
2122 x_new_focus_frame (f
);
2123 else if (f
== x_focus_frame
)
2124 x_new_focus_frame (0);
2129 f
= x_window_to_frame (event
.xfocus
.window
);
2130 if (f
&& f
== x_focus_frame
)
2131 x_new_focus_frame (0);
2134 #else /* ! defined (HAVE_X11) */
2137 if ((event
.detail
& 0xFF) == 1)
2138 break; /* Coming from our own subwindow */
2139 if (event
.subwindow
!= 0)
2140 break; /* Entering our own subwindow. */
2143 f
= x_window_to_frame (event
.window
);
2146 x_new_focus_frame (f
);
2151 if ((event
.detail
& 0xFF) == 1)
2152 break; /* Entering our own subwindow */
2153 if (event
.subwindow
!= 0)
2154 break; /* Leaving our own subwindow. */
2157 if (x_focus_frame
== 0
2158 && x_input_frame
!= 0
2159 && x_input_frame
== x_window_to_frame (event
.window
)
2160 && event
.window
== FRAME_X_WINDOW (x_input_frame
))
2165 frame_unhighlight (f
);
2168 #endif /* ! defined (HAVE_X11) */
2173 f
= x_window_to_frame (event
.xmotion
.window
);
2175 note_mouse_position (f
, &event
.xmotion
);
2177 else if ((f
= x_window_to_scrollbar (event
.xmotion
.window
,
2180 What should go here
?
2186 case ConfigureNotify
:
2189 f
= x_window_to_frame (event
.xconfigure
.window
);
2193 columns
= ((event
.xconfigure
.width
-
2194 (2 * f
->display
.x
->internal_border_width
)
2195 - f
->display
.x
->v_scrollbar_width
)
2196 / FONT_WIDTH (f
->display
.x
->font
));
2197 rows
= ((event
.xconfigure
.height
-
2198 (2 * f
->display
.x
->internal_border_width
)
2199 - f
->display
.x
->h_scrollbar_height
)
2200 / FONT_HEIGHT (f
->display
.x
->font
));
2202 /* Even if the number of character rows and columns has
2203 not changed, the font size may have changed, so we need
2204 to check the pixel dimensions as well. */
2205 if (columns
!= f
->width
2206 || rows
!= f
->height
2207 || event
.xconfigure
.width
!= f
->display
.x
->pixel_width
2208 || event
.xconfigure
.height
!= f
->display
.x
->pixel_height
)
2210 change_frame_size (f
, rows
, columns
, 0, 1);
2211 x_resize_scrollbars (f
);
2212 SET_FRAME_GARBAGED (f
);
2215 f
->display
.x
->pixel_width
= event
.xconfigure
.width
;
2216 f
->display
.x
->pixel_height
= event
.xconfigure
.height
;
2217 f
->display
.x
->left_pos
= event
.xconfigure
.x
;
2218 f
->display
.x
->top_pos
= event
.xconfigure
.y
;
2225 /* If we decide we want to generate an event to be seen
2226 by the rest of Emacs, we put it here. */
2227 struct input_event emacs_event
;
2228 emacs_event
.kind
= no_event
;
2230 f
= x_window_to_frame (event
.xbutton
.window
);
2232 if (!x_focus_frame
|| (f
== x_focus_frame
))
2233 construct_mouse_click (&emacs_event
,
2238 if ((f
= x_window_to_scrollbar (event
.xbutton
.window
,
2241 if (!x_focus_frame
|| (selected_frame
== x_focus_frame
))
2242 construct_mouse_click (&emacs_event
,
2243 &event
, f
, part
, prefix
);
2248 if (numchars
>= 1 && emacs_event
.kind
!= no_event
)
2250 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
2258 #else /* ! defined (HAVE_X11) */
2260 case ButtonReleased
:
2261 f
= x_window_to_frame (event
.window
);
2264 if (event
.window
== f
->display
.x
->icon_desc
)
2266 x_make_frame_visible (f
);
2268 if (warp_mouse_on_deiconify
)
2269 XWarpMouse (FRAME_X_WINDOW (f
), 10, 10);
2272 if (event
.window
== FRAME_X_WINDOW (f
))
2278 enqueue_event (&event
, &x_mouse_queue
);
2281 bufp
->kind
= ascii_keystroke
;
2282 bufp
->code
= (char) 'X' & 037; /* C-x */
2284 XSET (bufp
->time
, Lisp_Int
, event
.xkey
.time
);
2287 bufp
->kind
= ascii_keystroke
;
2288 bufp
->code
= (char) 0; /* C-@ */
2290 XSET (bufp
->time
, Lisp_Int
, event
.xkey
.time
);
2297 #endif /* ! defined (HAVE_X11) */
2301 case CirculateNotify
:
2303 case CirculateRequest
:
2306 #endif /* ! defined (HAVE_X11) */
2309 if (event
.xmapping
.request
== MappingKeyboard
)
2310 /* Someone has changed the keyboard mapping - flush the
2312 XRefreshKeyboardMapping (&event
.xmapping
);
2322 if (expected
&& ! event_found
)
2324 /* AOJ 880406: if select returns true but XPending doesn't, it means that
2325 there is an EOF condition; in other words, that X has died.
2326 Act as if there had been a hangup. */
2328 int fd
= ConnectionNumber (x_current_display
);
2331 if (0 != select (fd
+ 1, &mask
, (long *) 0, (long *) 0,
2333 && !XStuffPending ())
2334 kill (getpid (), SIGHUP
);
2336 #endif /* ! defined (HAVE_SELECT) */
2339 if (updating_frame
== 0)
2340 x_do_pending_expose ();
2347 /* Read and process only Expose events
2348 until we get an ExposeCopy event; then return.
2349 This is used in insert/delete line.
2350 We assume input is already blocked. */
2356 XKeyPressedEvent event
;
2360 /* while there are more events*/
2361 XMaskEvent (ExposeWindow
| ExposeRegion
| ExposeCopy
, &event
);
2365 if (event
.subwindow
!= 0)
2366 break; /* duplicate event */
2367 f
= x_window_to_frame (event
.window
);
2368 if (event
.window
== f
->display
.x
->icon_desc
)
2373 if (event
.window
== FRAME_X_WINDOW (f
))
2375 expose_all_windows
= 1;
2376 f
->display
.x
->needs_exposure
= 1;
2382 if (event
.subwindow
!= 0)
2383 break; /* duplicate event */
2384 f
= x_window_to_frame (event
.window
);
2385 if (event
.window
== f
->display
.x
->icon_desc
)
2390 /* If window already needs full redraw, ignore this rectangle. */
2391 if (expose_all_windows
&& f
->display
.x
->needs_exposure
)
2393 /* Put the event on the queue of rectangles to redraw. */
2394 if (enqueue_event (&event
, &x_expose_queue
))
2395 /* If it is full, we can't record the rectangle,
2396 so redraw this entire window. */
2398 /* Say must check all windows' needs_exposure flags. */
2399 expose_all_windows
= 1;
2400 f
->display
.x
->needs_exposure
= 1;
2409 #endif /* HAVE_X11 */
2412 /* Draw a hollow box cursor. Don't change the inside of the box. */
2418 int left
= f
->cursor_x
* FONT_WIDTH (f
->display
.x
->font
)
2419 + f
->display
.x
->internal_border_width
;
2420 int top
= f
->cursor_y
* FONT_HEIGHT (f
->display
.x
->font
)
2421 + f
->display
.x
->internal_border_width
;
2422 int width
= FONT_WIDTH (f
->display
.x
->font
);
2423 int height
= FONT_HEIGHT (f
->display
.x
->font
);
2426 /* Perhaps we should subtract 1 from width and height... */
2427 XDrawRectangle (x_current_display
, FRAME_X_WINDOW (f
),
2428 f
->display
.x
->cursor_gc
,
2429 left
, top
, width
- 1, height
- 1);
2430 #else /* ! defined (HAVE_X11) */
2431 XPixSet (FRAME_X_WINDOW (f
),
2432 left
, top
, width
, 1,
2433 f
->display
.x
->cursor_pixel
);
2435 XPixSet (FRAME_X_WINDOW (f
),
2436 left
, top
, 1, height
,
2437 f
->display
.x
->cursor_pixel
);
2439 XPixSet (FRAME_X_WINDOW (f
),
2440 left
+width
-1, top
, 1, height
,
2441 f
->display
.x
->cursor_pixel
);
2443 XPixSet (FRAME_X_WINDOW (f
),
2444 left
, top
+height
-1, width
, 1,
2445 f
->display
.x
->cursor_pixel
);
2446 #endif /* ! defined (HAVE_X11) */
2449 /* Clear the cursor of frame F to background color,
2450 and mark the cursor as not shown.
2451 This is used when the text where the cursor is
2452 is about to be rewritten. */
2461 || f
->phys_cursor_x
< 0)
2465 x_display_cursor (f
, 0);
2467 XClearArea (x_current_display
, FRAME_X_WINDOW (f
),
2468 f
->phys_cursor_x
* FONT_WIDTH (f
->display
.x
->font
)
2469 + f
->display
.x
->internal_border_width
,
2470 f
->phys_cursor_y
* FONT_HEIGHT (f
->display
.x
->font
)
2471 + f
->display
.x
->internal_border_width
,
2472 FONT_WIDTH (f
->display
.x
->font
) + 1, FONT_HEIGHT (f
->display
.x
->font
) + 1, False
);
2474 #else /* ! defined (HAVE_X11) */
2475 XPixSet (FRAME_X_WINDOW (f
),
2476 f
->phys_cursor_x
* FONT_WIDTH (f
->display
.x
->font
) + f
->display
.x
->internal_border_width
,
2477 f
->phys_cursor_y
* FONT_HEIGHT (f
->display
.x
->font
) + f
->display
.x
->internal_border_width
,
2478 FONT_WIDTH (f
->display
.x
->font
), FONT_HEIGHT (f
->display
.x
->font
),
2479 f
->display
.x
->background_pixel
);
2480 #endif /* ! defined (HAVE_X11) */
2481 f
->phys_cursor_x
= -1;
2485 x_display_bar_cursor (f
, on
)
2489 register int phys_x
= f
->phys_cursor_x
;
2490 register int phys_y
= f
->phys_cursor_y
;
2495 if (! f
->visible
|| (! on
&& f
->phys_cursor_x
< 0))
2500 (!on
|| phys_x
!= f
->cursor_x
|| phys_y
!= f
->cursor_y
))
2502 x1
= phys_x
* FONT_WIDTH (f
->display
.x
->font
)
2503 + f
->display
.x
->internal_border_width
;
2504 y1
= phys_y
* FONT_HEIGHT (f
->display
.x
->font
)
2505 + f
->display
.x
->internal_border_width
- 1;
2506 y2
= y1
+ FONT_HEIGHT (f
->display
.x
->font
) + 1;
2508 XDrawLine (x_current_display
, FRAME_X_WINDOW (f
),
2509 f
->display
.x
->reverse_gc
, x1
, y1
, x1
, y2
);
2511 f
->phys_cursor_x
= phys_x
= -1;
2514 if (on
&& f
== x_highlight_frame
)
2516 x1
= f
->cursor_x
* FONT_WIDTH (f
->display
.x
->font
)
2517 + f
->display
.x
->internal_border_width
;
2518 y1
= f
->cursor_y
* FONT_HEIGHT (f
->display
.x
->font
)
2519 + f
->display
.x
->internal_border_width
- 1;
2520 y2
= y1
+ FONT_HEIGHT (f
->display
.x
->font
) + 1;
2522 XDrawLine (x_current_display
, FRAME_X_WINDOW (f
),
2523 f
->display
.x
->cursor_gc
, x1
, y1
, x1
, y2
);
2525 f
->phys_cursor_x
= f
->cursor_x
;
2526 f
->phys_cursor_y
= f
->cursor_y
;
2528 #else /* ! defined (HAVE_X11) */
2530 #endif /* ! defined (HAVE_X11) */
2534 /* Redraw the glyph at ROW, COLUMN on frame F, in the style
2535 HIGHLIGHT. HIGHLIGHT is as defined for dumpglyphs. Return the
2539 x_draw_single_glyph (f
, row
, column
, glyph
, highlight
)
2546 (column
* FONT_WIDTH (f
->display
.x
->font
)
2547 + f
->display
.x
->internal_border_width
),
2548 (row
* FONT_HEIGHT (f
->display
.x
->font
)
2549 + f
->display
.x
->internal_border_width
),
2550 &glyph
, 1, highlight
, f
->display
.x
->font
);
2553 /* Turn the displayed cursor of frame F on or off according to ON.
2554 If ON is nonzero, where to put the cursor is specified
2555 by F->cursor_x and F->cursor_y. */
2558 x_display_box_cursor (f
, on
)
2562 struct frame_glyphs
*current_glyphs
= FRAME_CURRENT_GLYPHS (f
);
2564 /* If we're not updating, then we want to use the current frame's
2565 cursor position, not our local idea of where the cursor ought to be. */
2566 if (f
!= updating_frame
)
2568 curs_x
= FRAME_CURSOR_X (f
);
2569 curs_y
= FRAME_CURSOR_Y (f
);
2575 /* If cursor is off and we want it off, return quickly. */
2576 if (!on
&& f
->phys_cursor_x
< 0)
2579 /* If cursor is currently being shown and we don't want it to be
2580 or it is in the wrong place,
2581 or we want a hollow box and it's not so, (pout!)
2583 if (f
->phys_cursor_x
>= 0
2585 || f
->phys_cursor_x
!= curs_x
2586 || f
->phys_cursor_y
!= curs_y
2587 || (f
->display
.x
->text_cursor_kind
!= hollow_box_cursor
2588 && (f
!= x_highlight_frame
))))
2590 /* Erase the cursor by redrawing the character underneath it. */
2591 x_draw_single_glyph (f
, f
->phys_cursor_y
, f
->phys_cursor_x
,
2592 f
->phys_cursor_glyph
,
2593 current_glyphs
->highlight
[f
->phys_cursor_y
]);
2594 f
->phys_cursor_x
= -1;
2597 /* If we want to show a cursor,
2598 or we want a box cursor and it's not so,
2599 write it in the right place. */
2601 && (f
->phys_cursor_x
< 0
2602 || (f
->display
.x
->text_cursor_kind
!= filled_box_cursor
2603 && f
== x_highlight_frame
)))
2605 f
->phys_cursor_glyph
2606 = ((current_glyphs
->enable
[curs_y
]
2607 && curs_x
< current_glyphs
->used
[curs_y
])
2608 ? current_glyphs
->glyphs
[curs_y
][curs_x
]
2610 if (f
!= x_highlight_frame
)
2613 f
->display
.x
->text_cursor_kind
= hollow_box_cursor
;
2617 x_draw_single_glyph (f
, curs_y
, curs_x
,
2618 f
->phys_cursor_glyph
, 2);
2619 f
->display
.x
->text_cursor_kind
= filled_box_cursor
;
2622 f
->phys_cursor_x
= curs_x
;
2623 f
->phys_cursor_y
= curs_y
;
2626 if (updating_frame
!= f
)
2630 extern Lisp_Object Vbar_cursor
;
2632 x_display_cursor (f
, on
)
2636 if (EQ (Vbar_cursor
, Qnil
))
2637 x_display_box_cursor (f
, on
);
2639 x_display_bar_cursor (f
, on
);
2644 /* Refresh bitmap kitchen sink icon for frame F
2645 when we get an expose event for it. */
2651 /* Normally, the window manager handles this function. */
2652 #else /* ! defined (HAVE_X11) */
2655 if (f
->display
.x
->icon_bitmap_flag
)
2656 XBitmapBitsPut (f
->display
.x
->icon_desc
, 0, 0, sink_width
, sink_height
,
2657 sink_bits
, BlackPixel
, WHITE_PIX_DEFAULT
,
2658 icon_bitmap
, GXcopy
, AllPlanes
);
2661 extern struct frame
*selected_frame
;
2662 struct Lisp_String
*str
;
2663 unsigned char *string
;
2666 = XSTRING (XBUFFER (XWINDOW (f
->selected_window
)->buffer
)->name
)->data
;
2668 if (f
->display
.x
->icon_label
!= string
)
2670 f
->display
.x
->icon_label
= string
;
2671 XChangeWindow (f
->display
.x
->icon_desc
,
2672 XQueryWidth (string
, icon_font_info
->id
) + 10,
2673 icon_font_info
->height
+ 10);
2676 XText (f
->display
.x
->icon_desc
, 5, 5, string
,
2677 str
->size
, icon_font_info
->id
,
2678 BLACK_PIX_DEFAULT
, WHITE_PIX_DEFAULT
);
2681 #endif /* ! defined (HAVE_X11) */
2684 /* Make the x-window of frame F use the kitchen-sink icon
2685 that's a window generated by Emacs. */
2694 if (FRAME_X_WINDOW (f
) == 0)
2699 XFreePixmap (x_current_display
, icon_bitmap
);
2702 XCreateBitmapFromData (x_current_display
, FRAME_X_WINDOW (f
),
2703 gnu_bits
, gnu_width
, gnu_height
);
2704 x_wm_set_icon_pixmap (f
, icon_bitmap
);
2705 f
->display
.x
->icon_bitmap_flag
= 1;
2706 #else /* ! defined (HAVE_X11) */
2707 if (f
->display
.x
->icon_desc
)
2709 XClearIconWindow (FRAME_X_WINDOW (f
));
2710 XDestroyWindow (f
->display
.x
->icon_desc
);
2713 icon_window
= XCreateWindow (f
->display
.x
->parent_desc
,
2714 0, 0, sink_width
, sink_height
,
2715 2, WhitePixmap
, (Pixmap
) NULL
);
2717 if (icon_window
== 0)
2720 XSetIconWindow (FRAME_X_WINDOW (f
), icon_window
);
2721 XSelectInput (icon_window
, ExposeWindow
| UnmapWindow
);
2723 f
->display
.x
->icon_desc
= icon_window
;
2724 f
->display
.x
->icon_bitmap_flag
= 1;
2726 if (icon_bitmap
== 0)
2728 = XStoreBitmap (sink_mask_width
, sink_mask_height
, sink_mask_bits
);
2729 #endif /* ! defined (HAVE_X11) */
2735 /* Make the x-window of frame F use a rectangle with text. */
2738 x_text_icon (f
, icon_name
)
2746 char *X_DefaultValue
;
2750 #define WhitePixel 1
2751 #endif /* WhitePixel */
2754 #define BlackPixel 0
2755 #endif /* BlackPixel */
2756 #endif /* HAVE_X11 */
2758 if (FRAME_X_WINDOW (f
) == 0)
2761 if (icon_font_info
== 0)
2763 = XGetFont (XGetDefault (XDISPLAY
2764 (char *) XSTRING (invocation_name
)->data
,
2769 f
->display
.x
->icon_label
= icon_name
;
2771 if (! f
->display
.x
->icon_label
)
2772 f
->display
.x
->icon_label
= " *emacs* ";
2774 XSetIconName (x_current_display
, FRAME_X_WINDOW (f
),
2775 (char *) f
->display
.x
->icon_label
);
2777 f
->display
.x
->icon_bitmap_flag
= 0;
2778 x_wm_set_icon_pixmap (f
, 0);
2779 #else /* ! defined (HAVE_X11) */
2780 if (f
->display
.x
->icon_desc
)
2782 XClearIconWindow (XDISPLAY
FRAME_X_WINDOW (f
));
2783 XDestroyWindow (XDISPLAY f
->display
.x
->icon_desc
);
2787 f
->display
.x
->icon_label
= (unsigned char *) icon_name
;
2789 if (! f
->display
.x
->icon_label
)
2790 f
->display
.x
->icon_label
= XSTRING (f
->name
)->data
;
2792 width
= XStringWidth (f
->display
.x
->icon_label
, icon_font_info
, 0, 0);
2793 icon_window
= XCreateWindow (f
->display
.x
->parent_desc
,
2794 f
->display
.x
->left_pos
,
2795 f
->display
.x
->top_pos
,
2796 width
+ 10, icon_font_info
->height
+ 10,
2797 2, BlackPixmap
, WhitePixmap
);
2799 if (icon_window
== 0)
2802 XSetIconWindow (FRAME_X_WINDOW (f
), icon_window
);
2803 XSelectInput (icon_window
, ExposeWindow
| ExposeRegion
| UnmapWindow
| ButtonPressed
);
2805 f
->display
.x
->icon_desc
= icon_window
;
2806 f
->display
.x
->icon_bitmap_flag
= 0;
2807 f
->display
.x
->icon_label
= 0;
2808 #endif /* ! defined (HAVE_X11) */
2813 /* Handling X errors. */
2815 /* A handler for SIGPIPE, when it occurs on the X server's connection.
2816 This basically does an orderly shutdown of Emacs. */
2819 x_connection_closed ()
2824 Fkill_emacs (make_number (70));
2827 /* An X error handler which prints an error message and then kills Emacs.
2828 This is what's normally installed as Xlib's handler for protocol and
2831 x_error_quitter (display
, error
)
2837 /* Note that there is no real way portable across R3/R4 to get the
2838 original error handler. */
2840 XGetErrorText (display
, error
->error_code
, buf
, sizeof (buf
));
2841 fprintf (stderr
, "X protocol error: %s on protocol request %d\n",
2842 buf
, error
->request_code
);
2844 x_connection_closed ();
2847 /* A buffer for storing X error messages. */
2848 static char (*x_caught_error_message
)[200];
2850 /* An X error handler which stores the error message in
2851 x_caught_error_message. This is what's installed when
2852 x_catch_errors is in effect. */
2854 x_error_catcher (display
, error
)
2858 XGetErrorText (display
, error
->error_code
,
2859 *x_caught_error_message
, sizeof (*x_caught_error_message
));
2863 /* Begin trapping X errors.
2865 After calling this function, X protocol errors no longer cause
2866 Emacs to exit; instead, they are recorded in x_cfc_error_message.
2868 Calling x_check_errors signals an Emacs error if an X error has
2869 occurred since the last call to x_catch_errors or x_check_errors.
2871 Calling x_uncatch_errors resumes the normal error handling. */
2873 void x_catch_errors(), x_check_errors (), x_uncatch_errors ();
2878 /* Make sure any errors from previous requests have been dealt with. */
2879 XSync (x_current_display
, False
);
2881 /* Set up the error buffer. */
2882 x_caught_error_message
=
2883 (char (*)[]) xmalloc (sizeof (*x_caught_error_message
));
2885 /* Install our little error handler. */
2886 XHandleError (x_error_catcher
);
2889 /* If any X protocol errors have arrived since the last call to
2890 x_catch_errors or x_check_errors, signal an Emacs error using
2891 sprintf (a buffer, FORMAT, the x error message text) as the text. */
2893 x_check_errors (format
)
2896 /* Make sure to catch any errors incurred so far. */
2897 XSync (x_current_display
, False
);
2899 if ((*x_caught_error_message
)[0])
2903 sprintf (buf
, format
, *x_caught_error_message
);
2904 free (x_caught_error_message
);
2906 x_uncatch_errors ();
2914 free (x_caught_error_message
);
2915 XHandleError (x_error_quitter
);
2919 static unsigned int x_wire_count
;
2922 fprintf (stderr
, "Lib call: %d\n", ++x_wire_count
);
2927 /* Set the font of the x-window specified by frame F
2928 to the font named NEWNAME. This is safe to use
2929 even before F has an actual x-window. */
2933 /* A table of all the fonts we have already loaded. */
2934 static XFontStruct
**x_font_table
;
2936 /* The current capacity of x_font_table. */
2937 static int x_font_table_size
;
2939 /* The number of fonts actually stored in x_font_table.
2940 x_font_table[n] is used and valid iff 0 <= n < n_fonts.
2941 0 <= n_fonts <= x_font_table_size. */
2944 x_new_font (f
, fontname
)
2946 register char *fontname
;
2950 int n_matching_fonts
;
2951 XFontStruct
*font_info
;
2954 /* Get a list of all the fonts that match this name. Once we
2955 have a list of matching fonts, we compare them against the fonts
2956 we already have by comparing font ids. */
2957 font_names
= (char **) XListFontsWithInfo (x_current_display
, fontname
,
2958 1024, &n_matching_fonts
,
2960 /* If the server couldn't find any fonts whose named matched fontname,
2961 return an error code. */
2962 if (n_matching_fonts
== 0)
2965 /* See if we've already loaded a matching font. */
2970 for (i
= 0; i
< n_fonts
; i
++)
2971 for (j
= 0; j
< n_matching_fonts
; j
++)
2972 if (x_font_table
[i
]->fid
== font_info
[j
].fid
)
2980 /* If we have, just return it from the table. */
2982 f
->display
.x
->font
= x_font_table
[already_loaded
];
2984 /* Otherwise, load the font and add it to the table. */
2989 font
= (XFontStruct
*) XLoadQueryFont (x_current_display
, fontname
);
2993 /* Do we need to create the table? */
2994 if (x_font_table_size
== 0)
2996 x_font_table_size
= 16;
2998 = (XFontStruct
**) xmalloc (x_font_table_size
2999 * sizeof (x_font_table
[0]));
3001 /* Do we need to grow the table? */
3002 else if (n_fonts
>= x_font_table_size
)
3004 x_font_table_size
*= 2;
3006 = (XFontStruct
**) xrealloc (x_font_table
,
3008 * sizeof (x_font_table
[0])));
3011 f
->display
.x
->font
= x_font_table
[n_fonts
++] = font
;
3014 /* Free the information from XListFontsWithInfo. The data
3015 we actually retain comes from XLoadQueryFont. */
3016 XFreeFontInfo (font_names
, font_info
, n_matching_fonts
);
3018 /* Now make the frame display the given font. */
3019 if (FRAME_X_WINDOW (f
) != 0)
3021 XSetFont (x_current_display
, f
->display
.x
->normal_gc
,
3022 f
->display
.x
->font
->fid
);
3023 XSetFont (x_current_display
, f
->display
.x
->reverse_gc
,
3024 f
->display
.x
->font
->fid
);
3025 XSetFont (x_current_display
, f
->display
.x
->cursor_gc
,
3026 f
->display
.x
->font
->fid
);
3028 x_set_window_size (f
, f
->width
, f
->height
);
3033 #else /* ! defined (HAVE_X11) */
3034 x_new_font (f
, newname
)
3036 register char *newname
;
3041 temp
= XGetFont (newname
);
3042 if (temp
== (FONT_TYPE
*) 0)
3045 if (f
->display
.x
->font
)
3046 XLoseFont (f
->display
.x
->font
);
3048 f
->display
.x
->font
= temp
;
3050 if (FRAME_X_WINDOW (f
) != 0)
3051 x_set_window_size (f
, f
->width
, f
->height
);
3055 #endif /* ! defined (HAVE_X11) */
3057 x_calc_absolute_position (f
)
3061 if (f
->display
.x
->left_pos
< 0)
3062 f
->display
.x
->left_pos
3063 = XINT (x_screen_width
) - PIXEL_WIDTH (f
) + f
->display
.x
->left_pos
;
3065 if (f
->display
.x
->top_pos
< 0)
3066 f
->display
.x
->top_pos
3067 = XINT (x_screen_height
) - PIXEL_HEIGHT (f
) + f
->display
.x
->top_pos
;
3068 #else /* ! defined (HAVE_X11) */
3069 WINDOWINFO_TYPE parentinfo
;
3071 XGetWindowInfo (FRAME_X_WINDOW (f
), &parentinfo
);
3073 if (f
->display
.x
->left_pos
< 0)
3074 f
->display
.x
->left_pos
= parentinfo
.width
+ (f
->display
.x
->left_pos
+ 1)
3075 - PIXEL_WIDTH (f
) - 2 * f
->display
.x
->internal_border_width
;
3077 if (f
->display
.x
->top_pos
< 0)
3078 f
->display
.x
->top_pos
= parentinfo
.height
+ (f
->display
.x
->top_pos
+ 1)
3079 - PIXEL_HEIGHT (f
) - 2 * f
->display
.x
->internal_border_width
;
3080 #endif /* ! defined (HAVE_X11) */
3083 x_set_offset (f
, xoff
, yoff
)
3085 register int xoff
, yoff
;
3087 f
->display
.x
->top_pos
= yoff
;
3088 f
->display
.x
->left_pos
= xoff
;
3089 x_calc_absolute_position (f
);
3092 XMoveWindow (XDISPLAY
FRAME_X_WINDOW (f
),
3093 f
->display
.x
->left_pos
, f
->display
.x
->top_pos
);
3095 x_wm_set_size_hint (f
, 0);
3096 #endif /* ! defined (HAVE_X11) */
3100 /* Call this to change the size of frame F's x-window. */
3102 x_set_window_size (f
, cols
, rows
)
3106 int pixelwidth
, pixelheight
;
3108 int ibw
= f
->display
.x
->internal_border_width
;
3112 check_frame_size (f
, &rows
, &cols
);
3113 pixelwidth
= (cols
* FONT_WIDTH (f
->display
.x
->font
) + 2 * ibw
3114 + f
->display
.x
->v_scrollbar_width
);
3115 pixelheight
= (rows
* FONT_HEIGHT (f
->display
.x
->font
) + 2 * ibw
3116 + f
->display
.x
->h_scrollbar_height
);
3119 x_wm_set_size_hint (f
, 0);
3120 #endif /* ! defined (HAVE_X11) */
3121 XChangeWindowSize (FRAME_X_WINDOW (f
), pixelwidth
, pixelheight
);
3123 /* Now, strictly speaking, we can't be sure that this is accurate,
3124 but the window manager will get around to dealing with the size
3125 change request eventually, and we'll hear how it went when the
3126 ConfigureNotify event gets here. */
3127 FRAME_WIDTH (f
) = cols
;
3128 FRAME_WIDTH (f
) = rows
;
3129 PIXEL_WIDTH (f
) = pixelwidth
;
3130 PIXEL_HEIGHT (f
) = pixelheight
;
3137 x_set_resize_hint (f
)
3141 XSetResizeHint (FRAME_X_WINDOW (f
), 2 * f
->display
.x
->internal_border_width
,
3142 2 * f
->display
.x
->internal_border_width
,
3143 FONT_WIDTH (f
->display
.x
->font
), FONT_HEIGHT (f
->display
.x
->font
));
3145 #endif /* HAVE_X11 */
3148 x_set_mouse_position (f
, x
, y
)
3157 pix_x
= (FRAME_WIDTH (f
)
3158 * FONT_WIDTH (f
->display
.x
->font
)
3159 + 2 * f
->display
.x
->internal_border_width
3160 + f
->display
.x
->v_scrollbar_width
) / 2;
3162 pix_x
= x
* FONT_WIDTH (f
->display
.x
->font
) + 2; /* add 2 pixels to each
3163 dimension to move the
3168 pix_y
= (FRAME_HEIGHT (f
)
3169 * FONT_HEIGHT (f
->display
.x
->font
)
3170 + 2 * f
->display
.x
->internal_border_width
3171 + f
->display
.x
->h_scrollbar_height
) / 2;
3173 pix_y
= y
* FONT_HEIGHT (f
->display
.x
->font
) + 2;
3179 XWarpMousePointer (FRAME_X_WINDOW (f
), pix_x
, pix_y
);
3184 x_focus_on_frame (f
)
3189 /* I don't think that the ICCCM allows programs to do things like this
3190 without the interaction of the window manager. Whatever you end up
3191 doing with this code, do it to x_unfocus_frame too. */
3192 XSetInputFocus (x_current_display
, FRAME_X_WINDOW (f
),
3193 RevertToPointerRoot
, CurrentTime
);
3201 /* Look at the remarks in x_focus_on_frame. */
3202 if (x_focus_frame
== f
)
3203 XSetInputFocus (x_current_display
, PointerRoot
,
3204 RevertToPointerRoot
, CurrentTime
);
3208 #endif /* ! defined (HAVE_X11) */
3210 /* Raise frame F. */
3218 XRaiseWindow (XDISPLAY
FRAME_X_WINDOW (f
));
3224 /* Lower frame F. */
3232 XLowerWindow (XDISPLAY
FRAME_X_WINDOW (f
));
3238 /* Change from withdrawn state to mapped state. */
3240 x_make_frame_visible (f
)
3247 if (! FRAME_VISIBLE_P (f
))
3250 if (! EQ (Vx_no_window_manager
, Qt
))
3251 x_wm_set_window_state (f
, NormalState
);
3253 XMapWindow (XDISPLAY
FRAME_X_WINDOW (f
));
3254 if (f
->display
.x
->v_scrollbar
!= 0 || f
->display
.x
->h_scrollbar
!= 0)
3255 XMapSubwindows (x_current_display
, FRAME_X_WINDOW (f
));
3256 #else /* ! defined (HAVE_X11) */
3257 XMapWindow (XDISPLAY
FRAME_X_WINDOW (f
));
3258 if (f
->display
.x
->icon_desc
!= 0)
3259 XUnmapWindow (f
->display
.x
->icon_desc
);
3261 /* Handled by the MapNotify event for X11 */
3265 /* NOTE: this may cause problems for the first frame. */
3267 #endif /* ! defined (HAVE_X11) */
3275 /* Change from mapped state to withdrawn state. */
3277 x_make_frame_invisible (f
)
3289 if (! XWithdrawWindow (x_current_display
, FRAME_X_WINDOW (f
),
3290 DefaultScreen (x_current_display
)))
3292 UNBLOCK_INPUT_RESIGNAL
;
3293 error ("can't notify window manager of window withdrawl");
3296 #else /* ! defined (HAVE_X11R4) */
3299 /* Tell the window manager what we're going to do. */
3300 if (! EQ (Vx_no_window_manager
, Qt
))
3304 unmap
.xunmap
.type
= UnmapNotify
;
3305 unmap
.xunmap
.window
= FRAME_X_WINDOW (f
);
3306 unmap
.xunmap
.event
= DefaultRootWindow (x_current_display
);
3307 unmap
.xunmap
.from_configure
= False
;
3308 if (! XSendEvent (x_current_display
,
3309 DefaultRootWindow (x_current_display
),
3311 SubstructureRedirectMask
|SubstructureNotifyMask
,
3314 UNBLOCK_INPUT_RESIGNAL
;
3315 error ("can't notify window manager of withdrawal");
3319 /* Unmap the window ourselves. Cheeky! */
3320 XUnmapWindow (x_current_display
, FRAME_X_WINDOW (f
));
3322 #else /* ! defined (HAVE_X11) */
3324 XUnmapWindow (FRAME_X_WINDOW (f
));
3325 f
->visible
= 0; /* Handled by the UnMap event for X11 */
3326 if (f
->display
.x
->icon_desc
!= 0)
3327 XUnmapWindow (f
->display
.x
->icon_desc
);
3329 #endif /* ! defined (HAVE_X11) */
3330 #endif /* ! defined (HAVE_X11R4) */
3336 /* Window manager communication. Created in Fx_open_connection. */
3337 extern Atom Xatom_wm_change_state
;
3339 /* Change window state from mapped to iconified. */
3352 /* Since we don't know which revision of X we're running, we'll use both
3353 the X11R3 and X11R4 techniques. I don't know if this is a good idea. */
3355 /* X11R4: send a ClientMessage to the window manager using the
3356 WM_CHANGE_STATE type. */
3360 message
.xclient
.window
= FRAME_X_WINDOW (f
);
3361 message
.xclient
.type
= ClientMessage
;
3362 message
.xclient
.message_type
= Xatom_wm_change_state
;
3363 message
.xclient
.format
= 32;
3364 message
.xclient
.data
.l
[0] = IconicState
;
3366 if (! XSendEvent (x_current_display
,
3367 DefaultRootWindow (x_current_display
),
3369 SubstructureRedirectMask
| SubstructureNotifyMask
,
3372 UNBLOCK_INPUT_RESIGNAL
;
3373 error ("Can't notify window manager of iconification.");
3377 /* X11R3: set the initial_state field of the window manager hints to
3379 x_wm_set_window_state (f
, IconicState
);
3382 #else /* ! defined (HAVE_X11) */
3383 XUnmapWindow (XDISPLAY
FRAME_X_WINDOW (f
));
3385 f
->visible
= 0; /* Handled in the UnMap event for X11. */
3386 if (f
->display
.x
->icon_desc
!= 0)
3388 XMapWindow (XDISPLAY f
->display
.x
->icon_desc
);
3391 #endif /* ! defined (HAVE_X11) */
3397 /* Destroy the X window of frame F.
3398 DISPL is the former f->display (since f->display
3399 has already been nulled out). */
3401 x_destroy_window (f
, displ
)
3403 union display displ
;
3408 if (displ
.x
->icon_desc
!= 0)
3409 XDestroyWindow (XDISPLAY displ
.x
->icon_desc
);
3410 XDestroyWindow (XDISPLAY displ
.x
->window_desc
);
3415 if (f
== x_focus_frame
)
3417 if (f
== x_highlight_frame
)
3418 x_highlight_frame
= 0;
3423 /* Manage event queues.
3425 This code is only used by the X10 support.
3427 We cannot leave events in the X queue and get them when we are ready
3428 because X does not provide a subroutine to get only a certain kind
3429 of event but not block if there are no queued events of that kind.
3431 Therefore, we must examine events as they come in and copy events
3432 of certain kinds into our private queues.
3434 All ExposeRegion events are put in x_expose_queue.
3435 All ButtonPressed and ButtonReleased events are put in x_mouse_queue. */
3438 /* Write the event *P_XREP into the event queue *QUEUE.
3439 If the queue is full, do nothing, but return nonzero. */
3442 enqueue_event (p_xrep
, queue
)
3443 register XEvent
*p_xrep
;
3444 register struct event_queue
*queue
;
3446 int newindex
= queue
->windex
+ 1;
3447 if (newindex
== EVENT_BUFFER_SIZE
)
3449 if (newindex
== queue
->rindex
)
3451 queue
->xrep
[queue
->windex
] = *p_xrep
;
3452 queue
->windex
= newindex
;
3456 /* Fetch the next event from queue *QUEUE and store it in *P_XREP.
3457 If *QUEUE is empty, do nothing and return 0. */
3460 dequeue_event (p_xrep
, queue
)
3461 register XEvent
*p_xrep
;
3462 register struct event_queue
*queue
;
3464 if (queue
->windex
== queue
->rindex
)
3466 *p_xrep
= queue
->xrep
[queue
->rindex
++];
3467 if (queue
->rindex
== EVENT_BUFFER_SIZE
)
3472 /* Return the number of events buffered in *QUEUE. */
3475 queue_event_count (queue
)
3476 register struct event_queue
*queue
;
3478 int tem
= queue
->windex
- queue
->rindex
;
3481 return EVENT_BUFFER_SIZE
+ tem
;
3484 /* Return nonzero if mouse input is pending. */
3487 mouse_event_pending_p ()
3489 return queue_event_count (&x_mouse_queue
);
3491 #endif /* HAVE_X11 */
3495 x_wm_set_size_hint (f
, prompting
)
3499 XSizeHints size_hints
;
3500 Window window
= FRAME_X_WINDOW (f
);
3502 size_hints
.flags
= PResizeInc
| PMinSize
| PMaxSize
;
3504 flexlines
= f
->height
;
3506 size_hints
.x
= f
->display
.x
->left_pos
;
3507 size_hints
.y
= f
->display
.x
->top_pos
;
3508 size_hints
.height
= PIXEL_HEIGHT (f
);
3509 size_hints
.width
= PIXEL_WIDTH (f
);
3510 size_hints
.width_inc
= FONT_WIDTH (f
->display
.x
->font
);
3511 size_hints
.height_inc
= FONT_HEIGHT (f
->display
.x
->font
);
3512 size_hints
.max_width
=
3513 (x_screen_width
- ((2 * f
->display
.x
->internal_border_width
)
3514 + f
->display
.x
->v_scrollbar_width
));
3515 size_hints
.max_height
=
3516 (x_screen_height
- ((2 * f
->display
.x
->internal_border_width
)
3517 + f
->display
.x
->h_scrollbar_height
));
3519 int min_rows
= 0, min_cols
= 0;
3520 check_frame_size (f
, &min_rows
, &min_cols
);
3521 size_hints
.min_width
= ((2 * f
->display
.x
->internal_border_width
)
3522 + min_cols
* size_hints
.width_inc
3523 + f
->display
.x
->v_scrollbar_width
);
3524 size_hints
.min_height
= ((2 * f
->display
.x
->internal_border_width
)
3525 + min_rows
* size_hints
.height_inc
3526 + f
->display
.x
->h_scrollbar_height
);
3531 size_hints
.flags
|= prompting
;
3534 XSizeHints hints
; /* Sometimes I hate X Windows... */
3536 XGetNormalHints (x_current_display
, window
, &hints
);
3537 if (hints
.flags
& PSize
)
3538 size_hints
.flags
|= PSize
;
3539 if (hints
.flags
& PPosition
)
3540 size_hints
.flags
|= PPosition
;
3541 if (hints
.flags
& USPosition
)
3542 size_hints
.flags
|= USPosition
;
3543 if (hints
.flags
& USSize
)
3544 size_hints
.flags
|= USSize
;
3547 XSetNormalHints (x_current_display
, window
, &size_hints
);
3550 /* Used for IconicState or NormalState */
3551 x_wm_set_window_state (f
, state
)
3555 Window window
= FRAME_X_WINDOW (f
);
3557 f
->display
.x
->wm_hints
.flags
|= StateHint
;
3558 f
->display
.x
->wm_hints
.initial_state
= state
;
3560 XSetWMHints (x_current_display
, window
, &f
->display
.x
->wm_hints
);
3563 x_wm_set_icon_pixmap (f
, icon_pixmap
)
3567 Window window
= FRAME_X_WINDOW (f
);
3569 f
->display
.x
->wm_hints
.flags
|= IconPixmapHint
;
3570 f
->display
.x
->wm_hints
.icon_pixmap
= icon_pixmap
? icon_pixmap
: None
;
3572 XSetWMHints (x_current_display
, window
, &f
->display
.x
->wm_hints
);
3575 x_wm_set_icon_position (f
, icon_x
, icon_y
)
3579 Window window
= FRAME_X_WINDOW (f
);
3581 f
->display
.x
->wm_hints
.flags
|= IconPositionHint
;
3582 f
->display
.x
->wm_hints
.icon_x
= icon_x
;
3583 f
->display
.x
->wm_hints
.icon_y
= icon_y
;
3585 XSetWMHints (x_current_display
, window
, &f
->display
.x
->wm_hints
);
3590 x_term_init (display_name
)
3596 extern int old_fcntl_owner
;
3597 #endif /* ! defined (F_SETOWN) */
3599 x_focus_frame
= x_highlight_frame
= 0;
3601 x_current_display
= XOpenDisplay (display_name
);
3602 if (x_current_display
== 0)
3603 fatal ("X server %s not responding; check the DISPLAY environment variable or use \"-d\"\n",
3608 int hostname_size
= 256;
3610 hostname
= (char *) xmalloc (hostname_size
);
3613 XSetAfterFunction (x_current_display
, x_trace_wire
);
3616 invocation_name
= Ffile_name_nondirectory (Fcar (Vcommand_line_args
));
3618 /* Try to get the host name; if the buffer is too short, try
3619 again. Apparently, the only indication gethostname gives of
3620 whether the buffer was large enough is the presence or absence
3621 of a '\0' in the string. Eech. */
3624 gethostname (hostname
, hostname_size
- 1);
3625 hostname
[hostname_size
- 1] = '\0';
3627 /* Was the buffer large enough for gethostname to store the '\0'? */
3628 if (strlen (hostname
) < hostname_size
- 1)
3631 hostname_size
<<= 1;
3632 hostname
= (char *) xrealloc (hostname
, hostname_size
);
3634 x_id_name
= (char *) xmalloc (XSTRING (invocation_name
)->size
3637 sprintf (x_id_name
, "%s@%s", XSTRING (invocation_name
)->data
, hostname
);
3640 dup2 (ConnectionNumber (x_current_display
), 0);
3642 #ifndef SYSV_STREAMS
3643 /* Streams somehow keeps track of which descriptor number
3644 is being used to talk to X. So it is not safe to substitute
3645 descriptor 0. But it is safe to make descriptor 0 a copy of it. */
3646 close (ConnectionNumber (x_current_display
));
3647 ConnectionNumber (x_current_display
) = 0; /* Looks a little strange?
3648 * check the def of the macro;
3649 * it is a genuine lvalue */
3650 #endif /* SYSV_STREAMS */
3652 #endif /* ! defined (HAVE_X11) */
3655 old_fcntl_owner
= fcntl (0, F_GETOWN
, 0);
3656 #ifdef F_SETOWN_SOCK_NEG
3657 fcntl (0, F_SETOWN
, -getpid ()); /* stdin is a socket here */
3658 #else /* ! defined (F_SETOWN_SOCK_NEG) */
3659 fcntl (0, F_SETOWN
, getpid ());
3660 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
3661 #endif /* ! defined (F_SETOWN) */
3665 #endif /* ! defined (SIGIO) */
3667 /* Must use interrupt input because we cannot otherwise
3668 arrange for C-g to be noticed immediately.
3669 We cannot connect it to SIGINT. */
3670 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
3672 expose_all_windows
= 0;
3674 clear_frame_hook
= XTclear_frame
;
3675 clear_end_of_line_hook
= XTclear_end_of_line
;
3676 ins_del_lines_hook
= XTins_del_lines
;
3677 change_line_highlight_hook
= XTchange_line_highlight
;
3678 insert_glyphs_hook
= XTinsert_glyphs
;
3679 write_glyphs_hook
= XTwrite_glyphs
;
3680 delete_glyphs_hook
= XTdelete_glyphs
;
3681 ring_bell_hook
= XTring_bell
;
3682 reset_terminal_modes_hook
= XTreset_terminal_modes
;
3683 set_terminal_modes_hook
= XTset_terminal_modes
;
3684 update_begin_hook
= XTupdate_begin
;
3685 update_end_hook
= XTupdate_end
;
3686 set_terminal_window_hook
= XTset_terminal_window
;
3687 read_socket_hook
= XTread_socket
;
3688 cursor_to_hook
= XTcursor_to
;
3689 reassert_line_highlight_hook
= XTreassert_line_highlight
;
3690 frame_rehighlight_hook
= XTframe_rehighlight
;
3691 mouse_position_hook
= XTmouse_position
;
3693 scroll_region_ok
= 1; /* we'll scroll partial frames */
3694 char_ins_del_ok
= 0; /* just as fast to write the line */
3695 line_ins_del_ok
= 1; /* we'll just blt 'em */
3696 fast_clear_end_of_line
= 1; /* X does this well */
3697 memory_below_frame
= 0; /* we don't remember what scrolls
3701 /* Note that there is no real way portable across R3/R4 to get the
3702 original error handler. */
3703 XHandleError (x_error_quitter
);
3704 XHandleIOError (x_error_quitter
);
3706 /* Disable Window Change signals; they are handled by X events. */
3708 signal (SIGWINCH
, SIG_DFL
);
3709 #endif /* ! defined (SIGWINCH) */
3711 signal (SIGPIPE
, x_connection_closed
);
3717 staticpro (&invocation_name
);
3718 invocation_name
= Qnil
;
3720 #endif /* ! defined (HAVE_X11) */
3721 #endif /* ! defined (HAVE_X_WINDOWS) */