1 /* X Communication module for terminals which understand the X protocol.
2 Copyright (C) 1989, 93, 94, 95, 96, 1997, 1998, 1999
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* New display code by Gerd Moellmann <gerd@gnu.org>. */
23 /* Xt features made by Fred Pierresteguy. */
27 /* On 4.3 these lose if they come after xterm.h. */
28 /* Putting these at the beginning seems to be standard for other .c files. */
36 #include "blockinput.h"
38 /* Need syssignal.h for various externs and definitions that may be required
39 by some configurations for calls to signal later in this source file. */
40 #include "syssignal.h"
42 /* This may include sys/types.h, and that somehow loses
43 if this is not done before the other system files. */
45 #include <X11/cursorfont.h>
48 /* Load sys/types.h if not already loaded.
49 In some systems loading it twice is suicidal. */
51 #include <sys/types.h>
56 #include <sys/ioctl.h>
57 #endif /* ! defined (BSD_SYSTEM) */
62 #ifndef INCLUDED_FCNTL
69 /* Caused redefinition of DBL_DIG on Netbsd; seems not to be needed. */
70 /* #include <sys/param.h> */
76 #include "dispextern.h"
77 #include "termhooks.h"
89 #include "intervals.h"
93 #include <X11/Shell.h>
96 #include <sys/types.h>
97 #ifdef HAVE_SYS_TIME_H
106 extern void free_frame_menubar ();
107 extern FRAME_PTR
x_menubar_window_to_frame ();
109 #if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
111 extern void _XEditResCheckMessages ();
112 #endif /* not NO_EDITRES */
114 /* Include toolkit specific headers for the scroll bar widget. */
116 #ifdef USE_TOOLKIT_SCROLL_BARS
117 #if defined USE_MOTIF
118 #include <Xm/Xm.h> /* for LESSTIF_VERSION */
119 #include <Xm/ScrollBar.h>
120 #include <Xm/ScrollBarP.h>
121 #elif defined HAVE_XAW3D
122 #include <X11/Xaw3d/Simple.h>
123 #include <X11/Xaw3d/ThreeD.h>
124 #include <X11/Xaw3d/Scrollbar.h>
125 #define ARROW_SCROLLBAR
126 #include <X11/Xaw3d/ScrollbarP.h>
127 #endif /* HAVE_XAW3D */
128 #endif /* USE_TOOLKIT_SCROLL_BARS */
130 #endif /* USE_X_TOOLKIT */
132 #ifndef USE_X_TOOLKIT
133 #define x_any_window_to_frame x_window_to_frame
134 #define x_top_window_to_frame x_window_to_frame
139 #ifndef XtNinitialState
140 #define XtNinitialState "initialState"
145 /* memmove will be defined as a macro in Xfuncs.h unless
146 <string.h> is included beforehand. The declaration for memmove in
147 <string.h> will cause a syntax error when Xfuncs.h later includes it. */
152 #define min(a,b) ((a) < (b) ? (a) : (b))
155 #define max(a,b) ((a) > (b) ? (a) : (b))
158 #define abs(x) ((x) < 0 ? -(x) : (x))
160 #define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
163 /* Bitmaps for truncated lines. */
168 LEFT_TRUNCATION_BITMAP
,
169 RIGHT_TRUNCATION_BITMAP
,
170 OVERLAY_ARROW_BITMAP
,
171 CONTINUED_LINE_BITMAP
,
172 CONTINUATION_LINE_BITMAP
,
176 /* Bitmap drawn to indicate lines not displaying text if
177 `indicate-empty-lines' is non-nil. */
181 static unsigned char zv_bits
[] = {
182 0x00, 0x00, 0x1e, 0x1e, 0x1e, 0x1e, 0x00, 0x00};
184 /* An arrow like this: `<-'. */
187 #define left_height 8
188 static unsigned char left_bits
[] = {
189 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
191 /* Right truncation arrow bitmap `->'. */
193 #define right_width 8
194 #define right_height 8
195 static unsigned char right_bits
[] = {
196 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
198 /* Marker for continued lines. */
200 #define continued_width 8
201 #define continued_height 8
202 static unsigned char continued_bits
[] = {
203 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
205 /* Marker for continuation lines. */
207 #define continuation_width 8
208 #define continuation_height 8
209 static unsigned char continuation_bits
[] = {
210 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
212 /* Overlay arrow bitmap. */
218 static unsigned char ov_bits
[] = {
219 0x30, 0x08, 0x3c, 0x7e, 0x7a, 0x7a, 0x62, 0x3c};
221 /* A triangular arrow. */
224 static unsigned char ov_bits
[] = {
225 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
229 extern Lisp_Object Qhelp_echo
;
232 /* Non-zero means Emacs uses toolkit scroll bars. */
234 int x_toolkit_scroll_bars_p
;
236 /* If a string, XTread_socket generates an event to display that string.
237 (The display is done in read_char.) */
239 static Lisp_Object help_echo
;
241 /* Temporary variable for XTread_socket. */
243 static Lisp_Object previous_help_echo
;
245 /* Non-zero means that a HELP_EVENT has been generated since Emacs
248 static int any_help_event_p
;
250 /* Non-zero means draw block and hollow cursor as wide as the glyph
251 under it. For example, if a block cursor is over a tab, it will be
252 drawn as wide as that tab on the display. */
254 int x_stretch_cursor_p
;
256 /* This is a chain of structures for all the X displays currently in
259 struct x_display_info
*x_display_list
;
261 /* This is a list of cons cells, each of the form (NAME
262 . FONT-LIST-CACHE), one for each element of x_display_list and in
263 the same order. NAME is the name of the frame. FONT-LIST-CACHE
264 records previous values returned by x-list-fonts. */
266 Lisp_Object x_display_name_list
;
268 /* Frame being updated by update_frame. This is declared in term.c.
269 This is set by update_begin and looked at by all the XT functions.
270 It is zero while not inside an update. In that case, the XT
271 functions assume that `selected_frame' is the frame to apply to. */
273 extern struct frame
*updating_frame
;
275 extern int waiting_for_input
;
277 /* This is a frame waiting to be auto-raised, within XTread_socket. */
279 struct frame
*pending_autoraise_frame
;
282 /* The application context for Xt use. */
283 XtAppContext Xt_app_con
;
284 static String Xt_default_resources
[] = {0};
285 #endif /* USE_X_TOOLKIT */
287 /* Nominal cursor position -- where to draw output.
288 HPOS and VPOS are window relative glyph matrix coordinates.
289 X and Y are window relative pixel coordinates. */
291 struct cursor_pos output_cursor
;
296 Formerly, we used PointerMotionHintMask (in standard_event_mask)
297 so that we would have to call XQueryPointer after each MotionNotify
298 event to ask for another such event. However, this made mouse tracking
299 slow, and there was a bug that made it eventually stop.
301 Simply asking for MotionNotify all the time seems to work better.
303 In order to avoid asking for motion events and then throwing most
304 of them away or busy-polling the server for mouse positions, we ask
305 the server for pointer motion hints. This means that we get only
306 one event per group of mouse movements. "Groups" are delimited by
307 other kinds of events (focus changes and button clicks, for
308 example), or by XQueryPointer calls; when one of these happens, we
309 get another MotionNotify event the next time the mouse moves. This
310 is at least as efficient as getting motion events when mouse
311 tracking is on, and I suspect only negligibly worse when tracking
314 /* Where the mouse was last time we reported a mouse event. */
316 FRAME_PTR last_mouse_frame
;
317 static XRectangle last_mouse_glyph
;
318 static Lisp_Object last_mouse_press_frame
;
320 /* The scroll bar in which the last X motion event occurred.
322 If the last X motion event occurred in a scroll bar, we set this so
323 XTmouse_position can know whether to report a scroll bar motion or
326 If the last X motion event didn't occur in a scroll bar, we set
327 this to Qnil, to tell XTmouse_position to return an ordinary motion
330 static Lisp_Object last_mouse_scroll_bar
;
332 /* This is a hack. We would really prefer that XTmouse_position would
333 return the time associated with the position it returns, but there
334 doesn't seem to be any way to wrest the time-stamp from the server
335 along with the position query. So, we just keep track of the time
336 of the last movement we received, and return that in hopes that
337 it's somewhat accurate. */
339 static Time last_mouse_movement_time
;
341 /* Incremented by XTread_socket whenever it really tries to read
345 static int volatile input_signal_count
;
347 static int input_signal_count
;
350 /* Used locally within XTread_socket. */
352 static int x_noop_count
;
354 /* Initial values of argv and argc. */
356 extern char **initial_argv
;
357 extern int initial_argc
;
359 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
361 /* Tells if a window manager is present or not. */
363 extern Lisp_Object Vx_no_window_manager
;
365 extern Lisp_Object Qface
, Qmouse_face
;
369 /* A mask of extra modifier bits to put into every keyboard char. */
371 extern int extra_keyboard_modifiers
;
373 static Lisp_Object Qvendor_specific_keysyms
;
375 extern XrmDatabase
x_load_resources ();
376 extern Lisp_Object
x_icon_type ();
379 /* Enumeration for overriding/changing the face to use for drawing
380 glyphs in x_draw_glyphs. */
382 enum draw_glyphs_face
392 static void x_update_window_end
P_ ((struct window
*, int));
393 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
394 void x_delete_display
P_ ((struct x_display_info
*));
395 static unsigned int x_x_to_emacs_modifiers
P_ ((struct x_display_info
*,
397 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
399 static void set_output_cursor
P_ ((struct cursor_pos
*));
400 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
401 int *, int *, int *));
402 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
403 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
404 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
405 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
406 static void x_handle_tool_bar_click
P_ ((struct frame
*, XButtonEvent
*));
407 static void show_mouse_face
P_ ((struct x_display_info
*,
408 enum draw_glyphs_face
));
409 static int x_io_error_quitter
P_ ((Display
*));
410 int x_catch_errors
P_ ((Display
*));
411 void x_uncatch_errors
P_ ((Display
*, int));
412 void x_lower_frame
P_ ((struct frame
*));
413 void x_scroll_bar_clear
P_ ((struct frame
*));
414 int x_had_errors_p
P_ ((Display
*));
415 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
416 void x_raise_frame
P_ ((struct frame
*));
417 void x_set_window_size
P_ ((struct frame
*, int, int, int));
418 void x_wm_set_window_state
P_ ((struct frame
*, int));
419 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
420 void x_initialize
P_ ((void));
421 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
422 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
423 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
425 enum draw_glyphs_face
));
426 static void x_update_end
P_ ((struct frame
*));
427 static void XTframe_up_to_date
P_ ((struct frame
*));
428 static void XTreassert_line_highlight
P_ ((int, int));
429 static void x_change_line_highlight
P_ ((int, int, int, int));
430 static void XTset_terminal_modes
P_ ((void));
431 static void XTreset_terminal_modes
P_ ((void));
432 static void XTcursor_to
P_ ((int, int, int, int));
433 static void x_write_glyphs
P_ ((struct glyph
*, int));
434 static void x_clear_end_of_line
P_ ((int));
435 static void x_clear_frame
P_ ((void));
436 static void x_clear_cursor
P_ ((struct window
*));
437 static void frame_highlight
P_ ((struct frame
*));
438 static void frame_unhighlight
P_ ((struct frame
*));
439 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
440 static void XTframe_rehighlight
P_ ((struct frame
*));
441 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
442 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
443 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*));
444 static int x_intersect_rectangles
P_ ((XRectangle
*, XRectangle
*,
446 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
447 static void expose_window_tree
P_ ((struct window
*, XRectangle
*));
448 static void expose_window
P_ ((struct window
*, XRectangle
*));
449 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
450 XRectangle
*, enum glyph_row_area
));
451 static void expose_line
P_ ((struct window
*, struct glyph_row
*,
453 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
454 static void x_update_window_cursor
P_ ((struct window
*, int));
455 static void x_erase_phys_cursor
P_ ((struct window
*));
456 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
457 static void x_draw_bitmap
P_ ((struct window
*, struct glyph_row
*,
460 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
462 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, XRectangle
*));
463 static void x_draw_row_bitmaps
P_ ((struct window
*, struct glyph_row
*));
464 static void note_overwritten_text_cursor
P_ ((struct window
*, int, int));
465 static void x_flush
P_ ((struct frame
*f
));
468 /* Flush display of frame F, or of all frames if F is null. */
477 Lisp_Object rest
, frame
;
478 FOR_EACH_FRAME (rest
, frame
)
479 x_flush (XFRAME (frame
));
481 else if (FRAME_X_P (f
))
482 XFlush (FRAME_X_DISPLAY (f
));
487 /* Remove calls to XFlush by defining XFlush to an empty replacement.
488 Calls to XFlush should be unnecessary because the X output buffer
489 is flushed automatically as needed by calls to XPending,
490 XNextEvent, or XWindowEvent according to the XFlush man page.
491 XTread_socket calls XPending. Removing XFlush improves
494 #define XFlush(DISPLAY) (void) 0
497 /***********************************************************************
499 ***********************************************************************/
503 /* This is a function useful for recording debugging information about
504 the sequence of occurrences in this file. */
512 struct record event_record
[100];
514 int event_record_index
;
516 record_event (locus
, type
)
520 if (event_record_index
== sizeof (event_record
) / sizeof (struct record
))
521 event_record_index
= 0;
523 event_record
[event_record_index
].locus
= locus
;
524 event_record
[event_record_index
].type
= type
;
525 event_record_index
++;
532 /* Return the struct x_display_info corresponding to DPY. */
534 struct x_display_info
*
535 x_display_info_for_display (dpy
)
538 struct x_display_info
*dpyinfo
;
540 for (dpyinfo
= x_display_list
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
541 if (dpyinfo
->display
== dpy
)
549 /***********************************************************************
550 Starting and ending an update
551 ***********************************************************************/
553 /* Start an update of frame F. This function is installed as a hook
554 for update_begin, i.e. it is called when update_begin is called.
555 This function is called prior to calls to x_update_window_begin for
556 each window being updated. Currently, there is nothing to do here
557 because all interesting stuff is done on a window basis. */
567 /* Start update of window W. Set the global variable updated_window
568 to the window being updated and set output_cursor to the cursor
572 x_update_window_begin (w
)
575 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
576 struct x_display_info
*display_info
= FRAME_X_DISPLAY_INFO (f
);
579 set_output_cursor (&w
->cursor
);
583 if (f
== display_info
->mouse_face_mouse_frame
)
585 /* Don't do highlighting for mouse motion during the update. */
586 display_info
->mouse_face_defer
= 1;
588 /* If F needs to be redrawn, simply forget about any prior mouse
590 if (FRAME_GARBAGED_P (f
))
591 display_info
->mouse_face_window
= Qnil
;
593 /* Can we tell that this update does not affect the window
594 where the mouse highlight is? If so, no need to turn off.
595 Likewise, don't do anything if the frame is garbaged;
596 in that case, the frame's current matrix that we would use
597 is all wrong, and we will redisplay that line anyway. */
598 if (!NILP (display_info
->mouse_face_window
)
599 && w
== XWINDOW (display_info
->mouse_face_window
))
603 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
604 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
607 if (i
< w
->desired_matrix
->nrows
)
608 clear_mouse_face (display_info
);
616 /* Draw a vertical window border to the right of window W if W doesn't
617 have vertical scroll bars. */
620 x_draw_vertical_border (w
)
623 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
625 /* Redraw borders between horizontally adjacent windows. Don't
626 do it for frames with vertical scroll bars because either the
627 right scroll bar of a window, or the left scroll bar of its
628 neighbor will suffice as a border. */
629 if (!WINDOW_RIGHTMOST_P (w
)
630 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
634 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
635 x1
+= FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
);
638 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
639 f
->output_data
.x
->normal_gc
, x1
, y0
, x1
, y1
);
644 /* End update of window W (which is equal to updated_window). Draw
645 vertical borders between horizontally adjacent windows, and display
646 W's cursor if CURSOR_ON_P is non-zero. W may be a menu bar
647 pseudo-window in case we don't have X toolkit support. Such
648 windows don't have a cursor, so don't display it here. */
651 x_update_window_end (w
, cursor_on_p
)
655 if (!w
->pseudo_window_p
)
659 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
661 output_cursor
.x
, output_cursor
.y
);
662 x_draw_vertical_border (w
);
666 updated_window
= NULL
;
670 /* End update of frame F. This function is installed as a hook in
677 /* Mouse highlight may be displayed again. */
678 FRAME_X_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
681 XFlush (FRAME_X_DISPLAY (f
));
686 /* This function is called from various places in xdisp.c whenever a
687 complete update has been performed. The global variable
688 updated_window is not available here. */
691 XTframe_up_to_date (f
)
696 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
697 if (dpyinfo
->mouse_face_deferred_gc
698 || f
== dpyinfo
->mouse_face_mouse_frame
)
701 if (dpyinfo
->mouse_face_mouse_frame
)
702 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
703 dpyinfo
->mouse_face_mouse_x
,
704 dpyinfo
->mouse_face_mouse_y
);
705 dpyinfo
->mouse_face_deferred_gc
= 0;
712 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
713 arrow bitmaps, or clear the areas where they would be displayed
714 before DESIRED_ROW is made current. The window being updated is
715 found in updated_window. This function It is called from
716 update_window_line only if it is known that there are differences
717 between bitmaps to be drawn between current row and DESIRED_ROW. */
720 x_after_update_window_line (desired_row
)
721 struct glyph_row
*desired_row
;
723 struct window
*w
= updated_window
;
727 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
730 x_draw_row_bitmaps (w
, desired_row
);
732 /* When a window has disappeared, make sure that no rest of
733 full-width rows stays visible in the internal border. */
734 if (windows_or_buffers_changed
)
736 struct frame
*f
= XFRAME (w
->frame
);
737 int width
= FRAME_INTERNAL_BORDER_WIDTH (f
);
738 int height
= desired_row
->visible_height
;
739 int x
= (window_box_right (w
, -1)
740 + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
));
741 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
743 XClearArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
744 x
, y
, width
, height
, False
);
752 /* Draw the bitmap WHICH in one of the areas to the left or right of
753 window W. ROW is the glyph row for which to display the bitmap; it
754 determines the vertical position at which the bitmap has to be
758 x_draw_bitmap (w
, row
, which
)
760 struct glyph_row
*row
;
761 enum bitmap_type which
;
763 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
764 Display
*display
= FRAME_X_DISPLAY (f
);
765 Window window
= FRAME_X_WINDOW (f
);
769 GC gc
= f
->output_data
.x
->normal_gc
;
771 int depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
773 /* Must clip because of partially visible lines. */
774 x_clip_to_row (w
, row
, gc
, 1);
778 case LEFT_TRUNCATION_BITMAP
:
782 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
784 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
787 case OVERLAY_ARROW_BITMAP
:
791 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
793 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
796 case RIGHT_TRUNCATION_BITMAP
:
800 x
= window_box_right (w
, -1);
801 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
804 case CONTINUED_LINE_BITMAP
:
807 bits
= continued_bits
;
808 x
= window_box_right (w
, -1);
809 x
+= (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
) - wd
) / 2;
812 case CONTINUATION_LINE_BITMAP
:
813 wd
= continuation_width
;
814 h
= continuation_height
;
815 bits
= continuation_bits
;
816 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
818 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
825 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
827 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
834 /* Convert to frame coordinates. Set dy to the offset in the row to
835 start drawing the bitmap. */
836 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
837 dy
= (row
->height
- h
) / 2;
839 /* Draw the bitmap. I believe these small pixmaps can be cached
841 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
842 pixmap
= XCreatePixmapFromBitmapData (display
, window
, bits
, wd
, h
,
844 face
->background
, depth
);
845 XCopyArea (display
, pixmap
, window
, gc
, 0, 0, wd
, h
, x
, y
+ dy
);
846 XFreePixmap (display
, pixmap
);
847 XSetClipMask (display
, gc
, None
);
851 /* Draw flags bitmaps for glyph row ROW on window W. Call this
852 function with input blocked. */
855 x_draw_row_bitmaps (w
, row
)
857 struct glyph_row
*row
;
859 struct frame
*f
= XFRAME (w
->frame
);
860 enum bitmap_type bitmap
;
862 int header_line_height
= -1;
864 xassert (interrupt_input_blocked
);
866 /* If row is completely invisible, because of vscrolling, we
867 don't have to draw anything. */
868 if (row
->visible_height
<= 0)
871 face
= FACE_FROM_ID (f
, BITMAP_AREA_FACE_ID
);
872 PREPARE_FACE_FOR_DISPLAY (f
, face
);
874 /* Decide which bitmap to draw at the left side. */
875 if (row
->overlay_arrow_p
)
876 bitmap
= OVERLAY_ARROW_BITMAP
;
877 else if (row
->truncated_on_left_p
)
878 bitmap
= LEFT_TRUNCATION_BITMAP
;
879 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
880 bitmap
= CONTINUATION_LINE_BITMAP
;
881 else if (row
->indicate_empty_line_p
)
882 bitmap
= ZV_LINE_BITMAP
;
886 /* Clear flags area if no bitmap to draw or if bitmap doesn't fill
888 if (bitmap
== NO_BITMAP
889 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
890 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
892 /* If W has a vertical border to its left, don't draw over it. */
893 int border
= ((XFASTINT (w
->left
) > 0
894 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
896 int left
= window_box_left (w
, -1);
898 if (header_line_height
< 0)
899 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
901 /* In case the same realized face is used for bitmap areas and
902 for something displayed in the text (e.g. face `region' on
903 mono-displays, the fill style may have been changed to
904 FillSolid in x_draw_glyph_string_background. */
906 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
908 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
910 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
913 - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
915 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
917 FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - border
,
918 row
->visible_height
);
920 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
923 /* Draw the left bitmap. */
924 if (bitmap
!= NO_BITMAP
)
925 x_draw_bitmap (w
, row
, bitmap
);
927 /* Decide which bitmap to draw at the right side. */
928 if (row
->truncated_on_right_p
)
929 bitmap
= RIGHT_TRUNCATION_BITMAP
;
930 else if (row
->continued_p
)
931 bitmap
= CONTINUED_LINE_BITMAP
;
935 /* Clear flags area if no bitmap to draw of if bitmap doesn't fill
937 if (bitmap
== NO_BITMAP
938 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
)
939 || row
->height
> FRAME_FLAGS_BITMAP_HEIGHT (f
))
941 int right
= window_box_right (w
, -1);
943 if (header_line_height
< 0)
944 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
946 /* In case the same realized face is used for bitmap areas and
947 for something displayed in the text (e.g. face `region' on
948 mono-displays, the fill style may have been changed to
949 FillSolid in x_draw_glyph_string_background. */
951 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
953 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
954 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
957 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
959 FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
),
960 row
->visible_height
);
962 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
965 /* Draw the right bitmap. */
966 if (bitmap
!= NO_BITMAP
)
967 x_draw_bitmap (w
, row
, bitmap
);
971 /***********************************************************************
973 ***********************************************************************/
975 /* External interface to control of standout mode. Not used for X
976 frames. Aborts when called. */
979 XTreassert_line_highlight (new, vpos
)
986 /* Call this when about to modify line at position VPOS and change
987 whether it is highlighted. Not used for X frames. Aborts when
991 x_change_line_highlight (new_highlight
, vpos
, y
, first_unused_hpos
)
992 int new_highlight
, vpos
, y
, first_unused_hpos
;
998 /* This is called when starting Emacs and when restarting after
999 suspend. When starting Emacs, no X window is mapped. And nothing
1000 must be done to Emacs's own window if it is suspended (though that
1004 XTset_terminal_modes ()
1008 /* This is called when exiting or suspending Emacs. Exiting will make
1009 the X-windows go away, and suspending requires no action. */
1012 XTreset_terminal_modes ()
1018 /***********************************************************************
1020 ***********************************************************************/
1022 /* Set the global variable output_cursor to CURSOR. All cursor
1023 positions are relative to updated_window. */
1026 set_output_cursor (cursor
)
1027 struct cursor_pos
*cursor
;
1029 output_cursor
.hpos
= cursor
->hpos
;
1030 output_cursor
.vpos
= cursor
->vpos
;
1031 output_cursor
.x
= cursor
->x
;
1032 output_cursor
.y
= cursor
->y
;
1036 /* Set a nominal cursor position.
1038 HPOS and VPOS are column/row positions in a window glyph matrix. X
1039 and Y are window text area relative pixel positions.
1041 If this is done during an update, updated_window will contain the
1042 window that is being updated and the position is the future output
1043 cursor position for that window. If updated_window is null, use
1044 selected_window and display the cursor at the given position. */
1047 XTcursor_to (vpos
, hpos
, y
, x
)
1048 int vpos
, hpos
, y
, x
;
1052 /* If updated_window is not set, work on selected_window. */
1056 w
= XWINDOW (selected_window
);
1058 /* Set the output cursor. */
1059 output_cursor
.hpos
= hpos
;
1060 output_cursor
.vpos
= vpos
;
1061 output_cursor
.x
= x
;
1062 output_cursor
.y
= y
;
1064 /* If not called as part of an update, really display the cursor.
1065 This will also set the cursor position of W. */
1066 if (updated_window
== NULL
)
1069 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1070 XFlush (FRAME_X_DISPLAY (SELECTED_FRAME ()));
1077 /***********************************************************************
1079 ***********************************************************************/
1081 /* Function prototypes of this page. */
1083 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1086 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1087 int, XChar2b
*, int));
1088 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1089 static void x_encode_char
P_ ((int, XChar2b
*, struct font_info
*));
1090 static void x_append_glyph
P_ ((struct it
*));
1091 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1093 static void x_produce_glyphs
P_ ((struct it
*));
1094 static void x_produce_image_glyph
P_ ((struct it
*it
));
1097 /* Return a pointer to per-char metric information in FONT of a
1098 character pointed by B which is a pointer to an XChar2b. */
1100 #define PER_CHAR_METRIC(font, b) \
1102 ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \
1103 + (((font)->min_byte1 || (font)->max_byte1) \
1104 ? (((b)->byte1 - (font)->min_byte1) \
1105 * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
1107 : &((font)->max_bounds))
1110 /* Get metrics of character CHAR2B in FONT. Value is always non-null.
1111 If CHAR2B is not contained in FONT, the font's default character
1112 metric is returned. */
1114 static INLINE XCharStruct
*
1115 x_per_char_metric (font
, char2b
)
1119 /* The result metric information. */
1120 XCharStruct
*pcm
= NULL
;
1122 xassert (font
&& char2b
);
1124 if (font
->per_char
!= NULL
)
1126 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1128 /* min_char_or_byte2 specifies the linear character index
1129 corresponding to the first element of the per_char array,
1130 max_char_or_byte2 is the index of the last character. A
1131 character with non-zero CHAR2B->byte1 is not in the font.
1132 A character with byte2 less than min_char_or_byte2 or
1133 greater max_char_or_byte2 is not in the font. */
1134 if (char2b
->byte1
== 0
1135 && char2b
->byte2
>= font
->min_char_or_byte2
1136 && char2b
->byte2
<= font
->max_char_or_byte2
)
1137 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1141 /* If either min_byte1 or max_byte1 are nonzero, both
1142 min_char_or_byte2 and max_char_or_byte2 are less than
1143 256, and the 2-byte character index values corresponding
1144 to the per_char array element N (counting from 0) are:
1146 byte1 = N/D + min_byte1
1147 byte2 = N\D + min_char_or_byte2
1151 D = max_char_or_byte2 - min_char_or_byte2 + 1
1152 / = integer division
1153 \ = integer modulus */
1154 if (char2b
->byte1
>= font
->min_byte1
1155 && char2b
->byte1
<= font
->max_byte1
1156 && char2b
->byte2
>= font
->min_char_or_byte2
1157 && char2b
->byte2
<= font
->max_char_or_byte2
)
1159 pcm
= (font
->per_char
1160 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1161 * (char2b
->byte1
- font
->min_byte1
))
1162 + (char2b
->byte2
- font
->min_char_or_byte2
));
1168 /* If the per_char pointer is null, all glyphs between the first
1169 and last character indexes inclusive have the same
1170 information, as given by both min_bounds and max_bounds. */
1171 if (char2b
->byte2
>= font
->min_char_or_byte2
1172 && char2b
->byte2
<= font
->max_char_or_byte2
)
1173 pcm
= &font
->max_bounds
;
1177 if (pcm
== NULL
|| pcm
->width
== 0)
1179 /* Character not contained in the font. FONT->default_char
1180 gives the character that will be printed. FONT->default_char
1181 is a 16-bit character code with byte1 in the most significant
1182 byte and byte2 in the least significant byte. */
1183 XChar2b default_char
;
1184 default_char
.byte1
= (font
->default_char
>> BITS_PER_CHAR
) & 0xff;
1185 default_char
.byte2
= font
->default_char
& 0xff;
1187 /* Avoid an endless recursion if FONT->default_char itself
1188 hasn't per char metrics. handa@etl.go.jp reports that some
1189 fonts have this problem. */
1190 if (default_char
.byte1
!= char2b
->byte1
1191 || default_char
.byte2
!= char2b
->byte2
)
1192 pcm
= x_per_char_metric (font
, &default_char
);
1194 pcm
= &font
->max_bounds
;
1201 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1202 the two-byte form of C. Encoding is returned in *CHAR2B. */
1205 x_encode_char (c
, char2b
, font_info
)
1208 struct font_info
*font_info
;
1210 int charset
= CHAR_CHARSET (c
);
1211 XFontStruct
*font
= font_info
->font
;
1213 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1214 This may be either a program in a special encoder language or a
1216 if (font_info
->font_encoder
)
1218 /* It's a program. */
1219 struct ccl_program
*ccl
= font_info
->font_encoder
;
1221 if (CHARSET_DIMENSION (charset
) == 1)
1223 ccl
->reg
[0] = charset
;
1224 ccl
->reg
[1] = char2b
->byte2
;
1228 ccl
->reg
[0] = charset
;
1229 ccl
->reg
[1] = char2b
->byte1
;
1230 ccl
->reg
[2] = char2b
->byte2
;
1233 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1235 /* We assume that MSBs are appropriately set/reset by CCL
1237 if (font
->max_byte1
== 0) /* 1-byte font */
1238 char2b
->byte2
= ccl
->reg
[1];
1240 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1242 else if (font_info
->encoding
[charset
])
1244 /* Fixed encoding scheme. See fontset.h for the meaning of the
1245 encoding numbers. */
1246 int enc
= font_info
->encoding
[charset
];
1248 if ((enc
== 1 || enc
== 2)
1249 && CHARSET_DIMENSION (charset
) == 2)
1250 char2b
->byte1
|= 0x80;
1252 if (enc
== 1 || enc
== 3)
1253 char2b
->byte2
|= 0x80;
1258 /* Get face and two-byte form of character C in face FACE_ID on frame
1259 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1260 means we want to display multibyte text. Value is a pointer to a
1261 realized face that is ready for display. */
1263 static INLINE
struct face
*
1264 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1270 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1274 /* Unibyte case. We don't have to encode, but we have to make
1275 sure to use a face suitable for unibyte. */
1279 if (!FACE_SUITABLE_FOR_CHARSET_P (face
, -1))
1281 face_id
= FACE_FOR_CHARSET (f
, face_id
, -1);
1282 face
= FACE_FROM_ID (f
, face_id
);
1285 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1287 /* Case of ASCII in a face known to fit ASCII. */
1293 int c1
, c2
, charset
;
1295 /* Split characters into bytes. If c2 is -1 afterwards, C is
1296 really a one-byte character so that byte1 is zero. */
1297 SPLIT_CHAR (c
, charset
, c1
, c2
);
1299 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1301 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1303 /* Get the face for displaying C. If `face' is not suitable for
1304 charset, get the one that fits. (This can happen for the
1305 translations of composite characters where the glyph
1306 specifies a face for ASCII, but translations have a different
1308 if (!FACE_SUITABLE_FOR_CHARSET_P (face
, charset
))
1310 face_id
= FACE_FOR_CHARSET (f
, face_id
, charset
);
1311 face
= FACE_FROM_ID (f
, face_id
);
1314 /* Maybe encode the character in *CHAR2B. */
1315 if (charset
!= CHARSET_ASCII
)
1317 struct font_info
*font_info
1318 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1321 x_encode_char (c
, char2b
, font_info
);
1322 if (charset
== charset_latin_iso8859_1
)
1324 xassert (((XFontStruct
*) font_info
->font
)->max_char_or_byte2
1326 char2b
->byte2
|= 0x80;
1332 /* Make sure X resources of the face are allocated. */
1333 xassert (face
!= NULL
);
1334 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1340 /* Get face and two-byte form of character glyph GLYPH on frame F.
1341 The encoding of GLYPH->u.ch.code is returned in *CHAR2B. Value is
1342 a pointer to a realized face that is ready for display. */
1344 static INLINE
struct face
*
1345 x_get_glyph_face_and_encoding (f
, glyph
, char2b
)
1347 struct glyph
*glyph
;
1352 xassert (glyph
->type
== CHAR_GLYPH
);
1353 face
= FACE_FROM_ID (f
, glyph
->u
.ch
.face_id
);
1355 if (!glyph
->multibyte_p
)
1357 /* Unibyte case. We don't have to encode, but we have to make
1358 sure to use a face suitable for unibyte. */
1360 char2b
->byte2
= glyph
->u
.ch
.code
;
1362 else if (glyph
->u
.ch
.code
< 128
1363 && glyph
->u
.ch
.face_id
< BASIC_FACE_ID_SENTINEL
)
1365 /* Case of ASCII in a face known to fit ASCII. */
1367 char2b
->byte2
= glyph
->u
.ch
.code
;
1371 int c1
, c2
, charset
;
1373 /* Split characters into bytes. If c2 is -1 afterwards, C is
1374 really a one-byte character so that byte1 is zero. */
1375 SPLIT_CHAR (glyph
->u
.ch
.code
, charset
, c1
, c2
);
1377 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1379 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1381 /* Maybe encode the character in *CHAR2B. */
1382 if (charset
!= CHARSET_ASCII
)
1384 struct font_info
*font_info
1385 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1388 x_encode_char (glyph
->u
.ch
.code
, char2b
, font_info
);
1389 if (charset
== charset_latin_iso8859_1
)
1390 char2b
->byte2
|= 0x80;
1395 /* Make sure X resources of the face are allocated. */
1396 xassert (face
!= NULL
);
1397 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1402 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1403 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1409 struct glyph
*glyph
;
1410 enum glyph_row_area area
= it
->area
;
1412 xassert (it
->glyph_row
);
1413 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1415 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1416 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1418 /* Play it safe. If sub-structures of the glyph are not all the
1419 same size, it otherwise be that some bits stay set. This
1420 would prevent a comparison with GLYPH_EQUAL_P. */
1423 glyph
->type
= CHAR_GLYPH
;
1424 glyph
->pixel_width
= it
->pixel_width
;
1425 glyph
->u
.ch
.code
= it
->char_to_display
;
1426 glyph
->u
.ch
.face_id
= it
->face_id
;
1427 glyph
->charpos
= CHARPOS (it
->position
);
1428 glyph
->object
= it
->object
;
1429 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1430 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1431 glyph
->voffset
= it
->voffset
;
1432 glyph
->multibyte_p
= it
->multibyte_p
;
1433 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1434 || it
->phys_descent
> it
->descent
);
1435 ++it
->glyph_row
->used
[area
];
1440 /* Change IT->ascent and IT->height according to the setting of
1444 take_vertical_position_into_account (it
)
1449 if (it
->voffset
< 0)
1450 /* Increase the ascent so that we can display the text higher
1452 it
->ascent
+= abs (it
->voffset
);
1454 /* Increase the descent so that we can display the text lower
1456 it
->descent
+= it
->voffset
;
1461 /* Produce glyphs/get display metrics for the image IT is loaded with.
1462 See the description of struct display_iterator in dispextern.h for
1463 an overview of struct display_iterator. */
1466 x_produce_image_glyph (it
)
1472 xassert (it
->what
== IT_IMAGE
);
1474 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1475 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1478 /* Make sure X resources of the face and image are loaded. */
1479 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1480 prepare_image_for_display (it
->f
, img
);
1482 it
->ascent
= it
->phys_ascent
= IMAGE_ASCENT (img
);
1483 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->margin
- it
->ascent
;
1484 it
->pixel_width
= img
->width
+ 2 * img
->margin
;
1488 if (face
->box
!= FACE_NO_BOX
)
1490 it
->ascent
+= face
->box_line_width
;
1491 it
->descent
+= face
->box_line_width
;
1493 if (it
->start_of_box_run_p
)
1494 it
->pixel_width
+= face
->box_line_width
;
1495 if (it
->end_of_box_run_p
)
1496 it
->pixel_width
+= face
->box_line_width
;
1499 take_vertical_position_into_account (it
);
1503 struct glyph
*glyph
;
1504 enum glyph_row_area area
= it
->area
;
1506 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1507 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1509 glyph
->type
= IMAGE_GLYPH
;
1510 glyph
->u
.img
.id
= img
->id
;
1511 glyph
->u
.img
.face_id
= it
->face_id
;
1512 glyph
->pixel_width
= it
->pixel_width
;
1513 glyph
->charpos
= CHARPOS (it
->position
);
1514 glyph
->object
= it
->object
;
1515 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1516 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1517 glyph
->voffset
= it
->voffset
;
1518 glyph
->multibyte_p
= it
->multibyte_p
;
1519 ++it
->glyph_row
->used
[area
];
1525 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1526 of the glyph, WIDTH and HEIGHT are the width and height of the
1527 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1528 ascent of the glyph (0 <= ASCENT <= 1). */
1531 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1537 struct glyph
*glyph
;
1538 enum glyph_row_area area
= it
->area
;
1540 xassert (ascent
>= 0 && ascent
<= 1);
1542 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1543 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1545 glyph
->type
= STRETCH_GLYPH
;
1546 glyph
->u
.stretch
.ascent
= height
* ascent
;
1547 glyph
->u
.stretch
.height
= height
;
1548 glyph
->u
.stretch
.face_id
= it
->face_id
;
1549 glyph
->pixel_width
= width
;
1550 glyph
->charpos
= CHARPOS (it
->position
);
1551 glyph
->object
= object
;
1552 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1553 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1554 glyph
->voffset
= it
->voffset
;
1555 glyph
->multibyte_p
= it
->multibyte_p
;
1556 ++it
->glyph_row
->used
[area
];
1561 /* Produce a stretch glyph for iterator IT. IT->object is the value
1562 of the glyph property displayed. The value must be a list
1563 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1566 1. `:width WIDTH' specifies that the space should be WIDTH *
1567 canonical char width wide. WIDTH may be an integer or floating
1570 2. `:relative-width FACTOR' specifies that the width of the stretch
1571 should be computed from the width of the first character having the
1572 `glyph' property, and should be FACTOR times that width.
1574 3. `:align-to HPOS' specifies that the space should be wide enough
1575 to reach HPOS, a value in canonical character units.
1577 Exactly one of the above pairs must be present.
1579 4. `:height HEIGHT' specifies that the height of the stretch produced
1580 should be HEIGHT, measured in canonical character units.
1582 5. `:relative-height FACTOR' specifies that the height of the the
1583 stretch should be FACTOR times the height of the characters having
1586 Either none or exactly one of 4 or 5 must be present.
1588 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1589 of the stretch should be used for the ascent of the stretch.
1590 ASCENT must be in the range 0 <= ASCENT <= 100. */
1593 ((INTEGERP (X) || FLOATP (X)) \
1599 x_produce_stretch_glyph (it
)
1602 /* (space :width WIDTH :height HEIGHT. */
1603 extern Lisp_Object QCwidth
, QCheight
, QCascent
, Qspace
;
1604 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1605 extern Lisp_Object QCalign_to
;
1606 Lisp_Object prop
, plist
;
1607 double width
= 0, height
= 0, ascent
= 0;
1608 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1609 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1611 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1613 /* List should start with `space'. */
1614 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1615 plist
= XCDR (it
->object
);
1617 /* Compute the width of the stretch. */
1618 if (prop
= Fplist_get (plist
, QCwidth
),
1620 /* Absolute width `:width WIDTH' specified and valid. */
1621 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1622 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1625 /* Relative width `:relative-width FACTOR' specified and valid.
1626 Compute the width of the characters having the `glyph'
1629 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1632 if (it
->multibyte_p
)
1634 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1635 - IT_BYTEPOS (*it
));
1636 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1639 it2
.c
= *p
, it2
.len
= 1;
1641 it2
.glyph_row
= NULL
;
1642 it2
.what
= IT_CHARACTER
;
1643 x_produce_glyphs (&it2
);
1644 width
= NUMVAL (prop
) * it2
.pixel_width
;
1646 else if (prop
= Fplist_get (plist
, QCalign_to
),
1648 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1650 /* Nothing specified -> width defaults to canonical char width. */
1651 width
= CANON_X_UNIT (it
->f
);
1653 /* Compute height. */
1654 if (prop
= Fplist_get (plist
, QCheight
),
1656 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1657 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1659 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1661 height
= FONT_HEIGHT (font
);
1663 /* Compute percentage of height used for ascent. If
1664 `:ascent ASCENT' is present and valid, use that. Otherwise,
1665 derive the ascent from the font in use. */
1666 if (prop
= Fplist_get (plist
, QCascent
),
1667 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1668 ascent
= NUMVAL (prop
) / 100.0;
1670 ascent
= (double) font
->ascent
/ FONT_HEIGHT (font
);
1679 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1680 if (!STRINGP (object
))
1681 object
= it
->w
->buffer
;
1682 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1685 it
->pixel_width
= width
;
1686 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1687 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1690 if (face
->box
!= FACE_NO_BOX
)
1692 it
->ascent
+= face
->box_line_width
;
1693 it
->descent
+= face
->box_line_width
;
1695 if (it
->start_of_box_run_p
)
1696 it
->pixel_width
+= face
->box_line_width
;
1697 if (it
->end_of_box_run_p
)
1698 it
->pixel_width
+= face
->box_line_width
;
1701 take_vertical_position_into_account (it
);
1705 /* Produce glyphs/get display metrics for the display element IT is
1706 loaded with. See the description of struct display_iterator in
1707 dispextern.h for an overview of struct display_iterator. */
1710 x_produce_glyphs (it
)
1713 if (it
->what
== IT_CHARACTER
)
1719 int font_not_found_p
;
1721 /* Maybe translate single-byte characters to multibyte. */
1722 it
->char_to_display
= it
->c
;
1723 if (unibyte_display_via_language_environment
1724 && SINGLE_BYTE_CHAR_P (it
->c
)
1727 && !NILP (Vnonascii_translation_table
))))
1729 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1730 it
->charset
= CHAR_CHARSET (it
->char_to_display
);
1733 /* Get face and font to use. Encode IT->char_to_display. */
1734 face
= x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
1735 it
->face_id
, &char2b
,
1739 /* When no suitable font found, use the default font. */
1740 font_not_found_p
= font
== NULL
;
1741 if (font_not_found_p
)
1742 font
= FRAME_FONT (it
->f
);
1744 if (it
->char_to_display
>= ' '
1745 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
1747 /* Either unibyte or ASCII. */
1752 pcm
= x_per_char_metric (font
, &char2b
);
1753 it
->ascent
= font
->ascent
;
1754 it
->descent
= font
->descent
;
1755 it
->phys_ascent
= pcm
->ascent
;
1756 it
->phys_descent
= pcm
->descent
;
1757 it
->pixel_width
= pcm
->width
;
1759 /* If this is a space inside a region of text with
1760 `space-width' property, change its width. */
1761 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
1763 it
->pixel_width
*= XFLOATINT (it
->space_width
);
1765 /* If face has a box, add the box thickness to the character
1766 height. If character has a box line to the left and/or
1767 right, add the box line width to the character's width. */
1768 if (face
->box
!= FACE_NO_BOX
)
1770 int thick
= face
->box_line_width
;
1772 it
->ascent
+= thick
;
1773 it
->descent
+= thick
;
1775 if (it
->start_of_box_run_p
)
1776 it
->pixel_width
+= thick
;
1777 if (it
->end_of_box_run_p
)
1778 it
->pixel_width
+= thick
;
1781 /* If face has an overline, add the height of the overline
1782 (1 pixel) and a 1 pixel margin to the character height. */
1783 if (face
->overline_p
)
1786 take_vertical_position_into_account (it
);
1788 /* If we have to actually produce glyphs, do it. */
1793 /* Translate a space with a `space-width' property
1794 into a stretch glyph. */
1795 double ascent
= (double) font
->ascent
/ FONT_HEIGHT (font
);
1796 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1797 it
->ascent
+ it
->descent
, ascent
);
1800 x_append_glyph (it
);
1802 /* If characters with lbearing or rbearing are displayed
1803 in this line, record that fact in a flag of the
1804 glyph row. This is used to optimize X output code. */
1805 if (pcm
->lbearing
< 0
1806 || pcm
->rbearing
> pcm
->width
)
1807 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
1810 else if (it
->char_to_display
== '\n')
1812 /* A newline has no width but we need the height of the line. */
1813 it
->pixel_width
= 0;
1815 it
->ascent
= it
->phys_ascent
= font
->ascent
;
1816 it
->descent
= it
->phys_descent
= font
->descent
;
1818 if (face
->box
!= FACE_NO_BOX
)
1820 int thick
= face
->box_line_width
;
1821 it
->ascent
+= thick
;
1822 it
->descent
+= thick
;
1825 else if (it
->char_to_display
== '\t')
1827 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
1828 int x
= (it
->current_x
1830 + it
->continuation_lines_width
);
1831 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
1833 it
->pixel_width
= next_tab_x
- x
;
1835 it
->ascent
= it
->phys_ascent
= font
->ascent
;
1836 it
->descent
= it
->phys_descent
= font
->descent
;
1840 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
1841 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1842 it
->ascent
+ it
->descent
, ascent
);
1847 /* A multi-byte character. Assume that the display width of the
1848 character is the width of the character multiplied by the
1849 width of the font. There has to be better support for
1850 variable sizes in cmpchar_info to do anything better than
1853 Note: composite characters are represented as one glyph in
1854 the glyph matrix. There are no padding glyphs. */
1855 if (it
->charset
== CHARSET_COMPOSITION
)
1857 struct cmpchar_info
*cmpcharp
;
1860 idx
= COMPOSITE_CHAR_ID (it
->char_to_display
);
1861 cmpcharp
= cmpchar_table
[idx
];
1862 it
->pixel_width
= font
->max_bounds
.width
* cmpcharp
->width
;
1864 /* There are no padding glyphs, so there is only one glyph
1865 to produce for the composite char. Important is that
1866 pixel_width, ascent and descent are the values of what is
1867 drawn by draw_glyphs. */
1870 /* These settings may not be correct. We must have more
1871 information in cmpcharp to do the correct setting. */
1872 it
->ascent
= font
->ascent
;
1873 it
->descent
= font
->descent
;
1874 it
->phys_ascent
= font
->max_bounds
.ascent
;
1875 it
->phys_descent
= font
->max_bounds
.descent
;
1879 /* If we found a font, this font should give us the right
1880 metrics. If we didn't find a font, use the frame's
1881 default font and calculate the width of the character
1882 from the charset width; this is what old redisplay code
1884 pcm
= x_per_char_metric (font
, &char2b
);
1885 it
->pixel_width
= pcm
->width
;
1886 if (font_not_found_p
)
1887 it
->pixel_width
*= CHARSET_WIDTH (it
->charset
);
1889 it
->ascent
= font
->ascent
;
1890 it
->descent
= font
->descent
;
1891 it
->phys_ascent
= pcm
->ascent
;
1892 it
->phys_descent
= pcm
->descent
;
1894 && (pcm
->lbearing
< 0
1895 || pcm
->rbearing
> pcm
->width
))
1896 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
1899 if (face
->box
!= FACE_NO_BOX
)
1901 int thick
= face
->box_line_width
;
1902 it
->ascent
+= thick
;
1903 it
->descent
+= thick
;
1905 if (it
->start_of_box_run_p
)
1906 it
->pixel_width
+= thick
;
1907 if (it
->end_of_box_run_p
)
1908 it
->pixel_width
+= thick
;
1911 /* If face has an overline, add the height of the overline
1912 (1 pixel) and a 1 pixel margin to the character height. */
1913 if (face
->overline_p
)
1916 take_vertical_position_into_account (it
);
1919 x_append_glyph (it
);
1922 else if (it
->what
== IT_IMAGE
)
1923 x_produce_image_glyph (it
);
1924 else if (it
->what
== IT_STRETCH
)
1925 x_produce_stretch_glyph (it
);
1927 /* Accumulate dimensions. */
1928 xassert (it
->ascent
>= 0 && it
->descent
> 0);
1929 if (it
->area
== TEXT_AREA
)
1930 it
->current_x
+= it
->pixel_width
;
1932 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
1933 it
->max_descent
= max (it
->max_descent
, it
->descent
);
1934 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
1935 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
1939 /* Estimate the pixel height of the mode or top line on frame F.
1940 FACE_ID specifies what line's height to estimate. */
1943 x_estimate_mode_line_height (f
, face_id
)
1945 enum face_id face_id
;
1949 /* This function is called so early when Emacs starts that the face
1950 cache and mode line face are not yet initialized. */
1951 if (FRAME_FACE_CACHE (f
))
1953 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1955 height
= FONT_HEIGHT (face
->font
) + 2 * face
->box_line_width
;
1962 /***********************************************************************
1964 ***********************************************************************/
1966 /* A sequence of glyphs to be drawn in the same face.
1968 This data structure is not really completely X specific, so it
1969 could possibly, at least partially, be useful for other systems. It
1970 is currently not part of the external redisplay interface because
1971 it's not clear what other systems will need. */
1975 /* X-origin of the string. */
1978 /* Y-origin and y-position of the base line of this string. */
1981 /* The width of the string, not including a face extension. */
1984 /* The width of the string, including a face extension. */
1985 int background_width
;
1987 /* The height of this string. This is the height of the line this
1988 string is drawn in, and can be different from the height of the
1989 font the string is drawn in. */
1992 /* Number of pixels this string overwrites in front of its x-origin.
1993 This number is zero if the string has an lbearing >= 0; it is
1994 -lbearing, if the string has an lbearing < 0. */
1997 /* Number of pixels this string overwrites past its right-most
1998 nominal x-position, i.e. x + width. Zero if the string's
1999 rbearing is <= its nominal width, rbearing - width otherwise. */
2002 /* The frame on which the glyph string is drawn. */
2005 /* The window on which the glyph string is drawn. */
2008 /* X display and window for convenience. */
2012 /* The glyph row for which this string was built. It determines the
2013 y-origin and height of the string. */
2014 struct glyph_row
*row
;
2016 /* The area within row. */
2017 enum glyph_row_area area
;
2019 /* Characters to be drawn, and number of characters. */
2023 /* Character set of this glyph string. */
2026 /* A face-override for drawing cursors, mouse face and similar. */
2027 enum draw_glyphs_face hl
;
2029 /* Face in which this string is to be drawn. */
2032 /* Font in which this string is to be drawn. */
2035 /* Font info for this string. */
2036 struct font_info
*font_info
;
2038 /* Non-null means this string describes (part of) a composite
2039 character. All characters from char2b are drawn at the same
2040 x-origin in that case. */
2041 struct cmpchar_info
*cmpcharp
;
2043 /* Index of this glyph string's first character in the glyph
2044 definition of cmpcharp. If this is zero, this glyph string
2045 describes the first character of a composite character. */
2048 /* 1 means this glyph strings face has to be drawn to the right end
2049 of the window's drawing area. */
2050 unsigned extends_to_end_of_line_p
: 1;
2052 /* 1 means the background of this string has been drawn. */
2053 unsigned background_filled_p
: 1;
2055 /* 1 means glyph string must be drawn with 16-bit functions. */
2056 unsigned two_byte_p
: 1;
2058 /* 1 means that the original font determined for drawing this glyph
2059 string could not be loaded. The member `font' has been set to
2060 the frame's default font in this case. */
2061 unsigned font_not_found_p
: 1;
2063 /* 1 means that the face in which this glyph string is drawn has a
2065 unsigned stippled_p
: 1;
2067 /* 1 means only the foreground of this glyph string must be drawn,
2068 and we should use the physical height of the line this glyph
2069 string appears in as clip rect. */
2070 unsigned for_overlaps_p
: 1;
2072 /* The GC to use for drawing this glyph string. */
2075 /* A pointer to the first glyph in the string. This glyph
2076 corresponds to char2b[0]. Needed to draw rectangles if
2077 font_not_found_p is 1. */
2078 struct glyph
*first_glyph
;
2080 /* Image, if any. */
2083 struct glyph_string
*next
, *prev
;
2090 x_dump_glyph_string (s
)
2091 struct glyph_string
*s
;
2093 fprintf (stderr
, "glyph string\n");
2094 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2095 s
->x
, s
->y
, s
->width
, s
->height
);
2096 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2097 fprintf (stderr
, " hl = %d\n", s
->hl
);
2098 fprintf (stderr
, " left overhang = %d, right = %d\n",
2099 s
->left_overhang
, s
->right_overhang
);
2100 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2101 fprintf (stderr
, " extends to end of line = %d\n",
2102 s
->extends_to_end_of_line_p
);
2103 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2104 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2107 #endif /* GLYPH_DEBUG */
2111 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2112 struct glyph_string
**,
2113 struct glyph_string
*,
2114 struct glyph_string
*));
2115 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2116 struct glyph_string
**,
2117 struct glyph_string
*,
2118 struct glyph_string
*));
2119 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2120 struct glyph_string
**,
2121 struct glyph_string
*));
2122 static int x_left_overwritten
P_ ((struct glyph_string
*));
2123 static int x_left_overwriting
P_ ((struct glyph_string
*));
2124 static int x_right_overwritten
P_ ((struct glyph_string
*));
2125 static int x_right_overwriting
P_ ((struct glyph_string
*));
2126 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int, int,
2128 static void x_init_glyph_string
P_ ((struct glyph_string
*,
2129 XChar2b
*, struct window
*,
2131 enum glyph_row_area
, int,
2132 enum draw_glyphs_face
));
2133 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2134 enum glyph_row_area
, int, int,
2135 enum draw_glyphs_face
, int *, int *, int));
2136 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2137 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2138 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2140 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2141 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2142 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2143 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2144 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2145 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2146 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2147 static void x_get_glyph_overhangs
P_ ((struct glyph
*, struct frame
*,
2149 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2150 static int x_alloc_lighter_color
P_ ((struct frame
*, Display
*, Colormap
,
2151 unsigned long *, double, int));
2152 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2153 double, int, unsigned long));
2154 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2155 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2156 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2157 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2158 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
2159 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2160 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2162 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2163 int, int, int, int, XRectangle
*));
2164 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2165 int, int, int, XRectangle
*));
2166 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2167 enum glyph_row_area
));
2170 /* Append the list of glyph strings with head H and tail T to the list
2171 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2174 x_append_glyph_string_lists (head
, tail
, h
, t
)
2175 struct glyph_string
**head
, **tail
;
2176 struct glyph_string
*h
, *t
;
2190 /* Prepend the list of glyph strings with head H and tail T to the
2191 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2195 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2196 struct glyph_string
**head
, **tail
;
2197 struct glyph_string
*h
, *t
;
2211 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2212 Set *HEAD and *TAIL to the resulting list. */
2215 x_append_glyph_string (head
, tail
, s
)
2216 struct glyph_string
**head
, **tail
;
2217 struct glyph_string
*s
;
2219 s
->next
= s
->prev
= NULL
;
2220 x_append_glyph_string_lists (head
, tail
, s
, s
);
2224 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2229 struct glyph_string
*s
;
2231 if (s
->font
== FRAME_FONT (s
->f
)
2232 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2233 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2235 s
->gc
= s
->f
->output_data
.x
->cursor_gc
;
2238 /* Cursor on non-default face: must merge. */
2242 xgcv
.background
= s
->f
->output_data
.x
->cursor_pixel
;
2243 xgcv
.foreground
= s
->face
->background
;
2245 /* If the glyph would be invisible, try a different foreground. */
2246 if (xgcv
.foreground
== xgcv
.background
)
2247 xgcv
.foreground
= s
->face
->foreground
;
2248 if (xgcv
.foreground
== xgcv
.background
)
2249 xgcv
.foreground
= s
->f
->output_data
.x
->cursor_foreground_pixel
;
2250 if (xgcv
.foreground
== xgcv
.background
)
2251 xgcv
.foreground
= s
->face
->foreground
;
2253 /* Make sure the cursor is distinct from text in this face. */
2254 if (xgcv
.background
== s
->face
->background
2255 && xgcv
.foreground
== s
->face
->foreground
)
2257 xgcv
.background
= s
->face
->foreground
;
2258 xgcv
.foreground
= s
->face
->background
;
2261 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2262 xgcv
.font
= s
->font
->fid
;
2263 xgcv
.graphics_exposures
= False
;
2264 mask
= GCForeground
| GCBackground
| GCFont
| GCGraphicsExposures
;
2266 if (FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2267 XChangeGC (s
->display
, FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2270 FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2271 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
2273 s
->gc
= FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2278 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2281 x_set_mouse_face_gc (s
)
2282 struct glyph_string
*s
;
2286 /* What face has to be used for the mouse face? */
2287 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2288 face_id
= FACE_FOR_CHARSET (s
->f
, face_id
, s
->charset
);
2289 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2290 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2292 /* If font in this face is same as S->font, use it. */
2293 if (s
->font
== s
->face
->font
)
2294 s
->gc
= s
->face
->gc
;
2297 /* Otherwise construct scratch_cursor_gc with values from FACE
2302 xgcv
.background
= s
->face
->background
;
2303 xgcv
.foreground
= s
->face
->foreground
;
2304 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2305 xgcv
.font
= s
->font
->fid
;
2306 xgcv
.graphics_exposures
= False
;
2307 mask
= GCForeground
| GCBackground
| GCFont
| GCGraphicsExposures
;
2309 if (FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2310 XChangeGC (s
->display
, FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2313 FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2314 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
2316 s
->gc
= FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2319 xassert (s
->gc
!= 0);
2323 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2324 Faces to use in the mode line have already been computed when the
2325 matrix was built, so there isn't much to do, here. */
2328 x_set_mode_line_face_gc (s
)
2329 struct glyph_string
*s
;
2331 s
->gc
= s
->face
->gc
;
2332 xassert (s
->gc
!= 0);
2336 /* Set S->gc of glyph string S for drawing that glyph string. Set
2337 S->stippled_p to a non-zero value if the face of S has a stipple
2341 x_set_glyph_string_gc (s
)
2342 struct glyph_string
*s
;
2344 if (s
->hl
== DRAW_NORMAL_TEXT
)
2346 s
->gc
= s
->face
->gc
;
2347 s
->stippled_p
= s
->face
->stipple
!= 0;
2349 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
2351 x_set_mode_line_face_gc (s
);
2352 s
->stippled_p
= s
->face
->stipple
!= 0;
2354 else if (s
->hl
== DRAW_CURSOR
)
2356 x_set_cursor_gc (s
);
2359 else if (s
->hl
== DRAW_MOUSE_FACE
)
2361 x_set_mouse_face_gc (s
);
2362 s
->stippled_p
= s
->face
->stipple
!= 0;
2364 else if (s
->hl
== DRAW_IMAGE_RAISED
2365 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2367 s
->gc
= s
->face
->gc
;
2368 s
->stippled_p
= s
->face
->stipple
!= 0;
2372 s
->gc
= s
->face
->gc
;
2373 s
->stippled_p
= s
->face
->stipple
!= 0;
2376 /* GC must have been set. */
2377 xassert (s
->gc
!= 0);
2381 /* Return in *R the clipping rectangle for glyph string S. */
2384 x_get_glyph_string_clip_rect (s
, r
)
2385 struct glyph_string
*s
;
2388 if (s
->row
->full_width_p
)
2390 /* Draw full-width. X coordinates are relative to S->w->left. */
2391 int canon_x
= CANON_X_UNIT (s
->f
);
2393 r
->x
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
2394 r
->width
= XFASTINT (s
->w
->width
) * canon_x
;
2396 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
2398 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
2399 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
2403 r
->x
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
2405 /* Unless displaying a mode or menu bar line, which are always
2406 fully visible, clip to the visible part of the row. */
2407 if (s
->w
->pseudo_window_p
)
2408 r
->height
= s
->row
->visible_height
;
2410 r
->height
= s
->height
;
2414 /* This is a text line that may be partially visible. */
2415 r
->x
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
2416 r
->width
= window_box_width (s
->w
, s
->area
);
2417 r
->height
= s
->row
->visible_height
;
2420 /* Don't use S->y for clipping because it doesn't take partially
2421 visible lines into account. For example, it can be negative for
2422 partially visible lines at the top of a window. */
2423 if (!s
->row
->full_width_p
2424 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
2425 r
->y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2427 r
->y
= max (0, s
->row
->y
);
2429 /* If drawing a tool-bar window, draw it over the internal border
2430 at the top of the window. */
2431 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
2432 r
->y
-= s
->f
->output_data
.x
->internal_border_width
;
2434 /* If S draws overlapping rows, it's sufficient to use the top and
2435 bottom of the window for clipping because this glyph string
2436 intentionally draws over other lines. */
2437 if (s
->for_overlaps_p
)
2439 r
->y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2440 r
->height
= window_text_bottom_y (s
->w
) - r
->y
;
2443 r
->y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->y
);
2447 /* Set clipping for output of glyph string S. S may be part of a mode
2448 line or menu if we don't have X toolkit support. */
2451 x_set_glyph_string_clipping (s
)
2452 struct glyph_string
*s
;
2455 x_get_glyph_string_clip_rect (s
, &r
);
2456 XSetClipRectangles (s
->display
, s
->gc
, 0, 0, &r
, 1, Unsorted
);
2460 /* Compute left and right overhang of glyph string S. If S is a glyph
2461 string for a composite character, assume overhangs don't exist. */
2464 x_compute_glyph_string_overhangs (s
)
2465 struct glyph_string
*s
;
2467 if (s
->cmpcharp
== NULL
2468 && s
->first_glyph
->type
== CHAR_GLYPH
)
2471 int direction
, font_ascent
, font_descent
;
2472 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
2473 &font_ascent
, &font_descent
, &cs
);
2474 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
2475 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
2480 /* Compute overhangs and x-positions for glyph string S and its
2481 predecessors, or successors. X is the starting x-position for S.
2482 BACKWARD_P non-zero means process predecessors. */
2485 x_compute_overhangs_and_x (s
, x
, backward_p
)
2486 struct glyph_string
*s
;
2494 x_compute_glyph_string_overhangs (s
);
2504 x_compute_glyph_string_overhangs (s
);
2513 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
2514 frame F. Overhangs of glyphs other than type CHAR_GLYPH or of
2515 character glyphs for composite characters are assumed to be zero. */
2518 x_get_glyph_overhangs (glyph
, f
, left
, right
)
2519 struct glyph
*glyph
;
2527 if (glyph
->type
== CHAR_GLYPH
2528 && (c
= glyph
->u
.ch
.code
,
2529 CHAR_CHARSET (c
) != CHARSET_COMPOSITION
))
2533 struct font_info
*font_info
;
2536 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
);
2538 font_info
= FONT_INFO_FROM_ID (f
, face
->font_info_id
);
2541 XCharStruct
*pcm
= x_per_char_metric (font
, &char2b
);
2543 if (pcm
->rbearing
> pcm
->width
)
2544 *right
= pcm
->rbearing
- pcm
->width
;
2545 if (pcm
->lbearing
< 0)
2546 *left
= -pcm
->lbearing
;
2552 /* Return the index of the first glyph preceding glyph string S that
2553 is overwritten by S because of S's left overhang. Value is -1
2554 if no glyphs are overwritten. */
2557 x_left_overwritten (s
)
2558 struct glyph_string
*s
;
2562 if (s
->left_overhang
)
2565 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2566 int first
= s
->first_glyph
- glyphs
;
2568 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
2569 x
-= glyphs
[i
].pixel_width
;
2580 /* Return the index of the first glyph preceding glyph string S that
2581 is overwriting S because of its right overhang. Value is -1 if no
2582 glyph in front of S overwrites S. */
2585 x_left_overwriting (s
)
2586 struct glyph_string
*s
;
2589 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2590 int first
= s
->first_glyph
- glyphs
;
2594 for (i
= first
- 1; i
>= 0; --i
)
2597 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
2600 x
-= glyphs
[i
].pixel_width
;
2607 /* Return the index of the last glyph following glyph string S that is
2608 not overwritten by S because of S's right overhang. Value is -1 if
2609 no such glyph is found. */
2612 x_right_overwritten (s
)
2613 struct glyph_string
*s
;
2617 if (s
->right_overhang
)
2620 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2621 int first
= (s
->first_glyph
- glyphs
) + (s
->cmpcharp
? 1 : s
->nchars
);
2622 int end
= s
->row
->used
[s
->area
];
2624 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
2625 x
+= glyphs
[i
].pixel_width
;
2634 /* Return the index of the last glyph following glyph string S that
2635 overwrites S because of its left overhang. Value is negative
2636 if no such glyph is found. */
2639 x_right_overwriting (s
)
2640 struct glyph_string
*s
;
2643 int end
= s
->row
->used
[s
->area
];
2644 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2645 int first
= (s
->first_glyph
- glyphs
) + (s
->cmpcharp
? 1 : s
->nchars
);
2649 for (i
= first
; i
< end
; ++i
)
2652 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
2655 x
+= glyphs
[i
].pixel_width
;
2662 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
2665 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
2666 struct glyph_string
*s
;
2670 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
, &xgcv
);
2671 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
2672 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
2673 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
2677 /* Draw the background of glyph_string S. If S->background_filled_p
2678 is non-zero don't draw it. FORCE_P non-zero means draw the
2679 background even if it wouldn't be drawn normally. This is used
2680 when a string preceding S draws into the background of S. */
2683 x_draw_glyph_string_background (s
, force_p
)
2684 struct glyph_string
*s
;
2687 /* Nothing to do if background has already been drawn or if it
2688 shouldn't be drawn in the first place. */
2689 if (!s
->background_filled_p
)
2693 && !s
->font_not_found_p
2694 && !s
->extends_to_end_of_line_p
)
2696 /* Don't draw background for glyphs of a composite
2697 characters, except for the first one. */
2698 s
->background_filled_p
= 1;
2700 else if (s
->stippled_p
)
2702 /* Fill background with a stipple pattern. */
2703 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2704 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
2705 s
->y
+ s
->face
->box_line_width
,
2706 s
->background_width
,
2707 s
->height
- 2 * s
->face
->box_line_width
);
2708 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2709 s
->background_filled_p
= 1;
2711 else if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * s
->face
->box_line_width
2712 || s
->font_not_found_p
2713 || s
->extends_to_end_of_line_p
2717 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ s
->face
->box_line_width
,
2718 s
->background_width
,
2719 s
->height
- 2 * s
->face
->box_line_width
);
2720 s
->background_filled_p
= 1;
2726 /* Draw the foreground of glyph string S. */
2729 x_draw_glyph_string_foreground (s
)
2730 struct glyph_string
*s
;
2734 /* If first glyph of S has a left box line, start drawing the text
2735 of S to the right of that box line. */
2736 if (s
->face
->box
!= FACE_NO_BOX
2737 && s
->first_glyph
->left_box_line_p
)
2738 x
= s
->x
+ s
->face
->box_line_width
;
2742 if (s
->cmpcharp
== NULL
)
2744 /* Not a composite character. Draw characters of S as
2745 rectangles if S's font could not be loaded. */
2746 if (s
->font_not_found_p
)
2748 for (i
= 0; i
< s
->nchars
; ++i
)
2750 struct glyph
*g
= s
->first_glyph
+ i
;
2751 XDrawRectangle (s
->display
, s
->window
,
2752 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
2754 x
+= g
->pixel_width
;
2759 char *char1b
= (char *) s
->char2b
;
2761 /* If we can use 8-bit functions, condense S->char2b. */
2763 for (i
= 0; i
< s
->nchars
; ++i
)
2764 char1b
[i
] = s
->char2b
[i
].byte2
;
2766 /* Draw text with XDrawString if background has already been
2767 filled. Otherwise, use XDrawImageString. (Note that
2768 XDrawImageString is usually faster than XDrawString.)
2769 Always use XDrawImageString when drawing the cursor so
2770 that there is no chance that characters under a box
2771 cursor are invisible. */
2772 if (s
->for_overlaps_p
2773 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
2775 /* Draw characters with 16-bit or 8-bit functions. */
2777 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
, s
->ybase
,
2778 s
->char2b
, s
->nchars
);
2780 XDrawString (s
->display
, s
->window
, s
->gc
, x
, s
->ybase
,
2786 XDrawImageString16 (s
->display
, s
->window
, s
->gc
,
2787 x
, s
->ybase
, s
->char2b
, s
->nchars
);
2789 XDrawImageString (s
->display
, s
->window
, s
->gc
,
2790 x
, s
->ybase
, char1b
, s
->nchars
);
2796 /* S is a glyph string for a composite character. S->gidx is the
2797 index of the first character drawn in the vector
2798 S->cmpcharp->glyph. S->gidx == 0 means we are drawing the
2799 very first component character of a composite char. */
2801 /* Draw a single rectangle for the composite character if S's
2802 font could not be loaded. */
2803 if (s
->font_not_found_p
&& s
->gidx
== 0)
2804 XDrawRectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
2805 s
->width
- 1, s
->height
- 1);
2809 int relative_compose
, default_ascent
, i
;
2810 int highest
= 0, lowest
= 0;
2812 /* The value of font_info my be null if we couldn't find it
2813 in x_get_char_face_and_encoding. */
2814 if (s
->cmpcharp
->cmp_rule
== NULL
&& s
->font_info
)
2816 relative_compose
= s
->font_info
->relative_compose
;
2817 default_ascent
= s
->font_info
->default_ascent
;
2820 relative_compose
= default_ascent
= 0;
2822 if ((s
->cmpcharp
->cmp_rule
|| relative_compose
)
2825 /* This is the first character. Initialize variables.
2826 Highest is the highest position of glyphs ever
2827 written, lowest the lowest position. */
2829 int first_ch
= s
->first_glyph
->u
.ch
.code
;
2832 && CHAR_TABLE_P (Vuse_default_ascent
)
2833 && !NILP (Faref (Vuse_default_ascent
, first_ch
)))
2835 highest
= default_ascent
;
2840 pcm
= PER_CHAR_METRIC (s
->font
, s
->char2b
);
2841 highest
= pcm
->ascent
+ 1;
2842 lowest
= - pcm
->descent
;
2845 if (s
->cmpcharp
->cmp_rule
)
2846 x_offset
= (s
->cmpcharp
->col_offset
[0]
2847 * FONT_WIDTH (s
->f
->output_data
.x
->font
));
2849 /* Draw the first character at the normal position. */
2850 XDrawString16 (s
->display
, s
->window
, s
->gc
,
2852 s
->ybase
, s
->char2b
, 1);
2859 for (; i
< s
->nchars
; i
++, ++s
->gidx
)
2861 int x_offset
= 0, y_offset
= 0;
2863 if (relative_compose
)
2865 pcm
= PER_CHAR_METRIC (s
->font
, s
->char2b
+ i
);
2866 if (NILP (Vignore_relative_composition
)
2867 || NILP (Faref (Vignore_relative_composition
,
2868 make_number (s
->cmpcharp
->glyph
[s
->gidx
]))))
2870 if (- pcm
->descent
>= relative_compose
)
2872 /* Draw above the current glyphs. */
2873 y_offset
= highest
+ pcm
->descent
;
2874 highest
+= pcm
->ascent
+ pcm
->descent
;
2876 else if (pcm
->ascent
<= 0)
2878 /* Draw beneath the current glyphs. */
2879 y_offset
= lowest
- pcm
->ascent
;
2880 lowest
-= pcm
->ascent
+ pcm
->descent
;
2885 /* Draw the glyph at normal position. If
2886 it sticks out of HIGHEST or LOWEST,
2887 update them appropriately. */
2888 if (pcm
->ascent
> highest
)
2889 highest
= pcm
->ascent
;
2890 else if (- pcm
->descent
< lowest
)
2891 lowest
= - pcm
->descent
;
2894 else if (s
->cmpcharp
->cmp_rule
)
2896 int gref
= (s
->cmpcharp
->cmp_rule
[s
->gidx
] - 0xA0) / 9;
2897 int nref
= (s
->cmpcharp
->cmp_rule
[s
->gidx
] - 0xA0) % 9;
2900 /* Re-encode GREF and NREF so that they specify
2901 only Y-axis information:
2902 0:top, 1:base, 2:bottom, 3:center */
2903 gref
= gref
/ 3 + (gref
== 4) * 2;
2904 nref
= nref
/ 3 + (nref
== 4) * 2;
2906 pcm
= PER_CHAR_METRIC (s
->font
, s
->char2b
+ i
);
2907 bottom
= ((gref
== 0 ? highest
: gref
== 1 ? 0
2908 : gref
== 2 ? lowest
2909 : (highest
+ lowest
) / 2)
2910 - (nref
== 0 ? pcm
->ascent
+ pcm
->descent
2911 : nref
== 1 ? pcm
->descent
: nref
== 2 ? 0
2912 : (pcm
->ascent
+ pcm
->descent
) / 2));
2913 top
= bottom
+ (pcm
->ascent
+ pcm
->descent
);
2916 if (bottom
< lowest
)
2918 y_offset
= bottom
+ pcm
->descent
;
2919 x_offset
= (s
->cmpcharp
->col_offset
[s
->gidx
]
2920 * FONT_WIDTH (FRAME_FONT (s
->f
)));
2923 XDrawString16 (s
->display
, s
->window
, s
->gc
,
2924 x
+ x_offset
, s
->ybase
- y_offset
,
2932 #ifdef USE_X_TOOLKIT
2934 /* Allocate the color COLOR->pixel on the screen and display of
2935 widget WIDGET in colormap CMAP. If an exact match cannot be
2936 allocated, try the nearest color available. Value is non-zero
2937 if successful. This is called from lwlib. */
2940 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
2946 struct x_display_info
*dpyinfo
;
2949 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
2951 /* Find the top-level shell of the widget. Note that this function
2952 can be called when the widget is not yet realized, so XtWindow
2953 (widget) == 0. That's the reason we can't simply use
2954 x_any_window_to_frame. */
2955 while (!XtIsTopLevelShell (widget
))
2956 widget
= XtParent (widget
);
2958 /* Look for a frame with that top-level widget. Allocate the color
2959 on that frame to get the right gamma correction value. */
2960 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
2961 if (GC_FRAMEP (XCAR (tail
))
2962 && (f
= XFRAME (XCAR (tail
)),
2963 (f
->output_data
.nothing
!= 1
2964 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
2965 && f
->output_data
.x
->widget
== widget
)
2966 return x_alloc_nearest_color (f
, cmap
, color
);
2971 #endif /* USE_X_TOOLKIT */
2974 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
2975 CMAP. If an exact match can't be allocated, try the nearest color
2976 available. Value is non-zero if successful. Set *COLOR to the
2980 x_alloc_nearest_color (f
, cmap
, color
)
2985 Display
*display
= FRAME_X_DISPLAY (f
);
2986 Screen
*screen
= FRAME_X_SCREEN (f
);
2989 gamma_correct (f
, color
);
2990 rc
= XAllocColor (display
, cmap
, color
);
2993 /* If we got to this point, the colormap is full, so we're going
2994 to try to get the next closest color. The algorithm used is
2995 a least-squares matching, which is what X uses for closest
2996 color matching with StaticColor visuals. */
2998 unsigned long nearest_delta
= ~0;
2999 int ncells
= XDisplayCells (display
, XScreenNumberOfScreen (screen
));
3000 XColor
*cells
= (XColor
*) alloca (ncells
* sizeof *cells
);
3002 for (i
= 0; i
< ncells
; ++i
)
3004 XQueryColors (display
, cmap
, cells
, ncells
);
3006 for (nearest
= i
= 0; i
< ncells
; ++i
)
3008 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
3009 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
3010 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
3011 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
3013 if (delta
< nearest_delta
)
3016 nearest_delta
= delta
;
3020 color
->red
= cells
[nearest
].red
;
3021 color
->green
= cells
[nearest
].green
;
3022 color
->blue
= cells
[nearest
].blue
;
3023 rc
= XAllocColor (display
, cmap
, color
);
3030 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
3031 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3032 If this produces the same color as PIXEL, try a color where all RGB
3033 values have DELTA added. Return the allocated color in *PIXEL.
3034 DISPLAY is the X display, CMAP is the colormap to operate on.
3035 Value is non-zero if successful. */
3038 x_alloc_lighter_color (f
, display
, cmap
, pixel
, factor
, delta
)
3042 unsigned long *pixel
;
3049 /* Get RGB color values. */
3050 color
.pixel
= *pixel
;
3051 XQueryColor (display
, cmap
, &color
);
3053 /* Change RGB values by specified FACTOR. Avoid overflow! */
3054 xassert (factor
>= 0);
3055 new.red
= min (0xffff, factor
* color
.red
);
3056 new.green
= min (0xffff, factor
* color
.green
);
3057 new.blue
= min (0xffff, factor
* color
.blue
);
3059 /* Try to allocate the color. */
3060 success_p
= x_alloc_nearest_color (f
, cmap
, &new);
3063 if (new.pixel
== *pixel
)
3065 /* If we end up with the same color as before, try adding
3066 delta to the RGB values. */
3067 int class = FRAME_X_DISPLAY_INFO (f
)->visual
->class;
3069 /* If display has an immutable color map, freeing colors is
3070 not necessary and some servers don't allow it. So don't
3072 if (class != StaticColor
3073 && class != StaticGray
3074 && class != TrueColor
)
3075 XFreeColors (display
, cmap
, &new.pixel
, 1, 0);
3077 new.red
= min (0xffff, delta
+ color
.red
);
3078 new.green
= min (0xffff, delta
+ color
.green
);
3079 new.blue
= min (0xffff, delta
+ color
.blue
);
3080 success_p
= x_alloc_nearest_color (f
, cmap
, &new);
3091 /* Set up the foreground color for drawing relief lines of glyph
3092 string S. RELIEF is a pointer to a struct relief containing the GC
3093 with which lines will be drawn. Use a color that is FACTOR or
3094 DELTA lighter or darker than the relief's background which is found
3095 in S->f->output_data.x->relief_background. If such a color cannot
3096 be allocated, use DEFAULT_PIXEL, instead. */
3099 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3101 struct relief
*relief
;
3104 unsigned long default_pixel
;
3107 struct x_output
*di
= f
->output_data
.x
;
3108 unsigned long mask
= GCForeground
| GCLineWidth
| GCGraphicsExposures
;
3109 unsigned long pixel
;
3110 unsigned long background
= di
->relief_background
;
3111 Colormap cmap
= DefaultColormapOfScreen (FRAME_X_SCREEN (f
));
3112 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3113 Display
*dpy
= FRAME_X_DISPLAY (f
);
3115 xgcv
.graphics_exposures
= False
;
3116 xgcv
.line_width
= 1;
3118 /* Free previously allocated color. The color cell will be reused
3119 when it has been freed as many times as it was allocated, so this
3120 doesn't affect faces using the same colors. */
3122 && relief
->allocated_p
)
3124 /* If display has an immutable color map, freeing colors is not
3125 necessary and some servers don't allow it. So don't do it. */
3126 int class = dpyinfo
->visual
->class;
3127 if (class != StaticColor
3128 && class != StaticGray
3129 && class != TrueColor
)
3130 XFreeColors (dpy
, cmap
, &relief
->pixel
, 1, 0);
3131 relief
->allocated_p
= 0;
3134 /* Allocate new color. */
3135 xgcv
.foreground
= default_pixel
;
3137 if (dpyinfo
->n_planes
!= 1
3138 && x_alloc_lighter_color (f
, dpy
, cmap
, &pixel
, factor
, delta
))
3140 relief
->allocated_p
= 1;
3141 xgcv
.foreground
= relief
->pixel
= pixel
;
3144 if (relief
->gc
== 0)
3146 xgcv
.stipple
= dpyinfo
->gray
;
3148 relief
->gc
= XCreateGC (dpy
, FRAME_X_WINDOW (f
), mask
, &xgcv
);
3151 XChangeGC (dpy
, relief
->gc
, mask
, &xgcv
);
3155 /* Set up colors for the relief lines around glyph string S. */
3158 x_setup_relief_colors (s
)
3159 struct glyph_string
*s
;
3161 struct x_output
*di
= s
->f
->output_data
.x
;
3162 unsigned long color
;
3164 if (s
->face
->use_box_color_for_shadows_p
)
3165 color
= s
->face
->box_color
;
3170 /* Get the background color of the face. */
3171 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
3172 color
= xgcv
.background
;
3175 if (di
->white_relief
.gc
== 0
3176 || color
!= di
->relief_background
)
3178 di
->relief_background
= color
;
3179 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3180 WHITE_PIX_DEFAULT (s
->f
));
3181 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3182 BLACK_PIX_DEFAULT (s
->f
));
3187 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3188 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3189 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3190 relief. LEFT_P non-zero means draw a relief on the left side of
3191 the rectangle. RIGHT_P non-zero means draw a relief on the right
3192 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3196 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3197 raised_p
, left_p
, right_p
, clip_rect
)
3199 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
3200 XRectangle
*clip_rect
;
3206 gc
= f
->output_data
.x
->white_relief
.gc
;
3208 gc
= f
->output_data
.x
->black_relief
.gc
;
3209 XSetClipRectangles (FRAME_X_DISPLAY (f
), gc
, 0, 0, clip_rect
, 1, Unsorted
);
3212 for (i
= 0; i
< width
; ++i
)
3213 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
3214 left_x
+ i
* left_p
, top_y
+ i
,
3215 right_x
+ 1 - i
* right_p
, top_y
+ i
);
3219 for (i
= 0; i
< width
; ++i
)
3220 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
3221 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
);
3223 XSetClipMask (FRAME_X_DISPLAY (f
), gc
, None
);
3225 gc
= f
->output_data
.x
->black_relief
.gc
;
3227 gc
= f
->output_data
.x
->white_relief
.gc
;
3228 XSetClipRectangles (FRAME_X_DISPLAY (f
), gc
, 0, 0, clip_rect
, 1, Unsorted
);
3231 for (i
= 0; i
< width
; ++i
)
3232 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
3233 left_x
+ i
* left_p
, bottom_y
- i
,
3234 right_x
+ 1 - i
* right_p
, bottom_y
- i
);
3238 for (i
= 0; i
< width
; ++i
)
3239 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
3240 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
);
3242 XSetClipMask (FRAME_X_DISPLAY (f
), gc
, None
);
3246 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3247 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3248 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3249 left side of the rectangle. RIGHT_P non-zero means draw a line
3250 on the right side of the rectangle. CLIP_RECT is the clipping
3251 rectangle to use when drawing. */
3254 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3255 left_p
, right_p
, clip_rect
)
3256 struct glyph_string
*s
;
3257 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
;
3258 XRectangle
*clip_rect
;
3262 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3263 XSetForeground (s
->display
, s
->gc
, s
->face
->box_color
);
3264 XSetClipRectangles (s
->display
, s
->gc
, 0, 0, clip_rect
, 1, Unsorted
);
3267 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3268 left_x
, top_y
, right_x
- left_x
, width
);
3272 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3273 left_x
, top_y
, width
, bottom_y
- top_y
);
3276 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3277 left_x
, bottom_y
- width
, right_x
- left_x
, width
);
3281 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3282 right_x
- width
, top_y
, width
, bottom_y
- top_y
);
3284 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3285 XSetClipMask (s
->display
, s
->gc
, None
);
3289 /* Draw a box around glyph string S. */
3292 x_draw_glyph_string_box (s
)
3293 struct glyph_string
*s
;
3295 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3296 int left_p
, right_p
;
3297 struct glyph
*last_glyph
;
3298 XRectangle clip_rect
;
3300 last_x
= window_box_right (s
->w
, s
->area
);
3301 if (s
->row
->full_width_p
3302 && !s
->w
->pseudo_window_p
)
3304 last_x
+= FRAME_X_RIGHT_FLAGS_AREA_WIDTH (s
->f
);
3305 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
3306 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
3309 /* The glyph that may have a right box line. */
3310 last_glyph
= (s
->cmpcharp
|| s
->img
3312 : s
->first_glyph
+ s
->nchars
- 1);
3314 width
= s
->face
->box_line_width
;
3315 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3317 right_x
= ((s
->row
->full_width_p
3319 : min (last_x
, s
->x
+ s
->background_width
) - 1));
3321 bottom_y
= top_y
+ s
->height
- 1;
3323 left_p
= (s
->first_glyph
->left_box_line_p
3324 || (s
->hl
== DRAW_MOUSE_FACE
3326 || s
->prev
->hl
!= s
->hl
)));
3327 right_p
= (last_glyph
->right_box_line_p
3328 || (s
->hl
== DRAW_MOUSE_FACE
3330 || s
->next
->hl
!= s
->hl
)));
3332 x_get_glyph_string_clip_rect (s
, &clip_rect
);
3334 if (s
->face
->box
== FACE_SIMPLE_BOX
)
3335 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3336 left_p
, right_p
, &clip_rect
);
3339 x_setup_relief_colors (s
);
3340 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
3341 width
, raised_p
, left_p
, right_p
, &clip_rect
);
3346 /* Draw foreground of image glyph string S. */
3349 x_draw_image_foreground (s
)
3350 struct glyph_string
*s
;
3353 int y
= s
->ybase
- IMAGE_ASCENT (s
->img
);
3355 /* If first glyph of S has a left box line, start drawing it to the
3356 right of that line. */
3357 if (s
->face
->box
!= FACE_NO_BOX
3358 && s
->first_glyph
->left_box_line_p
)
3359 x
= s
->x
+ s
->face
->box_line_width
;
3363 /* If there is a margin around the image, adjust x- and y-position
3367 x
+= s
->img
->margin
;
3368 y
+= s
->img
->margin
;
3375 /* We can't set both a clip mask and use XSetClipRectangles
3376 because the latter also sets a clip mask. We also can't
3377 trust on the shape extension to be available
3378 (XShapeCombineRegion). So, compute the rectangle to draw
3380 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3383 XRectangle clip_rect
, image_rect
, r
;
3385 xgcv
.clip_mask
= s
->img
->mask
;
3386 xgcv
.clip_x_origin
= x
;
3387 xgcv
.clip_y_origin
= y
;
3388 xgcv
.function
= GXcopy
;
3389 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3391 x_get_glyph_string_clip_rect (s
, &clip_rect
);
3394 image_rect
.width
= s
->img
->width
;
3395 image_rect
.height
= s
->img
->height
;
3396 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
3397 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
3398 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
3402 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
3403 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
3405 /* When the image has a mask, we can expect that at
3406 least part of a mouse highlight or a block cursor will
3407 be visible. If the image doesn't have a mask, make
3408 a block cursor visible by drawing a rectangle around
3409 the image. I believe it's looking better if we do
3410 nothing here for mouse-face. */
3411 if (s
->hl
== DRAW_CURSOR
)
3412 XDrawRectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
3413 s
->img
->width
- 1, s
->img
->height
- 1);
3417 /* Draw a rectangle if image could not be loaded. */
3418 XDrawRectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
3419 s
->img
->width
- 1, s
->img
->height
- 1);
3423 /* Draw a relief around the image glyph string S. */
3426 x_draw_image_relief (s
)
3427 struct glyph_string
*s
;
3429 int x0
, y0
, x1
, y1
, thick
, raised_p
;
3432 int y
= s
->ybase
- IMAGE_ASCENT (s
->img
);
3434 /* If first glyph of S has a left box line, start drawing it to the
3435 right of that line. */
3436 if (s
->face
->box
!= FACE_NO_BOX
3437 && s
->first_glyph
->left_box_line_p
)
3438 x
= s
->x
+ s
->face
->box_line_width
;
3442 /* If there is a margin around the image, adjust x- and y-position
3446 x
+= s
->img
->margin
;
3447 y
+= s
->img
->margin
;
3450 if (s
->hl
== DRAW_IMAGE_SUNKEN
3451 || s
->hl
== DRAW_IMAGE_RAISED
)
3453 thick
= tool_bar_button_relief
> 0 ? tool_bar_button_relief
: 3;
3454 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
3458 thick
= abs (s
->img
->relief
);
3459 raised_p
= s
->img
->relief
> 0;
3464 x1
= x
+ s
->img
->width
+ thick
- 1;
3465 y1
= y
+ s
->img
->height
+ thick
- 1;
3467 x_setup_relief_colors (s
);
3468 x_get_glyph_string_clip_rect (s
, &r
);
3469 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
3473 /* Draw the foreground of image glyph string S to PIXMAP. */
3476 x_draw_image_foreground_1 (s
, pixmap
)
3477 struct glyph_string
*s
;
3481 int y
= s
->ybase
- s
->y
- IMAGE_ASCENT (s
->img
);
3483 /* If first glyph of S has a left box line, start drawing it to the
3484 right of that line. */
3485 if (s
->face
->box
!= FACE_NO_BOX
3486 && s
->first_glyph
->left_box_line_p
)
3487 x
= s
->face
->box_line_width
;
3491 /* If there is a margin around the image, adjust x- and y-position
3495 x
+= s
->img
->margin
;
3496 y
+= s
->img
->margin
;
3503 /* We can't set both a clip mask and use XSetClipRectangles
3504 because the latter also sets a clip mask. We also can't
3505 trust on the shape extension to be available
3506 (XShapeCombineRegion). So, compute the rectangle to draw
3508 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
3512 xgcv
.clip_mask
= s
->img
->mask
;
3513 xgcv
.clip_x_origin
= x
;
3514 xgcv
.clip_y_origin
= y
;
3515 xgcv
.function
= GXcopy
;
3516 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
3518 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
3519 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
3520 XSetClipMask (s
->display
, s
->gc
, None
);
3524 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
3525 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
3527 /* When the image has a mask, we can expect that at
3528 least part of a mouse highlight or a block cursor will
3529 be visible. If the image doesn't have a mask, make
3530 a block cursor visible by drawing a rectangle around
3531 the image. I believe it's looking better if we do
3532 nothing here for mouse-face. */
3533 if (s
->hl
== DRAW_CURSOR
)
3534 XDrawRectangle (s
->display
, pixmap
, s
->gc
, x
, y
,
3535 s
->img
->width
- 1, s
->img
->height
- 1);
3539 /* Draw a rectangle if image could not be loaded. */
3540 XDrawRectangle (s
->display
, pixmap
, s
->gc
, x
, y
,
3541 s
->img
->width
- 1, s
->img
->height
- 1);
3545 /* Draw part of the background of glyph string S. X, Y, W, and H
3546 give the rectangle to draw. */
3549 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
3550 struct glyph_string
*s
;
3555 /* Fill background with a stipple pattern. */
3556 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3557 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
3558 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3561 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
3565 /* Draw image glyph string S.
3568 s->x +-------------------------
3571 | +-------------------------
3574 | | +-------------------
3580 x_draw_image_glyph_string (s
)
3581 struct glyph_string
*s
;
3584 int box_line_width
= s
->face
->box_line_width
;
3585 int margin
= s
->img
->margin
;
3587 Pixmap pixmap
= None
;
3589 height
= s
->height
- 2 * box_line_width
;
3591 /* Fill background with face under the image. Do it only if row is
3592 taller than image or if image has a clip mask to reduce
3594 s
->stippled_p
= s
->face
->stipple
!= 0;
3595 if (height
> s
->img
->height
3598 || s
->img
->pixmap
== 0
3599 || s
->width
!= s
->background_width
)
3601 if (box_line_width
&& s
->first_glyph
->left_box_line_p
)
3602 x
= s
->x
+ box_line_width
;
3606 y
= s
->y
+ box_line_width
;
3610 /* Create a pixmap as large as the glyph string Fill it with
3611 the background color. Copy the image to it, using its
3612 mask. Copy the temporary pixmap to the display. */
3613 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
3614 int depth
= DefaultDepthOfScreen (screen
);
3616 /* Create a pixmap as large as the glyph string. */
3617 pixmap
= XCreatePixmap (s
->display
, s
->window
,
3618 s
->background_width
,
3621 /* Don't clip in the following because we're working on the
3623 XSetClipMask (s
->display
, s
->gc
, None
);
3625 /* Fill the pixmap with the background color/stipple. */
3628 /* Fill background with a stipple pattern. */
3629 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3630 XFillRectangle (s
->display
, pixmap
, s
->gc
,
3631 0, 0, s
->background_width
, s
->height
);
3632 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3637 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
3639 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
3640 XFillRectangle (s
->display
, pixmap
, s
->gc
,
3641 0, 0, s
->background_width
, s
->height
);
3642 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3646 /* Implementation idea: Is it possible to construct a mask?
3647 We could look at the color at the margins of the image, and
3648 say that this color is probably the background color of the
3650 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
3652 s
->background_filled_p
= 1;
3655 /* Draw the foreground. */
3658 x_draw_image_foreground_1 (s
, pixmap
);
3659 x_set_glyph_string_clipping (s
);
3660 XCopyArea (s
->display
, pixmap
, s
->window
, s
->gc
,
3661 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
3662 XFreePixmap (s
->display
, pixmap
);
3665 x_draw_image_foreground (s
);
3667 /* If we must draw a relief around the image, do it. */
3669 || s
->hl
== DRAW_IMAGE_RAISED
3670 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3671 x_draw_image_relief (s
);
3675 /* Draw stretch glyph string S. */
3678 x_draw_stretch_glyph_string (s
)
3679 struct glyph_string
*s
;
3681 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
3682 s
->stippled_p
= s
->face
->stipple
!= 0;
3684 if (s
->hl
== DRAW_CURSOR
3685 && !x_stretch_cursor_p
)
3687 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
3688 as wide as the stretch glyph. */
3689 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
3692 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
3694 /* Clear rest using the GC of the original non-cursor face. */
3695 if (width
< s
->background_width
)
3697 GC gc
= s
->face
->gc
;
3698 int x
= s
->x
+ width
, y
= s
->y
;
3699 int w
= s
->background_width
- width
, h
= s
->height
;
3702 x_get_glyph_string_clip_rect (s
, &r
);
3703 XSetClipRectangles (s
->display
, gc
, 0, 0, &r
, 1, Unsorted
);
3705 if (s
->face
->stipple
)
3707 /* Fill background with a stipple pattern. */
3708 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
3709 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
3710 XSetFillStyle (s
->display
, gc
, FillSolid
);
3715 XGetGCValues (s
->display
, gc
, GCForeground
| GCBackground
, &xgcv
);
3716 XSetForeground (s
->display
, gc
, xgcv
.background
);
3717 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
3718 XSetForeground (s
->display
, gc
, xgcv
.foreground
);
3723 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
3726 s
->background_filled_p
= 1;
3730 /* Draw glyph string S. */
3733 x_draw_glyph_string (s
)
3734 struct glyph_string
*s
;
3736 /* If S draws into the background of its successor, draw the
3737 background of the successor first so that S can draw into it.
3738 This makes S->next use XDrawString instead of XDrawImageString. */
3739 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
3741 xassert (s
->next
->img
== NULL
);
3742 x_set_glyph_string_gc (s
->next
);
3743 x_set_glyph_string_clipping (s
->next
);
3744 x_draw_glyph_string_background (s
->next
, 1);
3747 /* Set up S->gc, set clipping and draw S. */
3748 x_set_glyph_string_gc (s
);
3749 x_set_glyph_string_clipping (s
);
3751 switch (s
->first_glyph
->type
)
3754 x_draw_image_glyph_string (s
);
3758 x_draw_stretch_glyph_string (s
);
3762 if (s
->for_overlaps_p
)
3763 s
->background_filled_p
= 1;
3765 x_draw_glyph_string_background (s
, 0);
3766 x_draw_glyph_string_foreground (s
);
3773 if (!s
->for_overlaps_p
)
3775 /* Draw underline. */
3776 if (s
->face
->underline_p
)
3778 unsigned long dy
, h
;
3780 if (!XGetFontProperty (s
->font
, XA_UNDERLINE_THICKNESS
, &h
))
3782 if (!XGetFontProperty (s
->font
, XA_UNDERLINE_POSITION
, &dy
))
3785 if (s
->face
->underline_defaulted_p
)
3786 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3791 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3792 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
3793 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3795 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3799 /* Draw overline. */
3800 if (s
->face
->overline_p
)
3802 unsigned long dy
= 0, h
= 1;
3804 if (s
->face
->overline_color_defaulted_p
)
3805 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3810 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3811 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
3812 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3814 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3818 /* Draw strike-through. */
3819 if (s
->face
->strike_through_p
)
3821 unsigned long h
= 1;
3822 unsigned long dy
= (s
->height
- h
) / 2;
3824 if (s
->face
->strike_through_color_defaulted_p
)
3825 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3830 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3831 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
3832 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3834 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3839 if (s
->face
->box
!= FACE_NO_BOX
)
3840 x_draw_glyph_string_box (s
);
3843 /* Reset clipping. */
3844 XSetClipMask (s
->display
, s
->gc
, None
);
3848 /* A work-list entry used during the construction of glyph_string
3849 structures for a composite character. */
3853 /* Pointer to composite char info defining has the composite
3854 character is drawn. */
3855 struct cmpchar_info
*cmpcharp
;
3857 /* Start index in compcharp->glyph[]. */
3860 /* Next in stack. */
3865 static void x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
3866 int, struct work
**,
3867 struct work
**, int));
3870 /* Load glyph string S with information from the top of *STACK for a
3871 composite character. FACE_ID is the id of the face in which S is
3872 drawn. *NEW is a pointer to a struct work not on the stack, that
3873 can be used if this function needs to push a new structure on the
3874 stack. If it uses it, *NEW is set to null. OVERLAPS_P non-zero
3875 means S should draw the foreground only, and use its lines physical
3876 height for clipping. */
3879 x_fill_composite_glyph_string (s
, face_id
, stack
, new, overlaps_p
)
3880 struct glyph_string
*s
;
3882 struct work
**stack
, **new;
3888 xassert (s
&& *new && *stack
);
3890 s
->for_overlaps_p
= 1;
3892 /* Pop the work stack. */
3894 *stack
= work
->next
;
3896 /* For all glyphs of cmpcharp->glyph, starting at the offset
3897 work->offset, until we reach the end of the definition or
3898 encounter another composite char, get the font and face to use,
3900 for (i
= work
->gidx
; i
< work
->cmpcharp
->glyph_len
; ++i
)
3902 c
= FAST_GLYPH_CHAR (work
->cmpcharp
->glyph
[i
]);
3903 if (CHAR_CHARSET (c
) == CHARSET_COMPOSITION
)
3905 s
->face
= x_get_char_face_and_encoding (s
->f
, c
, face_id
,
3906 s
->char2b
+ s
->nchars
, 1);
3907 s
->font
= s
->face
->font
;
3908 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
3912 /* If we find another composite char in the glyph definition of
3913 work->cmpcharp, put back the rest of the glyphs on the work
3914 stack, and make a new entry for the composite char. */
3915 if (i
< work
->cmpcharp
->glyph_len
)
3917 /* Push back an unprocessed rest of this glyph spec. */
3918 if (i
< work
->cmpcharp
->glyph_len
- 1)
3921 work
->next
= *stack
;
3927 /* Make an entry for the composite char on the work stack. */
3928 work
->cmpcharp
= cmpchar_table
[COMPOSITE_CHAR_ID (c
)];
3930 work
->next
= *stack
;
3934 /* The width of this glyph string equals the width of the first
3935 glyph. All characters are drawn at the same x-position. */
3936 s
->width
= s
->first_glyph
->pixel_width
;
3938 /* If the specified font could not be loaded, use the frame's
3939 default font, but record the fact that we couldn't load it in
3940 the glyph string so that we can draw rectangles for the
3941 characters of the glyph string. */
3942 if (s
->font
== NULL
)
3944 s
->font_not_found_p
= 1;
3945 s
->font
= FRAME_FONT (s
->f
);
3948 /* Adjust base line for subscript/superscript text. */
3949 s
->ybase
+= s
->first_glyph
->voffset
;
3951 xassert (s
->face
&& s
->face
->gc
);
3953 /* This glyph string must always be drawn with 16-bit functions. */
3958 /* Load glyph string S with a sequence of non-composite characters.
3959 FACE_ID is the face id of the string. START is the index of the
3960 first glyph to consider, END is the index of the last + 1.
3961 OVERLAPS_P non-zero means S should draw the foreground only, and
3962 use its lines physical height for clipping.
3964 Value is the index of the first glyph not in S. */
3967 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
3968 struct glyph_string
*s
;
3970 int start
, end
, overlaps_p
;
3972 struct glyph
*glyph
, *last
;
3975 xassert (s
->charset
!= CHARSET_COMPOSITION
);
3976 xassert (s
->f
== XFRAME (s
->w
->frame
));
3977 xassert (s
->nchars
== 0);
3978 xassert (start
>= 0 && end
> start
);
3980 s
->for_overlaps_p
= overlaps_p
,
3981 glyph
= s
->row
->glyphs
[s
->area
] + start
;
3982 last
= s
->row
->glyphs
[s
->area
] + end
;
3983 voffset
= glyph
->voffset
;
3986 && glyph
->type
== CHAR_GLYPH
3987 && glyph
->voffset
== voffset
3988 /* Same face id implies same charset, nowadays. */
3989 && glyph
->u
.ch
.face_id
== face_id
)
3991 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
3992 s
->char2b
+ s
->nchars
);
3993 if (s
->char2b
[s
->nchars
].byte2
!= 0)
3997 xassert (s
->nchars
<= end
- start
);
3998 s
->width
+= glyph
->pixel_width
;
4002 s
->font
= s
->face
->font
;
4003 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4005 /* If the specified font could not be loaded, use the frame's font,
4006 but record the fact that we couldn't load it in
4007 S->font_not_found_p so that we can draw rectangles for the
4008 characters of the glyph string. */
4009 if (s
->font
== NULL
)
4011 s
->font_not_found_p
= 1;
4012 s
->font
= FRAME_FONT (s
->f
);
4015 /* Adjust base line for subscript/superscript text. */
4016 s
->ybase
+= voffset
;
4018 xassert (s
->face
&& s
->face
->gc
);
4019 return glyph
- s
->row
->glyphs
[s
->area
];
4023 /* Fill glyph string S from image glyph S->first_glyph. */
4026 x_fill_image_glyph_string (s
)
4027 struct glyph_string
*s
;
4029 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4030 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img
.id
);
4032 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->u
.img
.face_id
);
4033 s
->font
= s
->face
->font
;
4034 s
->width
= s
->first_glyph
->pixel_width
;
4036 /* Adjust base line for subscript/superscript text. */
4037 s
->ybase
+= s
->first_glyph
->voffset
;
4041 /* Fill glyph string S from stretch glyph S->first_glyph. */
4044 x_fill_stretch_glyph_string (s
)
4045 struct glyph_string
*s
;
4047 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4048 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->u
.stretch
.face_id
);
4049 s
->font
= s
->face
->font
;
4050 s
->width
= s
->first_glyph
->pixel_width
;
4052 /* Adjust base line for subscript/superscript text. */
4053 s
->ybase
+= s
->first_glyph
->voffset
;
4057 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4058 of XChar2b structures for S; it can't be allocated in
4059 x_init_glyph_string because it must be allocated via `alloca'. W
4060 is the window on which S is drawn. ROW and AREA are the glyph row
4061 and area within the row from which S is constructed. START is the
4062 index of the first glyph structure covered by S. HL is a
4063 face-override for drawing S. */
4066 x_init_glyph_string (s
, char2b
, w
, row
, area
, start
, hl
)
4067 struct glyph_string
*s
;
4070 struct glyph_row
*row
;
4071 enum glyph_row_area area
;
4073 enum draw_glyphs_face hl
;
4075 bzero (s
, sizeof *s
);
4077 s
->f
= XFRAME (w
->frame
);
4078 s
->display
= FRAME_X_DISPLAY (s
->f
);
4079 s
->window
= FRAME_X_WINDOW (s
->f
);
4084 s
->first_glyph
= row
->glyphs
[area
] + start
;
4085 s
->height
= row
->height
;
4086 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4088 /* Display the internal border below the tool-bar window. */
4089 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4090 s
->y
-= s
->f
->output_data
.x
->internal_border_width
;
4092 s
->ybase
= s
->y
+ row
->ascent
;
4096 /* Set background width of glyph string S. START is the index of the
4097 first glyph following S. LAST_X is the right-most x-position + 1
4098 in the drawing area. */
4101 x_set_glyph_string_background_width (s
, start
, last_x
)
4102 struct glyph_string
*s
;
4106 /* If the face of this glyph string has to be drawn to the end of
4107 the drawing area, set S->extends_to_end_of_line_p. */
4108 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4110 if (start
== s
->row
->used
[s
->area
]
4111 && s
->hl
== DRAW_NORMAL_TEXT
4112 && ((s
->area
== TEXT_AREA
&& s
->row
->fill_line_p
)
4113 || s
->face
->background
!= default_face
->background
4114 || s
->face
->stipple
!= default_face
->stipple
))
4115 s
->extends_to_end_of_line_p
= 1;
4117 /* If S extends its face to the end of the line, set its
4118 background_width to the distance to the right edge of the drawing
4120 if (s
->extends_to_end_of_line_p
)
4121 s
->background_width
= last_x
- s
->x
+ 1;
4123 s
->background_width
= s
->width
;
4127 /* Add a glyph string for a stretch glyph to the list of strings
4128 between HEAD and TAIL. START is the index of the stretch glyph in
4129 row area AREA of glyph row ROW. END is the index of the last glyph
4130 in that glyph row area. X is the current output position assigned
4131 to the new glyph string constructed. HL overrides that face of the
4132 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4133 is the right-most x-position of the drawing area. */
4135 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
4136 and below -- keep them on one line. */
4137 #define BUILD_STRETCH_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4140 s = (struct glyph_string *) alloca (sizeof *s); \
4141 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
4142 x_fill_stretch_glyph_string (s); \
4143 x_append_glyph_string (&HEAD, &TAIL, s); \
4150 /* Add a glyph string for an image glyph to the list of strings
4151 between HEAD and TAIL. START is the index of the image glyph in
4152 row area AREA of glyph row ROW. END is the index of the last glyph
4153 in that glyph row area. X is the current output position assigned
4154 to the new glyph string constructed. HL overrides that face of the
4155 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4156 is the right-most x-position of the drawing area. */
4158 #define BUILD_IMAGE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4161 s = (struct glyph_string *) alloca (sizeof *s); \
4162 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
4163 x_fill_image_glyph_string (s); \
4164 x_append_glyph_string (&HEAD, &TAIL, s); \
4171 /* Add a glyph string for a sequence of character glyphs to the list
4172 of strings between HEAD and TAIL. START is the index of the first
4173 glyph in row area AREA of glyph row ROW that is part of the new
4174 glyph string. END is the index of the last glyph in that glyph row
4175 area. X is the current output position assigned to the new glyph
4176 string constructed. HL overrides that face of the glyph; e.g. it
4177 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4178 right-most x-position of the drawing area. */
4180 #define BUILD_CHAR_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4183 int c, charset, face_id; \
4186 c = (ROW)->glyphs[AREA][START].u.ch.code; \
4187 charset = CHAR_CHARSET (c); \
4188 face_id = (ROW)->glyphs[AREA][START].u.ch.face_id; \
4190 if (charset == CHARSET_COMPOSITION) \
4192 struct work *stack, *work, *new = NULL; \
4194 struct glyph_string *first_s = NULL; \
4196 /* Push an initial entry for character c on the stack. */ \
4198 work = (struct work *) alloca (sizeof *work); \
4199 work->cmpcharp = cmpchar_table[COMPOSITE_CHAR_ID (c)]; \
4201 work->next = stack; \
4204 /* While the stack is not empty, append glyph_strings \
4205 to head/tail for glyphs to draw. */ \
4208 s = (struct glyph_string *) alloca (sizeof *s); \
4209 char2b = (XChar2b *) alloca (stack->cmpcharp->glyph_len \
4210 * sizeof (XChar2b)); \
4211 x_init_glyph_string (s, char2b, W, ROW, AREA, START, HL); \
4212 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4213 s->cmpcharp = stack->cmpcharp; \
4214 s->gidx = stack->gidx; \
4215 s->charset = charset; \
4220 /* Don't draw the background except for the \
4221 first glyph string. */ \
4222 s->background_filled_p = n > 0; \
4228 new = (struct work *) alloca (sizeof *new); \
4229 x_fill_composite_glyph_string (s, face_id, &stack, \
4230 &new, OVERLAPS_P); \
4238 s = (struct glyph_string *) alloca (sizeof *s); \
4239 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
4240 x_init_glyph_string (s, char2b, W, ROW, AREA, START, HL); \
4241 x_append_glyph_string (&HEAD, &TAIL, s); \
4242 s->charset = charset; \
4244 START = x_fill_glyph_string (s, face_id, START, END, \
4251 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4252 of AREA of glyph row ROW on window W between indices START and END.
4253 HL overrides the face for drawing glyph strings, e.g. it is
4254 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4255 x-positions of the drawing area.
4257 This is an ugly monster macro construct because we must use alloca
4258 to allocate glyph strings (because x_draw_glyphs can be called
4261 #define BUILD_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4264 HEAD = TAIL = NULL; \
4265 while (START < END) \
4267 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4268 switch (first_glyph->type) \
4271 BUILD_CHAR_GLYPH_STRINGS (W, ROW, AREA, START, END, HEAD, \
4272 TAIL, HL, X, LAST_X, \
4276 case STRETCH_GLYPH: \
4277 BUILD_STRETCH_GLYPH_STRING (W, ROW, AREA, START, END, \
4278 HEAD, TAIL, HL, X, LAST_X); \
4282 BUILD_IMAGE_GLYPH_STRING (W, ROW, AREA, START, END, HEAD, \
4283 TAIL, HL, X, LAST_X); \
4290 x_set_glyph_string_background_width (s, START, LAST_X); \
4297 /* Draw glyphs between START and END in AREA of ROW on window W,
4298 starting at x-position X. X is relative to AREA in W. HL is a
4299 face-override with the following meaning:
4301 DRAW_NORMAL_TEXT draw normally
4302 DRAW_CURSOR draw in cursor face
4303 DRAW_MOUSE_FACE draw in mouse face.
4304 DRAW_INVERSE_VIDEO draw in mode line face
4305 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4306 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4308 If REAL_START is non-null, return in *REAL_START the real starting
4309 position for display. This can be different from START in case
4310 overlapping glyphs must be displayed. If REAL_END is non-null,
4311 return in *REAL_END the real end position for display. This can be
4312 different from END in case overlapping glyphs must be displayed.
4314 If OVERLAPS_P is non-zero, draw only the foreground of characters
4315 and clip to the physical height of ROW.
4317 Value is the x-position reached, relative to AREA of W. */
4320 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, real_start
, real_end
,
4324 struct glyph_row
*row
;
4325 enum glyph_row_area area
;
4327 enum draw_glyphs_face hl
;
4328 int *real_start
, *real_end
;
4331 struct glyph_string
*head
, *tail
;
4332 struct glyph_string
*s
;
4333 int last_x
, area_width
;
4337 /* Let's rather be paranoid than getting a SEGV. */
4338 start
= max (0, start
);
4339 end
= min (end
, row
->used
[area
]);
4341 *real_start
= start
;
4345 /* Translate X to frame coordinates. Set last_x to the right
4346 end of the drawing area. */
4347 if (row
->full_width_p
)
4349 /* X is relative to the left edge of W, without scroll bars
4351 struct frame
*f
= XFRAME (w
->frame
);
4352 /* int width = FRAME_FLAGS_AREA_WIDTH (f); */
4353 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
4356 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4357 last_x
= window_left_x
+ area_width
;
4359 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4361 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4362 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
4368 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
4369 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
4373 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
4374 area_width
= window_box_width (w
, area
);
4375 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
4378 /* Build a doubly-linked list of glyph_string structures between
4379 head and tail from what we have to draw. Note that the macro
4380 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4381 the reason we use a separate variable `i'. */
4383 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
4386 x_reached
= tail
->x
+ tail
->background_width
;
4390 /* If there are any glyphs with lbearing < 0 or rbearing > width in
4391 the row, redraw some glyphs in front or following the glyph
4392 strings built above. */
4393 if (!overlaps_p
&& row
->contains_overlapping_glyphs_p
)
4396 struct glyph_string
*h
, *t
;
4398 /* Compute overhangs for all glyph strings. */
4399 for (s
= head
; s
; s
= s
->next
)
4400 x_compute_glyph_string_overhangs (s
);
4402 /* Prepend glyph strings for glyphs in front of the first glyph
4403 string that are overwritten because of the first glyph
4404 string's left overhang. The background of all strings
4405 prepended must be drawn because the first glyph string
4407 i
= x_left_overwritten (head
);
4411 BUILD_GLYPH_STRINGS (w
, row
, area
, j
, start
, h
, t
,
4412 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4416 *real_start
= start
;
4417 x_compute_overhangs_and_x (t
, head
->x
, 1);
4418 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4421 /* Prepend glyph strings for glyphs in front of the first glyph
4422 string that overwrite that glyph string because of their
4423 right overhang. For these strings, only the foreground must
4424 be drawn, because it draws over the glyph string at `head'.
4425 The background must not be drawn because this would overwrite
4426 right overhangs of preceding glyphs for which no glyph
4428 i
= x_left_overwriting (head
);
4431 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, start
, h
, t
,
4432 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
4434 for (s
= h
; s
; s
= s
->next
)
4435 s
->background_filled_p
= 1;
4438 x_compute_overhangs_and_x (t
, head
->x
, 1);
4439 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
4442 /* Append glyphs strings for glyphs following the last glyph
4443 string tail that are overwritten by tail. The background of
4444 these strings has to be drawn because tail's foreground draws
4446 i
= x_right_overwritten (tail
);
4449 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
4450 DRAW_NORMAL_TEXT
, x
, last_x
,
4452 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4453 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4458 /* Append glyph strings for glyphs following the last glyph
4459 string tail that overwrite tail. The foreground of such
4460 glyphs has to be drawn because it writes into the background
4461 of tail. The background must not be drawn because it could
4462 paint over the foreground of following glyphs. */
4463 i
= x_right_overwriting (tail
);
4466 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
4467 DRAW_NORMAL_TEXT
, x
, last_x
,
4469 for (s
= h
; s
; s
= s
->next
)
4470 s
->background_filled_p
= 1;
4471 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
4472 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
4478 /* Draw all strings. */
4479 for (s
= head
; s
; s
= s
->next
)
4480 x_draw_glyph_string (s
);
4482 /* Value is the x-position up to which drawn, relative to AREA of W.
4483 This doesn't include parts drawn because of overhangs. */
4484 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
4485 if (!row
->full_width_p
)
4487 if (area
> LEFT_MARGIN_AREA
)
4488 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
4489 if (area
> TEXT_AREA
)
4490 x_reached
-= window_box_width (w
, TEXT_AREA
);
4496 /* Fix the display of area AREA of overlapping row ROW in window W. */
4499 x_fix_overlapping_area (w
, row
, area
)
4501 struct glyph_row
*row
;
4502 enum glyph_row_area area
;
4508 if (area
== LEFT_MARGIN_AREA
)
4510 else if (area
== TEXT_AREA
)
4511 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
4513 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
4514 + window_box_width (w
, TEXT_AREA
));
4516 for (i
= 0; i
< row
->used
[area
];)
4518 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
4520 int start
= i
, start_x
= x
;
4524 x
+= row
->glyphs
[area
][i
].pixel_width
;
4527 while (i
< row
->used
[area
]
4528 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
4530 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
4532 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
4537 x
+= row
->glyphs
[area
][i
].pixel_width
;
4546 /* Output LEN glyphs starting at START at the nominal cursor position.
4547 Advance the nominal cursor over the text. The global variable
4548 updated_window contains the window being updated, updated_row is
4549 the glyph row being updated, and updated_area is the area of that
4550 row being updated. */
4553 x_write_glyphs (start
, len
)
4554 struct glyph
*start
;
4557 int x
, hpos
, real_start
, real_end
;
4559 xassert (updated_window
&& updated_row
);
4564 hpos
= start
- updated_row
->glyphs
[updated_area
];
4565 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
4566 updated_row
, updated_area
,
4568 (updated_row
->inverse_p
4569 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
4570 &real_start
, &real_end
, 0);
4572 /* If we drew over the cursor, note that it is not visible any more. */
4573 note_overwritten_text_cursor (updated_window
, real_start
,
4574 real_end
- real_start
);
4578 /* Advance the output cursor. */
4579 output_cursor
.hpos
+= len
;
4580 output_cursor
.x
= x
;
4584 /* Insert LEN glyphs from START at the nominal cursor position. */
4587 x_insert_glyphs (start
, len
)
4588 struct glyph
*start
;
4593 int line_height
, shift_by_width
, shifted_region_width
;
4594 struct glyph_row
*row
;
4595 struct glyph
*glyph
;
4596 int frame_x
, frame_y
, hpos
, real_start
, real_end
;
4598 xassert (updated_window
&& updated_row
);
4601 f
= XFRAME (WINDOW_FRAME (w
));
4603 /* Get the height of the line we are in. */
4605 line_height
= row
->height
;
4607 /* Get the width of the glyphs to insert. */
4609 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
4610 shift_by_width
+= glyph
->pixel_width
;
4612 /* Get the width of the region to shift right. */
4613 shifted_region_width
= (window_box_width (w
, updated_area
)
4618 frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, output_cursor
.x
);
4619 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
4620 XCopyArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), FRAME_X_WINDOW (f
),
4621 f
->output_data
.x
->normal_gc
,
4623 shifted_region_width
, line_height
,
4624 frame_x
+ shift_by_width
, frame_y
);
4626 /* Write the glyphs. */
4627 hpos
= start
- row
->glyphs
[updated_area
];
4628 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
4629 DRAW_NORMAL_TEXT
, &real_start
, &real_end
, 0);
4630 note_overwritten_text_cursor (w
, real_start
, real_end
- real_start
);
4632 /* Advance the output cursor. */
4633 output_cursor
.hpos
+= len
;
4634 output_cursor
.x
+= shift_by_width
;
4639 /* Delete N glyphs at the nominal cursor position. Not implemented
4650 /* Erase the current text line from the nominal cursor position
4651 (inclusive) to pixel column TO_X (exclusive). The idea is that
4652 everything from TO_X onward is already erased.
4654 TO_X is a pixel position relative to updated_area of
4655 updated_window. TO_X == -1 means clear to the end of this area. */
4658 x_clear_end_of_line (to_x
)
4662 struct window
*w
= updated_window
;
4663 int max_x
, min_y
, max_y
;
4664 int from_x
, from_y
, to_y
;
4666 xassert (updated_window
&& updated_row
);
4667 f
= XFRAME (w
->frame
);
4669 if (updated_row
->full_width_p
)
4671 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
4672 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
4673 && !w
->pseudo_window_p
)
4674 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
4677 max_x
= window_box_width (w
, updated_area
);
4678 max_y
= window_text_bottom_y (w
);
4680 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
4681 of window. For TO_X > 0, truncate to end of drawing area. */
4687 to_x
= min (to_x
, max_x
);
4689 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
4691 /* Notice if the cursor will be cleared by this operation. */
4692 if (!updated_row
->full_width_p
)
4693 note_overwritten_text_cursor (w
, output_cursor
.hpos
, -1);
4695 from_x
= output_cursor
.x
;
4697 /* Translate to frame coordinates. */
4698 if (updated_row
->full_width_p
)
4700 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
4701 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
4705 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
4706 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
4709 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
4710 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
4711 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
4713 /* Prevent inadvertently clearing to end of the X window. */
4714 if (to_x
> from_x
&& to_y
> from_y
)
4717 XClearArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4718 from_x
, from_y
, to_x
- from_x
, to_y
- from_y
,
4725 /* Clear entire frame. If updating_frame is non-null, clear that
4726 frame. Otherwise clear the selected frame. */
4736 f
= SELECTED_FRAME ();
4738 /* Clearing the frame will erase any cursor, so mark them all as no
4740 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4741 output_cursor
.hpos
= output_cursor
.vpos
= 0;
4742 output_cursor
.x
= -1;
4744 /* We don't set the output cursor here because there will always
4745 follow an explicit cursor_to. */
4747 XClearWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
4749 /* We have to clear the scroll bars, too. If we have changed
4750 colors or something like that, then they should be notified. */
4751 x_scroll_bar_clear (f
);
4753 XFlush (FRAME_X_DISPLAY (f
));
4759 /* Invert the middle quarter of the frame for .15 sec. */
4761 /* We use the select system call to do the waiting, so we have to make
4762 sure it's available. If it isn't, we just won't do visual bells. */
4764 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
4767 /* Subtract the `struct timeval' values X and Y, storing the result in
4768 *RESULT. Return 1 if the difference is negative, otherwise 0. */
4771 timeval_subtract (result
, x
, y
)
4772 struct timeval
*result
, x
, y
;
4774 /* Perform the carry for the later subtraction by updating y. This
4775 is safer because on some systems the tv_sec member is unsigned. */
4776 if (x
.tv_usec
< y
.tv_usec
)
4778 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
4779 y
.tv_usec
-= 1000000 * nsec
;
4783 if (x
.tv_usec
- y
.tv_usec
> 1000000)
4785 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
4786 y
.tv_usec
+= 1000000 * nsec
;
4790 /* Compute the time remaining to wait. tv_usec is certainly
4792 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
4793 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
4795 /* Return indication of whether the result should be considered
4797 return x
.tv_sec
< y
.tv_sec
;
4809 /* Create a GC that will use the GXxor function to flip foreground
4810 pixels into background pixels. */
4814 values
.function
= GXxor
;
4815 values
.foreground
= (f
->output_data
.x
->foreground_pixel
4816 ^ f
->output_data
.x
->background_pixel
);
4818 gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4819 GCFunction
| GCForeground
, &values
);
4823 /* Get the height not including a menu bar widget. */
4824 int height
= CHAR_TO_PIXEL_HEIGHT (f
, FRAME_HEIGHT (f
));
4825 /* Height of each line to flash. */
4826 int flash_height
= FRAME_LINE_HEIGHT (f
);
4827 /* These will be the left and right margins of the rectangles. */
4828 int flash_left
= FRAME_INTERNAL_BORDER_WIDTH (f
);
4829 int flash_right
= PIXEL_WIDTH (f
) - FRAME_INTERNAL_BORDER_WIDTH (f
);
4833 /* Don't flash the area between a scroll bar and the frame
4834 edge it is next to. */
4835 switch (FRAME_VERTICAL_SCROLL_BAR_TYPE (f
))
4837 case vertical_scroll_bar_left
:
4838 flash_left
+= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
4841 case vertical_scroll_bar_right
:
4842 flash_right
-= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
4849 width
= flash_right
- flash_left
;
4851 /* If window is tall, flash top and bottom line. */
4852 if (height
> 3 * FRAME_LINE_HEIGHT (f
))
4854 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
4856 (FRAME_INTERNAL_BORDER_WIDTH (f
)
4857 + FRAME_TOOL_BAR_LINES (f
) * CANON_Y_UNIT (f
)),
4858 width
, flash_height
);
4859 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
4861 (height
- flash_height
4862 - FRAME_INTERNAL_BORDER_WIDTH (f
)),
4863 width
, flash_height
);
4866 /* If it is short, flash it all. */
4867 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
4868 flash_left
, FRAME_INTERNAL_BORDER_WIDTH (f
),
4869 width
, height
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
4874 struct timeval wakeup
;
4876 EMACS_GET_TIME (wakeup
);
4878 /* Compute time to wait until, propagating carry from usecs. */
4879 wakeup
.tv_usec
+= 150000;
4880 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
4881 wakeup
.tv_usec
%= 1000000;
4883 /* Keep waiting until past the time wakeup. */
4886 struct timeval timeout
;
4888 EMACS_GET_TIME (timeout
);
4890 /* In effect, timeout = wakeup - timeout.
4891 Break if result would be negative. */
4892 if (timeval_subtract (&timeout
, wakeup
, timeout
))
4895 /* Try to wait that long--but we might wake up sooner. */
4896 select (0, NULL
, NULL
, NULL
, &timeout
);
4900 /* If window is tall, flash top and bottom line. */
4901 if (height
> 3 * FRAME_LINE_HEIGHT (f
))
4903 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
4905 (FRAME_INTERNAL_BORDER_WIDTH (f
)
4906 + FRAME_TOOL_BAR_LINES (f
) * CANON_Y_UNIT (f
)),
4907 width
, flash_height
);
4908 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
4910 (height
- flash_height
4911 - FRAME_INTERNAL_BORDER_WIDTH (f
)),
4912 width
, flash_height
);
4915 /* If it is short, flash it all. */
4916 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
4917 flash_left
, FRAME_INTERNAL_BORDER_WIDTH (f
),
4918 width
, height
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
4920 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
4928 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
4931 /* Make audible bell. */
4936 struct frame
*f
= SELECTED_FRAME ();
4938 if (FRAME_X_DISPLAY (f
))
4940 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
4947 XBell (FRAME_X_DISPLAY (f
), 0);
4948 XFlush (FRAME_X_DISPLAY (f
));
4955 /* Specify how many text lines, from the top of the window,
4956 should be affected by insert-lines and delete-lines operations.
4957 This, and those operations, are used only within an update
4958 that is bounded by calls to x_update_begin and x_update_end. */
4961 XTset_terminal_window (n
)
4964 /* This function intentionally left blank. */
4969 /***********************************************************************
4971 ***********************************************************************/
4973 /* Perform an insert-lines or delete-lines operation, inserting N
4974 lines or deleting -N lines at vertical position VPOS. */
4977 x_ins_del_lines (vpos
, n
)
4984 /* Scroll part of the display as described by RUN. */
4987 x_scroll_run (w
, run
)
4991 struct frame
*f
= XFRAME (w
->frame
);
4992 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
4994 /* Get frame-relative bounding box of the text display area of W,
4995 without mode lines. Include in this box the flags areas to the
4996 left and right of W. */
4997 window_box (w
, -1, &x
, &y
, &width
, &height
);
4998 width
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
4999 x
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
5001 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5002 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5003 bottom_y
= y
+ height
;
5007 /* Scrolling up. Make sure we don't copy part of the mode
5008 line at the bottom. */
5009 if (from_y
+ run
->height
> bottom_y
)
5010 height
= bottom_y
- from_y
;
5012 height
= run
->height
;
5016 /* Scolling down. Make sure we don't copy over the mode line.
5018 if (to_y
+ run
->height
> bottom_y
)
5019 height
= bottom_y
- to_y
;
5021 height
= run
->height
;
5026 /* Cursor off. Will be switched on again in x_update_window_end. */
5030 XCopyArea (FRAME_X_DISPLAY (f
),
5031 FRAME_X_WINDOW (f
), FRAME_X_WINDOW (f
),
5032 f
->output_data
.x
->normal_gc
,
5042 /***********************************************************************
5044 ***********************************************************************/
5046 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5047 corner of the exposed rectangle. W and H are width and height of
5048 the exposed area. All are pixel values. W or H zero means redraw
5049 the entire frame. */
5052 expose_frame (f
, x
, y
, w
, h
)
5058 TRACE ((stderr
, "expose_frame "));
5060 /* No need to redraw if frame will be redrawn soon. */
5061 if (FRAME_GARBAGED_P (f
))
5063 TRACE ((stderr
, " garbaged\n"));
5067 /* If basic faces haven't been realized yet, there is no point in
5068 trying to redraw anything. This can happen when we get an expose
5069 event while Emacs is starting, e.g. by moving another window. */
5070 if (FRAME_FACE_CACHE (f
) == NULL
5071 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
5073 TRACE ((stderr
, " no faces\n"));
5077 if (w
== 0 || h
== 0)
5080 r
.width
= CANON_X_UNIT (f
) * f
->width
;
5081 r
.height
= CANON_Y_UNIT (f
) * f
->height
;
5091 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.x
, r
.y
, r
.width
, r
.height
));
5092 expose_window_tree (XWINDOW (f
->root_window
), &r
);
5094 if (WINDOWP (f
->tool_bar_window
))
5096 struct window
*w
= XWINDOW (f
->tool_bar_window
);
5097 XRectangle window_rect
;
5098 XRectangle intersection_rect
;
5099 int window_x
, window_y
, window_width
, window_height
;
5102 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
5103 window_rect
.x
= window_x
;
5104 window_rect
.y
= window_y
;
5105 window_rect
.width
= window_width
;
5106 window_rect
.height
= window_height
;
5108 if (x_intersect_rectangles (&r
, &window_rect
, &intersection_rect
))
5109 expose_window (w
, &intersection_rect
);
5112 #ifndef USE_X_TOOLKIT
5113 if (WINDOWP (f
->menu_bar_window
))
5115 struct window
*w
= XWINDOW (f
->menu_bar_window
);
5116 XRectangle window_rect
;
5117 XRectangle intersection_rect
;
5118 int window_x
, window_y
, window_width
, window_height
;
5121 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
5122 window_rect
.x
= window_x
;
5123 window_rect
.y
= window_y
;
5124 window_rect
.width
= window_width
;
5125 window_rect
.height
= window_height
;
5127 if (x_intersect_rectangles (&r
, &window_rect
, &intersection_rect
))
5128 expose_window (w
, &intersection_rect
);
5130 #endif /* not USE_X_TOOLKIT */
5134 /* Redraw (parts) of all windows in the window tree rooted at W that
5135 intersect R. R contains frame pixel coordinates. */
5138 expose_window_tree (w
, r
)
5144 if (!NILP (w
->hchild
))
5145 expose_window_tree (XWINDOW (w
->hchild
), r
);
5146 else if (!NILP (w
->vchild
))
5147 expose_window_tree (XWINDOW (w
->vchild
), r
);
5150 XRectangle window_rect
;
5151 XRectangle intersection_rect
;
5152 struct frame
*f
= XFRAME (w
->frame
);
5153 int window_x
, window_y
, window_width
, window_height
;
5155 /* Frame-relative pixel rectangle of W. */
5156 window_box (w
, -1, &window_x
, &window_y
, &window_width
,
5160 - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
5161 - FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
));
5162 window_rect
.y
= window_y
;
5165 + FRAME_X_FLAGS_AREA_WIDTH (f
)
5166 + FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
));
5168 = window_height
+ CURRENT_MODE_LINE_HEIGHT (w
);
5170 if (x_intersect_rectangles (r
, &window_rect
, &intersection_rect
))
5171 expose_window (w
, &intersection_rect
);
5174 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5179 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5180 which intersects rectangle R. R is in window-relative coordinates. */
5183 expose_area (w
, row
, r
, area
)
5185 struct glyph_row
*row
;
5187 enum glyph_row_area area
;
5190 struct glyph
*first
= row
->glyphs
[area
];
5191 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5195 /* Set x to the window-relative start position for drawing glyphs of
5196 AREA. The first glyph of the text area can be partially visible.
5197 The first glyphs of other areas cannot. */
5198 if (area
== LEFT_MARGIN_AREA
)
5200 else if (area
== TEXT_AREA
)
5201 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5203 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5204 + window_box_width (w
, TEXT_AREA
));
5206 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5207 /* If row extends face to end of line write the whole line. */
5208 x_draw_glyphs (w
, x
, row
, area
,
5210 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5214 /* Find the first glyph that must be redrawn. */
5216 && x
+ first
->pixel_width
< r
->x
)
5218 x
+= first
->pixel_width
;
5222 /* Find the last one. */
5226 && x
< r
->x
+ r
->width
)
5228 x
+= last
->pixel_width
;
5234 x_draw_glyphs (w
, first_x
, row
, area
,
5235 first
- row
->glyphs
[area
],
5236 last
- row
->glyphs
[area
],
5237 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5243 /* Redraw the parts of the glyph row ROW on window W intersecting
5244 rectangle R. R is in window-relative coordinates. */
5247 expose_line (w
, row
, r
)
5249 struct glyph_row
*row
;
5252 xassert (row
->enabled_p
);
5254 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5255 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5256 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5260 if (row
->used
[LEFT_MARGIN_AREA
])
5261 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5262 if (row
->used
[TEXT_AREA
])
5263 expose_area (w
, row
, r
, TEXT_AREA
);
5264 if (row
->used
[RIGHT_MARGIN_AREA
])
5265 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5266 x_draw_row_bitmaps (w
, row
);
5271 /* Return non-zero if W's cursor intersects rectangle R. */
5274 x_phys_cursor_in_rect_p (w
, r
)
5278 XRectangle cr
, result
;
5279 struct glyph
*cursor_glyph
;
5281 cursor_glyph
= get_phys_cursor_glyph (w
);
5284 cr
.x
= w
->phys_cursor
.x
;
5285 cr
.y
= w
->phys_cursor
.y
;
5286 cr
.width
= cursor_glyph
->pixel_width
;
5287 cr
.height
= w
->phys_cursor_height
;
5288 return x_intersect_rectangles (&cr
, r
, &result
);
5295 /* Redraw a rectangle of window W. R is a rectangle in window
5296 relative coordinates. Call this function with input blocked. */
5299 expose_window (w
, r
)
5303 struct glyph_row
*row
;
5305 int yb
= window_text_bottom_y (w
);
5306 int cursor_cleared_p
;
5308 /* If window is not yet fully initialized, do nothing. This can
5309 happen when toolkit scroll bars are used and a window is split.
5310 Reconfiguring the scroll bar will generate an expose for a newly
5312 if (w
->current_matrix
== NULL
)
5315 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
5316 r
->x
, r
->y
, r
->width
, r
->height
));
5318 /* Convert to window coordinates. */
5319 r
->x
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->x
);
5320 r
->y
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->y
);
5322 /* Turn off the cursor. */
5323 if (!w
->pseudo_window_p
5324 && x_phys_cursor_in_rect_p (w
, r
))
5327 cursor_cleared_p
= 1;
5330 cursor_cleared_p
= 0;
5332 /* Find the first row intersecting the rectangle R. */
5333 row
= w
->current_matrix
->rows
;
5335 while (row
->enabled_p
5337 && y
+ row
->height
< r
->y
)
5343 /* Display the text in the rectangle, one text line at a time. */
5344 while (row
->enabled_p
5346 && y
< r
->y
+ r
->height
)
5348 expose_line (w
, row
, r
);
5353 /* Display the mode line if there is one. */
5354 if (WINDOW_WANTS_MODELINE_P (w
)
5355 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
5357 && row
->y
< r
->y
+ r
->height
)
5358 expose_line (w
, row
, r
);
5360 if (!w
->pseudo_window_p
)
5362 /* Draw border between windows. */
5363 x_draw_vertical_border (w
);
5365 /* Turn the cursor on again. */
5366 if (cursor_cleared_p
)
5367 x_update_window_cursor (w
, 1);
5372 /* Determine the intersection of two rectangles R1 and R2. Return
5373 the intersection in *RESULT. Value is non-zero if RESULT is not
5377 x_intersect_rectangles (r1
, r2
, result
)
5378 XRectangle
*r1
, *r2
, *result
;
5380 XRectangle
*left
, *right
;
5381 XRectangle
*upper
, *lower
;
5382 int intersection_p
= 0;
5384 /* Rearrange so that R1 is the left-most rectangle. */
5386 left
= r1
, right
= r2
;
5388 left
= r2
, right
= r1
;
5390 /* X0 of the intersection is right.x0, if this is inside R1,
5391 otherwise there is no intersection. */
5392 if (right
->x
<= left
->x
+ left
->width
)
5394 result
->x
= right
->x
;
5396 /* The right end of the intersection is the minimum of the
5397 the right ends of left and right. */
5398 result
->width
= (min (left
->x
+ left
->width
, right
->x
+ right
->width
)
5401 /* Same game for Y. */
5403 upper
= r1
, lower
= r2
;
5405 upper
= r2
, lower
= r1
;
5407 /* The upper end of the intersection is lower.y0, if this is inside
5408 of upper. Otherwise, there is no intersection. */
5409 if (lower
->y
<= upper
->y
+ upper
->height
)
5411 result
->y
= lower
->y
;
5413 /* The lower end of the intersection is the minimum of the lower
5414 ends of upper and lower. */
5415 result
->height
= (min (lower
->y
+ lower
->height
,
5416 upper
->y
+ upper
->height
)
5422 return intersection_p
;
5433 /* We used to only do this if Vx_no_window_manager was non-nil, but
5434 the ICCCM (section 4.1.6) says that the window's border pixmap
5435 and border pixel are window attributes which are "private to the
5436 client", so we can always change it to whatever we want. */
5438 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5439 f
->output_data
.x
->border_pixel
);
5441 x_update_cursor (f
, 1);
5445 frame_unhighlight (f
)
5448 /* We used to only do this if Vx_no_window_manager was non-nil, but
5449 the ICCCM (section 4.1.6) says that the window's border pixmap
5450 and border pixel are window attributes which are "private to the
5451 client", so we can always change it to whatever we want. */
5453 XSetWindowBorderPixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5454 f
->output_data
.x
->border_tile
);
5456 x_update_cursor (f
, 1);
5459 /* The focus has changed. Update the frames as necessary to reflect
5460 the new situation. Note that we can't change the selected frame
5461 here, because the Lisp code we are interrupting might become confused.
5462 Each event gets marked with the frame in which it occurred, so the
5463 Lisp code can tell when the switch took place by examining the events. */
5466 x_new_focus_frame (dpyinfo
, frame
)
5467 struct x_display_info
*dpyinfo
;
5468 struct frame
*frame
;
5470 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
5472 if (frame
!= dpyinfo
->x_focus_frame
)
5474 /* Set this before calling other routines, so that they see
5475 the correct value of x_focus_frame. */
5476 dpyinfo
->x_focus_frame
= frame
;
5478 if (old_focus
&& old_focus
->auto_lower
)
5479 x_lower_frame (old_focus
);
5482 selected_frame
= frame
;
5483 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
5485 Fselect_window (selected_frame
->selected_window
);
5486 choose_minibuf_frame ();
5489 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
5490 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
5492 pending_autoraise_frame
= 0;
5495 x_frame_rehighlight (dpyinfo
);
5498 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5501 x_mouse_leave (dpyinfo
)
5502 struct x_display_info
*dpyinfo
;
5504 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
5507 /* The focus has changed, or we have redirected a frame's focus to
5508 another frame (this happens when a frame uses a surrogate
5509 mini-buffer frame). Shift the highlight as appropriate.
5511 The FRAME argument doesn't necessarily have anything to do with which
5512 frame is being highlighted or un-highlighted; we only use it to find
5513 the appropriate X display info. */
5516 XTframe_rehighlight (frame
)
5517 struct frame
*frame
;
5519 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
5523 x_frame_rehighlight (dpyinfo
)
5524 struct x_display_info
*dpyinfo
;
5526 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
5528 if (dpyinfo
->x_focus_frame
)
5530 dpyinfo
->x_highlight_frame
5531 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
5532 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
5533 : dpyinfo
->x_focus_frame
);
5534 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
5536 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
5537 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
5541 dpyinfo
->x_highlight_frame
= 0;
5543 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
5546 frame_unhighlight (old_highlight
);
5547 if (dpyinfo
->x_highlight_frame
)
5548 frame_highlight (dpyinfo
->x_highlight_frame
);
5554 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
5556 /* Initialize mode_switch_bit and modifier_meaning. */
5558 x_find_modifier_meanings (dpyinfo
)
5559 struct x_display_info
*dpyinfo
;
5561 int min_code
, max_code
;
5564 XModifierKeymap
*mods
;
5566 dpyinfo
->meta_mod_mask
= 0;
5567 dpyinfo
->shift_lock_mask
= 0;
5568 dpyinfo
->alt_mod_mask
= 0;
5569 dpyinfo
->super_mod_mask
= 0;
5570 dpyinfo
->hyper_mod_mask
= 0;
5573 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
5575 min_code
= dpyinfo
->display
->min_keycode
;
5576 max_code
= dpyinfo
->display
->max_keycode
;
5579 syms
= XGetKeyboardMapping (dpyinfo
->display
,
5580 min_code
, max_code
- min_code
+ 1,
5582 mods
= XGetModifierMapping (dpyinfo
->display
);
5584 /* Scan the modifier table to see which modifier bits the Meta and
5585 Alt keysyms are on. */
5587 int row
, col
; /* The row and column in the modifier table. */
5589 for (row
= 3; row
< 8; row
++)
5590 for (col
= 0; col
< mods
->max_keypermod
; col
++)
5593 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
5595 /* Zeroes are used for filler. Skip them. */
5599 /* Are any of this keycode's keysyms a meta key? */
5603 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
5605 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
5611 dpyinfo
->meta_mod_mask
|= (1 << row
);
5616 dpyinfo
->alt_mod_mask
|= (1 << row
);
5621 dpyinfo
->hyper_mod_mask
|= (1 << row
);
5626 dpyinfo
->super_mod_mask
|= (1 << row
);
5630 /* Ignore this if it's not on the lock modifier. */
5631 if ((1 << row
) == LockMask
)
5632 dpyinfo
->shift_lock_mask
= LockMask
;
5640 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
5641 if (! dpyinfo
->meta_mod_mask
)
5643 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
5644 dpyinfo
->alt_mod_mask
= 0;
5647 /* If some keys are both alt and meta,
5648 make them just meta, not alt. */
5649 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
5651 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
5654 XFree ((char *) syms
);
5655 XFreeModifiermap (mods
);
5658 /* Convert between the modifier bits X uses and the modifier bits
5662 x_x_to_emacs_modifiers (dpyinfo
, state
)
5663 struct x_display_info
*dpyinfo
;
5666 return ( ((state
& (ShiftMask
| dpyinfo
->shift_lock_mask
)) ? shift_modifier
: 0)
5667 | ((state
& ControlMask
) ? ctrl_modifier
: 0)
5668 | ((state
& dpyinfo
->meta_mod_mask
) ? meta_modifier
: 0)
5669 | ((state
& dpyinfo
->alt_mod_mask
) ? alt_modifier
: 0)
5670 | ((state
& dpyinfo
->super_mod_mask
) ? super_modifier
: 0)
5671 | ((state
& dpyinfo
->hyper_mod_mask
) ? hyper_modifier
: 0));
5675 x_emacs_to_x_modifiers (dpyinfo
, state
)
5676 struct x_display_info
*dpyinfo
;
5679 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
5680 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
5681 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
5682 | ((state
& shift_modifier
) ? ShiftMask
: 0)
5683 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
5684 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
5687 /* Convert a keysym to its name. */
5690 x_get_keysym_name (keysym
)
5696 value
= XKeysymToString (keysym
);
5704 /* Mouse clicks and mouse movement. Rah. */
5706 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
5707 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
5708 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
5709 not force the value into range. */
5712 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
5714 register int pix_x
, pix_y
;
5715 register int *x
, *y
;
5719 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
5720 even for negative values. */
5722 pix_x
-= FONT_WIDTH ((f
)->output_data
.x
->font
) - 1;
5724 pix_y
-= (f
)->output_data
.x
->line_height
- 1;
5726 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
5727 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
5731 bounds
->width
= FONT_WIDTH (f
->output_data
.x
->font
);
5732 bounds
->height
= f
->output_data
.x
->line_height
;
5733 bounds
->x
= CHAR_TO_PIXEL_COL (f
, pix_x
);
5734 bounds
->y
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
5741 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
5742 pix_x
= FRAME_WINDOW_WIDTH (f
);
5746 else if (pix_y
> f
->height
)
5755 /* Given HPOS/VPOS in the current matrix of W, return corresponding
5756 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
5757 can't tell the positions because W's display is not up to date,
5761 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
5764 int *frame_x
, *frame_y
;
5768 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
5769 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
5771 if (display_completed
)
5773 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
5774 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
5775 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
5781 *frame_x
+= glyph
->pixel_width
;
5789 *frame_y
= *frame_x
= 0;
5793 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
5794 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
5799 /* Prepare a mouse-event in *RESULT for placement in the input queue.
5801 If the event is a button press, then note that we have grabbed
5805 construct_mouse_click (result
, event
, f
)
5806 struct input_event
*result
;
5807 XButtonEvent
*event
;
5810 /* Make the event type no_event; we'll change that when we decide
5812 result
->kind
= mouse_click
;
5813 result
->code
= event
->button
- Button1
;
5814 result
->timestamp
= event
->time
;
5815 result
->modifiers
= (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
5817 | (event
->type
== ButtonRelease
5821 XSETINT (result
->x
, event
->x
);
5822 XSETINT (result
->y
, event
->y
);
5823 XSETFRAME (result
->frame_or_window
, f
);
5827 #if 0 /* This function isn't called. --gerd */
5829 /* Prepare a menu-event in *RESULT for placement in the input queue. */
5832 construct_menu_click (result
, event
, f
)
5833 struct input_event
*result
;
5834 XButtonEvent
*event
;
5837 /* Make the event type no_event; we'll change that when we decide
5839 result
->kind
= mouse_click
;
5840 result
->code
= event
->button
- Button1
;
5841 result
->timestamp
= event
->time
;
5842 result
->modifiers
= (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
5844 | (event
->type
== ButtonRelease
5848 XSETINT (result
->x
, event
->x
);
5849 XSETINT (result
->y
, -1);
5850 XSETFRAME (result
->frame_or_window
, f
);
5856 /* Function to report a mouse movement to the mainstream Emacs code.
5857 The input handler calls this.
5859 We have received a mouse movement event, which is given in *event.
5860 If the mouse is over a different glyph than it was last time, tell
5861 the mainstream emacs code by setting mouse_moved. If not, ask for
5862 another motion event, so we can check again the next time it moves. */
5864 static XMotionEvent last_mouse_motion_event
;
5865 static Lisp_Object last_mouse_motion_frame
;
5868 note_mouse_movement (frame
, event
)
5870 XMotionEvent
*event
;
5872 last_mouse_movement_time
= event
->time
;
5873 last_mouse_motion_event
= *event
;
5874 XSETFRAME (last_mouse_motion_frame
, frame
);
5876 if (event
->window
!= FRAME_X_WINDOW (frame
))
5878 frame
->mouse_moved
= 1;
5879 last_mouse_scroll_bar
= Qnil
;
5880 note_mouse_highlight (frame
, -1, -1);
5883 /* Has the mouse moved off the glyph it was on at the last sighting? */
5884 else if (event
->x
< last_mouse_glyph
.x
5885 || event
->x
>= last_mouse_glyph
.x
+ last_mouse_glyph
.width
5886 || event
->y
< last_mouse_glyph
.y
5887 || event
->y
>= last_mouse_glyph
.y
+ last_mouse_glyph
.height
)
5889 frame
->mouse_moved
= 1;
5890 last_mouse_scroll_bar
= Qnil
;
5891 note_mouse_highlight (frame
, event
->x
, event
->y
);
5895 /* This is used for debugging, to turn off note_mouse_highlight. */
5897 int disable_mouse_highlight
;
5901 /************************************************************************
5903 ************************************************************************/
5905 /* Find the glyph under window-relative coordinates X/Y in window W.
5906 Consider only glyphs from buffer text, i.e. no glyphs from overlay
5907 strings. Return in *HPOS and *VPOS the row and column number of
5908 the glyph found. Return in *AREA the glyph area containing X.
5909 Value is a pointer to the glyph found or null if X/Y is not on
5910 text, or we can't tell because W's current matrix is not up to
5913 static struct glyph
*
5914 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
)
5917 int *hpos
, *vpos
, *area
;
5919 struct glyph
*glyph
, *end
;
5920 struct glyph_row
*row
;
5921 int x0
, i
, left_area_width
;
5923 /* Find row containing Y. Give up if some row is not enabled. */
5924 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
5926 row
= MATRIX_ROW (w
->current_matrix
, i
);
5927 if (!row
->enabled_p
)
5929 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
5936 /* Give up if Y is not in the window. */
5937 if (i
== w
->current_matrix
->nrows
)
5940 /* Get the glyph area containing X. */
5941 if (w
->pseudo_window_p
)
5948 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
5949 if (x
< left_area_width
)
5951 *area
= LEFT_MARGIN_AREA
;
5954 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
5957 x0
= row
->x
+ left_area_width
;
5961 *area
= RIGHT_MARGIN_AREA
;
5962 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
5966 /* Find glyph containing X. */
5967 glyph
= row
->glyphs
[*area
];
5968 end
= glyph
+ row
->used
[*area
];
5971 if (x
< x0
+ glyph
->pixel_width
)
5973 if (w
->pseudo_window_p
)
5975 else if (BUFFERP (glyph
->object
))
5979 x0
+= glyph
->pixel_width
;
5986 *hpos
= glyph
- row
->glyphs
[*area
];
5991 /* Convert frame-relative x/y to coordinates relative to window W.
5992 Takes pseudo-windows into account. */
5995 frame_to_window_pixel_xy (w
, x
, y
)
5999 if (w
->pseudo_window_p
)
6001 /* A pseudo-window is always full-width, and starts at the
6002 left edge of the frame, plus a frame border. */
6003 struct frame
*f
= XFRAME (w
->frame
);
6004 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6005 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6009 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6010 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6015 /* Take proper action when mouse has moved to the mode or top line of
6016 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6017 mode line. X is relative to the start of the text display area of
6018 W, so the width of bitmap areas and scroll bars must be subtracted
6019 to get a position relative to the start of the mode line. */
6022 note_mode_line_highlight (w
, x
, mode_line_p
)
6026 struct frame
*f
= XFRAME (w
->frame
);
6027 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6028 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6029 struct glyph_row
*row
;
6032 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
6034 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
6038 struct glyph
*glyph
, *end
;
6039 Lisp_Object help
, map
;
6042 /* Find the glyph under X. */
6043 glyph
= row
->glyphs
[TEXT_AREA
];
6044 end
= glyph
+ row
->used
[TEXT_AREA
];
6045 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
6046 + FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
));
6048 && x
>= x0
+ glyph
->pixel_width
)
6050 x0
+= glyph
->pixel_width
;
6055 && STRINGP (glyph
->object
)
6056 && XSTRING (glyph
->object
)->intervals
6057 && glyph
->charpos
>= 0
6058 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6060 /* If we're on a string with `help-echo' text property,
6061 arrange for the help to be displayed. This is done by
6062 setting the global variable help_echo to the help string. */
6063 help
= Fget_text_property (make_number (glyph
->charpos
),
6064 Qhelp_echo
, glyph
->object
);
6068 /* Change the mouse pointer according to what is under X/Y. */
6069 map
= Fget_text_property (make_number (glyph
->charpos
),
6070 Qlocal_map
, glyph
->object
);
6071 if (!NILP (Fkeymapp (map
)))
6072 cursor
= f
->output_data
.x
->nontext_cursor
;
6076 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
6080 /* Take proper action when the mouse has moved to position X, Y on
6081 frame F as regards highlighting characters that have mouse-face
6082 properties. Also de-highlighting chars where the mouse was before.
6083 X and Y can be negative or out of range. */
6086 note_mouse_highlight (f
, x
, y
)
6090 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6095 /* When a menu is active, don't highlight because this looks odd. */
6096 #ifdef USE_X_TOOLKIT
6097 if (popup_activated ())
6101 if (disable_mouse_highlight
)
6104 dpyinfo
->mouse_face_mouse_x
= x
;
6105 dpyinfo
->mouse_face_mouse_y
= y
;
6106 dpyinfo
->mouse_face_mouse_frame
= f
;
6108 if (dpyinfo
->mouse_face_defer
)
6113 dpyinfo
->mouse_face_deferred_gc
= 1;
6117 /* Which window is that in? */
6118 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
6120 /* If we were displaying active text in another window, clear that. */
6121 if (! EQ (window
, dpyinfo
->mouse_face_window
))
6122 clear_mouse_face (dpyinfo
);
6124 /* Not on a window -> return. */
6125 if (!WINDOWP (window
))
6128 /* Convert to window-relative pixel coordinates. */
6129 w
= XWINDOW (window
);
6130 frame_to_window_pixel_xy (w
, &x
, &y
);
6132 /* Handle tool-bar window differently since it doesn't display a
6134 if (EQ (window
, f
->tool_bar_window
))
6136 note_tool_bar_highlight (f
, x
, y
);
6140 if (portion
== 1 || portion
== 3)
6142 /* Mouse is on the mode or top line. */
6143 note_mode_line_highlight (w
, x
, portion
== 1);
6147 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6148 f
->output_data
.x
->text_cursor
);
6150 /* Are we in a window whose display is up to date?
6151 And verify the buffer's text has not changed. */
6152 if (/* Within text portion of the window. */
6154 && EQ (w
->window_end_valid
, w
->buffer
)
6155 && XFASTINT (w
->last_modified
) == BUF_MODIFF (XBUFFER (w
->buffer
))
6156 && (XFASTINT (w
->last_overlay_modified
)
6157 == BUF_OVERLAY_MODIFF (XBUFFER (w
->buffer
))))
6159 int hpos
, vpos
, pos
, i
, area
;
6160 struct glyph
*glyph
;
6162 /* Find the glyph under X/Y. */
6163 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
);
6165 /* Clear mouse face if X/Y not over text. */
6167 || area
!= TEXT_AREA
6168 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
6170 clear_mouse_face (dpyinfo
);
6174 pos
= glyph
->charpos
;
6175 xassert (w
->pseudo_window_p
|| BUFFERP (glyph
->object
));
6177 /* Check for mouse-face and help-echo. */
6179 Lisp_Object mouse_face
, overlay
, position
;
6180 Lisp_Object
*overlay_vec
;
6182 struct buffer
*obuf
;
6185 /* If we get an out-of-range value, return now; avoid an error. */
6186 if (pos
> BUF_Z (XBUFFER (w
->buffer
)))
6189 /* Make the window's buffer temporarily current for
6190 overlays_at and compute_char_face. */
6191 obuf
= current_buffer
;
6192 current_buffer
= XBUFFER (w
->buffer
);
6198 /* Is this char mouse-active or does it have help-echo? */
6199 XSETINT (position
, pos
);
6201 /* Put all the overlays we want in a vector in overlay_vec.
6202 Store the length in len. If there are more than 10, make
6203 enough space for all, and try again. */
6205 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6206 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
);
6207 if (noverlays
> len
)
6210 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6211 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
);
6214 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
6216 /* Check mouse-face highlighting. */
6217 if (! (EQ (window
, dpyinfo
->mouse_face_window
)
6218 && vpos
>= dpyinfo
->mouse_face_beg_row
6219 && vpos
<= dpyinfo
->mouse_face_end_row
6220 && (vpos
> dpyinfo
->mouse_face_beg_row
6221 || hpos
>= dpyinfo
->mouse_face_beg_col
)
6222 && (vpos
< dpyinfo
->mouse_face_end_row
6223 || hpos
< dpyinfo
->mouse_face_end_col
6224 || dpyinfo
->mouse_face_past_end
)))
6226 /* Clear the display of the old active region, if any. */
6227 clear_mouse_face (dpyinfo
);
6229 /* Find the highest priority overlay that has a mouse-face prop. */
6231 for (i
= 0; i
< noverlays
; i
++)
6233 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
6234 if (!NILP (mouse_face
))
6236 overlay
= overlay_vec
[i
];
6241 /* If no overlay applies, get a text property. */
6243 mouse_face
= Fget_text_property (position
, Qmouse_face
, w
->buffer
);
6245 /* Handle the overlay case. */
6246 if (! NILP (overlay
))
6248 /* Find the range of text around this char that
6249 should be active. */
6250 Lisp_Object before
, after
;
6253 before
= Foverlay_start (overlay
);
6254 after
= Foverlay_end (overlay
);
6255 /* Record this as the current active region. */
6256 fast_find_position (w
, XFASTINT (before
),
6257 &dpyinfo
->mouse_face_beg_col
,
6258 &dpyinfo
->mouse_face_beg_row
,
6259 &dpyinfo
->mouse_face_beg_x
,
6260 &dpyinfo
->mouse_face_beg_y
);
6261 dpyinfo
->mouse_face_past_end
6262 = !fast_find_position (w
, XFASTINT (after
),
6263 &dpyinfo
->mouse_face_end_col
,
6264 &dpyinfo
->mouse_face_end_row
,
6265 &dpyinfo
->mouse_face_end_x
,
6266 &dpyinfo
->mouse_face_end_y
);
6267 dpyinfo
->mouse_face_window
= window
;
6268 dpyinfo
->mouse_face_face_id
6269 = face_at_buffer_position (w
, pos
, 0, 0,
6270 &ignore
, pos
+ 1, 1);
6272 /* Display it as active. */
6273 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6275 /* Handle the text property case. */
6276 else if (! NILP (mouse_face
))
6278 /* Find the range of text around this char that
6279 should be active. */
6280 Lisp_Object before
, after
, beginning
, end
;
6283 beginning
= Fmarker_position (w
->start
);
6284 XSETINT (end
, (BUF_Z (XBUFFER (w
->buffer
))
6285 - XFASTINT (w
->window_end_pos
)));
6287 = Fprevious_single_property_change (make_number (pos
+ 1),
6289 w
->buffer
, beginning
);
6291 = Fnext_single_property_change (position
, Qmouse_face
,
6293 /* Record this as the current active region. */
6294 fast_find_position (w
, XFASTINT (before
),
6295 &dpyinfo
->mouse_face_beg_col
,
6296 &dpyinfo
->mouse_face_beg_row
,
6297 &dpyinfo
->mouse_face_beg_x
,
6298 &dpyinfo
->mouse_face_beg_y
);
6299 dpyinfo
->mouse_face_past_end
6300 = !fast_find_position (w
, XFASTINT (after
),
6301 &dpyinfo
->mouse_face_end_col
,
6302 &dpyinfo
->mouse_face_end_row
,
6303 &dpyinfo
->mouse_face_end_x
,
6304 &dpyinfo
->mouse_face_end_y
);
6305 dpyinfo
->mouse_face_window
= window
;
6306 dpyinfo
->mouse_face_face_id
6307 = face_at_buffer_position (w
, pos
, 0, 0,
6308 &ignore
, pos
+ 1, 1);
6310 /* Display it as active. */
6311 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
6315 /* Look for a `help-echo' property. */
6319 /* Check overlays first. */
6321 for (i
= 0; i
< noverlays
&& !STRINGP (help
); ++i
)
6322 help
= Foverlay_get (overlay_vec
[i
], Qhelp_echo
);
6324 /* Try text properties. */
6326 && ((STRINGP (glyph
->object
)
6327 && glyph
->charpos
>= 0
6328 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6329 || (BUFFERP (glyph
->object
)
6330 && glyph
->charpos
>= BEGV
6331 && glyph
->charpos
< ZV
)))
6332 help
= Fget_text_property (make_number (glyph
->charpos
),
6333 Qhelp_echo
, glyph
->object
);
6341 current_buffer
= obuf
;
6347 redo_mouse_highlight ()
6349 if (!NILP (last_mouse_motion_frame
)
6350 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
6351 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
6352 last_mouse_motion_event
.x
,
6353 last_mouse_motion_event
.y
);
6358 /***********************************************************************
6360 ***********************************************************************/
6362 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
6363 struct glyph
**, int *, int *, int *));
6365 /* Tool-bar item index of the item on which a mouse button was pressed
6368 static int last_tool_bar_item
;
6371 /* Get information about the tool-bar item at position X/Y on frame F.
6372 Return in *GLYPH a pointer to the glyph of the tool-bar item in
6373 the current matrix of the tool-bar window of F, or NULL if not
6374 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
6375 item in F->current_tool_bar_items. Value is
6377 -1 if X/Y is not on a tool-bar item
6378 0 if X/Y is on the same item that was highlighted before.
6382 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
6385 struct glyph
**glyph
;
6386 int *hpos
, *vpos
, *prop_idx
;
6388 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6389 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6392 /* Find the glyph under X/Y. */
6393 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
);
6397 /* Get the start of this tool-bar item's properties in
6398 f->current_tool_bar_items. */
6399 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
6402 /* Is mouse on the highlighted item? */
6403 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
6404 && *vpos
>= dpyinfo
->mouse_face_beg_row
6405 && *vpos
<= dpyinfo
->mouse_face_end_row
6406 && (*vpos
> dpyinfo
->mouse_face_beg_row
6407 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
6408 && (*vpos
< dpyinfo
->mouse_face_end_row
6409 || *hpos
< dpyinfo
->mouse_face_end_col
6410 || dpyinfo
->mouse_face_past_end
))
6417 /* Handle mouse button event on the tool-bar of frame F, at
6418 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
6422 x_handle_tool_bar_click (f
, button_event
)
6424 XButtonEvent
*button_event
;
6426 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6427 struct window
*w
= XWINDOW (f
->tool_bar_window
);
6428 int hpos
, vpos
, prop_idx
;
6429 struct glyph
*glyph
;
6430 Lisp_Object enabled_p
;
6431 int x
= button_event
->x
;
6432 int y
= button_event
->y
;
6434 /* If not on the highlighted tool-bar item, return. */
6435 frame_to_window_pixel_xy (w
, &x
, &y
);
6436 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
6439 /* If item is disabled, do nothing. */
6440 enabled_p
= (XVECTOR (f
->current_tool_bar_items
)
6441 ->contents
[prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
]);
6442 if (NILP (enabled_p
))
6445 if (button_event
->type
== ButtonPress
)
6447 /* Show item in pressed state. */
6448 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
6449 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
6450 last_tool_bar_item
= prop_idx
;
6454 Lisp_Object key
, frame
;
6455 struct input_event event
;
6457 /* Show item in released state. */
6458 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
6459 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
6461 key
= (XVECTOR (f
->current_tool_bar_items
)
6462 ->contents
[prop_idx
+ TOOL_BAR_ITEM_KEY
]);
6464 XSETFRAME (frame
, f
);
6465 event
.kind
= TOOL_BAR_EVENT
;
6466 event
.frame_or_window
= Fcons (frame
, Fcons (Qtool_bar
, Qnil
));
6467 kbd_buffer_store_event (&event
);
6469 event
.kind
= TOOL_BAR_EVENT
;
6470 event
.frame_or_window
= Fcons (frame
, key
);
6471 event
.modifiers
= x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
6472 button_event
->state
);
6473 kbd_buffer_store_event (&event
);
6474 last_tool_bar_item
= -1;
6479 /* Possibly highlight a tool-bar item on frame F when mouse moves to
6480 tool-bar window-relative coordinates X/Y. Called from
6481 note_mouse_highlight. */
6484 note_tool_bar_highlight (f
, x
, y
)
6488 Lisp_Object window
= f
->tool_bar_window
;
6489 struct window
*w
= XWINDOW (window
);
6490 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6492 struct glyph
*glyph
;
6493 struct glyph_row
*row
;
6495 Lisp_Object enabled_p
;
6497 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
6498 int mouse_down_p
, rc
;
6500 /* Function note_mouse_highlight is called with negative x(y
6501 values when mouse moves outside of the frame. */
6502 if (x
<= 0 || y
<= 0)
6504 clear_mouse_face (dpyinfo
);
6508 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
6511 /* Not on tool-bar item. */
6512 clear_mouse_face (dpyinfo
);
6516 /* On same tool-bar item as before. */
6519 clear_mouse_face (dpyinfo
);
6521 /* Mouse is down, but on different tool-bar item? */
6522 mouse_down_p
= (dpyinfo
->grabbed
6523 && f
== last_mouse_frame
6524 && FRAME_LIVE_P (f
));
6526 && last_tool_bar_item
!= prop_idx
)
6529 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
6530 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
6532 /* If tool-bar item is not enabled, don't highlight it. */
6533 enabled_p
= (XVECTOR (f
->current_tool_bar_items
)
6534 ->contents
[prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
]);
6535 if (!NILP (enabled_p
))
6537 /* Compute the x-position of the glyph. In front and past the
6538 image is a space. We include this is the highlighted area. */
6539 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6540 for (i
= x
= 0; i
< hpos
; ++i
)
6541 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
6543 /* Record this as the current active region. */
6544 dpyinfo
->mouse_face_beg_col
= hpos
;
6545 dpyinfo
->mouse_face_beg_row
= vpos
;
6546 dpyinfo
->mouse_face_beg_x
= x
;
6547 dpyinfo
->mouse_face_beg_y
= row
->y
;
6548 dpyinfo
->mouse_face_past_end
= 0;
6550 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
6551 dpyinfo
->mouse_face_end_row
= vpos
;
6552 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
6553 dpyinfo
->mouse_face_end_y
= row
->y
;
6554 dpyinfo
->mouse_face_window
= window
;
6555 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
6557 /* Display it as active. */
6558 show_mouse_face (dpyinfo
, draw
);
6559 dpyinfo
->mouse_face_image_state
= draw
;
6564 /* Set help_echo to a help string.to display for this tool-bar item.
6565 XTread_socket does the rest. */
6566 help_echo
= (XVECTOR (f
->current_tool_bar_items
)
6567 ->contents
[prop_idx
+ TOOL_BAR_ITEM_HELP
]);
6568 if (!STRINGP (help_echo
))
6569 help_echo
= (XVECTOR (f
->current_tool_bar_items
)
6570 ->contents
[prop_idx
+ TOOL_BAR_ITEM_CAPTION
]);
6575 /* Find the glyph matrix position of buffer position POS in window W.
6576 *HPOS, *VPOS, *X, and *Y are set to the positions found. W's
6577 current glyphs must be up to date. If POS is above window start
6578 return (0, 0, 0, 0). If POS is after end of W, return end of
6582 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
)
6585 int *hpos
, *vpos
, *x
, *y
;
6589 int maybe_next_line_p
= 0;
6590 int line_start_position
;
6591 int yb
= window_text_bottom_y (w
);
6592 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0);
6593 struct glyph_row
*best_row
= row
;
6594 int row_vpos
= 0, best_row_vpos
= 0;
6599 if (row
->used
[TEXT_AREA
])
6600 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
6602 line_start_position
= 0;
6604 if (line_start_position
> pos
)
6606 /* If the position sought is the end of the buffer,
6607 don't include the blank lines at the bottom of the window. */
6608 else if (line_start_position
== pos
6609 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
6611 maybe_next_line_p
= 1;
6614 else if (line_start_position
> 0)
6617 best_row_vpos
= row_vpos
;
6624 /* Find the right column within BEST_ROW. */
6626 current_x
= best_row
->x
;
6627 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
6629 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
6632 charpos
= glyph
->charpos
;
6636 *vpos
= best_row_vpos
;
6641 else if (charpos
> pos
)
6643 else if (charpos
> 0)
6646 current_x
+= glyph
->pixel_width
;
6649 /* If we're looking for the end of the buffer,
6650 and we didn't find it in the line we scanned,
6651 use the start of the following line. */
6652 if (maybe_next_line_p
)
6657 current_x
= best_row
->x
;
6660 *vpos
= best_row_vpos
;
6661 *hpos
= lastcol
+ 1;
6668 /* Display the active region described by mouse_face_*
6669 in its mouse-face if HL > 0, in its normal face if HL = 0. */
6672 show_mouse_face (dpyinfo
, draw
)
6673 struct x_display_info
*dpyinfo
;
6674 enum draw_glyphs_face draw
;
6676 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
6677 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
6679 int cursor_off_p
= 0;
6680 struct cursor_pos saved_cursor
;
6682 saved_cursor
= output_cursor
;
6684 /* If window is in the process of being destroyed, don't bother
6686 if (w
->current_matrix
== NULL
)
6689 /* Recognize when we are called to operate on rows that don't exist
6690 anymore. This can happen when a window is split. */
6691 if (dpyinfo
->mouse_face_end_row
>= w
->current_matrix
->nrows
)
6694 set_output_cursor (&w
->phys_cursor
);
6696 /* Note that mouse_face_beg_row etc. are window relative. */
6697 for (i
= dpyinfo
->mouse_face_beg_row
;
6698 i
<= dpyinfo
->mouse_face_end_row
;
6701 int start_hpos
, end_hpos
, start_x
;
6702 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
6704 /* Don't do anything if row doesn't have valid contents. */
6705 if (!row
->enabled_p
)
6708 /* For all but the first row, the highlight starts at column 0. */
6709 if (i
== dpyinfo
->mouse_face_beg_row
)
6711 start_hpos
= dpyinfo
->mouse_face_beg_col
;
6712 start_x
= dpyinfo
->mouse_face_beg_x
;
6720 if (i
== dpyinfo
->mouse_face_end_row
)
6721 end_hpos
= dpyinfo
->mouse_face_end_col
;
6723 end_hpos
= row
->used
[TEXT_AREA
];
6725 /* If the cursor's in the text we are about to rewrite, turn the
6727 if (!w
->pseudo_window_p
6728 && i
== output_cursor
.vpos
6729 && output_cursor
.hpos
>= start_hpos
- 1
6730 && output_cursor
.hpos
<= end_hpos
)
6732 x_update_window_cursor (w
, 0);
6736 if (end_hpos
> start_hpos
)
6737 x_draw_glyphs (w
, start_x
, row
, updated_area
,
6738 start_hpos
, end_hpos
, draw
, NULL
, NULL
, 0);
6741 /* If we turned the cursor off, turn it back on. */
6743 x_display_cursor (w
, 1,
6744 output_cursor
.hpos
, output_cursor
.vpos
,
6745 output_cursor
.x
, output_cursor
.y
);
6747 output_cursor
= saved_cursor
;
6751 /* Change the mouse cursor. */
6752 if (draw
== DRAW_NORMAL_TEXT
)
6753 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6754 f
->output_data
.x
->text_cursor
);
6755 else if (draw
== DRAW_MOUSE_FACE
)
6756 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6757 f
->output_data
.x
->cross_cursor
);
6759 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6760 f
->output_data
.x
->nontext_cursor
);
6763 /* Clear out the mouse-highlighted active region.
6764 Redraw it un-highlighted first. */
6767 clear_mouse_face (dpyinfo
)
6768 struct x_display_info
*dpyinfo
;
6773 if (! NILP (dpyinfo
->mouse_face_window
))
6774 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
6776 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
6777 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
6778 dpyinfo
->mouse_face_window
= Qnil
;
6781 /* Just discard the mouse face information for frame F, if any.
6782 This is used when the size of F is changed. */
6785 cancel_mouse_face (f
)
6789 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6791 window
= dpyinfo
->mouse_face_window
;
6792 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
6794 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
6795 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
6796 dpyinfo
->mouse_face_window
= Qnil
;
6800 static struct scroll_bar
*x_window_to_scroll_bar ();
6801 static void x_scroll_bar_report_motion ();
6803 /* Return the current position of the mouse.
6804 *fp should be a frame which indicates which display to ask about.
6806 If the mouse movement started in a scroll bar, set *fp, *bar_window,
6807 and *part to the frame, window, and scroll bar part that the mouse
6808 is over. Set *x and *y to the portion and whole of the mouse's
6809 position on the scroll bar.
6811 If the mouse movement started elsewhere, set *fp to the frame the
6812 mouse is on, *bar_window to nil, and *x and *y to the character cell
6815 Set *time to the server time-stamp for the time at which the mouse
6816 was at this position.
6818 Don't store anything if we don't have a valid set of values to report.
6820 This clears the mouse_moved flag, so we can wait for the next mouse
6824 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
6827 Lisp_Object
*bar_window
;
6828 enum scroll_bar_part
*part
;
6830 unsigned long *time
;
6836 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
6837 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
6843 Window dummy_window
;
6846 Lisp_Object frame
, tail
;
6848 /* Clear the mouse-moved flag for every frame on this display. */
6849 FOR_EACH_FRAME (tail
, frame
)
6850 if (FRAME_X_DISPLAY (XFRAME (frame
)) == FRAME_X_DISPLAY (*fp
))
6851 XFRAME (frame
)->mouse_moved
= 0;
6853 last_mouse_scroll_bar
= Qnil
;
6855 /* Figure out which root window we're on. */
6856 XQueryPointer (FRAME_X_DISPLAY (*fp
),
6857 DefaultRootWindow (FRAME_X_DISPLAY (*fp
)),
6859 /* The root window which contains the pointer. */
6862 /* Trash which we can't trust if the pointer is on
6863 a different screen. */
6866 /* The position on that root window. */
6869 /* More trash we can't trust. */
6872 /* Modifier keys and pointer buttons, about which
6874 (unsigned int *) &dummy
);
6876 /* Now we have a position on the root; find the innermost window
6877 containing the pointer. */
6881 int parent_x
= 0, parent_y
= 0;
6886 /* XTranslateCoordinates can get errors if the window
6887 structure is changing at the same time this function
6888 is running. So at least we must not crash from them. */
6890 count
= x_catch_errors (FRAME_X_DISPLAY (*fp
));
6892 if (FRAME_X_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
6893 && FRAME_LIVE_P (last_mouse_frame
))
6895 /* If mouse was grabbed on a frame, give coords for that frame
6896 even if the mouse is now outside it. */
6897 XTranslateCoordinates (FRAME_X_DISPLAY (*fp
),
6899 /* From-window, to-window. */
6900 root
, FRAME_X_WINDOW (last_mouse_frame
),
6902 /* From-position, to-position. */
6903 root_x
, root_y
, &win_x
, &win_y
,
6907 f1
= last_mouse_frame
;
6913 XTranslateCoordinates (FRAME_X_DISPLAY (*fp
),
6915 /* From-window, to-window. */
6918 /* From-position, to-position. */
6919 root_x
, root_y
, &win_x
, &win_y
,
6924 if (child
== None
|| child
== win
)
6932 /* Now we know that:
6933 win is the innermost window containing the pointer
6934 (XTC says it has no child containing the pointer),
6935 win_x and win_y are the pointer's position in it
6936 (XTC did this the last time through), and
6937 parent_x and parent_y are the pointer's position in win's parent.
6938 (They are what win_x and win_y were when win was child.
6939 If win is the root window, it has no parent, and
6940 parent_{x,y} are invalid, but that's okay, because we'll
6941 never use them in that case.) */
6943 /* Is win one of our frames? */
6944 f1
= x_any_window_to_frame (FRAME_X_DISPLAY_INFO (*fp
), win
);
6947 if (x_had_errors_p (FRAME_X_DISPLAY (*fp
)))
6950 x_uncatch_errors (FRAME_X_DISPLAY (*fp
), count
);
6952 /* If not, is it one of our scroll bars? */
6955 struct scroll_bar
*bar
= x_window_to_scroll_bar (win
);
6959 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
6965 if (f1
== 0 && insist
> 0)
6966 f1
= SELECTED_FRAME ();
6970 /* Ok, we found a frame. Store all the values.
6971 last_mouse_glyph is a rectangle used to reduce the
6972 generation of mouse events. To not miss any motion
6973 events, we must divide the frame into rectangles of the
6974 size of the smallest character that could be displayed
6975 on it, i.e. into the same rectangles that matrices on
6976 the frame are divided into. */
6978 #if OLD_REDISPLAY_CODE
6979 int ignore1
, ignore2
;
6980 pixel_to_glyph_coords (f1
, win_x
, win_y
, &ignore1
, &ignore2
,
6982 FRAME_X_DISPLAY_INFO (f1
)->grabbed
6986 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
6987 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
6991 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
6992 round down even for negative values. */
6998 last_mouse_glyph
.width
= width
;
6999 last_mouse_glyph
.height
= height
;
7000 last_mouse_glyph
.x
= (x
+ width
- 1) / width
* width
;
7001 last_mouse_glyph
.y
= (y
+ height
- 1) / height
* height
;
7008 XSETINT (*x
, win_x
);
7009 XSETINT (*y
, win_y
);
7010 *time
= last_mouse_movement_time
;
7019 DEFUN ("xt-process-timeouts", Fxt_process_timeouts
, Sxt_process_timeouts
,
7021 "Arrange for Xt timeout callbacks to be called.")
7024 #ifdef USE_X_TOOLKIT
7026 while (XtAppPending (Xt_app_con
) & XtIMTimer
)
7027 XtAppProcessEvent (Xt_app_con
, XtIMTimer
);
7029 #endif /* USE_X_TOOLKIT */
7036 /* Scroll bar support. */
7038 /* Given an X window ID, find the struct scroll_bar which manages it.
7039 This can be called in GC, so we have to make sure to strip off mark
7041 static struct scroll_bar
*
7042 x_window_to_scroll_bar (window_id
)
7047 for (tail
= Vframe_list
;
7048 XGCTYPE (tail
) == Lisp_Cons
;
7051 Lisp_Object frame
, bar
, condemned
;
7053 frame
= XCAR (tail
);
7054 /* All elements of Vframe_list should be frames. */
7055 if (! GC_FRAMEP (frame
))
7058 /* Scan this frame's scroll bar list for a scroll bar with the
7060 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
7061 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
7062 /* This trick allows us to search both the ordinary and
7063 condemned scroll bar lists with one loop. */
7064 ! GC_NILP (bar
) || (bar
= condemned
,
7067 bar
= XSCROLL_BAR (bar
)->next
)
7068 if (SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
7069 return XSCROLL_BAR (bar
);
7077 /************************************************************************
7079 ************************************************************************/
7081 #if USE_TOOLKIT_SCROLL_BARS
7083 static void x_scroll_bar_to_input_event
P_ ((XEvent
*, struct input_event
*));
7084 static void x_send_scroll_bar_event
P_ ((Lisp_Object
, int, int, int));
7085 static void x_create_toolkit_scroll_bar
P_ ((struct frame
*,
7086 struct scroll_bar
*));
7087 static void x_set_toolkit_scroll_bar_thumb
P_ ((struct scroll_bar
*,
7091 /* Id of action hook installed for scroll bars. */
7093 static XtActionHookId action_hook_id
;
7095 /* Lisp window being scrolled. Set when starting to interact with
7096 a toolkit scroll bar, reset to nil when ending the interaction. */
7098 static Lisp_Object window_being_scrolled
;
7100 /* Last scroll bar part sent in xm_scroll_callback. */
7102 static int last_scroll_bar_part
;
7105 /* Action hook installed via XtAppAddActionHook when toolkit scroll
7106 bars are used.. The hoos is responsible for detecting when
7107 the user ends an interaction with the scroll bar, and generates
7108 a `end-scroll' scroll_bar_click' event if so. */
7111 xt_action_hook (widget
, client_data
, action_name
, event
, params
,
7114 XtPointer client_data
;
7118 Cardinal
*num_params
;
7124 scroll_bar_p
= XmIsScrollBar (widget
);
7125 end_action
= "Release";
7126 #elif defined HAVE_XAW3D
7127 scroll_bar_p
= XtIsSubclass (widget
, scrollbarWidgetClass
);
7128 end_action
= "EndScroll";
7130 #error unknown scroll bar toolkit
7131 #endif /* HAVE_XAW3D */
7133 /* Although LessTif uses XtTimeouts like Xaw3d, the timer hack to
7134 let Xt timeouts be processed doesn't work. */
7136 && strcmp (action_name
, end_action
) == 0
7137 && WINDOWP (window_being_scrolled
))
7141 x_send_scroll_bar_event (window_being_scrolled
,
7142 scroll_bar_end_scroll
, 0, 0);
7143 w
= XWINDOW (window_being_scrolled
);
7144 XSCROLL_BAR (w
->vertical_scroll_bar
)->dragging
= Qnil
;
7145 window_being_scrolled
= Qnil
;
7146 last_scroll_bar_part
= -1;
7151 /* Send a client message with message type Xatom_Scrollbar for a
7152 scroll action to the frame of WINDOW. PART is a value identifying
7153 the part of the scroll bar that was clicked on. PORTION is the
7154 amount to scroll of a whole of WHOLE. */
7157 x_send_scroll_bar_event (window
, part
, portion
, whole
)
7159 int part
, portion
, whole
;
7162 XClientMessageEvent
*ev
= (XClientMessageEvent
*) &event
;
7163 struct frame
*f
= XFRAME (XWINDOW (window
)->frame
);
7165 /* Construct a ClientMessage event to send to the frame. */
7166 ev
->type
= ClientMessage
;
7167 ev
->message_type
= FRAME_X_DISPLAY_INFO (f
)->Xatom_Scrollbar
;
7168 ev
->display
= FRAME_X_DISPLAY (f
);
7169 ev
->window
= FRAME_X_WINDOW (f
);
7171 ev
->data
.l
[0] = (long) window
;
7172 ev
->data
.l
[1] = (long) part
;
7173 ev
->data
.l
[2] = (long) 0;
7174 ev
->data
.l
[3] = (long) portion
;
7175 ev
->data
.l
[4] = (long) whole
;
7177 /* Setting the event mask to zero means that the message will
7178 be sent to the client that created the window, and if that
7179 window no longer exists, no event will be sent. */
7181 XSendEvent (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), False
, 0, &event
);
7186 /* Transform a scroll bar ClientMessage EVENT to an Emacs input event
7190 x_scroll_bar_to_input_event (event
, ievent
)
7192 struct input_event
*ievent
;
7194 XClientMessageEvent
*ev
= (XClientMessageEvent
*) event
;
7195 Lisp_Object window
= (Lisp_Object
) ev
->data
.l
[0];
7196 struct frame
*f
= XFRAME (XWINDOW (window
)->frame
);
7198 ievent
->kind
= scroll_bar_click
;
7199 ievent
->frame_or_window
= window
;
7200 ievent
->timestamp
= XtLastTimestampProcessed (FRAME_X_DISPLAY (f
));
7201 ievent
->part
= ev
->data
.l
[1];
7202 ievent
->code
= ev
->data
.l
[2];
7203 ievent
->x
= make_number ((int) ev
->data
.l
[3]);
7204 ievent
->y
= make_number ((int) ev
->data
.l
[4]);
7205 ievent
->modifiers
= 0;
7211 /* Minimum and maximum values used for Motif scroll bars. */
7214 #define XM_SB_MAX 10000000
7215 #define XM_SB_RANGE (XM_SB_MAX - XM_SB_MIN)
7218 /* Scroll bar callback for Motif scroll bars. WIDGET is the scroll
7219 bar widget. CLIENT_DATA is a pointer to the scroll_bar structure.
7220 CALL_DATA is a pointer a a XmScrollBarCallbackStruct. */
7223 xm_scroll_callback (widget
, client_data
, call_data
)
7225 XtPointer client_data
, call_data
;
7227 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
7228 XmScrollBarCallbackStruct
*cs
= (XmScrollBarCallbackStruct
*) call_data
;
7230 int part
= -1, whole
= 0, portion
= 0;
7234 case XmCR_DECREMENT
:
7235 bar
->dragging
= Qnil
;
7236 part
= scroll_bar_up_arrow
;
7239 case XmCR_INCREMENT
:
7240 bar
->dragging
= Qnil
;
7241 part
= scroll_bar_down_arrow
;
7244 case XmCR_PAGE_DECREMENT
:
7245 bar
->dragging
= Qnil
;
7246 part
= scroll_bar_above_handle
;
7249 case XmCR_PAGE_INCREMENT
:
7250 bar
->dragging
= Qnil
;
7251 part
= scroll_bar_below_handle
;
7255 bar
->dragging
= Qnil
;
7256 part
= scroll_bar_to_top
;
7259 case XmCR_TO_BOTTOM
:
7260 bar
->dragging
= Qnil
;
7261 part
= scroll_bar_to_bottom
;
7267 int dragging_down_p
= (INTEGERP (bar
->dragging
)
7268 && XINT (bar
->dragging
) <= cs
->value
);
7270 /* Get the slider size. */
7272 XtVaGetValues (widget
, XmNsliderSize
, &slider_size
, NULL
);
7275 /* At the max position of the scroll bar, do a line-wise
7276 movement. Without doing anything, the LessTif scroll bar
7277 calls us with the same cs->value again and again. If we
7278 want to make sure that we can reach the end of the buffer,
7279 we have to do something.
7281 Implementation note: setting bar->dragging always to
7282 cs->value gives a smoother movement at the max position.
7283 Setting it to nil when doing line-wise movement gives
7284 a better slider behavior. */
7286 if (cs
->value
+ slider_size
== XM_SB_MAX
7288 && last_scroll_bar_part
== scroll_bar_down_arrow
))
7290 part
= scroll_bar_down_arrow
;
7291 bar
->dragging
= Qnil
;
7295 whole
= XM_SB_RANGE
;
7296 portion
= min (cs
->value
- XM_SB_MIN
, XM_SB_MAX
- slider_size
);
7297 part
= scroll_bar_handle
;
7298 bar
->dragging
= make_number (cs
->value
);
7303 case XmCR_VALUE_CHANGED
:
7309 window_being_scrolled
= bar
->window
;
7310 last_scroll_bar_part
= part
;
7311 x_send_scroll_bar_event (bar
->window
, part
, portion
, whole
);
7316 #else /* not USE_MOTIF, i.e. XAW3D. */
7319 /* Xaw3d scroll bar callback. Invoked when the thumb is dragged.
7320 WIDGET is the scroll bar widget. CLIENT_DATA is a pointer to the
7321 scroll bar struct. CALL_DATA is a pointer to a float saying where
7325 xaw3d_jump_callback (widget
, client_data
, call_data
)
7327 XtPointer client_data
, call_data
;
7329 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
7330 float top
= *(float *) call_data
;
7333 int dragging_down_p
, part
;
7334 double epsilon
= 0.01;
7336 /* Get the size of the thumb, a value between 0 and 1. */
7338 XtVaGetValues (widget
, XtNshown
, &shown
, NULL
);
7342 portion
= shown
< 1 ? top
* whole
: 0;
7343 dragging_down_p
= (INTEGERP (bar
->dragging
)
7344 && XINT (bar
->dragging
) < portion
);
7347 && (abs (top
+ shown
- 1) < epsilon
7349 && last_scroll_bar_part
== scroll_bar_down_arrow
)))
7350 part
= scroll_bar_down_arrow
;
7352 part
= scroll_bar_handle
;
7354 window_being_scrolled
= bar
->window
;
7355 bar
->dragging
= make_number (portion
);
7356 last_scroll_bar_part
= part
;
7357 x_send_scroll_bar_event (bar
->window
, part
, portion
, whole
);
7361 /* Xaw3d scroll bar callback. Invoked for incremental scrolling.,
7362 i.e. line or page up or down. WIDGET is the Xaw3d scroll bar
7363 widget. CLIENT_DATA is a pointer to the scroll_bar structure for
7364 the scroll bar. CALL_DATA is an integer specifying the action that
7365 has taken place. It's magnitude is in the range 0..height of the
7366 scroll bar. Negative values mean scroll towards buffer start.
7367 Values < height of scroll bar mean line-wise movement. */
7370 xaw3d_scroll_callback (widget
, client_data
, call_data
)
7372 XtPointer client_data
, call_data
;
7374 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
7375 int position
= (int) call_data
;
7379 /* Get the height of the scroll bar. */
7381 XtVaGetValues (widget
, XtNheight
, &height
, NULL
);
7386 if (abs (position
) < height
)
7387 part
= scroll_bar_up_arrow
;
7389 part
= scroll_bar_above_handle
;
7393 if (abs (position
) < height
)
7394 part
= scroll_bar_down_arrow
;
7396 part
= scroll_bar_below_handle
;
7399 window_being_scrolled
= bar
->window
;
7400 bar
->dragging
= Qnil
;
7401 last_scroll_bar_part
= part
;
7402 x_send_scroll_bar_event (bar
->window
, part
, 0, 0);
7406 #endif /* not USE_MOTIF */
7409 /* Create the widget for scroll bar BAR on frame F. Record the widget
7410 and X window of the scroll bar in BAR. */
7413 x_create_toolkit_scroll_bar (f
, bar
)
7415 struct scroll_bar
*bar
;
7421 char *scroll_bar_name
= "verticalScrollBar";
7422 unsigned long pixel
;
7427 /* LessTif 0.85, problems:
7429 1. When the mouse if over the scroll bar, the scroll bar will
7430 get keyboard events. I didn't find a way to turn this off.
7432 2. Do we have to explicitly set the cursor to get an arrow
7433 cursor (see below)? */
7435 /* Set resources. Create the widget. */
7436 XtSetArg (av
[ac
], XtNmappedWhenManaged
, False
); ++ac
;
7437 XtSetArg (av
[ac
], XmNminimum
, XM_SB_MIN
); ++ac
;
7438 XtSetArg (av
[ac
], XmNmaximum
, XM_SB_MAX
); ++ac
;
7439 XtSetArg (av
[ac
], XmNorientation
, XmVERTICAL
); ++ac
;
7440 XtSetArg (av
[ac
], XmNprocessingDirection
, XmMAX_ON_BOTTOM
), ++ac
;
7441 XtSetArg (av
[ac
], XmNincrement
, 1); ++ac
;
7442 XtSetArg (av
[ac
], XmNpageIncrement
, 1); ++ac
;
7444 pixel
= f
->output_data
.x
->scroll_bar_foreground_pixel
;
7447 XtSetArg (av
[ac
], XmNforeground
, pixel
);
7451 pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
7454 XtSetArg (av
[ac
], XmNbackground
, pixel
);
7458 widget
= XmCreateScrollBar (f
->output_data
.x
->edit_widget
,
7459 scroll_bar_name
, av
, ac
);
7461 /* Add one callback for everything that can happen. */
7462 XtAddCallback (widget
, XmNdecrementCallback
, xm_scroll_callback
,
7464 XtAddCallback (widget
, XmNdragCallback
, xm_scroll_callback
,
7466 XtAddCallback (widget
, XmNincrementCallback
, xm_scroll_callback
,
7468 XtAddCallback (widget
, XmNpageDecrementCallback
, xm_scroll_callback
,
7470 XtAddCallback (widget
, XmNpageIncrementCallback
, xm_scroll_callback
,
7472 XtAddCallback (widget
, XmNtoBottomCallback
, xm_scroll_callback
,
7474 XtAddCallback (widget
, XmNtoTopCallback
, xm_scroll_callback
,
7477 /* Realize the widget. Only after that is the X window created. */
7478 XtRealizeWidget (widget
);
7480 /* Set the cursor to an arrow. I didn't find a resource to do that.
7481 And I'm wondering why it hasn't an arrow cursor by default. */
7482 XDefineCursor (XtDisplay (widget
), XtWindow (widget
),
7483 f
->output_data
.x
->nontext_cursor
);
7485 #elif defined HAVE_XAW3D
7487 /* Set resources. Create the widget. The background of the
7488 Xaw3d scroll bar widget is a little bit light for my taste.
7489 We don't alter it here to let users change it according
7490 to their taste with `emacs*verticalScrollBar.background: xxx'. */
7491 XtSetArg (av
[ac
], XtNmappedWhenManaged
, False
); ++ac
;
7492 XtSetArg (av
[ac
], XtNorientation
, XtorientVertical
); ++ac
;
7493 XtSetArg (av
[ac
], XtNcursorName
, "left_ptr"); ++ac
;
7494 XtSetArg (av
[ac
], XtNbeNiceToColormap
, True
); ++ac
;
7496 pixel
= f
->output_data
.x
->scroll_bar_foreground_pixel
;
7499 XtSetArg (av
[ac
], XtNforeground
, pixel
);
7503 pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
7506 XtSetArg (av
[ac
], XtNbackground
, pixel
);
7510 widget
= XtCreateWidget (scroll_bar_name
, scrollbarWidgetClass
,
7511 f
->output_data
.x
->edit_widget
, av
, ac
);
7513 /* Define callbacks. */
7514 XtAddCallback (widget
, XtNjumpProc
, xaw3d_jump_callback
, (XtPointer
) bar
);
7515 XtAddCallback (widget
, XtNscrollProc
, xaw3d_scroll_callback
,
7518 /* Realize the widget. Only after that is the X window created. */
7519 XtRealizeWidget (widget
);
7521 #endif /* HAVE_XAW3D */
7523 /* Install an action hook that let's us detect when the user
7524 finishes interacting with a scroll bar. */
7525 if (action_hook_id
== 0)
7526 action_hook_id
= XtAppAddActionHook (Xt_app_con
, xt_action_hook
, 0);
7528 /* Remember X window and widget in the scroll bar vector. */
7529 SET_SCROLL_BAR_X_WIDGET (bar
, widget
);
7530 xwindow
= XtWindow (widget
);
7531 SET_SCROLL_BAR_X_WINDOW (bar
, xwindow
);
7537 /* Set the thumb size and position of scroll bar BAR. We are currently
7538 displaying PORTION out of a whole WHOLE, and our position POSITION. */
7541 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
)
7542 struct scroll_bar
*bar
;
7543 int portion
, position
, whole
;
7546 Widget widget
= SCROLL_BAR_X_WIDGET (bar
);
7552 top
= (float) position
/ whole
;
7553 shown
= (float) portion
/ whole
;
7561 Boolean arrow1_selected
, arrow2_selected
;
7562 unsigned char flags
;
7563 XmScrollBarWidget sb
;
7565 /* Slider size. Must be in the range [1 .. MAX - MIN] where NAX
7566 is the scroll bar's maximum and MIN is the scroll bar's minimum
7568 size
= shown
* XM_SB_RANGE
;
7569 size
= min (size
, XM_SB_RANGE
);
7570 size
= max (size
, 1);
7572 /* Position. Must be in the range [MIN .. MAX - SLIDER_SIZE]. */
7573 value
= top
* XM_SB_RANGE
;
7574 value
= min (value
, XM_SB_MAX
- size
);
7575 value
= max (value
, XM_SB_MIN
);
7577 /* LessTif: Calling XmScrollBarSetValues after an increment or
7578 decrement turns off auto-repeat LessTif-internally. This can
7579 be seen in ScrollBar.c which resets Arrow1Selected and
7580 Arrow2Selected. It also sets internal flags so that LessTif
7581 believes the mouse is in the slider. We either have to change
7582 our code, or work around that by accessing private data. */
7584 sb
= (XmScrollBarWidget
) widget
;
7585 arrow1_selected
= sb
->scrollBar
.arrow1_selected
;
7586 arrow2_selected
= sb
->scrollBar
.arrow2_selected
;
7587 flags
= sb
->scrollBar
.flags
;
7589 if (NILP (bar
->dragging
))
7590 XmScrollBarSetValues (widget
, value
, size
, 0, 0, False
);
7591 else if (last_scroll_bar_part
== scroll_bar_down_arrow
)
7592 /* This has the negative side effect that the slider value is
7593 not would it would be if we scrolled here using line-wise or
7594 page-wise movement. */
7595 XmScrollBarSetValues (widget
, value
, XM_SB_RANGE
- value
, 0, 0, False
);
7598 /* If currently dragging, only update the slider size.
7599 This reduces flicker effects. */
7600 int old_value
, old_size
, increment
, page_increment
;
7602 XmScrollBarGetValues (widget
, &old_value
, &old_size
,
7603 &increment
, &page_increment
);
7604 XmScrollBarSetValues (widget
, old_value
,
7605 min (size
, XM_SB_RANGE
- old_value
),
7609 sb
->scrollBar
.arrow1_selected
= arrow1_selected
;
7610 sb
->scrollBar
.arrow2_selected
= arrow2_selected
;
7611 sb
->scrollBar
.flags
= flags
;
7613 #elif defined HAVE_XAW3D
7615 /* Restrict to [0 1]. */
7616 top
= max (0, min (1, top
));
7617 shown
= max (0, min (1, shown
));
7619 /* If the call to XawScrollbarSetThumb below doesn't seem to work,
7620 check that your system's configuration file contains a define
7621 for `NARROWPROTO'. See s/freebsd.h for an example. */
7622 if (NILP (bar
->dragging
))
7624 float old_top
, old_shown
;
7625 XtVaGetValues (widget
, XtNtopOfThumb
, &old_top
, XtNshown
, &old_shown
,
7627 if (top
!= old_top
|| shown
!= old_shown
)
7628 XawScrollbarSetThumb (widget
, top
, shown
);
7632 ScrollbarWidget sb
= (ScrollbarWidget
) widget
;
7633 int scroll_mode
= sb
->scrollbar
.scroll_mode
;
7635 sb
->scrollbar
.scroll_mode
= 0;
7637 if (last_scroll_bar_part
== scroll_bar_down_arrow
)
7638 XawScrollbarSetThumb (widget
, top
, 1 - top
);
7642 XtVaGetValues (widget
, XtNtopOfThumb
, &old_top
, NULL
);
7643 XawScrollbarSetThumb (widget
, old_top
, min (shown
, 1 - old_top
));
7646 sb
->scrollbar
.scroll_mode
= scroll_mode
;
7649 #endif /* HAVE_XAW3D */
7654 #endif /* USE_TOOLKIT_SCROLL_BARS */
7658 /************************************************************************
7659 Scroll bars, general
7660 ************************************************************************/
7662 /* Create a scroll bar and return the scroll bar vector for it. W is
7663 the Emacs window on which to create the scroll bar. TOP, LEFT,
7664 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
7667 static struct scroll_bar
*
7668 x_scroll_bar_create (w
, top
, left
, width
, height
)
7670 int top
, left
, width
, height
;
7672 struct frame
*f
= XFRAME (w
->frame
);
7673 struct scroll_bar
*bar
7674 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
7678 #if USE_TOOLKIT_SCROLL_BARS
7679 x_create_toolkit_scroll_bar (f
, bar
);
7680 #else /* not USE_TOOLKIT_SCROLL_BARS */
7682 XSetWindowAttributes a
;
7686 a
.background_pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
7687 if (a
.background_pixel
== -1)
7688 a
.background_pixel
= f
->output_data
.x
->background_pixel
;
7690 a
.event_mask
= (ButtonPressMask
| ButtonReleaseMask
7691 | ButtonMotionMask
| PointerMotionHintMask
7693 a
.cursor
= FRAME_X_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
7695 mask
= (CWBackPixel
| CWEventMask
| CWCursor
);
7697 /* Clear the area of W that will serve as a scroll bar. This is
7698 for the case that a window has been split horizontally. In
7699 this case, no clear_frame is generated to reduce flickering. */
7700 XClearArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7702 window_box_height (w
), False
);
7704 window
= XCreateWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7705 /* Position and size of scroll bar. */
7706 left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
7708 width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
7710 /* Border width, depth, class, and visual. */
7717 SET_SCROLL_BAR_X_WINDOW (bar
, window
);
7719 #endif /* not USE_TOOLKIT_SCROLL_BARS */
7721 XSETWINDOW (bar
->window
, w
);
7722 XSETINT (bar
->top
, top
);
7723 XSETINT (bar
->left
, left
);
7724 XSETINT (bar
->width
, width
);
7725 XSETINT (bar
->height
, height
);
7726 XSETINT (bar
->start
, 0);
7727 XSETINT (bar
->end
, 0);
7728 bar
->dragging
= Qnil
;
7730 /* Add bar to its frame's list of scroll bars. */
7731 bar
->next
= FRAME_SCROLL_BARS (f
);
7733 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7734 if (!NILP (bar
->next
))
7735 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7737 /* Map the window/widget. */
7738 #if USE_TOOLKIT_SCROLL_BARS
7739 XtMapWidget (SCROLL_BAR_X_WIDGET (bar
));
7740 XtConfigureWidget (SCROLL_BAR_X_WIDGET (bar
),
7741 left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
7743 width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
7745 #else /* not USE_TOOLKIT_SCROLL_BARS */
7746 XMapRaised (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
));
7747 #endif /* not USE_TOOLKIT_SCROLL_BARS */
7754 /* Draw BAR's handle in the proper position.
7756 If the handle is already drawn from START to END, don't bother
7757 redrawing it, unless REBUILD is non-zero; in that case, always
7758 redraw it. (REBUILD is handy for drawing the handle after expose
7761 Normally, we want to constrain the start and end of the handle to
7762 fit inside its rectangle, but if the user is dragging the scroll
7763 bar handle, we want to let them drag it down all the way, so that
7764 the bar's top is as far down as it goes; otherwise, there's no way
7765 to move to the very end of the buffer. */
7767 #ifndef USE_TOOLKIT_SCROLL_BARS
7770 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
7771 struct scroll_bar
*bar
;
7775 int dragging
= ! NILP (bar
->dragging
);
7776 Window w
= SCROLL_BAR_X_WINDOW (bar
);
7777 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7778 GC gc
= f
->output_data
.x
->normal_gc
;
7780 /* If the display is already accurate, do nothing. */
7782 && start
== XINT (bar
->start
)
7783 && end
== XINT (bar
->end
))
7789 int inside_width
= VERTICAL_SCROLL_BAR_INSIDE_WIDTH (f
, XINT (bar
->width
));
7790 int inside_height
= VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
7791 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7793 /* Make sure the values are reasonable, and try to preserve
7794 the distance between start and end. */
7796 int length
= end
- start
;
7800 else if (start
> top_range
)
7802 end
= start
+ length
;
7806 else if (end
> top_range
&& ! dragging
)
7810 /* Store the adjusted setting in the scroll bar. */
7811 XSETINT (bar
->start
, start
);
7812 XSETINT (bar
->end
, end
);
7814 /* Clip the end position, just for display. */
7815 if (end
> top_range
)
7818 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels
7819 below top positions, to make sure the handle is always at least
7820 that many pixels tall. */
7821 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7823 /* Draw the empty space above the handle. Note that we can't clear
7824 zero-height areas; that means "clear to end of window." */
7826 XClearArea (FRAME_X_DISPLAY (f
), w
,
7828 /* x, y, width, height, and exposures. */
7829 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
7830 VERTICAL_SCROLL_BAR_TOP_BORDER
,
7831 inside_width
, start
,
7834 /* Change to proper foreground color if one is specified. */
7835 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
7836 XSetForeground (FRAME_X_DISPLAY (f
), gc
,
7837 f
->output_data
.x
->scroll_bar_foreground_pixel
);
7839 /* Draw the handle itself. */
7840 XFillRectangle (FRAME_X_DISPLAY (f
), w
, gc
,
7842 /* x, y, width, height */
7843 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
7844 VERTICAL_SCROLL_BAR_TOP_BORDER
+ start
,
7845 inside_width
, end
- start
);
7847 /* Restore the foreground color of the GC if we changed it above. */
7848 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
7849 XSetForeground (FRAME_X_DISPLAY (f
), gc
,
7850 f
->output_data
.x
->foreground_pixel
);
7852 /* Draw the empty space below the handle. Note that we can't
7853 clear zero-height areas; that means "clear to end of window." */
7854 if (end
< inside_height
)
7855 XClearArea (FRAME_X_DISPLAY (f
), w
,
7857 /* x, y, width, height, and exposures. */
7858 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
7859 VERTICAL_SCROLL_BAR_TOP_BORDER
+ end
,
7860 inside_width
, inside_height
- end
,
7868 #endif /* !USE_TOOLKIT_SCROLL_BARS */
7870 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
7874 x_scroll_bar_remove (bar
)
7875 struct scroll_bar
*bar
;
7879 #if USE_TOOLKIT_SCROLL_BARS
7880 XtDestroyWidget (SCROLL_BAR_X_WIDGET (bar
));
7881 #else /* not USE_TOOLKIT_SCROLL_BARS */
7883 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7884 XDestroyWindow (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
));
7886 #endif /* not USE_TOOLKIT_SCROLL_BARS */
7888 /* Disassociate this scroll bar from its window. */
7889 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
7895 /* Set the handle of the vertical scroll bar for WINDOW to indicate
7896 that we are displaying PORTION characters out of a total of WHOLE
7897 characters, starting at POSITION. If WINDOW has no scroll bar,
7901 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
7903 int portion
, whole
, position
;
7905 struct frame
*f
= XFRAME (w
->frame
);
7906 struct scroll_bar
*bar
;
7907 int top
, height
, left
, sb_left
, width
, sb_width
;
7908 int window_x
, window_y
, window_width
, window_height
;
7910 /* Get window dimensions. */
7911 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
7913 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
7914 height
= window_height
;
7916 /* Compute the left edge of the scroll bar area. */
7917 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7918 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
7920 left
= XFASTINT (w
->left
);
7921 left
*= CANON_X_UNIT (f
);
7922 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
7924 /* Compute the width of the scroll bar which might be less than
7925 the width of the area reserved for the scroll bar. */
7926 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
7927 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
7931 /* Compute the left edge of the scroll bar. */
7932 #ifdef USE_TOOLKIT_SCROLL_BARS
7933 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7934 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
7936 sb_left
= left
+ (width
- sb_width
) / 2;
7938 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7939 sb_left
= left
+ width
- sb_width
;
7944 /* Does the scroll bar exist yet? */
7945 if (NILP (w
->vertical_scroll_bar
))
7948 XClearArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7949 left
, top
, width
, height
, False
);
7951 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
7955 /* It may just need to be moved and resized. */
7956 unsigned int mask
= 0;
7958 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
7962 if (sb_left
!= XINT (bar
->left
))
7964 if (top
!= XINT (bar
->top
))
7966 if (sb_width
!= XINT (bar
->width
))
7968 if (height
!= XINT (bar
->height
))
7971 #ifdef USE_TOOLKIT_SCROLL_BARS
7973 /* Since toolkit scroll bars are smaller than the space reserved
7974 for them on the frame, we have to clear "under" them. */
7975 XClearArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7976 left
, top
, width
, height
, False
);
7978 /* Move/size the scroll bar widget. */
7980 XtConfigureWidget (SCROLL_BAR_X_WIDGET (bar
),
7981 sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
7983 sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
7986 #else /* not USE_TOOLKIT_SCROLL_BARS */
7988 if (VERTICAL_SCROLL_BAR_WIDTH_TRIM
)
7990 /* Clear areas not covered by the scroll bar. This makes sure a
7991 previous mode line display is cleared after C-x 2 C-x 1, for
7992 example. Non-toolkit scroll bars are as wide as the area
7993 reserved for scroll bars - trim at both sides. */
7994 XClearArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7995 left
, top
, VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
7997 XClearArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7998 left
+ width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
7999 top
, VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8003 /* Move/size the scroll bar window. */
8008 wc
.x
= sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
8010 wc
.width
= sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2;
8012 XConfigureWindow (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
),
8016 #endif /* not USE_TOOLKIT_SCROLL_BARS */
8018 /* Remember new settings. */
8019 XSETINT (bar
->left
, sb_left
);
8020 XSETINT (bar
->top
, top
);
8021 XSETINT (bar
->width
, sb_width
);
8022 XSETINT (bar
->height
, height
);
8027 #if USE_TOOLKIT_SCROLL_BARS
8028 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
);
8029 #else /* not USE_TOOLKIT_SCROLL_BARS */
8030 /* Set the scroll bar's current state, unless we're currently being
8032 if (NILP (bar
->dragging
))
8034 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
8037 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
8040 int start
= ((double) position
* top_range
) / whole
;
8041 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
8042 x_scroll_bar_set_handle (bar
, start
, end
, 0);
8045 #endif /* not USE_TOOLKIT_SCROLL_BARS */
8047 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
8051 /* The following three hooks are used when we're doing a thorough
8052 redisplay of the frame. We don't explicitly know which scroll bars
8053 are going to be deleted, because keeping track of when windows go
8054 away is a real pain - "Can you say set-window-configuration, boys
8055 and girls?" Instead, we just assert at the beginning of redisplay
8056 that *all* scroll bars are to be removed, and then save a scroll bar
8057 from the fiery pit when we actually redisplay its window. */
8059 /* Arrange for all scroll bars on FRAME to be removed at the next call
8060 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
8061 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
8064 XTcondemn_scroll_bars (frame
)
8067 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
8068 while (! NILP (FRAME_SCROLL_BARS (frame
)))
8071 bar
= FRAME_SCROLL_BARS (frame
);
8072 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
8073 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
8074 XSCROLL_BAR (bar
)->prev
= Qnil
;
8075 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
8076 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
8077 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
8081 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
8082 Note that WINDOW isn't necessarily condemned at all. */
8084 XTredeem_scroll_bar (window
)
8085 struct window
*window
;
8087 struct scroll_bar
*bar
;
8089 /* We can't redeem this window's scroll bar if it doesn't have one. */
8090 if (NILP (window
->vertical_scroll_bar
))
8093 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
8095 /* Unlink it from the condemned list. */
8097 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
8099 if (NILP (bar
->prev
))
8101 /* If the prev pointer is nil, it must be the first in one of
8103 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
8104 /* It's not condemned. Everything's fine. */
8106 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
8107 window
->vertical_scroll_bar
))
8108 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
8110 /* If its prev pointer is nil, it must be at the front of
8111 one or the other! */
8115 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
8117 if (! NILP (bar
->next
))
8118 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
8120 bar
->next
= FRAME_SCROLL_BARS (f
);
8122 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8123 if (! NILP (bar
->next
))
8124 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8128 /* Remove all scroll bars on FRAME that haven't been saved since the
8129 last call to `*condemn_scroll_bars_hook'. */
8132 XTjudge_scroll_bars (f
)
8135 Lisp_Object bar
, next
;
8137 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
8139 /* Clear out the condemned list now so we won't try to process any
8140 more events on the hapless scroll bars. */
8141 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
8143 for (; ! NILP (bar
); bar
= next
)
8145 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
8147 x_scroll_bar_remove (b
);
8150 b
->next
= b
->prev
= Qnil
;
8153 /* Now there should be no references to the condemned scroll bars,
8154 and they should get garbage-collected. */
8158 /* Handle an Expose or GraphicsExpose event on a scroll bar. This
8159 is a no-op when using toolkit scroll bars.
8161 This may be called from a signal handler, so we have to ignore GC
8165 x_scroll_bar_expose (bar
, event
)
8166 struct scroll_bar
*bar
;
8169 #ifndef USE_TOOLKIT_SCROLL_BARS
8171 Window w
= SCROLL_BAR_X_WINDOW (bar
);
8172 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8173 GC gc
= f
->output_data
.x
->normal_gc
;
8174 int width_trim
= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
8178 x_scroll_bar_set_handle (bar
, XINT (bar
->start
), XINT (bar
->end
), 1);
8180 /* Draw a one-pixel border just inside the edges of the scroll bar. */
8181 XDrawRectangle (FRAME_X_DISPLAY (f
), w
, gc
,
8183 /* x, y, width, height */
8185 XINT (bar
->width
) - 1 - width_trim
- width_trim
,
8186 XINT (bar
->height
) - 1);
8190 #endif /* not USE_TOOLKIT_SCROLL_BARS */
8193 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
8194 is set to something other than no_event, it is enqueued.
8196 This may be called from a signal handler, so we have to ignore GC
8199 #ifndef USE_TOOLKIT_SCROLL_BARS
8202 x_scroll_bar_handle_click (bar
, event
, emacs_event
)
8203 struct scroll_bar
*bar
;
8205 struct input_event
*emacs_event
;
8207 if (! GC_WINDOWP (bar
->window
))
8210 emacs_event
->kind
= scroll_bar_click
;
8211 emacs_event
->code
= event
->xbutton
.button
- Button1
;
8212 emacs_event
->modifiers
8213 = (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO
8214 (XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)))),
8215 event
->xbutton
.state
)
8216 | (event
->type
== ButtonRelease
8219 emacs_event
->frame_or_window
= bar
->window
;
8220 emacs_event
->timestamp
= event
->xbutton
.time
;
8223 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8225 = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
8228 = VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8229 int y
= event
->xbutton
.y
- VERTICAL_SCROLL_BAR_TOP_BORDER
;
8232 if (y
> top_range
) y
= top_range
;
8234 if (y
< XINT (bar
->start
))
8235 emacs_event
->part
= scroll_bar_above_handle
;
8236 else if (y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
8237 emacs_event
->part
= scroll_bar_handle
;
8239 emacs_event
->part
= scroll_bar_below_handle
;
8241 /* Just because the user has clicked on the handle doesn't mean
8242 they want to drag it. Lisp code needs to be able to decide
8243 whether or not we're dragging. */
8245 /* If the user has just clicked on the handle, record where they're
8247 if (event
->type
== ButtonPress
8248 && emacs_event
->part
== scroll_bar_handle
)
8249 XSETINT (bar
->dragging
, y
- XINT (bar
->start
));
8252 /* If the user has released the handle, set it to its final position. */
8253 if (event
->type
== ButtonRelease
8254 && ! NILP (bar
->dragging
))
8256 int new_start
= y
- XINT (bar
->dragging
);
8257 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
8259 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
8260 bar
->dragging
= Qnil
;
8263 /* Same deal here as the other #if 0. */
8265 /* Clicks on the handle are always reported as occurring at the top of
8267 if (emacs_event
->part
== scroll_bar_handle
)
8268 emacs_event
->x
= bar
->start
;
8270 XSETINT (emacs_event
->x
, y
);
8272 XSETINT (emacs_event
->x
, y
);
8275 XSETINT (emacs_event
->y
, top_range
);
8279 /* Handle some mouse motion while someone is dragging the scroll bar.
8281 This may be called from a signal handler, so we have to ignore GC
8285 x_scroll_bar_note_movement (bar
, event
)
8286 struct scroll_bar
*bar
;
8289 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
8291 last_mouse_movement_time
= event
->xmotion
.time
;
8294 XSETVECTOR (last_mouse_scroll_bar
, bar
);
8296 /* If we're dragging the bar, display it. */
8297 if (! GC_NILP (bar
->dragging
))
8299 /* Where should the handle be now? */
8300 int new_start
= event
->xmotion
.y
- XINT (bar
->dragging
);
8302 if (new_start
!= XINT (bar
->start
))
8304 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
8306 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
8311 #endif /* !USE_TOOLKIT_SCROLL_BARS */
8313 /* Return information to the user about the current position of the mouse
8314 on the scroll bar. */
8317 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
8319 Lisp_Object
*bar_window
;
8320 enum scroll_bar_part
*part
;
8322 unsigned long *time
;
8324 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
8325 Window w
= SCROLL_BAR_X_WINDOW (bar
);
8326 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8328 Window dummy_window
;
8330 unsigned int dummy_mask
;
8334 /* Get the mouse's position relative to the scroll bar window, and
8336 if (! XQueryPointer (FRAME_X_DISPLAY (f
), w
,
8338 /* Root, child, root x and root y. */
8339 &dummy_window
, &dummy_window
,
8340 &dummy_coord
, &dummy_coord
,
8342 /* Position relative to scroll bar. */
8345 /* Mouse buttons and modifier keys. */
8352 = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
8355 = VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8357 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
8359 if (! NILP (bar
->dragging
))
8360 win_y
-= XINT (bar
->dragging
);
8364 if (win_y
> top_range
)
8368 *bar_window
= bar
->window
;
8370 if (! NILP (bar
->dragging
))
8371 *part
= scroll_bar_handle
;
8372 else if (win_y
< XINT (bar
->start
))
8373 *part
= scroll_bar_above_handle
;
8374 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
8375 *part
= scroll_bar_handle
;
8377 *part
= scroll_bar_below_handle
;
8379 XSETINT (*x
, win_y
);
8380 XSETINT (*y
, top_range
);
8383 last_mouse_scroll_bar
= Qnil
;
8386 *time
= last_mouse_movement_time
;
8392 /* The screen has been cleared so we may have changed foreground or
8393 background colors, and the scroll bars may need to be redrawn.
8394 Clear out the scroll bars, and ask for expose events, so we can
8398 x_scroll_bar_clear (f
)
8401 #ifndef USE_TOOLKIT_SCROLL_BARS
8404 /* We can have scroll bars even if this is 0,
8405 if we just turned off scroll bar mode.
8406 But in that case we should not clear them. */
8407 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
8408 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
8409 bar
= XSCROLL_BAR (bar
)->next
)
8410 XClearArea (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)),
8412 #endif /* not USE_TOOLKIT_SCROLL_BARS */
8415 /* This processes Expose events from the menu-bar specific X event
8416 loop in xmenu.c. This allows to redisplay the frame if necessary
8417 when handling menu-bar or pop-up items. */
8420 process_expose_from_menu (event
)
8424 struct x_display_info
*dpyinfo
;
8425 int frame_exposed_p
= 0;
8429 dpyinfo
= x_display_info_for_display (event
.xexpose
.display
);
8430 f
= x_window_to_frame (dpyinfo
, event
.xexpose
.window
);
8433 if (f
->async_visible
== 0)
8435 f
->async_visible
= 1;
8436 f
->async_iconified
= 0;
8437 f
->output_data
.x
->has_been_visible
= 1;
8438 SET_FRAME_GARBAGED (f
);
8442 expose_frame (x_window_to_frame (dpyinfo
, event
.xexpose
.window
),
8443 event
.xexpose
.x
, event
.xexpose
.y
,
8444 event
.xexpose
.width
, event
.xexpose
.height
);
8445 frame_exposed_p
= 1;
8450 struct scroll_bar
*bar
8451 = x_window_to_scroll_bar (event
.xexpose
.window
);
8454 x_scroll_bar_expose (bar
, &event
);
8458 return frame_exposed_p
;
8461 /* Define a queue to save up SelectionRequest events for later handling. */
8463 struct selection_event_queue
8466 struct selection_event_queue
*next
;
8469 static struct selection_event_queue
*queue
;
8471 /* Nonzero means queue up certain events--don't process them yet. */
8473 static int x_queue_selection_requests
;
8475 /* Queue up an X event *EVENT, to be processed later. */
8478 x_queue_event (f
, event
)
8482 struct selection_event_queue
*queue_tmp
8483 = (struct selection_event_queue
*) xmalloc (sizeof (struct selection_event_queue
));
8485 if (queue_tmp
!= NULL
)
8487 queue_tmp
->event
= *event
;
8488 queue_tmp
->next
= queue
;
8493 /* Take all the queued events and put them back
8494 so that they get processed afresh. */
8497 x_unqueue_events (display
)
8500 while (queue
!= NULL
)
8502 struct selection_event_queue
*queue_tmp
= queue
;
8503 XPutBackEvent (display
, &queue_tmp
->event
);
8504 queue
= queue_tmp
->next
;
8505 xfree ((char *)queue_tmp
);
8509 /* Start queuing SelectionRequest events. */
8512 x_start_queuing_selection_requests (display
)
8515 x_queue_selection_requests
++;
8518 /* Stop queuing SelectionRequest events. */
8521 x_stop_queuing_selection_requests (display
)
8524 x_queue_selection_requests
--;
8525 x_unqueue_events (display
);
8528 /* The main X event-reading loop - XTread_socket. */
8530 /* Time stamp of enter window event. This is only used by XTread_socket,
8531 but we have to put it out here, since static variables within functions
8532 sometimes don't work. */
8534 static Time enter_timestamp
;
8536 /* This holds the state XLookupString needs to implement dead keys
8537 and other tricks known as "compose processing". _X Window System_
8538 says that a portable program can't use this, but Stephen Gildea assures
8539 me that letting the compiler initialize it to zeros will work okay.
8541 This must be defined outside of XTread_socket, for the same reasons
8542 given for enter_time stamp, above. */
8544 static XComposeStatus compose_status
;
8546 /* Record the last 100 characters stored
8547 to help debug the loss-of-chars-during-GC problem. */
8549 static int temp_index
;
8550 static short temp_buffer
[100];
8552 /* Set this to nonzero to fake an "X I/O error"
8553 on a particular display. */
8555 struct x_display_info
*XTread_socket_fake_io_error
;
8557 /* When we find no input here, we occasionally do a no-op command
8558 to verify that the X server is still running and we can still talk with it.
8559 We try all the open displays, one by one.
8560 This variable is used for cycling thru the displays. */
8562 static struct x_display_info
*next_noop_dpyinfo
;
8564 #define SET_SAVED_MENU_EVENT(size) \
8567 if (f->output_data.x->saved_menu_event == 0) \
8568 f->output_data.x->saved_menu_event \
8569 = (XEvent *) xmalloc (sizeof (XEvent)); \
8570 bcopy (&event, f->output_data.x->saved_menu_event, size); \
8571 if (numchars >= 1) \
8573 bufp->kind = menu_bar_activate_event; \
8574 XSETFRAME (bufp->frame_or_window, f); \
8582 #define SET_SAVED_BUTTON_EVENT SET_SAVED_MENU_EVENT (sizeof (XButtonEvent))
8583 #define SET_SAVED_KEY_EVENT SET_SAVED_MENU_EVENT (sizeof (XKeyEvent))
8585 /* Read events coming from the X server.
8586 This routine is called by the SIGIO handler.
8587 We return as soon as there are no more events to be read.
8589 Events representing keys are stored in buffer BUFP,
8590 which can hold up to NUMCHARS characters.
8591 We return the number of characters stored into the buffer,
8592 thus pretending to be `read'.
8594 EXPECTED is nonzero if the caller knows input is available. */
8597 XTread_socket (sd
, bufp
, numchars
, expected
)
8599 /* register */ struct input_event
*bufp
;
8600 /* register */ int numchars
;
8607 int event_found
= 0;
8608 struct x_display_info
*dpyinfo
;
8610 Status status_return
;
8613 if (interrupt_input_blocked
)
8615 interrupt_input_pending
= 1;
8619 interrupt_input_pending
= 0;
8622 /* So people can tell when we have read the available input. */
8623 input_signal_count
++;
8626 abort (); /* Don't think this happens. */
8628 /* Find the display we are supposed to read input for.
8629 It's the one communicating on descriptor SD. */
8630 for (dpyinfo
= x_display_list
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
8632 #if 0 /* This ought to be unnecessary; let's verify it. */
8634 /* If available, Xlib uses FIOSNBIO to make the socket
8635 non-blocking, and then looks for EWOULDBLOCK. If O_NDELAY is set,
8636 FIOSNBIO is ignored, and instead of signaling EWOULDBLOCK,
8637 a read returns 0, which Xlib interprets as equivalent to EPIPE. */
8638 fcntl (dpyinfo
->connection
, F_SETFL
, 0);
8639 #endif /* ! defined (FIOSNBIO) */
8642 #if 0 /* This code can't be made to work, with multiple displays,
8643 and appears not to be used on any system any more.
8644 Also keyboard.c doesn't turn O_NDELAY on and off
8645 for X connections. */
8648 if (! (fcntl (dpyinfo
->connection
, F_GETFL
, 0) & O_NDELAY
))
8650 extern int read_alarm_should_throw
;
8651 read_alarm_should_throw
= 1;
8652 XPeekEvent (dpyinfo
->display
, &event
);
8653 read_alarm_should_throw
= 0;
8655 #endif /* HAVE_SELECT */
8659 /* For debugging, this gives a way to fake an I/O error. */
8660 if (dpyinfo
== XTread_socket_fake_io_error
)
8662 XTread_socket_fake_io_error
= 0;
8663 x_io_error_quitter (dpyinfo
->display
);
8666 while (XPending (dpyinfo
->display
))
8668 XNextEvent (dpyinfo
->display
, &event
);
8670 if (display_busy_cursor_p
)
8672 /* Setting inhibit_busy_cursor to 2 inhibits busy-cursor
8673 display until the next X event is read and we come
8674 here again. Setting it to 1 inhibits busy-cursor
8675 display for direct commands. */
8676 if (event
.type
== MotionNotify
8677 || event
.type
== EnterNotify
8678 || (dpyinfo
->grabbed
8679 && event
.type
!= ButtonRelease
))
8680 inhibit_busy_cursor
= 2;
8682 inhibit_busy_cursor
= 1;
8687 struct frame
*f1
= x_any_window_to_frame (dpyinfo
,
8688 event
.xclient
.window
);
8689 /* The necessity of the following line took me
8690 a full work-day to decipher from the docs!! */
8691 if (f1
!= 0 && FRAME_XIC (f1
) && XFilterEvent (&event
, None
))
8701 if (event
.xclient
.message_type
8702 == dpyinfo
->Xatom_wm_protocols
8703 && event
.xclient
.format
== 32)
8705 if (event
.xclient
.data
.l
[0]
8706 == dpyinfo
->Xatom_wm_take_focus
)
8708 /* Use x_any_window_to_frame because this
8709 could be the shell widget window
8710 if the frame has no title bar. */
8711 f
= x_any_window_to_frame (dpyinfo
, event
.xclient
.window
);
8713 /* Not quite sure this is needed -pd */
8714 if (f
&& FRAME_XIC (f
))
8715 XSetICFocus (FRAME_XIC (f
));
8717 #if 0 /* Emacs sets WM hints whose `input' field is `true'. This
8718 instructs the WM to set the input focus automatically for
8719 Emacs with a call to XSetInputFocus. Setting WM_TAKE_FOCUS
8720 tells the WM to send us a ClientMessage WM_TAKE_FOCUS after
8721 it has set the focus. So, XSetInputFocus below is not
8724 The call to XSetInputFocus below has also caused trouble. In
8725 cases where the XSetInputFocus done by the WM and the one
8726 below are temporally close (on a fast machine), the call
8727 below can generate additional FocusIn events which confuse
8730 /* Since we set WM_TAKE_FOCUS, we must call
8731 XSetInputFocus explicitly. But not if f is null,
8732 since that might be an event for a deleted frame. */
8735 Display
*d
= event
.xclient
.display
;
8736 /* Catch and ignore errors, in case window has been
8737 iconified by a window manager such as GWM. */
8738 int count
= x_catch_errors (d
);
8739 XSetInputFocus (d
, event
.xclient
.window
,
8740 /* The ICCCM says this is
8741 the only valid choice. */
8743 event
.xclient
.data
.l
[1]);
8744 /* This is needed to detect the error
8745 if there is an error. */
8747 x_uncatch_errors (d
, count
);
8749 /* Not certain about handling scroll bars here */
8752 else if (event
.xclient
.data
.l
[0]
8753 == dpyinfo
->Xatom_wm_save_yourself
)
8755 /* Save state modify the WM_COMMAND property to
8756 something which can reinstate us. This notifies
8757 the session manager, who's looking for such a
8758 PropertyNotify. Can restart processing when
8759 a keyboard or mouse event arrives. */
8762 f
= x_top_window_to_frame (dpyinfo
,
8763 event
.xclient
.window
);
8765 /* This is just so we only give real data once
8766 for a single Emacs process. */
8767 if (f
== SELECTED_FRAME ())
8768 XSetCommand (FRAME_X_DISPLAY (f
),
8769 event
.xclient
.window
,
8770 initial_argv
, initial_argc
);
8772 XSetCommand (FRAME_X_DISPLAY (f
),
8773 event
.xclient
.window
,
8777 else if (event
.xclient
.data
.l
[0]
8778 == dpyinfo
->Xatom_wm_delete_window
)
8781 = x_any_window_to_frame (dpyinfo
,
8782 event
.xclient
.window
);
8789 bufp
->kind
= delete_window_event
;
8790 XSETFRAME (bufp
->frame_or_window
, f
);
8798 else if (event
.xclient
.message_type
8799 == dpyinfo
->Xatom_wm_configure_denied
)
8802 else if (event
.xclient
.message_type
8803 == dpyinfo
->Xatom_wm_window_moved
)
8807 = x_window_to_frame (dpyinfo
, event
.xclient
.window
);
8809 new_x
= event
.xclient
.data
.s
[0];
8810 new_y
= event
.xclient
.data
.s
[1];
8814 f
->output_data
.x
->left_pos
= new_x
;
8815 f
->output_data
.x
->top_pos
= new_y
;
8819 else if (event
.xclient
.message_type
8820 == dpyinfo
->Xatom_editres
)
8823 = x_any_window_to_frame (dpyinfo
, event
.xclient
.window
);
8824 _XEditResCheckMessages (f
->output_data
.x
->widget
, NULL
,
8827 #endif /* HACK_EDITRES */
8828 else if ((event
.xclient
.message_type
8829 == dpyinfo
->Xatom_DONE
)
8830 || (event
.xclient
.message_type
8831 == dpyinfo
->Xatom_PAGE
))
8833 /* Ghostview job completed. Kill it. We could
8834 reply with "Next" if we received "Page", but we
8835 currently never do because we are interested in
8836 images, only, which should have 1 page. */
8837 Pixmap pixmap
= (Pixmap
) event
.xclient
.data
.l
[1];
8839 = x_window_to_frame (dpyinfo
, event
.xclient
.window
);
8840 x_kill_gs_process (pixmap
, f
);
8841 expose_frame (f
, 0, 0, 0, 0);
8843 #ifdef USE_TOOLKIT_SCROLL_BARS
8844 /* Scroll bar callbacks send a ClientMessage from which
8845 we construct an input_event. */
8846 else if (event
.xclient
.message_type
8847 == dpyinfo
->Xatom_Scrollbar
)
8849 x_scroll_bar_to_input_event (&event
, bufp
);
8850 ++bufp
, ++count
, --numchars
;
8853 #endif /* USE_TOOLKIT_SCROLL_BARS */
8859 case SelectionNotify
:
8860 #ifdef USE_X_TOOLKIT
8861 if (! x_window_to_frame (dpyinfo
, event
.xselection
.requestor
))
8863 #endif /* not USE_X_TOOLKIT */
8864 x_handle_selection_notify (&event
.xselection
);
8867 case SelectionClear
: /* Someone has grabbed ownership. */
8868 #ifdef USE_X_TOOLKIT
8869 if (! x_window_to_frame (dpyinfo
, event
.xselectionclear
.window
))
8871 #endif /* USE_X_TOOLKIT */
8873 XSelectionClearEvent
*eventp
= (XSelectionClearEvent
*) &event
;
8878 bufp
->kind
= selection_clear_event
;
8879 SELECTION_EVENT_DISPLAY (bufp
) = eventp
->display
;
8880 SELECTION_EVENT_SELECTION (bufp
) = eventp
->selection
;
8881 SELECTION_EVENT_TIME (bufp
) = eventp
->time
;
8882 bufp
->frame_or_window
= Qnil
;
8890 case SelectionRequest
: /* Someone wants our selection. */
8891 #ifdef USE_X_TOOLKIT
8892 if (!x_window_to_frame (dpyinfo
, event
.xselectionrequest
.owner
))
8894 #endif /* USE_X_TOOLKIT */
8895 if (x_queue_selection_requests
)
8896 x_queue_event (x_window_to_frame (dpyinfo
, event
.xselectionrequest
.owner
),
8900 XSelectionRequestEvent
*eventp
= (XSelectionRequestEvent
*) &event
;
8905 bufp
->kind
= selection_request_event
;
8906 SELECTION_EVENT_DISPLAY (bufp
) = eventp
->display
;
8907 SELECTION_EVENT_REQUESTOR (bufp
) = eventp
->requestor
;
8908 SELECTION_EVENT_SELECTION (bufp
) = eventp
->selection
;
8909 SELECTION_EVENT_TARGET (bufp
) = eventp
->target
;
8910 SELECTION_EVENT_PROPERTY (bufp
) = eventp
->property
;
8911 SELECTION_EVENT_TIME (bufp
) = eventp
->time
;
8912 bufp
->frame_or_window
= Qnil
;
8920 case PropertyNotify
:
8921 #ifdef USE_X_TOOLKIT
8922 if (!x_any_window_to_frame (dpyinfo
, event
.xproperty
.window
))
8924 #endif /* not USE_X_TOOLKIT */
8925 x_handle_property_notify (&event
.xproperty
);
8928 case ReparentNotify
:
8929 f
= x_top_window_to_frame (dpyinfo
, event
.xreparent
.window
);
8933 f
->output_data
.x
->parent_desc
= event
.xreparent
.parent
;
8934 x_real_positions (f
, &x
, &y
);
8935 f
->output_data
.x
->left_pos
= x
;
8936 f
->output_data
.x
->top_pos
= y
;
8941 f
= x_window_to_frame (dpyinfo
, event
.xexpose
.window
);
8944 if (f
->async_visible
== 0)
8946 f
->async_visible
= 1;
8947 f
->async_iconified
= 0;
8948 f
->output_data
.x
->has_been_visible
= 1;
8949 SET_FRAME_GARBAGED (f
);
8952 expose_frame (x_window_to_frame (dpyinfo
,
8953 event
.xexpose
.window
),
8954 event
.xexpose
.x
, event
.xexpose
.y
,
8955 event
.xexpose
.width
, event
.xexpose
.height
);
8959 #ifdef USE_TOOLKIT_SCROLL_BARS
8960 /* Dispatch event to the widget. */
8962 #else /* not USE_TOOLKIT_SCROLL_BARS */
8963 struct scroll_bar
*bar
8964 = x_window_to_scroll_bar (event
.xexpose
.window
);
8967 x_scroll_bar_expose (bar
, &event
);
8968 #ifdef USE_X_TOOLKIT
8971 #endif /* USE_X_TOOLKIT */
8972 #endif /* not USE_TOOLKIT_SCROLL_BARS */
8976 case GraphicsExpose
: /* This occurs when an XCopyArea's
8977 source area was obscured or not
8979 f
= x_window_to_frame (dpyinfo
, event
.xgraphicsexpose
.drawable
);
8983 event
.xgraphicsexpose
.x
, event
.xgraphicsexpose
.y
,
8984 event
.xgraphicsexpose
.width
,
8985 event
.xgraphicsexpose
.height
);
8987 #ifdef USE_X_TOOLKIT
8990 #endif /* USE_X_TOOLKIT */
8993 case NoExpose
: /* This occurs when an XCopyArea's
8994 source area was completely
8999 /* Redo the mouse-highlight after the tooltip has gone. */
9000 if (event
.xmap
.window
== tip_window
)
9003 redo_mouse_highlight ();
9006 f
= x_top_window_to_frame (dpyinfo
, event
.xunmap
.window
);
9007 if (f
) /* F may no longer exist if
9008 the frame was deleted. */
9010 /* While a frame is unmapped, display generation is
9011 disabled; you don't want to spend time updating a
9012 display that won't ever be seen. */
9013 f
->async_visible
= 0;
9014 /* We can't distinguish, from the event, whether the window
9015 has become iconified or invisible. So assume, if it
9016 was previously visible, than now it is iconified.
9017 But x_make_frame_invisible clears both
9018 the visible flag and the iconified flag;
9019 and that way, we know the window is not iconified now. */
9020 if (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
))
9022 f
->async_iconified
= 1;
9024 bufp
->kind
= iconify_event
;
9025 XSETFRAME (bufp
->frame_or_window
, f
);
9034 if (event
.xmap
.window
== tip_window
)
9035 /* The tooltip has been drawn already. Avoid
9036 the SET_FRAME_GARBAGED below. */
9039 /* We use x_top_window_to_frame because map events can
9040 come for sub-windows and they don't mean that the
9041 frame is visible. */
9042 f
= x_top_window_to_frame (dpyinfo
, event
.xmap
.window
);
9045 f
->async_visible
= 1;
9046 f
->async_iconified
= 0;
9047 f
->output_data
.x
->has_been_visible
= 1;
9049 /* wait_reading_process_input will notice this and update
9050 the frame's display structures. */
9051 SET_FRAME_GARBAGED (f
);
9055 bufp
->kind
= deiconify_event
;
9056 XSETFRAME (bufp
->frame_or_window
, f
);
9061 else if (! NILP (Vframe_list
)
9062 && ! NILP (XCDR (Vframe_list
)))
9063 /* Force a redisplay sooner or later
9064 to update the frame titles
9065 in case this is the second frame. */
9066 record_asynch_buffer_change ();
9071 f
= x_any_window_to_frame (dpyinfo
, event
.xkey
.window
);
9074 /* I couldn't find a way to prevent LessTif scroll bars
9075 from consuming key events. */
9078 Widget widget
= XtWindowToWidget (dpyinfo
->display
,
9080 if (widget
&& XmIsScrollBar (widget
))
9082 widget
= XtParent (widget
);
9083 f
= x_any_window_to_frame (dpyinfo
, XtWindow (widget
));
9086 #endif /* USE_MOTIF */
9090 KeySym keysym
, orig_keysym
;
9091 /* al%imercury@uunet.uu.net says that making this 81 instead of
9092 80 fixed a bug whereby meta chars made his Emacs hang. */
9093 unsigned char copy_buffer
[81];
9097 |= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f
),
9098 extra_keyboard_modifiers
);
9099 modifiers
= event
.xkey
.state
;
9101 /* This will have to go some day... */
9103 /* make_lispy_event turns chars into control chars.
9104 Don't do it here because XLookupString is too eager. */
9105 event
.xkey
.state
&= ~ControlMask
;
9106 event
.xkey
.state
&= ~(dpyinfo
->meta_mod_mask
9107 | dpyinfo
->super_mod_mask
9108 | dpyinfo
->hyper_mod_mask
9109 | dpyinfo
->alt_mod_mask
);
9111 /* In case Meta is ComposeCharacter,
9112 clear its status. According to Markus Ehrnsperger
9113 Markus.Ehrnsperger@lehrstuhl-bross.physik.uni-muenchen.de
9114 this enables ComposeCharacter to work whether or
9115 not it is combined with Meta. */
9116 if (modifiers
& dpyinfo
->meta_mod_mask
)
9117 bzero (&compose_status
, sizeof (compose_status
));
9122 /* The necessity of the following line took me
9123 a full work-day to decipher from the docs!! */
9124 if (XFilterEvent (&event
, None
))
9126 nbytes
= XmbLookupString (FRAME_XIC (f
),
9127 &event
.xkey
, copy_buffer
,
9130 if (status_return
== XLookupNone
)
9132 else if (status_return
== XLookupChars
)
9134 else if (status_return
!= XLookupKeySym
9135 && status_return
!= XLookupBoth
)
9139 nbytes
= XLookupString (&event
.xkey
, copy_buffer
,
9140 80, &keysym
, &compose_status
);
9142 nbytes
= XLookupString (&event
.xkey
, copy_buffer
,
9143 80, &keysym
, &compose_status
);
9146 orig_keysym
= keysym
;
9150 if (((keysym
>= XK_BackSpace
&& keysym
<= XK_Escape
)
9151 || keysym
== XK_Delete
9152 #ifdef XK_ISO_Left_Tab
9153 || (keysym
>= XK_ISO_Left_Tab
&& keysym
<= XK_ISO_Enter
)
9155 || (keysym
>= XK_Kanji
&& keysym
<= XK_Eisu_toggle
)
9156 || IsCursorKey (keysym
) /* 0xff50 <= x < 0xff60 */
9157 || IsMiscFunctionKey (keysym
) /* 0xff60 <= x < VARIES */
9159 /* This recognizes the "extended function keys".
9160 It seems there's no cleaner way.
9161 Test IsModifierKey to avoid handling mode_switch
9163 || ((unsigned) (keysym
) >= XK_Select
9164 && (unsigned)(keysym
) < XK_KP_Space
)
9166 #ifdef XK_dead_circumflex
9167 || orig_keysym
== XK_dead_circumflex
9169 #ifdef XK_dead_grave
9170 || orig_keysym
== XK_dead_grave
9172 #ifdef XK_dead_tilde
9173 || orig_keysym
== XK_dead_tilde
9175 #ifdef XK_dead_diaeresis
9176 || orig_keysym
== XK_dead_diaeresis
9178 #ifdef XK_dead_macron
9179 || orig_keysym
== XK_dead_macron
9181 #ifdef XK_dead_degree
9182 || orig_keysym
== XK_dead_degree
9184 #ifdef XK_dead_acute
9185 || orig_keysym
== XK_dead_acute
9187 #ifdef XK_dead_cedilla
9188 || orig_keysym
== XK_dead_cedilla
9190 #ifdef XK_dead_breve
9191 || orig_keysym
== XK_dead_breve
9193 #ifdef XK_dead_ogonek
9194 || orig_keysym
== XK_dead_ogonek
9196 #ifdef XK_dead_caron
9197 || orig_keysym
== XK_dead_caron
9199 #ifdef XK_dead_doubleacute
9200 || orig_keysym
== XK_dead_doubleacute
9202 #ifdef XK_dead_abovedot
9203 || orig_keysym
== XK_dead_abovedot
9205 || IsKeypadKey (keysym
) /* 0xff80 <= x < 0xffbe */
9206 || IsFunctionKey (keysym
) /* 0xffbe <= x < 0xffe1 */
9207 /* Any "vendor-specific" key is ok. */
9208 || (orig_keysym
& (1 << 28)))
9209 && ! (IsModifierKey (orig_keysym
)
9211 #ifdef XK_Mode_switch
9212 || ((unsigned)(orig_keysym
) == XK_Mode_switch
)
9215 || ((unsigned)(orig_keysym
) == XK_Num_Lock
)
9217 #endif /* not HAVE_X11R5 */
9220 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
9222 temp_buffer
[temp_index
++] = keysym
;
9223 bufp
->kind
= non_ascii_keystroke
;
9224 bufp
->code
= keysym
;
9225 XSETFRAME (bufp
->frame_or_window
, f
);
9227 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
9229 bufp
->timestamp
= event
.xkey
.time
;
9234 if (display_busy_cursor_p
)
9235 if (keysym
!= XK_Return
|| minibuf_level
== 0)
9236 inhibit_busy_cursor
= 2;
9238 else if (numchars
> nbytes
)
9242 for (i
= 0; i
< nbytes
; i
++)
9244 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
9246 temp_buffer
[temp_index
++] = copy_buffer
[i
];
9247 bufp
->kind
= ascii_keystroke
;
9248 bufp
->code
= copy_buffer
[i
];
9249 XSETFRAME (bufp
->frame_or_window
, f
);
9251 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
9253 bufp
->timestamp
= event
.xkey
.time
;
9260 if (keysym
== NoSymbol
)
9271 /* Here's a possible interpretation of the whole
9272 FocusIn-EnterNotify FocusOut-LeaveNotify mess. If
9273 you get a FocusIn event, you have to get a FocusOut
9274 event before you relinquish the focus. If you
9275 haven't received a FocusIn event, then a mere
9276 LeaveNotify is enough to free you. */
9280 int from_menu_bar_p
= 0;
9282 f
= x_any_window_to_frame (dpyinfo
, event
.xcrossing
.window
);
9284 #ifdef LESSTIF_VERSION
9285 /* When clicking outside of a menu bar popup to close
9286 it, we get a FocusIn/ EnterNotify sequence of
9287 events. The flag event.xcrossing.focus is not set
9288 in the EnterNotify event of that sequence because
9289 the focus is in the menu bar,
9290 event.xcrossing.window is the frame's X window.
9291 Unconditionally setting the focus frame to null in
9292 this case is not the right thing, because no event
9293 follows that could set the focus frame to the right
9296 This could be a LessTif bug, but I wasn't able to
9297 reproduce the behavior in a simple test program.
9299 (gerd, LessTif 0.88.1). */
9301 if (!event
.xcrossing
.focus
9303 && f
->output_data
.x
->menubar_widget
)
9308 XGetInputFocus (FRAME_X_DISPLAY (f
), &focus
, &revert
);
9309 if (focus
== XtWindow (f
->output_data
.x
->menubar_widget
))
9310 from_menu_bar_p
= 1;
9312 #endif /* LESSTIF_VERSION */
9314 if (event
.xcrossing
.focus
|| from_menu_bar_p
)
9316 /* Avoid nasty pop/raise loops. */
9317 if (f
&& (!(f
->auto_raise
)
9319 || (event
.xcrossing
.time
- enter_timestamp
) > 500))
9321 x_new_focus_frame (dpyinfo
, f
);
9322 enter_timestamp
= event
.xcrossing
.time
;
9325 else if (f
== dpyinfo
->x_focus_frame
)
9326 x_new_focus_frame (dpyinfo
, 0);
9328 /* EnterNotify counts as mouse movement,
9329 so update things that depend on mouse position. */
9330 if (f
&& !f
->output_data
.x
->busy_p
)
9331 note_mouse_movement (f
, &event
.xmotion
);
9336 f
= x_any_window_to_frame (dpyinfo
, event
.xfocus
.window
);
9337 if (event
.xfocus
.detail
!= NotifyPointer
)
9338 dpyinfo
->x_focus_event_frame
= f
;
9340 x_new_focus_frame (dpyinfo
, f
);
9343 if (f
&& FRAME_XIC (f
))
9344 XSetICFocus (FRAME_XIC (f
));
9350 f
= x_top_window_to_frame (dpyinfo
, event
.xcrossing
.window
);
9354 int from_menu_bar_p
= 0;
9356 if (f
== dpyinfo
->mouse_face_mouse_frame
)
9358 /* If we move outside the frame, then we're
9359 certainly no longer on any text in the frame. */
9360 clear_mouse_face (dpyinfo
);
9361 dpyinfo
->mouse_face_mouse_frame
= 0;
9364 /* Generate a nil HELP_EVENT to cancel a help-echo.
9365 Do it only if there's something to cancel.
9366 Otherwise, the startup message is cleared when
9367 the mouse leaves the frame. */
9368 if (any_help_event_p
)
9370 XSETFRAME (frame
, f
);
9371 bufp
->kind
= HELP_EVENT
;
9372 bufp
->frame_or_window
= Fcons (frame
, Qnil
);
9373 ++bufp
, ++count
, --numchars
;
9376 #ifdef LESSTIF_VERSION
9377 /* Please see the comment at the start of the
9378 EnterNotify case. */
9379 if (!event
.xcrossing
.focus
9380 && f
->output_data
.x
->menubar_widget
)
9384 XGetInputFocus (FRAME_X_DISPLAY (f
), &focus
, &revert
);
9385 if (focus
== XtWindow (f
->output_data
.x
->menubar_widget
))
9386 from_menu_bar_p
= 1;
9388 #endif /* LESSTIF_VERSION */
9390 if (event
.xcrossing
.focus
|| from_menu_bar_p
)
9391 x_mouse_leave (dpyinfo
);
9394 if (f
== dpyinfo
->x_focus_event_frame
)
9395 dpyinfo
->x_focus_event_frame
= 0;
9396 if (f
== dpyinfo
->x_focus_frame
)
9397 x_new_focus_frame (dpyinfo
, 0);
9403 f
= x_any_window_to_frame (dpyinfo
, event
.xfocus
.window
);
9404 if (event
.xfocus
.detail
!= NotifyPointer
9405 && f
== dpyinfo
->x_focus_event_frame
)
9406 dpyinfo
->x_focus_event_frame
= 0;
9407 if (f
&& f
== dpyinfo
->x_focus_frame
)
9408 x_new_focus_frame (dpyinfo
, 0);
9411 if (f
&& FRAME_XIC (f
))
9412 XUnsetICFocus (FRAME_XIC (f
));
9419 previous_help_echo
= help_echo
;
9422 if (dpyinfo
->grabbed
&& last_mouse_frame
9423 && FRAME_LIVE_P (last_mouse_frame
))
9424 f
= last_mouse_frame
;
9426 f
= x_window_to_frame (dpyinfo
, event
.xmotion
.window
);
9429 note_mouse_movement (f
, &event
.xmotion
);
9432 #ifndef USE_TOOLKIT_SCROLL_BARS
9433 struct scroll_bar
*bar
9434 = x_window_to_scroll_bar (event
.xmotion
.window
);
9437 x_scroll_bar_note_movement (bar
, &event
);
9438 #endif /* USE_TOOLKIT_SCROLL_BARS */
9440 /* If we move outside the frame, then we're
9441 certainly no longer on any text in the frame. */
9442 clear_mouse_face (dpyinfo
);
9445 /* If the contents of the global variable help_echo
9446 has changed, generate a HELP_EVENT. */
9447 if (STRINGP (help_echo
)
9448 || STRINGP (previous_help_echo
))
9453 XSETFRAME (frame
, f
);
9457 any_help_event_p
= 1;
9458 bufp
->kind
= HELP_EVENT
;
9459 bufp
->frame_or_window
= Fcons (frame
, help_echo
);
9460 ++bufp
, ++count
, --numchars
;
9466 case ConfigureNotify
:
9467 f
= x_top_window_to_frame (dpyinfo
, event
.xconfigure
.window
);
9470 #ifndef USE_X_TOOLKIT
9471 int rows
= PIXEL_TO_CHAR_HEIGHT (f
, event
.xconfigure
.height
);
9472 int columns
= PIXEL_TO_CHAR_WIDTH (f
, event
.xconfigure
.width
);
9474 /* In the toolkit version, change_frame_size
9475 is called by the code that handles resizing
9476 of the EmacsFrame widget. */
9478 /* Even if the number of character rows and columns has
9479 not changed, the font size may have changed, so we need
9480 to check the pixel dimensions as well. */
9481 if (columns
!= f
->width
9482 || rows
!= f
->height
9483 || event
.xconfigure
.width
!= f
->output_data
.x
->pixel_width
9484 || event
.xconfigure
.height
!= f
->output_data
.x
->pixel_height
)
9486 change_frame_size (f
, rows
, columns
, 0, 1, 0);
9487 SET_FRAME_GARBAGED (f
);
9488 cancel_mouse_face (f
);
9492 f
->output_data
.x
->pixel_width
= event
.xconfigure
.width
;
9493 f
->output_data
.x
->pixel_height
= event
.xconfigure
.height
;
9495 /* What we have now is the position of Emacs's own window.
9496 Convert that to the position of the window manager window. */
9497 x_real_positions (f
, &f
->output_data
.x
->left_pos
,
9498 &f
->output_data
.x
->top_pos
);
9500 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
9502 /* Since the WM decorations come below top_pos now,
9503 we must put them below top_pos in the future. */
9504 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
9505 x_wm_set_size_hint (f
, (long) 0, 0);
9508 /* Some window managers pass (0,0) as the location of
9509 the window, and the Motif event handler stores it
9510 in the emacs widget, which messes up Motif menus. */
9511 if (event
.xconfigure
.x
== 0 && event
.xconfigure
.y
== 0)
9513 event
.xconfigure
.x
= f
->output_data
.x
->widget
->core
.x
;
9514 event
.xconfigure
.y
= f
->output_data
.x
->widget
->core
.y
;
9516 #endif /* USE_MOTIF */
9523 /* If we decide we want to generate an event to be seen
9524 by the rest of Emacs, we put it here. */
9525 struct input_event emacs_event
;
9528 emacs_event
.kind
= no_event
;
9529 bzero (&compose_status
, sizeof (compose_status
));
9531 if (dpyinfo
->grabbed
9533 && FRAME_LIVE_P (last_mouse_frame
))
9534 f
= last_mouse_frame
;
9536 f
= x_window_to_frame (dpyinfo
, event
.xbutton
.window
);
9540 /* Is this in the tool-bar? */
9541 if (WINDOWP (f
->tool_bar_window
)
9542 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
9547 x
= event
.xbutton
.x
;
9548 y
= event
.xbutton
.y
;
9551 window
= window_from_coordinates (f
, x
, y
, &p
, 1);
9552 if (EQ (window
, f
->tool_bar_window
))
9554 x_handle_tool_bar_click (f
, &event
.xbutton
);
9560 if (!dpyinfo
->x_focus_frame
9561 || f
== dpyinfo
->x_focus_frame
)
9562 construct_mouse_click (&emacs_event
, &event
, f
);
9566 #ifndef USE_TOOLKIT_SCROLL_BARS
9567 struct scroll_bar
*bar
9568 = x_window_to_scroll_bar (event
.xbutton
.window
);
9571 x_scroll_bar_handle_click (bar
, &event
, &emacs_event
);
9572 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9575 if (event
.type
== ButtonPress
)
9577 dpyinfo
->grabbed
|= (1 << event
.xbutton
.button
);
9578 last_mouse_frame
= f
;
9579 /* Ignore any mouse motion that happened
9580 before this event; any subsequent mouse-movement
9581 Emacs events should reflect only motion after
9587 last_tool_bar_item
= -1;
9588 if (display_busy_cursor_p
)
9589 inhibit_busy_cursor
= 2;
9593 dpyinfo
->grabbed
&= ~(1 << event
.xbutton
.button
);
9596 if (numchars
>= 1 && emacs_event
.kind
!= no_event
)
9598 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
9604 #ifdef USE_X_TOOLKIT
9605 f
= x_menubar_window_to_frame (dpyinfo
, event
.xbutton
.window
);
9606 /* For a down-event in the menu bar,
9607 don't pass it to Xt right now.
9608 Instead, save it away
9609 and we will pass it to Xt from kbd_buffer_get_event.
9610 That way, we can run some Lisp code first. */
9611 if (f
&& event
.type
== ButtonPress
9612 /* Verify the event is really within the menu bar
9613 and not just sent to it due to grabbing. */
9614 && event
.xbutton
.x
>= 0
9615 && event
.xbutton
.x
< f
->output_data
.x
->pixel_width
9616 && event
.xbutton
.y
>= 0
9617 && event
.xbutton
.y
< f
->output_data
.x
->menubar_height
9618 && event
.xbutton
.same_screen
)
9620 SET_SAVED_BUTTON_EVENT
;
9621 XSETFRAME (last_mouse_press_frame
, f
);
9623 else if (event
.type
== ButtonPress
)
9625 last_mouse_press_frame
= Qnil
;
9629 #ifdef USE_MOTIF /* This should do not harm for Lucid,
9630 but I am trying to be cautious. */
9631 else if (event
.type
== ButtonRelease
)
9633 if (!NILP (last_mouse_press_frame
))
9635 f
= XFRAME (last_mouse_press_frame
);
9636 if (f
->output_data
.x
)
9637 SET_SAVED_BUTTON_EVENT
;
9642 #endif /* USE_MOTIF */
9645 #endif /* USE_X_TOOLKIT */
9649 case CirculateNotify
:
9652 case CirculateRequest
:
9655 case VisibilityNotify
:
9659 /* Someone has changed the keyboard mapping - update the
9661 switch (event
.xmapping
.request
)
9663 case MappingModifier
:
9664 x_find_modifier_meanings (dpyinfo
);
9665 /* This is meant to fall through. */
9666 case MappingKeyboard
:
9667 XRefreshKeyboardMapping (&event
.xmapping
);
9673 #ifdef USE_X_TOOLKIT
9675 XtDispatchEvent (&event
);
9677 #endif /* USE_X_TOOLKIT */
9685 /* On some systems, an X bug causes Emacs to get no more events
9686 when the window is destroyed. Detect that. (1994.) */
9689 /* Emacs and the X Server eats up CPU time if XNoOp is done every time.
9690 One XNOOP in 100 loops will make Emacs terminate.
9691 B. Bretthauer, 1994 */
9693 if (x_noop_count
>= 100)
9697 if (next_noop_dpyinfo
== 0)
9698 next_noop_dpyinfo
= x_display_list
;
9700 XNoOp (next_noop_dpyinfo
->display
);
9702 /* Each time we get here, cycle through the displays now open. */
9703 next_noop_dpyinfo
= next_noop_dpyinfo
->next
;
9707 /* If the focus was just given to an auto-raising frame,
9709 /* ??? This ought to be able to handle more than one such frame. */
9710 if (pending_autoraise_frame
)
9712 x_raise_frame (pending_autoraise_frame
);
9713 pending_autoraise_frame
= 0;
9723 /***********************************************************************
9725 ***********************************************************************/
9727 /* Note if the text cursor of window W has been overwritten by a
9728 drawing operation that outputs N glyphs starting at HPOS in the
9729 line given by output_cursor.vpos. N < 0 means all the rest of the
9730 line after HPOS has been written. */
9733 note_overwritten_text_cursor (w
, hpos
, n
)
9737 if (updated_area
== TEXT_AREA
9738 && output_cursor
.vpos
== w
->phys_cursor
.vpos
9739 && hpos
<= w
->phys_cursor
.hpos
9741 || hpos
+ n
> w
->phys_cursor
.hpos
))
9742 w
->phys_cursor_on_p
= 0;
9746 /* Set clipping for output in glyph row ROW. W is the window in which
9747 we operate. GC is the graphics context to set clipping in.
9748 WHOLE_LINE_P non-zero means include the areas used for truncation
9749 mark display and alike in the clipping rectangle.
9751 ROW may be a text row or, e.g., a mode line. Text rows must be
9752 clipped to the interior of the window dedicated to text display,
9753 mode lines must be clipped to the whole window. */
9756 x_clip_to_row (w
, row
, gc
, whole_line_p
)
9758 struct glyph_row
*row
;
9762 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
9763 XRectangle clip_rect
;
9764 int window_x
, window_y
, window_width
, window_height
;
9766 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
9768 clip_rect
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
9769 clip_rect
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
9770 clip_rect
.y
= max (clip_rect
.y
, window_y
);
9771 clip_rect
.width
= window_width
;
9772 clip_rect
.height
= row
->visible_height
;
9774 /* If clipping to the whole line, including trunc marks, extend
9775 the rectangle to the left and increase its width. */
9778 clip_rect
.x
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
9779 clip_rect
.width
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
9782 XSetClipRectangles (FRAME_X_DISPLAY (f
), gc
, 0, 0, &clip_rect
, 1, Unsorted
);
9786 /* Draw a hollow box cursor on window W in glyph row ROW. */
9789 x_draw_hollow_cursor (w
, row
)
9791 struct glyph_row
*row
;
9793 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
9794 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
9795 Display
*dpy
= FRAME_X_DISPLAY (f
);
9798 struct glyph
*cursor_glyph
;
9801 /* Compute frame-relative coordinates from window-relative
9803 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9804 y
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
9805 + row
->ascent
- w
->phys_cursor_ascent
);
9806 h
= row
->height
- 1;
9808 /* Get the glyph the cursor is on. If we can't tell because
9809 the current matrix is invalid or such, give up. */
9810 cursor_glyph
= get_phys_cursor_glyph (w
);
9811 if (cursor_glyph
== NULL
)
9814 /* Compute the width of the rectangle to draw. If on a stretch
9815 glyph, and `x-stretch-block-cursor' is nil, don't draw a
9816 rectangle as wide as the glyph, but use a canonical character
9818 wd
= cursor_glyph
->pixel_width
- 1;
9819 if (cursor_glyph
->type
== STRETCH_GLYPH
9820 && !x_stretch_cursor_p
)
9821 wd
= min (CANON_X_UNIT (f
), wd
);
9823 /* The foreground of cursor_gc is typically the same as the normal
9824 background color, which can cause the cursor box to be invisible. */
9825 xgcv
.foreground
= f
->output_data
.x
->cursor_pixel
;
9826 if (dpyinfo
->scratch_cursor_gc
)
9827 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
9829 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_X_WINDOW (f
),
9830 GCForeground
, &xgcv
);
9831 gc
= dpyinfo
->scratch_cursor_gc
;
9833 /* Set clipping, draw the rectangle, and reset clipping again. */
9834 x_clip_to_row (w
, row
, gc
, 0);
9835 XDrawRectangle (dpy
, FRAME_X_WINDOW (f
), gc
, x
, y
, wd
, h
);
9836 XSetClipMask (dpy
, gc
, None
);
9840 /* Draw a bar cursor on window W in glyph row ROW.
9842 Implementation note: One would like to draw a bar cursor with an
9843 angle equal to the one given by the font property XA_ITALIC_ANGLE.
9844 Unfortunately, I didn't find a font yet that has this property set.
9848 x_draw_bar_cursor (w
, row
)
9850 struct glyph_row
*row
;
9852 /* If cursor hpos is out of bounds, don't draw garbage. This can
9853 happen in mini-buffer windows when switching between echo area
9854 glyphs and mini-buffer. */
9855 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
9857 struct frame
*f
= XFRAME (w
->frame
);
9858 struct glyph
*cursor_glyph
;
9866 cursor_glyph
= get_phys_cursor_glyph (w
);
9867 if (cursor_glyph
== NULL
)
9870 xgcv
.background
= f
->output_data
.x
->cursor_pixel
;
9871 xgcv
.foreground
= f
->output_data
.x
->cursor_pixel
;
9872 xgcv
.graphics_exposures
= 0;
9873 mask
= GCForeground
| GCBackground
| GCGraphicsExposures
;
9874 dpy
= FRAME_X_DISPLAY (f
);
9875 window
= FRAME_X_WINDOW (f
);
9876 gc
= FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
;
9879 XChangeGC (dpy
, gc
, mask
, &xgcv
);
9882 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
9883 FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
9886 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9887 x_clip_to_row (w
, row
, gc
, 0);
9888 XFillRectangle (dpy
, window
, gc
,
9890 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
9891 min (cursor_glyph
->pixel_width
,
9892 f
->output_data
.x
->cursor_width
),
9894 XSetClipMask (dpy
, gc
, None
);
9899 /* Clear the cursor of window W to background color, and mark the
9900 cursor as not shown. This is used when the text where the cursor
9901 is is about to be rewritten. */
9907 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
9908 x_update_window_cursor (w
, 0);
9912 /* Draw the cursor glyph of window W in glyph row ROW. See the
9913 comment of x_draw_glyphs for the meaning of HL. */
9916 x_draw_phys_cursor_glyph (w
, row
, hl
)
9918 struct glyph_row
*row
;
9919 enum draw_glyphs_face hl
;
9921 /* If cursor hpos is out of bounds, don't draw garbage. This can
9922 happen in mini-buffer windows when switching between echo area
9923 glyphs and mini-buffer. */
9924 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
9926 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
9927 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
9930 /* When we erase the cursor, and ROW is overlapped by other
9931 rows, make sure that these overlapping parts of other rows
9933 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
9935 if (row
> w
->current_matrix
->rows
9936 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
9937 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
9939 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
9940 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
9941 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
9947 /* Erase the image of a cursor of window W from the screen. */
9950 x_erase_phys_cursor (w
)
9953 struct frame
*f
= XFRAME (w
->frame
);
9954 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
9955 int hpos
= w
->phys_cursor
.hpos
;
9956 int vpos
= w
->phys_cursor
.vpos
;
9957 int mouse_face_here_p
= 0;
9958 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
9959 struct glyph_row
*cursor_row
;
9960 struct glyph
*cursor_glyph
;
9961 enum draw_glyphs_face hl
;
9963 /* No cursor displayed or row invalidated => nothing to do on the
9965 if (w
->phys_cursor_type
== NO_CURSOR
)
9966 goto mark_cursor_off
;
9968 /* VPOS >= active_glyphs->nrows means that window has been resized.
9969 Don't bother to erase the cursor. */
9970 if (vpos
>= active_glyphs
->nrows
)
9971 goto mark_cursor_off
;
9973 /* If row containing cursor is marked invalid, there is nothing we
9975 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
9976 if (!cursor_row
->enabled_p
)
9977 goto mark_cursor_off
;
9979 /* This can happen when the new row is shorter than the old one.
9980 In this case, either x_draw_glyphs or clear_end_of_line
9981 should have cleared the cursor. Note that we wouldn't be
9982 able to erase the cursor in this case because we don't have a
9983 cursor glyph at hand. */
9984 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
9985 goto mark_cursor_off
;
9987 /* If the cursor is in the mouse face area, redisplay that when
9988 we clear the cursor. */
9989 if (w
== XWINDOW (dpyinfo
->mouse_face_window
)
9990 && (vpos
> dpyinfo
->mouse_face_beg_row
9991 || (vpos
== dpyinfo
->mouse_face_beg_row
9992 && hpos
>= dpyinfo
->mouse_face_beg_col
))
9993 && (vpos
< dpyinfo
->mouse_face_end_row
9994 || (vpos
== dpyinfo
->mouse_face_end_row
9995 && hpos
< dpyinfo
->mouse_face_end_col
))
9996 /* Don't redraw the cursor's spot in mouse face if it is at the
9997 end of a line (on a newline). The cursor appears there, but
9998 mouse highlighting does not. */
9999 && cursor_row
->used
[TEXT_AREA
] > hpos
)
10000 mouse_face_here_p
= 1;
10002 /* Maybe clear the display under the cursor. */
10003 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
10006 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
10008 cursor_glyph
= get_phys_cursor_glyph (w
);
10009 if (cursor_glyph
== NULL
)
10010 goto mark_cursor_off
;
10012 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
10014 XClearArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
10016 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
10018 cursor_glyph
->pixel_width
,
10019 cursor_row
->visible_height
,
10023 /* Erase the cursor by redrawing the character underneath it. */
10024 if (mouse_face_here_p
)
10025 hl
= DRAW_MOUSE_FACE
;
10026 else if (cursor_row
->inverse_p
)
10027 hl
= DRAW_INVERSE_VIDEO
;
10029 hl
= DRAW_NORMAL_TEXT
;
10030 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
10033 w
->phys_cursor_on_p
= 0;
10034 w
->phys_cursor_type
= NO_CURSOR
;
10038 /* Display or clear cursor of window W. If ON is zero, clear the
10039 cursor. If it is non-zero, display the cursor. If ON is nonzero,
10040 where to put the cursor is specified by HPOS, VPOS, X and Y. */
10043 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
10045 int on
, hpos
, vpos
, x
, y
;
10047 struct frame
*f
= XFRAME (w
->frame
);
10048 int new_cursor_type
;
10049 struct glyph_matrix
*current_glyphs
;
10050 struct glyph_row
*glyph_row
;
10051 struct glyph
*glyph
;
10053 /* This is pointless on invisible frames, and dangerous on garbaged
10054 windows and frames; in the latter case, the frame or window may
10055 be in the midst of changing its size, and x and y may be off the
10057 if (! FRAME_VISIBLE_P (f
)
10058 || FRAME_GARBAGED_P (f
)
10059 || vpos
>= w
->current_matrix
->nrows
10060 || hpos
>= w
->current_matrix
->matrix_w
)
10063 /* If cursor is off and we want it off, return quickly. */
10064 if (!on
&& !w
->phys_cursor_on_p
)
10067 current_glyphs
= w
->current_matrix
;
10068 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
10069 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
10071 /* If cursor row is not enabled, we don't really know where to
10072 display the cursor. */
10073 if (!glyph_row
->enabled_p
)
10075 w
->phys_cursor_on_p
= 0;
10079 xassert (interrupt_input_blocked
);
10081 /* Set new_cursor_type to the cursor we want to be displayed. In a
10082 mini-buffer window, we want the cursor only to appear if we are
10083 reading input from this window. For the selected window, we want
10084 the cursor type given by the frame parameter. If explicitly
10085 marked off, draw no cursor. In all other cases, we want a hollow
10087 if (cursor_in_echo_area
10088 && FRAME_HAS_MINIBUF_P (f
)
10089 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
10091 if (w
== XWINDOW (echo_area_window
))
10092 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
10094 new_cursor_type
= HOLLOW_BOX_CURSOR
;
10098 if (w
!= XWINDOW (selected_window
)
10099 || f
!= FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
)
10101 if (MINI_WINDOW_P (w
))
10102 new_cursor_type
= NO_CURSOR
;
10104 new_cursor_type
= HOLLOW_BOX_CURSOR
;
10106 else if (w
->cursor_off_p
)
10107 new_cursor_type
= NO_CURSOR
;
10109 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
10112 /* If cursor is currently being shown and we don't want it to be or
10113 it is in the wrong place, or the cursor type is not what we want,
10115 if (w
->phys_cursor_on_p
10117 || w
->phys_cursor
.x
!= x
10118 || w
->phys_cursor
.y
!= y
10119 || new_cursor_type
!= w
->phys_cursor_type
))
10120 x_erase_phys_cursor (w
);
10122 /* If the cursor is now invisible and we want it to be visible,
10124 if (on
&& !w
->phys_cursor_on_p
)
10126 w
->phys_cursor_ascent
= glyph_row
->ascent
;
10127 w
->phys_cursor_height
= glyph_row
->height
;
10129 /* Set phys_cursor_.* before x_draw_.* is called because some
10130 of them may need the information. */
10131 w
->phys_cursor
.x
= x
;
10132 w
->phys_cursor
.y
= glyph_row
->y
;
10133 w
->phys_cursor
.hpos
= hpos
;
10134 w
->phys_cursor
.vpos
= vpos
;
10135 w
->phys_cursor_type
= new_cursor_type
;
10136 w
->phys_cursor_on_p
= 1;
10138 switch (new_cursor_type
)
10140 case HOLLOW_BOX_CURSOR
:
10141 x_draw_hollow_cursor (w
, glyph_row
);
10144 case FILLED_BOX_CURSOR
:
10145 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
10149 x_draw_bar_cursor (w
, glyph_row
);
10161 if (updating_frame
!= f
)
10162 XFlush (FRAME_X_DISPLAY (f
));
10167 /* Display the cursor on window W, or clear it. X and Y are window
10168 relative pixel coordinates. HPOS and VPOS are glyph matrix
10169 positions. If W is not the selected window, display a hollow
10170 cursor. ON non-zero means display the cursor at X, Y which
10171 correspond to HPOS, VPOS, otherwise it is cleared. */
10174 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
10176 int on
, hpos
, vpos
, x
, y
;
10179 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
10184 /* Display the cursor on window W, or clear it, according to ON_P.
10185 Don't change the cursor's position. */
10188 x_update_cursor (f
, on_p
)
10191 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
10195 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
10196 in the window tree rooted at W. */
10199 x_update_cursor_in_window_tree (w
, on_p
)
10205 if (!NILP (w
->hchild
))
10206 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
10207 else if (!NILP (w
->vchild
))
10208 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
10210 x_update_window_cursor (w
, on_p
);
10212 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
10217 /* Switch the display of W's cursor on or off, according to the value
10221 x_update_window_cursor (w
, on
)
10226 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
10227 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
10236 /* Refresh bitmap kitchen sink icon for frame F
10237 when we get an expose event for it. */
10243 /* Normally, the window manager handles this function. */
10246 /* Make the x-window of frame F use the gnu icon bitmap. */
10249 x_bitmap_icon (f
, file
)
10255 if (FRAME_X_WINDOW (f
) == 0)
10258 /* Free up our existing icon bitmap if any. */
10259 if (f
->output_data
.x
->icon_bitmap
> 0)
10260 x_destroy_bitmap (f
, f
->output_data
.x
->icon_bitmap
);
10261 f
->output_data
.x
->icon_bitmap
= 0;
10263 if (STRINGP (file
))
10264 bitmap_id
= x_create_bitmap_from_file (f
, file
);
10267 /* Create the GNU bitmap if necessary. */
10268 if (FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
< 0)
10269 FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
10270 = x_create_bitmap_from_data (f
, gnu_bits
,
10271 gnu_width
, gnu_height
);
10273 /* The first time we create the GNU bitmap,
10274 this increments the ref-count one extra time.
10275 As a result, the GNU bitmap is never freed.
10276 That way, we don't have to worry about allocating it again. */
10277 x_reference_bitmap (f
, FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
);
10279 bitmap_id
= FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
;
10282 x_wm_set_icon_pixmap (f
, bitmap_id
);
10283 f
->output_data
.x
->icon_bitmap
= bitmap_id
;
10289 /* Make the x-window of frame F use a rectangle with text.
10290 Use ICON_NAME as the text. */
10293 x_text_icon (f
, icon_name
)
10297 if (FRAME_X_WINDOW (f
) == 0)
10302 XTextProperty text
;
10303 text
.value
= (unsigned char *) icon_name
;
10304 text
.encoding
= XA_STRING
;
10306 text
.nitems
= strlen (icon_name
);
10307 #ifdef USE_X_TOOLKIT
10308 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
10310 #else /* not USE_X_TOOLKIT */
10311 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
10312 #endif /* not USE_X_TOOLKIT */
10314 #else /* not HAVE_X11R4 */
10315 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), icon_name
);
10316 #endif /* not HAVE_X11R4 */
10318 if (f
->output_data
.x
->icon_bitmap
> 0)
10319 x_destroy_bitmap (f
, f
->output_data
.x
->icon_bitmap
);
10320 f
->output_data
.x
->icon_bitmap
= 0;
10321 x_wm_set_icon_pixmap (f
, 0);
10326 #define X_ERROR_MESSAGE_SIZE 200
10328 /* If non-nil, this should be a string.
10329 It means catch X errors and store the error message in this string. */
10331 static Lisp_Object x_error_message_string
;
10333 /* An X error handler which stores the error message in
10334 x_error_message_string. This is called from x_error_handler if
10335 x_catch_errors is in effect. */
10338 x_error_catcher (display
, error
)
10340 XErrorEvent
*error
;
10342 XGetErrorText (display
, error
->error_code
,
10343 XSTRING (x_error_message_string
)->data
,
10344 X_ERROR_MESSAGE_SIZE
);
10347 /* Begin trapping X errors for display DPY. Actually we trap X errors
10348 for all displays, but DPY should be the display you are actually
10351 After calling this function, X protocol errors no longer cause
10352 Emacs to exit; instead, they are recorded in the string
10353 stored in x_error_message_string.
10355 Calling x_check_errors signals an Emacs error if an X error has
10356 occurred since the last call to x_catch_errors or x_check_errors.
10358 Calling x_uncatch_errors resumes the normal error handling. */
10360 void x_check_errors ();
10361 static Lisp_Object
x_catch_errors_unwind ();
10364 x_catch_errors (dpy
)
10367 int count
= specpdl_ptr
- specpdl
;
10369 /* Make sure any errors from previous requests have been dealt with. */
10370 XSync (dpy
, False
);
10372 record_unwind_protect (x_catch_errors_unwind
, x_error_message_string
);
10374 x_error_message_string
= make_uninit_string (X_ERROR_MESSAGE_SIZE
);
10375 XSTRING (x_error_message_string
)->data
[0] = 0;
10380 /* Unbind the binding that we made to check for X errors. */
10383 x_catch_errors_unwind (old_val
)
10384 Lisp_Object old_val
;
10386 x_error_message_string
= old_val
;
10390 /* If any X protocol errors have arrived since the last call to
10391 x_catch_errors or x_check_errors, signal an Emacs error using
10392 sprintf (a buffer, FORMAT, the x error message text) as the text. */
10395 x_check_errors (dpy
, format
)
10399 /* Make sure to catch any errors incurred so far. */
10400 XSync (dpy
, False
);
10402 if (XSTRING (x_error_message_string
)->data
[0])
10403 error (format
, XSTRING (x_error_message_string
)->data
);
10406 /* Nonzero if we had any X protocol errors
10407 since we did x_catch_errors on DPY. */
10410 x_had_errors_p (dpy
)
10413 /* Make sure to catch any errors incurred so far. */
10414 XSync (dpy
, False
);
10416 return XSTRING (x_error_message_string
)->data
[0] != 0;
10419 /* Forget about any errors we have had, since we did x_catch_errors on DPY. */
10422 x_clear_errors (dpy
)
10425 XSTRING (x_error_message_string
)->data
[0] = 0;
10428 /* Stop catching X protocol errors and let them make Emacs die.
10429 DPY should be the display that was passed to x_catch_errors.
10430 COUNT should be the value that was returned by
10431 the corresponding call to x_catch_errors. */
10434 x_uncatch_errors (dpy
, count
)
10438 unbind_to (count
, Qnil
);
10442 static unsigned int x_wire_count
;
10445 fprintf (stderr
, "Lib call: %d\n", ++x_wire_count
);
10450 /* Handle SIGPIPE, which can happen when the connection to a server
10451 simply goes away. SIGPIPE is handled by x_connection_signal.
10452 Don't need to do anything, because the write which caused the
10453 SIGPIPE will fail, causing Xlib to invoke the X IO error handler,
10454 which will do the appropriate cleanup for us. */
10457 x_connection_signal (signalnum
) /* If we don't have an argument, */
10458 int signalnum
; /* some compilers complain in signal calls. */
10461 /* USG systems forget handlers when they are used;
10462 must reestablish each time */
10463 signal (signalnum
, x_connection_signal
);
10467 /* Handling X errors. */
10469 /* Handle the loss of connection to display DISPLAY. */
10472 x_connection_closed (display
, error_message
)
10474 char *error_message
;
10476 struct x_display_info
*dpyinfo
= x_display_info_for_display (display
);
10477 Lisp_Object frame
, tail
;
10479 /* Indicate that this display is dead. */
10481 #ifdef USE_X_TOOLKIT
10482 XtCloseDisplay (display
);
10485 dpyinfo
->display
= 0;
10487 /* First delete frames whose mini-buffers are on frames
10488 that are on the dead display. */
10489 FOR_EACH_FRAME (tail
, frame
)
10491 Lisp_Object minibuf_frame
;
10493 = WINDOW_FRAME (XWINDOW (FRAME_MINIBUF_WINDOW (XFRAME (frame
))));
10494 if (FRAME_X_P (XFRAME (frame
))
10495 && FRAME_X_P (XFRAME (minibuf_frame
))
10496 && ! EQ (frame
, minibuf_frame
)
10497 && FRAME_X_DISPLAY_INFO (XFRAME (minibuf_frame
)) == dpyinfo
)
10498 Fdelete_frame (frame
, Qt
);
10501 /* Now delete all remaining frames on the dead display.
10502 We are now sure none of these is used as the mini-buffer
10503 for another frame that we need to delete. */
10504 FOR_EACH_FRAME (tail
, frame
)
10505 if (FRAME_X_P (XFRAME (frame
))
10506 && FRAME_X_DISPLAY_INFO (XFRAME (frame
)) == dpyinfo
)
10508 /* Set this to t so that Fdelete_frame won't get confused
10509 trying to find a replacement. */
10510 FRAME_KBOARD (XFRAME (frame
))->Vdefault_minibuffer_frame
= Qt
;
10511 Fdelete_frame (frame
, Qt
);
10515 x_delete_display (dpyinfo
);
10517 if (x_display_list
== 0)
10519 fprintf (stderr
, "%s\n", error_message
);
10520 shut_down_emacs (0, 0, Qnil
);
10524 /* Ordinary stack unwind doesn't deal with these. */
10526 sigunblock (sigmask (SIGIO
));
10528 sigunblock (sigmask (SIGALRM
));
10529 TOTALLY_UNBLOCK_INPUT
;
10531 clear_waiting_for_input ();
10532 error ("%s", error_message
);
10535 /* This is the usual handler for X protocol errors.
10536 It kills all frames on the display that we got the error for.
10537 If that was the only one, it prints an error message and kills Emacs. */
10540 x_error_quitter (display
, error
)
10542 XErrorEvent
*error
;
10544 char buf
[256], buf1
[356];
10546 /* Note that there is no real way portable across R3/R4 to get the
10547 original error handler. */
10549 XGetErrorText (display
, error
->error_code
, buf
, sizeof (buf
));
10550 sprintf (buf1
, "X protocol error: %s on protocol request %d",
10551 buf
, error
->request_code
);
10552 x_connection_closed (display
, buf1
);
10555 /* This is the first-level handler for X protocol errors.
10556 It calls x_error_quitter or x_error_catcher. */
10559 x_error_handler (display
, error
)
10561 XErrorEvent
*error
;
10563 if (! NILP (x_error_message_string
))
10564 x_error_catcher (display
, error
);
10566 x_error_quitter (display
, error
);
10570 /* This is the handler for X IO errors, always.
10571 It kills all frames on the display that we lost touch with.
10572 If that was the only one, it prints an error message and kills Emacs. */
10575 x_io_error_quitter (display
)
10580 sprintf (buf
, "Connection lost to X server `%s'", DisplayString (display
));
10581 x_connection_closed (display
, buf
);
10585 /* Changing the font of the frame. */
10587 /* Give frame F the font named FONTNAME as its default font, and
10588 return the full name of that font. FONTNAME may be a wildcard
10589 pattern; in that case, we choose some font that fits the pattern.
10590 The return value shows which font we chose. */
10593 x_new_font (f
, fontname
)
10595 register char *fontname
;
10597 struct font_info
*fontp
10598 = fs_load_font (f
, FRAME_X_FONT_TABLE (f
), CHARSET_ASCII
, fontname
, -1);
10603 f
->output_data
.x
->font
= (XFontStruct
*) (fontp
->font
);
10604 f
->output_data
.x
->font_baseline
10605 = (f
->output_data
.x
->font
->ascent
+ fontp
->baseline_offset
);
10606 f
->output_data
.x
->fontset
= -1;
10608 /* Compute the scroll bar width in character columns. */
10609 if (f
->scroll_bar_pixel_width
> 0)
10611 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
10612 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
10616 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
10617 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
10620 /* Now make the frame display the given font. */
10621 if (FRAME_X_WINDOW (f
) != 0)
10623 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->normal_gc
,
10624 f
->output_data
.x
->font
->fid
);
10625 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->reverse_gc
,
10626 f
->output_data
.x
->font
->fid
);
10627 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
10628 f
->output_data
.x
->font
->fid
);
10630 frame_update_line_height (f
);
10631 x_set_window_size (f
, 0, f
->width
, f
->height
);
10634 /* If we are setting a new frame's font for the first time,
10635 there are no faces yet, so this font's height is the line height. */
10636 f
->output_data
.x
->line_height
= FONT_HEIGHT (f
->output_data
.x
->font
);
10638 return build_string (fontp
->full_name
);
10641 /* Give frame F the fontset named FONTSETNAME as its default font, and
10642 return the full name of that fontset. FONTSETNAME may be a wildcard
10643 pattern; in that case, we choose some fontset that fits the pattern.
10644 The return value shows which fontset we chose. */
10647 x_new_fontset (f
, fontsetname
)
10651 int fontset
= fs_query_fontset (f
, fontsetname
);
10652 struct fontset_info
*fontsetp
;
10653 Lisp_Object result
;
10658 if (f
->output_data
.x
->fontset
== fontset
)
10659 /* This fontset is already set in frame F. There's nothing more
10661 return build_string (fontsetname
);
10663 fontsetp
= FRAME_FONTSET_DATA (f
)->fontset_table
[fontset
];
10665 if (!fontsetp
->fontname
[CHARSET_ASCII
])
10666 /* This fontset doesn't contain ASCII font. */
10669 result
= x_new_font (f
, fontsetp
->fontname
[CHARSET_ASCII
]);
10671 if (!STRINGP (result
))
10672 /* Can't load ASCII font. */
10675 /* Since x_new_font doesn't update any fontset information, do it now. */
10676 f
->output_data
.x
->fontset
= fontset
;
10677 FS_LOAD_FONT (f
, FRAME_X_FONT_TABLE (f
),
10678 CHARSET_ASCII
, fontsetp
->fontname
[CHARSET_ASCII
], fontset
);
10680 return build_string (fontsetname
);
10683 /* Calculate the absolute position in frame F
10684 from its current recorded position values and gravity. */
10687 x_calc_absolute_position (f
)
10691 int win_x
= 0, win_y
= 0;
10692 int flags
= f
->output_data
.x
->size_hint_flags
;
10695 /* We have nothing to do if the current position
10696 is already for the top-left corner. */
10697 if (! ((flags
& XNegative
) || (flags
& YNegative
)))
10700 #ifdef USE_X_TOOLKIT
10701 this_window
= XtWindow (f
->output_data
.x
->widget
);
10703 this_window
= FRAME_X_WINDOW (f
);
10706 /* Find the position of the outside upper-left corner of
10707 the inner window, with respect to the outer window.
10708 But do this only if we will need the results. */
10709 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
10714 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
10717 x_clear_errors (FRAME_X_DISPLAY (f
));
10718 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
10720 /* From-window, to-window. */
10722 f
->output_data
.x
->parent_desc
,
10724 /* From-position, to-position. */
10725 0, 0, &win_x
, &win_y
,
10727 /* Child of win. */
10729 if (x_had_errors_p (FRAME_X_DISPLAY (f
)))
10731 Window newroot
, newparent
= 0xdeadbeef;
10732 Window
*newchildren
;
10735 if (! XQueryTree (FRAME_X_DISPLAY (f
), this_window
, &newroot
,
10736 &newparent
, &newchildren
, &nchildren
))
10739 XFree ((char *) newchildren
);
10741 f
->output_data
.x
->parent_desc
= newparent
;
10747 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
10751 /* Treat negative positions as relative to the leftmost bottommost
10752 position that fits on the screen. */
10753 if (flags
& XNegative
)
10754 f
->output_data
.x
->left_pos
= (FRAME_X_DISPLAY_INFO (f
)->width
10755 - 2 * f
->output_data
.x
->border_width
- win_x
10757 + f
->output_data
.x
->left_pos
);
10759 if (flags
& YNegative
)
10761 int menubar_height
= 0;
10763 #ifdef USE_X_TOOLKIT
10764 if (f
->output_data
.x
->menubar_widget
)
10766 = (f
->output_data
.x
->menubar_widget
->core
.height
10767 + f
->output_data
.x
->menubar_widget
->core
.border_width
);
10770 f
->output_data
.x
->top_pos
= (FRAME_X_DISPLAY_INFO (f
)->height
10771 - 2 * f
->output_data
.x
->border_width
10775 + f
->output_data
.x
->top_pos
);
10778 /* The left_pos and top_pos
10779 are now relative to the top and left screen edges,
10780 so the flags should correspond. */
10781 f
->output_data
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
10784 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
10785 to really change the position, and 0 when calling from
10786 x_make_frame_visible (in that case, XOFF and YOFF are the current
10787 position values). It is -1 when calling from x_set_frame_parameters,
10788 which means, do adjust for borders but don't change the gravity. */
10791 x_set_offset (f
, xoff
, yoff
, change_gravity
)
10793 register int xoff
, yoff
;
10794 int change_gravity
;
10796 int modified_top
, modified_left
;
10798 if (change_gravity
> 0)
10800 f
->output_data
.x
->top_pos
= yoff
;
10801 f
->output_data
.x
->left_pos
= xoff
;
10802 f
->output_data
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
10804 f
->output_data
.x
->size_hint_flags
|= XNegative
;
10806 f
->output_data
.x
->size_hint_flags
|= YNegative
;
10807 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
10809 x_calc_absolute_position (f
);
10812 x_wm_set_size_hint (f
, (long) 0, 0);
10814 modified_left
= f
->output_data
.x
->left_pos
;
10815 modified_top
= f
->output_data
.x
->top_pos
;
10816 #if 0 /* Running on psilocin (Debian), and displaying on the NCD X-terminal,
10817 this seems to be unnecessary and incorrect. rms, 4/17/97. */
10818 /* It is a mystery why we need to add the border_width here
10819 when the frame is already visible, but experiment says we do. */
10820 if (change_gravity
!= 0)
10822 modified_left
+= f
->output_data
.x
->border_width
;
10823 modified_top
+= f
->output_data
.x
->border_width
;
10827 #ifdef USE_X_TOOLKIT
10828 XMoveWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
10829 modified_left
, modified_top
);
10830 #else /* not USE_X_TOOLKIT */
10831 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
10832 modified_left
, modified_top
);
10833 #endif /* not USE_X_TOOLKIT */
10837 /* Call this to change the size of frame F's x-window.
10838 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
10839 for this size change and subsequent size changes.
10840 Otherwise we leave the window gravity unchanged. */
10843 x_set_window_size (f
, change_gravity
, cols
, rows
)
10845 int change_gravity
;
10848 #ifndef USE_X_TOOLKIT
10849 int pixelwidth
, pixelheight
;
10854 #ifdef USE_X_TOOLKIT
10856 /* The x and y position of the widget is clobbered by the
10857 call to XtSetValues within EmacsFrameSetCharSize.
10858 This is a real kludge, but I don't understand Xt so I can't
10859 figure out a correct fix. Can anyone else tell me? -- rms. */
10860 int xpos
= f
->output_data
.x
->widget
->core
.x
;
10861 int ypos
= f
->output_data
.x
->widget
->core
.y
;
10862 EmacsFrameSetCharSize (f
->output_data
.x
->edit_widget
, cols
, rows
);
10863 f
->output_data
.x
->widget
->core
.x
= xpos
;
10864 f
->output_data
.x
->widget
->core
.y
= ypos
;
10867 #else /* not USE_X_TOOLKIT */
10869 check_frame_size (f
, &rows
, &cols
);
10870 f
->output_data
.x
->vertical_scroll_bar_extra
10871 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
10873 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
10874 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
10875 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.x
->font
)));
10876 f
->output_data
.x
->flags_areas_extra
10877 = FRAME_FLAGS_AREA_WIDTH (f
);
10878 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
10879 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
10881 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
10882 x_wm_set_size_hint (f
, (long) 0, 0);
10884 XSync (FRAME_X_DISPLAY (f
), False
);
10885 XResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
10886 pixelwidth
, pixelheight
);
10888 /* Now, strictly speaking, we can't be sure that this is accurate,
10889 but the window manager will get around to dealing with the size
10890 change request eventually, and we'll hear how it went when the
10891 ConfigureNotify event gets here.
10893 We could just not bother storing any of this information here,
10894 and let the ConfigureNotify event set everything up, but that
10895 might be kind of confusing to the Lisp code, since size changes
10896 wouldn't be reported in the frame parameters until some random
10897 point in the future when the ConfigureNotify event arrives.
10899 We pass 1 for DELAY since we can't run Lisp code inside of
10901 change_frame_size (f
, rows
, cols
, 0, 1, 0);
10902 PIXEL_WIDTH (f
) = pixelwidth
;
10903 PIXEL_HEIGHT (f
) = pixelheight
;
10905 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
10906 receive in the ConfigureNotify event; if we get what we asked
10907 for, then the event won't cause the screen to become garbaged, so
10908 we have to make sure to do it here. */
10909 SET_FRAME_GARBAGED (f
);
10911 XFlush (FRAME_X_DISPLAY (f
));
10913 #endif /* not USE_X_TOOLKIT */
10915 /* If cursor was outside the new size, mark it as off. */
10916 mark_window_cursors_off (XWINDOW (f
->root_window
));
10918 /* Clear out any recollection of where the mouse highlighting was,
10919 since it might be in a place that's outside the new frame size.
10920 Actually checking whether it is outside is a pain in the neck,
10921 so don't try--just let the highlighting be done afresh with new size. */
10922 cancel_mouse_face (f
);
10927 /* Mouse warping. */
10930 x_set_mouse_position (f
, x
, y
)
10936 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.x
->font
) / 2;
10937 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.x
->line_height
/ 2;
10939 if (pix_x
< 0) pix_x
= 0;
10940 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
10942 if (pix_y
< 0) pix_y
= 0;
10943 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
10947 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
10948 0, 0, 0, 0, pix_x
, pix_y
);
10952 /* Move the mouse to position pixel PIX_X, PIX_Y relative to frame F. */
10955 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
10961 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
10962 0, 0, 0, 0, pix_x
, pix_y
);
10966 /* focus shifting, raising and lowering. */
10969 x_focus_on_frame (f
)
10972 #if 0 /* This proves to be unpleasant. */
10976 /* I don't think that the ICCCM allows programs to do things like this
10977 without the interaction of the window manager. Whatever you end up
10978 doing with this code, do it to x_unfocus_frame too. */
10979 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
10980 RevertToPointerRoot
, CurrentTime
);
10985 x_unfocus_frame (f
)
10989 /* Look at the remarks in x_focus_on_frame. */
10990 if (FRAME_X_DISPLAY_INFO (f
)->x_focus_frame
== f
)
10991 XSetInputFocus (FRAME_X_DISPLAY (f
), PointerRoot
,
10992 RevertToPointerRoot
, CurrentTime
);
10996 /* Raise frame F. */
11002 if (f
->async_visible
)
11005 #ifdef USE_X_TOOLKIT
11006 XRaiseWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
));
11007 #else /* not USE_X_TOOLKIT */
11008 XRaiseWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
11009 #endif /* not USE_X_TOOLKIT */
11010 XFlush (FRAME_X_DISPLAY (f
));
11015 /* Lower frame F. */
11021 if (f
->async_visible
)
11024 #ifdef USE_X_TOOLKIT
11025 XLowerWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
));
11026 #else /* not USE_X_TOOLKIT */
11027 XLowerWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
11028 #endif /* not USE_X_TOOLKIT */
11029 XFlush (FRAME_X_DISPLAY (f
));
11035 XTframe_raise_lower (f
, raise_flag
)
11045 /* Change of visibility. */
11047 /* This tries to wait until the frame is really visible.
11048 However, if the window manager asks the user where to position
11049 the frame, this will return before the user finishes doing that.
11050 The frame will not actually be visible at that time,
11051 but it will become visible later when the window manager
11052 finishes with it. */
11055 x_make_frame_visible (f
)
11059 int original_top
, original_left
;
11063 type
= x_icon_type (f
);
11065 x_bitmap_icon (f
, type
);
11067 if (! FRAME_VISIBLE_P (f
))
11069 /* We test FRAME_GARBAGED_P here to make sure we don't
11070 call x_set_offset a second time
11071 if we get to x_make_frame_visible a second time
11072 before the window gets really visible. */
11073 if (! FRAME_ICONIFIED_P (f
)
11074 && ! f
->output_data
.x
->asked_for_visible
)
11075 x_set_offset (f
, f
->output_data
.x
->left_pos
, f
->output_data
.x
->top_pos
, 0);
11077 f
->output_data
.x
->asked_for_visible
= 1;
11079 if (! EQ (Vx_no_window_manager
, Qt
))
11080 x_wm_set_window_state (f
, NormalState
);
11081 #ifdef USE_X_TOOLKIT
11082 /* This was XtPopup, but that did nothing for an iconified frame. */
11083 XtMapWidget (f
->output_data
.x
->widget
);
11084 #else /* not USE_X_TOOLKIT */
11085 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
11086 #endif /* not USE_X_TOOLKIT */
11087 #if 0 /* This seems to bring back scroll bars in the wrong places
11088 if the window configuration has changed. They seem
11089 to come back ok without this. */
11090 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
11091 XMapSubwindows (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
11095 XFlush (FRAME_X_DISPLAY (f
));
11097 /* Synchronize to ensure Emacs knows the frame is visible
11098 before we do anything else. We do this loop with input not blocked
11099 so that incoming events are handled. */
11102 int count
= input_signal_count
;
11103 /* This must be before UNBLOCK_INPUT
11104 since events that arrive in response to the actions above
11105 will set it when they are handled. */
11106 int previously_visible
= f
->output_data
.x
->has_been_visible
;
11108 original_left
= f
->output_data
.x
->left_pos
;
11109 original_top
= f
->output_data
.x
->top_pos
;
11111 /* This must come after we set COUNT. */
11114 /* We unblock here so that arriving X events are processed. */
11116 /* Now move the window back to where it was "supposed to be".
11117 But don't do it if the gravity is negative.
11118 When the gravity is negative, this uses a position
11119 that is 3 pixels too low. Perhaps that's really the border width.
11121 Don't do this if the window has never been visible before,
11122 because the window manager may choose the position
11123 and we don't want to override it. */
11125 if (! FRAME_VISIBLE_P (f
) && ! FRAME_ICONIFIED_P (f
)
11126 && f
->output_data
.x
->win_gravity
== NorthWestGravity
11127 && previously_visible
)
11131 unsigned int width
, height
, border
, depth
;
11135 /* On some window managers (such as FVWM) moving an existing
11136 window, even to the same place, causes the window manager
11137 to introduce an offset. This can cause the window to move
11138 to an unexpected location. Check the geometry (a little
11139 slow here) and then verify that the window is in the right
11140 place. If the window is not in the right place, move it
11141 there, and take the potential window manager hit. */
11142 XGetGeometry (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
11143 &rootw
, &x
, &y
, &width
, &height
, &border
, &depth
);
11145 if (original_left
!= x
|| original_top
!= y
)
11146 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
11147 original_left
, original_top
);
11152 XSETFRAME (frame
, f
);
11157 /* Once we have handled input events,
11158 we should have received the MapNotify if one is coming.
11159 So if we have not got it yet, stop looping.
11160 Some window managers make their own decisions
11161 about visibility. */
11162 if (input_signal_count
!= count
)
11164 /* Machines that do polling rather than SIGIO have been observed
11165 to go into a busy-wait here. So we'll fake an alarm signal
11166 to let the handler know that there's something to be read.
11167 We used to raise a real alarm, but it seems that the handler
11168 isn't always enabled here. This is probably a bug. */
11169 if (input_polling_used ())
11171 /* It could be confusing if a real alarm arrives while processing
11172 the fake one. Turn it off and let the handler reset it. */
11174 input_poll_signal (0);
11176 /* Once we have handled input events,
11177 we should have received the MapNotify if one is coming.
11178 So if we have not got it yet, stop looping.
11179 Some window managers make their own decisions
11180 about visibility. */
11181 if (input_signal_count
!= count
)
11184 FRAME_SAMPLE_VISIBILITY (f
);
11188 /* Change from mapped state to withdrawn state. */
11190 /* Make the frame visible (mapped and not iconified). */
11193 x_make_frame_invisible (f
)
11198 #ifdef USE_X_TOOLKIT
11199 /* Use the frame's outermost window, not the one we normally draw on. */
11200 window
= XtWindow (f
->output_data
.x
->widget
);
11201 #else /* not USE_X_TOOLKIT */
11202 window
= FRAME_X_WINDOW (f
);
11203 #endif /* not USE_X_TOOLKIT */
11205 /* Don't keep the highlight on an invisible frame. */
11206 if (FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
11207 FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
11209 #if 0/* This might add unreliability; I don't trust it -- rms. */
11210 if (! f
->async_visible
&& ! f
->async_iconified
)
11216 /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
11217 that the current position of the window is user-specified, rather than
11218 program-specified, so that when the window is mapped again, it will be
11219 placed at the same location, without forcing the user to position it
11220 by hand again (they have already done that once for this window.) */
11221 x_wm_set_size_hint (f
, (long) 0, 1);
11225 if (! XWithdrawWindow (FRAME_X_DISPLAY (f
), window
,
11226 DefaultScreen (FRAME_X_DISPLAY (f
))))
11228 UNBLOCK_INPUT_RESIGNAL
;
11229 error ("Can't notify window manager of window withdrawal");
11231 #else /* ! defined (HAVE_X11R4) */
11233 /* Tell the window manager what we're going to do. */
11234 if (! EQ (Vx_no_window_manager
, Qt
))
11238 unmap
.xunmap
.type
= UnmapNotify
;
11239 unmap
.xunmap
.window
= window
;
11240 unmap
.xunmap
.event
= DefaultRootWindow (FRAME_X_DISPLAY (f
));
11241 unmap
.xunmap
.from_configure
= False
;
11242 if (! XSendEvent (FRAME_X_DISPLAY (f
),
11243 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
11245 SubstructureRedirectMaskSubstructureNotifyMask
,
11248 UNBLOCK_INPUT_RESIGNAL
;
11249 error ("Can't notify window manager of withdrawal");
11253 /* Unmap the window ourselves. Cheeky! */
11254 XUnmapWindow (FRAME_X_DISPLAY (f
), window
);
11255 #endif /* ! defined (HAVE_X11R4) */
11257 /* We can't distinguish this from iconification
11258 just by the event that we get from the server.
11259 So we can't win using the usual strategy of letting
11260 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
11261 and synchronize with the server to make sure we agree. */
11263 FRAME_ICONIFIED_P (f
) = 0;
11264 f
->async_visible
= 0;
11265 f
->async_iconified
= 0;
11272 /* Change window state from mapped to iconified. */
11275 x_iconify_frame (f
)
11281 /* Don't keep the highlight on an invisible frame. */
11282 if (FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
11283 FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
11285 if (f
->async_iconified
)
11290 FRAME_SAMPLE_VISIBILITY (f
);
11292 type
= x_icon_type (f
);
11294 x_bitmap_icon (f
, type
);
11296 #ifdef USE_X_TOOLKIT
11298 if (! FRAME_VISIBLE_P (f
))
11300 if (! EQ (Vx_no_window_manager
, Qt
))
11301 x_wm_set_window_state (f
, IconicState
);
11302 /* This was XtPopup, but that did nothing for an iconified frame. */
11303 XtMapWidget (f
->output_data
.x
->widget
);
11304 /* The server won't give us any event to indicate
11305 that an invisible frame was changed to an icon,
11306 so we have to record it here. */
11309 f
->async_iconified
= 1;
11310 f
->async_visible
= 0;
11315 result
= XIconifyWindow (FRAME_X_DISPLAY (f
),
11316 XtWindow (f
->output_data
.x
->widget
),
11317 DefaultScreen (FRAME_X_DISPLAY (f
)));
11321 error ("Can't notify window manager of iconification");
11323 f
->async_iconified
= 1;
11324 f
->async_visible
= 0;
11328 XFlush (FRAME_X_DISPLAY (f
));
11330 #else /* not USE_X_TOOLKIT */
11332 /* Make sure the X server knows where the window should be positioned,
11333 in case the user deiconifies with the window manager. */
11334 if (! FRAME_VISIBLE_P (f
) && !FRAME_ICONIFIED_P (f
))
11335 x_set_offset (f
, f
->output_data
.x
->left_pos
, f
->output_data
.x
->top_pos
, 0);
11337 /* Since we don't know which revision of X we're running, we'll use both
11338 the X11R3 and X11R4 techniques. I don't know if this is a good idea. */
11340 /* X11R4: send a ClientMessage to the window manager using the
11341 WM_CHANGE_STATE type. */
11345 message
.xclient
.window
= FRAME_X_WINDOW (f
);
11346 message
.xclient
.type
= ClientMessage
;
11347 message
.xclient
.message_type
= FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_change_state
;
11348 message
.xclient
.format
= 32;
11349 message
.xclient
.data
.l
[0] = IconicState
;
11351 if (! XSendEvent (FRAME_X_DISPLAY (f
),
11352 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
11354 SubstructureRedirectMask
| SubstructureNotifyMask
,
11357 UNBLOCK_INPUT_RESIGNAL
;
11358 error ("Can't notify window manager of iconification");
11362 /* X11R3: set the initial_state field of the window manager hints to
11364 x_wm_set_window_state (f
, IconicState
);
11366 if (!FRAME_VISIBLE_P (f
))
11368 /* If the frame was withdrawn, before, we must map it. */
11369 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
11372 f
->async_iconified
= 1;
11373 f
->async_visible
= 0;
11375 XFlush (FRAME_X_DISPLAY (f
));
11377 #endif /* not USE_X_TOOLKIT */
11380 /* Destroy the X window of frame F. */
11383 x_destroy_window (f
)
11386 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
11390 /* If a display connection is dead, don't try sending more
11391 commands to the X server. */
11392 if (dpyinfo
->display
!= 0)
11394 if (f
->output_data
.x
->icon_desc
!= 0)
11395 XDestroyWindow (FRAME_X_DISPLAY (f
), f
->output_data
.x
->icon_desc
);
11399 XDestroyIC (FRAME_XIC (f
));
11400 #if ! defined (SOLARIS2) || defined (HAVE_X11R6)
11401 /* This line causes crashes on Solaris with Openwin,
11402 due to an apparent bug in XCloseIM.
11403 X11R6 seems not to have the bug. */
11404 XCloseIM (FRAME_XIM (f
));
11408 XDestroyWindow (FRAME_X_DISPLAY (f
), f
->output_data
.x
->window_desc
);
11409 #ifdef USE_X_TOOLKIT
11410 if (f
->output_data
.x
->widget
)
11411 XtDestroyWidget (f
->output_data
.x
->widget
);
11412 free_frame_menubar (f
);
11413 #endif /* USE_X_TOOLKIT */
11415 free_frame_faces (f
);
11416 XFlush (FRAME_X_DISPLAY (f
));
11419 if (f
->output_data
.x
->saved_menu_event
)
11420 xfree (f
->output_data
.x
->saved_menu_event
);
11422 xfree (f
->output_data
.x
);
11423 f
->output_data
.x
= 0;
11424 if (f
== dpyinfo
->x_focus_frame
)
11425 dpyinfo
->x_focus_frame
= 0;
11426 if (f
== dpyinfo
->x_focus_event_frame
)
11427 dpyinfo
->x_focus_event_frame
= 0;
11428 if (f
== dpyinfo
->x_highlight_frame
)
11429 dpyinfo
->x_highlight_frame
= 0;
11431 dpyinfo
->reference_count
--;
11433 if (f
== dpyinfo
->mouse_face_mouse_frame
)
11435 dpyinfo
->mouse_face_beg_row
11436 = dpyinfo
->mouse_face_beg_col
= -1;
11437 dpyinfo
->mouse_face_end_row
11438 = dpyinfo
->mouse_face_end_col
= -1;
11439 dpyinfo
->mouse_face_window
= Qnil
;
11440 dpyinfo
->mouse_face_deferred_gc
= 0;
11441 dpyinfo
->mouse_face_mouse_frame
= 0;
11447 /* Setting window manager hints. */
11449 /* Set the normal size hints for the window manager, for frame F.
11450 FLAGS is the flags word to use--or 0 meaning preserve the flags
11451 that the window now has.
11452 If USER_POSITION is nonzero, we set the USPosition
11453 flag (this is useful when FLAGS is 0). */
11456 x_wm_set_size_hint (f
, flags
, user_position
)
11461 XSizeHints size_hints
;
11463 #ifdef USE_X_TOOLKIT
11466 Dimension widget_width
, widget_height
;
11467 Window window
= XtWindow (f
->output_data
.x
->widget
);
11468 #else /* not USE_X_TOOLKIT */
11469 Window window
= FRAME_X_WINDOW (f
);
11470 #endif /* not USE_X_TOOLKIT */
11472 /* Setting PMaxSize caused various problems. */
11473 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
11475 size_hints
.x
= f
->output_data
.x
->left_pos
;
11476 size_hints
.y
= f
->output_data
.x
->top_pos
;
11478 #ifdef USE_X_TOOLKIT
11479 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
11480 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
11481 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
11482 size_hints
.height
= widget_height
;
11483 size_hints
.width
= widget_width
;
11484 #else /* not USE_X_TOOLKIT */
11485 size_hints
.height
= PIXEL_HEIGHT (f
);
11486 size_hints
.width
= PIXEL_WIDTH (f
);
11487 #endif /* not USE_X_TOOLKIT */
11489 size_hints
.width_inc
= FONT_WIDTH (f
->output_data
.x
->font
);
11490 size_hints
.height_inc
= f
->output_data
.x
->line_height
;
11491 size_hints
.max_width
11492 = FRAME_X_DISPLAY_INFO (f
)->width
- CHAR_TO_PIXEL_WIDTH (f
, 0);
11493 size_hints
.max_height
11494 = FRAME_X_DISPLAY_INFO (f
)->height
- CHAR_TO_PIXEL_HEIGHT (f
, 0);
11496 /* Calculate the base and minimum sizes.
11498 (When we use the X toolkit, we don't do it here.
11499 Instead we copy the values that the widgets are using, below.) */
11500 #ifndef USE_X_TOOLKIT
11502 int base_width
, base_height
;
11503 int min_rows
= 0, min_cols
= 0;
11505 base_width
= CHAR_TO_PIXEL_WIDTH (f
, 0);
11506 base_height
= CHAR_TO_PIXEL_HEIGHT (f
, 0);
11508 check_frame_size (f
, &min_rows
, &min_cols
);
11510 /* The window manager uses the base width hints to calculate the
11511 current number of rows and columns in the frame while
11512 resizing; min_width and min_height aren't useful for this
11513 purpose, since they might not give the dimensions for a
11514 zero-row, zero-column frame.
11516 We use the base_width and base_height members if we have
11517 them; otherwise, we set the min_width and min_height members
11518 to the size for a zero x zero frame. */
11521 size_hints
.flags
|= PBaseSize
;
11522 size_hints
.base_width
= base_width
;
11523 size_hints
.base_height
= base_height
;
11524 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
11525 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
11527 size_hints
.min_width
= base_width
;
11528 size_hints
.min_height
= base_height
;
11532 /* If we don't need the old flags, we don't need the old hint at all. */
11535 size_hints
.flags
|= flags
;
11538 #endif /* not USE_X_TOOLKIT */
11541 XSizeHints hints
; /* Sometimes I hate X Windows... */
11542 long supplied_return
;
11546 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
11549 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
11552 #ifdef USE_X_TOOLKIT
11553 size_hints
.base_height
= hints
.base_height
;
11554 size_hints
.base_width
= hints
.base_width
;
11555 size_hints
.min_height
= hints
.min_height
;
11556 size_hints
.min_width
= hints
.min_width
;
11560 size_hints
.flags
|= flags
;
11565 if (hints
.flags
& PSize
)
11566 size_hints
.flags
|= PSize
;
11567 if (hints
.flags
& PPosition
)
11568 size_hints
.flags
|= PPosition
;
11569 if (hints
.flags
& USPosition
)
11570 size_hints
.flags
|= USPosition
;
11571 if (hints
.flags
& USSize
)
11572 size_hints
.flags
|= USSize
;
11576 #ifndef USE_X_TOOLKIT
11581 size_hints
.win_gravity
= f
->output_data
.x
->win_gravity
;
11582 size_hints
.flags
|= PWinGravity
;
11586 size_hints
.flags
&= ~ PPosition
;
11587 size_hints
.flags
|= USPosition
;
11589 #endif /* PWinGravity */
11592 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
11594 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
11598 /* Used for IconicState or NormalState */
11601 x_wm_set_window_state (f
, state
)
11605 #ifdef USE_X_TOOLKIT
11608 XtSetArg (al
[0], XtNinitialState
, state
);
11609 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
11610 #else /* not USE_X_TOOLKIT */
11611 Window window
= FRAME_X_WINDOW (f
);
11613 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
11614 f
->output_data
.x
->wm_hints
.initial_state
= state
;
11616 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
11617 #endif /* not USE_X_TOOLKIT */
11621 x_wm_set_icon_pixmap (f
, pixmap_id
)
11625 Pixmap icon_pixmap
;
11627 #ifndef USE_X_TOOLKIT
11628 Window window
= FRAME_X_WINDOW (f
);
11633 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
11634 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
11638 /* It seems there is no way to turn off use of an icon pixmap.
11639 The following line does it, only if no icon has yet been created,
11640 for some window managers. But with mwm it crashes.
11641 Some people say it should clear the IconPixmapHint bit in this case,
11642 but that doesn't work, and the X consortium said it isn't the
11643 right thing at all. Since there is no way to win,
11644 best to explicitly give up. */
11646 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
11652 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
11656 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
11657 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
11660 #else /* not USE_X_TOOLKIT */
11662 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
11663 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
11665 #endif /* not USE_X_TOOLKIT */
11669 x_wm_set_icon_position (f
, icon_x
, icon_y
)
11671 int icon_x
, icon_y
;
11673 #ifdef USE_X_TOOLKIT
11674 Window window
= XtWindow (f
->output_data
.x
->widget
);
11676 Window window
= FRAME_X_WINDOW (f
);
11679 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
11680 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
11681 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
11683 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
11687 /***********************************************************************
11689 ***********************************************************************/
11691 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
11694 x_get_font_info (f
, font_idx
)
11698 return (FRAME_X_FONT_TABLE (f
) + font_idx
);
11702 /* Return a list of names of available fonts matching PATTERN on frame
11703 F. If SIZE is not 0, it is the size (maximum bound width) of fonts
11704 to be listed. Frame F NULL means we have not yet created any
11705 frame on X, and consult the first display in x_display_list.
11706 MAXNAMES sets a limit on how many fonts to match. */
11709 x_list_fonts (f
, pattern
, size
, maxnames
)
11711 Lisp_Object pattern
;
11715 Lisp_Object list
= Qnil
, patterns
, newlist
= Qnil
, key
= Qnil
;
11716 Lisp_Object tem
, second_best
;
11717 Display
*dpy
= f
!= NULL
? FRAME_X_DISPLAY (f
) : x_display_list
->display
;
11718 int try_XLoadQueryFont
= 0;
11721 patterns
= Fassoc (pattern
, Valternate_fontname_alist
);
11722 if (NILP (patterns
))
11723 patterns
= Fcons (pattern
, Qnil
);
11725 if (maxnames
== 1 && !size
)
11726 /* We can return any single font matching PATTERN. */
11727 try_XLoadQueryFont
= 1;
11729 for (; CONSP (patterns
); patterns
= XCDR (patterns
))
11734 pattern
= XCAR (patterns
);
11735 /* See if we cached the result for this particular query.
11736 The cache is an alist of the form:
11737 (((PATTERN . MAXNAMES) (FONTNAME . WIDTH) ...) ...)
11739 if (f
&& (tem
= XCDR (FRAME_X_DISPLAY_INFO (f
)->name_list_element
),
11740 key
= Fcons (pattern
, make_number (maxnames
)),
11741 !NILP (list
= Fassoc (key
, tem
))))
11743 list
= Fcdr_safe (list
);
11744 /* We have a cashed list. Don't have to get the list again. */
11748 /* At first, put PATTERN in the cache. */
11751 count
= x_catch_errors (dpy
);
11753 if (try_XLoadQueryFont
)
11756 unsigned long value
;
11758 font
= XLoadQueryFont (dpy
, XSTRING (pattern
)->data
);
11759 if (x_had_errors_p (dpy
))
11761 /* This error is perhaps due to insufficient memory on X
11762 server. Let's just ignore it. */
11764 x_clear_errors (dpy
);
11768 && XGetFontProperty (font
, XA_FONT
, &value
))
11770 char *name
= (char *) XGetAtomName (dpy
, (Atom
) value
);
11771 int len
= strlen (name
);
11774 /* If DXPC (a Differential X Protocol Compressor)
11775 Ver.3.7 is running, XGetAtomName will return null
11776 string. We must avoid such a name. */
11778 try_XLoadQueryFont
= 0;
11782 names
= (char **) alloca (sizeof (char *));
11783 /* Some systems only allow alloca assigned to a
11785 tmp
= (char *) alloca (len
+ 1); names
[0] = tmp
;
11786 bcopy (name
, names
[0], len
+ 1);
11791 try_XLoadQueryFont
= 0;
11794 XFreeFont (dpy
, font
);
11797 if (!try_XLoadQueryFont
)
11799 /* We try at least 10 fonts because XListFonts will return
11800 auto-scaled fonts at the head. */
11801 names
= XListFonts (dpy
, XSTRING (pattern
)->data
, max (maxnames
, 10),
11803 if (x_had_errors_p (dpy
))
11805 /* This error is perhaps due to insufficient memory on X
11806 server. Let's just ignore it. */
11808 x_clear_errors (dpy
);
11812 x_uncatch_errors (dpy
, count
);
11819 /* Make a list of all the fonts we got back.
11820 Store that in the font cache for the display. */
11821 for (i
= 0; i
< num_fonts
; i
++)
11824 char *p
= names
[i
];
11825 int average_width
= -1, dashes
= 0;
11827 /* Count the number of dashes in NAMES[I]. If there are
11828 14 dashes, and the field value following 12th dash
11829 (AVERAGE_WIDTH) is 0, this is a auto-scaled font which
11830 is usually too ugly to be used for editing. Let's
11836 if (dashes
== 7) /* PIXEL_SIZE field */
11838 else if (dashes
== 12) /* AVERAGE_WIDTH field */
11839 average_width
= atoi (p
);
11841 if (dashes
< 14 || average_width
!= 0)
11843 tem
= build_string (names
[i
]);
11844 if (NILP (Fassoc (tem
, list
)))
11846 if (STRINGP (Vx_pixel_size_width_font_regexp
)
11847 && ((fast_c_string_match_ignore_case
11848 (Vx_pixel_size_width_font_regexp
, names
[i
]))
11850 /* We can set the value of PIXEL_SIZE to the
11851 width of this font. */
11852 list
= Fcons (Fcons (tem
, make_number (width
)), list
);
11854 /* For the moment, width is not known. */
11855 list
= Fcons (Fcons (tem
, Qnil
), list
);
11859 if (!try_XLoadQueryFont
)
11860 XFreeFontNames (names
);
11863 /* Now store the result in the cache. */
11865 XCDR (FRAME_X_DISPLAY_INFO (f
)->name_list_element
)
11866 = Fcons (Fcons (key
, list
),
11867 XCDR (FRAME_X_DISPLAY_INFO (f
)->name_list_element
));
11870 if (NILP (list
)) continue; /* Try the remaining alternatives. */
11872 newlist
= second_best
= Qnil
;
11873 /* Make a list of the fonts that have the right width. */
11874 for (; CONSP (list
); list
= XCDR (list
))
11880 if (!CONSP (tem
) || NILP (XCAR (tem
)))
11884 newlist
= Fcons (XCAR (tem
), newlist
);
11888 if (!INTEGERP (XCDR (tem
)))
11890 /* Since we have not yet known the size of this font, we
11891 must try slow function call XLoadQueryFont. */
11892 XFontStruct
*thisinfo
;
11895 count
= x_catch_errors (dpy
);
11896 thisinfo
= XLoadQueryFont (dpy
,
11897 XSTRING (XCAR (tem
))->data
);
11898 if (x_had_errors_p (dpy
))
11900 /* This error is perhaps due to insufficient memory on X
11901 server. Let's just ignore it. */
11903 x_clear_errors (dpy
);
11905 x_uncatch_errors (dpy
, count
);
11911 = (thisinfo
->min_bounds
.width
== 0
11913 : make_number (thisinfo
->max_bounds
.width
));
11914 XFreeFont (dpy
, thisinfo
);
11917 /* For unknown reason, the previous call of XListFont had
11918 returned a font which can't be opened. Record the size
11919 as 0 not to try to open it again. */
11920 XCDR (tem
) = make_number (0);
11923 found_size
= XINT (XCDR (tem
));
11924 if (found_size
== size
)
11925 newlist
= Fcons (XCAR (tem
), newlist
);
11926 else if (found_size
> 0)
11928 if (NILP (second_best
))
11930 else if (found_size
< size
)
11932 if (XINT (XCDR (second_best
)) > size
11933 || XINT (XCDR (second_best
)) < found_size
)
11938 if (XINT (XCDR (second_best
)) > size
11939 && XINT (XCDR (second_best
)) > found_size
)
11944 if (!NILP (newlist
))
11946 else if (!NILP (second_best
))
11948 newlist
= Fcons (XCAR (second_best
), Qnil
);
11959 /* Check that FONT is valid on frame F. It is if it can be found in F's
11963 x_check_font (f
, font
)
11968 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
11970 xassert (font
!= NULL
);
11972 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
11973 if (dpyinfo
->font_table
[i
].name
11974 && font
== dpyinfo
->font_table
[i
].font
)
11977 xassert (i
< dpyinfo
->n_fonts
);
11980 #endif /* GLYPH_DEBUG != 0 */
11982 /* Set *W to the minimum width, *H to the minimum font height of FONT.
11983 Note: There are (broken) X fonts out there with invalid XFontStruct
11984 min_bounds contents. For example, handa@etl.go.jp reports that
11985 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
11986 have font->min_bounds.width == 0. */
11989 x_font_min_bounds (font
, w
, h
)
11993 *h
= FONT_HEIGHT (font
);
11994 *w
= font
->min_bounds
.width
;
11996 /* Try to handle the case where FONT->min_bounds has invalid
11997 contents. Since the only font known to have invalid min_bounds
11998 is fixed-width, use max_bounds if min_bounds seems to be invalid. */
12000 *w
= font
->max_bounds
.width
;
12004 /* Compute the smallest character width and smallest font height over
12005 all fonts available on frame F. Set the members smallest_char_width
12006 and smallest_font_height in F's x_display_info structure to
12007 the values computed. Value is non-zero if smallest_font_height or
12008 smallest_char_width become smaller than they were before. */
12011 x_compute_min_glyph_bounds (f
)
12015 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
12017 int old_width
= dpyinfo
->smallest_char_width
;
12018 int old_height
= dpyinfo
->smallest_font_height
;
12020 dpyinfo
->smallest_font_height
= 100000;
12021 dpyinfo
->smallest_char_width
= 100000;
12023 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
12024 if (dpyinfo
->font_table
[i
].name
)
12026 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
12029 font
= (XFontStruct
*) fontp
->font
;
12030 xassert (font
!= (XFontStruct
*) ~0);
12031 x_font_min_bounds (font
, &w
, &h
);
12033 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
12034 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
12037 xassert (dpyinfo
->smallest_char_width
> 0
12038 && dpyinfo
->smallest_font_height
> 0);
12040 return (dpyinfo
->n_fonts
== 1
12041 || dpyinfo
->smallest_char_width
< old_width
12042 || dpyinfo
->smallest_font_height
< old_height
);
12046 /* Load font named FONTNAME of the size SIZE for frame F, and return a
12047 pointer to the structure font_info while allocating it dynamically.
12048 If SIZE is 0, load any size of font.
12049 If loading is failed, return NULL. */
12052 x_load_font (f
, fontname
, size
)
12054 register char *fontname
;
12057 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
12058 Lisp_Object font_names
;
12061 /* Get a list of all the fonts that match this name. Once we
12062 have a list of matching fonts, we compare them against the fonts
12063 we already have by comparing names. */
12064 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
12066 if (!NILP (font_names
))
12071 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
12072 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
12073 if (dpyinfo
->font_table
[i
].name
12074 && (!strcmp (dpyinfo
->font_table
[i
].name
,
12075 XSTRING (XCAR (tail
))->data
)
12076 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
12077 XSTRING (XCAR (tail
))->data
)))
12078 return (dpyinfo
->font_table
+ i
);
12081 /* Load the font and add it to the table. */
12085 struct font_info
*fontp
;
12086 unsigned long value
;
12089 /* If we have found fonts by x_list_font, load one of them. If
12090 not, we still try to load a font by the name given as FONTNAME
12091 because XListFonts (called in x_list_font) of some X server has
12092 a bug of not finding a font even if the font surely exists and
12093 is loadable by XLoadQueryFont. */
12094 if (size
> 0 && !NILP (font_names
))
12095 fontname
= (char *) XSTRING (XCAR (font_names
))->data
;
12098 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
12099 font
= (XFontStruct
*) XLoadQueryFont (FRAME_X_DISPLAY (f
), fontname
);
12100 if (x_had_errors_p (FRAME_X_DISPLAY (f
)))
12102 /* This error is perhaps due to insufficient memory on X
12103 server. Let's just ignore it. */
12105 x_clear_errors (FRAME_X_DISPLAY (f
));
12107 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
12112 /* Find a free slot in the font table. */
12113 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
12114 if (dpyinfo
->font_table
[i
].name
== NULL
)
12117 /* If no free slot found, maybe enlarge the font table. */
12118 if (i
== dpyinfo
->n_fonts
12119 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
12122 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
12123 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
12124 dpyinfo
->font_table
12125 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
12128 fontp
= dpyinfo
->font_table
+ i
;
12129 if (i
== dpyinfo
->n_fonts
)
12130 ++dpyinfo
->n_fonts
;
12132 /* Now fill in the slots of *FONTP. */
12134 fontp
->font
= font
;
12135 fontp
->font_idx
= i
;
12136 fontp
->name
= (char *) xmalloc (strlen (fontname
) + 1);
12137 bcopy (fontname
, fontp
->name
, strlen (fontname
) + 1);
12139 /* Try to get the full name of FONT. Put it in FULL_NAME. */
12141 if (XGetFontProperty (font
, XA_FONT
, &value
))
12143 char *name
= (char *) XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);
12147 /* Count the number of dashes in the "full name".
12148 If it is too few, this isn't really the font's full name,
12150 In X11R4, the fonts did not come with their canonical names
12161 full_name
= (char *) xmalloc (p
- name
+ 1);
12162 bcopy (name
, full_name
, p
- name
+ 1);
12168 if (full_name
!= 0)
12169 fontp
->full_name
= full_name
;
12171 fontp
->full_name
= fontp
->name
;
12173 fontp
->size
= font
->max_bounds
.width
;
12174 fontp
->height
= FONT_HEIGHT (font
);
12176 /* For some font, ascent and descent in max_bounds field is
12177 larger than the above value. */
12178 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
12179 if (max_height
> fontp
->height
)
12180 fontp
->height
= max_height
;
12183 if (NILP (font_names
))
12185 /* We come here because of a bug of XListFonts mentioned at
12186 the head of this block. Let's store this information in
12187 the cache for x_list_fonts. */
12188 Lisp_Object lispy_name
= build_string (fontname
);
12189 Lisp_Object lispy_full_name
= build_string (fontp
->full_name
);
12191 XCDR (dpyinfo
->name_list_element
)
12192 = Fcons (Fcons (Fcons (lispy_name
, make_number (256)),
12193 Fcons (Fcons (lispy_full_name
,
12194 make_number (fontp
->size
)),
12196 XCDR (dpyinfo
->name_list_element
));
12198 XCDR (dpyinfo
->name_list_element
)
12199 = Fcons (Fcons (Fcons (lispy_full_name
, make_number (256)),
12200 Fcons (Fcons (lispy_full_name
,
12201 make_number (fontp
->size
)),
12203 XCDR (dpyinfo
->name_list_element
));
12206 /* The slot `encoding' specifies how to map a character
12207 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
12208 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF, 0:0x2020..0x7F7F,
12209 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF,
12210 0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF, or
12211 2:0xA020..0xFF7F). For the moment, we don't know which charset
12212 uses this font. So, we set information in fontp->encoding[1]
12213 which is never used by any charset. If mapping can't be
12214 decided, set FONT_ENCODING_NOT_DECIDED. */
12216 = (font
->max_byte1
== 0
12218 ? (font
->min_char_or_byte2
< 0x80
12219 ? (font
->max_char_or_byte2
< 0x80
12220 ? 0 /* 0x20..0x7F */
12221 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
12222 : 1) /* 0xA0..0xFF */
12224 : (font
->min_byte1
< 0x80
12225 ? (font
->max_byte1
< 0x80
12226 ? (font
->min_char_or_byte2
< 0x80
12227 ? (font
->max_char_or_byte2
< 0x80
12228 ? 0 /* 0x2020..0x7F7F */
12229 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
12230 : 3) /* 0x20A0..0x7FFF */
12231 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
12232 : (font
->min_char_or_byte2
< 0x80
12233 ? (font
->max_char_or_byte2
< 0x80
12234 ? 2 /* 0xA020..0xFF7F */
12235 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
12236 : 1))); /* 0xA0A0..0xFFFF */
12238 fontp
->baseline_offset
12239 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
12240 ? (long) value
: 0);
12241 fontp
->relative_compose
12242 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
12243 ? (long) value
: 0);
12244 fontp
->default_ascent
12245 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
12246 ? (long) value
: 0);
12248 /* Set global flag fonts_changed_p to non-zero if the font loaded
12249 has a character with a smaller width than any other character
12250 before, or if the font loaded has a smalle>r height than any
12251 other font loaded before. If this happens, it will make a
12252 glyph matrix reallocation necessary. */
12253 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
12260 /* Return a pointer to struct font_info of a font named FONTNAME for
12261 frame F. If no such font is loaded, return NULL. */
12264 x_query_font (f
, fontname
)
12266 register char *fontname
;
12268 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
12271 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
12272 if (dpyinfo
->font_table
[i
].name
12273 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
12274 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
12275 return (dpyinfo
->font_table
+ i
);
12280 /* Find a CCL program for a font specified by FONTP, and set the member
12281 `encoder' of the structure. */
12284 x_find_ccl_program (fontp
)
12285 struct font_info
*fontp
;
12287 Lisp_Object list
, elt
;
12289 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
12293 && STRINGP (XCAR (elt
))
12294 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
12300 struct ccl_program
*ccl
12301 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
12303 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
12306 fontp
->font_encoder
= ccl
;
12312 /***********************************************************************
12314 ***********************************************************************/
12316 #ifdef USE_X_TOOLKIT
12317 static XrmOptionDescRec emacs_options
[] = {
12318 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
12319 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
12321 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
12322 XrmoptionSepArg
, NULL
},
12323 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
12325 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
12326 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
12327 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
12328 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
12329 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
12330 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
12331 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
12333 #endif /* USE_X_TOOLKIT */
12335 static int x_initialized
;
12337 #ifdef MULTI_KBOARD
12338 /* Test whether two display-name strings agree up to the dot that separates
12339 the screen number from the server number. */
12341 same_x_server (name1
, name2
)
12342 char *name1
, *name2
;
12344 int seen_colon
= 0;
12345 unsigned char *system_name
= XSTRING (Vsystem_name
)->data
;
12346 int system_name_length
= strlen (system_name
);
12347 int length_until_period
= 0;
12349 while (system_name
[length_until_period
] != 0
12350 && system_name
[length_until_period
] != '.')
12351 length_until_period
++;
12353 /* Treat `unix' like an empty host name. */
12354 if (! strncmp (name1
, "unix:", 5))
12356 if (! strncmp (name2
, "unix:", 5))
12358 /* Treat this host's name like an empty host name. */
12359 if (! strncmp (name1
, system_name
, system_name_length
)
12360 && name1
[system_name_length
] == ':')
12361 name1
+= system_name_length
;
12362 if (! strncmp (name2
, system_name
, system_name_length
)
12363 && name2
[system_name_length
] == ':')
12364 name2
+= system_name_length
;
12365 /* Treat this host's domainless name like an empty host name. */
12366 if (! strncmp (name1
, system_name
, length_until_period
)
12367 && name1
[length_until_period
] == ':')
12368 name1
+= length_until_period
;
12369 if (! strncmp (name2
, system_name
, length_until_period
)
12370 && name2
[length_until_period
] == ':')
12371 name2
+= length_until_period
;
12373 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
12377 if (seen_colon
&& *name1
== '.')
12381 && (*name1
== '.' || *name1
== '\0')
12382 && (*name2
== '.' || *name2
== '\0'));
12386 struct x_display_info
*
12387 x_term_init (display_name
, xrm_option
, resource_name
)
12388 Lisp_Object display_name
;
12390 char *resource_name
;
12394 struct x_display_info
*dpyinfo
;
12399 if (!x_initialized
)
12405 #ifdef USE_X_TOOLKIT
12406 /* weiner@footloose.sps.mot.com reports that this causes
12408 X protocol error: BadAtom (invalid Atom parameter)
12409 on protocol request 18skiloaf.
12410 So let's not use it until R6. */
12411 #ifdef HAVE_X11XTR6
12412 XtSetLanguageProc (NULL
, NULL
, NULL
);
12423 argv
[argc
++] = "-xrm";
12424 argv
[argc
++] = xrm_option
;
12426 dpy
= XtOpenDisplay (Xt_app_con
, XSTRING (display_name
)->data
,
12427 resource_name
, EMACS_CLASS
,
12428 emacs_options
, XtNumber (emacs_options
),
12431 #ifdef HAVE_X11XTR6
12432 /* I think this is to compensate for XtSetLanguageProc. */
12437 #else /* not USE_X_TOOLKIT */
12439 XSetLocaleModifiers ("");
12441 dpy
= XOpenDisplay (XSTRING (display_name
)->data
);
12442 #endif /* not USE_X_TOOLKIT */
12444 /* Detect failure. */
12451 /* We have definitely succeeded. Record the new connection. */
12453 dpyinfo
= (struct x_display_info
*) xmalloc (sizeof (struct x_display_info
));
12455 #ifdef MULTI_KBOARD
12457 struct x_display_info
*share
;
12460 for (share
= x_display_list
, tail
= x_display_name_list
; share
;
12461 share
= share
->next
, tail
= XCDR (tail
))
12462 if (same_x_server (XSTRING (XCAR (XCAR (tail
)))->data
,
12463 XSTRING (display_name
)->data
))
12466 dpyinfo
->kboard
= share
->kboard
;
12469 dpyinfo
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
12470 init_kboard (dpyinfo
->kboard
);
12471 if (!EQ (XSYMBOL (Qvendor_specific_keysyms
)->function
, Qunbound
))
12473 char *vendor
= ServerVendor (dpy
);
12474 dpyinfo
->kboard
->Vsystem_key_alist
12475 = call1 (Qvendor_specific_keysyms
,
12476 build_string (vendor
? vendor
: ""));
12479 dpyinfo
->kboard
->next_kboard
= all_kboards
;
12480 all_kboards
= dpyinfo
->kboard
;
12481 /* Don't let the initial kboard remain current longer than necessary.
12482 That would cause problems if a file loaded on startup tries to
12483 prompt in the mini-buffer. */
12484 if (current_kboard
== initial_kboard
)
12485 current_kboard
= dpyinfo
->kboard
;
12487 dpyinfo
->kboard
->reference_count
++;
12491 /* Put this display on the chain. */
12492 dpyinfo
->next
= x_display_list
;
12493 x_display_list
= dpyinfo
;
12495 /* Put it on x_display_name_list as well, to keep them parallel. */
12496 x_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
12497 x_display_name_list
);
12498 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
12500 dpyinfo
->display
= dpy
;
12503 XSetAfterFunction (x_current_display
, x_trace_wire
);
12507 = (char *) xmalloc (STRING_BYTES (XSTRING (Vinvocation_name
))
12508 + STRING_BYTES (XSTRING (Vsystem_name
))
12510 sprintf (dpyinfo
->x_id_name
, "%s@%s",
12511 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
12513 /* Figure out which modifier bits mean what. */
12514 x_find_modifier_meanings (dpyinfo
);
12516 /* Get the scroll bar cursor. */
12517 dpyinfo
->vertical_scroll_bar_cursor
12518 = XCreateFontCursor (dpyinfo
->display
, XC_sb_v_double_arrow
);
12520 xrdb
= x_load_resources (dpyinfo
->display
, xrm_option
,
12521 resource_name
, EMACS_CLASS
);
12522 #ifdef HAVE_XRMSETDATABASE
12523 XrmSetDatabase (dpyinfo
->display
, xrdb
);
12525 dpyinfo
->display
->db
= xrdb
;
12527 /* Put the rdb where we can find it in a way that works on
12529 dpyinfo
->xrdb
= xrdb
;
12531 dpyinfo
->screen
= ScreenOfDisplay (dpyinfo
->display
,
12532 DefaultScreen (dpyinfo
->display
));
12533 dpyinfo
->visual
= select_visual (dpyinfo
->display
, dpyinfo
->screen
,
12534 &dpyinfo
->n_planes
);
12535 dpyinfo
->height
= HeightOfScreen (dpyinfo
->screen
);
12536 dpyinfo
->width
= WidthOfScreen (dpyinfo
->screen
);
12537 dpyinfo
->root_window
= RootWindowOfScreen (dpyinfo
->screen
);
12538 dpyinfo
->grabbed
= 0;
12539 dpyinfo
->reference_count
= 0;
12540 dpyinfo
->icon_bitmap_id
= -1;
12541 dpyinfo
->font_table
= NULL
;
12542 dpyinfo
->n_fonts
= 0;
12543 dpyinfo
->font_table_size
= 0;
12544 dpyinfo
->bitmaps
= 0;
12545 dpyinfo
->bitmaps_size
= 0;
12546 dpyinfo
->bitmaps_last
= 0;
12547 dpyinfo
->scratch_cursor_gc
= 0;
12548 dpyinfo
->mouse_face_mouse_frame
= 0;
12549 dpyinfo
->mouse_face_deferred_gc
= 0;
12550 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
12551 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
12552 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
12553 dpyinfo
->mouse_face_window
= Qnil
;
12554 dpyinfo
->mouse_face_mouse_x
= dpyinfo
->mouse_face_mouse_y
= 0;
12555 dpyinfo
->mouse_face_defer
= 0;
12556 dpyinfo
->x_focus_frame
= 0;
12557 dpyinfo
->x_focus_event_frame
= 0;
12558 dpyinfo
->x_highlight_frame
= 0;
12559 dpyinfo
->image_cache
= make_image_cache ();
12562 int screen_number
= XScreenNumberOfScreen (dpyinfo
->screen
);
12563 double pixels
= DisplayHeight (dpyinfo
->display
, screen_number
);
12564 double mm
= DisplayHeightMM (dpyinfo
->display
, screen_number
);
12565 dpyinfo
->resy
= pixels
* 25.4 / mm
;
12566 pixels
= DisplayWidth (dpyinfo
->display
, screen_number
);
12567 mm
= DisplayWidthMM (dpyinfo
->display
, screen_number
);
12568 dpyinfo
->resx
= pixels
* 25.4 / mm
;
12571 dpyinfo
->Xatom_wm_protocols
12572 = XInternAtom (dpyinfo
->display
, "WM_PROTOCOLS", False
);
12573 dpyinfo
->Xatom_wm_take_focus
12574 = XInternAtom (dpyinfo
->display
, "WM_TAKE_FOCUS", False
);
12575 dpyinfo
->Xatom_wm_save_yourself
12576 = XInternAtom (dpyinfo
->display
, "WM_SAVE_YOURSELF", False
);
12577 dpyinfo
->Xatom_wm_delete_window
12578 = XInternAtom (dpyinfo
->display
, "WM_DELETE_WINDOW", False
);
12579 dpyinfo
->Xatom_wm_change_state
12580 = XInternAtom (dpyinfo
->display
, "WM_CHANGE_STATE", False
);
12581 dpyinfo
->Xatom_wm_configure_denied
12582 = XInternAtom (dpyinfo
->display
, "WM_CONFIGURE_DENIED", False
);
12583 dpyinfo
->Xatom_wm_window_moved
12584 = XInternAtom (dpyinfo
->display
, "WM_MOVED", False
);
12585 dpyinfo
->Xatom_editres
12586 = XInternAtom (dpyinfo
->display
, "Editres", False
);
12587 dpyinfo
->Xatom_CLIPBOARD
12588 = XInternAtom (dpyinfo
->display
, "CLIPBOARD", False
);
12589 dpyinfo
->Xatom_TIMESTAMP
12590 = XInternAtom (dpyinfo
->display
, "TIMESTAMP", False
);
12591 dpyinfo
->Xatom_TEXT
12592 = XInternAtom (dpyinfo
->display
, "TEXT", False
);
12593 dpyinfo
->Xatom_COMPOUND_TEXT
12594 = XInternAtom (dpyinfo
->display
, "COMPOUND_TEXT", False
);
12595 dpyinfo
->Xatom_DELETE
12596 = XInternAtom (dpyinfo
->display
, "DELETE", False
);
12597 dpyinfo
->Xatom_MULTIPLE
12598 = XInternAtom (dpyinfo
->display
, "MULTIPLE", False
);
12599 dpyinfo
->Xatom_INCR
12600 = XInternAtom (dpyinfo
->display
, "INCR", False
);
12601 dpyinfo
->Xatom_EMACS_TMP
12602 = XInternAtom (dpyinfo
->display
, "_EMACS_TMP_", False
);
12603 dpyinfo
->Xatom_TARGETS
12604 = XInternAtom (dpyinfo
->display
, "TARGETS", False
);
12605 dpyinfo
->Xatom_NULL
12606 = XInternAtom (dpyinfo
->display
, "NULL", False
);
12607 dpyinfo
->Xatom_ATOM_PAIR
12608 = XInternAtom (dpyinfo
->display
, "ATOM_PAIR", False
);
12609 /* For properties of font. */
12610 dpyinfo
->Xatom_PIXEL_SIZE
12611 = XInternAtom (dpyinfo
->display
, "PIXEL_SIZE", False
);
12612 dpyinfo
->Xatom_MULE_BASELINE_OFFSET
12613 = XInternAtom (dpyinfo
->display
, "_MULE_BASELINE_OFFSET", False
);
12614 dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
12615 = XInternAtom (dpyinfo
->display
, "_MULE_RELATIVE_COMPOSE", False
);
12616 dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
12617 = XInternAtom (dpyinfo
->display
, "_MULE_DEFAULT_ASCENT", False
);
12619 /* Ghostscript support. */
12620 dpyinfo
->Xatom_PAGE
= XInternAtom (dpyinfo
->display
, "PAGE", False
);
12621 dpyinfo
->Xatom_DONE
= XInternAtom (dpyinfo
->display
, "DONE", False
);
12623 dpyinfo
->Xatom_Scrollbar
= XInternAtom (dpyinfo
->display
, "SCROLLBAR",
12626 dpyinfo
->cut_buffers_initialized
= 0;
12628 connection
= ConnectionNumber (dpyinfo
->display
);
12629 dpyinfo
->connection
= connection
;
12634 null_bits
[0] = 0x00;
12636 dpyinfo
->null_pixel
12637 = XCreatePixmapFromBitmapData (dpyinfo
->display
, dpyinfo
->root_window
,
12638 null_bits
, 1, 1, (long) 0, (long) 0,
12643 extern int gray_bitmap_width
, gray_bitmap_height
;
12644 extern unsigned char *gray_bitmap_bits
;
12646 = XCreatePixmapFromBitmapData (dpyinfo
->display
, dpyinfo
->root_window
,
12648 gray_bitmap_width
, gray_bitmap_height
,
12649 (unsigned long) 1, (unsigned long) 0, 1);
12652 #ifdef subprocesses
12653 /* This is only needed for distinguishing keyboard and process input. */
12654 if (connection
!= 0)
12655 add_keyboard_wait_descriptor (connection
);
12658 #ifndef F_SETOWN_BUG
12660 #ifdef F_SETOWN_SOCK_NEG
12661 /* stdin is a socket here */
12662 fcntl (connection
, F_SETOWN
, -getpid ());
12663 #else /* ! defined (F_SETOWN_SOCK_NEG) */
12664 fcntl (connection
, F_SETOWN
, getpid ());
12665 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
12666 #endif /* ! defined (F_SETOWN) */
12667 #endif /* F_SETOWN_BUG */
12670 if (interrupt_input
)
12671 init_sigio (connection
);
12672 #endif /* ! defined (SIGIO) */
12675 #ifdef HAVE_X11R5 /* It seems X11R4 lacks XtCvtStringToFont, and XPointer. */
12676 /* Make sure that we have a valid font for dialog boxes
12677 so that Xt does not crash. */
12679 Display
*dpy
= dpyinfo
->display
;
12680 XrmValue d
, fr
, to
;
12684 d
.addr
= (XPointer
)&dpy
;
12685 d
.size
= sizeof (Display
*);
12686 fr
.addr
= XtDefaultFont
;
12687 fr
.size
= sizeof (XtDefaultFont
);
12688 to
.size
= sizeof (Font
*);
12689 to
.addr
= (XPointer
)&font
;
12690 count
= x_catch_errors (dpy
);
12691 if (!XtCallConverter (dpy
, XtCvtStringToFont
, &d
, 1, &fr
, &to
, NULL
))
12693 if (x_had_errors_p (dpy
) || !XQueryFont (dpy
, font
))
12694 XrmPutLineResource (&xrdb
, "Emacs.dialog.*.font: 9x15");
12695 x_uncatch_errors (dpy
, count
);
12705 /* Get rid of display DPYINFO, assuming all frames are already gone,
12706 and without sending any more commands to the X server. */
12709 x_delete_display (dpyinfo
)
12710 struct x_display_info
*dpyinfo
;
12712 delete_keyboard_wait_descriptor (dpyinfo
->connection
);
12714 /* Discard this display from x_display_name_list and x_display_list.
12715 We can't use Fdelq because that can quit. */
12716 if (! NILP (x_display_name_list
)
12717 && EQ (XCAR (x_display_name_list
), dpyinfo
->name_list_element
))
12718 x_display_name_list
= XCDR (x_display_name_list
);
12723 tail
= x_display_name_list
;
12724 while (CONSP (tail
) && CONSP (XCDR (tail
)))
12726 if (EQ (XCAR (XCDR (tail
)),
12727 dpyinfo
->name_list_element
))
12729 XCDR (tail
) = XCDR (XCDR (tail
));
12732 tail
= XCDR (tail
);
12736 if (x_display_list
== dpyinfo
)
12737 x_display_list
= dpyinfo
->next
;
12740 struct x_display_info
*tail
;
12742 for (tail
= x_display_list
; tail
; tail
= tail
->next
)
12743 if (tail
->next
== dpyinfo
)
12744 tail
->next
= tail
->next
->next
;
12747 #ifndef USE_X_TOOLKIT /* I'm told Xt does this itself. */
12748 #ifndef AIX /* On AIX, XCloseDisplay calls this. */
12749 XrmDestroyDatabase (dpyinfo
->xrdb
);
12752 #ifdef MULTI_KBOARD
12753 if (--dpyinfo
->kboard
->reference_count
== 0)
12754 delete_kboard (dpyinfo
->kboard
);
12756 xfree (dpyinfo
->font_table
);
12757 xfree (dpyinfo
->x_id_name
);
12761 /* Set up use of X before we make the first connection. */
12763 static struct redisplay_interface x_redisplay_interface
=
12768 x_clear_end_of_line
,
12770 x_after_update_window_line
,
12771 x_update_window_begin
,
12772 x_update_window_end
,
12775 x_get_glyph_overhangs
,
12776 x_fix_overlapping_area
12782 rif
= &x_redisplay_interface
;
12784 clear_frame_hook
= x_clear_frame
;
12785 ins_del_lines_hook
= x_ins_del_lines
;
12786 change_line_highlight_hook
= x_change_line_highlight
;
12787 delete_glyphs_hook
= x_delete_glyphs
;
12788 ring_bell_hook
= XTring_bell
;
12789 reset_terminal_modes_hook
= XTreset_terminal_modes
;
12790 set_terminal_modes_hook
= XTset_terminal_modes
;
12791 update_begin_hook
= x_update_begin
;
12792 update_end_hook
= x_update_end
;
12793 set_terminal_window_hook
= XTset_terminal_window
;
12794 read_socket_hook
= XTread_socket
;
12795 frame_up_to_date_hook
= XTframe_up_to_date
;
12796 reassert_line_highlight_hook
= XTreassert_line_highlight
;
12797 mouse_position_hook
= XTmouse_position
;
12798 frame_rehighlight_hook
= XTframe_rehighlight
;
12799 frame_raise_lower_hook
= XTframe_raise_lower
;
12800 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
12801 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
12802 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
12803 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
12804 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
12806 scroll_region_ok
= 1; /* we'll scroll partial frames */
12807 char_ins_del_ok
= 0; /* just as fast to write the line */
12808 line_ins_del_ok
= 1; /* we'll just blt 'em */
12809 fast_clear_end_of_line
= 1; /* X does this well */
12810 memory_below_frame
= 0; /* we don't remember what scrolls
12815 last_tool_bar_item
= -1;
12816 any_help_event_p
= 0;
12818 /* Try to use interrupt input; if we can't, then start polling. */
12819 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
12821 #ifdef USE_X_TOOLKIT
12822 XtToolkitInitialize ();
12823 Xt_app_con
= XtCreateApplicationContext ();
12824 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
12827 /* Note that there is no real way portable across R3/R4 to get the
12828 original error handler. */
12829 XSetErrorHandler (x_error_handler
);
12830 XSetIOErrorHandler (x_io_error_quitter
);
12832 /* Disable Window Change signals; they are handled by X events. */
12834 signal (SIGWINCH
, SIG_DFL
);
12835 #endif /* ! defined (SIGWINCH) */
12837 signal (SIGPIPE
, x_connection_signal
);
12844 staticpro (&x_error_message_string
);
12845 x_error_message_string
= Qnil
;
12847 staticpro (&x_display_name_list
);
12848 x_display_name_list
= Qnil
;
12850 staticpro (&last_mouse_scroll_bar
);
12851 last_mouse_scroll_bar
= Qnil
;
12853 staticpro (&Qvendor_specific_keysyms
);
12854 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
12856 staticpro (&last_mouse_press_frame
);
12857 last_mouse_press_frame
= Qnil
;
12859 staticpro (&help_echo
);
12861 staticpro (&previous_help_echo
);
12862 previous_help_echo
= Qnil
;
12864 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
12865 "*Non-nil means draw block cursor as wide as the glyph under it.\n\
12866 For example, if a block cursor is over a tab, it will be drawn as\n\
12867 wide as that tab on the display.");
12868 x_stretch_cursor_p
= 0;
12870 DEFVAR_BOOL ("x-toolkit-scroll-bars-p", &x_toolkit_scroll_bars_p
,
12871 "If not nil, Emacs uses toolkit scroll bars.");
12872 #if USE_TOOLKIT_SCROLL_BARS
12873 x_toolkit_scroll_bars_p
= 1;
12875 x_toolkit_scroll_bars_p
= 0;
12878 defsubr (&Sxt_process_timeouts
);
12879 staticpro (&last_mouse_motion_frame
);
12880 last_mouse_motion_frame
= Qnil
;
12883 #endif /* not HAVE_X_WINDOWS */