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 these lose if they come 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. */
43 /* Load sys/types.h if not already loaded.
44 In some systems loading it twice is suicidal. */
46 #include <sys/types.h>
51 #include <sys/ioctl.h>
53 #else /* ! defined (BSD) */
54 #include <sys/termio.h>
56 #endif /* ! defined (BSD) */
58 /* Allow m- file to inhibit use of FIONREAD. */
59 #ifdef BROKEN_FIONREAD
61 #endif /* ! defined (BROKEN_FIONREAD) */
63 /* We are unable to use interrupts if FIONREAD is not available,
64 so flush SIGIO so we won't try. */
68 #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
))
1100 if (!f
->async_visible
)
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 /* Which modifier keys are on which modifier bits?
1433 With each keystroke, X returns eight bits indicating which modifier
1434 keys were held down when the key was pressed. The interpretation
1435 of the top five modifier bits depends on what keys are attached
1436 to them. If the Meta_L and Meta_R keysyms are on mod5, then mod5
1439 x_meta_mod_mask is a mask containing the bits used for the meta key.
1440 It may have more than one bit set, if more than one modifier bit
1441 has meta keys on it. Basically, if EVENT is a KeyPress event,
1442 the meta key is pressed if (EVENT.state & x_meta_mod_mask) != 0.
1444 x_shift_lock_mask is LockMask if the XK_Shift_Lock keysym is on the
1445 lock modifier bit, or zero otherwise. Non-alphabetic keys should
1446 only be affected by the lock modifier bit if XK_Shift_Lock is in
1447 use; XK_Caps_Lock should only affect alphabetic keys. With this
1448 arrangement, the lock modifier should shift the character if
1449 (EVENT.state & x_shift_lock_mask) != 0. */
1450 static int x_meta_mod_mask
, x_shift_lock_mask
;
1452 /* Initialize mode_switch_bit and modifier_meaning. */
1454 x_find_modifier_meanings ()
1456 int min_code
, max_code
;
1459 XModifierKeymap
*mods
;
1460 int alt_mod_mask
= 0;
1462 x_meta_mod_mask
= 0;
1463 x_shift_lock_mask
= 0;
1465 XDisplayKeycodes (x_current_display
, &min_code
, &max_code
);
1466 syms
= XGetKeyboardMapping (x_current_display
,
1467 min_code
, max_code
- min_code
+ 1,
1469 mods
= XGetModifierMapping (x_current_display
);
1471 /* Scan the modifier table to see which modifier bits the Meta and
1472 Alt keysyms are on. */
1474 int row
, col
; /* The row and column in the modifier table. */
1476 for (row
= 3; row
< 8; row
++)
1477 for (col
= 0; col
< mods
->max_keypermod
; col
++)
1480 mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
1482 /* Are any of this keycode's keysyms a meta key? */
1486 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
1488 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
1494 x_meta_mod_mask
|= (1 << row
);
1499 alt_mod_mask
|= (1 << row
);
1503 /* Ignore this if it's not on the lock modifier. */
1504 if ((1 << row
) == LockMask
)
1505 x_shift_lock_mask
= LockMask
;
1513 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
1514 if (! x_meta_mod_mask
)
1515 x_meta_mod_mask
= alt_mod_mask
;
1517 XFree ((char *) syms
);
1518 XFreeModifiermap (mods
);
1522 /* Convert a set of X modifier bits to the proper form for a
1523 struct input_event modifiers value. */
1526 x_convert_modifiers (state
)
1529 return ( ((state
& (ShiftMask
| x_shift_lock_mask
)) ? shift_modifier
: 0)
1530 | ((state
& ControlMask
) ? ctrl_modifier
: 0)
1531 | ((state
& x_meta_mod_mask
) ? meta_modifier
: 0));
1534 extern struct frame
*x_window_to_scrollbar ();
1535 extern Lisp_Object Vmouse_event
;
1537 /* Prepare a mouse-event in *RESULT for placement in the input queue.
1539 If the event is a button press, then note that we have grabbed
1542 If PART and PREFIX are 0, then the event occurred in the text part;
1543 otherwise it happened in a scrollbar. */
1546 construct_mouse_click (result
, event
, f
, part
, prefix
)
1547 struct input_event
*result
;
1548 XButtonEvent
*event
;
1553 /* Initialize those fields text and scrollbar clicks hold in common.
1554 Make the event type no_event; we'll change that when we decide
1556 result
->kind
= no_event
;
1557 XSET (result
->code
, Lisp_Int
, event
->button
);
1558 result
->timestamp
= event
->time
;
1559 result
->modifiers
= (x_convert_modifiers (event
->state
)
1560 | (event
->type
== ButtonRelease
1564 /* Notice if the mouse is still grabbed. */
1565 if (event
->type
== ButtonPress
)
1567 if (! x_mouse_grabbed
)
1568 Vmouse_depressed
= Qt
;
1569 x_mouse_grabbed
|= (1 << event
->button
);
1571 else if (event
->type
== ButtonRelease
)
1573 x_mouse_grabbed
&= ~(1 << event
->button
);
1574 if (!x_mouse_grabbed
)
1575 Vmouse_depressed
= Qnil
;
1578 if (! NILP (part
)) /* Scrollbar event */
1582 pos
= event
->y
- (f
->display
.x
->v_scrollbar_width
- 2);
1584 len
= ((FONT_HEIGHT (f
->display
.x
->font
) * f
->height
)
1585 + f
->display
.x
->internal_border_width
1586 - (2 * (f
->display
.x
->v_scrollbar_width
- 2)));
1589 result
->kind
= scrollbar_click
;
1590 result
->part
= part
;
1591 XSET (result
->x
, Lisp_Int
, (f
->display
.x
->top_pos
- event
->y
));
1592 XSET (result
->y
, Lisp_Int
, f
->display
.x
->pixel_height
);
1595 else /* Text Window Event */
1599 pixel_to_glyph_coords (f
, event
->x
, event
->y
, &column
, &row
, NULL
);
1600 result
->kind
= mouse_click
;
1601 XFASTINT (result
->x
) = column
;
1602 XFASTINT (result
->y
) = row
;
1608 /* Mouse movement. Rah.
1610 In order to avoid asking for motion events and then throwing most
1611 of them away or busy-polling the server for mouse positions, we ask
1612 the server for pointer motion hints. This means that we get only
1613 one event per group of mouse movements. "Groups" are delimited by
1614 other kinds of events (focus changes and button clicks, for
1615 example), or by XQueryPointer calls; when one of these happens, we
1616 get another MotionNotify event the next time the mouse moves. This
1617 is at least as efficient as getting motion events when mouse
1618 tracking is on, and I suspect only negligibly worse when tracking
1621 The silly O'Reilly & Associates Nutshell guides barely document
1622 pointer motion hints at all (I think you have to infer how they
1623 work from an example), and the description of XQueryPointer doesn't
1624 mention that calling it causes you to get another motion hint from
1625 the server, which is very important. */
1627 /* Where the mouse was last time we reported a mouse event. */
1628 static FRAME_PTR last_mouse_frame
;
1629 static XRectangle last_mouse_glyph
;
1631 /* This is a hack. We would really prefer that XTmouse_position would
1632 return the time associated with the position it returns, but there
1633 doesn't seem to be any way to wrest the timestamp from the server
1634 along with the position query. So, we just keep track of the time
1635 of the last movement we received, and return that in hopes that
1636 it's somewhat accurate. */
1637 static Time last_mouse_movement_time
;
1639 /* Function to report a mouse movement to the mainstream Emacs code.
1640 The input handler calls this.
1642 We have received a mouse movement event, which is given in *event.
1643 If the mouse is over a different glyph than it was last time, tell
1644 the mainstream emacs code by setting mouse_moved. If not, ask for
1645 another motion event, so we can check again the next time it moves. */
1647 note_mouse_position (frame
, event
)
1649 XMotionEvent
*event
;
1652 last_mouse_movement_time
= event
->time
;
1654 /* Has the mouse moved off the glyph it was on at the last sighting? */
1655 if (event
->x
< last_mouse_glyph
.x
1656 || event
->x
>= last_mouse_glyph
.x
+ last_mouse_glyph
.width
1657 || event
->y
< last_mouse_glyph
.y
1658 || event
->y
>= last_mouse_glyph
.y
+ last_mouse_glyph
.height
)
1662 /* It's on the same glyph. Call XQueryPointer so we'll get an
1663 event the next time the mouse moves and we can see if it's
1664 *still* on the same glyph. */
1667 XQueryPointer (event
->display
, event
->window
,
1668 (Window
*) &dummy
, (Window
*) &dummy
,
1669 &dummy
, &dummy
, &dummy
, &dummy
,
1670 (unsigned int *) &dummy
);
1674 /* Return the current position of the mouse.
1676 This clears the mouse_moved flag, so we can wait for the next mouse
1677 position. This also calls XQueryPointer, which will cause the
1678 server to give us another MotionNotify when the mouse moves again.
1682 XTmouse_position (f
, x
, y
, time
)
1685 unsigned long *time
;
1688 Display
*d
= x_current_display
;
1689 Window guess
, root
, child
;
1693 /* I would like to have an X function that just told me the
1694 innermost window containing the mouse.
1696 /* There doesn't seem to be any way to just get the innermost window
1697 containing the pointer, no matter what X frame it's on; you have
1698 to guess a window, and then X will tell you which one of that
1699 window's children it's in. If the pointer isn't in any of that
1700 window's children, it gives you a root window that contains it.
1702 So we start with the selected frame's window and chase down
1703 branches under the guidance of XQueryPointer until we hit a leaf
1704 (all of the Emacs windows we care about are leaf windows). If at
1705 any time XQueryPointer returns false, that means that the current
1706 window does not contain the pointer any more (perhaps it moved),
1707 so we start with the root window XQueryPointer has given us and
1710 guess
= FRAME_X_WINDOW (selected_frame
);
1712 if (XQueryPointer (d
, guess
, &root
, &child
,
1713 &dummy
, &dummy
, &ix
, &iy
, (unsigned int *) &dummy
))
1716 /* Guess is a leaf window, and it contains the pointer. */
1722 /* When XQueryPointer returns False, the pointer isn't in guess
1723 anymore, but root is the root window of the frame we should
1727 *f
= last_mouse_frame
= x_window_to_frame (guess
);
1732 pixel_to_glyph_coords (*f
, ix
, iy
, &ix
, &iy
, &last_mouse_glyph
);
1733 XSET (*x
, Lisp_Int
, ix
);
1734 XSET (*y
, Lisp_Int
, iy
);
1739 /* I don't know how to find the time for the last movement; it seems
1740 like XQueryPointer ought to return it, but it doesn't. So, we'll
1741 return the time of the last MotionNotify event we received. Note
1742 that the use of motion hints means that this isn't guaranteed to
1743 be accurate at all. */
1744 *time
= last_mouse_movement_time
;
1749 #else /* ! defined (HAVE_X11) */
1750 #define XEvent XKeyPressedEvent
1751 #endif /* ! defined (HAVE_X11) */
1754 /* Timestamp of enter window event. This is only used by XTread_socket,
1755 but we have to put it out here, since static variables within functions
1756 sometimes don't work. */
1757 static Time enter_timestamp
;
1759 /* This holds the state XLookupString needs to implement dead keys
1760 and other tricks known as "compose processing". _X Window System_
1761 says that a portable program can't use this, but Stephen Gildea assures
1762 me that letting the compiler initialize it to zeros will work okay.
1764 This must be defined outside of XTread_socket, for the same reasons
1765 given for enter_timestamp, above. */
1766 static XComposeStatus compose_status
;
1768 /* Communication with window managers. */
1769 Atom Xatom_wm_protocols
;
1771 /* Kinds of protocol things we may receive. */
1772 Atom Xatom_wm_take_focus
;
1773 Atom Xatom_wm_save_yourself
;
1774 Atom Xatom_wm_delete_window
;
1776 /* Other WM communication */
1777 Atom Xatom_wm_configure_denied
; /* When our config request is denied */
1778 Atom Xatom_wm_window_moved
; /* When the WM moves us. */
1780 /* Read events coming from the X server.
1781 This routine is called by the SIGIO handler.
1782 We return as soon as there are no more events to be read.
1784 Events representing keys are stored in buffer BUFP,
1785 which can hold up to NUMCHARS characters.
1786 We return the number of characters stored into the buffer,
1787 thus pretending to be `read'.
1789 WAITP is nonzero if we should block until input arrives.
1790 EXPECTED is nonzero if the caller knows input is available. */
1793 XTread_socket (sd
, bufp
, numchars
, waitp
, expected
)
1795 register struct input_event
*bufp
;
1796 register int numchars
;
1803 int items_pending
; /* How many items are in the X queue. */
1810 if (x_input_blocked
)
1812 x_pending_input
= 1;
1816 x_pending_input
= 0;
1820 abort (); /* Don't think this happens. */
1823 /* If available, Xlib uses FIOSNBIO to make the socket
1824 non-blocking, and then looks for EWOULDBLOCK. If O_NDELAY is set,
1825 FIOSNBIO is ignored, and instead of signalling EWOULDBLOCK,
1826 a read returns 0, which Xlib interprets as equivalent to EPIPE. */
1827 fcntl (fileno (stdin
), F_SETFL
, 0);
1828 #endif /* ! defined (FIOSNBIO) */
1832 if (! (fcntl (fileno (stdin
), F_GETFL
, 0) & O_NDELAY
))
1834 extern int read_alarm_should_throw
;
1835 read_alarm_should_throw
= 1;
1836 XPeekEvent (XDISPLAY
&event
);
1837 read_alarm_should_throw
= 0;
1839 #endif /* HAVE_SELECT */
1842 while (XStuffPending () != 0)
1844 XNextEvent (XDISPLAY
&event
);
1852 if (event
.xclient
.message_type
== Xatom_wm_protocols
1853 && event
.xclient
.format
== 32)
1855 if (event
.xclient
.data
.l
[0] == Xatom_wm_take_focus
)
1857 f
= x_window_to_frame (event
.xclient
.window
);
1859 x_focus_on_frame (f
);
1860 /* Not certain about handling scrollbars here */
1862 else if (event
.xclient
.data
.l
[0] == Xatom_wm_save_yourself
)
1864 /* Save state modify the WM_COMMAND property to
1865 something which can reinstate us. This notifies
1866 the session manager, who's looking for such a
1867 PropertyNotify. Can restart processing when
1868 a keyboard or mouse event arrives. */
1873 else if (event
.xclient
.data
.l
[0] == Xatom_wm_delete_window
)
1875 struct frame
*f
= x_window_to_frame (event
.xclient
.window
);
1883 else if (event
.xclient
.message_type
== Xatom_wm_configure_denied
)
1886 else if (event
.xclient
.message_type
== Xatom_wm_window_moved
)
1890 new_x
= event
.xclient
.data
.s
[0];
1891 new_y
= event
.xclient
.data
.s
[1];
1896 case SelectionClear
: /* Someone has grabbed ownership. */
1897 x_disown_selection (event
.xselectionclear
.window
,
1898 event
.xselectionclear
.selection
,
1899 event
.xselectionclear
.time
);
1902 case SelectionRequest
: /* Someone wants our selection. */
1903 x_answer_selection_request (event
);
1906 case PropertyNotify
:
1908 /* If we're being told about a root window property, then it's
1909 a cut buffer change. */
1910 if (event
.xproperty
.window
== ROOT_WINDOW
)
1911 x_invalidate_cut_buffer_cache (&event
.xproperty
);
1913 /* Otherwise, we're probably handling an incremental
1914 selection transmission. */
1917 /* If we were to do this synchronously, there'd be no worry
1918 about re-selecting. */
1919 x_send_incremental (event
);
1924 f
= x_window_to_frame (event
.xexpose
.window
);
1927 if (f
->async_visible
== 0)
1929 f
->async_visible
= 1;
1930 f
->async_iconified
= 0;
1931 SET_FRAME_GARBAGED (f
);
1934 dumprectangle (x_window_to_frame (event
.xexpose
.window
),
1935 event
.xexpose
.x
, event
.xexpose
.y
,
1936 event
.xexpose
.width
, event
.xexpose
.height
);
1940 case GraphicsExpose
: /* This occurs when an XCopyArea's
1941 source area was obscured or not
1943 dumprectangle (x_window_to_frame (event
.xgraphicsexpose
.drawable
),
1944 event
.xgraphicsexpose
.x
, event
.xgraphicsexpose
.y
,
1945 event
.xgraphicsexpose
.width
,
1946 event
.xgraphicsexpose
.height
);
1949 case NoExpose
: /* This occurs when an XCopyArea's
1950 source area was completely
1953 #else /* ! defined (HAVE_X11) */
1955 if (event
.subwindow
!= 0)
1956 break; /* duplicate event */
1957 f
= x_window_to_frame (event
.window
);
1958 if (event
.window
== f
->display
.x
->icon_desc
)
1961 f
->async_iconified
= 1;
1963 if (event
.window
== FRAME_X_WINDOW (f
))
1965 /* Say must check all windows' needs_exposure flags. */
1966 expose_all_windows
= 1;
1967 f
->display
.x
->needs_exposure
= 1;
1968 f
->async_visible
= 1;
1973 if (event
.subwindow
!= 0)
1974 break; /* duplicate event */
1975 f
= x_window_to_frame (event
.window
);
1976 if (event
.window
== f
->display
.x
->icon_desc
)
1981 /* If window already needs full redraw, ignore this rectangle. */
1982 if (expose_all_windows
&& f
->display
.x
->needs_exposure
)
1984 /* Put the event on the queue of rectangles to redraw. */
1985 if (enqueue_event (&event
, &x_expose_queue
))
1986 /* If it is full, we can't record the rectangle,
1987 so redraw this entire window. */
1989 /* Say must check all windows' needs_exposure flags. */
1990 expose_all_windows
= 1;
1991 f
->display
.x
->needs_exposure
= 1;
1996 /* This should happen only when we are expecting it,
1997 in x_read_exposes. */
1999 #endif /* ! defined (HAVE_X11) */
2006 f
= x_window_to_frame (event
.xunmap
.window
);
2007 if (f
) /* F may no longer exist if
2008 the frame was deleted. */
2010 /* While a frame is unmapped, display generation is
2011 disabled; you don't want to spend time updating a
2012 display that won't ever be seen. */
2013 f
->async_visible
= 0;
2014 x_mouse_x
= x_mouse_y
= -1;
2020 f
= x_window_to_frame (event
.xmap
.window
);
2023 f
->async_visible
= 1;
2024 f
->async_iconified
= 0;
2026 /* wait_reading_process_input will notice this and update
2027 the frame's display structures. */
2028 SET_FRAME_GARBAGED (f
);
2032 /* Turn off processing if we become fully obscured. */
2033 case VisibilityNotify
:
2036 #else /* ! defined (HAVE_X11) */
2038 f
= x_window_to_frame (event
.window
);
2039 if (event
.window
== f
->display
.x
->icon_desc
)
2040 f
->async_iconified
= 0;
2041 if (event
.window
== FRAME_X_WINDOW (f
))
2042 f
->async_visible
= 0;
2044 #endif /* ! defined (HAVE_X11) */
2048 f
= x_window_to_frame (event
.xkey
.window
);
2052 char copy_buffer
[80];
2053 int modifiers
= event
.xkey
.state
;
2055 /* Some keyboards generate different characters
2056 depending on the state of the meta key, in an attempt
2057 to support non-English typists. It would be nice to
2058 keep this functionality somehow, but for now, we will
2059 just clear the meta-key flag to get the 'pure' character. */
2060 event
.xkey
.state
&= ~Mod1Mask
;
2062 /* This will have to go some day... */
2064 XLookupString (&event
.xkey
, copy_buffer
, 80, &keysym
,
2067 /* Strip off the vendor-specific keysym bit, and take a shot
2068 at recognizing the codes. HP servers have extra keysyms
2069 that fit into the MiscFunctionKey category. */
2074 if (IsCursorKey (keysym
) /* 0xff50 <= x < 0xff60 */
2075 || IsMiscFunctionKey (keysym
) /* 0xff60 <= x < 0xff80 */
2076 || IsKeypadKey (keysym
) /* 0xff80 <= x < 0xffbe */
2077 || IsFunctionKey (keysym
)) /* 0xffbe <= x < 0xffe1 */
2079 bufp
->kind
= non_ascii_keystroke
;
2080 XSET (bufp
->code
, Lisp_Int
, (unsigned) keysym
- 0xff50);
2082 bufp
->modifiers
= x_convert_modifiers (modifiers
);
2083 bufp
->timestamp
= event
.xkey
.time
;
2088 else if (numchars
> nbytes
)
2094 if (modifiers
& x_meta_mod_mask
)
2095 *copy_buffer
|= METABIT
;
2096 bufp
->kind
= ascii_keystroke
;
2097 XSET (bufp
->code
, Lisp_Int
, *copy_buffer
);
2099 bufp
->timestamp
= event
.xkey
.time
;
2103 for (i
= nbytes
- 1; i
> 1; i
--)
2105 bufp
->kind
= ascii_keystroke
;
2106 XSET (bufp
->code
, Lisp_Int
, copy_buffer
[i
]);
2108 bufp
->timestamp
= event
.xkey
.time
;
2118 #else /* ! defined (HAVE_X11) */
2121 register char *where_mapping
;
2123 f
= x_window_to_frame (event
.window
);
2124 /* Ignore keys typed on icon windows. */
2125 if (f
!= 0 && event
.window
== f
->display
.x
->icon_desc
)
2127 where_mapping
= XLookupMapping (&event
, &nbytes
);
2128 /* Nasty fix for arrow keys */
2129 if (!nbytes
&& IsCursorKey (event
.detail
& 0xff))
2131 switch (event
.detail
& 0xff)
2133 case KC_CURSOR_LEFT
:
2134 where_mapping
= "\002";
2136 case KC_CURSOR_RIGHT
:
2137 where_mapping
= "\006";
2140 where_mapping
= "\020";
2142 case KC_CURSOR_DOWN
:
2143 where_mapping
= "\016";
2148 if (numchars
- nbytes
> 0)
2152 for (i
= 0; i
< nbytes
; i
++)
2154 bufp
->kind
= ascii_keystroke
;
2155 XSET (bufp
->code
, Lisp_Int
, where_mapping
[i
]);
2156 XSET (bufp
->time
, Lisp_Int
, event
.xkey
.time
);
2165 #endif /* ! defined (HAVE_X11) */
2169 f
= x_window_to_frame (event
.xcrossing
.window
);
2171 if (event
.xcrossing
.detail
== NotifyInferior
) /* Left Scrollbar */
2173 else if (event
.xcrossing
.focus
) /* Entered Window */
2175 /* If we decide we want to generate an event to be seen
2176 by the rest of Emacs, we put it here. */
2177 struct input_event emacs_event
;
2178 emacs_event
.kind
= no_event
;
2180 /* Avoid nasty pop/raise loops. */
2181 if (f
&& (!(f
->auto_raise
)
2183 || (event
.xcrossing
.time
- enter_timestamp
) > 500))
2185 x_new_focus_frame (f
);
2186 enter_timestamp
= event
.xcrossing
.time
;
2189 else if ((f
= x_window_to_scrollbar (event
.xcrossing
.window
,
2191 /* Fake a motion event */
2192 notice_mouse_movement (&emacs_event
,
2193 event
.xmotion
, f
, scrollbar_window
,
2198 if (! EQ (Vx_send_mouse_movement_events
, Qnil
)
2200 && emacs_event
.kind
!= no_event
)
2202 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
2209 else if (f
== x_focus_frame
)
2210 x_new_focus_frame (0);
2212 else if (f
= x_window_to_frame (event
.xcrossing
.window
))
2219 f
= x_window_to_frame (event
.xfocus
.window
);
2221 x_new_focus_frame (f
);
2225 if (event
.xcrossing
.detail
!= NotifyInferior
2226 && event
.xcrossing
.subwindow
== None
2227 && event
.xcrossing
.mode
== NotifyNormal
)
2229 f
= x_window_to_frame (event
.xcrossing
.window
);
2231 if (event
.xcrossing
.focus
)
2232 x_new_focus_frame (f
);
2233 else if (f
== x_focus_frame
)
2234 x_new_focus_frame (0);
2239 f
= x_window_to_frame (event
.xfocus
.window
);
2240 if (f
&& f
== x_focus_frame
)
2241 x_new_focus_frame (0);
2244 #else /* ! defined (HAVE_X11) */
2247 if ((event
.detail
& 0xFF) == 1)
2248 break; /* Coming from our own subwindow */
2249 if (event
.subwindow
!= 0)
2250 break; /* Entering our own subwindow. */
2253 f
= x_window_to_frame (event
.window
);
2256 x_new_focus_frame (f
);
2261 if ((event
.detail
& 0xFF) == 1)
2262 break; /* Entering our own subwindow */
2263 if (event
.subwindow
!= 0)
2264 break; /* Leaving our own subwindow. */
2267 if (x_focus_frame
== 0
2268 && x_input_frame
!= 0
2269 && x_input_frame
== x_window_to_frame (event
.window
)
2270 && event
.window
== FRAME_X_WINDOW (x_input_frame
))
2275 frame_unhighlight (f
);
2278 #endif /* ! defined (HAVE_X11) */
2283 f
= x_window_to_frame (event
.xmotion
.window
);
2285 note_mouse_position (f
, &event
.xmotion
);
2287 else if ((f
= x_window_to_scrollbar (event
.xmotion
.window
,
2290 What should go here
?
2296 case ConfigureNotify
:
2299 f
= x_window_to_frame (event
.xconfigure
.window
);
2303 columns
= ((event
.xconfigure
.width
-
2304 (2 * f
->display
.x
->internal_border_width
)
2305 - f
->display
.x
->v_scrollbar_width
)
2306 / FONT_WIDTH (f
->display
.x
->font
));
2307 rows
= ((event
.xconfigure
.height
-
2308 (2 * f
->display
.x
->internal_border_width
)
2309 - f
->display
.x
->h_scrollbar_height
)
2310 / FONT_HEIGHT (f
->display
.x
->font
));
2312 /* Even if the number of character rows and columns has
2313 not changed, the font size may have changed, so we need
2314 to check the pixel dimensions as well. */
2315 if (columns
!= f
->width
2316 || rows
!= f
->height
2317 || event
.xconfigure
.width
!= f
->display
.x
->pixel_width
2318 || event
.xconfigure
.height
!= f
->display
.x
->pixel_height
)
2320 change_frame_size (f
, rows
, columns
, 0, 1);
2321 x_resize_scrollbars (f
);
2322 SET_FRAME_GARBAGED (f
);
2325 f
->display
.x
->pixel_width
= event
.xconfigure
.width
;
2326 f
->display
.x
->pixel_height
= event
.xconfigure
.height
;
2327 f
->display
.x
->left_pos
= event
.xconfigure
.x
;
2328 f
->display
.x
->top_pos
= event
.xconfigure
.y
;
2335 /* If we decide we want to generate an event to be seen
2336 by the rest of Emacs, we put it here. */
2337 struct input_event emacs_event
;
2338 emacs_event
.kind
= no_event
;
2340 f
= x_window_to_frame (event
.xbutton
.window
);
2342 if (!x_focus_frame
|| (f
== x_focus_frame
))
2343 construct_mouse_click (&emacs_event
,
2344 &event
, f
, Qnil
, 0);
2348 if ((f
= x_window_to_scrollbar (event
.xbutton
.window
,
2351 if (!x_focus_frame
|| (selected_frame
== x_focus_frame
))
2352 construct_mouse_click (&emacs_event
,
2353 &event
, f
, part
, prefix
);
2358 if (numchars
>= 1 && emacs_event
.kind
!= no_event
)
2360 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
2368 #else /* ! defined (HAVE_X11) */
2370 case ButtonReleased
:
2371 f
= x_window_to_frame (event
.window
);
2374 if (event
.window
== f
->display
.x
->icon_desc
)
2376 x_make_frame_visible (f
);
2378 if (warp_mouse_on_deiconify
)
2379 XWarpMouse (FRAME_X_WINDOW (f
), 10, 10);
2382 if (event
.window
== FRAME_X_WINDOW (f
))
2388 enqueue_event (&event
, &x_mouse_queue
);
2391 bufp
->kind
= ascii_keystroke
;
2392 bufp
->code
= (char) 'X' & 037; /* C-x */
2394 XSET (bufp
->time
, Lisp_Int
, event
.xkey
.time
);
2397 bufp
->kind
= ascii_keystroke
;
2398 bufp
->code
= (char) 0; /* C-@ */
2400 XSET (bufp
->time
, Lisp_Int
, event
.xkey
.time
);
2407 #endif /* ! defined (HAVE_X11) */
2411 case CirculateNotify
:
2413 case CirculateRequest
:
2416 #endif /* ! defined (HAVE_X11) */
2419 /* Someone has changed the keyboard mapping - update the
2421 switch (event
.xmapping
.request
)
2423 case MappingModifier
:
2424 x_find_modifier_meanings ();
2425 /* This is meant to fall through. */
2426 case MappingKeyboard
:
2427 XRefreshKeyboardMapping (&event
.xmapping
);
2438 if (expected
&& ! event_found
)
2440 /* AOJ 880406: if select returns true but XPending doesn't, it means that
2441 there is an EOF condition; in other words, that X has died.
2442 Act as if there had been a hangup. */
2444 int fd
= ConnectionNumber (x_current_display
);
2447 if (0 != select (fd
+ 1, &mask
, (long *) 0, (long *) 0,
2449 && !XStuffPending ())
2450 kill (getpid (), SIGHUP
);
2452 #endif /* ! defined (HAVE_SELECT) */
2455 if (updating_frame
== 0)
2456 x_do_pending_expose ();
2463 /* Read and process only Expose events
2464 until we get an ExposeCopy event; then return.
2465 This is used in insert/delete line.
2466 We assume input is already blocked. */
2472 XKeyPressedEvent event
;
2476 /* while there are more events*/
2477 XMaskEvent (ExposeWindow
| ExposeRegion
| ExposeCopy
, &event
);
2481 if (event
.subwindow
!= 0)
2482 break; /* duplicate event */
2483 f
= x_window_to_frame (event
.window
);
2484 if (event
.window
== f
->display
.x
->icon_desc
)
2489 if (event
.window
== FRAME_X_WINDOW (f
))
2491 expose_all_windows
= 1;
2492 f
->display
.x
->needs_exposure
= 1;
2498 if (event
.subwindow
!= 0)
2499 break; /* duplicate event */
2500 f
= x_window_to_frame (event
.window
);
2501 if (event
.window
== f
->display
.x
->icon_desc
)
2506 /* If window already needs full redraw, ignore this rectangle. */
2507 if (expose_all_windows
&& f
->display
.x
->needs_exposure
)
2509 /* Put the event on the queue of rectangles to redraw. */
2510 if (enqueue_event (&event
, &x_expose_queue
))
2511 /* If it is full, we can't record the rectangle,
2512 so redraw this entire window. */
2514 /* Say must check all windows' needs_exposure flags. */
2515 expose_all_windows
= 1;
2516 f
->display
.x
->needs_exposure
= 1;
2525 #endif /* HAVE_X11 */
2528 /* Draw a hollow box cursor. Don't change the inside of the box. */
2534 int left
= f
->cursor_x
* FONT_WIDTH (f
->display
.x
->font
)
2535 + f
->display
.x
->internal_border_width
;
2536 int top
= f
->cursor_y
* FONT_HEIGHT (f
->display
.x
->font
)
2537 + f
->display
.x
->internal_border_width
;
2538 int width
= FONT_WIDTH (f
->display
.x
->font
);
2539 int height
= FONT_HEIGHT (f
->display
.x
->font
);
2542 /* Perhaps we should subtract 1 from width and height... */
2543 XDrawRectangle (x_current_display
, FRAME_X_WINDOW (f
),
2544 f
->display
.x
->cursor_gc
,
2545 left
, top
, width
- 1, height
- 1);
2546 #else /* ! defined (HAVE_X11) */
2547 XPixSet (FRAME_X_WINDOW (f
),
2548 left
, top
, width
, 1,
2549 f
->display
.x
->cursor_pixel
);
2551 XPixSet (FRAME_X_WINDOW (f
),
2552 left
, top
, 1, height
,
2553 f
->display
.x
->cursor_pixel
);
2555 XPixSet (FRAME_X_WINDOW (f
),
2556 left
+width
-1, top
, 1, height
,
2557 f
->display
.x
->cursor_pixel
);
2559 XPixSet (FRAME_X_WINDOW (f
),
2560 left
, top
+height
-1, width
, 1,
2561 f
->display
.x
->cursor_pixel
);
2562 #endif /* ! defined (HAVE_X11) */
2565 /* Clear the cursor of frame F to background color,
2566 and mark the cursor as not shown.
2567 This is used when the text where the cursor is
2568 is about to be rewritten. */
2577 || f
->phys_cursor_x
< 0)
2581 x_display_cursor (f
, 0);
2583 XClearArea (x_current_display
, FRAME_X_WINDOW (f
),
2584 f
->phys_cursor_x
* FONT_WIDTH (f
->display
.x
->font
)
2585 + f
->display
.x
->internal_border_width
,
2586 f
->phys_cursor_y
* FONT_HEIGHT (f
->display
.x
->font
)
2587 + f
->display
.x
->internal_border_width
,
2588 FONT_WIDTH (f
->display
.x
->font
) + 1, FONT_HEIGHT (f
->display
.x
->font
) + 1, False
);
2590 #else /* ! defined (HAVE_X11) */
2591 XPixSet (FRAME_X_WINDOW (f
),
2592 f
->phys_cursor_x
* FONT_WIDTH (f
->display
.x
->font
) + f
->display
.x
->internal_border_width
,
2593 f
->phys_cursor_y
* FONT_HEIGHT (f
->display
.x
->font
) + f
->display
.x
->internal_border_width
,
2594 FONT_WIDTH (f
->display
.x
->font
), FONT_HEIGHT (f
->display
.x
->font
),
2595 f
->display
.x
->background_pixel
);
2596 #endif /* ! defined (HAVE_X11) */
2597 f
->phys_cursor_x
= -1;
2601 x_display_bar_cursor (f
, on
)
2605 register int phys_x
= f
->phys_cursor_x
;
2606 register int phys_y
= f
->phys_cursor_y
;
2611 if (! f
->visible
|| (! on
&& f
->phys_cursor_x
< 0))
2616 (!on
|| phys_x
!= f
->cursor_x
|| phys_y
!= f
->cursor_y
))
2618 x1
= phys_x
* FONT_WIDTH (f
->display
.x
->font
)
2619 + f
->display
.x
->internal_border_width
;
2620 y1
= phys_y
* FONT_HEIGHT (f
->display
.x
->font
)
2621 + f
->display
.x
->internal_border_width
- 1;
2622 y2
= y1
+ FONT_HEIGHT (f
->display
.x
->font
) + 1;
2624 XDrawLine (x_current_display
, FRAME_X_WINDOW (f
),
2625 f
->display
.x
->reverse_gc
, x1
, y1
, x1
, y2
);
2627 f
->phys_cursor_x
= phys_x
= -1;
2630 if (on
&& f
== x_highlight_frame
)
2632 x1
= f
->cursor_x
* FONT_WIDTH (f
->display
.x
->font
)
2633 + f
->display
.x
->internal_border_width
;
2634 y1
= f
->cursor_y
* FONT_HEIGHT (f
->display
.x
->font
)
2635 + f
->display
.x
->internal_border_width
- 1;
2636 y2
= y1
+ FONT_HEIGHT (f
->display
.x
->font
) + 1;
2638 XDrawLine (x_current_display
, FRAME_X_WINDOW (f
),
2639 f
->display
.x
->cursor_gc
, x1
, y1
, x1
, y2
);
2641 f
->phys_cursor_x
= f
->cursor_x
;
2642 f
->phys_cursor_y
= f
->cursor_y
;
2644 #else /* ! defined (HAVE_X11) */
2646 #endif /* ! defined (HAVE_X11) */
2650 /* Redraw the glyph at ROW, COLUMN on frame F, in the style
2651 HIGHLIGHT. HIGHLIGHT is as defined for dumpglyphs. Return the
2655 x_draw_single_glyph (f
, row
, column
, glyph
, highlight
)
2662 (column
* FONT_WIDTH (f
->display
.x
->font
)
2663 + f
->display
.x
->internal_border_width
),
2664 (row
* FONT_HEIGHT (f
->display
.x
->font
)
2665 + f
->display
.x
->internal_border_width
),
2666 &glyph
, 1, highlight
, f
->display
.x
->font
);
2669 /* Turn the displayed cursor of frame F on or off according to ON.
2670 If ON is nonzero, where to put the cursor is specified
2671 by F->cursor_x and F->cursor_y. */
2674 x_display_box_cursor (f
, on
)
2678 struct frame_glyphs
*current_glyphs
= FRAME_CURRENT_GLYPHS (f
);
2680 /* If we're not updating, then we want to use the current frame's
2681 cursor position, not our local idea of where the cursor ought to be. */
2682 if (f
!= updating_frame
)
2684 curs_x
= FRAME_CURSOR_X (f
);
2685 curs_y
= FRAME_CURSOR_Y (f
);
2691 /* If cursor is off and we want it off, return quickly. */
2692 if (!on
&& f
->phys_cursor_x
< 0)
2695 /* If cursor is currently being shown and we don't want it to be
2696 or it is in the wrong place,
2697 or we want a hollow box and it's not so, (pout!)
2699 if (f
->phys_cursor_x
>= 0
2701 || f
->phys_cursor_x
!= curs_x
2702 || f
->phys_cursor_y
!= curs_y
2703 || (f
->display
.x
->text_cursor_kind
!= hollow_box_cursor
2704 && (f
!= x_highlight_frame
))))
2706 /* Erase the cursor by redrawing the character underneath it. */
2707 x_draw_single_glyph (f
, f
->phys_cursor_y
, f
->phys_cursor_x
,
2708 f
->phys_cursor_glyph
,
2709 current_glyphs
->highlight
[f
->phys_cursor_y
]);
2710 f
->phys_cursor_x
= -1;
2713 /* If we want to show a cursor,
2714 or we want a box cursor and it's not so,
2715 write it in the right place. */
2717 && (f
->phys_cursor_x
< 0
2718 || (f
->display
.x
->text_cursor_kind
!= filled_box_cursor
2719 && f
== x_highlight_frame
)))
2721 f
->phys_cursor_glyph
2722 = ((current_glyphs
->enable
[curs_y
]
2723 && curs_x
< current_glyphs
->used
[curs_y
])
2724 ? current_glyphs
->glyphs
[curs_y
][curs_x
]
2726 if (f
!= x_highlight_frame
)
2729 f
->display
.x
->text_cursor_kind
= hollow_box_cursor
;
2733 x_draw_single_glyph (f
, curs_y
, curs_x
,
2734 f
->phys_cursor_glyph
, 2);
2735 f
->display
.x
->text_cursor_kind
= filled_box_cursor
;
2738 f
->phys_cursor_x
= curs_x
;
2739 f
->phys_cursor_y
= curs_y
;
2742 if (updating_frame
!= f
)
2746 extern Lisp_Object Vbar_cursor
;
2748 x_display_cursor (f
, on
)
2752 if (EQ (Vbar_cursor
, Qnil
))
2753 x_display_box_cursor (f
, on
);
2755 x_display_bar_cursor (f
, on
);
2760 /* Refresh bitmap kitchen sink icon for frame F
2761 when we get an expose event for it. */
2767 /* Normally, the window manager handles this function. */
2768 #else /* ! defined (HAVE_X11) */
2771 if (f
->display
.x
->icon_bitmap_flag
)
2772 XBitmapBitsPut (f
->display
.x
->icon_desc
, 0, 0, sink_width
, sink_height
,
2773 sink_bits
, BlackPixel
, WHITE_PIX_DEFAULT
,
2774 icon_bitmap
, GXcopy
, AllPlanes
);
2777 extern struct frame
*selected_frame
;
2778 struct Lisp_String
*str
;
2779 unsigned char *string
;
2782 = XSTRING (XBUFFER (XWINDOW (f
->selected_window
)->buffer
)->name
)->data
;
2784 if (f
->display
.x
->icon_label
!= string
)
2786 f
->display
.x
->icon_label
= string
;
2787 XChangeWindow (f
->display
.x
->icon_desc
,
2788 XQueryWidth (string
, icon_font_info
->id
) + 10,
2789 icon_font_info
->height
+ 10);
2792 XText (f
->display
.x
->icon_desc
, 5, 5, string
,
2793 str
->size
, icon_font_info
->id
,
2794 BLACK_PIX_DEFAULT
, WHITE_PIX_DEFAULT
);
2797 #endif /* ! defined (HAVE_X11) */
2800 /* Make the x-window of frame F use the kitchen-sink icon
2801 that's a window generated by Emacs. */
2810 if (FRAME_X_WINDOW (f
) == 0)
2815 XFreePixmap (x_current_display
, icon_bitmap
);
2818 XCreateBitmapFromData (x_current_display
, FRAME_X_WINDOW (f
),
2819 gnu_bits
, gnu_width
, gnu_height
);
2820 x_wm_set_icon_pixmap (f
, icon_bitmap
);
2821 f
->display
.x
->icon_bitmap_flag
= 1;
2822 #else /* ! defined (HAVE_X11) */
2823 if (f
->display
.x
->icon_desc
)
2825 XClearIconWindow (FRAME_X_WINDOW (f
));
2826 XDestroyWindow (f
->display
.x
->icon_desc
);
2829 icon_window
= XCreateWindow (f
->display
.x
->parent_desc
,
2830 0, 0, sink_width
, sink_height
,
2831 2, WhitePixmap
, (Pixmap
) NULL
);
2833 if (icon_window
== 0)
2836 XSetIconWindow (FRAME_X_WINDOW (f
), icon_window
);
2837 XSelectInput (icon_window
, ExposeWindow
| UnmapWindow
);
2839 f
->display
.x
->icon_desc
= icon_window
;
2840 f
->display
.x
->icon_bitmap_flag
= 1;
2842 if (icon_bitmap
== 0)
2844 = XStoreBitmap (sink_mask_width
, sink_mask_height
, sink_mask_bits
);
2845 #endif /* ! defined (HAVE_X11) */
2851 /* Make the x-window of frame F use a rectangle with text. */
2854 x_text_icon (f
, icon_name
)
2862 char *X_DefaultValue
;
2866 #define WhitePixel 1
2867 #endif /* WhitePixel */
2870 #define BlackPixel 0
2871 #endif /* BlackPixel */
2872 #endif /* HAVE_X11 */
2874 if (FRAME_X_WINDOW (f
) == 0)
2877 if (icon_font_info
== 0)
2879 = XGetFont (XGetDefault (XDISPLAY
2880 (char *) XSTRING (invocation_name
)->data
,
2885 f
->display
.x
->icon_label
= icon_name
;
2887 if (! f
->display
.x
->icon_label
)
2888 f
->display
.x
->icon_label
= " *emacs* ";
2890 XSetIconName (x_current_display
, FRAME_X_WINDOW (f
),
2891 (char *) f
->display
.x
->icon_label
);
2893 f
->display
.x
->icon_bitmap_flag
= 0;
2894 x_wm_set_icon_pixmap (f
, 0);
2895 #else /* ! defined (HAVE_X11) */
2896 if (f
->display
.x
->icon_desc
)
2898 XClearIconWindow (XDISPLAY
FRAME_X_WINDOW (f
));
2899 XDestroyWindow (XDISPLAY f
->display
.x
->icon_desc
);
2903 f
->display
.x
->icon_label
= (unsigned char *) icon_name
;
2905 if (! f
->display
.x
->icon_label
)
2906 f
->display
.x
->icon_label
= XSTRING (f
->name
)->data
;
2908 width
= XStringWidth (f
->display
.x
->icon_label
, icon_font_info
, 0, 0);
2909 icon_window
= XCreateWindow (f
->display
.x
->parent_desc
,
2910 f
->display
.x
->left_pos
,
2911 f
->display
.x
->top_pos
,
2912 width
+ 10, icon_font_info
->height
+ 10,
2913 2, BlackPixmap
, WhitePixmap
);
2915 if (icon_window
== 0)
2918 XSetIconWindow (FRAME_X_WINDOW (f
), icon_window
);
2919 XSelectInput (icon_window
, ExposeWindow
| ExposeRegion
| UnmapWindow
| ButtonPressed
);
2921 f
->display
.x
->icon_desc
= icon_window
;
2922 f
->display
.x
->icon_bitmap_flag
= 0;
2923 f
->display
.x
->icon_label
= 0;
2924 #endif /* ! defined (HAVE_X11) */
2929 /* Handling X errors. */
2931 /* A handler for SIGPIPE, when it occurs on the X server's connection.
2932 This basically does an orderly shutdown of Emacs. */
2935 x_connection_closed ()
2940 Fkill_emacs (make_number (70));
2943 /* An X error handler which prints an error message and then kills Emacs.
2944 This is what's normally installed as Xlib's handler for protocol and
2947 x_error_quitter (display
, error
)
2953 /* Note that there is no real way portable across R3/R4 to get the
2954 original error handler. */
2956 XGetErrorText (display
, error
->error_code
, buf
, sizeof (buf
));
2957 fprintf (stderr
, "X protocol error: %s on protocol request %d\n",
2958 buf
, error
->request_code
);
2960 x_connection_closed ();
2963 /* A buffer for storing X error messages. */
2964 static char (*x_caught_error_message
)[200];
2966 /* An X error handler which stores the error message in
2967 x_caught_error_message. This is what's installed when
2968 x_catch_errors is in effect. */
2970 x_error_catcher (display
, error
)
2974 XGetErrorText (display
, error
->error_code
,
2975 *x_caught_error_message
, sizeof (*x_caught_error_message
));
2979 /* Begin trapping X errors.
2981 After calling this function, X protocol errors no longer cause
2982 Emacs to exit; instead, they are recorded in x_cfc_error_message.
2984 Calling x_check_errors signals an Emacs error if an X error has
2985 occurred since the last call to x_catch_errors or x_check_errors.
2987 Calling x_uncatch_errors resumes the normal error handling. */
2989 void x_catch_errors(), x_check_errors (), x_uncatch_errors ();
2994 /* Make sure any errors from previous requests have been dealt with. */
2995 XSync (x_current_display
, False
);
2997 /* Set up the error buffer. */
2998 x_caught_error_message
=
2999 (char (*)[]) xmalloc (sizeof (*x_caught_error_message
));
3000 (*x_caught_error_message
)[0] = '\0';
3002 /* Install our little error handler. */
3003 XHandleError (x_error_catcher
);
3006 /* If any X protocol errors have arrived since the last call to
3007 x_catch_errors or x_check_errors, signal an Emacs error using
3008 sprintf (a buffer, FORMAT, the x error message text) as the text. */
3010 x_check_errors (format
)
3013 /* Make sure to catch any errors incurred so far. */
3014 XSync (x_current_display
, False
);
3016 if ((*x_caught_error_message
)[0])
3020 sprintf (buf
, format
, *x_caught_error_message
);
3021 free (x_caught_error_message
);
3023 x_uncatch_errors ();
3031 free (x_caught_error_message
);
3032 XHandleError (x_error_quitter
);
3036 static unsigned int x_wire_count
;
3039 fprintf (stderr
, "Lib call: %d\n", ++x_wire_count
);
3044 /* Set the font of the x-window specified by frame F
3045 to the font named NEWNAME. This is safe to use
3046 even before F has an actual x-window. */
3050 /* A table of all the fonts we have already loaded. */
3051 static XFontStruct
**x_font_table
;
3053 /* The current capacity of x_font_table. */
3054 static int x_font_table_size
;
3056 /* The number of fonts actually stored in x_font_table.
3057 x_font_table[n] is used and valid iff 0 <= n < n_fonts.
3058 0 <= n_fonts <= x_font_table_size. */
3061 x_new_font (f
, fontname
)
3063 register char *fontname
;
3067 int n_matching_fonts
;
3068 XFontStruct
*font_info
;
3071 /* Get a list of all the fonts that match this name. Once we
3072 have a list of matching fonts, we compare them against the fonts
3073 we already have by comparing font ids. */
3074 font_names
= (char **) XListFontsWithInfo (x_current_display
, fontname
,
3075 1024, &n_matching_fonts
,
3077 /* If the server couldn't find any fonts whose named matched fontname,
3078 return an error code. */
3079 if (n_matching_fonts
== 0)
3082 /* See if we've already loaded a matching font. */
3087 for (i
= 0; i
< n_fonts
; i
++)
3088 for (j
= 0; j
< n_matching_fonts
; j
++)
3089 if (x_font_table
[i
]->fid
== font_info
[j
].fid
)
3097 /* If we have, just return it from the table. */
3099 f
->display
.x
->font
= x_font_table
[already_loaded
];
3101 /* Otherwise, load the font and add it to the table. */
3106 font
= (XFontStruct
*) XLoadQueryFont (x_current_display
, fontname
);
3110 /* Do we need to create the table? */
3111 if (x_font_table_size
== 0)
3113 x_font_table_size
= 16;
3115 = (XFontStruct
**) xmalloc (x_font_table_size
3116 * sizeof (x_font_table
[0]));
3118 /* Do we need to grow the table? */
3119 else if (n_fonts
>= x_font_table_size
)
3121 x_font_table_size
*= 2;
3123 = (XFontStruct
**) xrealloc (x_font_table
,
3125 * sizeof (x_font_table
[0])));
3128 f
->display
.x
->font
= x_font_table
[n_fonts
++] = font
;
3131 /* Free the information from XListFontsWithInfo. The data
3132 we actually retain comes from XLoadQueryFont. */
3133 XFreeFontInfo (font_names
, font_info
, n_matching_fonts
);
3135 /* Now make the frame display the given font. */
3136 if (FRAME_X_WINDOW (f
) != 0)
3138 XSetFont (x_current_display
, f
->display
.x
->normal_gc
,
3139 f
->display
.x
->font
->fid
);
3140 XSetFont (x_current_display
, f
->display
.x
->reverse_gc
,
3141 f
->display
.x
->font
->fid
);
3142 XSetFont (x_current_display
, f
->display
.x
->cursor_gc
,
3143 f
->display
.x
->font
->fid
);
3145 x_set_window_size (f
, f
->width
, f
->height
);
3150 #else /* ! defined (HAVE_X11) */
3151 x_new_font (f
, newname
)
3153 register char *newname
;
3158 temp
= XGetFont (newname
);
3159 if (temp
== (FONT_TYPE
*) 0)
3162 if (f
->display
.x
->font
)
3163 XLoseFont (f
->display
.x
->font
);
3165 f
->display
.x
->font
= temp
;
3167 if (FRAME_X_WINDOW (f
) != 0)
3168 x_set_window_size (f
, f
->width
, f
->height
);
3172 #endif /* ! defined (HAVE_X11) */
3174 x_calc_absolute_position (f
)
3178 if (f
->display
.x
->left_pos
< 0)
3179 f
->display
.x
->left_pos
3180 = x_screen_width
- PIXEL_WIDTH (f
) + f
->display
.x
->left_pos
;
3182 if (f
->display
.x
->top_pos
< 0)
3183 f
->display
.x
->top_pos
3184 = x_screen_height
- PIXEL_HEIGHT (f
) + f
->display
.x
->top_pos
;
3185 #else /* ! defined (HAVE_X11) */
3186 WINDOWINFO_TYPE parentinfo
;
3188 XGetWindowInfo (FRAME_X_WINDOW (f
), &parentinfo
);
3190 if (f
->display
.x
->left_pos
< 0)
3191 f
->display
.x
->left_pos
= parentinfo
.width
+ (f
->display
.x
->left_pos
+ 1)
3192 - PIXEL_WIDTH (f
) - 2 * f
->display
.x
->internal_border_width
;
3194 if (f
->display
.x
->top_pos
< 0)
3195 f
->display
.x
->top_pos
= parentinfo
.height
+ (f
->display
.x
->top_pos
+ 1)
3196 - PIXEL_HEIGHT (f
) - 2 * f
->display
.x
->internal_border_width
;
3197 #endif /* ! defined (HAVE_X11) */
3200 x_set_offset (f
, xoff
, yoff
)
3202 register int xoff
, yoff
;
3204 f
->display
.x
->top_pos
= yoff
;
3205 f
->display
.x
->left_pos
= xoff
;
3206 x_calc_absolute_position (f
);
3209 XMoveWindow (XDISPLAY
FRAME_X_WINDOW (f
),
3210 f
->display
.x
->left_pos
, f
->display
.x
->top_pos
);
3212 x_wm_set_size_hint (f
, 0);
3213 #endif /* ! defined (HAVE_X11) */
3217 /* Call this to change the size of frame F's x-window. */
3219 x_set_window_size (f
, cols
, rows
)
3223 int pixelwidth
, pixelheight
;
3225 int ibw
= f
->display
.x
->internal_border_width
;
3229 check_frame_size (f
, &rows
, &cols
);
3230 pixelwidth
= (cols
* FONT_WIDTH (f
->display
.x
->font
) + 2 * ibw
3231 + f
->display
.x
->v_scrollbar_width
);
3232 pixelheight
= (rows
* FONT_HEIGHT (f
->display
.x
->font
) + 2 * ibw
3233 + f
->display
.x
->h_scrollbar_height
);
3236 x_wm_set_size_hint (f
, 0);
3237 #endif /* ! defined (HAVE_X11) */
3238 XChangeWindowSize (FRAME_X_WINDOW (f
), pixelwidth
, pixelheight
);
3240 /* Now, strictly speaking, we can't be sure that this is accurate,
3241 but the window manager will get around to dealing with the size
3242 change request eventually, and we'll hear how it went when the
3243 ConfigureNotify event gets here. */
3244 FRAME_WIDTH (f
) = cols
;
3245 FRAME_WIDTH (f
) = rows
;
3246 PIXEL_WIDTH (f
) = pixelwidth
;
3247 PIXEL_HEIGHT (f
) = pixelheight
;
3254 x_set_resize_hint (f
)
3258 XSetResizeHint (FRAME_X_WINDOW (f
), 2 * f
->display
.x
->internal_border_width
,
3259 2 * f
->display
.x
->internal_border_width
,
3260 FONT_WIDTH (f
->display
.x
->font
), FONT_HEIGHT (f
->display
.x
->font
));
3262 #endif /* HAVE_X11 */
3265 x_set_mouse_position (f
, x
, y
)
3274 pix_x
= (FRAME_WIDTH (f
)
3275 * FONT_WIDTH (f
->display
.x
->font
)
3276 + 2 * f
->display
.x
->internal_border_width
3277 + f
->display
.x
->v_scrollbar_width
) / 2;
3279 pix_x
= x
* FONT_WIDTH (f
->display
.x
->font
) + 2; /* add 2 pixels to each
3280 dimension to move the
3285 pix_y
= (FRAME_HEIGHT (f
)
3286 * FONT_HEIGHT (f
->display
.x
->font
)
3287 + 2 * f
->display
.x
->internal_border_width
3288 + f
->display
.x
->h_scrollbar_height
) / 2;
3290 pix_y
= y
* FONT_HEIGHT (f
->display
.x
->font
) + 2;
3296 XWarpMousePointer (FRAME_X_WINDOW (f
), pix_x
, pix_y
);
3301 x_focus_on_frame (f
)
3306 /* I don't think that the ICCCM allows programs to do things like this
3307 without the interaction of the window manager. Whatever you end up
3308 doing with this code, do it to x_unfocus_frame too. */
3309 XSetInputFocus (x_current_display
, FRAME_X_WINDOW (f
),
3310 RevertToPointerRoot
, CurrentTime
);
3318 /* Look at the remarks in x_focus_on_frame. */
3319 if (x_focus_frame
== f
)
3320 XSetInputFocus (x_current_display
, PointerRoot
,
3321 RevertToPointerRoot
, CurrentTime
);
3325 #endif /* ! defined (HAVE_X11) */
3327 /* Raise frame F. */
3332 if (f
->async_visible
)
3335 XRaiseWindow (XDISPLAY
FRAME_X_WINDOW (f
));
3341 /* Lower frame F. */
3346 if (f
->async_visible
)
3349 XLowerWindow (XDISPLAY
FRAME_X_WINDOW (f
));
3355 /* Change from withdrawn state to mapped state. */
3357 x_make_frame_visible (f
)
3364 if (! FRAME_VISIBLE_P (f
))
3367 if (! EQ (Vx_no_window_manager
, Qt
))
3368 x_wm_set_window_state (f
, NormalState
);
3370 XMapWindow (XDISPLAY
FRAME_X_WINDOW (f
));
3371 if (f
->display
.x
->v_scrollbar
!= 0 || f
->display
.x
->h_scrollbar
!= 0)
3372 XMapSubwindows (x_current_display
, FRAME_X_WINDOW (f
));
3373 #else /* ! defined (HAVE_X11) */
3374 XMapWindow (XDISPLAY
FRAME_X_WINDOW (f
));
3375 if (f
->display
.x
->icon_desc
!= 0)
3376 XUnmapWindow (f
->display
.x
->icon_desc
);
3378 /* Handled by the MapNotify event for X11 */
3379 f
->async_visible
= 1;
3380 f
->async_iconified
= 0;
3382 /* NOTE: this may cause problems for the first frame. */
3384 #endif /* ! defined (HAVE_X11) */
3392 /* Change from mapped state to withdrawn state. */
3394 x_make_frame_invisible (f
)
3399 if (! f
->async_visible
)
3406 if (! XWithdrawWindow (x_current_display
, FRAME_X_WINDOW (f
),
3407 DefaultScreen (x_current_display
)))
3409 UNBLOCK_INPUT_RESIGNAL
;
3410 error ("can't notify window manager of window withdrawl");
3413 #else /* ! defined (HAVE_X11R4) */
3416 /* Tell the window manager what we're going to do. */
3417 if (! EQ (Vx_no_window_manager
, Qt
))
3421 unmap
.xunmap
.type
= UnmapNotify
;
3422 unmap
.xunmap
.window
= FRAME_X_WINDOW (f
);
3423 unmap
.xunmap
.event
= DefaultRootWindow (x_current_display
);
3424 unmap
.xunmap
.from_configure
= False
;
3425 if (! XSendEvent (x_current_display
,
3426 DefaultRootWindow (x_current_display
),
3428 SubstructureRedirectMask
|SubstructureNotifyMask
,
3431 UNBLOCK_INPUT_RESIGNAL
;
3432 error ("can't notify window manager of withdrawal");
3436 /* Unmap the window ourselves. Cheeky! */
3437 XUnmapWindow (x_current_display
, FRAME_X_WINDOW (f
));
3439 #else /* ! defined (HAVE_X11) */
3441 XUnmapWindow (FRAME_X_WINDOW (f
));
3442 f
->async_visible
= 0; /* Handled by the UnMap event for X11 */
3443 if (f
->display
.x
->icon_desc
!= 0)
3444 XUnmapWindow (f
->display
.x
->icon_desc
);
3446 #endif /* ! defined (HAVE_X11) */
3447 #endif /* ! defined (HAVE_X11R4) */
3453 /* Window manager communication. Created in Fx_open_connection. */
3454 extern Atom Xatom_wm_change_state
;
3456 /* Change window state from mapped to iconified. */
3463 if (f
->async_iconified
)
3469 /* Since we don't know which revision of X we're running, we'll use both
3470 the X11R3 and X11R4 techniques. I don't know if this is a good idea. */
3472 /* X11R4: send a ClientMessage to the window manager using the
3473 WM_CHANGE_STATE type. */
3477 message
.xclient
.window
= FRAME_X_WINDOW (f
);
3478 message
.xclient
.type
= ClientMessage
;
3479 message
.xclient
.message_type
= Xatom_wm_change_state
;
3480 message
.xclient
.format
= 32;
3481 message
.xclient
.data
.l
[0] = IconicState
;
3483 if (! XSendEvent (x_current_display
,
3484 DefaultRootWindow (x_current_display
),
3486 SubstructureRedirectMask
| SubstructureNotifyMask
,
3489 UNBLOCK_INPUT_RESIGNAL
;
3490 error ("Can't notify window manager of iconification.");
3494 /* X11R3: set the initial_state field of the window manager hints to
3496 x_wm_set_window_state (f
, IconicState
);
3498 f
->async_iconified
= 1;
3499 #else /* ! defined (HAVE_X11) */
3500 XUnmapWindow (XDISPLAY
FRAME_X_WINDOW (f
));
3502 f
->async_visible
= 0; /* Handled in the UnMap event for X11. */
3503 if (f
->display
.x
->icon_desc
!= 0)
3505 XMapWindow (XDISPLAY f
->display
.x
->icon_desc
);
3508 #endif /* ! defined (HAVE_X11) */
3514 /* Destroy the X window of frame F.
3515 DISPL is the former f->display (since f->display
3516 has already been nulled out). */
3518 x_destroy_window (f
, displ
)
3520 union display displ
;
3525 if (displ
.x
->icon_desc
!= 0)
3526 XDestroyWindow (XDISPLAY displ
.x
->icon_desc
);
3527 XDestroyWindow (XDISPLAY displ
.x
->window_desc
);
3532 if (f
== x_focus_frame
)
3534 if (f
== x_highlight_frame
)
3535 x_highlight_frame
= 0;
3540 /* Manage event queues.
3542 This code is only used by the X10 support.
3544 We cannot leave events in the X queue and get them when we are ready
3545 because X does not provide a subroutine to get only a certain kind
3546 of event but not block if there are no queued events of that kind.
3548 Therefore, we must examine events as they come in and copy events
3549 of certain kinds into our private queues.
3551 All ExposeRegion events are put in x_expose_queue.
3552 All ButtonPressed and ButtonReleased events are put in x_mouse_queue. */
3555 /* Write the event *P_XREP into the event queue *QUEUE.
3556 If the queue is full, do nothing, but return nonzero. */
3559 enqueue_event (p_xrep
, queue
)
3560 register XEvent
*p_xrep
;
3561 register struct event_queue
*queue
;
3563 int newindex
= queue
->windex
+ 1;
3564 if (newindex
== EVENT_BUFFER_SIZE
)
3566 if (newindex
== queue
->rindex
)
3568 queue
->xrep
[queue
->windex
] = *p_xrep
;
3569 queue
->windex
= newindex
;
3573 /* Fetch the next event from queue *QUEUE and store it in *P_XREP.
3574 If *QUEUE is empty, do nothing and return 0. */
3577 dequeue_event (p_xrep
, queue
)
3578 register XEvent
*p_xrep
;
3579 register struct event_queue
*queue
;
3581 if (queue
->windex
== queue
->rindex
)
3583 *p_xrep
= queue
->xrep
[queue
->rindex
++];
3584 if (queue
->rindex
== EVENT_BUFFER_SIZE
)
3589 /* Return the number of events buffered in *QUEUE. */
3592 queue_event_count (queue
)
3593 register struct event_queue
*queue
;
3595 int tem
= queue
->windex
- queue
->rindex
;
3598 return EVENT_BUFFER_SIZE
+ tem
;
3601 /* Return nonzero if mouse input is pending. */
3604 mouse_event_pending_p ()
3606 return queue_event_count (&x_mouse_queue
);
3608 #endif /* HAVE_X11 */
3612 x_wm_set_size_hint (f
, prompting
)
3616 XSizeHints size_hints
;
3617 Window window
= FRAME_X_WINDOW (f
);
3619 size_hints
.flags
= PResizeInc
| PMinSize
| PMaxSize
;
3621 flexlines
= f
->height
;
3623 size_hints
.x
= f
->display
.x
->left_pos
;
3624 size_hints
.y
= f
->display
.x
->top_pos
;
3625 size_hints
.height
= PIXEL_HEIGHT (f
);
3626 size_hints
.width
= PIXEL_WIDTH (f
);
3627 size_hints
.width_inc
= FONT_WIDTH (f
->display
.x
->font
);
3628 size_hints
.height_inc
= FONT_HEIGHT (f
->display
.x
->font
);
3629 size_hints
.max_width
=
3630 (x_screen_width
- ((2 * f
->display
.x
->internal_border_width
)
3631 + f
->display
.x
->v_scrollbar_width
));
3632 size_hints
.max_height
=
3633 (x_screen_height
- ((2 * f
->display
.x
->internal_border_width
)
3634 + f
->display
.x
->h_scrollbar_height
));
3636 int base_width
, base_height
;
3638 base_width
= ((2 * f
->display
.x
->internal_border_width
)
3639 + f
->display
.x
->v_scrollbar_width
);
3640 base_height
= ((2 * f
->display
.x
->internal_border_width
)
3641 + f
->display
.x
->h_scrollbar_height
);
3644 int min_rows
= 0, min_cols
= 0;
3645 check_frame_size (f
, &min_rows
, &min_cols
);
3647 /* The window manager uses the base width hints to calculate the
3648 current number of rows and columns in the frame while
3649 resizing; min_width and min_height aren't useful for this
3650 purpose, since they might not give the dimensions for a
3651 zero-row, zero-column frame.
3653 We use the base_width and base_height members if we have
3654 them; otherwise, we set the min_width and min_height members
3655 to the size for a zero x zero frame. */
3658 size_hints
.flags
|= PBaseSize
;
3659 size_hints
.base_width
= base_width
;
3660 size_hints
.base_height
= base_height
;
3661 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
3662 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
3664 size_hints
.min_width
= base_width
;
3665 size_hints
.min_height
= base_height
;
3672 size_hints
.flags
|= prompting
;
3675 XSizeHints hints
; /* Sometimes I hate X Windows... */
3677 XGetNormalHints (x_current_display
, window
, &hints
);
3678 if (hints
.flags
& PSize
)
3679 size_hints
.flags
|= PSize
;
3680 if (hints
.flags
& PPosition
)
3681 size_hints
.flags
|= PPosition
;
3682 if (hints
.flags
& USPosition
)
3683 size_hints
.flags
|= USPosition
;
3684 if (hints
.flags
& USSize
)
3685 size_hints
.flags
|= USSize
;
3689 XSetWMNormalHints (x_current_display
, window
, &size_hints
);
3691 XSetNormalHints (x_current_display
, window
, &size_hints
);
3695 /* Used for IconicState or NormalState */
3696 x_wm_set_window_state (f
, state
)
3700 Window window
= FRAME_X_WINDOW (f
);
3702 f
->display
.x
->wm_hints
.flags
|= StateHint
;
3703 f
->display
.x
->wm_hints
.initial_state
= state
;
3705 XSetWMHints (x_current_display
, window
, &f
->display
.x
->wm_hints
);
3708 x_wm_set_icon_pixmap (f
, icon_pixmap
)
3712 Window window
= FRAME_X_WINDOW (f
);
3714 f
->display
.x
->wm_hints
.flags
|= IconPixmapHint
;
3715 f
->display
.x
->wm_hints
.icon_pixmap
= icon_pixmap
? icon_pixmap
: None
;
3717 XSetWMHints (x_current_display
, window
, &f
->display
.x
->wm_hints
);
3720 x_wm_set_icon_position (f
, icon_x
, icon_y
)
3724 Window window
= FRAME_X_WINDOW (f
);
3726 f
->display
.x
->wm_hints
.flags
|= IconPositionHint
;
3727 f
->display
.x
->wm_hints
.icon_x
= icon_x
;
3728 f
->display
.x
->wm_hints
.icon_y
= icon_y
;
3730 XSetWMHints (x_current_display
, window
, &f
->display
.x
->wm_hints
);
3735 x_term_init (display_name
)
3741 extern int old_fcntl_owner
;
3742 #endif /* ! defined (F_SETOWN) */
3744 x_focus_frame
= x_highlight_frame
= 0;
3746 x_current_display
= XOpenDisplay (display_name
);
3747 if (x_current_display
== 0)
3748 fatal ("X server %s not responding; check the DISPLAY environment variable or use \"-d\"\n",
3753 int hostname_size
= 256;
3755 hostname
= (char *) xmalloc (hostname_size
);
3758 XSetAfterFunction (x_current_display
, x_trace_wire
);
3761 invocation_name
= Ffile_name_nondirectory (Fcar (Vcommand_line_args
));
3763 /* Try to get the host name; if the buffer is too short, try
3764 again. Apparently, the only indication gethostname gives of
3765 whether the buffer was large enough is the presence or absence
3766 of a '\0' in the string. Eech. */
3769 gethostname (hostname
, hostname_size
- 1);
3770 hostname
[hostname_size
- 1] = '\0';
3772 /* Was the buffer large enough for gethostname to store the '\0'? */
3773 if (strlen (hostname
) < hostname_size
- 1)
3776 hostname_size
<<= 1;
3777 hostname
= (char *) xrealloc (hostname
, hostname_size
);
3779 x_id_name
= (char *) xmalloc (XSTRING (invocation_name
)->size
3782 sprintf (x_id_name
, "%s@%s", XSTRING (invocation_name
)->data
, hostname
);
3785 /* Figure out which modifier bits mean what. */
3786 x_find_modifier_meanings ();
3788 /* Watch for PropertyNotify events on the root window; we use them
3789 to figure out when to invalidate our cache of the cut buffers. */
3790 x_watch_cut_buffer_cache ();
3792 dup2 (ConnectionNumber (x_current_display
), 0);
3794 #ifndef SYSV_STREAMS
3795 /* Streams somehow keeps track of which descriptor number
3796 is being used to talk to X. So it is not safe to substitute
3797 descriptor 0. But it is safe to make descriptor 0 a copy of it. */
3798 close (ConnectionNumber (x_current_display
));
3799 ConnectionNumber (x_current_display
) = 0; /* Looks a little strange?
3800 * check the def of the macro;
3801 * it is a genuine lvalue */
3802 #endif /* SYSV_STREAMS */
3804 #endif /* ! defined (HAVE_X11) */
3807 old_fcntl_owner
= fcntl (0, F_GETOWN
, 0);
3808 #ifdef F_SETOWN_SOCK_NEG
3809 fcntl (0, F_SETOWN
, -getpid ()); /* stdin is a socket here */
3810 #else /* ! defined (F_SETOWN_SOCK_NEG) */
3811 fcntl (0, F_SETOWN
, getpid ());
3812 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
3813 #endif /* ! defined (F_SETOWN) */
3817 #endif /* ! defined (SIGIO) */
3819 /* Must use interrupt input because we cannot otherwise
3820 arrange for C-g to be noticed immediately.
3821 We cannot connect it to SIGINT. */
3822 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
3824 expose_all_windows
= 0;
3826 clear_frame_hook
= XTclear_frame
;
3827 clear_end_of_line_hook
= XTclear_end_of_line
;
3828 ins_del_lines_hook
= XTins_del_lines
;
3829 change_line_highlight_hook
= XTchange_line_highlight
;
3830 insert_glyphs_hook
= XTinsert_glyphs
;
3831 write_glyphs_hook
= XTwrite_glyphs
;
3832 delete_glyphs_hook
= XTdelete_glyphs
;
3833 ring_bell_hook
= XTring_bell
;
3834 reset_terminal_modes_hook
= XTreset_terminal_modes
;
3835 set_terminal_modes_hook
= XTset_terminal_modes
;
3836 update_begin_hook
= XTupdate_begin
;
3837 update_end_hook
= XTupdate_end
;
3838 set_terminal_window_hook
= XTset_terminal_window
;
3839 read_socket_hook
= XTread_socket
;
3840 cursor_to_hook
= XTcursor_to
;
3841 reassert_line_highlight_hook
= XTreassert_line_highlight
;
3842 frame_rehighlight_hook
= XTframe_rehighlight
;
3843 mouse_position_hook
= XTmouse_position
;
3845 scroll_region_ok
= 1; /* we'll scroll partial frames */
3846 char_ins_del_ok
= 0; /* just as fast to write the line */
3847 line_ins_del_ok
= 1; /* we'll just blt 'em */
3848 fast_clear_end_of_line
= 1; /* X does this well */
3849 memory_below_frame
= 0; /* we don't remember what scrolls
3853 /* Note that there is no real way portable across R3/R4 to get the
3854 original error handler. */
3855 XHandleError (x_error_quitter
);
3856 XHandleIOError (x_error_quitter
);
3858 /* Disable Window Change signals; they are handled by X events. */
3860 signal (SIGWINCH
, SIG_DFL
);
3861 #endif /* ! defined (SIGWINCH) */
3863 signal (SIGPIPE
, x_connection_closed
);
3869 staticpro (&invocation_name
);
3870 invocation_name
= Qnil
;
3872 #endif /* ! defined (HAVE_X11) */
3873 #endif /* ! defined (HAVE_X_WINDOWS) */