1 /* X Communication module for terminals which understand the X protocol.
2 Copyright (C) 1989, 93, 94, 95, 96, 1997, 1998, 1999, 2000, 2001
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>
47 /* Load sys/types.h if not already loaded.
48 In some systems loading it twice is suicidal. */
50 #include <sys/types.h>
54 #include <sys/ioctl.h>
55 #endif /* ! defined (BSD_SYSTEM) */
60 #ifndef INCLUDED_FCNTL
67 /* Caused redefinition of DBL_DIG on Netbsd; seems not to be needed. */
68 /* #include <sys/param.h> */
74 #include "dispextern.h"
76 #include "termhooks.h"
84 #include "intervals.h"
90 #include <X11/Shell.h>
93 #ifdef HAVE_SYS_TIME_H
101 extern int xlwmenu_window_p (Widget w
, Window window
);
102 extern void xlwmenu_redisplay
P_ ((Widget
));
107 extern void free_frame_menubar
P_ ((struct frame
*));
108 extern struct frame
*x_menubar_window_to_frame
P_ ((struct x_display_info
*,
111 #if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
113 extern void _XEditResCheckMessages ();
114 #endif /* not NO_EDITRES */
116 /* Include toolkit specific headers for the scroll bar widget. */
118 #ifdef USE_TOOLKIT_SCROLL_BARS
119 #if defined USE_MOTIF
120 #include <Xm/Xm.h> /* for LESSTIF_VERSION */
121 #include <Xm/ScrollBar.h>
122 #else /* !USE_MOTIF i.e. use Xaw */
125 #include <X11/Xaw3d/Simple.h>
126 #include <X11/Xaw3d/Scrollbar.h>
127 #define ARROW_SCROLLBAR
128 #include <X11/Xaw3d/ScrollbarP.h>
129 #else /* !HAVE_XAW3D */
130 #include <X11/Xaw/Simple.h>
131 #include <X11/Xaw/Scrollbar.h>
132 #endif /* !HAVE_XAW3D */
134 #define XtNpickTop "pickTop"
135 #endif /* !XtNpickTop */
136 #endif /* !USE_MOTIF */
137 #endif /* USE_TOOLKIT_SCROLL_BARS */
139 #endif /* USE_X_TOOLKIT */
141 #ifndef USE_X_TOOLKIT
142 #define x_any_window_to_frame x_window_to_frame
143 #define x_top_window_to_frame x_window_to_frame
148 #ifndef XtNinitialState
149 #define XtNinitialState "initialState"
153 #define abs(x) ((x) < 0 ? -(x) : (x))
155 #define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
158 /* Fringe bitmaps. */
160 enum fringe_bitmap_type
163 LEFT_TRUNCATION_BITMAP
,
164 RIGHT_TRUNCATION_BITMAP
,
165 OVERLAY_ARROW_BITMAP
,
166 CONTINUED_LINE_BITMAP
,
167 CONTINUATION_LINE_BITMAP
,
171 /* Bitmap drawn to indicate lines not displaying text if
172 `indicate-empty-lines' is non-nil. */
177 static unsigned char zv_bits
[] = {
178 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
179 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
180 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
181 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
182 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
183 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
184 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
185 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
187 /* An arrow like this: `<-'. */
190 #define left_height 8
191 static unsigned char left_bits
[] = {
192 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
194 /* Right truncation arrow bitmap `->'. */
196 #define right_width 8
197 #define right_height 8
198 static unsigned char right_bits
[] = {
199 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
201 /* Marker for continued lines. */
203 #define continued_width 8
204 #define continued_height 8
205 static unsigned char continued_bits
[] = {
206 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
208 /* Marker for continuation lines. */
210 #define continuation_width 8
211 #define continuation_height 8
212 static unsigned char continuation_bits
[] = {
213 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
215 /* Overlay arrow bitmap. */
221 static unsigned char ov_bits
[] = {
222 0x30, 0x08, 0x3c, 0x7e, 0x7a, 0x7a, 0x62, 0x3c};
224 /* A triangular arrow. */
227 static unsigned char ov_bits
[] = {
228 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
232 extern Lisp_Object Qhelp_echo
;
235 /* Non-nil means Emacs uses toolkit scroll bars. */
237 Lisp_Object Vx_toolkit_scroll_bars
;
239 /* If a string, XTread_socket generates an event to display that string.
240 (The display is done in read_char.) */
242 static Lisp_Object help_echo
;
243 static Lisp_Object help_echo_window
;
244 static Lisp_Object help_echo_object
;
245 static int help_echo_pos
;
247 /* Temporary variable for XTread_socket. */
249 static Lisp_Object previous_help_echo
;
251 /* Non-zero means that a HELP_EVENT has been generated since Emacs
254 static int any_help_event_p
;
256 /* Non-zero means draw block and hollow cursor as wide as the glyph
257 under it. For example, if a block cursor is over a tab, it will be
258 drawn as wide as that tab on the display. */
260 int x_stretch_cursor_p
;
262 /* Non-zero means make use of UNDERLINE_POSITION font properties. */
264 int x_use_underline_position_properties
;
266 /* This is a chain of structures for all the X displays currently in
269 struct x_display_info
*x_display_list
;
271 /* This is a list of cons cells, each of the form (NAME
272 . FONT-LIST-CACHE), one for each element of x_display_list and in
273 the same order. NAME is the name of the frame. FONT-LIST-CACHE
274 records previous values returned by x-list-fonts. */
276 Lisp_Object x_display_name_list
;
278 /* Frame being updated by update_frame. This is declared in term.c.
279 This is set by update_begin and looked at by all the XT functions.
280 It is zero while not inside an update. In that case, the XT
281 functions assume that `selected_frame' is the frame to apply to. */
283 extern struct frame
*updating_frame
;
285 /* This is a frame waiting to be auto-raised, within XTread_socket. */
287 struct frame
*pending_autoraise_frame
;
290 /* The application context for Xt use. */
291 XtAppContext Xt_app_con
;
292 static String Xt_default_resources
[] = {0};
293 #endif /* USE_X_TOOLKIT */
295 /* Nominal cursor position -- where to draw output.
296 HPOS and VPOS are window relative glyph matrix coordinates.
297 X and Y are window relative pixel coordinates. */
299 struct cursor_pos output_cursor
;
301 /* Non-zero means user is interacting with a toolkit scroll bar. */
303 static int toolkit_scroll_bar_interaction
;
307 Formerly, we used PointerMotionHintMask (in standard_event_mask)
308 so that we would have to call XQueryPointer after each MotionNotify
309 event to ask for another such event. However, this made mouse tracking
310 slow, and there was a bug that made it eventually stop.
312 Simply asking for MotionNotify all the time seems to work better.
314 In order to avoid asking for motion events and then throwing most
315 of them away or busy-polling the server for mouse positions, we ask
316 the server for pointer motion hints. This means that we get only
317 one event per group of mouse movements. "Groups" are delimited by
318 other kinds of events (focus changes and button clicks, for
319 example), or by XQueryPointer calls; when one of these happens, we
320 get another MotionNotify event the next time the mouse moves. This
321 is at least as efficient as getting motion events when mouse
322 tracking is on, and I suspect only negligibly worse when tracking
325 /* Where the mouse was last time we reported a mouse event. */
327 FRAME_PTR last_mouse_frame
;
328 static XRectangle last_mouse_glyph
;
329 static Lisp_Object last_mouse_press_frame
;
331 /* The scroll bar in which the last X motion event occurred.
333 If the last X motion event occurred in a scroll bar, we set this so
334 XTmouse_position can know whether to report a scroll bar motion or
337 If the last X motion event didn't occur in a scroll bar, we set
338 this to Qnil, to tell XTmouse_position to return an ordinary motion
341 static Lisp_Object last_mouse_scroll_bar
;
343 /* This is a hack. We would really prefer that XTmouse_position would
344 return the time associated with the position it returns, but there
345 doesn't seem to be any way to wrest the time-stamp from the server
346 along with the position query. So, we just keep track of the time
347 of the last movement we received, and return that in hopes that
348 it's somewhat accurate. */
350 static Time last_mouse_movement_time
;
352 /* Incremented by XTread_socket whenever it really tries to read
356 static int volatile input_signal_count
;
358 static int input_signal_count
;
361 /* Used locally within XTread_socket. */
363 static int x_noop_count
;
365 /* Initial values of argv and argc. */
367 extern char **initial_argv
;
368 extern int initial_argc
;
370 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
372 /* Tells if a window manager is present or not. */
374 extern Lisp_Object Vx_no_window_manager
;
376 extern Lisp_Object Qface
, Qmouse_face
;
380 /* A mask of extra modifier bits to put into every keyboard char. */
382 extern int extra_keyboard_modifiers
;
384 static Lisp_Object Qvendor_specific_keysyms
;
386 extern XrmDatabase x_load_resources
P_ ((Display
*, char *, char *, char *));
387 extern Lisp_Object x_icon_type
P_ ((struct frame
*));
390 /* Enumeration for overriding/changing the face to use for drawing
391 glyphs in x_draw_glyphs. */
393 enum draw_glyphs_face
403 static int cursor_in_mouse_face_p
P_ ((struct window
*));
404 static int clear_mouse_face
P_ ((struct x_display_info
*));
405 static int x_alloc_nearest_color_1
P_ ((Display
*, Colormap
, XColor
*));
406 static void x_set_window_size_1
P_ ((struct frame
*, int, int, int));
407 static const XColor
*x_color_cells
P_ ((Display
*, int *));
408 static void x_update_window_end
P_ ((struct window
*, int, int));
409 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
410 void x_delete_display
P_ ((struct x_display_info
*));
411 static unsigned int x_x_to_emacs_modifiers
P_ ((struct x_display_info
*,
413 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
414 int *, int *, Lisp_Object
));
415 static int fast_find_string_pos
P_ ((struct window
*, int, Lisp_Object
,
416 int *, int *, int *, int *, int));
417 static void set_output_cursor
P_ ((struct cursor_pos
*));
418 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
419 int *, int *, int *, int));
420 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
421 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
422 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
423 static void x_handle_tool_bar_click
P_ ((struct frame
*, XButtonEvent
*));
424 static void show_mouse_face
P_ ((struct x_display_info
*,
425 enum draw_glyphs_face
));
426 static int x_io_error_quitter
P_ ((Display
*));
427 int x_catch_errors
P_ ((Display
*));
428 void x_uncatch_errors
P_ ((Display
*, int));
429 void x_lower_frame
P_ ((struct frame
*));
430 void x_scroll_bar_clear
P_ ((struct frame
*));
431 int x_had_errors_p
P_ ((Display
*));
432 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
433 void x_raise_frame
P_ ((struct frame
*));
434 void x_set_window_size
P_ ((struct frame
*, int, int, int));
435 void x_wm_set_window_state
P_ ((struct frame
*, int));
436 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
437 void x_initialize
P_ ((void));
438 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
439 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
440 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
442 enum draw_glyphs_face
));
443 static void x_update_end
P_ ((struct frame
*));
444 static void XTframe_up_to_date
P_ ((struct frame
*));
445 static void XTset_terminal_modes
P_ ((void));
446 static void XTreset_terminal_modes
P_ ((void));
447 static void XTcursor_to
P_ ((int, int, int, int));
448 static void x_write_glyphs
P_ ((struct glyph
*, int));
449 static void x_clear_end_of_line
P_ ((int));
450 static void x_clear_frame
P_ ((void));
451 static void x_clear_cursor
P_ ((struct window
*));
452 static void frame_highlight
P_ ((struct frame
*));
453 static void frame_unhighlight
P_ ((struct frame
*));
454 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
455 static void XTframe_rehighlight
P_ ((struct frame
*));
456 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
457 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
458 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int));
459 static int x_intersect_rectangles
P_ ((XRectangle
*, XRectangle
*,
461 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
462 static int expose_window_tree
P_ ((struct window
*, XRectangle
*));
463 static int expose_window
P_ ((struct window
*, XRectangle
*));
464 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
465 XRectangle
*, enum glyph_row_area
));
466 static int expose_line
P_ ((struct window
*, struct glyph_row
*,
468 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
469 static void x_update_window_cursor
P_ ((struct window
*, int));
470 static void x_erase_phys_cursor
P_ ((struct window
*));
471 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
472 static void x_draw_fringe_bitmap
P_ ((struct window
*, struct glyph_row
*,
473 enum fringe_bitmap_type
, int left_p
));
475 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
477 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, XRectangle
*));
478 static void x_draw_row_fringe_bitmaps
P_ ((struct window
*, struct glyph_row
*));
479 static void notice_overwritten_cursor
P_ ((struct window
*, enum glyph_row_area
,
480 int, int, int, int));
481 static void x_flush
P_ ((struct frame
*f
));
482 static void x_update_begin
P_ ((struct frame
*));
483 static void x_update_window_begin
P_ ((struct window
*));
484 static void x_draw_vertical_border
P_ ((struct window
*));
485 static void x_after_update_window_line
P_ ((struct glyph_row
*));
486 static INLINE
void take_vertical_position_into_account
P_ ((struct it
*));
487 static void x_produce_stretch_glyph
P_ ((struct it
*));
488 static struct scroll_bar
*x_window_to_scroll_bar
P_ ((Window
));
489 static void x_scroll_bar_report_motion
P_ ((struct frame
**, Lisp_Object
*,
490 enum scroll_bar_part
*,
491 Lisp_Object
*, Lisp_Object
*,
494 /* Flush display of frame F, or of all frames if F is null. */
503 Lisp_Object rest
, frame
;
504 FOR_EACH_FRAME (rest
, frame
)
505 x_flush (XFRAME (frame
));
507 else if (FRAME_X_P (f
))
508 XFlush (FRAME_X_DISPLAY (f
));
513 /* Remove calls to XFlush by defining XFlush to an empty replacement.
514 Calls to XFlush should be unnecessary because the X output buffer
515 is flushed automatically as needed by calls to XPending,
516 XNextEvent, or XWindowEvent according to the XFlush man page.
517 XTread_socket calls XPending. Removing XFlush improves
520 #define XFlush(DISPLAY) (void) 0
523 /***********************************************************************
525 ***********************************************************************/
529 /* This is a function useful for recording debugging information about
530 the sequence of occurrences in this file. */
538 struct record event_record
[100];
540 int event_record_index
;
542 record_event (locus
, type
)
546 if (event_record_index
== sizeof (event_record
) / sizeof (struct record
))
547 event_record_index
= 0;
549 event_record
[event_record_index
].locus
= locus
;
550 event_record
[event_record_index
].type
= type
;
551 event_record_index
++;
558 /* Return the struct x_display_info corresponding to DPY. */
560 struct x_display_info
*
561 x_display_info_for_display (dpy
)
564 struct x_display_info
*dpyinfo
;
566 for (dpyinfo
= x_display_list
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
567 if (dpyinfo
->display
== dpy
)
575 /***********************************************************************
576 Starting and ending an update
577 ***********************************************************************/
579 /* Start an update of frame F. This function is installed as a hook
580 for update_begin, i.e. it is called when update_begin is called.
581 This function is called prior to calls to x_update_window_begin for
582 each window being updated. Currently, there is nothing to do here
583 because all interesting stuff is done on a window basis. */
593 /* Start update of window W. Set the global variable updated_window
594 to the window being updated and set output_cursor to the cursor
598 x_update_window_begin (w
)
601 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
602 struct x_display_info
*display_info
= FRAME_X_DISPLAY_INFO (f
);
605 set_output_cursor (&w
->cursor
);
609 if (f
== display_info
->mouse_face_mouse_frame
)
611 /* Don't do highlighting for mouse motion during the update. */
612 display_info
->mouse_face_defer
= 1;
614 /* If F needs to be redrawn, simply forget about any prior mouse
616 if (FRAME_GARBAGED_P (f
))
617 display_info
->mouse_face_window
= Qnil
;
619 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
620 their mouse_face_p flag set, which means that they are always
621 unequal to rows in a desired matrix which never have that
622 flag set. So, rows containing mouse-face glyphs are never
623 scrolled, and we don't have to switch the mouse highlight off
624 here to prevent it from being scrolled. */
626 /* Can we tell that this update does not affect the window
627 where the mouse highlight is? If so, no need to turn off.
628 Likewise, don't do anything if the frame is garbaged;
629 in that case, the frame's current matrix that we would use
630 is all wrong, and we will redisplay that line anyway. */
631 if (!NILP (display_info
->mouse_face_window
)
632 && w
== XWINDOW (display_info
->mouse_face_window
))
636 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
637 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
640 if (i
< w
->desired_matrix
->nrows
)
641 clear_mouse_face (display_info
);
650 /* Draw a vertical window border to the right of window W if W doesn't
651 have vertical scroll bars. */
654 x_draw_vertical_border (w
)
657 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
659 /* Redraw borders between horizontally adjacent windows. Don't
660 do it for frames with vertical scroll bars because either the
661 right scroll bar of a window, or the left scroll bar of its
662 neighbor will suffice as a border. */
663 if (!WINDOW_RIGHTMOST_P (w
)
664 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
668 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
669 x1
+= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
672 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
673 f
->output_data
.x
->normal_gc
, x1
, y0
, x1
, y1
);
678 /* End update of window W (which is equal to updated_window).
680 Draw vertical borders between horizontally adjacent windows, and
681 display W's cursor if CURSOR_ON_P is non-zero.
683 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
684 glyphs in mouse-face were overwritten. In that case we have to
685 make sure that the mouse-highlight is properly redrawn.
687 W may be a menu bar pseudo-window in case we don't have X toolkit
688 support. Such windows don't have a cursor, so don't display it
692 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
694 int cursor_on_p
, mouse_face_overwritten_p
;
696 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
698 if (!w
->pseudo_window_p
)
703 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
705 output_cursor
.x
, output_cursor
.y
);
707 x_draw_vertical_border (w
);
711 /* If a row with mouse-face was overwritten, arrange for
712 XTframe_up_to_date to redisplay the mouse highlight. */
713 if (mouse_face_overwritten_p
)
715 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
716 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
717 dpyinfo
->mouse_face_window
= Qnil
;
720 updated_window
= NULL
;
724 /* End update of frame F. This function is installed as a hook in
731 /* Mouse highlight may be displayed again. */
732 FRAME_X_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
735 XFlush (FRAME_X_DISPLAY (f
));
740 /* This function is called from various places in xdisp.c whenever a
741 complete update has been performed. The global variable
742 updated_window is not available here. */
745 XTframe_up_to_date (f
)
750 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
752 if (dpyinfo
->mouse_face_deferred_gc
753 || f
== dpyinfo
->mouse_face_mouse_frame
)
756 if (dpyinfo
->mouse_face_mouse_frame
)
757 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
758 dpyinfo
->mouse_face_mouse_x
,
759 dpyinfo
->mouse_face_mouse_y
);
760 dpyinfo
->mouse_face_deferred_gc
= 0;
767 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
768 arrow bitmaps, or clear the fringes if no bitmaps are required
769 before DESIRED_ROW is made current. The window being updated is
770 found in updated_window. This function It is called from
771 update_window_line only if it is known that there are differences
772 between bitmaps to be drawn between current row and DESIRED_ROW. */
775 x_after_update_window_line (desired_row
)
776 struct glyph_row
*desired_row
;
778 struct window
*w
= updated_window
;
784 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
787 x_draw_row_fringe_bitmaps (w
, desired_row
);
791 /* When a window has disappeared, make sure that no rest of
792 full-width rows stays visible in the internal border. Could
793 check here if updated_window is the leftmost/rightmost window,
794 but I guess it's not worth doing since vertically split windows
795 are almost never used, internal border is rarely set, and the
796 overhead is very small. */
797 if (windows_or_buffers_changed
798 && desired_row
->full_width_p
799 && (f
= XFRAME (w
->frame
),
800 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
802 && (height
= desired_row
->visible_height
,
805 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
807 /* Internal border is drawn below the tool bar. */
808 if (WINDOWP (f
->tool_bar_window
)
809 && w
== XWINDOW (f
->tool_bar_window
))
813 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
814 0, y
, width
, height
, False
);
815 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
816 f
->output_data
.x
->pixel_width
- width
,
817 y
, width
, height
, False
);
823 /* Draw the bitmap WHICH in one of the left or right fringes of
824 window W. ROW is the glyph row for which to display the bitmap; it
825 determines the vertical position at which the bitmap has to be
829 x_draw_fringe_bitmap (w
, row
, which
, left_p
)
831 struct glyph_row
*row
;
832 enum fringe_bitmap_type which
;
835 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
836 Display
*display
= FRAME_X_DISPLAY (f
);
837 Window window
= FRAME_X_WINDOW (f
);
842 GC gc
= f
->output_data
.x
->normal_gc
;
844 int depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
846 /* Must clip because of partially visible lines. */
847 x_clip_to_row (w
, row
, gc
, 1);
849 /* Convert row to frame coordinates. */
850 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
854 case NO_FRINGE_BITMAP
:
859 case LEFT_TRUNCATION_BITMAP
:
865 case OVERLAY_ARROW_BITMAP
:
871 case RIGHT_TRUNCATION_BITMAP
:
877 case CONTINUED_LINE_BITMAP
:
878 wd
= continued_width
;
879 h
= continued_height
;
880 bits
= continued_bits
;
883 case CONTINUATION_LINE_BITMAP
:
884 wd
= continuation_width
;
885 h
= continuation_height
;
886 bits
= continuation_bits
;
891 h
= zv_height
- (y
% zv_period
);
892 bits
= zv_bits
+ (y
% zv_period
);
899 /* Clip bitmap if too high. */
903 /* Set dy to the offset in the row to start drawing the bitmap. */
904 dy
= (row
->height
- h
) / 2;
906 face
= FACE_FROM_ID (f
, FRINGE_FACE_ID
);
907 PREPARE_FACE_FOR_DISPLAY (f
, face
);
909 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
914 if (wd
> FRAME_X_LEFT_FRINGE_WIDTH (f
))
915 wd
= FRAME_X_LEFT_FRINGE_WIDTH (f
);
916 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
918 - (FRAME_X_LEFT_FRINGE_WIDTH (f
) - wd
) / 2);
919 if (wd
< FRAME_X_LEFT_FRINGE_WIDTH (f
) || row
->height
> h
)
921 /* If W has a vertical border to its left, don't draw over it. */
922 int border
= ((XFASTINT (w
->left
) > 0
923 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
925 b1
= (window_box_left (w
, -1)
926 - FRAME_X_LEFT_FRINGE_WIDTH (f
)
928 b2
= (FRAME_X_LEFT_FRINGE_WIDTH (f
) - border
);
933 if (wd
> FRAME_X_RIGHT_FRINGE_WIDTH (f
))
934 wd
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
935 x
= (window_box_right (w
, -1)
936 + (FRAME_X_RIGHT_FRINGE_WIDTH (f
) - wd
) / 2);
937 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
939 if (wd
< FRAME_X_RIGHT_FRINGE_WIDTH (f
) || row
->height
> h
)
941 b1
= window_box_right (w
, -1);
942 b2
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
948 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
950 /* In case the same realized face is used for fringes and
951 for something displayed in the text (e.g. face `region' on
952 mono-displays, the fill style may have been changed to
953 FillSolid in x_draw_glyph_string_background. */
955 XSetFillStyle (display
, face
->gc
, FillOpaqueStippled
);
957 XSetForeground (display
, face
->gc
, face
->background
);
959 XFillRectangle (display
, window
, face
->gc
,
961 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
964 row
->visible_height
);
966 XSetForeground (display
, face
->gc
, face
->foreground
);
969 if (which
!= NO_FRINGE_BITMAP
)
971 /* Draw the bitmap. I believe these small pixmaps can be cached
973 pixmap
= XCreatePixmapFromBitmapData (display
, window
, bits
, wd
, h
,
975 face
->background
, depth
);
976 XCopyArea (display
, pixmap
, window
, gc
, 0, 0, wd
, h
, x
, y
+ dy
);
977 XFreePixmap (display
, pixmap
);
980 XSetClipMask (display
, gc
, None
);
984 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
985 function with input blocked. */
988 x_draw_row_fringe_bitmaps (w
, row
)
990 struct glyph_row
*row
;
992 struct frame
*f
= XFRAME (w
->frame
);
993 enum fringe_bitmap_type bitmap
;
995 xassert (interrupt_input_blocked
);
997 /* If row is completely invisible, because of vscrolling, we
998 don't have to draw anything. */
999 if (row
->visible_height
<= 0)
1002 if (FRAME_X_LEFT_FRINGE_WIDTH (f
) != 0)
1004 /* Decide which bitmap to draw in the left fringe. */
1005 if (row
->overlay_arrow_p
)
1006 bitmap
= OVERLAY_ARROW_BITMAP
;
1007 else if (row
->truncated_on_left_p
)
1008 bitmap
= LEFT_TRUNCATION_BITMAP
;
1009 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
1010 bitmap
= CONTINUATION_LINE_BITMAP
;
1011 else if (row
->indicate_empty_line_p
)
1012 bitmap
= ZV_LINE_BITMAP
;
1014 bitmap
= NO_FRINGE_BITMAP
;
1016 x_draw_fringe_bitmap (w
, row
, bitmap
, 1);
1019 if (FRAME_X_RIGHT_FRINGE_WIDTH (f
) != 0)
1021 /* Decide which bitmap to draw in the right fringe. */
1022 if (row
->truncated_on_right_p
)
1023 bitmap
= RIGHT_TRUNCATION_BITMAP
;
1024 else if (row
->continued_p
)
1025 bitmap
= CONTINUED_LINE_BITMAP
;
1026 else if (row
->indicate_empty_line_p
&& FRAME_X_LEFT_FRINGE_WIDTH (f
) == 0)
1027 bitmap
= ZV_LINE_BITMAP
;
1029 bitmap
= NO_FRINGE_BITMAP
;
1031 x_draw_fringe_bitmap (w
, row
, bitmap
, 0);
1037 /* This is called when starting Emacs and when restarting after
1038 suspend. When starting Emacs, no X window is mapped. And nothing
1039 must be done to Emacs's own window if it is suspended (though that
1043 XTset_terminal_modes ()
1047 /* This is called when exiting or suspending Emacs. Exiting will make
1048 the X-windows go away, and suspending requires no action. */
1051 XTreset_terminal_modes ()
1057 /***********************************************************************
1059 ***********************************************************************/
1061 /* Set the global variable output_cursor to CURSOR. All cursor
1062 positions are relative to updated_window. */
1065 set_output_cursor (cursor
)
1066 struct cursor_pos
*cursor
;
1068 output_cursor
.hpos
= cursor
->hpos
;
1069 output_cursor
.vpos
= cursor
->vpos
;
1070 output_cursor
.x
= cursor
->x
;
1071 output_cursor
.y
= cursor
->y
;
1075 /* Set a nominal cursor position.
1077 HPOS and VPOS are column/row positions in a window glyph matrix. X
1078 and Y are window text area relative pixel positions.
1080 If this is done during an update, updated_window will contain the
1081 window that is being updated and the position is the future output
1082 cursor position for that window. If updated_window is null, use
1083 selected_window and display the cursor at the given position. */
1086 XTcursor_to (vpos
, hpos
, y
, x
)
1087 int vpos
, hpos
, y
, x
;
1091 /* If updated_window is not set, work on selected_window. */
1095 w
= XWINDOW (selected_window
);
1097 /* Set the output cursor. */
1098 output_cursor
.hpos
= hpos
;
1099 output_cursor
.vpos
= vpos
;
1100 output_cursor
.x
= x
;
1101 output_cursor
.y
= y
;
1103 /* If not called as part of an update, really display the cursor.
1104 This will also set the cursor position of W. */
1105 if (updated_window
== NULL
)
1108 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1109 XFlush (FRAME_X_DISPLAY (SELECTED_FRAME ()));
1116 /***********************************************************************
1118 ***********************************************************************/
1120 /* Function prototypes of this page. */
1122 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1126 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1127 int, XChar2b
*, int));
1128 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1129 static void x_encode_char
P_ ((int, XChar2b
*, struct font_info
*));
1130 static void x_append_glyph
P_ ((struct it
*));
1131 static void x_append_composite_glyph
P_ ((struct it
*));
1132 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1134 static void x_produce_glyphs
P_ ((struct it
*));
1135 static void x_produce_image_glyph
P_ ((struct it
*it
));
1138 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1139 is not contained in the font. */
1141 static INLINE XCharStruct
*
1142 x_per_char_metric (font
, char2b
)
1146 /* The result metric information. */
1147 XCharStruct
*pcm
= NULL
;
1149 xassert (font
&& char2b
);
1151 if (font
->per_char
!= NULL
)
1153 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1155 /* min_char_or_byte2 specifies the linear character index
1156 corresponding to the first element of the per_char array,
1157 max_char_or_byte2 is the index of the last character. A
1158 character with non-zero CHAR2B->byte1 is not in the font.
1159 A character with byte2 less than min_char_or_byte2 or
1160 greater max_char_or_byte2 is not in the font. */
1161 if (char2b
->byte1
== 0
1162 && char2b
->byte2
>= font
->min_char_or_byte2
1163 && char2b
->byte2
<= font
->max_char_or_byte2
)
1164 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1168 /* If either min_byte1 or max_byte1 are nonzero, both
1169 min_char_or_byte2 and max_char_or_byte2 are less than
1170 256, and the 2-byte character index values corresponding
1171 to the per_char array element N (counting from 0) are:
1173 byte1 = N/D + min_byte1
1174 byte2 = N\D + min_char_or_byte2
1178 D = max_char_or_byte2 - min_char_or_byte2 + 1
1179 / = integer division
1180 \ = integer modulus */
1181 if (char2b
->byte1
>= font
->min_byte1
1182 && char2b
->byte1
<= font
->max_byte1
1183 && char2b
->byte2
>= font
->min_char_or_byte2
1184 && char2b
->byte2
<= font
->max_char_or_byte2
)
1186 pcm
= (font
->per_char
1187 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1188 * (char2b
->byte1
- font
->min_byte1
))
1189 + (char2b
->byte2
- font
->min_char_or_byte2
));
1195 /* If the per_char pointer is null, all glyphs between the first
1196 and last character indexes inclusive have the same
1197 information, as given by both min_bounds and max_bounds. */
1198 if (char2b
->byte2
>= font
->min_char_or_byte2
1199 && char2b
->byte2
<= font
->max_char_or_byte2
)
1200 pcm
= &font
->max_bounds
;
1203 return ((pcm
== NULL
1204 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1209 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1210 the two-byte form of C. Encoding is returned in *CHAR2B. */
1213 x_encode_char (c
, char2b
, font_info
)
1216 struct font_info
*font_info
;
1218 int charset
= CHAR_CHARSET (c
);
1219 XFontStruct
*font
= font_info
->font
;
1221 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1222 This may be either a program in a special encoder language or a
1224 if (font_info
->font_encoder
)
1226 /* It's a program. */
1227 struct ccl_program
*ccl
= font_info
->font_encoder
;
1229 if (CHARSET_DIMENSION (charset
) == 1)
1231 ccl
->reg
[0] = charset
;
1232 ccl
->reg
[1] = char2b
->byte2
;
1236 ccl
->reg
[0] = charset
;
1237 ccl
->reg
[1] = char2b
->byte1
;
1238 ccl
->reg
[2] = char2b
->byte2
;
1241 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1243 /* We assume that MSBs are appropriately set/reset by CCL
1245 if (font
->max_byte1
== 0) /* 1-byte font */
1246 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1248 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1250 else if (font_info
->encoding
[charset
])
1252 /* Fixed encoding scheme. See fontset.h for the meaning of the
1253 encoding numbers. */
1254 int enc
= font_info
->encoding
[charset
];
1256 if ((enc
== 1 || enc
== 2)
1257 && CHARSET_DIMENSION (charset
) == 2)
1258 char2b
->byte1
|= 0x80;
1260 if (enc
== 1 || enc
== 3)
1261 char2b
->byte2
|= 0x80;
1266 /* Get face and two-byte form of character C in face FACE_ID on frame
1267 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1268 means we want to display multibyte text. Value is a pointer to a
1269 realized face that is ready for display. */
1271 static INLINE
struct face
*
1272 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1278 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1282 /* Unibyte case. We don't have to encode, but we have to make
1283 sure to use a face suitable for unibyte. */
1286 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1287 face
= FACE_FROM_ID (f
, face_id
);
1289 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1291 /* Case of ASCII in a face known to fit ASCII. */
1297 int c1
, c2
, charset
;
1299 /* Split characters into bytes. If c2 is -1 afterwards, C is
1300 really a one-byte character so that byte1 is zero. */
1301 SPLIT_CHAR (c
, charset
, c1
, c2
);
1303 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1305 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1307 /* Maybe encode the character in *CHAR2B. */
1308 if (face
->font
!= NULL
)
1310 struct font_info
*font_info
1311 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1313 x_encode_char (c
, char2b
, font_info
);
1317 /* Make sure X resources of the face are allocated. */
1318 xassert (face
!= NULL
);
1319 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1325 /* Get face and two-byte form of character glyph GLYPH on frame F.
1326 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1327 a pointer to a realized face that is ready for display. */
1329 static INLINE
struct face
*
1330 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1332 struct glyph
*glyph
;
1338 xassert (glyph
->type
== CHAR_GLYPH
);
1339 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1344 if (!glyph
->multibyte_p
)
1346 /* Unibyte case. We don't have to encode, but we have to make
1347 sure to use a face suitable for unibyte. */
1349 char2b
->byte2
= glyph
->u
.ch
;
1351 else if (glyph
->u
.ch
< 128
1352 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1354 /* Case of ASCII in a face known to fit ASCII. */
1356 char2b
->byte2
= glyph
->u
.ch
;
1360 int c1
, c2
, charset
;
1362 /* Split characters into bytes. If c2 is -1 afterwards, C is
1363 really a one-byte character so that byte1 is zero. */
1364 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1366 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1368 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1370 /* Maybe encode the character in *CHAR2B. */
1371 if (charset
!= CHARSET_ASCII
)
1373 struct font_info
*font_info
1374 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1377 x_encode_char (glyph
->u
.ch
, char2b
, font_info
);
1380 = ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
1385 /* Make sure X resources of the face are allocated. */
1386 xassert (face
!= NULL
);
1387 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1392 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1393 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1399 struct glyph
*glyph
;
1400 enum glyph_row_area area
= it
->area
;
1402 xassert (it
->glyph_row
);
1403 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1405 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1406 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1408 glyph
->charpos
= CHARPOS (it
->position
);
1409 glyph
->object
= it
->object
;
1410 glyph
->pixel_width
= it
->pixel_width
;
1411 glyph
->voffset
= it
->voffset
;
1412 glyph
->type
= CHAR_GLYPH
;
1413 glyph
->multibyte_p
= it
->multibyte_p
;
1414 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1415 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1416 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1417 || it
->phys_descent
> it
->descent
);
1418 glyph
->padding_p
= 0;
1419 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1420 glyph
->face_id
= it
->face_id
;
1421 glyph
->u
.ch
= it
->char_to_display
;
1422 ++it
->glyph_row
->used
[area
];
1426 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1427 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1430 x_append_composite_glyph (it
)
1433 struct glyph
*glyph
;
1434 enum glyph_row_area area
= it
->area
;
1436 xassert (it
->glyph_row
);
1438 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1439 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1441 glyph
->charpos
= CHARPOS (it
->position
);
1442 glyph
->object
= it
->object
;
1443 glyph
->pixel_width
= it
->pixel_width
;
1444 glyph
->voffset
= it
->voffset
;
1445 glyph
->type
= COMPOSITE_GLYPH
;
1446 glyph
->multibyte_p
= it
->multibyte_p
;
1447 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1448 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1449 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1450 || it
->phys_descent
> it
->descent
);
1451 glyph
->padding_p
= 0;
1452 glyph
->glyph_not_available_p
= 0;
1453 glyph
->face_id
= it
->face_id
;
1454 glyph
->u
.cmp_id
= it
->cmp_id
;
1455 ++it
->glyph_row
->used
[area
];
1460 /* Change IT->ascent and IT->height according to the setting of
1464 take_vertical_position_into_account (it
)
1469 if (it
->voffset
< 0)
1470 /* Increase the ascent so that we can display the text higher
1472 it
->ascent
+= abs (it
->voffset
);
1474 /* Increase the descent so that we can display the text lower
1476 it
->descent
+= it
->voffset
;
1481 /* Produce glyphs/get display metrics for the image IT is loaded with.
1482 See the description of struct display_iterator in dispextern.h for
1483 an overview of struct display_iterator. */
1486 x_produce_image_glyph (it
)
1492 xassert (it
->what
== IT_IMAGE
);
1494 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1495 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1498 /* Make sure X resources of the face and image are loaded. */
1499 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1500 prepare_image_for_display (it
->f
, img
);
1502 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
1503 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
1504 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
1508 if (face
->box
!= FACE_NO_BOX
)
1510 if (face
->box_line_width
> 0)
1512 it
->ascent
+= face
->box_line_width
;
1513 it
->descent
+= face
->box_line_width
;
1516 if (it
->start_of_box_run_p
)
1517 it
->pixel_width
+= abs (face
->box_line_width
);
1518 if (it
->end_of_box_run_p
)
1519 it
->pixel_width
+= abs (face
->box_line_width
);
1522 take_vertical_position_into_account (it
);
1526 struct glyph
*glyph
;
1527 enum glyph_row_area area
= it
->area
;
1529 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1530 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1532 glyph
->charpos
= CHARPOS (it
->position
);
1533 glyph
->object
= it
->object
;
1534 glyph
->pixel_width
= it
->pixel_width
;
1535 glyph
->voffset
= it
->voffset
;
1536 glyph
->type
= IMAGE_GLYPH
;
1537 glyph
->multibyte_p
= it
->multibyte_p
;
1538 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1539 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1540 glyph
->overlaps_vertically_p
= 0;
1541 glyph
->padding_p
= 0;
1542 glyph
->glyph_not_available_p
= 0;
1543 glyph
->face_id
= it
->face_id
;
1544 glyph
->u
.img_id
= img
->id
;
1545 ++it
->glyph_row
->used
[area
];
1551 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1552 of the glyph, WIDTH and HEIGHT are the width and height of the
1553 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1554 ascent of the glyph (0 <= ASCENT <= 1). */
1557 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1563 struct glyph
*glyph
;
1564 enum glyph_row_area area
= it
->area
;
1566 xassert (ascent
>= 0 && ascent
<= 1);
1568 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1569 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1571 glyph
->charpos
= CHARPOS (it
->position
);
1572 glyph
->object
= object
;
1573 glyph
->pixel_width
= width
;
1574 glyph
->voffset
= it
->voffset
;
1575 glyph
->type
= STRETCH_GLYPH
;
1576 glyph
->multibyte_p
= it
->multibyte_p
;
1577 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1578 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1579 glyph
->overlaps_vertically_p
= 0;
1580 glyph
->padding_p
= 0;
1581 glyph
->glyph_not_available_p
= 0;
1582 glyph
->face_id
= it
->face_id
;
1583 glyph
->u
.stretch
.ascent
= height
* ascent
;
1584 glyph
->u
.stretch
.height
= height
;
1585 ++it
->glyph_row
->used
[area
];
1590 /* Produce a stretch glyph for iterator IT. IT->object is the value
1591 of the glyph property displayed. The value must be a list
1592 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1595 1. `:width WIDTH' specifies that the space should be WIDTH *
1596 canonical char width wide. WIDTH may be an integer or floating
1599 2. `:relative-width FACTOR' specifies that the width of the stretch
1600 should be computed from the width of the first character having the
1601 `glyph' property, and should be FACTOR times that width.
1603 3. `:align-to HPOS' specifies that the space should be wide enough
1604 to reach HPOS, a value in canonical character units.
1606 Exactly one of the above pairs must be present.
1608 4. `:height HEIGHT' specifies that the height of the stretch produced
1609 should be HEIGHT, measured in canonical character units.
1611 5. `:relative-height FACTOR' specifies that the height of the
1612 stretch should be FACTOR times the height of the characters having
1615 Either none or exactly one of 4 or 5 must be present.
1617 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1618 of the stretch should be used for the ascent of the stretch.
1619 ASCENT must be in the range 0 <= ASCENT <= 100. */
1622 ((INTEGERP (X) || FLOATP (X)) \
1628 x_produce_stretch_glyph (it
)
1631 /* (space :width WIDTH :height HEIGHT. */
1633 extern Lisp_Object Qspace
;
1635 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
1636 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1637 extern Lisp_Object QCalign_to
;
1638 Lisp_Object prop
, plist
;
1639 double width
= 0, height
= 0, ascent
= 0;
1640 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1641 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1643 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1645 /* List should start with `space'. */
1646 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1647 plist
= XCDR (it
->object
);
1649 /* Compute the width of the stretch. */
1650 if (prop
= Fplist_get (plist
, QCwidth
),
1652 /* Absolute width `:width WIDTH' specified and valid. */
1653 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1654 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1657 /* Relative width `:relative-width FACTOR' specified and valid.
1658 Compute the width of the characters having the `glyph'
1661 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1664 if (it
->multibyte_p
)
1666 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1667 - IT_BYTEPOS (*it
));
1668 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1671 it2
.c
= *p
, it2
.len
= 1;
1673 it2
.glyph_row
= NULL
;
1674 it2
.what
= IT_CHARACTER
;
1675 x_produce_glyphs (&it2
);
1676 width
= NUMVAL (prop
) * it2
.pixel_width
;
1678 else if (prop
= Fplist_get (plist
, QCalign_to
),
1680 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1682 /* Nothing specified -> width defaults to canonical char width. */
1683 width
= CANON_X_UNIT (it
->f
);
1685 /* Compute height. */
1686 if (prop
= Fplist_get (plist
, QCheight
),
1688 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1689 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1691 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1693 height
= FONT_HEIGHT (font
);
1695 /* Compute percentage of height used for ascent. If
1696 `:ascent ASCENT' is present and valid, use that. Otherwise,
1697 derive the ascent from the font in use. */
1698 if (prop
= Fplist_get (plist
, QCascent
),
1699 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1700 ascent
= NUMVAL (prop
) / 100.0;
1702 ascent
= (double) font
->ascent
/ FONT_HEIGHT (font
);
1711 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1712 if (!STRINGP (object
))
1713 object
= it
->w
->buffer
;
1714 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1717 it
->pixel_width
= width
;
1718 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1719 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1722 if (face
->box
!= FACE_NO_BOX
)
1724 if (face
->box_line_width
> 0)
1726 it
->ascent
+= face
->box_line_width
;
1727 it
->descent
+= face
->box_line_width
;
1730 if (it
->start_of_box_run_p
)
1731 it
->pixel_width
+= abs (face
->box_line_width
);
1732 if (it
->end_of_box_run_p
)
1733 it
->pixel_width
+= abs (face
->box_line_width
);
1736 take_vertical_position_into_account (it
);
1739 /* Return proper value to be used as baseline offset of font that has
1740 ASCENT and DESCENT to draw characters by the font at the vertical
1741 center of the line of frame F.
1743 Here, out task is to find the value of BOFF in the following figure;
1745 -------------------------+-----------+-
1746 -+-+---------+-+ | |
1748 | | | | F_ASCENT F_HEIGHT
1751 | | |-|-+------+-----------|------- baseline
1753 | |---------|-+-+ | |
1755 -+-+---------+-+ F_DESCENT |
1756 -------------------------+-----------+-
1758 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1759 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1760 DESCENT = FONT->descent
1761 HEIGHT = FONT_HEIGHT (FONT)
1762 F_DESCENT = (F->output_data.x->font->descent
1763 - F->output_data.x->baseline_offset)
1764 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1767 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1769 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
1770 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
1771 - ((F)->output_data.x->font->descent - (F)->output_data.x->baseline_offset))
1773 /* Produce glyphs/get display metrics for the display element IT is
1774 loaded with. See the description of struct display_iterator in
1775 dispextern.h for an overview of struct display_iterator. */
1778 x_produce_glyphs (it
)
1781 it
->glyph_not_available_p
= 0;
1783 if (it
->what
== IT_CHARACTER
)
1787 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1789 int font_not_found_p
;
1790 struct font_info
*font_info
;
1791 int boff
; /* baseline offset */
1792 /* We may change it->multibyte_p upon unibyte<->multibyte
1793 conversion. So, save the current value now and restore it
1796 Note: It seems that we don't have to record multibyte_p in
1797 struct glyph because the character code itself tells if or
1798 not the character is multibyte. Thus, in the future, we must
1799 consider eliminating the field `multibyte_p' in the struct
1801 int saved_multibyte_p
= it
->multibyte_p
;
1803 /* Maybe translate single-byte characters to multibyte, or the
1805 it
->char_to_display
= it
->c
;
1806 if (!ASCII_BYTE_P (it
->c
))
1808 if (unibyte_display_via_language_environment
1809 && SINGLE_BYTE_CHAR_P (it
->c
)
1811 || !NILP (Vnonascii_translation_table
)))
1813 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1814 it
->multibyte_p
= 1;
1815 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1816 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1818 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
1819 && !it
->multibyte_p
)
1821 it
->multibyte_p
= 1;
1822 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1823 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1827 /* Get font to use. Encode IT->char_to_display. */
1828 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
1829 it
->face_id
, &char2b
,
1833 /* When no suitable font found, use the default font. */
1834 font_not_found_p
= font
== NULL
;
1835 if (font_not_found_p
)
1837 font
= FRAME_FONT (it
->f
);
1838 boff
= it
->f
->output_data
.x
->baseline_offset
;
1843 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
1844 boff
= font_info
->baseline_offset
;
1845 if (font_info
->vertical_centering
)
1846 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
1849 if (it
->char_to_display
>= ' '
1850 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
1852 /* Either unibyte or ASCII. */
1857 pcm
= x_per_char_metric (font
, &char2b
);
1858 it
->ascent
= font
->ascent
+ boff
;
1859 it
->descent
= font
->descent
- boff
;
1863 it
->phys_ascent
= pcm
->ascent
+ boff
;
1864 it
->phys_descent
= pcm
->descent
- boff
;
1865 it
->pixel_width
= pcm
->width
;
1869 it
->glyph_not_available_p
= 1;
1870 it
->phys_ascent
= font
->ascent
+ boff
;
1871 it
->phys_descent
= font
->descent
- boff
;
1872 it
->pixel_width
= FONT_WIDTH (font
);
1875 /* If this is a space inside a region of text with
1876 `space-width' property, change its width. */
1877 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
1879 it
->pixel_width
*= XFLOATINT (it
->space_width
);
1881 /* If face has a box, add the box thickness to the character
1882 height. If character has a box line to the left and/or
1883 right, add the box line width to the character's width. */
1884 if (face
->box
!= FACE_NO_BOX
)
1886 int thick
= face
->box_line_width
;
1890 it
->ascent
+= thick
;
1891 it
->descent
+= thick
;
1896 if (it
->start_of_box_run_p
)
1897 it
->pixel_width
+= thick
;
1898 if (it
->end_of_box_run_p
)
1899 it
->pixel_width
+= thick
;
1902 /* If face has an overline, add the height of the overline
1903 (1 pixel) and a 1 pixel margin to the character height. */
1904 if (face
->overline_p
)
1907 take_vertical_position_into_account (it
);
1909 /* If we have to actually produce glyphs, do it. */
1914 /* Translate a space with a `space-width' property
1915 into a stretch glyph. */
1916 double ascent
= (double) font
->ascent
/ FONT_HEIGHT (font
);
1917 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1918 it
->ascent
+ it
->descent
, ascent
);
1921 x_append_glyph (it
);
1923 /* If characters with lbearing or rbearing are displayed
1924 in this line, record that fact in a flag of the
1925 glyph row. This is used to optimize X output code. */
1926 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
1927 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
1930 else if (it
->char_to_display
== '\n')
1932 /* A newline has no width but we need the height of the line. */
1933 it
->pixel_width
= 0;
1935 it
->ascent
= it
->phys_ascent
= font
->ascent
+ boff
;
1936 it
->descent
= it
->phys_descent
= font
->descent
- boff
;
1938 if (face
->box
!= FACE_NO_BOX
1939 && face
->box_line_width
> 0)
1941 it
->ascent
+= face
->box_line_width
;
1942 it
->descent
+= face
->box_line_width
;
1945 else if (it
->char_to_display
== '\t')
1947 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
1948 int x
= it
->current_x
+ it
->continuation_lines_width
;
1949 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
1951 /* If the distance from the current position to the next tab
1952 stop is less than a canonical character width, use the
1953 tab stop after that. */
1954 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
1955 next_tab_x
+= tab_width
;
1957 it
->pixel_width
= next_tab_x
- x
;
1959 it
->ascent
= it
->phys_ascent
= font
->ascent
+ boff
;
1960 it
->descent
= it
->phys_descent
= font
->descent
- boff
;
1964 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
1965 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1966 it
->ascent
+ it
->descent
, ascent
);
1971 /* A multi-byte character. Assume that the display width of the
1972 character is the width of the character multiplied by the
1973 width of the font. */
1975 /* If we found a font, this font should give us the right
1976 metrics. If we didn't find a font, use the frame's
1977 default font and calculate the width of the character
1978 from the charset width; this is what old redisplay code
1980 pcm
= x_per_char_metric (font
, &char2b
);
1981 if (font_not_found_p
|| !pcm
)
1983 int charset
= CHAR_CHARSET (it
->char_to_display
);
1985 it
->glyph_not_available_p
= 1;
1986 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
1987 * CHARSET_WIDTH (charset
));
1988 it
->phys_ascent
= font
->ascent
+ boff
;
1989 it
->phys_descent
= font
->descent
- boff
;
1993 it
->pixel_width
= pcm
->width
;
1994 it
->phys_ascent
= pcm
->ascent
+ boff
;
1995 it
->phys_descent
= pcm
->descent
- boff
;
1997 && (pcm
->lbearing
< 0
1998 || pcm
->rbearing
> pcm
->width
))
1999 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2002 it
->ascent
= font
->ascent
+ boff
;
2003 it
->descent
= font
->descent
- boff
;
2004 if (face
->box
!= FACE_NO_BOX
)
2006 int thick
= face
->box_line_width
;
2010 it
->ascent
+= thick
;
2011 it
->descent
+= thick
;
2016 if (it
->start_of_box_run_p
)
2017 it
->pixel_width
+= thick
;
2018 if (it
->end_of_box_run_p
)
2019 it
->pixel_width
+= thick
;
2022 /* If face has an overline, add the height of the overline
2023 (1 pixel) and a 1 pixel margin to the character height. */
2024 if (face
->overline_p
)
2027 take_vertical_position_into_account (it
);
2030 x_append_glyph (it
);
2032 it
->multibyte_p
= saved_multibyte_p
;
2034 else if (it
->what
== IT_COMPOSITION
)
2036 /* Note: A composition is represented as one glyph in the
2037 glyph matrix. There are no padding glyphs. */
2040 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2042 int font_not_found_p
;
2043 struct font_info
*font_info
;
2044 int boff
; /* baseline offset */
2045 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2047 /* Maybe translate single-byte characters to multibyte. */
2048 it
->char_to_display
= it
->c
;
2049 if (unibyte_display_via_language_environment
2050 && SINGLE_BYTE_CHAR_P (it
->c
)
2053 && !NILP (Vnonascii_translation_table
))))
2055 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2058 /* Get face and font to use. Encode IT->char_to_display. */
2059 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2060 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2061 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2062 it
->face_id
, &char2b
, it
->multibyte_p
);
2065 /* When no suitable font found, use the default font. */
2066 font_not_found_p
= font
== NULL
;
2067 if (font_not_found_p
)
2069 font
= FRAME_FONT (it
->f
);
2070 boff
= it
->f
->output_data
.x
->baseline_offset
;
2075 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2076 boff
= font_info
->baseline_offset
;
2077 if (font_info
->vertical_centering
)
2078 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2081 /* There are no padding glyphs, so there is only one glyph to
2082 produce for the composition. Important is that pixel_width,
2083 ascent and descent are the values of what is drawn by
2084 draw_glyphs (i.e. the values of the overall glyphs composed). */
2087 /* If we have not yet calculated pixel size data of glyphs of
2088 the composition for the current face font, calculate them
2089 now. Theoretically, we have to check all fonts for the
2090 glyphs, but that requires much time and memory space. So,
2091 here we check only the font of the first glyph. This leads
2092 to incorrect display very rarely, and C-l (recenter) can
2093 correct the display anyway. */
2094 if (cmp
->font
!= (void *) font
)
2096 /* Ascent and descent of the font of the first character of
2097 this composition (adjusted by baseline offset). Ascent
2098 and descent of overall glyphs should not be less than
2099 them respectively. */
2100 int font_ascent
= font
->ascent
+ boff
;
2101 int font_descent
= font
->descent
- boff
;
2102 /* Bounding box of the overall glyphs. */
2103 int leftmost
, rightmost
, lowest
, highest
;
2104 int i
, width
, ascent
, descent
;
2106 cmp
->font
= (void *) font
;
2108 /* Initialize the bounding box. */
2110 && (pcm
= x_per_char_metric (font
, &char2b
)))
2113 ascent
= pcm
->ascent
;
2114 descent
= pcm
->descent
;
2118 width
= FONT_WIDTH (font
);
2119 ascent
= font
->ascent
;
2120 descent
= font
->descent
;
2124 lowest
= - descent
+ boff
;
2125 highest
= ascent
+ boff
;
2129 && font_info
->default_ascent
2130 && CHAR_TABLE_P (Vuse_default_ascent
)
2131 && !NILP (Faref (Vuse_default_ascent
,
2132 make_number (it
->char_to_display
))))
2133 highest
= font_info
->default_ascent
+ boff
;
2135 /* Draw the first glyph at the normal position. It may be
2136 shifted to right later if some other glyphs are drawn at
2138 cmp
->offsets
[0] = 0;
2139 cmp
->offsets
[1] = boff
;
2141 /* Set cmp->offsets for the remaining glyphs. */
2142 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2144 int left
, right
, btm
, top
;
2145 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2146 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2148 face
= FACE_FROM_ID (it
->f
, face_id
);
2149 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2154 font
= FRAME_FONT (it
->f
);
2155 boff
= it
->f
->output_data
.x
->baseline_offset
;
2161 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2162 boff
= font_info
->baseline_offset
;
2163 if (font_info
->vertical_centering
)
2164 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2168 && (pcm
= x_per_char_metric (font
, &char2b
)))
2171 ascent
= pcm
->ascent
;
2172 descent
= pcm
->descent
;
2176 width
= FONT_WIDTH (font
);
2181 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2183 /* Relative composition with or without
2185 left
= (leftmost
+ rightmost
- width
) / 2;
2186 btm
= - descent
+ boff
;
2187 if (font_info
&& font_info
->relative_compose
2188 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2189 || NILP (Faref (Vignore_relative_composition
,
2190 make_number (ch
)))))
2193 if (- descent
>= font_info
->relative_compose
)
2194 /* One extra pixel between two glyphs. */
2196 else if (ascent
<= 0)
2197 /* One extra pixel between two glyphs. */
2198 btm
= lowest
- 1 - ascent
- descent
;
2203 /* A composition rule is specified by an integer
2204 value that encodes global and new reference
2205 points (GREF and NREF). GREF and NREF are
2206 specified by numbers as below:
2214 ---3---4---5--- baseline
2216 6---7---8 -- descent
2218 int rule
= COMPOSITION_RULE (cmp
, i
);
2219 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2221 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2222 grefx
= gref
% 3, nrefx
= nref
% 3;
2223 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2226 + grefx
* (rightmost
- leftmost
) / 2
2227 - nrefx
* width
/ 2);
2228 btm
= ((grefy
== 0 ? highest
2230 : grefy
== 2 ? lowest
2231 : (highest
+ lowest
) / 2)
2232 - (nrefy
== 0 ? ascent
+ descent
2233 : nrefy
== 1 ? descent
- boff
2235 : (ascent
+ descent
) / 2));
2238 cmp
->offsets
[i
* 2] = left
;
2239 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2241 /* Update the bounding box of the overall glyphs. */
2242 right
= left
+ width
;
2243 top
= btm
+ descent
+ ascent
;
2244 if (left
< leftmost
)
2246 if (right
> rightmost
)
2254 /* If there are glyphs whose x-offsets are negative,
2255 shift all glyphs to the right and make all x-offsets
2259 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2260 cmp
->offsets
[i
* 2] -= leftmost
;
2261 rightmost
-= leftmost
;
2264 cmp
->pixel_width
= rightmost
;
2265 cmp
->ascent
= highest
;
2266 cmp
->descent
= - lowest
;
2267 if (cmp
->ascent
< font_ascent
)
2268 cmp
->ascent
= font_ascent
;
2269 if (cmp
->descent
< font_descent
)
2270 cmp
->descent
= font_descent
;
2273 it
->pixel_width
= cmp
->pixel_width
;
2274 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2275 it
->descent
= it
->phys_descent
= cmp
->descent
;
2277 if (face
->box
!= FACE_NO_BOX
)
2279 int thick
= face
->box_line_width
;
2283 it
->ascent
+= thick
;
2284 it
->descent
+= thick
;
2289 if (it
->start_of_box_run_p
)
2290 it
->pixel_width
+= thick
;
2291 if (it
->end_of_box_run_p
)
2292 it
->pixel_width
+= thick
;
2295 /* If face has an overline, add the height of the overline
2296 (1 pixel) and a 1 pixel margin to the character height. */
2297 if (face
->overline_p
)
2300 take_vertical_position_into_account (it
);
2303 x_append_composite_glyph (it
);
2305 else if (it
->what
== IT_IMAGE
)
2306 x_produce_image_glyph (it
);
2307 else if (it
->what
== IT_STRETCH
)
2308 x_produce_stretch_glyph (it
);
2310 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2311 because this isn't true for images with `:ascent 100'. */
2312 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
2313 if (it
->area
== TEXT_AREA
)
2314 it
->current_x
+= it
->pixel_width
;
2316 it
->descent
+= it
->extra_line_spacing
;
2318 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2319 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2320 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2321 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2325 /* Estimate the pixel height of the mode or top line on frame F.
2326 FACE_ID specifies what line's height to estimate. */
2329 x_estimate_mode_line_height (f
, face_id
)
2331 enum face_id face_id
;
2333 int height
= FONT_HEIGHT (FRAME_FONT (f
));
2335 /* This function is called so early when Emacs starts that the face
2336 cache and mode line face are not yet initialized. */
2337 if (FRAME_FACE_CACHE (f
))
2339 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2343 height
= FONT_HEIGHT (face
->font
);
2344 if (face
->box_line_width
> 0)
2345 height
+= 2 * face
->box_line_width
;
2353 /***********************************************************************
2355 ***********************************************************************/
2357 /* A sequence of glyphs to be drawn in the same face.
2359 This data structure is not really completely X specific, so it
2360 could possibly, at least partially, be useful for other systems. It
2361 is currently not part of the external redisplay interface because
2362 it's not clear what other systems will need. */
2366 /* X-origin of the string. */
2369 /* Y-origin and y-position of the base line of this string. */
2372 /* The width of the string, not including a face extension. */
2375 /* The width of the string, including a face extension. */
2376 int background_width
;
2378 /* The height of this string. This is the height of the line this
2379 string is drawn in, and can be different from the height of the
2380 font the string is drawn in. */
2383 /* Number of pixels this string overwrites in front of its x-origin.
2384 This number is zero if the string has an lbearing >= 0; it is
2385 -lbearing, if the string has an lbearing < 0. */
2388 /* Number of pixels this string overwrites past its right-most
2389 nominal x-position, i.e. x + width. Zero if the string's
2390 rbearing is <= its nominal width, rbearing - width otherwise. */
2393 /* The frame on which the glyph string is drawn. */
2396 /* The window on which the glyph string is drawn. */
2399 /* X display and window for convenience. */
2403 /* The glyph row for which this string was built. It determines the
2404 y-origin and height of the string. */
2405 struct glyph_row
*row
;
2407 /* The area within row. */
2408 enum glyph_row_area area
;
2410 /* Characters to be drawn, and number of characters. */
2414 /* A face-override for drawing cursors, mouse face and similar. */
2415 enum draw_glyphs_face hl
;
2417 /* Face in which this string is to be drawn. */
2420 /* Font in which this string is to be drawn. */
2423 /* Font info for this string. */
2424 struct font_info
*font_info
;
2426 /* Non-null means this string describes (part of) a composition.
2427 All characters from char2b are drawn composed. */
2428 struct composition
*cmp
;
2430 /* Index of this glyph string's first character in the glyph
2431 definition of CMP. If this is zero, this glyph string describes
2432 the first character of a composition. */
2435 /* 1 means this glyph strings face has to be drawn to the right end
2436 of the window's drawing area. */
2437 unsigned extends_to_end_of_line_p
: 1;
2439 /* 1 means the background of this string has been drawn. */
2440 unsigned background_filled_p
: 1;
2442 /* 1 means glyph string must be drawn with 16-bit functions. */
2443 unsigned two_byte_p
: 1;
2445 /* 1 means that the original font determined for drawing this glyph
2446 string could not be loaded. The member `font' has been set to
2447 the frame's default font in this case. */
2448 unsigned font_not_found_p
: 1;
2450 /* 1 means that the face in which this glyph string is drawn has a
2452 unsigned stippled_p
: 1;
2454 /* 1 means only the foreground of this glyph string must be drawn,
2455 and we should use the physical height of the line this glyph
2456 string appears in as clip rect. */
2457 unsigned for_overlaps_p
: 1;
2459 /* The GC to use for drawing this glyph string. */
2462 /* A pointer to the first glyph in the string. This glyph
2463 corresponds to char2b[0]. Needed to draw rectangles if
2464 font_not_found_p is 1. */
2465 struct glyph
*first_glyph
;
2467 /* Image, if any. */
2470 struct glyph_string
*next
, *prev
;
2477 x_dump_glyph_string (s
)
2478 struct glyph_string
*s
;
2480 fprintf (stderr
, "glyph string\n");
2481 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2482 s
->x
, s
->y
, s
->width
, s
->height
);
2483 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2484 fprintf (stderr
, " hl = %d\n", s
->hl
);
2485 fprintf (stderr
, " left overhang = %d, right = %d\n",
2486 s
->left_overhang
, s
->right_overhang
);
2487 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2488 fprintf (stderr
, " extends to end of line = %d\n",
2489 s
->extends_to_end_of_line_p
);
2490 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2491 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2494 #endif /* GLYPH_DEBUG */
2498 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2499 struct glyph_string
**,
2500 struct glyph_string
*,
2501 struct glyph_string
*));
2502 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2503 struct glyph_string
**,
2504 struct glyph_string
*,
2505 struct glyph_string
*));
2506 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2507 struct glyph_string
**,
2508 struct glyph_string
*));
2509 static int x_left_overwritten
P_ ((struct glyph_string
*));
2510 static int x_left_overwriting
P_ ((struct glyph_string
*));
2511 static int x_right_overwritten
P_ ((struct glyph_string
*));
2512 static int x_right_overwriting
P_ ((struct glyph_string
*));
2513 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int, int,
2515 static void x_init_glyph_string
P_ ((struct glyph_string
*,
2516 XChar2b
*, struct window
*,
2518 enum glyph_row_area
, int,
2519 enum draw_glyphs_face
));
2520 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2521 enum glyph_row_area
, int, int,
2522 enum draw_glyphs_face
, int));
2523 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2524 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2525 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2527 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2528 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2529 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2530 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2531 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2532 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2533 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2534 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2535 static void x_get_glyph_overhangs
P_ ((struct glyph
*, struct frame
*,
2537 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2538 static int x_alloc_lighter_color
P_ ((struct frame
*, Display
*, Colormap
,
2539 unsigned long *, double, int));
2540 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2541 double, int, unsigned long));
2542 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2543 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2544 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2545 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2546 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
2547 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2548 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2550 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2551 int, int, int, int, XRectangle
*));
2552 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2553 int, int, int, XRectangle
*));
2554 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2555 enum glyph_row_area
));
2556 static int x_fill_stretch_glyph_string
P_ ((struct glyph_string
*,
2558 enum glyph_row_area
, int, int));
2561 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
2565 /* Append the list of glyph strings with head H and tail T to the list
2566 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2569 x_append_glyph_string_lists (head
, tail
, h
, t
)
2570 struct glyph_string
**head
, **tail
;
2571 struct glyph_string
*h
, *t
;
2585 /* Prepend the list of glyph strings with head H and tail T to the
2586 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2590 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2591 struct glyph_string
**head
, **tail
;
2592 struct glyph_string
*h
, *t
;
2606 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2607 Set *HEAD and *TAIL to the resulting list. */
2610 x_append_glyph_string (head
, tail
, s
)
2611 struct glyph_string
**head
, **tail
;
2612 struct glyph_string
*s
;
2614 s
->next
= s
->prev
= NULL
;
2615 x_append_glyph_string_lists (head
, tail
, s
, s
);
2619 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2624 struct glyph_string
*s
;
2626 if (s
->font
== FRAME_FONT (s
->f
)
2627 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2628 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2630 s
->gc
= s
->f
->output_data
.x
->cursor_gc
;
2633 /* Cursor on non-default face: must merge. */
2637 xgcv
.background
= s
->f
->output_data
.x
->cursor_pixel
;
2638 xgcv
.foreground
= s
->face
->background
;
2640 /* If the glyph would be invisible, try a different foreground. */
2641 if (xgcv
.foreground
== xgcv
.background
)
2642 xgcv
.foreground
= s
->face
->foreground
;
2643 if (xgcv
.foreground
== xgcv
.background
)
2644 xgcv
.foreground
= s
->f
->output_data
.x
->cursor_foreground_pixel
;
2645 if (xgcv
.foreground
== xgcv
.background
)
2646 xgcv
.foreground
= s
->face
->foreground
;
2648 /* Make sure the cursor is distinct from text in this face. */
2649 if (xgcv
.background
== s
->face
->background
2650 && xgcv
.foreground
== s
->face
->foreground
)
2652 xgcv
.background
= s
->face
->foreground
;
2653 xgcv
.foreground
= s
->face
->background
;
2656 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2657 xgcv
.font
= s
->font
->fid
;
2658 xgcv
.graphics_exposures
= False
;
2659 mask
= GCForeground
| GCBackground
| GCFont
| GCGraphicsExposures
;
2661 if (FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2662 XChangeGC (s
->display
, FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2665 FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2666 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
2668 s
->gc
= FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2673 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2676 x_set_mouse_face_gc (s
)
2677 struct glyph_string
*s
;
2682 /* What face has to be used last for the mouse face? */
2683 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2684 face
= FACE_FROM_ID (s
->f
, face_id
);
2686 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
2688 if (s
->first_glyph
->type
== CHAR_GLYPH
)
2689 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2691 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
2692 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2693 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2695 /* If font in this face is same as S->font, use it. */
2696 if (s
->font
== s
->face
->font
)
2697 s
->gc
= s
->face
->gc
;
2700 /* Otherwise construct scratch_cursor_gc with values from FACE
2705 xgcv
.background
= s
->face
->background
;
2706 xgcv
.foreground
= s
->face
->foreground
;
2707 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2708 xgcv
.font
= s
->font
->fid
;
2709 xgcv
.graphics_exposures
= False
;
2710 mask
= GCForeground
| GCBackground
| GCFont
| GCGraphicsExposures
;
2712 if (FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2713 XChangeGC (s
->display
, FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2716 FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2717 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
2719 s
->gc
= FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2722 xassert (s
->gc
!= 0);
2726 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2727 Faces to use in the mode line have already been computed when the
2728 matrix was built, so there isn't much to do, here. */
2731 x_set_mode_line_face_gc (s
)
2732 struct glyph_string
*s
;
2734 s
->gc
= s
->face
->gc
;
2738 /* Set S->gc of glyph string S for drawing that glyph string. Set
2739 S->stippled_p to a non-zero value if the face of S has a stipple
2743 x_set_glyph_string_gc (s
)
2744 struct glyph_string
*s
;
2746 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2748 if (s
->hl
== DRAW_NORMAL_TEXT
)
2750 s
->gc
= s
->face
->gc
;
2751 s
->stippled_p
= s
->face
->stipple
!= 0;
2753 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
2755 x_set_mode_line_face_gc (s
);
2756 s
->stippled_p
= s
->face
->stipple
!= 0;
2758 else if (s
->hl
== DRAW_CURSOR
)
2760 x_set_cursor_gc (s
);
2763 else if (s
->hl
== DRAW_MOUSE_FACE
)
2765 x_set_mouse_face_gc (s
);
2766 s
->stippled_p
= s
->face
->stipple
!= 0;
2768 else if (s
->hl
== DRAW_IMAGE_RAISED
2769 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2771 s
->gc
= s
->face
->gc
;
2772 s
->stippled_p
= s
->face
->stipple
!= 0;
2776 s
->gc
= s
->face
->gc
;
2777 s
->stippled_p
= s
->face
->stipple
!= 0;
2780 /* GC must have been set. */
2781 xassert (s
->gc
!= 0);
2785 /* Return in *R the clipping rectangle for glyph string S. */
2788 x_get_glyph_string_clip_rect (s
, r
)
2789 struct glyph_string
*s
;
2792 if (s
->row
->full_width_p
)
2794 /* Draw full-width. X coordinates are relative to S->w->left. */
2795 int canon_x
= CANON_X_UNIT (s
->f
);
2797 r
->x
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
2798 r
->width
= XFASTINT (s
->w
->width
) * canon_x
;
2800 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
2802 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
2803 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
2807 r
->x
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
2809 /* Unless displaying a mode or menu bar line, which are always
2810 fully visible, clip to the visible part of the row. */
2811 if (s
->w
->pseudo_window_p
)
2812 r
->height
= s
->row
->visible_height
;
2814 r
->height
= s
->height
;
2818 /* This is a text line that may be partially visible. */
2819 r
->x
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
2820 r
->width
= window_box_width (s
->w
, s
->area
);
2821 r
->height
= s
->row
->visible_height
;
2824 /* If S draws overlapping rows, it's sufficient to use the top and
2825 bottom of the window for clipping because this glyph string
2826 intentionally draws over other lines. */
2827 if (s
->for_overlaps_p
)
2829 r
->y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2830 r
->height
= window_text_bottom_y (s
->w
) - r
->y
;
2834 /* Don't use S->y for clipping because it doesn't take partially
2835 visible lines into account. For example, it can be negative for
2836 partially visible lines at the top of a window. */
2837 if (!s
->row
->full_width_p
2838 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
2839 r
->y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2841 r
->y
= max (0, s
->row
->y
);
2843 /* If drawing a tool-bar window, draw it over the internal border
2844 at the top of the window. */
2845 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
2846 r
->y
-= s
->f
->output_data
.x
->internal_border_width
;
2849 r
->y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->y
);
2853 /* Set clipping for output of glyph string S. S may be part of a mode
2854 line or menu if we don't have X toolkit support. */
2857 x_set_glyph_string_clipping (s
)
2858 struct glyph_string
*s
;
2861 x_get_glyph_string_clip_rect (s
, &r
);
2862 XSetClipRectangles (s
->display
, s
->gc
, 0, 0, &r
, 1, Unsorted
);
2866 /* Compute left and right overhang of glyph string S. If S is a glyph
2867 string for a composition, assume overhangs don't exist. */
2870 x_compute_glyph_string_overhangs (s
)
2871 struct glyph_string
*s
;
2874 && s
->first_glyph
->type
== CHAR_GLYPH
)
2877 int direction
, font_ascent
, font_descent
;
2878 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
2879 &font_ascent
, &font_descent
, &cs
);
2880 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
2881 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
2886 /* Compute overhangs and x-positions for glyph string S and its
2887 predecessors, or successors. X is the starting x-position for S.
2888 BACKWARD_P non-zero means process predecessors. */
2891 x_compute_overhangs_and_x (s
, x
, backward_p
)
2892 struct glyph_string
*s
;
2900 x_compute_glyph_string_overhangs (s
);
2910 x_compute_glyph_string_overhangs (s
);
2919 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
2920 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
2921 assumed to be zero. */
2924 x_get_glyph_overhangs (glyph
, f
, left
, right
)
2925 struct glyph
*glyph
;
2931 if (glyph
->type
== CHAR_GLYPH
)
2935 struct font_info
*font_info
;
2939 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
2941 font_info
= FONT_INFO_FROM_ID (f
, face
->font_info_id
);
2943 && (pcm
= x_per_char_metric (font
, &char2b
)))
2945 if (pcm
->rbearing
> pcm
->width
)
2946 *right
= pcm
->rbearing
- pcm
->width
;
2947 if (pcm
->lbearing
< 0)
2948 *left
= -pcm
->lbearing
;
2954 /* Return the index of the first glyph preceding glyph string S that
2955 is overwritten by S because of S's left overhang. Value is -1
2956 if no glyphs are overwritten. */
2959 x_left_overwritten (s
)
2960 struct glyph_string
*s
;
2964 if (s
->left_overhang
)
2967 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2968 int first
= s
->first_glyph
- glyphs
;
2970 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
2971 x
-= glyphs
[i
].pixel_width
;
2982 /* Return the index of the first glyph preceding glyph string S that
2983 is overwriting S because of its right overhang. Value is -1 if no
2984 glyph in front of S overwrites S. */
2987 x_left_overwriting (s
)
2988 struct glyph_string
*s
;
2991 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2992 int first
= s
->first_glyph
- glyphs
;
2996 for (i
= first
- 1; i
>= 0; --i
)
2999 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3002 x
-= glyphs
[i
].pixel_width
;
3009 /* Return the index of the last glyph following glyph string S that is
3010 not overwritten by S because of S's right overhang. Value is -1 if
3011 no such glyph is found. */
3014 x_right_overwritten (s
)
3015 struct glyph_string
*s
;
3019 if (s
->right_overhang
)
3022 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3023 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3024 int end
= s
->row
->used
[s
->area
];
3026 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3027 x
+= glyphs
[i
].pixel_width
;
3036 /* Return the index of the last glyph following glyph string S that
3037 overwrites S because of its left overhang. Value is negative
3038 if no such glyph is found. */
3041 x_right_overwriting (s
)
3042 struct glyph_string
*s
;
3045 int end
= s
->row
->used
[s
->area
];
3046 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3047 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3051 for (i
= first
; i
< end
; ++i
)
3054 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3057 x
+= glyphs
[i
].pixel_width
;
3064 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3067 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3068 struct glyph_string
*s
;
3072 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
, &xgcv
);
3073 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
3074 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
3075 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3079 /* Draw the background of glyph_string S. If S->background_filled_p
3080 is non-zero don't draw it. FORCE_P non-zero means draw the
3081 background even if it wouldn't be drawn normally. This is used
3082 when a string preceding S draws into the background of S, or S
3083 contains the first component of a composition. */
3086 x_draw_glyph_string_background (s
, force_p
)
3087 struct glyph_string
*s
;
3090 /* Nothing to do if background has already been drawn or if it
3091 shouldn't be drawn in the first place. */
3092 if (!s
->background_filled_p
)
3094 int box_line_width
= max (s
->face
->box_line_width
, 0);
3098 /* Fill background with a stipple pattern. */
3099 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3100 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3101 s
->y
+ box_line_width
,
3102 s
->background_width
,
3103 s
->height
- 2 * box_line_width
);
3104 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3105 s
->background_filled_p
= 1;
3107 else if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
3108 || s
->font_not_found_p
3109 || s
->extends_to_end_of_line_p
3112 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
3113 s
->background_width
,
3114 s
->height
- 2 * box_line_width
);
3115 s
->background_filled_p
= 1;
3121 /* Draw the foreground of glyph string S. */
3124 x_draw_glyph_string_foreground (s
)
3125 struct glyph_string
*s
;
3129 /* If first glyph of S has a left box line, start drawing the text
3130 of S to the right of that box line. */
3131 if (s
->face
->box
!= FACE_NO_BOX
3132 && s
->first_glyph
->left_box_line_p
)
3133 x
= s
->x
+ abs (s
->face
->box_line_width
);
3137 /* Draw characters of S as rectangles if S's font could not be
3139 if (s
->font_not_found_p
)
3141 for (i
= 0; i
< s
->nchars
; ++i
)
3143 struct glyph
*g
= s
->first_glyph
+ i
;
3144 XDrawRectangle (s
->display
, s
->window
,
3145 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3147 x
+= g
->pixel_width
;
3152 char *char1b
= (char *) s
->char2b
;
3153 int boff
= s
->font_info
->baseline_offset
;
3155 if (s
->font_info
->vertical_centering
)
3156 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3158 /* If we can use 8-bit functions, condense S->char2b. */
3160 for (i
= 0; i
< s
->nchars
; ++i
)
3161 char1b
[i
] = s
->char2b
[i
].byte2
;
3163 /* Draw text with XDrawString if background has already been
3164 filled. Otherwise, use XDrawImageString. (Note that
3165 XDrawImageString is usually faster than XDrawString.) Always
3166 use XDrawImageString when drawing the cursor so that there is
3167 no chance that characters under a box cursor are invisible. */
3168 if (s
->for_overlaps_p
3169 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3171 /* Draw characters with 16-bit or 8-bit functions. */
3173 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
3174 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3176 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
3177 s
->ybase
- boff
, char1b
, s
->nchars
);
3182 XDrawImageString16 (s
->display
, s
->window
, s
->gc
, x
,
3183 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3185 XDrawImageString (s
->display
, s
->window
, s
->gc
, x
,
3186 s
->ybase
- boff
, char1b
, s
->nchars
);
3191 /* Draw the foreground of composite glyph string S. */
3194 x_draw_composite_glyph_string_foreground (s
)
3195 struct glyph_string
*s
;
3199 /* If first glyph of S has a left box line, start drawing the text
3200 of S to the right of that box line. */
3201 if (s
->face
->box
!= FACE_NO_BOX
3202 && s
->first_glyph
->left_box_line_p
)
3203 x
= s
->x
+ abs (s
->face
->box_line_width
);
3207 /* S is a glyph string for a composition. S->gidx is the index of
3208 the first character drawn for glyphs of this composition.
3209 S->gidx == 0 means we are drawing the very first character of
3210 this composition. */
3212 /* Draw a rectangle for the composition if the font for the very
3213 first character of the composition could not be loaded. */
3214 if (s
->font_not_found_p
)
3217 XDrawRectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
3218 s
->width
- 1, s
->height
- 1);
3222 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3223 XDrawString16 (s
->display
, s
->window
, s
->gc
,
3224 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3225 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3231 #ifdef USE_X_TOOLKIT
3233 static struct frame
*x_frame_of_widget
P_ ((Widget
));
3234 static Boolean cvt_string_to_pixel
P_ ((Display
*, XrmValue
*, Cardinal
*,
3235 XrmValue
*, XrmValue
*, XtPointer
*));
3236 static void cvt_pixel_dtor
P_ ((XtAppContext
, XrmValue
*, XtPointer
,
3237 XrmValue
*, Cardinal
*));
3240 /* Return the frame on which widget WIDGET is used.. Abort if frame
3241 cannot be determined. */
3243 static struct frame
*
3244 x_frame_of_widget (widget
)
3247 struct x_display_info
*dpyinfo
;
3251 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
3253 /* Find the top-level shell of the widget. Note that this function
3254 can be called when the widget is not yet realized, so XtWindow
3255 (widget) == 0. That's the reason we can't simply use
3256 x_any_window_to_frame. */
3257 while (!XtIsTopLevelShell (widget
))
3258 widget
= XtParent (widget
);
3260 /* Look for a frame with that top-level widget. Allocate the color
3261 on that frame to get the right gamma correction value. */
3262 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
3263 if (GC_FRAMEP (XCAR (tail
))
3264 && (f
= XFRAME (XCAR (tail
)),
3265 (f
->output_data
.nothing
!= 1
3266 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
3267 && f
->output_data
.x
->widget
== widget
)
3274 /* Allocate the color COLOR->pixel on the screen and display of
3275 widget WIDGET in colormap CMAP. If an exact match cannot be
3276 allocated, try the nearest color available. Value is non-zero
3277 if successful. This is called from lwlib. */
3280 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
3285 struct frame
*f
= x_frame_of_widget (widget
);
3286 return x_alloc_nearest_color (f
, cmap
, color
);
3290 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
3291 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3292 If this produces the same color as PIXEL, try a color where all RGB
3293 values have DELTA added. Return the allocated color in *PIXEL.
3294 DISPLAY is the X display, CMAP is the colormap to operate on.
3295 Value is non-zero if successful. */
3298 x_alloc_lighter_color_for_widget (widget
, display
, cmap
, pixel
, factor
, delta
)
3302 unsigned long *pixel
;
3306 struct frame
*f
= x_frame_of_widget (widget
);
3307 return x_alloc_lighter_color (f
, display
, cmap
, pixel
, factor
, delta
);
3311 /* Structure specifying which arguments should be passed by Xt to
3312 cvt_string_to_pixel. We want the widget's screen and colormap. */
3314 static XtConvertArgRec cvt_string_to_pixel_args
[] =
3316 {XtWidgetBaseOffset
, (XtPointer
) XtOffset (Widget
, core
.screen
),
3318 {XtWidgetBaseOffset
, (XtPointer
) XtOffset (Widget
, core
.colormap
),
3323 /* The address of this variable is returned by
3324 cvt_string_to_pixel. */
3326 static Pixel cvt_string_to_pixel_value
;
3329 /* Convert a color name to a pixel color.
3331 DPY is the display we are working on.
3333 ARGS is an array of *NARGS XrmValue structures holding additional
3334 information about the widget for which the conversion takes place.
3335 The contents of this array are determined by the specification
3336 in cvt_string_to_pixel_args.
3338 FROM is a pointer to an XrmValue which points to the color name to
3339 convert. TO is an XrmValue in which to return the pixel color.
3341 CLOSURE_RET is a pointer to user-data, in which we record if
3342 we allocated the color or not.
3344 Value is True if successful, False otherwise. */
3347 cvt_string_to_pixel (dpy
, args
, nargs
, from
, to
, closure_ret
)
3351 XrmValue
*from
, *to
;
3352 XtPointer
*closure_ret
;
3362 XtAppWarningMsg (XtDisplayToApplicationContext (dpy
),
3363 "wrongParameters", "cvt_string_to_pixel",
3365 "Screen and colormap args required", NULL
, NULL
);
3369 screen
= *(Screen
**) args
[0].addr
;
3370 cmap
= *(Colormap
*) args
[1].addr
;
3371 color_name
= (String
) from
->addr
;
3373 if (strcmp (color_name
, XtDefaultBackground
) == 0)
3375 *closure_ret
= (XtPointer
) False
;
3376 pixel
= WhitePixelOfScreen (screen
);
3378 else if (strcmp (color_name
, XtDefaultForeground
) == 0)
3380 *closure_ret
= (XtPointer
) False
;
3381 pixel
= BlackPixelOfScreen (screen
);
3383 else if (XParseColor (dpy
, cmap
, color_name
, &color
)
3384 && x_alloc_nearest_color_1 (dpy
, cmap
, &color
))
3386 pixel
= color
.pixel
;
3387 *closure_ret
= (XtPointer
) True
;
3392 Cardinal nparams
= 1;
3394 params
[0] = color_name
;
3395 XtAppWarningMsg (XtDisplayToApplicationContext (dpy
),
3396 "badValue", "cvt_string_to_pixel",
3397 "XtToolkitError", "Invalid color `%s'",
3402 if (to
->addr
!= NULL
)
3404 if (to
->size
< sizeof (Pixel
))
3406 to
->size
= sizeof (Pixel
);
3410 *(Pixel
*) to
->addr
= pixel
;
3414 cvt_string_to_pixel_value
= pixel
;
3415 to
->addr
= (XtPointer
) &cvt_string_to_pixel_value
;
3418 to
->size
= sizeof (Pixel
);
3423 /* Free a pixel color which was previously allocated via
3424 cvt_string_to_pixel. This is registered as the destructor
3425 for this type of resource via XtSetTypeConverter.
3427 APP is the application context in which we work.
3429 TO is a pointer to an XrmValue holding the color to free.
3430 CLOSURE is the value we stored in CLOSURE_RET for this color
3431 in cvt_string_to_pixel.
3433 ARGS and NARGS are like for cvt_string_to_pixel. */
3436 cvt_pixel_dtor (app
, to
, closure
, args
, nargs
)
3445 XtAppWarningMsg (app
, "wrongParameters", "cvt_pixel_dtor",
3447 "Screen and colormap arguments required",
3450 else if (closure
!= NULL
)
3452 /* We did allocate the pixel, so free it. */
3453 Screen
*screen
= *(Screen
**) args
[0].addr
;
3454 Colormap cmap
= *(Colormap
*) args
[1].addr
;
3455 x_free_dpy_colors (DisplayOfScreen (screen
), screen
, cmap
,
3456 (Pixel
*) to
->addr
, 1);
3461 #endif /* USE_X_TOOLKIT */
3464 /* Value is an array of XColor structures for the contents of the
3465 color map of display DPY. Set *NCELLS to the size of the array.
3466 Note that this probably shouldn't be called for large color maps,
3467 say a 24-bit TrueColor map. */
3469 static const XColor
*
3470 x_color_cells (dpy
, ncells
)
3474 struct x_display_info
*dpyinfo
= x_display_info_for_display (dpy
);
3476 if (dpyinfo
->color_cells
== NULL
)
3478 Screen
*screen
= dpyinfo
->screen
;
3481 dpyinfo
->ncolor_cells
3482 = XDisplayCells (dpy
, XScreenNumberOfScreen (screen
));
3483 dpyinfo
->color_cells
3484 = (XColor
*) xmalloc (dpyinfo
->ncolor_cells
3485 * sizeof *dpyinfo
->color_cells
);
3487 for (i
= 0; i
< dpyinfo
->ncolor_cells
; ++i
)
3488 dpyinfo
->color_cells
[i
].pixel
= i
;
3490 XQueryColors (dpy
, dpyinfo
->cmap
,
3491 dpyinfo
->color_cells
, dpyinfo
->ncolor_cells
);
3494 *ncells
= dpyinfo
->ncolor_cells
;
3495 return dpyinfo
->color_cells
;
3499 /* On frame F, translate pixel colors to RGB values for the NCOLORS
3500 colors in COLORS. Use cached information, if available. */
3503 x_query_colors (f
, colors
, ncolors
)
3508 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3510 if (dpyinfo
->color_cells
)
3513 for (i
= 0; i
< ncolors
; ++i
)
3515 unsigned long pixel
= colors
[i
].pixel
;
3516 xassert (pixel
< dpyinfo
->ncolor_cells
);
3517 xassert (dpyinfo
->color_cells
[pixel
].pixel
== pixel
);
3518 colors
[i
] = dpyinfo
->color_cells
[pixel
];
3522 XQueryColors (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), colors
, ncolors
);
3526 /* On frame F, translate pixel color to RGB values for the color in
3527 COLOR. Use cached information, if available. */
3530 x_query_color (f
, color
)
3534 x_query_colors (f
, color
, 1);
3538 /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP. If an
3539 exact match can't be allocated, try the nearest color available.
3540 Value is non-zero if successful. Set *COLOR to the color
3544 x_alloc_nearest_color_1 (dpy
, cmap
, color
)
3551 rc
= XAllocColor (dpy
, cmap
, color
);
3554 /* If we got to this point, the colormap is full, so we're going
3555 to try to get the next closest color. The algorithm used is
3556 a least-squares matching, which is what X uses for closest
3557 color matching with StaticColor visuals. */
3559 unsigned long nearest_delta
= ~0;
3561 const XColor
*cells
= x_color_cells (dpy
, &ncells
);
3563 for (nearest
= i
= 0; i
< ncells
; ++i
)
3565 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
3566 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
3567 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
3568 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
3570 if (delta
< nearest_delta
)
3573 nearest_delta
= delta
;
3577 color
->red
= cells
[nearest
].red
;
3578 color
->green
= cells
[nearest
].green
;
3579 color
->blue
= cells
[nearest
].blue
;
3580 rc
= XAllocColor (dpy
, cmap
, color
);
3584 /* If allocation succeeded, and the allocated pixel color is not
3585 equal to a cached pixel color recorded earlier, there was a
3586 change in the colormap, so clear the color cache. */
3587 struct x_display_info
*dpyinfo
= x_display_info_for_display (dpy
);
3588 XColor
*cached_color
;
3590 if (dpyinfo
->color_cells
3591 && (cached_color
= &dpyinfo
->color_cells
[color
->pixel
],
3592 (cached_color
->red
!= color
->red
3593 || cached_color
->blue
!= color
->blue
3594 || cached_color
->green
!= color
->green
)))
3596 xfree (dpyinfo
->color_cells
);
3597 dpyinfo
->color_cells
= NULL
;
3598 dpyinfo
->ncolor_cells
= 0;
3602 #ifdef DEBUG_X_COLORS
3604 register_color (color
->pixel
);
3605 #endif /* DEBUG_X_COLORS */
3611 /* Allocate the color COLOR->pixel on frame F, colormap CMAP. If an
3612 exact match can't be allocated, try the nearest color available.
3613 Value is non-zero if successful. Set *COLOR to the color
3617 x_alloc_nearest_color (f
, cmap
, color
)
3622 gamma_correct (f
, color
);
3623 return x_alloc_nearest_color_1 (FRAME_X_DISPLAY (f
), cmap
, color
);
3627 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
3628 It's necessary to do this instead of just using PIXEL directly to
3629 get color reference counts right. */
3632 x_copy_color (f
, pixel
)
3634 unsigned long pixel
;
3638 color
.pixel
= pixel
;
3640 x_query_color (f
, &color
);
3641 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
3643 #ifdef DEBUG_X_COLORS
3644 register_color (pixel
);
3650 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
3651 It's necessary to do this instead of just using PIXEL directly to
3652 get color reference counts right. */
3655 x_copy_dpy_color (dpy
, cmap
, pixel
)
3658 unsigned long pixel
;
3662 color
.pixel
= pixel
;
3664 XQueryColor (dpy
, cmap
, &color
);
3665 XAllocColor (dpy
, cmap
, &color
);
3667 #ifdef DEBUG_X_COLORS
3668 register_color (pixel
);
3674 /* Brightness beyond which a color won't have its highlight brightness
3677 Nominally, highlight colors for `3d' faces are calculated by
3678 brightening an object's color by a constant scale factor, but this
3679 doesn't yield good results for dark colors, so for colors who's
3680 brightness is less than this value (on a scale of 0-65535) have an
3681 use an additional additive factor.
3683 The value here is set so that the default menu-bar/mode-line color
3684 (grey75) will not have its highlights changed at all. */
3685 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
3688 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
3689 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3690 If this produces the same color as PIXEL, try a color where all RGB
3691 values have DELTA added. Return the allocated color in *PIXEL.
3692 DISPLAY is the X display, CMAP is the colormap to operate on.
3693 Value is non-zero if successful. */
3696 x_alloc_lighter_color (f
, display
, cmap
, pixel
, factor
, delta
)
3700 unsigned long *pixel
;
3708 /* Get RGB color values. */
3709 color
.pixel
= *pixel
;
3710 x_query_color (f
, &color
);
3712 /* Change RGB values by specified FACTOR. Avoid overflow! */
3713 xassert (factor
>= 0);
3714 new.red
= min (0xffff, factor
* color
.red
);
3715 new.green
= min (0xffff, factor
* color
.green
);
3716 new.blue
= min (0xffff, factor
* color
.blue
);
3718 /* Calculate brightness of COLOR. */
3719 bright
= (2 * color
.red
+ 3 * color
.green
+ color
.blue
) / 6;
3721 /* We only boost colors that are darker than
3722 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
3723 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
3724 /* Make an additive adjustment to NEW, because it's dark enough so
3725 that scaling by FACTOR alone isn't enough. */
3727 /* How far below the limit this color is (0 - 1, 1 being darker). */
3728 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
3729 /* The additive adjustment. */
3730 int min_delta
= delta
* dimness
* factor
/ 2;
3734 new.red
= max (0, new.red
- min_delta
);
3735 new.green
= max (0, new.green
- min_delta
);
3736 new.blue
= max (0, new.blue
- min_delta
);
3740 new.red
= min (0xffff, min_delta
+ new.red
);
3741 new.green
= min (0xffff, min_delta
+ new.green
);
3742 new.blue
= min (0xffff, min_delta
+ new.blue
);
3746 /* Try to allocate the color. */
3747 success_p
= x_alloc_nearest_color (f
, cmap
, &new);
3750 if (new.pixel
== *pixel
)
3752 /* If we end up with the same color as before, try adding
3753 delta to the RGB values. */
3754 x_free_colors (f
, &new.pixel
, 1);
3756 new.red
= min (0xffff, delta
+ color
.red
);
3757 new.green
= min (0xffff, delta
+ color
.green
);
3758 new.blue
= min (0xffff, delta
+ color
.blue
);
3759 success_p
= x_alloc_nearest_color (f
, cmap
, &new);
3770 /* Set up the foreground color for drawing relief lines of glyph
3771 string S. RELIEF is a pointer to a struct relief containing the GC
3772 with which lines will be drawn. Use a color that is FACTOR or
3773 DELTA lighter or darker than the relief's background which is found
3774 in S->f->output_data.x->relief_background. If such a color cannot
3775 be allocated, use DEFAULT_PIXEL, instead. */
3778 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3780 struct relief
*relief
;
3783 unsigned long default_pixel
;
3786 struct x_output
*di
= f
->output_data
.x
;
3787 unsigned long mask
= GCForeground
| GCLineWidth
| GCGraphicsExposures
;
3788 unsigned long pixel
;
3789 unsigned long background
= di
->relief_background
;
3790 Colormap cmap
= FRAME_X_COLORMAP (f
);
3791 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3792 Display
*dpy
= FRAME_X_DISPLAY (f
);
3794 xgcv
.graphics_exposures
= False
;
3795 xgcv
.line_width
= 1;
3797 /* Free previously allocated color. The color cell will be reused
3798 when it has been freed as many times as it was allocated, so this
3799 doesn't affect faces using the same colors. */
3801 && relief
->allocated_p
)
3803 x_free_colors (f
, &relief
->pixel
, 1);
3804 relief
->allocated_p
= 0;
3807 /* Allocate new color. */
3808 xgcv
.foreground
= default_pixel
;
3810 if (dpyinfo
->n_planes
!= 1
3811 && x_alloc_lighter_color (f
, dpy
, cmap
, &pixel
, factor
, delta
))
3813 relief
->allocated_p
= 1;
3814 xgcv
.foreground
= relief
->pixel
= pixel
;
3817 if (relief
->gc
== 0)
3819 xgcv
.stipple
= dpyinfo
->gray
;
3821 relief
->gc
= XCreateGC (dpy
, FRAME_X_WINDOW (f
), mask
, &xgcv
);
3824 XChangeGC (dpy
, relief
->gc
, mask
, &xgcv
);
3828 /* Set up colors for the relief lines around glyph string S. */
3831 x_setup_relief_colors (s
)
3832 struct glyph_string
*s
;
3834 struct x_output
*di
= s
->f
->output_data
.x
;
3835 unsigned long color
;
3837 if (s
->face
->use_box_color_for_shadows_p
)
3838 color
= s
->face
->box_color
;
3839 else if (s
->first_glyph
->type
== IMAGE_GLYPH
3841 && !IMAGE_BACKGROUND_TRANSPARENT (s
->img
, s
->f
, 0))
3842 color
= IMAGE_BACKGROUND (s
->img
, s
->f
, 0);
3847 /* Get the background color of the face. */
3848 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
3849 color
= xgcv
.background
;
3852 if (di
->white_relief
.gc
== 0
3853 || color
!= di
->relief_background
)
3855 di
->relief_background
= color
;
3856 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3857 WHITE_PIX_DEFAULT (s
->f
));
3858 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3859 BLACK_PIX_DEFAULT (s
->f
));
3864 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3865 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3866 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3867 relief. LEFT_P non-zero means draw a relief on the left side of
3868 the rectangle. RIGHT_P non-zero means draw a relief on the right
3869 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3873 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3874 raised_p
, left_p
, right_p
, clip_rect
)
3876 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
3877 XRectangle
*clip_rect
;
3879 Display
*dpy
= FRAME_X_DISPLAY (f
);
3880 Window window
= FRAME_X_WINDOW (f
);
3885 gc
= f
->output_data
.x
->white_relief
.gc
;
3887 gc
= f
->output_data
.x
->black_relief
.gc
;
3888 XSetClipRectangles (dpy
, gc
, 0, 0, clip_rect
, 1, Unsorted
);
3891 for (i
= 0; i
< width
; ++i
)
3892 XDrawLine (dpy
, window
, gc
,
3893 left_x
+ i
* left_p
, top_y
+ i
,
3894 right_x
+ 1 - i
* right_p
, top_y
+ i
);
3898 for (i
= 0; i
< width
; ++i
)
3899 XDrawLine (dpy
, window
, gc
,
3900 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
+ 1);
3902 XSetClipMask (dpy
, gc
, None
);
3904 gc
= f
->output_data
.x
->black_relief
.gc
;
3906 gc
= f
->output_data
.x
->white_relief
.gc
;
3907 XSetClipRectangles (dpy
, gc
, 0, 0, clip_rect
, 1, Unsorted
);
3910 for (i
= 0; i
< width
; ++i
)
3911 XDrawLine (dpy
, window
, gc
,
3912 left_x
+ i
* left_p
, bottom_y
- i
,
3913 right_x
+ 1 - i
* right_p
, bottom_y
- i
);
3917 for (i
= 0; i
< width
; ++i
)
3918 XDrawLine (dpy
, window
, gc
,
3919 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
);
3921 XSetClipMask (dpy
, gc
, None
);
3925 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3926 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3927 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3928 left side of the rectangle. RIGHT_P non-zero means draw a line
3929 on the right side of the rectangle. CLIP_RECT is the clipping
3930 rectangle to use when drawing. */
3933 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3934 left_p
, right_p
, clip_rect
)
3935 struct glyph_string
*s
;
3936 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
;
3937 XRectangle
*clip_rect
;
3941 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3942 XSetForeground (s
->display
, s
->gc
, s
->face
->box_color
);
3943 XSetClipRectangles (s
->display
, s
->gc
, 0, 0, clip_rect
, 1, Unsorted
);
3946 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3947 left_x
, top_y
, right_x
- left_x
+ 1, width
);
3951 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3952 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
3955 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3956 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
3960 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3961 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
3963 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3964 XSetClipMask (s
->display
, s
->gc
, None
);
3968 /* Draw a box around glyph string S. */
3971 x_draw_glyph_string_box (s
)
3972 struct glyph_string
*s
;
3974 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3975 int left_p
, right_p
;
3976 struct glyph
*last_glyph
;
3977 XRectangle clip_rect
;
3979 last_x
= window_box_right (s
->w
, s
->area
);
3980 if (s
->row
->full_width_p
3981 && !s
->w
->pseudo_window_p
)
3983 last_x
+= FRAME_X_RIGHT_FRINGE_WIDTH (s
->f
);
3984 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
3985 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
3988 /* The glyph that may have a right box line. */
3989 last_glyph
= (s
->cmp
|| s
->img
3991 : s
->first_glyph
+ s
->nchars
- 1);
3993 width
= abs (s
->face
->box_line_width
);
3994 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3996 right_x
= (s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
3998 : min (last_x
, s
->x
+ s
->background_width
) - 1);
4000 bottom_y
= top_y
+ s
->height
- 1;
4002 left_p
= (s
->first_glyph
->left_box_line_p
4003 || (s
->hl
== DRAW_MOUSE_FACE
4005 || s
->prev
->hl
!= s
->hl
)));
4006 right_p
= (last_glyph
->right_box_line_p
4007 || (s
->hl
== DRAW_MOUSE_FACE
4009 || s
->next
->hl
!= s
->hl
)));
4011 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4013 if (s
->face
->box
== FACE_SIMPLE_BOX
)
4014 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
4015 left_p
, right_p
, &clip_rect
);
4018 x_setup_relief_colors (s
);
4019 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
4020 width
, raised_p
, left_p
, right_p
, &clip_rect
);
4025 /* Draw foreground of image glyph string S. */
4028 x_draw_image_foreground (s
)
4029 struct glyph_string
*s
;
4032 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4034 /* If first glyph of S has a left box line, start drawing it to the
4035 right of that line. */
4036 if (s
->face
->box
!= FACE_NO_BOX
4037 && s
->first_glyph
->left_box_line_p
)
4038 x
= s
->x
+ abs (s
->face
->box_line_width
);
4042 /* If there is a margin around the image, adjust x- and y-position
4044 x
+= s
->img
->hmargin
;
4045 y
+= s
->img
->vmargin
;
4051 /* We can't set both a clip mask and use XSetClipRectangles
4052 because the latter also sets a clip mask. We also can't
4053 trust on the shape extension to be available
4054 (XShapeCombineRegion). So, compute the rectangle to draw
4056 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4059 XRectangle clip_rect
, image_rect
, r
;
4061 xgcv
.clip_mask
= s
->img
->mask
;
4062 xgcv
.clip_x_origin
= x
;
4063 xgcv
.clip_y_origin
= y
;
4064 xgcv
.function
= GXcopy
;
4065 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4067 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4070 image_rect
.width
= s
->img
->width
;
4071 image_rect
.height
= s
->img
->height
;
4072 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
4073 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
4074 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
4078 XRectangle clip_rect
, image_rect
, r
;
4080 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4083 image_rect
.width
= s
->img
->width
;
4084 image_rect
.height
= s
->img
->height
;
4085 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
4086 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
4087 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
4089 /* When the image has a mask, we can expect that at
4090 least part of a mouse highlight or a block cursor will
4091 be visible. If the image doesn't have a mask, make
4092 a block cursor visible by drawing a rectangle around
4093 the image. I believe it's looking better if we do
4094 nothing here for mouse-face. */
4095 if (s
->hl
== DRAW_CURSOR
)
4096 XDrawRectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
4097 s
->img
->width
- 1, s
->img
->height
- 1);
4101 /* Draw a rectangle if image could not be loaded. */
4102 XDrawRectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
4103 s
->img
->width
- 1, s
->img
->height
- 1);
4107 /* Draw a relief around the image glyph string S. */
4110 x_draw_image_relief (s
)
4111 struct glyph_string
*s
;
4113 int x0
, y0
, x1
, y1
, thick
, raised_p
;
4116 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4118 /* If first glyph of S has a left box line, start drawing it to the
4119 right of that line. */
4120 if (s
->face
->box
!= FACE_NO_BOX
4121 && s
->first_glyph
->left_box_line_p
)
4122 x
= s
->x
+ abs (s
->face
->box_line_width
);
4126 /* If there is a margin around the image, adjust x- and y-position
4128 x
+= s
->img
->hmargin
;
4129 y
+= s
->img
->vmargin
;
4131 if (s
->hl
== DRAW_IMAGE_SUNKEN
4132 || s
->hl
== DRAW_IMAGE_RAISED
)
4134 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
4135 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
4139 thick
= abs (s
->img
->relief
);
4140 raised_p
= s
->img
->relief
> 0;
4145 x1
= x
+ s
->img
->width
+ thick
- 1;
4146 y1
= y
+ s
->img
->height
+ thick
- 1;
4148 x_setup_relief_colors (s
);
4149 x_get_glyph_string_clip_rect (s
, &r
);
4150 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
4154 /* Draw the foreground of image glyph string S to PIXMAP. */
4157 x_draw_image_foreground_1 (s
, pixmap
)
4158 struct glyph_string
*s
;
4162 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
4164 /* If first glyph of S has a left box line, start drawing it to the
4165 right of that line. */
4166 if (s
->face
->box
!= FACE_NO_BOX
4167 && s
->first_glyph
->left_box_line_p
)
4168 x
= abs (s
->face
->box_line_width
);
4172 /* If there is a margin around the image, adjust x- and y-position
4174 x
+= s
->img
->hmargin
;
4175 y
+= s
->img
->vmargin
;
4181 /* We can't set both a clip mask and use XSetClipRectangles
4182 because the latter also sets a clip mask. We also can't
4183 trust on the shape extension to be available
4184 (XShapeCombineRegion). So, compute the rectangle to draw
4186 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4190 xgcv
.clip_mask
= s
->img
->mask
;
4191 xgcv
.clip_x_origin
= x
;
4192 xgcv
.clip_y_origin
= y
;
4193 xgcv
.function
= GXcopy
;
4194 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4196 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4197 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4198 XSetClipMask (s
->display
, s
->gc
, None
);
4202 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4203 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4205 /* When the image has a mask, we can expect that at
4206 least part of a mouse highlight or a block cursor will
4207 be visible. If the image doesn't have a mask, make
4208 a block cursor visible by drawing a rectangle around
4209 the image. I believe it's looking better if we do
4210 nothing here for mouse-face. */
4211 if (s
->hl
== DRAW_CURSOR
)
4212 XDrawRectangle (s
->display
, pixmap
, s
->gc
, x
, y
,
4213 s
->img
->width
- 1, s
->img
->height
- 1);
4217 /* Draw a rectangle if image could not be loaded. */
4218 XDrawRectangle (s
->display
, pixmap
, s
->gc
, x
, y
,
4219 s
->img
->width
- 1, s
->img
->height
- 1);
4223 /* Draw part of the background of glyph string S. X, Y, W, and H
4224 give the rectangle to draw. */
4227 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
4228 struct glyph_string
*s
;
4233 /* Fill background with a stipple pattern. */
4234 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4235 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
4236 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4239 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
4243 /* Draw image glyph string S.
4246 s->x +-------------------------
4249 | +-------------------------
4252 | | +-------------------
4258 x_draw_image_glyph_string (s
)
4259 struct glyph_string
*s
;
4262 int box_line_hwidth
= abs (s
->face
->box_line_width
);
4263 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
4265 Pixmap pixmap
= None
;
4267 height
= s
->height
- 2 * box_line_vwidth
;
4269 /* Fill background with face under the image. Do it only if row is
4270 taller than image or if image has a clip mask to reduce
4272 s
->stippled_p
= s
->face
->stipple
!= 0;
4273 if (height
> s
->img
->height
4277 || s
->img
->pixmap
== 0
4278 || s
->width
!= s
->background_width
)
4280 if (box_line_hwidth
&& s
->first_glyph
->left_box_line_p
)
4281 x
= s
->x
+ box_line_hwidth
;
4285 y
= s
->y
+ box_line_vwidth
;
4289 /* Create a pixmap as large as the glyph string. Fill it
4290 with the background color. Copy the image to it, using
4291 its mask. Copy the temporary pixmap to the display. */
4292 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
4293 int depth
= DefaultDepthOfScreen (screen
);
4295 /* Create a pixmap as large as the glyph string. */
4296 pixmap
= XCreatePixmap (s
->display
, s
->window
,
4297 s
->background_width
,
4300 /* Don't clip in the following because we're working on the
4302 XSetClipMask (s
->display
, s
->gc
, None
);
4304 /* Fill the pixmap with the background color/stipple. */
4307 /* Fill background with a stipple pattern. */
4308 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4309 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4310 0, 0, s
->background_width
, s
->height
);
4311 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4316 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
4318 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
4319 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4320 0, 0, s
->background_width
, s
->height
);
4321 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4325 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
4327 s
->background_filled_p
= 1;
4330 /* Draw the foreground. */
4333 x_draw_image_foreground_1 (s
, pixmap
);
4334 x_set_glyph_string_clipping (s
);
4335 XCopyArea (s
->display
, pixmap
, s
->window
, s
->gc
,
4336 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
4337 XFreePixmap (s
->display
, pixmap
);
4340 x_draw_image_foreground (s
);
4342 /* If we must draw a relief around the image, do it. */
4344 || s
->hl
== DRAW_IMAGE_RAISED
4345 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4346 x_draw_image_relief (s
);
4350 /* Draw stretch glyph string S. */
4353 x_draw_stretch_glyph_string (s
)
4354 struct glyph_string
*s
;
4356 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4357 s
->stippled_p
= s
->face
->stipple
!= 0;
4359 if (s
->hl
== DRAW_CURSOR
4360 && !x_stretch_cursor_p
)
4362 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4363 as wide as the stretch glyph. */
4364 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4367 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4369 /* Clear rest using the GC of the original non-cursor face. */
4370 if (width
< s
->background_width
)
4372 int x
= s
->x
+ width
, y
= s
->y
;
4373 int w
= s
->background_width
- width
, h
= s
->height
;
4377 if (s
->row
->mouse_face_p
4378 && cursor_in_mouse_face_p (s
->w
))
4380 x_set_mouse_face_gc (s
);
4386 x_get_glyph_string_clip_rect (s
, &r
);
4387 XSetClipRectangles (s
->display
, gc
, 0, 0, &r
, 1, Unsorted
);
4389 if (s
->face
->stipple
)
4391 /* Fill background with a stipple pattern. */
4392 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4393 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4394 XSetFillStyle (s
->display
, gc
, FillSolid
);
4399 XGetGCValues (s
->display
, gc
, GCForeground
| GCBackground
, &xgcv
);
4400 XSetForeground (s
->display
, gc
, xgcv
.background
);
4401 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4402 XSetForeground (s
->display
, gc
, xgcv
.foreground
);
4406 else if (!s
->background_filled_p
)
4407 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4410 s
->background_filled_p
= 1;
4414 /* Draw glyph string S. */
4417 x_draw_glyph_string (s
)
4418 struct glyph_string
*s
;
4420 int relief_drawn_p
= 0;
4422 /* If S draws into the background of its successor, draw the
4423 background of the successor first so that S can draw into it.
4424 This makes S->next use XDrawString instead of XDrawImageString. */
4425 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4427 xassert (s
->next
->img
== NULL
);
4428 x_set_glyph_string_gc (s
->next
);
4429 x_set_glyph_string_clipping (s
->next
);
4430 x_draw_glyph_string_background (s
->next
, 1);
4433 /* Set up S->gc, set clipping and draw S. */
4434 x_set_glyph_string_gc (s
);
4436 /* Draw relief (if any) in advance for char/composition so that the
4437 glyph string can be drawn over it. */
4438 if (!s
->for_overlaps_p
4439 && s
->face
->box
!= FACE_NO_BOX
4440 && (s
->first_glyph
->type
== CHAR_GLYPH
4441 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
4444 x_set_glyph_string_clipping (s
);
4445 x_draw_glyph_string_background (s
, 1);
4446 x_draw_glyph_string_box (s
);
4447 x_set_glyph_string_clipping (s
);
4451 x_set_glyph_string_clipping (s
);
4453 switch (s
->first_glyph
->type
)
4456 x_draw_image_glyph_string (s
);
4460 x_draw_stretch_glyph_string (s
);
4464 if (s
->for_overlaps_p
)
4465 s
->background_filled_p
= 1;
4467 x_draw_glyph_string_background (s
, 0);
4468 x_draw_glyph_string_foreground (s
);
4471 case COMPOSITE_GLYPH
:
4472 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4473 s
->background_filled_p
= 1;
4475 x_draw_glyph_string_background (s
, 1);
4476 x_draw_composite_glyph_string_foreground (s
);
4483 if (!s
->for_overlaps_p
)
4485 /* Draw underline. */
4486 if (s
->face
->underline_p
)
4488 unsigned long tem
, h
;
4491 /* Get the underline thickness. Default is 1 pixel. */
4492 if (!XGetFontProperty (s
->font
, XA_UNDERLINE_THICKNESS
, &h
))
4495 /* Get the underline position. This is the recommended
4496 vertical offset in pixels from the baseline to the top of
4497 the underline. This is a signed value according to the
4498 specs, and its default is
4500 ROUND ((maximum descent) / 2), with
4501 ROUND(x) = floor (x + 0.5) */
4503 if (x_use_underline_position_properties
4504 && XGetFontProperty (s
->font
, XA_UNDERLINE_POSITION
, &tem
))
4505 y
= s
->ybase
+ (long) tem
;
4506 else if (s
->face
->font
)
4507 y
= s
->ybase
+ (s
->face
->font
->max_bounds
.descent
+ 1) / 2;
4509 y
= s
->y
+ s
->height
- h
;
4511 if (s
->face
->underline_defaulted_p
)
4512 XFillRectangle (s
->display
, s
->window
, s
->gc
,
4513 s
->x
, y
, s
->width
, h
);
4517 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4518 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
4519 XFillRectangle (s
->display
, s
->window
, s
->gc
,
4520 s
->x
, y
, s
->width
, h
);
4521 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4525 /* Draw overline. */
4526 if (s
->face
->overline_p
)
4528 unsigned long dy
= 0, h
= 1;
4530 if (s
->face
->overline_color_defaulted_p
)
4531 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4536 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4537 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
4538 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4540 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4544 /* Draw strike-through. */
4545 if (s
->face
->strike_through_p
)
4547 unsigned long h
= 1;
4548 unsigned long dy
= (s
->height
- h
) / 2;
4550 if (s
->face
->strike_through_color_defaulted_p
)
4551 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4556 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4557 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
4558 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4560 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4564 /* Draw relief if not yet drawn. */
4565 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
4566 x_draw_glyph_string_box (s
);
4569 /* Reset clipping. */
4570 XSetClipMask (s
->display
, s
->gc
, None
);
4574 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4575 struct face
**, int));
4578 /* Fill glyph string S with composition components specified by S->cmp.
4580 FACES is an array of faces for all components of this composition.
4581 S->gidx is the index of the first component for S.
4582 OVERLAPS_P non-zero means S should draw the foreground only, and
4583 use its physical height for clipping.
4585 Value is the index of a component not in S. */
4588 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4589 struct glyph_string
*s
;
4590 struct face
**faces
;
4597 s
->for_overlaps_p
= overlaps_p
;
4599 s
->face
= faces
[s
->gidx
];
4600 s
->font
= s
->face
->font
;
4601 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4603 /* For all glyphs of this composition, starting at the offset
4604 S->gidx, until we reach the end of the definition or encounter a
4605 glyph that requires the different face, add it to S. */
4607 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4610 /* All glyph strings for the same composition has the same width,
4611 i.e. the width set for the first component of the composition. */
4613 s
->width
= s
->first_glyph
->pixel_width
;
4615 /* If the specified font could not be loaded, use the frame's
4616 default font, but record the fact that we couldn't load it in
4617 the glyph string so that we can draw rectangles for the
4618 characters of the glyph string. */
4619 if (s
->font
== NULL
)
4621 s
->font_not_found_p
= 1;
4622 s
->font
= FRAME_FONT (s
->f
);
4625 /* Adjust base line for subscript/superscript text. */
4626 s
->ybase
+= s
->first_glyph
->voffset
;
4628 xassert (s
->face
&& s
->face
->gc
);
4630 /* This glyph string must always be drawn with 16-bit functions. */
4633 return s
->gidx
+ s
->nchars
;
4637 /* Fill glyph string S from a sequence of character glyphs.
4639 FACE_ID is the face id of the string. START is the index of the
4640 first glyph to consider, END is the index of the last + 1.
4641 OVERLAPS_P non-zero means S should draw the foreground only, and
4642 use its physical height for clipping.
4644 Value is the index of the first glyph not in S. */
4647 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4648 struct glyph_string
*s
;
4650 int start
, end
, overlaps_p
;
4652 struct glyph
*glyph
, *last
;
4654 int glyph_not_available_p
;
4656 xassert (s
->f
== XFRAME (s
->w
->frame
));
4657 xassert (s
->nchars
== 0);
4658 xassert (start
>= 0 && end
> start
);
4660 s
->for_overlaps_p
= overlaps_p
,
4661 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4662 last
= s
->row
->glyphs
[s
->area
] + end
;
4663 voffset
= glyph
->voffset
;
4665 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4668 && glyph
->type
== CHAR_GLYPH
4669 && glyph
->voffset
== voffset
4670 /* Same face id implies same font, nowadays. */
4671 && glyph
->face_id
== face_id
4672 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
4676 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
4677 s
->char2b
+ s
->nchars
,
4679 s
->two_byte_p
= two_byte_p
;
4681 xassert (s
->nchars
<= end
- start
);
4682 s
->width
+= glyph
->pixel_width
;
4686 s
->font
= s
->face
->font
;
4687 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4689 /* If the specified font could not be loaded, use the frame's font,
4690 but record the fact that we couldn't load it in
4691 S->font_not_found_p so that we can draw rectangles for the
4692 characters of the glyph string. */
4693 if (s
->font
== NULL
|| glyph_not_available_p
)
4695 s
->font_not_found_p
= 1;
4696 s
->font
= FRAME_FONT (s
->f
);
4699 /* Adjust base line for subscript/superscript text. */
4700 s
->ybase
+= voffset
;
4702 xassert (s
->face
&& s
->face
->gc
);
4703 return glyph
- s
->row
->glyphs
[s
->area
];
4707 /* Fill glyph string S from image glyph S->first_glyph. */
4710 x_fill_image_glyph_string (s
)
4711 struct glyph_string
*s
;
4713 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4714 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
4716 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4717 s
->font
= s
->face
->font
;
4718 s
->width
= s
->first_glyph
->pixel_width
;
4720 /* Adjust base line for subscript/superscript text. */
4721 s
->ybase
+= s
->first_glyph
->voffset
;
4725 /* Fill glyph string S from a sequence of stretch glyphs.
4727 ROW is the glyph row in which the glyphs are found, AREA is the
4728 area within the row. START is the index of the first glyph to
4729 consider, END is the index of the last + 1.
4731 Value is the index of the first glyph not in S. */
4734 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
4735 struct glyph_string
*s
;
4736 struct glyph_row
*row
;
4737 enum glyph_row_area area
;
4740 struct glyph
*glyph
, *last
;
4741 int voffset
, face_id
;
4743 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4745 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4746 last
= s
->row
->glyphs
[s
->area
] + end
;
4747 face_id
= glyph
->face_id
;
4748 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
4749 s
->font
= s
->face
->font
;
4750 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4751 s
->width
= glyph
->pixel_width
;
4752 voffset
= glyph
->voffset
;
4756 && glyph
->type
== STRETCH_GLYPH
4757 && glyph
->voffset
== voffset
4758 && glyph
->face_id
== face_id
);
4760 s
->width
+= glyph
->pixel_width
;
4762 /* Adjust base line for subscript/superscript text. */
4763 s
->ybase
+= voffset
;
4765 /* The case that face->gc == 0 is handled when drawing the glyph
4766 string by calling PREPARE_FACE_FOR_DISPLAY. */
4768 return glyph
- s
->row
->glyphs
[s
->area
];
4772 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4773 of XChar2b structures for S; it can't be allocated in
4774 x_init_glyph_string because it must be allocated via `alloca'. W
4775 is the window on which S is drawn. ROW and AREA are the glyph row
4776 and area within the row from which S is constructed. START is the
4777 index of the first glyph structure covered by S. HL is a
4778 face-override for drawing S. */
4781 x_init_glyph_string (s
, char2b
, w
, row
, area
, start
, hl
)
4782 struct glyph_string
*s
;
4785 struct glyph_row
*row
;
4786 enum glyph_row_area area
;
4788 enum draw_glyphs_face hl
;
4790 bzero (s
, sizeof *s
);
4792 s
->f
= XFRAME (w
->frame
);
4793 s
->display
= FRAME_X_DISPLAY (s
->f
);
4794 s
->window
= FRAME_X_WINDOW (s
->f
);
4799 s
->first_glyph
= row
->glyphs
[area
] + start
;
4800 s
->height
= row
->height
;
4801 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4803 /* Display the internal border below the tool-bar window. */
4804 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4805 s
->y
-= s
->f
->output_data
.x
->internal_border_width
;
4807 s
->ybase
= s
->y
+ row
->ascent
;
4811 /* Set background width of glyph string S. START is the index of the
4812 first glyph following S. LAST_X is the right-most x-position + 1
4813 in the drawing area. */
4816 x_set_glyph_string_background_width (s
, start
, last_x
)
4817 struct glyph_string
*s
;
4821 /* If the face of this glyph string has to be drawn to the end of
4822 the drawing area, set S->extends_to_end_of_line_p. */
4823 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4825 if (start
== s
->row
->used
[s
->area
]
4826 && s
->area
== TEXT_AREA
4827 && ((s
->hl
== DRAW_NORMAL_TEXT
4828 && (s
->row
->fill_line_p
4829 || s
->face
->background
!= default_face
->background
4830 || s
->face
->stipple
!= default_face
->stipple
4831 || s
->row
->mouse_face_p
))
4832 || s
->hl
== DRAW_MOUSE_FACE
4833 || ((s
->hl
== DRAW_IMAGE_RAISED
|| s
->hl
== DRAW_IMAGE_SUNKEN
)
4834 && s
->row
->fill_line_p
)))
4835 s
->extends_to_end_of_line_p
= 1;
4837 /* If S extends its face to the end of the line, set its
4838 background_width to the distance to the right edge of the drawing
4840 if (s
->extends_to_end_of_line_p
)
4841 s
->background_width
= last_x
- s
->x
+ 1;
4843 s
->background_width
= s
->width
;
4847 /* Add a glyph string for a stretch glyph to the list of strings
4848 between HEAD and TAIL. START is the index of the stretch glyph in
4849 row area AREA of glyph row ROW. END is the index of the last glyph
4850 in that glyph row area. X is the current output position assigned
4851 to the new glyph string constructed. HL overrides that face of the
4852 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4853 is the right-most x-position of the drawing area. */
4855 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
4856 and below -- keep them on one line. */
4857 #define BUILD_STRETCH_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4860 s = (struct glyph_string *) alloca (sizeof *s); \
4861 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
4862 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4863 x_append_glyph_string (&HEAD, &TAIL, s); \
4869 /* Add a glyph string for an image glyph to the list of strings
4870 between HEAD and TAIL. START is the index of the image glyph in
4871 row area AREA of glyph row ROW. END is the index of the last glyph
4872 in that glyph row area. X is the current output position assigned
4873 to the new glyph string constructed. HL overrides that face of the
4874 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4875 is the right-most x-position of the drawing area. */
4877 #define BUILD_IMAGE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4880 s = (struct glyph_string *) alloca (sizeof *s); \
4881 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
4882 x_fill_image_glyph_string (s); \
4883 x_append_glyph_string (&HEAD, &TAIL, s); \
4890 /* Add a glyph string for a sequence of character glyphs to the list
4891 of strings between HEAD and TAIL. START is the index of the first
4892 glyph in row area AREA of glyph row ROW that is part of the new
4893 glyph string. END is the index of the last glyph in that glyph row
4894 area. X is the current output position assigned to the new glyph
4895 string constructed. HL overrides that face of the glyph; e.g. it
4896 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4897 right-most x-position of the drawing area. */
4899 #define BUILD_CHAR_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4905 c = (ROW)->glyphs[AREA][START].u.ch; \
4906 face_id = (ROW)->glyphs[AREA][START].face_id; \
4908 s = (struct glyph_string *) alloca (sizeof *s); \
4909 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
4910 x_init_glyph_string (s, char2b, W, ROW, AREA, START, HL); \
4911 x_append_glyph_string (&HEAD, &TAIL, s); \
4913 START = x_fill_glyph_string (s, face_id, START, END, \
4919 /* Add a glyph string for a composite sequence to the list of strings
4920 between HEAD and TAIL. START is the index of the first glyph in
4921 row area AREA of glyph row ROW that is part of the new glyph
4922 string. END is the index of the last glyph in that glyph row area.
4923 X is the current output position assigned to the new glyph string
4924 constructed. HL overrides that face of the glyph; e.g. it is
4925 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4926 x-position of the drawing area. */
4928 #define BUILD_COMPOSITE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4930 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4931 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4932 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4933 struct composition *cmp = composition_table[cmp_id]; \
4934 int glyph_len = cmp->glyph_len; \
4936 struct face **faces; \
4937 struct glyph_string *first_s = NULL; \
4940 base_face = base_face->ascii_face; \
4941 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
4942 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4943 /* At first, fill in `char2b' and `faces'. */ \
4944 for (n = 0; n < glyph_len; n++) \
4946 int c = COMPOSITION_GLYPH (cmp, n); \
4947 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4948 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4949 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4950 this_face_id, char2b + n, 1); \
4953 /* Make glyph_strings for each glyph sequence that is drawable by \
4954 the same face, and append them to HEAD/TAIL. */ \
4955 for (n = 0; n < cmp->glyph_len;) \
4957 s = (struct glyph_string *) alloca (sizeof *s); \
4958 x_init_glyph_string (s, char2b + n, W, ROW, AREA, START, HL); \
4959 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4967 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4975 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4976 of AREA of glyph row ROW on window W between indices START and END.
4977 HL overrides the face for drawing glyph strings, e.g. it is
4978 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4979 x-positions of the drawing area.
4981 This is an ugly monster macro construct because we must use alloca
4982 to allocate glyph strings (because x_draw_glyphs can be called
4985 #define BUILD_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4988 HEAD = TAIL = NULL; \
4989 while (START < END) \
4991 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4992 switch (first_glyph->type) \
4995 BUILD_CHAR_GLYPH_STRINGS (W, ROW, AREA, START, END, HEAD, \
4996 TAIL, HL, X, LAST_X, \
5000 case COMPOSITE_GLYPH: \
5001 BUILD_COMPOSITE_GLYPH_STRING (W, ROW, AREA, START, END, \
5002 HEAD, TAIL, HL, X, LAST_X,\
5006 case STRETCH_GLYPH: \
5007 BUILD_STRETCH_GLYPH_STRING (W, ROW, AREA, START, END, \
5008 HEAD, TAIL, HL, X, LAST_X); \
5012 BUILD_IMAGE_GLYPH_STRING (W, ROW, AREA, START, END, HEAD, \
5013 TAIL, HL, X, LAST_X); \
5020 x_set_glyph_string_background_width (s, START, LAST_X); \
5027 /* Draw glyphs between START and END in AREA of ROW on window W,
5028 starting at x-position X. X is relative to AREA in W. HL is a
5029 face-override with the following meaning:
5031 DRAW_NORMAL_TEXT draw normally
5032 DRAW_CURSOR draw in cursor face
5033 DRAW_MOUSE_FACE draw in mouse face.
5034 DRAW_INVERSE_VIDEO draw in mode line face
5035 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
5036 DRAW_IMAGE_RAISED draw an image with a raised relief around it
5038 If OVERLAPS_P is non-zero, draw only the foreground of characters
5039 and clip to the physical height of ROW.
5041 Value is the x-position reached, relative to AREA of W. */
5044 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, overlaps_p
)
5047 struct glyph_row
*row
;
5048 enum glyph_row_area area
;
5050 enum draw_glyphs_face hl
;
5053 struct glyph_string
*head
, *tail
;
5054 struct glyph_string
*s
;
5055 int last_x
, area_width
;
5059 /* Let's rather be paranoid than getting a SEGV. */
5060 end
= min (end
, row
->used
[area
]);
5061 start
= max (0, start
);
5062 start
= min (end
, start
);
5064 /* Translate X to frame coordinates. Set last_x to the right
5065 end of the drawing area. */
5066 if (row
->full_width_p
)
5068 /* X is relative to the left edge of W, without scroll bars
5070 struct frame
*f
= XFRAME (w
->frame
);
5071 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
5074 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5075 last_x
= window_left_x
+ area_width
;
5077 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
5079 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5080 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
5086 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
5087 last_x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
5091 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
5092 area_width
= window_box_width (w
, area
);
5093 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
5096 /* Build a doubly-linked list of glyph_string structures between
5097 head and tail from what we have to draw. Note that the macro
5098 BUILD_GLYPH_STRINGS will modify its start parameter. That's
5099 the reason we use a separate variable `i'. */
5101 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
5104 x_reached
= tail
->x
+ tail
->background_width
;
5108 /* If there are any glyphs with lbearing < 0 or rbearing > width in
5109 the row, redraw some glyphs in front or following the glyph
5110 strings built above. */
5111 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
5114 struct glyph_string
*h
, *t
;
5116 /* Compute overhangs for all glyph strings. */
5117 for (s
= head
; s
; s
= s
->next
)
5118 x_compute_glyph_string_overhangs (s
);
5120 /* Prepend glyph strings for glyphs in front of the first glyph
5121 string that are overwritten because of the first glyph
5122 string's left overhang. The background of all strings
5123 prepended must be drawn because the first glyph string
5125 i
= x_left_overwritten (head
);
5129 BUILD_GLYPH_STRINGS (w
, row
, area
, j
, start
, h
, t
,
5130 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5133 x_compute_overhangs_and_x (t
, head
->x
, 1);
5134 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5137 /* Prepend glyph strings for glyphs in front of the first glyph
5138 string that overwrite that glyph string because of their
5139 right overhang. For these strings, only the foreground must
5140 be drawn, because it draws over the glyph string at `head'.
5141 The background must not be drawn because this would overwrite
5142 right overhangs of preceding glyphs for which no glyph
5144 i
= x_left_overwriting (head
);
5147 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, start
, h
, t
,
5148 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5150 for (s
= h
; s
; s
= s
->next
)
5151 s
->background_filled_p
= 1;
5152 x_compute_overhangs_and_x (t
, head
->x
, 1);
5153 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5156 /* Append glyphs strings for glyphs following the last glyph
5157 string tail that are overwritten by tail. The background of
5158 these strings has to be drawn because tail's foreground draws
5160 i
= x_right_overwritten (tail
);
5163 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5164 DRAW_NORMAL_TEXT
, x
, last_x
,
5166 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5167 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5170 /* Append glyph strings for glyphs following the last glyph
5171 string tail that overwrite tail. The foreground of such
5172 glyphs has to be drawn because it writes into the background
5173 of tail. The background must not be drawn because it could
5174 paint over the foreground of following glyphs. */
5175 i
= x_right_overwriting (tail
);
5178 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5179 DRAW_NORMAL_TEXT
, x
, last_x
,
5181 for (s
= h
; s
; s
= s
->next
)
5182 s
->background_filled_p
= 1;
5183 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5184 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5188 /* Draw all strings. */
5189 for (s
= head
; s
; s
= s
->next
)
5190 x_draw_glyph_string (s
);
5192 if (area
== TEXT_AREA
5193 && !row
->full_width_p
5194 /* When drawing overlapping rows, only the glyph strings'
5195 foreground is drawn, which doesn't erase a cursor
5199 int x0
= head
? head
->x
: x
;
5200 int x1
= tail
? tail
->x
+ tail
->background_width
: x
;
5202 x0
= FRAME_TO_WINDOW_PIXEL_X (w
, x0
);
5203 x1
= FRAME_TO_WINDOW_PIXEL_X (w
, x1
);
5205 if (XFASTINT (w
->left_margin_width
) != 0)
5207 int left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
5208 x0
-= left_area_width
;
5209 x1
-= left_area_width
;
5212 notice_overwritten_cursor (w
, area
, x0
, x1
,
5213 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
5216 /* Value is the x-position up to which drawn, relative to AREA of W.
5217 This doesn't include parts drawn because of overhangs. */
5218 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
5219 if (!row
->full_width_p
)
5221 if (area
> LEFT_MARGIN_AREA
&& XFASTINT (w
->left_margin_width
) != 0)
5222 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
5223 if (area
> TEXT_AREA
)
5224 x_reached
-= window_box_width (w
, TEXT_AREA
);
5231 /* Fix the display of area AREA of overlapping row ROW in window W. */
5234 x_fix_overlapping_area (w
, row
, area
)
5236 struct glyph_row
*row
;
5237 enum glyph_row_area area
;
5243 if (area
== LEFT_MARGIN_AREA
)
5245 else if (area
== TEXT_AREA
)
5246 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5248 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5249 + window_box_width (w
, TEXT_AREA
));
5251 for (i
= 0; i
< row
->used
[area
];)
5253 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
5255 int start
= i
, start_x
= x
;
5259 x
+= row
->glyphs
[area
][i
].pixel_width
;
5262 while (i
< row
->used
[area
]
5263 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
5265 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
5266 DRAW_NORMAL_TEXT
, 1);
5270 x
+= row
->glyphs
[area
][i
].pixel_width
;
5279 /* Output LEN glyphs starting at START at the nominal cursor position.
5280 Advance the nominal cursor over the text. The global variable
5281 updated_window contains the window being updated, updated_row is
5282 the glyph row being updated, and updated_area is the area of that
5283 row being updated. */
5286 x_write_glyphs (start
, len
)
5287 struct glyph
*start
;
5292 xassert (updated_window
&& updated_row
);
5297 hpos
= start
- updated_row
->glyphs
[updated_area
];
5298 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
5299 updated_row
, updated_area
,
5301 DRAW_NORMAL_TEXT
, 0);
5305 /* Advance the output cursor. */
5306 output_cursor
.hpos
+= len
;
5307 output_cursor
.x
= x
;
5311 /* Insert LEN glyphs from START at the nominal cursor position. */
5314 x_insert_glyphs (start
, len
)
5315 struct glyph
*start
;
5320 int line_height
, shift_by_width
, shifted_region_width
;
5321 struct glyph_row
*row
;
5322 struct glyph
*glyph
;
5323 int frame_x
, frame_y
, hpos
;
5325 xassert (updated_window
&& updated_row
);
5328 f
= XFRAME (WINDOW_FRAME (w
));
5330 /* Get the height of the line we are in. */
5332 line_height
= row
->height
;
5334 /* Get the width of the glyphs to insert. */
5336 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5337 shift_by_width
+= glyph
->pixel_width
;
5339 /* Get the width of the region to shift right. */
5340 shifted_region_width
= (window_box_width (w
, updated_area
)
5345 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
5346 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5347 XCopyArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), FRAME_X_WINDOW (f
),
5348 f
->output_data
.x
->normal_gc
,
5350 shifted_region_width
, line_height
,
5351 frame_x
+ shift_by_width
, frame_y
);
5353 /* Write the glyphs. */
5354 hpos
= start
- row
->glyphs
[updated_area
];
5355 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5356 DRAW_NORMAL_TEXT
, 0);
5358 /* Advance the output cursor. */
5359 output_cursor
.hpos
+= len
;
5360 output_cursor
.x
+= shift_by_width
;
5365 /* Delete N glyphs at the nominal cursor position. Not implemented
5376 /* Like XClearArea, but check that WIDTH and HEIGHT are reasonable.
5377 If they are <= 0, this is probably an error. */
5380 x_clear_area (dpy
, window
, x
, y
, width
, height
, exposures
)
5387 xassert (width
> 0 && height
> 0);
5388 XClearArea (dpy
, window
, x
, y
, width
, height
, exposures
);
5392 /* Erase the current text line from the nominal cursor position
5393 (inclusive) to pixel column TO_X (exclusive). The idea is that
5394 everything from TO_X onward is already erased.
5396 TO_X is a pixel position relative to updated_area of
5397 updated_window. TO_X == -1 means clear to the end of this area. */
5400 x_clear_end_of_line (to_x
)
5404 struct window
*w
= updated_window
;
5405 int max_x
, min_y
, max_y
;
5406 int from_x
, from_y
, to_y
;
5408 xassert (updated_window
&& updated_row
);
5409 f
= XFRAME (w
->frame
);
5411 if (updated_row
->full_width_p
)
5413 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5414 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5415 && !w
->pseudo_window_p
)
5416 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5419 max_x
= window_box_width (w
, updated_area
);
5420 max_y
= window_text_bottom_y (w
);
5422 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5423 of window. For TO_X > 0, truncate to end of drawing area. */
5429 to_x
= min (to_x
, max_x
);
5431 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5433 /* Notice if the cursor will be cleared by this operation. */
5434 if (!updated_row
->full_width_p
)
5435 notice_overwritten_cursor (w
, updated_area
,
5436 output_cursor
.x
, -1,
5438 MATRIX_ROW_BOTTOM_Y (updated_row
));
5440 from_x
= output_cursor
.x
;
5442 /* Translate to frame coordinates. */
5443 if (updated_row
->full_width_p
)
5445 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5446 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5450 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5451 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5454 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5455 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5456 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5458 /* Prevent inadvertently clearing to end of the X window. */
5459 if (to_x
> from_x
&& to_y
> from_y
)
5462 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5463 from_x
, from_y
, to_x
- from_x
, to_y
- from_y
,
5470 /* Clear entire frame. If updating_frame is non-null, clear that
5471 frame. Otherwise clear the selected frame. */
5481 f
= SELECTED_FRAME ();
5483 /* Clearing the frame will erase any cursor, so mark them all as no
5485 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5486 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5487 output_cursor
.x
= -1;
5489 /* We don't set the output cursor here because there will always
5490 follow an explicit cursor_to. */
5492 XClearWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
5494 /* We have to clear the scroll bars, too. If we have changed
5495 colors or something like that, then they should be notified. */
5496 x_scroll_bar_clear (f
);
5498 XFlush (FRAME_X_DISPLAY (f
));
5504 /* Invert the middle quarter of the frame for .15 sec. */
5506 /* We use the select system call to do the waiting, so we have to make
5507 sure it's available. If it isn't, we just won't do visual bells. */
5509 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5512 /* Subtract the `struct timeval' values X and Y, storing the result in
5513 *RESULT. Return 1 if the difference is negative, otherwise 0. */
5516 timeval_subtract (result
, x
, y
)
5517 struct timeval
*result
, x
, y
;
5519 /* Perform the carry for the later subtraction by updating y. This
5520 is safer because on some systems the tv_sec member is unsigned. */
5521 if (x
.tv_usec
< y
.tv_usec
)
5523 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
5524 y
.tv_usec
-= 1000000 * nsec
;
5528 if (x
.tv_usec
- y
.tv_usec
> 1000000)
5530 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
5531 y
.tv_usec
+= 1000000 * nsec
;
5535 /* Compute the time remaining to wait. tv_usec is certainly
5537 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
5538 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
5540 /* Return indication of whether the result should be considered
5542 return x
.tv_sec
< y
.tv_sec
;
5554 /* Create a GC that will use the GXxor function to flip foreground
5555 pixels into background pixels. */
5559 values
.function
= GXxor
;
5560 values
.foreground
= (f
->output_data
.x
->foreground_pixel
5561 ^ f
->output_data
.x
->background_pixel
);
5563 gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5564 GCFunction
| GCForeground
, &values
);
5568 /* Get the height not including a menu bar widget. */
5569 int height
= CHAR_TO_PIXEL_HEIGHT (f
, FRAME_HEIGHT (f
));
5570 /* Height of each line to flash. */
5571 int flash_height
= FRAME_LINE_HEIGHT (f
);
5572 /* These will be the left and right margins of the rectangles. */
5573 int flash_left
= FRAME_INTERNAL_BORDER_WIDTH (f
);
5574 int flash_right
= PIXEL_WIDTH (f
) - FRAME_INTERNAL_BORDER_WIDTH (f
);
5578 /* Don't flash the area between a scroll bar and the frame
5579 edge it is next to. */
5580 switch (FRAME_VERTICAL_SCROLL_BAR_TYPE (f
))
5582 case vertical_scroll_bar_left
:
5583 flash_left
+= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
5586 case vertical_scroll_bar_right
:
5587 flash_right
-= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
5594 width
= flash_right
- flash_left
;
5596 /* If window is tall, flash top and bottom line. */
5597 if (height
> 3 * FRAME_LINE_HEIGHT (f
))
5599 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5601 (FRAME_INTERNAL_BORDER_WIDTH (f
)
5602 + FRAME_TOOL_BAR_LINES (f
) * CANON_Y_UNIT (f
)),
5603 width
, flash_height
);
5604 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5606 (height
- flash_height
5607 - FRAME_INTERNAL_BORDER_WIDTH (f
)),
5608 width
, flash_height
);
5611 /* If it is short, flash it all. */
5612 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5613 flash_left
, FRAME_INTERNAL_BORDER_WIDTH (f
),
5614 width
, height
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
5619 struct timeval wakeup
;
5621 EMACS_GET_TIME (wakeup
);
5623 /* Compute time to wait until, propagating carry from usecs. */
5624 wakeup
.tv_usec
+= 150000;
5625 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
5626 wakeup
.tv_usec
%= 1000000;
5628 /* Keep waiting until past the time wakeup or any input gets
5630 while (! detect_input_pending ())
5632 struct timeval current
;
5633 struct timeval timeout
;
5635 EMACS_GET_TIME (current
);
5637 /* Break if result would be negative. */
5638 if (timeval_subtract (¤t
, wakeup
, current
))
5641 /* How long `select' should wait. */
5643 timeout
.tv_usec
= 10000;
5645 /* Try to wait that long--but we might wake up sooner. */
5646 select (0, NULL
, NULL
, NULL
, &timeout
);
5650 /* If window is tall, flash top and bottom line. */
5651 if (height
> 3 * FRAME_LINE_HEIGHT (f
))
5653 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5655 (FRAME_INTERNAL_BORDER_WIDTH (f
)
5656 + FRAME_TOOL_BAR_LINES (f
) * CANON_Y_UNIT (f
)),
5657 width
, flash_height
);
5658 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5660 (height
- flash_height
5661 - FRAME_INTERNAL_BORDER_WIDTH (f
)),
5662 width
, flash_height
);
5665 /* If it is short, flash it all. */
5666 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5667 flash_left
, FRAME_INTERNAL_BORDER_WIDTH (f
),
5668 width
, height
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
5670 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
5678 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
5681 /* Make audible bell. */
5686 struct frame
*f
= SELECTED_FRAME ();
5688 if (FRAME_X_DISPLAY (f
))
5690 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5697 XBell (FRAME_X_DISPLAY (f
), 0);
5698 XFlush (FRAME_X_DISPLAY (f
));
5705 /* Specify how many text lines, from the top of the window,
5706 should be affected by insert-lines and delete-lines operations.
5707 This, and those operations, are used only within an update
5708 that is bounded by calls to x_update_begin and x_update_end. */
5711 XTset_terminal_window (n
)
5714 /* This function intentionally left blank. */
5719 /***********************************************************************
5721 ***********************************************************************/
5723 /* Perform an insert-lines or delete-lines operation, inserting N
5724 lines or deleting -N lines at vertical position VPOS. */
5727 x_ins_del_lines (vpos
, n
)
5734 /* Scroll part of the display as described by RUN. */
5737 x_scroll_run (w
, run
)
5741 struct frame
*f
= XFRAME (w
->frame
);
5742 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5744 /* Get frame-relative bounding box of the text display area of W,
5745 without mode lines. Include in this box the left and right
5747 window_box (w
, -1, &x
, &y
, &width
, &height
);
5748 width
+= FRAME_X_FRINGE_WIDTH (f
);
5749 x
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
5751 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5752 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5753 bottom_y
= y
+ height
;
5757 /* Scrolling up. Make sure we don't copy part of the mode
5758 line at the bottom. */
5759 if (from_y
+ run
->height
> bottom_y
)
5760 height
= bottom_y
- from_y
;
5762 height
= run
->height
;
5766 /* Scolling down. Make sure we don't copy over the mode line.
5768 if (to_y
+ run
->height
> bottom_y
)
5769 height
= bottom_y
- to_y
;
5771 height
= run
->height
;
5776 /* Cursor off. Will be switched on again in x_update_window_end. */
5780 XCopyArea (FRAME_X_DISPLAY (f
),
5781 FRAME_X_WINDOW (f
), FRAME_X_WINDOW (f
),
5782 f
->output_data
.x
->normal_gc
,
5792 /***********************************************************************
5794 ***********************************************************************/
5796 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5797 corner of the exposed rectangle. W and H are width and height of
5798 the exposed area. All are pixel values. W or H zero means redraw
5799 the entire frame. */
5802 expose_frame (f
, x
, y
, w
, h
)
5807 int mouse_face_overwritten_p
= 0;
5809 TRACE ((stderr
, "expose_frame "));
5811 /* No need to redraw if frame will be redrawn soon. */
5812 if (FRAME_GARBAGED_P (f
))
5814 TRACE ((stderr
, " garbaged\n"));
5818 /* If basic faces haven't been realized yet, there is no point in
5819 trying to redraw anything. This can happen when we get an expose
5820 event while Emacs is starting, e.g. by moving another window. */
5821 if (FRAME_FACE_CACHE (f
) == NULL
5822 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
5824 TRACE ((stderr
, " no faces\n"));
5828 if (w
== 0 || h
== 0)
5831 r
.width
= CANON_X_UNIT (f
) * f
->width
;
5832 r
.height
= CANON_Y_UNIT (f
) * f
->height
;
5842 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.x
, r
.y
, r
.width
, r
.height
));
5843 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
5845 if (WINDOWP (f
->tool_bar_window
))
5846 mouse_face_overwritten_p
5847 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
5849 #ifndef USE_X_TOOLKIT
5850 if (WINDOWP (f
->menu_bar_window
))
5851 mouse_face_overwritten_p
5852 |= expose_window (XWINDOW (f
->menu_bar_window
), &r
);
5853 #endif /* not USE_X_TOOLKIT */
5855 /* Some window managers support a focus-follows-mouse style with
5856 delayed raising of frames. Imagine a partially obscured frame,
5857 and moving the mouse into partially obscured mouse-face on that
5858 frame. The visible part of the mouse-face will be highlighted,
5859 then the WM raises the obscured frame. With at least one WM, KDE
5860 2.1, Emacs is not getting any event for the raising of the frame
5861 (even tried with SubstructureRedirectMask), only Expose events.
5862 These expose events will draw text normally, i.e. not
5863 highlighted. Which means we must redo the highlight here.
5864 Subsume it under ``we love X''. --gerd 2001-08-15 */
5865 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
5867 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
5868 if (f
== dpyinfo
->mouse_face_mouse_frame
)
5870 int x
= dpyinfo
->mouse_face_mouse_x
;
5871 int y
= dpyinfo
->mouse_face_mouse_y
;
5872 clear_mouse_face (dpyinfo
);
5873 note_mouse_highlight (f
, x
, y
);
5879 /* Redraw (parts) of all windows in the window tree rooted at W that
5880 intersect R. R contains frame pixel coordinates. Value is
5881 non-zero if the exposure overwrites mouse-face. */
5884 expose_window_tree (w
, r
)
5888 struct frame
*f
= XFRAME (w
->frame
);
5889 int mouse_face_overwritten_p
= 0;
5891 while (w
&& !FRAME_GARBAGED_P (f
))
5893 if (!NILP (w
->hchild
))
5894 mouse_face_overwritten_p
5895 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
5896 else if (!NILP (w
->vchild
))
5897 mouse_face_overwritten_p
5898 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
5900 mouse_face_overwritten_p
|= expose_window (w
, r
);
5902 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
5905 return mouse_face_overwritten_p
;
5909 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5910 which intersects rectangle R. R is in window-relative coordinates. */
5913 expose_area (w
, row
, r
, area
)
5915 struct glyph_row
*row
;
5917 enum glyph_row_area area
;
5919 struct glyph
*first
= row
->glyphs
[area
];
5920 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5922 int first_x
, start_x
, x
;
5924 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5925 /* If row extends face to end of line write the whole line. */
5926 x_draw_glyphs (w
, 0, row
, area
, 0, row
->used
[area
],
5927 DRAW_NORMAL_TEXT
, 0);
5930 /* Set START_X to the window-relative start position for drawing glyphs of
5931 AREA. The first glyph of the text area can be partially visible.
5932 The first glyphs of other areas cannot. */
5933 if (area
== LEFT_MARGIN_AREA
)
5935 else if (area
== TEXT_AREA
)
5936 start_x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5938 start_x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5939 + window_box_width (w
, TEXT_AREA
));
5942 /* Find the first glyph that must be redrawn. */
5944 && x
+ first
->pixel_width
< r
->x
)
5946 x
+= first
->pixel_width
;
5950 /* Find the last one. */
5954 && x
< r
->x
+ r
->width
)
5956 x
+= last
->pixel_width
;
5962 x_draw_glyphs (w
, first_x
- start_x
, row
, area
,
5963 first
- row
->glyphs
[area
],
5964 last
- row
->glyphs
[area
],
5965 DRAW_NORMAL_TEXT
, 0);
5970 /* Redraw the parts of the glyph row ROW on window W intersecting
5971 rectangle R. R is in window-relative coordinates. Value is
5972 non-zero if mouse-face was overwritten. */
5975 expose_line (w
, row
, r
)
5977 struct glyph_row
*row
;
5980 xassert (row
->enabled_p
);
5982 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5983 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5984 DRAW_NORMAL_TEXT
, 0);
5987 if (row
->used
[LEFT_MARGIN_AREA
])
5988 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5989 if (row
->used
[TEXT_AREA
])
5990 expose_area (w
, row
, r
, TEXT_AREA
);
5991 if (row
->used
[RIGHT_MARGIN_AREA
])
5992 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5993 x_draw_row_fringe_bitmaps (w
, row
);
5996 return row
->mouse_face_p
;
6000 /* Return non-zero if W's cursor intersects rectangle R. */
6003 x_phys_cursor_in_rect_p (w
, r
)
6007 XRectangle cr
, result
;
6008 struct glyph
*cursor_glyph
;
6010 cursor_glyph
= get_phys_cursor_glyph (w
);
6013 cr
.x
= w
->phys_cursor
.x
;
6014 cr
.y
= w
->phys_cursor
.y
;
6015 cr
.width
= cursor_glyph
->pixel_width
;
6016 cr
.height
= w
->phys_cursor_height
;
6017 return x_intersect_rectangles (&cr
, r
, &result
);
6024 /* Redraw the part of window W intersection rectangle FR. Pixel
6025 coordinates in FR are frame-relative. Call this function with
6026 input blocked. Value is non-zero if the exposure overwrites
6030 expose_window (w
, fr
)
6034 struct frame
*f
= XFRAME (w
->frame
);
6036 int mouse_face_overwritten_p
= 0;
6038 /* If window is not yet fully initialized, do nothing. This can
6039 happen when toolkit scroll bars are used and a window is split.
6040 Reconfiguring the scroll bar will generate an expose for a newly
6042 if (w
->current_matrix
== NULL
)
6045 /* When we're currently updating the window, display and current
6046 matrix usually don't agree. Arrange for a thorough display
6048 if (w
== updated_window
)
6050 SET_FRAME_GARBAGED (f
);
6054 /* Frame-relative pixel rectangle of W. */
6055 wr
.x
= XFASTINT (w
->left
) * CANON_X_UNIT (f
);
6056 wr
.y
= XFASTINT (w
->top
) * CANON_Y_UNIT (f
);
6057 wr
.width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
6058 wr
.height
= XFASTINT (w
->height
) * CANON_Y_UNIT (f
);
6060 if (x_intersect_rectangles (fr
, &wr
, &r
))
6062 int yb
= window_text_bottom_y (w
);
6063 struct glyph_row
*row
;
6064 int cursor_cleared_p
;
6066 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
6067 r
.x
, r
.y
, r
.width
, r
.height
));
6069 /* Convert to window coordinates. */
6070 r
.x
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.x
);
6071 r
.y
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.y
);
6073 /* Turn off the cursor. */
6074 if (!w
->pseudo_window_p
6075 && x_phys_cursor_in_rect_p (w
, &r
))
6078 cursor_cleared_p
= 1;
6081 cursor_cleared_p
= 0;
6083 /* Find the first row intersecting the rectangle R. */
6084 for (row
= w
->current_matrix
->rows
;
6089 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
6091 if ((y0
>= r
.y
&& y0
< r
.y
+ r
.height
)
6092 || (y1
> r
.y
&& y1
< r
.y
+ r
.height
)
6093 || (r
.y
>= y0
&& r
.y
< y1
)
6094 || (r
.y
+ r
.height
> y0
&& r
.y
+ r
.height
< y1
))
6096 if (expose_line (w
, row
, &r
))
6097 mouse_face_overwritten_p
= 1;
6104 /* Display the mode line if there is one. */
6105 if (WINDOW_WANTS_MODELINE_P (w
)
6106 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
6108 && row
->y
< r
.y
+ r
.height
)
6110 if (expose_line (w
, row
, &r
))
6111 mouse_face_overwritten_p
= 1;
6114 if (!w
->pseudo_window_p
)
6116 /* Draw border between windows. */
6117 x_draw_vertical_border (w
);
6119 /* Turn the cursor on again. */
6120 if (cursor_cleared_p
)
6121 x_update_window_cursor (w
, 1);
6125 return mouse_face_overwritten_p
;
6129 /* Determine the intersection of two rectangles R1 and R2. Return
6130 the intersection in *RESULT. Value is non-zero if RESULT is not
6134 x_intersect_rectangles (r1
, r2
, result
)
6135 XRectangle
*r1
, *r2
, *result
;
6137 XRectangle
*left
, *right
;
6138 XRectangle
*upper
, *lower
;
6139 int intersection_p
= 0;
6141 /* Rearrange so that R1 is the left-most rectangle. */
6143 left
= r1
, right
= r2
;
6145 left
= r2
, right
= r1
;
6147 /* X0 of the intersection is right.x0, if this is inside R1,
6148 otherwise there is no intersection. */
6149 if (right
->x
<= left
->x
+ left
->width
)
6151 result
->x
= right
->x
;
6153 /* The right end of the intersection is the minimum of the
6154 the right ends of left and right. */
6155 result
->width
= (min (left
->x
+ left
->width
, right
->x
+ right
->width
)
6158 /* Same game for Y. */
6160 upper
= r1
, lower
= r2
;
6162 upper
= r2
, lower
= r1
;
6164 /* The upper end of the intersection is lower.y0, if this is inside
6165 of upper. Otherwise, there is no intersection. */
6166 if (lower
->y
<= upper
->y
+ upper
->height
)
6168 result
->y
= lower
->y
;
6170 /* The lower end of the intersection is the minimum of the lower
6171 ends of upper and lower. */
6172 result
->height
= (min (lower
->y
+ lower
->height
,
6173 upper
->y
+ upper
->height
)
6179 return intersection_p
;
6190 /* We used to only do this if Vx_no_window_manager was non-nil, but
6191 the ICCCM (section 4.1.6) says that the window's border pixmap
6192 and border pixel are window attributes which are "private to the
6193 client", so we can always change it to whatever we want. */
6195 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6196 f
->output_data
.x
->border_pixel
);
6198 x_update_cursor (f
, 1);
6202 frame_unhighlight (f
)
6205 /* We used to only do this if Vx_no_window_manager was non-nil, but
6206 the ICCCM (section 4.1.6) says that the window's border pixmap
6207 and border pixel are window attributes which are "private to the
6208 client", so we can always change it to whatever we want. */
6210 XSetWindowBorderPixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6211 f
->output_data
.x
->border_tile
);
6213 x_update_cursor (f
, 1);
6216 /* The focus has changed. Update the frames as necessary to reflect
6217 the new situation. Note that we can't change the selected frame
6218 here, because the Lisp code we are interrupting might become confused.
6219 Each event gets marked with the frame in which it occurred, so the
6220 Lisp code can tell when the switch took place by examining the events. */
6223 x_new_focus_frame (dpyinfo
, frame
)
6224 struct x_display_info
*dpyinfo
;
6225 struct frame
*frame
;
6227 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
6229 if (frame
!= dpyinfo
->x_focus_frame
)
6231 /* Set this before calling other routines, so that they see
6232 the correct value of x_focus_frame. */
6233 dpyinfo
->x_focus_frame
= frame
;
6235 if (old_focus
&& old_focus
->auto_lower
)
6236 x_lower_frame (old_focus
);
6239 selected_frame
= frame
;
6240 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
6242 Fselect_window (selected_frame
->selected_window
);
6243 choose_minibuf_frame ();
6246 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
6247 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
6249 pending_autoraise_frame
= 0;
6252 x_frame_rehighlight (dpyinfo
);
6255 /* Handle an event saying the mouse has moved out of an Emacs frame. */
6258 x_mouse_leave (dpyinfo
)
6259 struct x_display_info
*dpyinfo
;
6261 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
6264 /* The focus has changed, or we have redirected a frame's focus to
6265 another frame (this happens when a frame uses a surrogate
6266 mini-buffer frame). Shift the highlight as appropriate.
6268 The FRAME argument doesn't necessarily have anything to do with which
6269 frame is being highlighted or un-highlighted; we only use it to find
6270 the appropriate X display info. */
6273 XTframe_rehighlight (frame
)
6274 struct frame
*frame
;
6276 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
6280 x_frame_rehighlight (dpyinfo
)
6281 struct x_display_info
*dpyinfo
;
6283 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
6285 if (dpyinfo
->x_focus_frame
)
6287 dpyinfo
->x_highlight_frame
6288 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
6289 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
6290 : dpyinfo
->x_focus_frame
);
6291 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
6293 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
6294 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
6298 dpyinfo
->x_highlight_frame
= 0;
6300 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
6303 frame_unhighlight (old_highlight
);
6304 if (dpyinfo
->x_highlight_frame
)
6305 frame_highlight (dpyinfo
->x_highlight_frame
);
6311 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
6313 /* Initialize mode_switch_bit and modifier_meaning. */
6315 x_find_modifier_meanings (dpyinfo
)
6316 struct x_display_info
*dpyinfo
;
6318 int min_code
, max_code
;
6321 XModifierKeymap
*mods
;
6323 dpyinfo
->meta_mod_mask
= 0;
6324 dpyinfo
->shift_lock_mask
= 0;
6325 dpyinfo
->alt_mod_mask
= 0;
6326 dpyinfo
->super_mod_mask
= 0;
6327 dpyinfo
->hyper_mod_mask
= 0;
6330 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
6332 min_code
= dpyinfo
->display
->min_keycode
;
6333 max_code
= dpyinfo
->display
->max_keycode
;
6336 syms
= XGetKeyboardMapping (dpyinfo
->display
,
6337 min_code
, max_code
- min_code
+ 1,
6339 mods
= XGetModifierMapping (dpyinfo
->display
);
6341 /* Scan the modifier table to see which modifier bits the Meta and
6342 Alt keysyms are on. */
6344 int row
, col
; /* The row and column in the modifier table. */
6346 for (row
= 3; row
< 8; row
++)
6347 for (col
= 0; col
< mods
->max_keypermod
; col
++)
6350 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
6352 /* Zeroes are used for filler. Skip them. */
6356 /* Are any of this keycode's keysyms a meta key? */
6360 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
6362 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
6368 dpyinfo
->meta_mod_mask
|= (1 << row
);
6373 dpyinfo
->alt_mod_mask
|= (1 << row
);
6378 dpyinfo
->hyper_mod_mask
|= (1 << row
);
6383 dpyinfo
->super_mod_mask
|= (1 << row
);
6387 /* Ignore this if it's not on the lock modifier. */
6388 if ((1 << row
) == LockMask
)
6389 dpyinfo
->shift_lock_mask
= LockMask
;
6397 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
6398 if (! dpyinfo
->meta_mod_mask
)
6400 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
6401 dpyinfo
->alt_mod_mask
= 0;
6404 /* If some keys are both alt and meta,
6405 make them just meta, not alt. */
6406 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
6408 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
6411 XFree ((char *) syms
);
6412 XFreeModifiermap (mods
);
6415 /* Convert between the modifier bits X uses and the modifier bits
6419 x_x_to_emacs_modifiers (dpyinfo
, state
)
6420 struct x_display_info
*dpyinfo
;
6423 return ( ((state
& (ShiftMask
| dpyinfo
->shift_lock_mask
)) ? shift_modifier
: 0)
6424 | ((state
& ControlMask
) ? ctrl_modifier
: 0)
6425 | ((state
& dpyinfo
->meta_mod_mask
) ? meta_modifier
: 0)
6426 | ((state
& dpyinfo
->alt_mod_mask
) ? alt_modifier
: 0)
6427 | ((state
& dpyinfo
->super_mod_mask
) ? super_modifier
: 0)
6428 | ((state
& dpyinfo
->hyper_mod_mask
) ? hyper_modifier
: 0));
6432 x_emacs_to_x_modifiers (dpyinfo
, state
)
6433 struct x_display_info
*dpyinfo
;
6436 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
6437 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
6438 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
6439 | ((state
& shift_modifier
) ? ShiftMask
: 0)
6440 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
6441 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
6444 /* Convert a keysym to its name. */
6447 x_get_keysym_name (keysym
)
6453 value
= XKeysymToString (keysym
);
6461 /* Mouse clicks and mouse movement. Rah. */
6463 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
6464 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
6465 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
6466 not force the value into range. */
6469 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
6471 register int pix_x
, pix_y
;
6472 register int *x
, *y
;
6476 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
6477 even for negative values. */
6479 pix_x
-= FONT_WIDTH ((f
)->output_data
.x
->font
) - 1;
6481 pix_y
-= (f
)->output_data
.x
->line_height
- 1;
6483 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
6484 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
6488 bounds
->width
= FONT_WIDTH (f
->output_data
.x
->font
);
6489 bounds
->height
= f
->output_data
.x
->line_height
;
6490 bounds
->x
= CHAR_TO_PIXEL_COL (f
, pix_x
);
6491 bounds
->y
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
6498 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
6499 pix_x
= FRAME_WINDOW_WIDTH (f
);
6503 else if (pix_y
> f
->height
)
6512 /* Given HPOS/VPOS in the current matrix of W, return corresponding
6513 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
6514 can't tell the positions because W's display is not up to date,
6518 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
6521 int *frame_x
, *frame_y
;
6525 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
6526 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
6528 if (display_completed
)
6530 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6531 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
6532 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
6538 *frame_x
+= glyph
->pixel_width
;
6546 *frame_y
= *frame_x
= 0;
6550 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
6551 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
6556 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6558 If the event is a button press, then note that we have grabbed
6562 construct_mouse_click (result
, event
, f
)
6563 struct input_event
*result
;
6564 XButtonEvent
*event
;
6567 /* Make the event type no_event; we'll change that when we decide
6569 result
->kind
= mouse_click
;
6570 result
->code
= event
->button
- Button1
;
6571 result
->timestamp
= event
->time
;
6572 result
->modifiers
= (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
6574 | (event
->type
== ButtonRelease
6578 XSETINT (result
->x
, event
->x
);
6579 XSETINT (result
->y
, event
->y
);
6580 XSETFRAME (result
->frame_or_window
, f
);
6586 /* Function to report a mouse movement to the mainstream Emacs code.
6587 The input handler calls this.
6589 We have received a mouse movement event, which is given in *event.
6590 If the mouse is over a different glyph than it was last time, tell
6591 the mainstream emacs code by setting mouse_moved. If not, ask for
6592 another motion event, so we can check again the next time it moves. */
6594 static XMotionEvent last_mouse_motion_event
;
6595 static Lisp_Object last_mouse_motion_frame
;
6598 note_mouse_movement (frame
, event
)
6600 XMotionEvent
*event
;
6602 last_mouse_movement_time
= event
->time
;
6603 last_mouse_motion_event
= *event
;
6604 XSETFRAME (last_mouse_motion_frame
, frame
);
6606 if (event
->window
!= FRAME_X_WINDOW (frame
))
6608 frame
->mouse_moved
= 1;
6609 last_mouse_scroll_bar
= Qnil
;
6610 note_mouse_highlight (frame
, -1, -1);
6613 /* Has the mouse moved off the glyph it was on at the last sighting? */
6614 else if (event
->x
< last_mouse_glyph
.x
6615 || event
->x
>= last_mouse_glyph
.x
+ last_mouse_glyph
.width
6616 || event
->y
< last_mouse_glyph
.y
6617 || event
->y
>= last_mouse_glyph
.y
+ last_mouse_glyph
.height
)
6619 frame
->mouse_moved
= 1;
6620 last_mouse_scroll_bar
= Qnil
;
6621 note_mouse_highlight (frame
, event
->x
, event
->y
);
6625 /* This is used for debugging, to turn off note_mouse_highlight. */
6627 int disable_mouse_highlight
;
6631 /************************************************************************
6633 ************************************************************************/
6635 /* Find the glyph under window-relative coordinates X/Y in window W.
6636 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6637 strings. Return in *HPOS and *VPOS the row and column number of
6638 the glyph found. Return in *AREA the glyph area containing X.
6639 Value is a pointer to the glyph found or null if X/Y is not on
6640 text, or we can't tell because W's current matrix is not up to
6643 static struct glyph
*
6644 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
, buffer_only_p
)
6647 int *hpos
, *vpos
, *area
;
6650 struct glyph
*glyph
, *end
;
6651 struct glyph_row
*row
= NULL
;
6652 int x0
, i
, left_area_width
;
6654 /* Find row containing Y. Give up if some row is not enabled. */
6655 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6657 row
= MATRIX_ROW (w
->current_matrix
, i
);
6658 if (!row
->enabled_p
)
6660 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6667 /* Give up if Y is not in the window. */
6668 if (i
== w
->current_matrix
->nrows
)
6671 /* Get the glyph area containing X. */
6672 if (w
->pseudo_window_p
)
6679 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6680 if (x
< left_area_width
)
6682 *area
= LEFT_MARGIN_AREA
;
6685 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6688 x0
= row
->x
+ left_area_width
;
6692 *area
= RIGHT_MARGIN_AREA
;
6693 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6697 /* Find glyph containing X. */
6698 glyph
= row
->glyphs
[*area
];
6699 end
= glyph
+ row
->used
[*area
];
6702 if (x
< x0
+ glyph
->pixel_width
)
6704 if (w
->pseudo_window_p
)
6706 else if (!buffer_only_p
|| BUFFERP (glyph
->object
))
6710 x0
+= glyph
->pixel_width
;
6717 *hpos
= glyph
- row
->glyphs
[*area
];
6722 /* Convert frame-relative x/y to coordinates relative to window W.
6723 Takes pseudo-windows into account. */
6726 frame_to_window_pixel_xy (w
, x
, y
)
6730 if (w
->pseudo_window_p
)
6732 /* A pseudo-window is always full-width, and starts at the
6733 left edge of the frame, plus a frame border. */
6734 struct frame
*f
= XFRAME (w
->frame
);
6735 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6736 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6740 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6741 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6746 /* Take proper action when mouse has moved to the mode or header line of
6747 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6748 mode line. X is relative to the start of the text display area of
6749 W, so the width of fringes and scroll bars must be subtracted
6750 to get a position relative to the start of the mode line. */
6753 note_mode_line_highlight (w
, x
, mode_line_p
)
6757 struct frame
*f
= XFRAME (w
->frame
);
6758 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6759 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6760 struct glyph_row
*row
;
6763 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
6765 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
6769 struct glyph
*glyph
, *end
;
6770 Lisp_Object help
, map
;
6773 /* Find the glyph under X. */
6774 glyph
= row
->glyphs
[TEXT_AREA
];
6775 end
= glyph
+ row
->used
[TEXT_AREA
];
6776 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
6777 + FRAME_X_LEFT_FRINGE_WIDTH (f
));
6780 && x
>= x0
+ glyph
->pixel_width
)
6782 x0
+= glyph
->pixel_width
;
6787 && STRINGP (glyph
->object
)
6788 && XSTRING (glyph
->object
)->intervals
6789 && glyph
->charpos
>= 0
6790 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6792 /* If we're on a string with `help-echo' text property,
6793 arrange for the help to be displayed. This is done by
6794 setting the global variable help_echo to the help string. */
6795 help
= Fget_text_property (make_number (glyph
->charpos
),
6796 Qhelp_echo
, glyph
->object
);
6800 XSETWINDOW (help_echo_window
, w
);
6801 help_echo_object
= glyph
->object
;
6802 help_echo_pos
= glyph
->charpos
;
6805 /* Change the mouse pointer according to what is under X/Y. */
6806 map
= Fget_text_property (make_number (glyph
->charpos
),
6807 Qlocal_map
, glyph
->object
);
6809 cursor
= f
->output_data
.x
->nontext_cursor
;
6812 map
= Fget_text_property (make_number (glyph
->charpos
),
6813 Qkeymap
, glyph
->object
);
6815 cursor
= f
->output_data
.x
->nontext_cursor
;
6820 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
6824 /* Take proper action when the mouse has moved to position X, Y on
6825 frame F as regards highlighting characters that have mouse-face
6826 properties. Also de-highlighting chars where the mouse was before.
6827 X and Y can be negative or out of range. */
6830 note_mouse_highlight (f
, x
, y
)
6834 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6838 Cursor cursor
= None
;
6841 /* When a menu is active, don't highlight because this looks odd. */
6842 #ifdef USE_X_TOOLKIT
6843 if (popup_activated ())
6847 if (disable_mouse_highlight
6848 || !f
->glyphs_initialized_p
)
6851 dpyinfo
->mouse_face_mouse_x
= x
;
6852 dpyinfo
->mouse_face_mouse_y
= y
;
6853 dpyinfo
->mouse_face_mouse_frame
= f
;
6855 if (dpyinfo
->mouse_face_defer
)
6860 dpyinfo
->mouse_face_deferred_gc
= 1;
6864 /* Which window is that in? */
6865 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
6867 /* If we were displaying active text in another window, clear that. */
6868 if (! EQ (window
, dpyinfo
->mouse_face_window
))
6869 clear_mouse_face (dpyinfo
);
6871 /* Not on a window -> return. */
6872 if (!WINDOWP (window
))
6875 /* Convert to window-relative pixel coordinates. */
6876 w
= XWINDOW (window
);
6877 frame_to_window_pixel_xy (w
, &x
, &y
);
6879 /* Handle tool-bar window differently since it doesn't display a
6881 if (EQ (window
, f
->tool_bar_window
))
6883 note_tool_bar_highlight (f
, x
, y
);
6887 /* Mouse is on the mode or header line? */
6888 if (portion
== 1 || portion
== 3)
6890 note_mode_line_highlight (w
, x
, portion
== 1);
6895 cursor
= f
->output_data
.x
->horizontal_drag_cursor
;
6897 cursor
= f
->output_data
.x
->text_cursor
;
6899 /* Are we in a window whose display is up to date?
6900 And verify the buffer's text has not changed. */
6901 b
= XBUFFER (w
->buffer
);
6902 if (/* Within text portion of the window. */
6904 && EQ (w
->window_end_valid
, w
->buffer
)
6905 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
6906 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
6908 int hpos
, vpos
, pos
, i
, area
;
6909 struct glyph
*glyph
;
6911 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
6912 Lisp_Object
*overlay_vec
= NULL
;
6914 struct buffer
*obuf
;
6915 int obegv
, ozv
, same_region
;
6917 /* Find the glyph under X/Y. */
6918 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
, 0);
6920 /* Clear mouse face if X/Y not over text. */
6922 || area
!= TEXT_AREA
6923 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
6925 if (clear_mouse_face (dpyinfo
))
6930 pos
= glyph
->charpos
;
6931 object
= glyph
->object
;
6932 if (!STRINGP (object
) && !BUFFERP (object
))
6935 /* If we get an out-of-range value, return now; avoid an error. */
6936 if (BUFFERP (object
) && pos
> BUF_Z (b
))
6939 /* Make the window's buffer temporarily current for
6940 overlays_at and compute_char_face. */
6941 obuf
= current_buffer
;
6948 /* Is this char mouse-active or does it have help-echo? */
6949 position
= make_number (pos
);
6951 if (BUFFERP (object
))
6953 /* Put all the overlays we want in a vector in overlay_vec.
6954 Store the length in len. If there are more than 10, make
6955 enough space for all, and try again. */
6957 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6958 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
6959 if (noverlays
> len
)
6962 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6963 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
6966 /* Sort overlays into increasing priority order. */
6967 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
6972 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
6973 && vpos
>= dpyinfo
->mouse_face_beg_row
6974 && vpos
<= dpyinfo
->mouse_face_end_row
6975 && (vpos
> dpyinfo
->mouse_face_beg_row
6976 || hpos
>= dpyinfo
->mouse_face_beg_col
)
6977 && (vpos
< dpyinfo
->mouse_face_end_row
6978 || hpos
< dpyinfo
->mouse_face_end_col
6979 || dpyinfo
->mouse_face_past_end
));
6984 /* Check mouse-face highlighting. */
6986 /* If there exists an overlay with mouse-face overlapping
6987 the one we are currently highlighting, we have to
6988 check if we enter the overlapping overlay, and then
6989 highlight only that. */
6990 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
6991 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
6993 /* Find the highest priority overlay that has a mouse-face
6996 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
6998 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
6999 if (!NILP (mouse_face
))
7000 overlay
= overlay_vec
[i
];
7003 /* If we're actually highlighting the same overlay as
7004 before, there's no need to do that again. */
7006 && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
7007 goto check_help_echo
;
7009 dpyinfo
->mouse_face_overlay
= overlay
;
7011 /* Clear the display of the old active region, if any. */
7012 if (clear_mouse_face (dpyinfo
))
7015 /* If no overlay applies, get a text property. */
7017 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
7019 /* Handle the overlay case. */
7020 if (!NILP (overlay
))
7022 /* Find the range of text around this char that
7023 should be active. */
7024 Lisp_Object before
, after
;
7027 before
= Foverlay_start (overlay
);
7028 after
= Foverlay_end (overlay
);
7029 /* Record this as the current active region. */
7030 fast_find_position (w
, XFASTINT (before
),
7031 &dpyinfo
->mouse_face_beg_col
,
7032 &dpyinfo
->mouse_face_beg_row
,
7033 &dpyinfo
->mouse_face_beg_x
,
7034 &dpyinfo
->mouse_face_beg_y
, Qnil
);
7036 dpyinfo
->mouse_face_past_end
7037 = !fast_find_position (w
, XFASTINT (after
),
7038 &dpyinfo
->mouse_face_end_col
,
7039 &dpyinfo
->mouse_face_end_row
,
7040 &dpyinfo
->mouse_face_end_x
,
7041 &dpyinfo
->mouse_face_end_y
, Qnil
);
7042 dpyinfo
->mouse_face_window
= window
;
7043 dpyinfo
->mouse_face_face_id
7044 = face_at_buffer_position (w
, pos
, 0, 0,
7045 &ignore
, pos
+ 1, 1);
7047 /* Display it as active. */
7048 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7051 /* Handle the text property case. */
7052 else if (!NILP (mouse_face
) && BUFFERP (object
))
7054 /* Find the range of text around this char that
7055 should be active. */
7056 Lisp_Object before
, after
, beginning
, end
;
7059 beginning
= Fmarker_position (w
->start
);
7060 end
= make_number (BUF_Z (XBUFFER (object
))
7061 - XFASTINT (w
->window_end_pos
));
7063 = Fprevious_single_property_change (make_number (pos
+ 1),
7067 = Fnext_single_property_change (position
, Qmouse_face
,
7070 /* Record this as the current active region. */
7071 fast_find_position (w
, XFASTINT (before
),
7072 &dpyinfo
->mouse_face_beg_col
,
7073 &dpyinfo
->mouse_face_beg_row
,
7074 &dpyinfo
->mouse_face_beg_x
,
7075 &dpyinfo
->mouse_face_beg_y
, Qnil
);
7076 dpyinfo
->mouse_face_past_end
7077 = !fast_find_position (w
, XFASTINT (after
),
7078 &dpyinfo
->mouse_face_end_col
,
7079 &dpyinfo
->mouse_face_end_row
,
7080 &dpyinfo
->mouse_face_end_x
,
7081 &dpyinfo
->mouse_face_end_y
, Qnil
);
7082 dpyinfo
->mouse_face_window
= window
;
7084 if (BUFFERP (object
))
7085 dpyinfo
->mouse_face_face_id
7086 = face_at_buffer_position (w
, pos
, 0, 0,
7087 &ignore
, pos
+ 1, 1);
7089 /* Display it as active. */
7090 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7093 else if (!NILP (mouse_face
) && STRINGP (object
))
7098 b
= Fprevious_single_property_change (make_number (pos
+ 1),
7101 e
= Fnext_single_property_change (position
, Qmouse_face
,
7104 b
= make_number (0);
7106 e
= make_number (XSTRING (object
)->size
- 1);
7107 fast_find_string_pos (w
, XINT (b
), object
,
7108 &dpyinfo
->mouse_face_beg_col
,
7109 &dpyinfo
->mouse_face_beg_row
,
7110 &dpyinfo
->mouse_face_beg_x
,
7111 &dpyinfo
->mouse_face_beg_y
, 0);
7112 fast_find_string_pos (w
, XINT (e
), object
,
7113 &dpyinfo
->mouse_face_end_col
,
7114 &dpyinfo
->mouse_face_end_row
,
7115 &dpyinfo
->mouse_face_end_x
,
7116 &dpyinfo
->mouse_face_end_y
, 1);
7117 dpyinfo
->mouse_face_past_end
= 0;
7118 dpyinfo
->mouse_face_window
= window
;
7119 dpyinfo
->mouse_face_face_id
7120 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
7122 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7125 else if (STRINGP (object
) && NILP (mouse_face
))
7127 /* A string which doesn't have mouse-face, but
7128 the text ``under'' it might have. */
7129 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
7130 int start
= MATRIX_ROW_START_CHARPOS (r
);
7132 pos
= string_buffer_position (w
, object
, start
);
7134 mouse_face
= get_char_property_and_overlay (make_number (pos
),
7138 if (!NILP (mouse_face
) && !NILP (overlay
))
7140 Lisp_Object before
= Foverlay_start (overlay
);
7141 Lisp_Object after
= Foverlay_end (overlay
);
7144 /* Note that we might not be able to find position
7145 BEFORE in the glyph matrix if the overlay is
7146 entirely covered by a `display' property. In
7147 this case, we overshoot. So let's stop in
7148 the glyph matrix before glyphs for OBJECT. */
7149 fast_find_position (w
, XFASTINT (before
),
7150 &dpyinfo
->mouse_face_beg_col
,
7151 &dpyinfo
->mouse_face_beg_row
,
7152 &dpyinfo
->mouse_face_beg_x
,
7153 &dpyinfo
->mouse_face_beg_y
,
7156 dpyinfo
->mouse_face_past_end
7157 = !fast_find_position (w
, XFASTINT (after
),
7158 &dpyinfo
->mouse_face_end_col
,
7159 &dpyinfo
->mouse_face_end_row
,
7160 &dpyinfo
->mouse_face_end_x
,
7161 &dpyinfo
->mouse_face_end_y
,
7163 dpyinfo
->mouse_face_window
= window
;
7164 dpyinfo
->mouse_face_face_id
7165 = face_at_buffer_position (w
, pos
, 0, 0,
7166 &ignore
, pos
+ 1, 1);
7168 /* Display it as active. */
7169 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7177 /* Look for a `help-echo' property. */
7179 Lisp_Object help
, overlay
;
7181 /* Check overlays first. */
7182 help
= overlay
= Qnil
;
7183 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
7185 overlay
= overlay_vec
[i
];
7186 help
= Foverlay_get (overlay
, Qhelp_echo
);
7192 help_echo_window
= window
;
7193 help_echo_object
= overlay
;
7194 help_echo_pos
= pos
;
7198 Lisp_Object object
= glyph
->object
;
7199 int charpos
= glyph
->charpos
;
7201 /* Try text properties. */
7202 if (STRINGP (object
)
7204 && charpos
< XSTRING (object
)->size
)
7206 help
= Fget_text_property (make_number (charpos
),
7207 Qhelp_echo
, object
);
7210 /* If the string itself doesn't specify a help-echo,
7211 see if the buffer text ``under'' it does. */
7213 = MATRIX_ROW (w
->current_matrix
, vpos
);
7214 int start
= MATRIX_ROW_START_CHARPOS (r
);
7215 int pos
= string_buffer_position (w
, object
, start
);
7218 help
= Fget_char_property (make_number (pos
),
7219 Qhelp_echo
, w
->buffer
);
7228 else if (BUFFERP (object
)
7231 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
7237 help_echo_window
= window
;
7238 help_echo_object
= object
;
7239 help_echo_pos
= charpos
;
7246 current_buffer
= obuf
;
7252 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
7256 redo_mouse_highlight ()
7258 if (!NILP (last_mouse_motion_frame
)
7259 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
7260 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
7261 last_mouse_motion_event
.x
,
7262 last_mouse_motion_event
.y
);
7267 /***********************************************************************
7269 ***********************************************************************/
7271 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
7272 struct glyph
**, int *, int *, int *));
7274 /* Tool-bar item index of the item on which a mouse button was pressed
7277 static int last_tool_bar_item
;
7280 /* Get information about the tool-bar item at position X/Y on frame F.
7281 Return in *GLYPH a pointer to the glyph of the tool-bar item in
7282 the current matrix of the tool-bar window of F, or NULL if not
7283 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
7284 item in F->tool_bar_items. Value is
7286 -1 if X/Y is not on a tool-bar item
7287 0 if X/Y is on the same item that was highlighted before.
7291 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
7294 struct glyph
**glyph
;
7295 int *hpos
, *vpos
, *prop_idx
;
7297 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7298 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7301 /* Find the glyph under X/Y. */
7302 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
, 0);
7306 /* Get the start of this tool-bar item's properties in
7307 f->tool_bar_items. */
7308 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
7311 /* Is mouse on the highlighted item? */
7312 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
7313 && *vpos
>= dpyinfo
->mouse_face_beg_row
7314 && *vpos
<= dpyinfo
->mouse_face_end_row
7315 && (*vpos
> dpyinfo
->mouse_face_beg_row
7316 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
7317 && (*vpos
< dpyinfo
->mouse_face_end_row
7318 || *hpos
< dpyinfo
->mouse_face_end_col
7319 || dpyinfo
->mouse_face_past_end
))
7326 /* Handle mouse button event on the tool-bar of frame F, at
7327 frame-relative coordinates X/Y. EVENT_TYPE is either ButtonPress
7331 x_handle_tool_bar_click (f
, button_event
)
7333 XButtonEvent
*button_event
;
7335 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7336 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7337 int hpos
, vpos
, prop_idx
;
7338 struct glyph
*glyph
;
7339 Lisp_Object enabled_p
;
7340 int x
= button_event
->x
;
7341 int y
= button_event
->y
;
7343 /* If not on the highlighted tool-bar item, return. */
7344 frame_to_window_pixel_xy (w
, &x
, &y
);
7345 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
7348 /* If item is disabled, do nothing. */
7349 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7350 if (NILP (enabled_p
))
7353 if (button_event
->type
== ButtonPress
)
7355 /* Show item in pressed state. */
7356 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
7357 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
7358 last_tool_bar_item
= prop_idx
;
7362 Lisp_Object key
, frame
;
7363 struct input_event event
;
7365 /* Show item in released state. */
7366 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
7367 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
7369 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
7371 XSETFRAME (frame
, f
);
7372 event
.kind
= TOOL_BAR_EVENT
;
7373 event
.frame_or_window
= frame
;
7375 kbd_buffer_store_event (&event
);
7377 event
.kind
= TOOL_BAR_EVENT
;
7378 event
.frame_or_window
= frame
;
7380 event
.modifiers
= x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
7381 button_event
->state
);
7382 kbd_buffer_store_event (&event
);
7383 last_tool_bar_item
= -1;
7388 /* Possibly highlight a tool-bar item on frame F when mouse moves to
7389 tool-bar window-relative coordinates X/Y. Called from
7390 note_mouse_highlight. */
7393 note_tool_bar_highlight (f
, x
, y
)
7397 Lisp_Object window
= f
->tool_bar_window
;
7398 struct window
*w
= XWINDOW (window
);
7399 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7401 struct glyph
*glyph
;
7402 struct glyph_row
*row
;
7404 Lisp_Object enabled_p
;
7406 enum draw_glyphs_face draw
;
7407 int mouse_down_p
, rc
;
7409 /* Function note_mouse_highlight is called with negative x(y
7410 values when mouse moves outside of the frame. */
7411 if (x
<= 0 || y
<= 0)
7413 clear_mouse_face (dpyinfo
);
7417 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
7420 /* Not on tool-bar item. */
7421 clear_mouse_face (dpyinfo
);
7427 clear_mouse_face (dpyinfo
);
7429 /* Mouse is down, but on different tool-bar item? */
7430 mouse_down_p
= (dpyinfo
->grabbed
7431 && f
== last_mouse_frame
7432 && FRAME_LIVE_P (f
));
7434 && last_tool_bar_item
!= prop_idx
)
7437 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
7438 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
7440 /* If tool-bar item is not enabled, don't highlight it. */
7441 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7442 if (!NILP (enabled_p
))
7444 /* Compute the x-position of the glyph. In front and past the
7445 image is a space. We include this is the highlighted area. */
7446 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
7447 for (i
= x
= 0; i
< hpos
; ++i
)
7448 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
7450 /* Record this as the current active region. */
7451 dpyinfo
->mouse_face_beg_col
= hpos
;
7452 dpyinfo
->mouse_face_beg_row
= vpos
;
7453 dpyinfo
->mouse_face_beg_x
= x
;
7454 dpyinfo
->mouse_face_beg_y
= row
->y
;
7455 dpyinfo
->mouse_face_past_end
= 0;
7457 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
7458 dpyinfo
->mouse_face_end_row
= vpos
;
7459 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
7460 dpyinfo
->mouse_face_end_y
= row
->y
;
7461 dpyinfo
->mouse_face_window
= window
;
7462 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
7464 /* Display it as active. */
7465 show_mouse_face (dpyinfo
, draw
);
7466 dpyinfo
->mouse_face_image_state
= draw
;
7471 /* Set help_echo to a help string.to display for this tool-bar item.
7472 XTread_socket does the rest. */
7473 help_echo_object
= help_echo_window
= Qnil
;
7475 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
7476 if (NILP (help_echo
))
7477 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
7482 /* Find the glyph matrix position of buffer position CHARPOS in window
7483 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
7484 current glyphs must be up to date. If CHARPOS is above window
7485 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
7486 of last line in W. In the row containing CHARPOS, stop before glyphs
7487 having STOP as object. */
7489 #if 0 /* This is a version of fast_find_position that's more correct
7490 in the presence of hscrolling, for example. I didn't install
7491 it right away because the problem fixed is minor, it failed
7492 in 20.x as well, and I think it's too risky to install
7493 so near the release of 21.1. 2001-09-25 gerd. */
7496 fast_find_position (w
, charpos
, hpos
, vpos
, x
, y
, stop
)
7499 int *hpos
, *vpos
, *x
, *y
;
7502 struct glyph_row
*row
, *first
;
7503 struct glyph
*glyph
, *end
;
7504 int i
, past_end
= 0;
7506 first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7507 row
= row_containing_pos (w
, charpos
, first
, NULL
, 0);
7510 if (charpos
< MATRIX_ROW_START_CHARPOS (first
))
7512 *x
= *y
= *hpos
= *vpos
= 0;
7517 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
7524 *vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7526 glyph
= row
->glyphs
[TEXT_AREA
];
7527 end
= glyph
+ row
->used
[TEXT_AREA
];
7529 /* Skip over glyphs not having an object at the start of the row.
7530 These are special glyphs like truncation marks on terminal
7532 if (row
->displays_text_p
)
7534 && INTEGERP (glyph
->object
)
7535 && !EQ (stop
, glyph
->object
)
7536 && glyph
->charpos
< 0)
7538 *x
+= glyph
->pixel_width
;
7543 && !INTEGERP (glyph
->object
)
7544 && !EQ (stop
, glyph
->object
)
7545 && (!BUFFERP (glyph
->object
)
7546 || glyph
->charpos
< charpos
))
7548 *x
+= glyph
->pixel_width
;
7552 *hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
7559 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
, stop
)
7562 int *hpos
, *vpos
, *x
, *y
;
7567 int maybe_next_line_p
= 0;
7568 int line_start_position
;
7569 int yb
= window_text_bottom_y (w
);
7570 struct glyph_row
*row
, *best_row
;
7571 int row_vpos
, best_row_vpos
;
7574 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7575 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7579 if (row
->used
[TEXT_AREA
])
7580 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
7582 line_start_position
= 0;
7584 if (line_start_position
> pos
)
7586 /* If the position sought is the end of the buffer,
7587 don't include the blank lines at the bottom of the window. */
7588 else if (line_start_position
== pos
7589 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
7591 maybe_next_line_p
= 1;
7594 else if (line_start_position
> 0)
7597 best_row_vpos
= row_vpos
;
7600 if (row
->y
+ row
->height
>= yb
)
7607 /* Find the right column within BEST_ROW. */
7609 current_x
= best_row
->x
;
7610 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
7612 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
7613 int charpos
= glyph
->charpos
;
7615 if (BUFFERP (glyph
->object
))
7620 *vpos
= best_row_vpos
;
7625 else if (charpos
> pos
)
7628 else if (EQ (glyph
->object
, stop
))
7633 current_x
+= glyph
->pixel_width
;
7636 /* If we're looking for the end of the buffer,
7637 and we didn't find it in the line we scanned,
7638 use the start of the following line. */
7639 if (maybe_next_line_p
)
7644 current_x
= best_row
->x
;
7647 *vpos
= best_row_vpos
;
7648 *hpos
= lastcol
+ 1;
7657 /* Find the position of the glyph for position POS in OBJECT in
7658 window W's current matrix, and return in *X/*Y the pixel
7659 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
7661 RIGHT_P non-zero means return the position of the right edge of the
7662 glyph, RIGHT_P zero means return the left edge position.
7664 If no glyph for POS exists in the matrix, return the position of
7665 the glyph with the next smaller position that is in the matrix, if
7666 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
7667 exists in the matrix, return the position of the glyph with the
7668 next larger position in OBJECT.
7670 Value is non-zero if a glyph was found. */
7673 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
7677 int *hpos
, *vpos
, *x
, *y
;
7680 int yb
= window_text_bottom_y (w
);
7681 struct glyph_row
*r
;
7682 struct glyph
*best_glyph
= NULL
;
7683 struct glyph_row
*best_row
= NULL
;
7686 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7687 r
->enabled_p
&& r
->y
< yb
;
7690 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7691 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
7694 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
7695 if (EQ (g
->object
, object
))
7697 if (g
->charpos
== pos
)
7704 else if (best_glyph
== NULL
7705 || ((abs (g
->charpos
- pos
)
7706 < abs (best_glyph
->charpos
- pos
))
7709 : g
->charpos
> pos
)))
7723 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
7727 *x
+= best_glyph
->pixel_width
;
7732 *vpos
= best_row
- w
->current_matrix
->rows
;
7735 return best_glyph
!= NULL
;
7739 /* Display the active region described by mouse_face_*
7740 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7743 show_mouse_face (dpyinfo
, draw
)
7744 struct x_display_info
*dpyinfo
;
7745 enum draw_glyphs_face draw
;
7747 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
7748 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7750 if (/* If window is in the process of being destroyed, don't bother
7752 w
->current_matrix
!= NULL
7753 /* Recognize when we are called to operate on rows that don't exist
7754 anymore. This can happen when a window is split. */
7755 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
7757 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
7758 struct glyph_row
*row
, *first
, *last
;
7760 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
7761 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
7763 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
7765 int start_hpos
, end_hpos
, start_x
;
7767 /* For all but the first row, the highlight starts at column 0. */
7770 start_hpos
= dpyinfo
->mouse_face_beg_col
;
7771 start_x
= dpyinfo
->mouse_face_beg_x
;
7780 end_hpos
= dpyinfo
->mouse_face_end_col
;
7782 end_hpos
= row
->used
[TEXT_AREA
];
7784 if (end_hpos
> start_hpos
)
7786 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
7787 start_hpos
, end_hpos
, draw
, 0);
7790 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
7794 /* When we've written over the cursor, arrange for it to
7795 be displayed again. */
7796 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
7797 x_display_cursor (w
, 1,
7798 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
7799 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
7802 /* Change the mouse cursor. */
7803 if (draw
== DRAW_NORMAL_TEXT
)
7804 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7805 f
->output_data
.x
->text_cursor
);
7806 else if (draw
== DRAW_MOUSE_FACE
)
7807 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7808 f
->output_data
.x
->cross_cursor
);
7810 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7811 f
->output_data
.x
->nontext_cursor
);
7814 /* Clear out the mouse-highlighted active region.
7815 Redraw it un-highlighted first. Value is non-zero if mouse
7816 face was actually drawn unhighlighted. */
7819 clear_mouse_face (dpyinfo
)
7820 struct x_display_info
*dpyinfo
;
7824 if (!NILP (dpyinfo
->mouse_face_window
))
7826 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
7830 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7831 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7832 dpyinfo
->mouse_face_window
= Qnil
;
7833 dpyinfo
->mouse_face_overlay
= Qnil
;
7838 /* Clear any mouse-face on window W. This function is part of the
7839 redisplay interface, and is called from try_window_id and similar
7840 functions to ensure the mouse-highlight is off. */
7843 x_clear_mouse_face (w
)
7846 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
7850 XSETWINDOW (window
, w
);
7851 if (EQ (window
, dpyinfo
->mouse_face_window
))
7852 clear_mouse_face (dpyinfo
);
7857 /* Just discard the mouse face information for frame F, if any.
7858 This is used when the size of F is changed. */
7861 cancel_mouse_face (f
)
7865 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7867 window
= dpyinfo
->mouse_face_window
;
7868 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
7870 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7871 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7872 dpyinfo
->mouse_face_window
= Qnil
;
7877 static int glyph_rect
P_ ((struct frame
*f
, int, int, XRectangle
*));
7880 /* Try to determine frame pixel position and size of the glyph under
7881 frame pixel coordinates X/Y on frame F . Return the position and
7882 size in *RECT. Value is non-zero if we could compute these
7886 glyph_rect (f
, x
, y
, rect
)
7892 int part
, found
= 0;
7894 window
= window_from_coordinates (f
, x
, y
, &part
, 0);
7897 struct window
*w
= XWINDOW (window
);
7898 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7899 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
7901 frame_to_window_pixel_xy (w
, &x
, &y
);
7903 for (; !found
&& r
< end
&& r
->enabled_p
; ++r
)
7906 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7907 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
7910 for (gx
= r
->x
; !found
&& g
< end
; gx
+= g
->pixel_width
, ++g
)
7913 rect
->width
= g
->pixel_width
;
7914 rect
->height
= r
->height
;
7915 rect
->x
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
7916 rect
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
7926 /* Return the current position of the mouse.
7927 *FP should be a frame which indicates which display to ask about.
7929 If the mouse movement started in a scroll bar, set *FP, *BAR_WINDOW,
7930 and *PART to the frame, window, and scroll bar part that the mouse
7931 is over. Set *X and *Y to the portion and whole of the mouse's
7932 position on the scroll bar.
7934 If the mouse movement started elsewhere, set *FP to the frame the
7935 mouse is on, *BAR_WINDOW to nil, and *X and *Y to the character cell
7938 Set *TIME to the server time-stamp for the time at which the mouse
7939 was at this position.
7941 Don't store anything if we don't have a valid set of values to report.
7943 This clears the mouse_moved flag, so we can wait for the next mouse
7947 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
7950 Lisp_Object
*bar_window
;
7951 enum scroll_bar_part
*part
;
7953 unsigned long *time
;
7959 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
7960 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
7966 Window dummy_window
;
7969 Lisp_Object frame
, tail
;
7971 /* Clear the mouse-moved flag for every frame on this display. */
7972 FOR_EACH_FRAME (tail
, frame
)
7973 if (FRAME_X_DISPLAY (XFRAME (frame
)) == FRAME_X_DISPLAY (*fp
))
7974 XFRAME (frame
)->mouse_moved
= 0;
7976 last_mouse_scroll_bar
= Qnil
;
7978 /* Figure out which root window we're on. */
7979 XQueryPointer (FRAME_X_DISPLAY (*fp
),
7980 DefaultRootWindow (FRAME_X_DISPLAY (*fp
)),
7982 /* The root window which contains the pointer. */
7985 /* Trash which we can't trust if the pointer is on
7986 a different screen. */
7989 /* The position on that root window. */
7992 /* More trash we can't trust. */
7995 /* Modifier keys and pointer buttons, about which
7997 (unsigned int *) &dummy
);
7999 /* Now we have a position on the root; find the innermost window
8000 containing the pointer. */
8004 int parent_x
= 0, parent_y
= 0;
8009 /* XTranslateCoordinates can get errors if the window
8010 structure is changing at the same time this function
8011 is running. So at least we must not crash from them. */
8013 count
= x_catch_errors (FRAME_X_DISPLAY (*fp
));
8015 if (FRAME_X_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
8016 && FRAME_LIVE_P (last_mouse_frame
))
8018 /* If mouse was grabbed on a frame, give coords for that frame
8019 even if the mouse is now outside it. */
8020 XTranslateCoordinates (FRAME_X_DISPLAY (*fp
),
8022 /* From-window, to-window. */
8023 root
, FRAME_X_WINDOW (last_mouse_frame
),
8025 /* From-position, to-position. */
8026 root_x
, root_y
, &win_x
, &win_y
,
8030 f1
= last_mouse_frame
;
8036 XTranslateCoordinates (FRAME_X_DISPLAY (*fp
),
8038 /* From-window, to-window. */
8041 /* From-position, to-position. */
8042 root_x
, root_y
, &win_x
, &win_y
,
8047 if (child
== None
|| child
== win
)
8055 /* Now we know that:
8056 win is the innermost window containing the pointer
8057 (XTC says it has no child containing the pointer),
8058 win_x and win_y are the pointer's position in it
8059 (XTC did this the last time through), and
8060 parent_x and parent_y are the pointer's position in win's parent.
8061 (They are what win_x and win_y were when win was child.
8062 If win is the root window, it has no parent, and
8063 parent_{x,y} are invalid, but that's okay, because we'll
8064 never use them in that case.) */
8066 /* Is win one of our frames? */
8067 f1
= x_any_window_to_frame (FRAME_X_DISPLAY_INFO (*fp
), win
);
8069 #ifdef USE_X_TOOLKIT
8070 /* If we end up with the menu bar window, say it's not
8073 && f1
->output_data
.x
->menubar_widget
8074 && win
== XtWindow (f1
->output_data
.x
->menubar_widget
))
8076 #endif /* USE_X_TOOLKIT */
8079 if (x_had_errors_p (FRAME_X_DISPLAY (*fp
)))
8082 x_uncatch_errors (FRAME_X_DISPLAY (*fp
), count
);
8084 /* If not, is it one of our scroll bars? */
8087 struct scroll_bar
*bar
= x_window_to_scroll_bar (win
);
8091 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8097 if (f1
== 0 && insist
> 0)
8098 f1
= SELECTED_FRAME ();
8102 /* Ok, we found a frame. Store all the values.
8103 last_mouse_glyph is a rectangle used to reduce the
8104 generation of mouse events. To not miss any motion
8105 events, we must divide the frame into rectangles of the
8106 size of the smallest character that could be displayed
8107 on it, i.e. into the same rectangles that matrices on
8108 the frame are divided into. */
8110 int width
, height
, gx
, gy
;
8113 if (glyph_rect (f1
, win_x
, win_y
, &rect
))
8114 last_mouse_glyph
= rect
;
8117 width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
8118 height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
8122 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
8123 round down even for negative values. */
8128 gx
= (gx
+ width
- 1) / width
* width
;
8129 gy
= (gy
+ height
- 1) / height
* height
;
8131 last_mouse_glyph
.width
= width
;
8132 last_mouse_glyph
.height
= height
;
8133 last_mouse_glyph
.x
= gx
;
8134 last_mouse_glyph
.y
= gy
;
8140 XSETINT (*x
, win_x
);
8141 XSETINT (*y
, win_y
);
8142 *time
= last_mouse_movement_time
;
8151 #ifdef USE_X_TOOLKIT
8153 /* Atimer callback function for TIMER. Called every 0.1s to process
8154 Xt timeouts, if needed. We must avoid calling XtAppPending as
8155 much as possible because that function does an implicit XFlush
8156 that slows us down. */
8159 x_process_timeouts (timer
)
8160 struct atimer
*timer
;
8162 if (toolkit_scroll_bar_interaction
|| popup_activated_flag
)
8165 while (XtAppPending (Xt_app_con
) & XtIMTimer
)
8166 XtAppProcessEvent (Xt_app_con
, XtIMTimer
);
8171 #endif /* USE_X_TOOLKIT */
8174 /* Scroll bar support. */
8176 /* Given an X window ID, find the struct scroll_bar which manages it.
8177 This can be called in GC, so we have to make sure to strip off mark
8180 static struct scroll_bar
*
8181 x_window_to_scroll_bar (window_id
)
8186 for (tail
= Vframe_list
;
8187 XGCTYPE (tail
) == Lisp_Cons
;
8190 Lisp_Object frame
, bar
, condemned
;
8192 frame
= XCAR (tail
);
8193 /* All elements of Vframe_list should be frames. */
8194 if (! GC_FRAMEP (frame
))
8197 /* Scan this frame's scroll bar list for a scroll bar with the
8199 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
8200 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
8201 /* This trick allows us to search both the ordinary and
8202 condemned scroll bar lists with one loop. */
8203 ! GC_NILP (bar
) || (bar
= condemned
,
8206 bar
= XSCROLL_BAR (bar
)->next
)
8207 if (SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
8208 return XSCROLL_BAR (bar
);
8215 #if defined USE_LUCID
8217 /* Return the Lucid menu bar WINDOW is part of. Return null
8218 if WINDOW is not part of a menu bar. */
8221 x_window_to_menu_bar (window
)
8226 for (tail
= Vframe_list
;
8227 XGCTYPE (tail
) == Lisp_Cons
;
8230 Lisp_Object frame
= XCAR (tail
);
8231 Widget menu_bar
= XFRAME (frame
)->output_data
.x
->menubar_widget
;
8233 if (menu_bar
&& xlwmenu_window_p (menu_bar
, window
))
8240 #endif /* USE_LUCID */
8243 /************************************************************************
8245 ************************************************************************/
8247 #ifdef USE_TOOLKIT_SCROLL_BARS
8249 static void x_scroll_bar_to_input_event
P_ ((XEvent
*, struct input_event
*));
8250 static void x_send_scroll_bar_event
P_ ((Lisp_Object
, int, int, int));
8251 static void x_create_toolkit_scroll_bar
P_ ((struct frame
*,
8252 struct scroll_bar
*));
8253 static void x_set_toolkit_scroll_bar_thumb
P_ ((struct scroll_bar
*,
8257 /* Id of action hook installed for scroll bars. */
8259 static XtActionHookId action_hook_id
;
8261 /* Lisp window being scrolled. Set when starting to interact with
8262 a toolkit scroll bar, reset to nil when ending the interaction. */
8264 static Lisp_Object window_being_scrolled
;
8266 /* Last scroll bar part sent in xm_scroll_callback. */
8268 static int last_scroll_bar_part
;
8270 /* Whether this is an Xaw with arrow-scrollbars. This should imply
8271 that movements of 1/20 of the screen size are mapped to up/down. */
8273 static Boolean xaw3d_arrow_scroll
;
8275 /* Whether the drag scrolling maintains the mouse at the top of the
8276 thumb. If not, resizing the thumb needs to be done more carefully
8277 to avoid jerkyness. */
8279 static Boolean xaw3d_pick_top
;
8282 /* Action hook installed via XtAppAddActionHook when toolkit scroll
8283 bars are used.. The hook is responsible for detecting when
8284 the user ends an interaction with the scroll bar, and generates
8285 a `end-scroll' scroll_bar_click' event if so. */
8288 xt_action_hook (widget
, client_data
, action_name
, event
, params
,
8291 XtPointer client_data
;
8295 Cardinal
*num_params
;
8301 scroll_bar_p
= XmIsScrollBar (widget
);
8302 end_action
= "Release";
8303 #else /* !USE_MOTIF i.e. use Xaw */
8304 scroll_bar_p
= XtIsSubclass (widget
, scrollbarWidgetClass
);
8305 end_action
= "EndScroll";
8306 #endif /* USE_MOTIF */
8309 && strcmp (action_name
, end_action
) == 0
8310 && WINDOWP (window_being_scrolled
))
8314 x_send_scroll_bar_event (window_being_scrolled
,
8315 scroll_bar_end_scroll
, 0, 0);
8316 w
= XWINDOW (window_being_scrolled
);
8317 XSCROLL_BAR (w
->vertical_scroll_bar
)->dragging
= Qnil
;
8318 window_being_scrolled
= Qnil
;
8319 last_scroll_bar_part
= -1;
8321 /* Xt timeouts no longer needed. */
8322 toolkit_scroll_bar_interaction
= 0;
8326 /* A vector of windows used for communication between
8327 x_send_scroll_bar_event and x_scroll_bar_to_input_event. */
8329 static struct window
**scroll_bar_windows
;
8330 static int scroll_bar_windows_size
;
8333 /* Send a client message with message type Xatom_Scrollbar for a
8334 scroll action to the frame of WINDOW. PART is a value identifying
8335 the part of the scroll bar that was clicked on. PORTION is the
8336 amount to scroll of a whole of WHOLE. */
8339 x_send_scroll_bar_event (window
, part
, portion
, whole
)
8341 int part
, portion
, whole
;
8344 XClientMessageEvent
*ev
= (XClientMessageEvent
*) &event
;
8345 struct window
*w
= XWINDOW (window
);
8346 struct frame
*f
= XFRAME (w
->frame
);
8351 /* Construct a ClientMessage event to send to the frame. */
8352 ev
->type
= ClientMessage
;
8353 ev
->message_type
= FRAME_X_DISPLAY_INFO (f
)->Xatom_Scrollbar
;
8354 ev
->display
= FRAME_X_DISPLAY (f
);
8355 ev
->window
= FRAME_X_WINDOW (f
);
8358 /* We can only transfer 32 bits in the XClientMessageEvent, which is
8359 not enough to store a pointer or Lisp_Object on a 64 bit system.
8360 So, store the window in scroll_bar_windows and pass the index
8361 into that array in the event. */
8362 for (i
= 0; i
< scroll_bar_windows_size
; ++i
)
8363 if (scroll_bar_windows
[i
] == NULL
)
8366 if (i
== scroll_bar_windows_size
)
8368 int new_size
= max (10, 2 * scroll_bar_windows_size
);
8369 size_t nbytes
= new_size
* sizeof *scroll_bar_windows
;
8370 size_t old_nbytes
= scroll_bar_windows_size
* sizeof *scroll_bar_windows
;
8372 scroll_bar_windows
= (struct window
**) xrealloc (scroll_bar_windows
,
8374 bzero (&scroll_bar_windows
[i
], nbytes
- old_nbytes
);
8375 scroll_bar_windows_size
= new_size
;
8378 scroll_bar_windows
[i
] = w
;
8379 ev
->data
.l
[0] = (long) i
;
8380 ev
->data
.l
[1] = (long) part
;
8381 ev
->data
.l
[2] = (long) 0;
8382 ev
->data
.l
[3] = (long) portion
;
8383 ev
->data
.l
[4] = (long) whole
;
8385 /* Make Xt timeouts work while the scroll bar is active. */
8386 toolkit_scroll_bar_interaction
= 1;
8388 /* Setting the event mask to zero means that the message will
8389 be sent to the client that created the window, and if that
8390 window no longer exists, no event will be sent. */
8391 XSendEvent (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), False
, 0, &event
);
8396 /* Transform a scroll bar ClientMessage EVENT to an Emacs input event
8400 x_scroll_bar_to_input_event (event
, ievent
)
8402 struct input_event
*ievent
;
8404 XClientMessageEvent
*ev
= (XClientMessageEvent
*) event
;
8409 w
= scroll_bar_windows
[ev
->data
.l
[0]];
8410 scroll_bar_windows
[ev
->data
.l
[0]] = NULL
;
8412 XSETWINDOW (window
, w
);
8413 f
= XFRAME (w
->frame
);
8415 ievent
->kind
= scroll_bar_click
;
8416 ievent
->frame_or_window
= window
;
8418 ievent
->timestamp
= XtLastTimestampProcessed (FRAME_X_DISPLAY (f
));
8419 ievent
->part
= ev
->data
.l
[1];
8420 ievent
->code
= ev
->data
.l
[2];
8421 ievent
->x
= make_number ((int) ev
->data
.l
[3]);
8422 ievent
->y
= make_number ((int) ev
->data
.l
[4]);
8423 ievent
->modifiers
= 0;
8429 /* Minimum and maximum values used for Motif scroll bars. */
8432 #define XM_SB_MAX 10000000
8433 #define XM_SB_RANGE (XM_SB_MAX - XM_SB_MIN)
8436 /* Scroll bar callback for Motif scroll bars. WIDGET is the scroll
8437 bar widget. CLIENT_DATA is a pointer to the scroll_bar structure.
8438 CALL_DATA is a pointer a a XmScrollBarCallbackStruct. */
8441 xm_scroll_callback (widget
, client_data
, call_data
)
8443 XtPointer client_data
, call_data
;
8445 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
8446 XmScrollBarCallbackStruct
*cs
= (XmScrollBarCallbackStruct
*) call_data
;
8447 int part
= -1, whole
= 0, portion
= 0;
8451 case XmCR_DECREMENT
:
8452 bar
->dragging
= Qnil
;
8453 part
= scroll_bar_up_arrow
;
8456 case XmCR_INCREMENT
:
8457 bar
->dragging
= Qnil
;
8458 part
= scroll_bar_down_arrow
;
8461 case XmCR_PAGE_DECREMENT
:
8462 bar
->dragging
= Qnil
;
8463 part
= scroll_bar_above_handle
;
8466 case XmCR_PAGE_INCREMENT
:
8467 bar
->dragging
= Qnil
;
8468 part
= scroll_bar_below_handle
;
8472 bar
->dragging
= Qnil
;
8473 part
= scroll_bar_to_top
;
8476 case XmCR_TO_BOTTOM
:
8477 bar
->dragging
= Qnil
;
8478 part
= scroll_bar_to_bottom
;
8484 int dragging_down_p
= (INTEGERP (bar
->dragging
)
8485 && XINT (bar
->dragging
) <= cs
->value
);
8487 /* Get the slider size. */
8489 XtVaGetValues (widget
, XmNsliderSize
, &slider_size
, NULL
);
8492 /* At the max position of the scroll bar, do a line-wise
8493 movement. Without doing anything, we would be called with
8494 the same cs->value again and again. If we want to make
8495 sure that we can reach the end of the buffer, we have to do
8498 Implementation note: setting bar->dragging always to
8499 cs->value gives a smoother movement at the max position.
8500 Setting it to nil when doing line-wise movement gives
8501 a better slider behavior. */
8503 if (cs
->value
+ slider_size
== XM_SB_MAX
8505 && last_scroll_bar_part
== scroll_bar_down_arrow
))
8507 part
= scroll_bar_down_arrow
;
8508 bar
->dragging
= Qnil
;
8512 whole
= XM_SB_RANGE
;
8513 portion
= min (cs
->value
- XM_SB_MIN
, XM_SB_MAX
- slider_size
);
8514 part
= scroll_bar_handle
;
8515 bar
->dragging
= make_number (cs
->value
);
8520 case XmCR_VALUE_CHANGED
:
8526 window_being_scrolled
= bar
->window
;
8527 last_scroll_bar_part
= part
;
8528 x_send_scroll_bar_event (bar
->window
, part
, portion
, whole
);
8533 #else /* !USE_MOTIF, i.e. Xaw. */
8536 /* Xaw scroll bar callback. Invoked when the thumb is dragged.
8537 WIDGET is the scroll bar widget. CLIENT_DATA is a pointer to the
8538 scroll bar struct. CALL_DATA is a pointer to a float saying where
8542 xaw_jump_callback (widget
, client_data
, call_data
)
8544 XtPointer client_data
, call_data
;
8546 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
8547 float top
= *(float *) call_data
;
8549 int whole
, portion
, height
;
8552 /* Get the size of the thumb, a value between 0 and 1. */
8554 XtVaGetValues (widget
, XtNshown
, &shown
, XtNheight
, &height
, NULL
);
8558 portion
= shown
< 1 ? top
* whole
: 0;
8560 if (shown
< 1 && (abs (top
+ shown
- 1) < 1.0/height
))
8561 /* Some derivatives of Xaw refuse to shrink the thumb when you reach
8562 the bottom, so we force the scrolling whenever we see that we're
8563 too close to the bottom (in x_set_toolkit_scroll_bar_thumb
8564 we try to ensure that we always stay two pixels away from the
8566 part
= scroll_bar_down_arrow
;
8568 part
= scroll_bar_handle
;
8570 window_being_scrolled
= bar
->window
;
8571 bar
->dragging
= make_number (portion
);
8572 last_scroll_bar_part
= part
;
8573 x_send_scroll_bar_event (bar
->window
, part
, portion
, whole
);
8577 /* Xaw scroll bar callback. Invoked for incremental scrolling.,
8578 i.e. line or page up or down. WIDGET is the Xaw scroll bar
8579 widget. CLIENT_DATA is a pointer to the scroll_bar structure for
8580 the scroll bar. CALL_DATA is an integer specifying the action that
8581 has taken place. It's magnitude is in the range 0..height of the
8582 scroll bar. Negative values mean scroll towards buffer start.
8583 Values < height of scroll bar mean line-wise movement. */
8586 xaw_scroll_callback (widget
, client_data
, call_data
)
8588 XtPointer client_data
, call_data
;
8590 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
8591 int position
= (int) call_data
;
8595 /* Get the height of the scroll bar. */
8597 XtVaGetValues (widget
, XtNheight
, &height
, NULL
);
8600 if (abs (position
) >= height
)
8601 part
= (position
< 0) ? scroll_bar_above_handle
: scroll_bar_below_handle
;
8603 /* If Xaw3d was compiled with ARROW_SCROLLBAR,
8604 it maps line-movement to call_data = max(5, height/20). */
8605 else if (xaw3d_arrow_scroll
&& abs (position
) <= max (5, height
/ 20))
8606 part
= (position
< 0) ? scroll_bar_up_arrow
: scroll_bar_down_arrow
;
8608 part
= scroll_bar_move_ratio
;
8610 window_being_scrolled
= bar
->window
;
8611 bar
->dragging
= Qnil
;
8612 last_scroll_bar_part
= part
;
8613 x_send_scroll_bar_event (bar
->window
, part
, position
, height
);
8617 #endif /* not USE_MOTIF */
8620 /* Create the widget for scroll bar BAR on frame F. Record the widget
8621 and X window of the scroll bar in BAR. */
8624 x_create_toolkit_scroll_bar (f
, bar
)
8626 struct scroll_bar
*bar
;
8632 char *scroll_bar_name
= "verticalScrollBar";
8633 unsigned long pixel
;
8638 /* Set resources. Create the widget. */
8639 XtSetArg (av
[ac
], XtNmappedWhenManaged
, False
); ++ac
;
8640 XtSetArg (av
[ac
], XmNminimum
, XM_SB_MIN
); ++ac
;
8641 XtSetArg (av
[ac
], XmNmaximum
, XM_SB_MAX
); ++ac
;
8642 XtSetArg (av
[ac
], XmNorientation
, XmVERTICAL
); ++ac
;
8643 XtSetArg (av
[ac
], XmNprocessingDirection
, XmMAX_ON_BOTTOM
), ++ac
;
8644 XtSetArg (av
[ac
], XmNincrement
, 1); ++ac
;
8645 XtSetArg (av
[ac
], XmNpageIncrement
, 1); ++ac
;
8647 pixel
= f
->output_data
.x
->scroll_bar_foreground_pixel
;
8650 XtSetArg (av
[ac
], XmNforeground
, pixel
);
8654 pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8657 XtSetArg (av
[ac
], XmNbackground
, pixel
);
8661 widget
= XmCreateScrollBar (f
->output_data
.x
->edit_widget
,
8662 scroll_bar_name
, av
, ac
);
8664 /* Add one callback for everything that can happen. */
8665 XtAddCallback (widget
, XmNdecrementCallback
, xm_scroll_callback
,
8667 XtAddCallback (widget
, XmNdragCallback
, xm_scroll_callback
,
8669 XtAddCallback (widget
, XmNincrementCallback
, xm_scroll_callback
,
8671 XtAddCallback (widget
, XmNpageDecrementCallback
, xm_scroll_callback
,
8673 XtAddCallback (widget
, XmNpageIncrementCallback
, xm_scroll_callback
,
8675 XtAddCallback (widget
, XmNtoBottomCallback
, xm_scroll_callback
,
8677 XtAddCallback (widget
, XmNtoTopCallback
, xm_scroll_callback
,
8680 /* Realize the widget. Only after that is the X window created. */
8681 XtRealizeWidget (widget
);
8683 /* Set the cursor to an arrow. I didn't find a resource to do that.
8684 And I'm wondering why it hasn't an arrow cursor by default. */
8685 XDefineCursor (XtDisplay (widget
), XtWindow (widget
),
8686 f
->output_data
.x
->nontext_cursor
);
8688 #else /* !USE_MOTIF i.e. use Xaw */
8690 /* Set resources. Create the widget. The background of the
8691 Xaw3d scroll bar widget is a little bit light for my taste.
8692 We don't alter it here to let users change it according
8693 to their taste with `emacs*verticalScrollBar.background: xxx'. */
8694 XtSetArg (av
[ac
], XtNmappedWhenManaged
, False
); ++ac
;
8695 XtSetArg (av
[ac
], XtNorientation
, XtorientVertical
); ++ac
;
8696 /* For smoother scrolling with Xaw3d -sm */
8697 /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */
8699 pixel
= f
->output_data
.x
->scroll_bar_foreground_pixel
;
8702 XtSetArg (av
[ac
], XtNforeground
, pixel
);
8706 pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8709 XtSetArg (av
[ac
], XtNbackground
, pixel
);
8713 /* Top/bottom shadow colors. */
8715 /* Allocate them, if necessary. */
8716 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
== -1)
8718 pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8719 if (!x_alloc_lighter_color (f
, FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
8720 &pixel
, 1.2, 0x8000))
8722 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= pixel
;
8724 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
== -1)
8726 pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8727 if (!x_alloc_lighter_color (f
, FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
8728 &pixel
, 0.6, 0x4000))
8730 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= pixel
;
8733 /* Tell the toolkit about them. */
8734 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
== -1
8735 || f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
== -1)
8736 /* We tried to allocate a color for the top/bottom shadow, and
8737 failed, so tell Xaw3d to use dithering instead. */
8739 XtSetArg (av
[ac
], XtNbeNiceToColormap
, True
);
8743 /* Tell what colors Xaw3d should use for the top/bottom shadow, to
8744 be more consistent with other emacs 3d colors, and since Xaw3d is
8745 not good at dealing with allocation failure. */
8747 /* This tells Xaw3d to use real colors instead of dithering for
8749 XtSetArg (av
[ac
], XtNbeNiceToColormap
, False
);
8752 /* Specify the colors. */
8753 pixel
= f
->output_data
.x
->scroll_bar_top_shadow_pixel
;
8756 XtSetArg (av
[ac
], "topShadowPixel", pixel
);
8759 pixel
= f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
;
8762 XtSetArg (av
[ac
], "bottomShadowPixel", pixel
);
8767 widget
= XtCreateWidget (scroll_bar_name
, scrollbarWidgetClass
,
8768 f
->output_data
.x
->edit_widget
, av
, ac
);
8772 char *val
= initial
;
8773 XtVaGetValues (widget
, XtNscrollVCursor
, (XtPointer
) &val
,
8774 XtNpickTop
, (XtPointer
) &xaw3d_pick_top
, NULL
);
8776 { /* ARROW_SCROLL */
8777 xaw3d_arrow_scroll
= True
;
8778 /* Isn't that just a personal preference ? -sm */
8779 XtVaSetValues (widget
, XtNcursorName
, "top_left_arrow", NULL
);
8783 /* Define callbacks. */
8784 XtAddCallback (widget
, XtNjumpProc
, xaw_jump_callback
, (XtPointer
) bar
);
8785 XtAddCallback (widget
, XtNscrollProc
, xaw_scroll_callback
,
8788 /* Realize the widget. Only after that is the X window created. */
8789 XtRealizeWidget (widget
);
8791 #endif /* !USE_MOTIF */
8793 /* Install an action hook that let's us detect when the user
8794 finishes interacting with a scroll bar. */
8795 if (action_hook_id
== 0)
8796 action_hook_id
= XtAppAddActionHook (Xt_app_con
, xt_action_hook
, 0);
8798 /* Remember X window and widget in the scroll bar vector. */
8799 SET_SCROLL_BAR_X_WIDGET (bar
, widget
);
8800 xwindow
= XtWindow (widget
);
8801 SET_SCROLL_BAR_X_WINDOW (bar
, xwindow
);
8807 /* Set the thumb size and position of scroll bar BAR. We are currently
8808 displaying PORTION out of a whole WHOLE, and our position POSITION. */
8811 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
)
8812 struct scroll_bar
*bar
;
8813 int portion
, position
, whole
;
8815 struct frame
*f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8816 Widget widget
= SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
);
8823 top
= (float) position
/ whole
;
8824 shown
= (float) portion
/ whole
;
8833 /* Slider size. Must be in the range [1 .. MAX - MIN] where MAX
8834 is the scroll bar's maximum and MIN is the scroll bar's minimum
8836 size
= shown
* XM_SB_RANGE
;
8837 size
= min (size
, XM_SB_RANGE
);
8838 size
= max (size
, 1);
8840 /* Position. Must be in the range [MIN .. MAX - SLIDER_SIZE]. */
8841 value
= top
* XM_SB_RANGE
;
8842 value
= min (value
, XM_SB_MAX
- size
);
8843 value
= max (value
, XM_SB_MIN
);
8845 if (NILP (bar
->dragging
))
8846 XmScrollBarSetValues (widget
, value
, size
, 0, 0, False
);
8847 else if (last_scroll_bar_part
== scroll_bar_down_arrow
)
8848 /* This has the negative side effect that the slider value is
8849 not what it would be if we scrolled here using line-wise or
8850 page-wise movement. */
8851 XmScrollBarSetValues (widget
, value
, XM_SB_RANGE
- value
, 0, 0, False
);
8854 /* If currently dragging, only update the slider size.
8855 This reduces flicker effects. */
8856 int old_value
, old_size
, increment
, page_increment
;
8858 XmScrollBarGetValues (widget
, &old_value
, &old_size
,
8859 &increment
, &page_increment
);
8860 XmScrollBarSetValues (widget
, old_value
,
8861 min (size
, XM_SB_RANGE
- old_value
),
8865 #else /* !USE_MOTIF i.e. use Xaw */
8867 float old_top
, old_shown
;
8869 XtVaGetValues (widget
,
8870 XtNtopOfThumb
, &old_top
,
8871 XtNshown
, &old_shown
,
8875 /* Massage the top+shown values. */
8876 if (NILP (bar
->dragging
) || last_scroll_bar_part
== scroll_bar_down_arrow
)
8877 top
= max (0, min (1, top
));
8880 /* Keep two pixels available for moving the thumb down. */
8881 shown
= max (0, min (1 - top
- (2.0 / height
), shown
));
8883 /* If the call to XawScrollbarSetThumb below doesn't seem to work,
8884 check that your system's configuration file contains a define
8885 for `NARROWPROTO'. See s/freebsd.h for an example. */
8886 if (top
!= old_top
|| shown
!= old_shown
)
8888 if (NILP (bar
->dragging
))
8889 XawScrollbarSetThumb (widget
, top
, shown
);
8893 ScrollbarWidget sb
= (ScrollbarWidget
) widget
;
8894 int scroll_mode
= 0;
8896 /* `scroll_mode' only exists with Xaw3d + ARROW_SCROLLBAR. */
8897 if (xaw3d_arrow_scroll
)
8899 /* Xaw3d stupidly ignores resize requests while dragging
8900 so we have to make it believe it's not in dragging mode. */
8901 scroll_mode
= sb
->scrollbar
.scroll_mode
;
8902 if (scroll_mode
== 2)
8903 sb
->scrollbar
.scroll_mode
= 0;
8906 /* Try to make the scrolling a tad smoother. */
8907 if (!xaw3d_pick_top
)
8908 shown
= min (shown
, old_shown
);
8910 XawScrollbarSetThumb (widget
, top
, shown
);
8913 if (xaw3d_arrow_scroll
&& scroll_mode
== 2)
8914 sb
->scrollbar
.scroll_mode
= scroll_mode
;
8919 #endif /* !USE_MOTIF */
8924 #endif /* USE_TOOLKIT_SCROLL_BARS */
8928 /************************************************************************
8929 Scroll bars, general
8930 ************************************************************************/
8932 /* Create a scroll bar and return the scroll bar vector for it. W is
8933 the Emacs window on which to create the scroll bar. TOP, LEFT,
8934 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
8937 static struct scroll_bar
*
8938 x_scroll_bar_create (w
, top
, left
, width
, height
)
8940 int top
, left
, width
, height
;
8942 struct frame
*f
= XFRAME (w
->frame
);
8943 struct scroll_bar
*bar
8944 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
8948 #ifdef USE_TOOLKIT_SCROLL_BARS
8949 x_create_toolkit_scroll_bar (f
, bar
);
8950 #else /* not USE_TOOLKIT_SCROLL_BARS */
8952 XSetWindowAttributes a
;
8956 a
.background_pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8957 if (a
.background_pixel
== -1)
8958 a
.background_pixel
= f
->output_data
.x
->background_pixel
;
8960 a
.event_mask
= (ButtonPressMask
| ButtonReleaseMask
8961 | ButtonMotionMask
| PointerMotionHintMask
8963 a
.cursor
= FRAME_X_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
8965 mask
= (CWBackPixel
| CWEventMask
| CWCursor
);
8967 /* Clear the area of W that will serve as a scroll bar. This is
8968 for the case that a window has been split horizontally. In
8969 this case, no clear_frame is generated to reduce flickering. */
8970 if (width
> 0 && height
> 0)
8971 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8973 window_box_height (w
), False
);
8975 window
= XCreateWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8976 /* Position and size of scroll bar. */
8977 left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8979 width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8981 /* Border width, depth, class, and visual. */
8988 SET_SCROLL_BAR_X_WINDOW (bar
, window
);
8990 #endif /* not USE_TOOLKIT_SCROLL_BARS */
8992 XSETWINDOW (bar
->window
, w
);
8993 XSETINT (bar
->top
, top
);
8994 XSETINT (bar
->left
, left
);
8995 XSETINT (bar
->width
, width
);
8996 XSETINT (bar
->height
, height
);
8997 XSETINT (bar
->start
, 0);
8998 XSETINT (bar
->end
, 0);
8999 bar
->dragging
= Qnil
;
9001 /* Add bar to its frame's list of scroll bars. */
9002 bar
->next
= FRAME_SCROLL_BARS (f
);
9004 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
9005 if (!NILP (bar
->next
))
9006 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
9008 /* Map the window/widget. */
9009 #ifdef USE_TOOLKIT_SCROLL_BARS
9011 Widget scroll_bar
= SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
);
9012 XtConfigureWidget (scroll_bar
,
9013 left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9015 width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
9016 max (height
, 1), 0);
9017 XtMapWidget (scroll_bar
);
9019 #else /* not USE_TOOLKIT_SCROLL_BARS */
9020 XMapRaised (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
));
9021 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9028 /* Draw BAR's handle in the proper position.
9030 If the handle is already drawn from START to END, don't bother
9031 redrawing it, unless REBUILD is non-zero; in that case, always
9032 redraw it. (REBUILD is handy for drawing the handle after expose
9035 Normally, we want to constrain the start and end of the handle to
9036 fit inside its rectangle, but if the user is dragging the scroll
9037 bar handle, we want to let them drag it down all the way, so that
9038 the bar's top is as far down as it goes; otherwise, there's no way
9039 to move to the very end of the buffer. */
9041 #ifndef USE_TOOLKIT_SCROLL_BARS
9044 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
9045 struct scroll_bar
*bar
;
9049 int dragging
= ! NILP (bar
->dragging
);
9050 Window w
= SCROLL_BAR_X_WINDOW (bar
);
9051 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9052 GC gc
= f
->output_data
.x
->normal_gc
;
9054 /* If the display is already accurate, do nothing. */
9056 && start
== XINT (bar
->start
)
9057 && end
== XINT (bar
->end
))
9063 int inside_width
= VERTICAL_SCROLL_BAR_INSIDE_WIDTH (f
, XINT (bar
->width
));
9064 int inside_height
= VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
9065 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
9067 /* Make sure the values are reasonable, and try to preserve
9068 the distance between start and end. */
9070 int length
= end
- start
;
9074 else if (start
> top_range
)
9076 end
= start
+ length
;
9080 else if (end
> top_range
&& ! dragging
)
9084 /* Store the adjusted setting in the scroll bar. */
9085 XSETINT (bar
->start
, start
);
9086 XSETINT (bar
->end
, end
);
9088 /* Clip the end position, just for display. */
9089 if (end
> top_range
)
9092 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels
9093 below top positions, to make sure the handle is always at least
9094 that many pixels tall. */
9095 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
9097 /* Draw the empty space above the handle. Note that we can't clear
9098 zero-height areas; that means "clear to end of window." */
9100 x_clear_area (FRAME_X_DISPLAY (f
), w
,
9101 /* x, y, width, height, and exposures. */
9102 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
9103 VERTICAL_SCROLL_BAR_TOP_BORDER
,
9104 inside_width
, start
,
9107 /* Change to proper foreground color if one is specified. */
9108 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
9109 XSetForeground (FRAME_X_DISPLAY (f
), gc
,
9110 f
->output_data
.x
->scroll_bar_foreground_pixel
);
9112 /* Draw the handle itself. */
9113 XFillRectangle (FRAME_X_DISPLAY (f
), w
, gc
,
9114 /* x, y, width, height */
9115 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
9116 VERTICAL_SCROLL_BAR_TOP_BORDER
+ start
,
9117 inside_width
, end
- start
);
9119 /* Restore the foreground color of the GC if we changed it above. */
9120 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
9121 XSetForeground (FRAME_X_DISPLAY (f
), gc
,
9122 f
->output_data
.x
->foreground_pixel
);
9124 /* Draw the empty space below the handle. Note that we can't
9125 clear zero-height areas; that means "clear to end of window." */
9126 if (end
< inside_height
)
9127 x_clear_area (FRAME_X_DISPLAY (f
), w
,
9128 /* x, y, width, height, and exposures. */
9129 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
9130 VERTICAL_SCROLL_BAR_TOP_BORDER
+ end
,
9131 inside_width
, inside_height
- end
,
9139 #endif /* !USE_TOOLKIT_SCROLL_BARS */
9141 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
9145 x_scroll_bar_remove (bar
)
9146 struct scroll_bar
*bar
;
9148 struct frame
*f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9151 #ifdef USE_TOOLKIT_SCROLL_BARS
9152 XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
));
9154 XDestroyWindow (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
));
9157 /* Disassociate this scroll bar from its window. */
9158 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
9164 /* Set the handle of the vertical scroll bar for WINDOW to indicate
9165 that we are displaying PORTION characters out of a total of WHOLE
9166 characters, starting at POSITION. If WINDOW has no scroll bar,
9170 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
9172 int portion
, whole
, position
;
9174 struct frame
*f
= XFRAME (w
->frame
);
9175 struct scroll_bar
*bar
;
9176 int top
, height
, left
, sb_left
, width
, sb_width
;
9177 int window_x
, window_y
, window_width
, window_height
;
9179 /* Get window dimensions. */
9180 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
9182 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
9183 height
= window_height
;
9185 /* Compute the left edge of the scroll bar area. */
9186 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
9187 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
9189 left
= XFASTINT (w
->left
);
9190 left
*= CANON_X_UNIT (f
);
9191 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
9193 /* Compute the width of the scroll bar which might be less than
9194 the width of the area reserved for the scroll bar. */
9195 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
9196 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
9200 /* Compute the left edge of the scroll bar. */
9201 #ifdef USE_TOOLKIT_SCROLL_BARS
9202 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
9203 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
9205 sb_left
= left
+ (width
- sb_width
) / 2;
9207 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
9208 sb_left
= left
+ width
- sb_width
;
9213 /* Does the scroll bar exist yet? */
9214 if (NILP (w
->vertical_scroll_bar
))
9216 if (width
> 0 && height
> 0)
9219 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9220 left
, top
, width
, height
, False
);
9224 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
9228 /* It may just need to be moved and resized. */
9229 unsigned int mask
= 0;
9231 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
9235 if (sb_left
!= XINT (bar
->left
))
9237 if (top
!= XINT (bar
->top
))
9239 if (sb_width
!= XINT (bar
->width
))
9241 if (height
!= XINT (bar
->height
))
9244 #ifdef USE_TOOLKIT_SCROLL_BARS
9246 /* Since toolkit scroll bars are smaller than the space reserved
9247 for them on the frame, we have to clear "under" them. */
9248 if (width
> 0 && height
> 0)
9249 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9250 left
, top
, width
, height
, False
);
9252 /* Move/size the scroll bar widget. */
9254 XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
),
9255 sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9257 sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
9258 max (height
, 1), 0);
9260 #else /* not USE_TOOLKIT_SCROLL_BARS */
9262 /* Clear areas not covered by the scroll bar because of
9263 VERTICAL_SCROLL_BAR_WIDTH_TRIM. */
9264 if (VERTICAL_SCROLL_BAR_WIDTH_TRIM
)
9266 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9267 left
, top
, VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9269 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9270 left
+ width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9271 top
, VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9275 /* Clear areas not covered by the scroll bar because it's not as
9276 wide as the area reserved for it . This makes sure a
9277 previous mode line display is cleared after C-x 2 C-x 1, for
9280 int area_width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
9281 int rest
= area_width
- sb_width
;
9282 if (rest
> 0 && height
> 0)
9284 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f
))
9285 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9286 left
+ area_width
- rest
, top
,
9287 rest
, height
, False
);
9289 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9290 left
, top
, rest
, height
, False
);
9294 /* Move/size the scroll bar window. */
9299 wc
.x
= sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
9301 wc
.width
= sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2;
9303 XConfigureWindow (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
),
9307 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9309 /* Remember new settings. */
9310 XSETINT (bar
->left
, sb_left
);
9311 XSETINT (bar
->top
, top
);
9312 XSETINT (bar
->width
, sb_width
);
9313 XSETINT (bar
->height
, height
);
9318 #ifdef USE_TOOLKIT_SCROLL_BARS
9319 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
);
9320 #else /* not USE_TOOLKIT_SCROLL_BARS */
9321 /* Set the scroll bar's current state, unless we're currently being
9323 if (NILP (bar
->dragging
))
9325 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
9328 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
9331 int start
= ((double) position
* top_range
) / whole
;
9332 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
9333 x_scroll_bar_set_handle (bar
, start
, end
, 0);
9336 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9338 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
9342 /* The following three hooks are used when we're doing a thorough
9343 redisplay of the frame. We don't explicitly know which scroll bars
9344 are going to be deleted, because keeping track of when windows go
9345 away is a real pain - "Can you say set-window-configuration, boys
9346 and girls?" Instead, we just assert at the beginning of redisplay
9347 that *all* scroll bars are to be removed, and then save a scroll bar
9348 from the fiery pit when we actually redisplay its window. */
9350 /* Arrange for all scroll bars on FRAME to be removed at the next call
9351 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
9352 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
9355 XTcondemn_scroll_bars (frame
)
9358 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
9359 while (! NILP (FRAME_SCROLL_BARS (frame
)))
9362 bar
= FRAME_SCROLL_BARS (frame
);
9363 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
9364 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
9365 XSCROLL_BAR (bar
)->prev
= Qnil
;
9366 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
9367 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
9368 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
9373 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
9374 Note that WINDOW isn't necessarily condemned at all. */
9377 XTredeem_scroll_bar (window
)
9378 struct window
*window
;
9380 struct scroll_bar
*bar
;
9383 /* We can't redeem this window's scroll bar if it doesn't have one. */
9384 if (NILP (window
->vertical_scroll_bar
))
9387 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
9389 /* Unlink it from the condemned list. */
9390 f
= XFRAME (WINDOW_FRAME (window
));
9391 if (NILP (bar
->prev
))
9393 /* If the prev pointer is nil, it must be the first in one of
9395 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
9396 /* It's not condemned. Everything's fine. */
9398 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
9399 window
->vertical_scroll_bar
))
9400 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
9402 /* If its prev pointer is nil, it must be at the front of
9403 one or the other! */
9407 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
9409 if (! NILP (bar
->next
))
9410 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
9412 bar
->next
= FRAME_SCROLL_BARS (f
);
9414 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
9415 if (! NILP (bar
->next
))
9416 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
9419 /* Remove all scroll bars on FRAME that haven't been saved since the
9420 last call to `*condemn_scroll_bars_hook'. */
9423 XTjudge_scroll_bars (f
)
9426 Lisp_Object bar
, next
;
9428 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
9430 /* Clear out the condemned list now so we won't try to process any
9431 more events on the hapless scroll bars. */
9432 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
9434 for (; ! NILP (bar
); bar
= next
)
9436 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
9438 x_scroll_bar_remove (b
);
9441 b
->next
= b
->prev
= Qnil
;
9444 /* Now there should be no references to the condemned scroll bars,
9445 and they should get garbage-collected. */
9449 /* Handle an Expose or GraphicsExpose event on a scroll bar. This
9450 is a no-op when using toolkit scroll bars.
9452 This may be called from a signal handler, so we have to ignore GC
9456 x_scroll_bar_expose (bar
, event
)
9457 struct scroll_bar
*bar
;
9460 #ifndef USE_TOOLKIT_SCROLL_BARS
9462 Window w
= SCROLL_BAR_X_WINDOW (bar
);
9463 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9464 GC gc
= f
->output_data
.x
->normal_gc
;
9465 int width_trim
= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
9469 x_scroll_bar_set_handle (bar
, XINT (bar
->start
), XINT (bar
->end
), 1);
9471 /* Draw a one-pixel border just inside the edges of the scroll bar. */
9472 XDrawRectangle (FRAME_X_DISPLAY (f
), w
, gc
,
9474 /* x, y, width, height */
9476 XINT (bar
->width
) - 1 - width_trim
- width_trim
,
9477 XINT (bar
->height
) - 1);
9481 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9484 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
9485 is set to something other than no_event, it is enqueued.
9487 This may be called from a signal handler, so we have to ignore GC
9490 #ifndef USE_TOOLKIT_SCROLL_BARS
9493 x_scroll_bar_handle_click (bar
, event
, emacs_event
)
9494 struct scroll_bar
*bar
;
9496 struct input_event
*emacs_event
;
9498 if (! GC_WINDOWP (bar
->window
))
9501 emacs_event
->kind
= scroll_bar_click
;
9502 emacs_event
->code
= event
->xbutton
.button
- Button1
;
9503 emacs_event
->modifiers
9504 = (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO
9505 (XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)))),
9506 event
->xbutton
.state
)
9507 | (event
->type
== ButtonRelease
9510 emacs_event
->frame_or_window
= bar
->window
;
9511 emacs_event
->arg
= Qnil
;
9512 emacs_event
->timestamp
= event
->xbutton
.time
;
9515 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9517 = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
9520 = VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
9521 int y
= event
->xbutton
.y
- VERTICAL_SCROLL_BAR_TOP_BORDER
;
9524 if (y
> top_range
) y
= top_range
;
9526 if (y
< XINT (bar
->start
))
9527 emacs_event
->part
= scroll_bar_above_handle
;
9528 else if (y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
9529 emacs_event
->part
= scroll_bar_handle
;
9531 emacs_event
->part
= scroll_bar_below_handle
;
9533 /* Just because the user has clicked on the handle doesn't mean
9534 they want to drag it. Lisp code needs to be able to decide
9535 whether or not we're dragging. */
9537 /* If the user has just clicked on the handle, record where they're
9539 if (event
->type
== ButtonPress
9540 && emacs_event
->part
== scroll_bar_handle
)
9541 XSETINT (bar
->dragging
, y
- XINT (bar
->start
));
9544 /* If the user has released the handle, set it to its final position. */
9545 if (event
->type
== ButtonRelease
9546 && ! NILP (bar
->dragging
))
9548 int new_start
= y
- XINT (bar
->dragging
);
9549 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
9551 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
9552 bar
->dragging
= Qnil
;
9555 /* Same deal here as the other #if 0. */
9557 /* Clicks on the handle are always reported as occurring at the top of
9559 if (emacs_event
->part
== scroll_bar_handle
)
9560 emacs_event
->x
= bar
->start
;
9562 XSETINT (emacs_event
->x
, y
);
9564 XSETINT (emacs_event
->x
, y
);
9567 XSETINT (emacs_event
->y
, top_range
);
9571 /* Handle some mouse motion while someone is dragging the scroll bar.
9573 This may be called from a signal handler, so we have to ignore GC
9577 x_scroll_bar_note_movement (bar
, event
)
9578 struct scroll_bar
*bar
;
9581 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
9583 last_mouse_movement_time
= event
->xmotion
.time
;
9586 XSETVECTOR (last_mouse_scroll_bar
, bar
);
9588 /* If we're dragging the bar, display it. */
9589 if (! GC_NILP (bar
->dragging
))
9591 /* Where should the handle be now? */
9592 int new_start
= event
->xmotion
.y
- XINT (bar
->dragging
);
9594 if (new_start
!= XINT (bar
->start
))
9596 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
9598 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
9603 #endif /* !USE_TOOLKIT_SCROLL_BARS */
9605 /* Return information to the user about the current position of the mouse
9606 on the scroll bar. */
9609 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
9611 Lisp_Object
*bar_window
;
9612 enum scroll_bar_part
*part
;
9614 unsigned long *time
;
9616 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
9617 Window w
= SCROLL_BAR_X_WINDOW (bar
);
9618 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9620 Window dummy_window
;
9622 unsigned int dummy_mask
;
9626 /* Get the mouse's position relative to the scroll bar window, and
9628 if (! XQueryPointer (FRAME_X_DISPLAY (f
), w
,
9630 /* Root, child, root x and root y. */
9631 &dummy_window
, &dummy_window
,
9632 &dummy_coord
, &dummy_coord
,
9634 /* Position relative to scroll bar. */
9637 /* Mouse buttons and modifier keys. */
9644 = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
9647 = VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
9649 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
9651 if (! NILP (bar
->dragging
))
9652 win_y
-= XINT (bar
->dragging
);
9656 if (win_y
> top_range
)
9660 *bar_window
= bar
->window
;
9662 if (! NILP (bar
->dragging
))
9663 *part
= scroll_bar_handle
;
9664 else if (win_y
< XINT (bar
->start
))
9665 *part
= scroll_bar_above_handle
;
9666 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
9667 *part
= scroll_bar_handle
;
9669 *part
= scroll_bar_below_handle
;
9671 XSETINT (*x
, win_y
);
9672 XSETINT (*y
, top_range
);
9675 last_mouse_scroll_bar
= Qnil
;
9678 *time
= last_mouse_movement_time
;
9684 /* The screen has been cleared so we may have changed foreground or
9685 background colors, and the scroll bars may need to be redrawn.
9686 Clear out the scroll bars, and ask for expose events, so we can
9690 x_scroll_bar_clear (f
)
9693 #ifndef USE_TOOLKIT_SCROLL_BARS
9696 /* We can have scroll bars even if this is 0,
9697 if we just turned off scroll bar mode.
9698 But in that case we should not clear them. */
9699 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
9700 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
9701 bar
= XSCROLL_BAR (bar
)->next
)
9702 XClearArea (FRAME_X_DISPLAY (f
),
9703 SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)),
9705 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9708 /* This processes Expose events from the menu-bar specific X event
9709 loop in xmenu.c. This allows to redisplay the frame if necessary
9710 when handling menu-bar or pop-up items. */
9713 process_expose_from_menu (event
)
9717 struct x_display_info
*dpyinfo
;
9718 int frame_exposed_p
= 0;
9722 dpyinfo
= x_display_info_for_display (event
.xexpose
.display
);
9723 f
= x_window_to_frame (dpyinfo
, event
.xexpose
.window
);
9726 if (f
->async_visible
== 0)
9728 f
->async_visible
= 1;
9729 f
->async_iconified
= 0;
9730 f
->output_data
.x
->has_been_visible
= 1;
9731 SET_FRAME_GARBAGED (f
);
9735 expose_frame (x_window_to_frame (dpyinfo
, event
.xexpose
.window
),
9736 event
.xexpose
.x
, event
.xexpose
.y
,
9737 event
.xexpose
.width
, event
.xexpose
.height
);
9738 frame_exposed_p
= 1;
9743 struct scroll_bar
*bar
9744 = x_window_to_scroll_bar (event
.xexpose
.window
);
9747 x_scroll_bar_expose (bar
, &event
);
9751 return frame_exposed_p
;
9754 /* Define a queue to save up SelectionRequest events for later handling. */
9756 struct selection_event_queue
9759 struct selection_event_queue
*next
;
9762 static struct selection_event_queue
*queue
;
9764 /* Nonzero means queue up certain events--don't process them yet. */
9766 static int x_queue_selection_requests
;
9768 /* Queue up an X event *EVENT, to be processed later. */
9771 x_queue_event (f
, event
)
9775 struct selection_event_queue
*queue_tmp
9776 = (struct selection_event_queue
*) xmalloc (sizeof (struct selection_event_queue
));
9778 if (queue_tmp
!= NULL
)
9780 queue_tmp
->event
= *event
;
9781 queue_tmp
->next
= queue
;
9786 /* Take all the queued events and put them back
9787 so that they get processed afresh. */
9790 x_unqueue_events (display
)
9793 while (queue
!= NULL
)
9795 struct selection_event_queue
*queue_tmp
= queue
;
9796 XPutBackEvent (display
, &queue_tmp
->event
);
9797 queue
= queue_tmp
->next
;
9798 xfree ((char *)queue_tmp
);
9802 /* Start queuing SelectionRequest events. */
9805 x_start_queuing_selection_requests (display
)
9808 x_queue_selection_requests
++;
9811 /* Stop queuing SelectionRequest events. */
9814 x_stop_queuing_selection_requests (display
)
9817 x_queue_selection_requests
--;
9818 x_unqueue_events (display
);
9821 /* The main X event-reading loop - XTread_socket. */
9823 /* Time stamp of enter window event. This is only used by XTread_socket,
9824 but we have to put it out here, since static variables within functions
9825 sometimes don't work. */
9827 static Time enter_timestamp
;
9829 /* This holds the state XLookupString needs to implement dead keys
9830 and other tricks known as "compose processing". _X Window System_
9831 says that a portable program can't use this, but Stephen Gildea assures
9832 me that letting the compiler initialize it to zeros will work okay.
9834 This must be defined outside of XTread_socket, for the same reasons
9835 given for enter_timestamp, above. */
9837 static XComposeStatus compose_status
;
9839 /* Record the last 100 characters stored
9840 to help debug the loss-of-chars-during-GC problem. */
9842 static int temp_index
;
9843 static short temp_buffer
[100];
9845 /* Set this to nonzero to fake an "X I/O error"
9846 on a particular display. */
9848 struct x_display_info
*XTread_socket_fake_io_error
;
9850 /* When we find no input here, we occasionally do a no-op command
9851 to verify that the X server is still running and we can still talk with it.
9852 We try all the open displays, one by one.
9853 This variable is used for cycling thru the displays. */
9855 static struct x_display_info
*next_noop_dpyinfo
;
9857 #define SET_SAVED_MENU_EVENT(size) \
9860 if (f->output_data.x->saved_menu_event == 0) \
9861 f->output_data.x->saved_menu_event \
9862 = (XEvent *) xmalloc (sizeof (XEvent)); \
9863 bcopy (&event, f->output_data.x->saved_menu_event, size); \
9864 if (numchars >= 1) \
9866 bufp->kind = menu_bar_activate_event; \
9867 XSETFRAME (bufp->frame_or_window, f); \
9876 #define SET_SAVED_BUTTON_EVENT SET_SAVED_MENU_EVENT (sizeof (XButtonEvent))
9877 #define SET_SAVED_KEY_EVENT SET_SAVED_MENU_EVENT (sizeof (XKeyEvent))
9879 /* Read events coming from the X server.
9880 This routine is called by the SIGIO handler.
9881 We return as soon as there are no more events to be read.
9883 Events representing keys are stored in buffer BUFP,
9884 which can hold up to NUMCHARS characters.
9885 We return the number of characters stored into the buffer,
9886 thus pretending to be `read'.
9888 EXPECTED is nonzero if the caller knows input is available. */
9891 XTread_socket (sd
, bufp
, numchars
, expected
)
9893 /* register */ struct input_event
*bufp
;
9894 /* register */ int numchars
;
9901 int event_found
= 0;
9902 struct x_display_info
*dpyinfo
;
9903 struct coding_system coding
;
9905 if (interrupt_input_blocked
)
9907 interrupt_input_pending
= 1;
9911 interrupt_input_pending
= 0;
9914 /* So people can tell when we have read the available input. */
9915 input_signal_count
++;
9918 abort (); /* Don't think this happens. */
9922 /* The input should be decoded if it is from XIM. Currently the
9923 locale of XIM is the same as that of the system. So, we can use
9924 Vlocale_coding_system which is initialized properly at Emacs
9926 setup_coding_system (Vlocale_coding_system
, &coding
);
9927 coding
.src_multibyte
= 0;
9928 coding
.dst_multibyte
= 1;
9929 /* The input is converted to events, thus we can't handle
9930 composition. Anyway, there's no XIM that gives us composition
9932 coding
.composing
= COMPOSITION_DISABLED
;
9934 /* Find the display we are supposed to read input for.
9935 It's the one communicating on descriptor SD. */
9936 for (dpyinfo
= x_display_list
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
9938 #if 0 /* This ought to be unnecessary; let's verify it. */
9940 /* If available, Xlib uses FIOSNBIO to make the socket
9941 non-blocking, and then looks for EWOULDBLOCK. If O_NDELAY is set,
9942 FIOSNBIO is ignored, and instead of signaling EWOULDBLOCK,
9943 a read returns 0, which Xlib interprets as equivalent to EPIPE. */
9944 fcntl (dpyinfo
->connection
, F_SETFL
, 0);
9945 #endif /* ! defined (FIOSNBIO) */
9948 #if 0 /* This code can't be made to work, with multiple displays,
9949 and appears not to be used on any system any more.
9950 Also keyboard.c doesn't turn O_NDELAY on and off
9951 for X connections. */
9954 if (! (fcntl (dpyinfo
->connection
, F_GETFL
, 0) & O_NDELAY
))
9956 extern int read_alarm_should_throw
;
9957 read_alarm_should_throw
= 1;
9958 XPeekEvent (dpyinfo
->display
, &event
);
9959 read_alarm_should_throw
= 0;
9961 #endif /* HAVE_SELECT */
9965 /* For debugging, this gives a way to fake an I/O error. */
9966 if (dpyinfo
== XTread_socket_fake_io_error
)
9968 XTread_socket_fake_io_error
= 0;
9969 x_io_error_quitter (dpyinfo
->display
);
9972 while (XPending (dpyinfo
->display
))
9974 XNextEvent (dpyinfo
->display
, &event
);
9978 /* Filter events for the current X input method.
9979 XFilterEvent returns non-zero if the input method has
9980 consumed the event. We pass the frame's X window to
9981 XFilterEvent because that's the one for which the IC
9983 struct frame
*f1
= x_any_window_to_frame (dpyinfo
,
9984 event
.xclient
.window
);
9985 if (XFilterEvent (&event
, f1
? FRAME_X_WINDOW (f1
) : None
))
9995 if (event
.xclient
.message_type
9996 == dpyinfo
->Xatom_wm_protocols
9997 && event
.xclient
.format
== 32)
9999 if (event
.xclient
.data
.l
[0]
10000 == dpyinfo
->Xatom_wm_take_focus
)
10002 /* Use x_any_window_to_frame because this
10003 could be the shell widget window
10004 if the frame has no title bar. */
10005 f
= x_any_window_to_frame (dpyinfo
, event
.xclient
.window
);
10007 /* Not quite sure this is needed -pd */
10008 if (f
&& FRAME_XIC (f
))
10009 XSetICFocus (FRAME_XIC (f
));
10011 #if 0 /* Emacs sets WM hints whose `input' field is `true'. This
10012 instructs the WM to set the input focus automatically for
10013 Emacs with a call to XSetInputFocus. Setting WM_TAKE_FOCUS
10014 tells the WM to send us a ClientMessage WM_TAKE_FOCUS after
10015 it has set the focus. So, XSetInputFocus below is not
10018 The call to XSetInputFocus below has also caused trouble. In
10019 cases where the XSetInputFocus done by the WM and the one
10020 below are temporally close (on a fast machine), the call
10021 below can generate additional FocusIn events which confuse
10024 /* Since we set WM_TAKE_FOCUS, we must call
10025 XSetInputFocus explicitly. But not if f is null,
10026 since that might be an event for a deleted frame. */
10029 Display
*d
= event
.xclient
.display
;
10030 /* Catch and ignore errors, in case window has been
10031 iconified by a window manager such as GWM. */
10032 int count
= x_catch_errors (d
);
10033 XSetInputFocus (d
, event
.xclient
.window
,
10034 /* The ICCCM says this is
10035 the only valid choice. */
10037 event
.xclient
.data
.l
[1]);
10038 /* This is needed to detect the error
10039 if there is an error. */
10041 x_uncatch_errors (d
, count
);
10043 /* Not certain about handling scroll bars here */
10046 else if (event
.xclient
.data
.l
[0]
10047 == dpyinfo
->Xatom_wm_save_yourself
)
10049 /* Save state modify the WM_COMMAND property to
10050 something which can reinstate us. This notifies
10051 the session manager, who's looking for such a
10052 PropertyNotify. Can restart processing when
10053 a keyboard or mouse event arrives. */
10056 f
= x_top_window_to_frame (dpyinfo
,
10057 event
.xclient
.window
);
10059 /* This is just so we only give real data once
10060 for a single Emacs process. */
10061 if (f
== SELECTED_FRAME ())
10062 XSetCommand (FRAME_X_DISPLAY (f
),
10063 event
.xclient
.window
,
10064 initial_argv
, initial_argc
);
10066 XSetCommand (FRAME_X_DISPLAY (f
),
10067 event
.xclient
.window
,
10071 else if (event
.xclient
.data
.l
[0]
10072 == dpyinfo
->Xatom_wm_delete_window
)
10075 = x_any_window_to_frame (dpyinfo
,
10076 event
.xclient
.window
);
10083 bufp
->kind
= delete_window_event
;
10084 XSETFRAME (bufp
->frame_or_window
, f
);
10093 else if (event
.xclient
.message_type
10094 == dpyinfo
->Xatom_wm_configure_denied
)
10097 else if (event
.xclient
.message_type
10098 == dpyinfo
->Xatom_wm_window_moved
)
10102 = x_window_to_frame (dpyinfo
, event
.xclient
.window
);
10104 new_x
= event
.xclient
.data
.s
[0];
10105 new_y
= event
.xclient
.data
.s
[1];
10109 f
->output_data
.x
->left_pos
= new_x
;
10110 f
->output_data
.x
->top_pos
= new_y
;
10113 #ifdef HACK_EDITRES
10114 else if (event
.xclient
.message_type
10115 == dpyinfo
->Xatom_editres
)
10118 = x_any_window_to_frame (dpyinfo
, event
.xclient
.window
);
10119 _XEditResCheckMessages (f
->output_data
.x
->widget
, NULL
,
10122 #endif /* HACK_EDITRES */
10123 else if ((event
.xclient
.message_type
10124 == dpyinfo
->Xatom_DONE
)
10125 || (event
.xclient
.message_type
10126 == dpyinfo
->Xatom_PAGE
))
10128 /* Ghostview job completed. Kill it. We could
10129 reply with "Next" if we received "Page", but we
10130 currently never do because we are interested in
10131 images, only, which should have 1 page. */
10132 Pixmap pixmap
= (Pixmap
) event
.xclient
.data
.l
[1];
10134 = x_window_to_frame (dpyinfo
, event
.xclient
.window
);
10135 x_kill_gs_process (pixmap
, f
);
10136 expose_frame (f
, 0, 0, 0, 0);
10138 #ifdef USE_TOOLKIT_SCROLL_BARS
10139 /* Scroll bar callbacks send a ClientMessage from which
10140 we construct an input_event. */
10141 else if (event
.xclient
.message_type
10142 == dpyinfo
->Xatom_Scrollbar
)
10144 x_scroll_bar_to_input_event (&event
, bufp
);
10145 ++bufp
, ++count
, --numchars
;
10148 #endif /* USE_TOOLKIT_SCROLL_BARS */
10154 case SelectionNotify
:
10155 #ifdef USE_X_TOOLKIT
10156 if (! x_window_to_frame (dpyinfo
, event
.xselection
.requestor
))
10158 #endif /* not USE_X_TOOLKIT */
10159 x_handle_selection_notify (&event
.xselection
);
10162 case SelectionClear
: /* Someone has grabbed ownership. */
10163 #ifdef USE_X_TOOLKIT
10164 if (! x_window_to_frame (dpyinfo
, event
.xselectionclear
.window
))
10166 #endif /* USE_X_TOOLKIT */
10168 XSelectionClearEvent
*eventp
= (XSelectionClearEvent
*) &event
;
10173 bufp
->kind
= selection_clear_event
;
10174 SELECTION_EVENT_DISPLAY (bufp
) = eventp
->display
;
10175 SELECTION_EVENT_SELECTION (bufp
) = eventp
->selection
;
10176 SELECTION_EVENT_TIME (bufp
) = eventp
->time
;
10177 bufp
->frame_or_window
= Qnil
;
10186 case SelectionRequest
: /* Someone wants our selection. */
10187 #ifdef USE_X_TOOLKIT
10188 if (!x_window_to_frame (dpyinfo
, event
.xselectionrequest
.owner
))
10190 #endif /* USE_X_TOOLKIT */
10191 if (x_queue_selection_requests
)
10192 x_queue_event (x_window_to_frame (dpyinfo
, event
.xselectionrequest
.owner
),
10196 XSelectionRequestEvent
*eventp
10197 = (XSelectionRequestEvent
*) &event
;
10202 bufp
->kind
= selection_request_event
;
10203 SELECTION_EVENT_DISPLAY (bufp
) = eventp
->display
;
10204 SELECTION_EVENT_REQUESTOR (bufp
) = eventp
->requestor
;
10205 SELECTION_EVENT_SELECTION (bufp
) = eventp
->selection
;
10206 SELECTION_EVENT_TARGET (bufp
) = eventp
->target
;
10207 SELECTION_EVENT_PROPERTY (bufp
) = eventp
->property
;
10208 SELECTION_EVENT_TIME (bufp
) = eventp
->time
;
10209 bufp
->frame_or_window
= Qnil
;
10218 case PropertyNotify
:
10219 #if 0 /* This is plain wrong. In the case that we are waiting for a
10220 PropertyNotify used as an ACK in incremental selection
10221 transfer, the property will be on the receiver's window. */
10222 #if defined USE_X_TOOLKIT
10223 if (!x_any_window_to_frame (dpyinfo
, event
.xproperty
.window
))
10227 x_handle_property_notify (&event
.xproperty
);
10230 case ReparentNotify
:
10231 f
= x_top_window_to_frame (dpyinfo
, event
.xreparent
.window
);
10235 f
->output_data
.x
->parent_desc
= event
.xreparent
.parent
;
10236 x_real_positions (f
, &x
, &y
);
10237 f
->output_data
.x
->left_pos
= x
;
10238 f
->output_data
.x
->top_pos
= y
;
10243 f
= x_window_to_frame (dpyinfo
, event
.xexpose
.window
);
10246 if (f
->async_visible
== 0)
10248 f
->async_visible
= 1;
10249 f
->async_iconified
= 0;
10250 f
->output_data
.x
->has_been_visible
= 1;
10251 SET_FRAME_GARBAGED (f
);
10254 expose_frame (x_window_to_frame (dpyinfo
,
10255 event
.xexpose
.window
),
10256 event
.xexpose
.x
, event
.xexpose
.y
,
10257 event
.xexpose
.width
, event
.xexpose
.height
);
10261 #ifndef USE_TOOLKIT_SCROLL_BARS
10262 struct scroll_bar
*bar
;
10264 #if defined USE_LUCID
10265 /* Submenus of the Lucid menu bar aren't widgets
10266 themselves, so there's no way to dispatch events
10267 to them. Recognize this case separately. */
10270 = x_window_to_menu_bar (event
.xexpose
.window
);
10272 xlwmenu_redisplay (widget
);
10274 #endif /* USE_LUCID */
10276 #ifdef USE_TOOLKIT_SCROLL_BARS
10277 /* Dispatch event to the widget. */
10279 #else /* not USE_TOOLKIT_SCROLL_BARS */
10280 bar
= x_window_to_scroll_bar (event
.xexpose
.window
);
10283 x_scroll_bar_expose (bar
, &event
);
10284 #ifdef USE_X_TOOLKIT
10287 #endif /* USE_X_TOOLKIT */
10288 #endif /* not USE_TOOLKIT_SCROLL_BARS */
10292 case GraphicsExpose
: /* This occurs when an XCopyArea's
10293 source area was obscured or not
10295 f
= x_window_to_frame (dpyinfo
, event
.xgraphicsexpose
.drawable
);
10299 event
.xgraphicsexpose
.x
, event
.xgraphicsexpose
.y
,
10300 event
.xgraphicsexpose
.width
,
10301 event
.xgraphicsexpose
.height
);
10303 #ifdef USE_X_TOOLKIT
10306 #endif /* USE_X_TOOLKIT */
10309 case NoExpose
: /* This occurs when an XCopyArea's
10310 source area was completely
10315 /* Redo the mouse-highlight after the tooltip has gone. */
10316 if (event
.xmap
.window
== tip_window
)
10319 redo_mouse_highlight ();
10322 f
= x_top_window_to_frame (dpyinfo
, event
.xunmap
.window
);
10323 if (f
) /* F may no longer exist if
10324 the frame was deleted. */
10326 /* While a frame is unmapped, display generation is
10327 disabled; you don't want to spend time updating a
10328 display that won't ever be seen. */
10329 f
->async_visible
= 0;
10330 /* We can't distinguish, from the event, whether the window
10331 has become iconified or invisible. So assume, if it
10332 was previously visible, than now it is iconified.
10333 But x_make_frame_invisible clears both
10334 the visible flag and the iconified flag;
10335 and that way, we know the window is not iconified now. */
10336 if (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
))
10338 f
->async_iconified
= 1;
10340 bufp
->kind
= iconify_event
;
10341 XSETFRAME (bufp
->frame_or_window
, f
);
10351 if (event
.xmap
.window
== tip_window
)
10352 /* The tooltip has been drawn already. Avoid
10353 the SET_FRAME_GARBAGED below. */
10356 /* We use x_top_window_to_frame because map events can
10357 come for sub-windows and they don't mean that the
10358 frame is visible. */
10359 f
= x_top_window_to_frame (dpyinfo
, event
.xmap
.window
);
10362 f
->async_visible
= 1;
10363 f
->async_iconified
= 0;
10364 f
->output_data
.x
->has_been_visible
= 1;
10366 /* wait_reading_process_input will notice this and update
10367 the frame's display structures. */
10368 SET_FRAME_GARBAGED (f
);
10372 bufp
->kind
= deiconify_event
;
10373 XSETFRAME (bufp
->frame_or_window
, f
);
10379 else if (! NILP (Vframe_list
)
10380 && ! NILP (XCDR (Vframe_list
)))
10381 /* Force a redisplay sooner or later
10382 to update the frame titles
10383 in case this is the second frame. */
10384 record_asynch_buffer_change ();
10389 f
= x_any_window_to_frame (dpyinfo
, event
.xkey
.window
);
10391 #if defined USE_MOTIF && defined USE_TOOLKIT_SCROLL_BARS
10394 /* Scroll bars consume key events, but we want
10395 the keys to go to the scroll bar's frame. */
10396 Widget widget
= XtWindowToWidget (dpyinfo
->display
,
10397 event
.xkey
.window
);
10398 if (widget
&& XmIsScrollBar (widget
))
10400 widget
= XtParent (widget
);
10401 f
= x_any_window_to_frame (dpyinfo
, XtWindow (widget
));
10404 #endif /* USE_MOTIF and USE_TOOLKIT_SCROLL_BARS */
10408 KeySym keysym
, orig_keysym
;
10409 /* al%imercury@uunet.uu.net says that making this 81
10410 instead of 80 fixed a bug whereby meta chars made
10413 It seems that some version of XmbLookupString has
10414 a bug of not returning XBufferOverflow in
10415 status_return even if the input is too long to
10416 fit in 81 bytes. So, we must prepare sufficient
10417 bytes for copy_buffer. 513 bytes (256 chars for
10418 two-byte character set) seems to be a fairly good
10419 approximation. -- 2000.8.10 handa@etl.go.jp */
10420 unsigned char copy_buffer
[513];
10421 unsigned char *copy_bufptr
= copy_buffer
;
10422 int copy_bufsiz
= sizeof (copy_buffer
);
10426 |= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f
),
10427 extra_keyboard_modifiers
);
10428 modifiers
= event
.xkey
.state
;
10430 /* This will have to go some day... */
10432 /* make_lispy_event turns chars into control chars.
10433 Don't do it here because XLookupString is too eager. */
10434 event
.xkey
.state
&= ~ControlMask
;
10435 event
.xkey
.state
&= ~(dpyinfo
->meta_mod_mask
10436 | dpyinfo
->super_mod_mask
10437 | dpyinfo
->hyper_mod_mask
10438 | dpyinfo
->alt_mod_mask
);
10440 /* In case Meta is ComposeCharacter,
10441 clear its status. According to Markus Ehrnsperger
10442 Markus.Ehrnsperger@lehrstuhl-bross.physik.uni-muenchen.de
10443 this enables ComposeCharacter to work whether or
10444 not it is combined with Meta. */
10445 if (modifiers
& dpyinfo
->meta_mod_mask
)
10446 bzero (&compose_status
, sizeof (compose_status
));
10451 Status status_return
;
10453 nbytes
= XmbLookupString (FRAME_XIC (f
),
10454 &event
.xkey
, copy_bufptr
,
10455 copy_bufsiz
, &keysym
,
10457 if (status_return
== XBufferOverflow
)
10459 copy_bufsiz
= nbytes
+ 1;
10460 copy_bufptr
= (char *) alloca (copy_bufsiz
);
10461 nbytes
= XmbLookupString (FRAME_XIC (f
),
10462 &event
.xkey
, copy_bufptr
,
10463 copy_bufsiz
, &keysym
,
10467 if (status_return
== XLookupNone
)
10469 else if (status_return
== XLookupChars
)
10474 else if (status_return
!= XLookupKeySym
10475 && status_return
!= XLookupBoth
)
10479 nbytes
= XLookupString (&event
.xkey
, copy_bufptr
,
10480 copy_bufsiz
, &keysym
,
10483 nbytes
= XLookupString (&event
.xkey
, copy_bufptr
,
10484 copy_bufsiz
, &keysym
,
10488 orig_keysym
= keysym
;
10492 if (((keysym
>= XK_BackSpace
&& keysym
<= XK_Escape
)
10493 || keysym
== XK_Delete
10494 #ifdef XK_ISO_Left_Tab
10495 || (keysym
>= XK_ISO_Left_Tab
&& keysym
<= XK_ISO_Enter
)
10497 || (keysym
>= XK_Kanji
&& keysym
<= XK_Eisu_toggle
)
10498 || IsCursorKey (keysym
) /* 0xff50 <= x < 0xff60 */
10499 || IsMiscFunctionKey (keysym
) /* 0xff60 <= x < VARIES */
10501 /* This recognizes the "extended function keys".
10502 It seems there's no cleaner way.
10503 Test IsModifierKey to avoid handling mode_switch
10505 || ((unsigned) (keysym
) >= XK_Select
10506 && (unsigned)(keysym
) < XK_KP_Space
)
10508 #ifdef XK_dead_circumflex
10509 || orig_keysym
== XK_dead_circumflex
10511 #ifdef XK_dead_grave
10512 || orig_keysym
== XK_dead_grave
10514 #ifdef XK_dead_tilde
10515 || orig_keysym
== XK_dead_tilde
10517 #ifdef XK_dead_diaeresis
10518 || orig_keysym
== XK_dead_diaeresis
10520 #ifdef XK_dead_macron
10521 || orig_keysym
== XK_dead_macron
10523 #ifdef XK_dead_degree
10524 || orig_keysym
== XK_dead_degree
10526 #ifdef XK_dead_acute
10527 || orig_keysym
== XK_dead_acute
10529 #ifdef XK_dead_cedilla
10530 || orig_keysym
== XK_dead_cedilla
10532 #ifdef XK_dead_breve
10533 || orig_keysym
== XK_dead_breve
10535 #ifdef XK_dead_ogonek
10536 || orig_keysym
== XK_dead_ogonek
10538 #ifdef XK_dead_caron
10539 || orig_keysym
== XK_dead_caron
10541 #ifdef XK_dead_doubleacute
10542 || orig_keysym
== XK_dead_doubleacute
10544 #ifdef XK_dead_abovedot
10545 || orig_keysym
== XK_dead_abovedot
10547 || IsKeypadKey (keysym
) /* 0xff80 <= x < 0xffbe */
10548 || IsFunctionKey (keysym
) /* 0xffbe <= x < 0xffe1 */
10549 /* Any "vendor-specific" key is ok. */
10550 || (orig_keysym
& (1 << 28))
10551 || (keysym
!= NoSymbol
&& nbytes
== 0))
10552 && ! (IsModifierKey (orig_keysym
)
10554 #ifdef XK_Mode_switch
10555 || ((unsigned)(orig_keysym
) == XK_Mode_switch
)
10558 || ((unsigned)(orig_keysym
) == XK_Num_Lock
)
10560 #endif /* not HAVE_X11R5 */
10563 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
10565 temp_buffer
[temp_index
++] = keysym
;
10566 bufp
->kind
= non_ascii_keystroke
;
10567 bufp
->code
= keysym
;
10568 XSETFRAME (bufp
->frame_or_window
, f
);
10571 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
10573 bufp
->timestamp
= event
.xkey
.time
;
10578 else if (numchars
> nbytes
)
10584 for (i
= 0; i
< nbytes
; i
++)
10586 if (temp_index
== (sizeof temp_buffer
10589 temp_buffer
[temp_index
++] = copy_bufptr
[i
];
10592 if (/* If the event is not from XIM, */
10593 event
.xkey
.keycode
!= 0
10594 /* or the current locale doesn't request
10595 decoding of the intup data, ... */
10596 || coding
.type
== coding_type_raw_text
10597 || coding
.type
== coding_type_no_conversion
)
10599 /* ... we can use the input data as is. */
10604 /* We have to decode the input data. */
10608 require
= decoding_buffer_size (&coding
, nbytes
);
10609 p
= (unsigned char *) alloca (require
);
10610 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
10611 decode_coding (&coding
, copy_bufptr
, p
,
10613 nbytes
= coding
.produced
;
10614 nchars
= coding
.produced_char
;
10618 /* Convert the input data to a sequence of
10619 character events. */
10620 for (i
= 0; i
< nbytes
; i
+= len
)
10622 if (nchars
== nbytes
)
10623 c
= copy_bufptr
[i
], len
= 1;
10625 c
= STRING_CHAR_AND_LENGTH (copy_bufptr
+ i
,
10628 bufp
->kind
= (SINGLE_BYTE_CHAR_P (c
)
10630 : multibyte_char_keystroke
);
10632 XSETFRAME (bufp
->frame_or_window
, f
);
10635 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
10637 bufp
->timestamp
= event
.xkey
.time
;
10642 numchars
-= nchars
;
10644 if (keysym
== NoSymbol
)
10654 /* Don't dispatch this event since XtDispatchEvent calls
10655 XFilterEvent, and two calls in a row may freeze the
10664 /* Don't dispatch this event since XtDispatchEvent calls
10665 XFilterEvent, and two calls in a row may freeze the
10672 /* Here's a possible interpretation of the whole
10673 FocusIn-EnterNotify FocusOut-LeaveNotify mess. If
10674 you get a FocusIn event, you have to get a FocusOut
10675 event before you relinquish the focus. If you
10676 haven't received a FocusIn event, then a mere
10677 LeaveNotify is enough to free you. */
10681 f
= x_any_window_to_frame (dpyinfo
, event
.xcrossing
.window
);
10684 if (event
.xcrossing
.focus
)
10686 /* Avoid nasty pop/raise loops. */
10687 if (f
&& (!(f
->auto_raise
)
10688 || !(f
->auto_lower
)
10689 || (event
.xcrossing
.time
- enter_timestamp
) > 500))
10691 x_new_focus_frame (dpyinfo
, f
);
10692 enter_timestamp
= event
.xcrossing
.time
;
10695 else if (f
== dpyinfo
->x_focus_frame
)
10696 x_new_focus_frame (dpyinfo
, 0);
10699 /* EnterNotify counts as mouse movement,
10700 so update things that depend on mouse position. */
10701 if (f
&& !f
->output_data
.x
->hourglass_p
)
10702 note_mouse_movement (f
, &event
.xmotion
);
10707 f
= x_any_window_to_frame (dpyinfo
, event
.xfocus
.window
);
10708 if (event
.xfocus
.detail
!= NotifyPointer
)
10709 dpyinfo
->x_focus_event_frame
= f
;
10712 x_new_focus_frame (dpyinfo
, f
);
10714 /* Don't stop displaying the initial startup message
10715 for a switch-frame event we don't need. */
10716 if (GC_NILP (Vterminal_frame
)
10717 && GC_CONSP (Vframe_list
)
10718 && !GC_NILP (XCDR (Vframe_list
)))
10720 bufp
->kind
= FOCUS_IN_EVENT
;
10721 XSETFRAME (bufp
->frame_or_window
, f
);
10723 ++bufp
, ++count
, --numchars
;
10728 if (f
&& FRAME_XIC (f
))
10729 XSetICFocus (FRAME_XIC (f
));
10735 f
= x_top_window_to_frame (dpyinfo
, event
.xcrossing
.window
);
10738 if (f
== dpyinfo
->mouse_face_mouse_frame
)
10740 /* If we move outside the frame, then we're
10741 certainly no longer on any text in the frame. */
10742 clear_mouse_face (dpyinfo
);
10743 dpyinfo
->mouse_face_mouse_frame
= 0;
10746 /* Generate a nil HELP_EVENT to cancel a help-echo.
10747 Do it only if there's something to cancel.
10748 Otherwise, the startup message is cleared when
10749 the mouse leaves the frame. */
10750 if (any_help_event_p
)
10755 XSETFRAME (frame
, f
);
10757 n
= gen_help_event (bufp
, numchars
,
10758 Qnil
, frame
, Qnil
, Qnil
, 0);
10759 bufp
+= n
, count
+= n
, numchars
-= n
;
10763 if (event
.xcrossing
.focus
)
10764 x_mouse_leave (dpyinfo
);
10767 if (f
== dpyinfo
->x_focus_event_frame
)
10768 dpyinfo
->x_focus_event_frame
= 0;
10769 if (f
== dpyinfo
->x_focus_frame
)
10770 x_new_focus_frame (dpyinfo
, 0);
10777 f
= x_any_window_to_frame (dpyinfo
, event
.xfocus
.window
);
10778 if (event
.xfocus
.detail
!= NotifyPointer
10779 && f
== dpyinfo
->x_focus_event_frame
)
10780 dpyinfo
->x_focus_event_frame
= 0;
10781 if (f
&& f
== dpyinfo
->x_focus_frame
)
10782 x_new_focus_frame (dpyinfo
, 0);
10785 if (f
&& FRAME_XIC (f
))
10786 XUnsetICFocus (FRAME_XIC (f
));
10793 previous_help_echo
= help_echo
;
10794 help_echo
= help_echo_object
= help_echo_window
= Qnil
;
10795 help_echo_pos
= -1;
10797 if (dpyinfo
->grabbed
&& last_mouse_frame
10798 && FRAME_LIVE_P (last_mouse_frame
))
10799 f
= last_mouse_frame
;
10801 f
= x_window_to_frame (dpyinfo
, event
.xmotion
.window
);
10804 note_mouse_movement (f
, &event
.xmotion
);
10807 #ifndef USE_TOOLKIT_SCROLL_BARS
10808 struct scroll_bar
*bar
10809 = x_window_to_scroll_bar (event
.xmotion
.window
);
10812 x_scroll_bar_note_movement (bar
, &event
);
10813 #endif /* USE_TOOLKIT_SCROLL_BARS */
10815 /* If we move outside the frame, then we're
10816 certainly no longer on any text in the frame. */
10817 clear_mouse_face (dpyinfo
);
10820 /* If the contents of the global variable help_echo
10821 has changed, generate a HELP_EVENT. */
10822 if (!NILP (help_echo
)
10823 || !NILP (previous_help_echo
))
10829 XSETFRAME (frame
, f
);
10833 any_help_event_p
= 1;
10834 n
= gen_help_event (bufp
, numchars
, help_echo
, frame
,
10835 help_echo_window
, help_echo_object
,
10837 bufp
+= n
, count
+= n
, numchars
-= n
;
10843 case ConfigureNotify
:
10844 f
= x_top_window_to_frame (dpyinfo
, event
.xconfigure
.window
);
10847 #ifndef USE_X_TOOLKIT
10848 int rows
= PIXEL_TO_CHAR_HEIGHT (f
, event
.xconfigure
.height
);
10849 int columns
= PIXEL_TO_CHAR_WIDTH (f
, event
.xconfigure
.width
);
10851 /* In the toolkit version, change_frame_size
10852 is called by the code that handles resizing
10853 of the EmacsFrame widget. */
10855 /* Even if the number of character rows and columns has
10856 not changed, the font size may have changed, so we need
10857 to check the pixel dimensions as well. */
10858 if (columns
!= f
->width
10859 || rows
!= f
->height
10860 || event
.xconfigure
.width
!= f
->output_data
.x
->pixel_width
10861 || event
.xconfigure
.height
!= f
->output_data
.x
->pixel_height
)
10863 change_frame_size (f
, rows
, columns
, 0, 1, 0);
10864 SET_FRAME_GARBAGED (f
);
10865 cancel_mouse_face (f
);
10869 f
->output_data
.x
->pixel_width
= event
.xconfigure
.width
;
10870 f
->output_data
.x
->pixel_height
= event
.xconfigure
.height
;
10872 /* What we have now is the position of Emacs's own window.
10873 Convert that to the position of the window manager window. */
10874 x_real_positions (f
, &f
->output_data
.x
->left_pos
,
10875 &f
->output_data
.x
->top_pos
);
10878 if (FRAME_XIC (f
) && (FRAME_XIC_STYLE (f
) & XIMStatusArea
))
10879 xic_set_statusarea (f
);
10882 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
10884 /* Since the WM decorations come below top_pos now,
10885 we must put them below top_pos in the future. */
10886 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
10887 x_wm_set_size_hint (f
, (long) 0, 0);
10890 /* Some window managers pass (0,0) as the location of
10891 the window, and the Motif event handler stores it
10892 in the emacs widget, which messes up Motif menus. */
10893 if (event
.xconfigure
.x
== 0 && event
.xconfigure
.y
== 0)
10895 event
.xconfigure
.x
= f
->output_data
.x
->widget
->core
.x
;
10896 event
.xconfigure
.y
= f
->output_data
.x
->widget
->core
.y
;
10898 #endif /* USE_MOTIF */
10903 case ButtonRelease
:
10905 /* If we decide we want to generate an event to be seen
10906 by the rest of Emacs, we put it here. */
10907 struct input_event emacs_event
;
10908 int tool_bar_p
= 0;
10910 emacs_event
.kind
= no_event
;
10911 bzero (&compose_status
, sizeof (compose_status
));
10913 if (dpyinfo
->grabbed
10914 && last_mouse_frame
10915 && FRAME_LIVE_P (last_mouse_frame
))
10916 f
= last_mouse_frame
;
10918 f
= x_window_to_frame (dpyinfo
, event
.xbutton
.window
);
10922 /* Is this in the tool-bar? */
10923 if (WINDOWP (f
->tool_bar_window
)
10924 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
10926 Lisp_Object window
;
10929 x
= event
.xbutton
.x
;
10930 y
= event
.xbutton
.y
;
10933 window
= window_from_coordinates (f
, x
, y
, &p
, 1);
10934 if (EQ (window
, f
->tool_bar_window
))
10936 x_handle_tool_bar_click (f
, &event
.xbutton
);
10942 if (!dpyinfo
->x_focus_frame
10943 || f
== dpyinfo
->x_focus_frame
)
10944 construct_mouse_click (&emacs_event
, &event
, f
);
10948 #ifndef USE_TOOLKIT_SCROLL_BARS
10949 struct scroll_bar
*bar
10950 = x_window_to_scroll_bar (event
.xbutton
.window
);
10953 x_scroll_bar_handle_click (bar
, &event
, &emacs_event
);
10954 #endif /* not USE_TOOLKIT_SCROLL_BARS */
10957 if (event
.type
== ButtonPress
)
10959 dpyinfo
->grabbed
|= (1 << event
.xbutton
.button
);
10960 last_mouse_frame
= f
;
10961 /* Ignore any mouse motion that happened
10962 before this event; any subsequent mouse-movement
10963 Emacs events should reflect only motion after
10964 the ButtonPress. */
10966 f
->mouse_moved
= 0;
10969 last_tool_bar_item
= -1;
10973 dpyinfo
->grabbed
&= ~(1 << event
.xbutton
.button
);
10976 if (numchars
>= 1 && emacs_event
.kind
!= no_event
)
10978 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
10984 #ifdef USE_X_TOOLKIT
10985 f
= x_menubar_window_to_frame (dpyinfo
, event
.xbutton
.window
);
10986 /* For a down-event in the menu bar,
10987 don't pass it to Xt right now.
10988 Instead, save it away
10989 and we will pass it to Xt from kbd_buffer_get_event.
10990 That way, we can run some Lisp code first. */
10991 if (f
&& event
.type
== ButtonPress
10992 /* Verify the event is really within the menu bar
10993 and not just sent to it due to grabbing. */
10994 && event
.xbutton
.x
>= 0
10995 && event
.xbutton
.x
< f
->output_data
.x
->pixel_width
10996 && event
.xbutton
.y
>= 0
10997 && event
.xbutton
.y
< f
->output_data
.x
->menubar_height
10998 && event
.xbutton
.same_screen
)
11000 SET_SAVED_BUTTON_EVENT
;
11001 XSETFRAME (last_mouse_press_frame
, f
);
11003 else if (event
.type
== ButtonPress
)
11005 last_mouse_press_frame
= Qnil
;
11009 #ifdef USE_MOTIF /* This should do not harm for Lucid,
11010 but I am trying to be cautious. */
11011 else if (event
.type
== ButtonRelease
)
11013 if (!NILP (last_mouse_press_frame
))
11015 f
= XFRAME (last_mouse_press_frame
);
11016 if (f
->output_data
.x
)
11017 SET_SAVED_BUTTON_EVENT
;
11022 #endif /* USE_MOTIF */
11025 #endif /* USE_X_TOOLKIT */
11029 case CirculateNotify
:
11032 case CirculateRequest
:
11035 case VisibilityNotify
:
11038 case MappingNotify
:
11039 /* Someone has changed the keyboard mapping - update the
11041 switch (event
.xmapping
.request
)
11043 case MappingModifier
:
11044 x_find_modifier_meanings (dpyinfo
);
11045 /* This is meant to fall through. */
11046 case MappingKeyboard
:
11047 XRefreshKeyboardMapping (&event
.xmapping
);
11053 #ifdef USE_X_TOOLKIT
11055 XtDispatchEvent (&event
);
11057 #endif /* USE_X_TOOLKIT */
11065 /* On some systems, an X bug causes Emacs to get no more events
11066 when the window is destroyed. Detect that. (1994.) */
11069 /* Emacs and the X Server eats up CPU time if XNoOp is done every time.
11070 One XNOOP in 100 loops will make Emacs terminate.
11071 B. Bretthauer, 1994 */
11073 if (x_noop_count
>= 100)
11077 if (next_noop_dpyinfo
== 0)
11078 next_noop_dpyinfo
= x_display_list
;
11080 XNoOp (next_noop_dpyinfo
->display
);
11082 /* Each time we get here, cycle through the displays now open. */
11083 next_noop_dpyinfo
= next_noop_dpyinfo
->next
;
11087 /* If the focus was just given to an auto-raising frame,
11089 /* ??? This ought to be able to handle more than one such frame. */
11090 if (pending_autoraise_frame
)
11092 x_raise_frame (pending_autoraise_frame
);
11093 pending_autoraise_frame
= 0;
11104 /***********************************************************************
11106 ***********************************************************************/
11108 /* Notice when the text cursor of window W has been completely
11109 overwritten by a drawing operation that outputs glyphs in AREA
11110 starting at X0 and ending at X1 in the line starting at Y0 and
11111 ending at Y1. X coordinates are area-relative. X1 < 0 means all
11112 the rest of the line after X0 has been written. Y coordinates
11113 are window-relative. */
11116 notice_overwritten_cursor (w
, area
, x0
, x1
, y0
, y1
)
11118 enum glyph_row_area area
;
11119 int x0
, y0
, x1
, y1
;
11121 if (area
== TEXT_AREA
11122 && w
->phys_cursor_on_p
11123 && y0
<= w
->phys_cursor
.y
11124 && y1
>= w
->phys_cursor
.y
+ w
->phys_cursor_height
11125 && x0
<= w
->phys_cursor
.x
11126 && (x1
< 0 || x1
> w
->phys_cursor
.x
))
11127 w
->phys_cursor_on_p
= 0;
11131 /* Set clipping for output in glyph row ROW. W is the window in which
11132 we operate. GC is the graphics context to set clipping in.
11133 WHOLE_LINE_P non-zero means include the areas used for truncation
11134 mark display and alike in the clipping rectangle.
11136 ROW may be a text row or, e.g., a mode line. Text rows must be
11137 clipped to the interior of the window dedicated to text display,
11138 mode lines must be clipped to the whole window. */
11141 x_clip_to_row (w
, row
, gc
, whole_line_p
)
11143 struct glyph_row
*row
;
11147 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
11148 XRectangle clip_rect
;
11149 int window_x
, window_y
, window_width
, window_height
;
11151 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
11153 clip_rect
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
11154 clip_rect
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
11155 clip_rect
.y
= max (clip_rect
.y
, window_y
);
11156 clip_rect
.width
= window_width
;
11157 clip_rect
.height
= row
->visible_height
;
11159 /* If clipping to the whole line, including trunc marks, extend
11160 the rectangle to the left and increase its width. */
11163 clip_rect
.x
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
11164 clip_rect
.width
+= FRAME_X_FRINGE_WIDTH (f
);
11167 XSetClipRectangles (FRAME_X_DISPLAY (f
), gc
, 0, 0, &clip_rect
, 1, Unsorted
);
11171 /* Draw a hollow box cursor on window W in glyph row ROW. */
11174 x_draw_hollow_cursor (w
, row
)
11176 struct glyph_row
*row
;
11178 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
11179 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
11180 Display
*dpy
= FRAME_X_DISPLAY (f
);
11183 struct glyph
*cursor_glyph
;
11186 /* Compute frame-relative coordinates from window-relative
11188 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
11189 y
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
11190 + row
->ascent
- w
->phys_cursor_ascent
);
11191 h
= row
->height
- 1;
11193 /* Get the glyph the cursor is on. If we can't tell because
11194 the current matrix is invalid or such, give up. */
11195 cursor_glyph
= get_phys_cursor_glyph (w
);
11196 if (cursor_glyph
== NULL
)
11199 /* Compute the width of the rectangle to draw. If on a stretch
11200 glyph, and `x-stretch-block-cursor' is nil, don't draw a
11201 rectangle as wide as the glyph, but use a canonical character
11203 wd
= cursor_glyph
->pixel_width
- 1;
11204 if (cursor_glyph
->type
== STRETCH_GLYPH
11205 && !x_stretch_cursor_p
)
11206 wd
= min (CANON_X_UNIT (f
), wd
);
11208 /* The foreground of cursor_gc is typically the same as the normal
11209 background color, which can cause the cursor box to be invisible. */
11210 xgcv
.foreground
= f
->output_data
.x
->cursor_pixel
;
11211 if (dpyinfo
->scratch_cursor_gc
)
11212 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
11214 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_X_WINDOW (f
),
11215 GCForeground
, &xgcv
);
11216 gc
= dpyinfo
->scratch_cursor_gc
;
11218 /* Set clipping, draw the rectangle, and reset clipping again. */
11219 x_clip_to_row (w
, row
, gc
, 0);
11220 XDrawRectangle (dpy
, FRAME_X_WINDOW (f
), gc
, x
, y
, wd
, h
);
11221 XSetClipMask (dpy
, gc
, None
);
11225 /* Draw a bar cursor on window W in glyph row ROW.
11227 Implementation note: One would like to draw a bar cursor with an
11228 angle equal to the one given by the font property XA_ITALIC_ANGLE.
11229 Unfortunately, I didn't find a font yet that has this property set.
11233 x_draw_bar_cursor (w
, row
, width
)
11235 struct glyph_row
*row
;
11238 struct frame
*f
= XFRAME (w
->frame
);
11239 struct glyph
*cursor_glyph
;
11241 /* If cursor is out of bounds, don't draw garbage. This can happen
11242 in mini-buffer windows when switching between echo area glyphs
11243 and mini-buffer. */
11244 cursor_glyph
= get_phys_cursor_glyph (w
);
11245 if (cursor_glyph
== NULL
)
11248 /* If on an image, draw like a normal cursor. That's usually better
11249 visible than drawing a bar, esp. if the image is large so that
11250 the bar might not be in the window. */
11251 if (cursor_glyph
->type
== IMAGE_GLYPH
)
11253 struct glyph_row
*row
;
11254 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
11255 x_draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
11259 Display
*dpy
= FRAME_X_DISPLAY (f
);
11260 Window window
= FRAME_X_WINDOW (f
);
11261 GC gc
= FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
;
11262 unsigned long mask
= GCForeground
| GCBackground
| GCGraphicsExposures
;
11263 struct face
*face
= FACE_FROM_ID (f
, cursor_glyph
->face_id
);
11266 /* If the glyph's background equals the color we normally draw
11267 the bar cursor in, the bar cursor in its normal color is
11268 invisible. Use the glyph's foreground color instead in this
11269 case, on the assumption that the glyph's colors are chosen so
11270 that the glyph is legible. */
11271 if (face
->background
== f
->output_data
.x
->cursor_pixel
)
11272 xgcv
.background
= xgcv
.foreground
= face
->foreground
;
11274 xgcv
.background
= xgcv
.foreground
= f
->output_data
.x
->cursor_pixel
;
11275 xgcv
.graphics_exposures
= 0;
11278 XChangeGC (dpy
, gc
, mask
, &xgcv
);
11281 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
11282 FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
11286 width
= f
->output_data
.x
->cursor_width
;
11287 width
= min (cursor_glyph
->pixel_width
, width
);
11289 x_clip_to_row (w
, row
, gc
, 0);
11290 XFillRectangle (dpy
, window
, gc
,
11291 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
11292 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
11293 width
, row
->height
);
11294 XSetClipMask (dpy
, gc
, None
);
11299 /* Clear the cursor of window W to background color, and mark the
11300 cursor as not shown. This is used when the text where the cursor
11301 is is about to be rewritten. */
11307 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
11308 x_update_window_cursor (w
, 0);
11312 /* Draw the cursor glyph of window W in glyph row ROW. See the
11313 comment of x_draw_glyphs for the meaning of HL. */
11316 x_draw_phys_cursor_glyph (w
, row
, hl
)
11318 struct glyph_row
*row
;
11319 enum draw_glyphs_face hl
;
11321 /* If cursor hpos is out of bounds, don't draw garbage. This can
11322 happen in mini-buffer windows when switching between echo area
11323 glyphs and mini-buffer. */
11324 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
11326 int on_p
= w
->phys_cursor_on_p
;
11328 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
11329 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
11331 w
->phys_cursor_on_p
= on_p
;
11333 /* When we erase the cursor, and ROW is overlapped by other
11334 rows, make sure that these overlapping parts of other rows
11336 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
11338 if (row
> w
->current_matrix
->rows
11339 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
11340 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
11342 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
11343 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
11344 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
11350 /* Erase the image of a cursor of window W from the screen. */
11353 x_erase_phys_cursor (w
)
11356 struct frame
*f
= XFRAME (w
->frame
);
11357 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
11358 int hpos
= w
->phys_cursor
.hpos
;
11359 int vpos
= w
->phys_cursor
.vpos
;
11360 int mouse_face_here_p
= 0;
11361 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
11362 struct glyph_row
*cursor_row
;
11363 struct glyph
*cursor_glyph
;
11364 enum draw_glyphs_face hl
;
11366 /* No cursor displayed or row invalidated => nothing to do on the
11368 if (w
->phys_cursor_type
== NO_CURSOR
)
11369 goto mark_cursor_off
;
11371 /* VPOS >= active_glyphs->nrows means that window has been resized.
11372 Don't bother to erase the cursor. */
11373 if (vpos
>= active_glyphs
->nrows
)
11374 goto mark_cursor_off
;
11376 /* If row containing cursor is marked invalid, there is nothing we
11378 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
11379 if (!cursor_row
->enabled_p
)
11380 goto mark_cursor_off
;
11382 /* This can happen when the new row is shorter than the old one.
11383 In this case, either x_draw_glyphs or clear_end_of_line
11384 should have cleared the cursor. Note that we wouldn't be
11385 able to erase the cursor in this case because we don't have a
11386 cursor glyph at hand. */
11387 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
11388 goto mark_cursor_off
;
11390 /* If the cursor is in the mouse face area, redisplay that when
11391 we clear the cursor. */
11392 if (! NILP (dpyinfo
->mouse_face_window
)
11393 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
11394 && (vpos
> dpyinfo
->mouse_face_beg_row
11395 || (vpos
== dpyinfo
->mouse_face_beg_row
11396 && hpos
>= dpyinfo
->mouse_face_beg_col
))
11397 && (vpos
< dpyinfo
->mouse_face_end_row
11398 || (vpos
== dpyinfo
->mouse_face_end_row
11399 && hpos
< dpyinfo
->mouse_face_end_col
))
11400 /* Don't redraw the cursor's spot in mouse face if it is at the
11401 end of a line (on a newline). The cursor appears there, but
11402 mouse highlighting does not. */
11403 && cursor_row
->used
[TEXT_AREA
] > hpos
)
11404 mouse_face_here_p
= 1;
11406 /* Maybe clear the display under the cursor. */
11407 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
11410 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
11412 cursor_glyph
= get_phys_cursor_glyph (w
);
11413 if (cursor_glyph
== NULL
)
11414 goto mark_cursor_off
;
11416 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
11418 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
11420 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
11422 cursor_glyph
->pixel_width
,
11423 cursor_row
->visible_height
,
11427 /* Erase the cursor by redrawing the character underneath it. */
11428 if (mouse_face_here_p
)
11429 hl
= DRAW_MOUSE_FACE
;
11431 hl
= DRAW_NORMAL_TEXT
;
11432 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
11435 w
->phys_cursor_on_p
= 0;
11436 w
->phys_cursor_type
= NO_CURSOR
;
11440 /* Non-zero if physical cursor of window W is within mouse face. */
11443 cursor_in_mouse_face_p (w
)
11446 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
11447 int in_mouse_face
= 0;
11449 if (WINDOWP (dpyinfo
->mouse_face_window
)
11450 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
11452 int hpos
= w
->phys_cursor
.hpos
;
11453 int vpos
= w
->phys_cursor
.vpos
;
11455 if (vpos
>= dpyinfo
->mouse_face_beg_row
11456 && vpos
<= dpyinfo
->mouse_face_end_row
11457 && (vpos
> dpyinfo
->mouse_face_beg_row
11458 || hpos
>= dpyinfo
->mouse_face_beg_col
)
11459 && (vpos
< dpyinfo
->mouse_face_end_row
11460 || hpos
< dpyinfo
->mouse_face_end_col
11461 || dpyinfo
->mouse_face_past_end
))
11465 return in_mouse_face
;
11469 /* Display or clear cursor of window W. If ON is zero, clear the
11470 cursor. If it is non-zero, display the cursor. If ON is nonzero,
11471 where to put the cursor is specified by HPOS, VPOS, X and Y. */
11474 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
11476 int on
, hpos
, vpos
, x
, y
;
11478 struct frame
*f
= XFRAME (w
->frame
);
11479 int new_cursor_type
;
11480 int new_cursor_width
;
11481 struct glyph_matrix
*current_glyphs
;
11482 struct glyph_row
*glyph_row
;
11483 struct glyph
*glyph
;
11484 int cursor_non_selected
;
11486 /* This is pointless on invisible frames, and dangerous on garbaged
11487 windows and frames; in the latter case, the frame or window may
11488 be in the midst of changing its size, and x and y may be off the
11490 if (! FRAME_VISIBLE_P (f
)
11491 || FRAME_GARBAGED_P (f
)
11492 || vpos
>= w
->current_matrix
->nrows
11493 || hpos
>= w
->current_matrix
->matrix_w
)
11496 /* If cursor is off and we want it off, return quickly. */
11497 if (!on
&& !w
->phys_cursor_on_p
)
11500 current_glyphs
= w
->current_matrix
;
11501 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
11502 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
11504 /* If cursor row is not enabled, we don't really know where to
11505 display the cursor. */
11506 if (!glyph_row
->enabled_p
)
11508 w
->phys_cursor_on_p
= 0;
11512 xassert (interrupt_input_blocked
);
11514 /* Set new_cursor_type to the cursor we want to be displayed. In a
11515 mini-buffer window, we want the cursor only to appear if we are
11516 reading input from this window. For the selected window, we want
11517 the cursor type given by the frame parameter. If explicitly
11518 marked off, draw no cursor. In all other cases, we want a hollow
11520 cursor_non_selected
11521 = !NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows
,
11523 new_cursor_width
= -1;
11524 if (cursor_in_echo_area
11525 && FRAME_HAS_MINIBUF_P (f
)
11526 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
11528 if (w
== XWINDOW (echo_area_window
))
11529 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
11530 else if (cursor_non_selected
)
11531 new_cursor_type
= HOLLOW_BOX_CURSOR
;
11533 new_cursor_type
= NO_CURSOR
;
11537 if (f
!= FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
11538 || w
!= XWINDOW (f
->selected_window
))
11540 if ((MINI_WINDOW_P (w
) && minibuf_level
== 0)
11541 || !cursor_non_selected
11542 || NILP (XBUFFER (w
->buffer
)->cursor_type
))
11543 new_cursor_type
= NO_CURSOR
;
11545 new_cursor_type
= HOLLOW_BOX_CURSOR
;
11547 else if (w
->cursor_off_p
)
11548 new_cursor_type
= NO_CURSOR
;
11551 struct buffer
*b
= XBUFFER (w
->buffer
);
11553 if (EQ (b
->cursor_type
, Qt
))
11554 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
11556 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
11557 &new_cursor_width
);
11561 /* If cursor is currently being shown and we don't want it to be or
11562 it is in the wrong place, or the cursor type is not what we want,
11564 if (w
->phys_cursor_on_p
11566 || w
->phys_cursor
.x
!= x
11567 || w
->phys_cursor
.y
!= y
11568 || new_cursor_type
!= w
->phys_cursor_type
))
11569 x_erase_phys_cursor (w
);
11571 /* If the cursor is now invisible and we want it to be visible,
11573 if (on
&& !w
->phys_cursor_on_p
)
11575 w
->phys_cursor_ascent
= glyph_row
->ascent
;
11576 w
->phys_cursor_height
= glyph_row
->height
;
11578 /* Set phys_cursor_.* before x_draw_.* is called because some
11579 of them may need the information. */
11580 w
->phys_cursor
.x
= x
;
11581 w
->phys_cursor
.y
= glyph_row
->y
;
11582 w
->phys_cursor
.hpos
= hpos
;
11583 w
->phys_cursor
.vpos
= vpos
;
11584 w
->phys_cursor_type
= new_cursor_type
;
11585 w
->phys_cursor_on_p
= 1;
11587 switch (new_cursor_type
)
11589 case HOLLOW_BOX_CURSOR
:
11590 x_draw_hollow_cursor (w
, glyph_row
);
11593 case FILLED_BOX_CURSOR
:
11594 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
11598 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
11609 if (w
== XWINDOW (f
->selected_window
))
11610 if (FRAME_XIC (f
) && (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
))
11611 xic_set_preeditarea (w
, x
, y
);
11616 if (updating_frame
!= f
)
11617 XFlush (FRAME_X_DISPLAY (f
));
11622 /* Display the cursor on window W, or clear it. X and Y are window
11623 relative pixel coordinates. HPOS and VPOS are glyph matrix
11624 positions. If W is not the selected window, display a hollow
11625 cursor. ON non-zero means display the cursor at X, Y which
11626 correspond to HPOS, VPOS, otherwise it is cleared. */
11629 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
11631 int on
, hpos
, vpos
, x
, y
;
11634 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
11639 /* Display the cursor on window W, or clear it, according to ON_P.
11640 Don't change the cursor's position. */
11643 x_update_cursor (f
, on_p
)
11646 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
11650 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
11651 in the window tree rooted at W. */
11654 x_update_cursor_in_window_tree (w
, on_p
)
11660 if (!NILP (w
->hchild
))
11661 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
11662 else if (!NILP (w
->vchild
))
11663 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
11665 x_update_window_cursor (w
, on_p
);
11667 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
11672 /* Switch the display of W's cursor on or off, according to the value
11676 x_update_window_cursor (w
, on
)
11680 /* Don't update cursor in windows whose frame is in the process
11681 of being deleted. */
11682 if (w
->current_matrix
)
11685 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
11686 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
11696 /* Make the x-window of frame F use the gnu icon bitmap. */
11699 x_bitmap_icon (f
, file
)
11705 if (FRAME_X_WINDOW (f
) == 0)
11708 /* Free up our existing icon bitmap if any. */
11709 if (f
->output_data
.x
->icon_bitmap
> 0)
11710 x_destroy_bitmap (f
, f
->output_data
.x
->icon_bitmap
);
11711 f
->output_data
.x
->icon_bitmap
= 0;
11713 if (STRINGP (file
))
11714 bitmap_id
= x_create_bitmap_from_file (f
, file
);
11717 /* Create the GNU bitmap if necessary. */
11718 if (FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
< 0)
11719 FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
11720 = x_create_bitmap_from_data (f
, gnu_bits
,
11721 gnu_width
, gnu_height
);
11723 /* The first time we create the GNU bitmap,
11724 this increments the ref-count one extra time.
11725 As a result, the GNU bitmap is never freed.
11726 That way, we don't have to worry about allocating it again. */
11727 x_reference_bitmap (f
, FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
);
11729 bitmap_id
= FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
;
11732 x_wm_set_icon_pixmap (f
, bitmap_id
);
11733 f
->output_data
.x
->icon_bitmap
= bitmap_id
;
11739 /* Make the x-window of frame F use a rectangle with text.
11740 Use ICON_NAME as the text. */
11743 x_text_icon (f
, icon_name
)
11747 if (FRAME_X_WINDOW (f
) == 0)
11752 XTextProperty text
;
11753 text
.value
= (unsigned char *) icon_name
;
11754 text
.encoding
= XA_STRING
;
11756 text
.nitems
= strlen (icon_name
);
11757 #ifdef USE_X_TOOLKIT
11758 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
11760 #else /* not USE_X_TOOLKIT */
11761 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
11762 #endif /* not USE_X_TOOLKIT */
11764 #else /* not HAVE_X11R4 */
11765 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), icon_name
);
11766 #endif /* not HAVE_X11R4 */
11768 if (f
->output_data
.x
->icon_bitmap
> 0)
11769 x_destroy_bitmap (f
, f
->output_data
.x
->icon_bitmap
);
11770 f
->output_data
.x
->icon_bitmap
= 0;
11771 x_wm_set_icon_pixmap (f
, 0);
11776 #define X_ERROR_MESSAGE_SIZE 200
11778 /* If non-nil, this should be a string.
11779 It means catch X errors and store the error message in this string. */
11781 static Lisp_Object x_error_message_string
;
11783 /* An X error handler which stores the error message in
11784 x_error_message_string. This is called from x_error_handler if
11785 x_catch_errors is in effect. */
11788 x_error_catcher (display
, error
)
11790 XErrorEvent
*error
;
11792 XGetErrorText (display
, error
->error_code
,
11793 XSTRING (x_error_message_string
)->data
,
11794 X_ERROR_MESSAGE_SIZE
);
11797 /* Begin trapping X errors for display DPY. Actually we trap X errors
11798 for all displays, but DPY should be the display you are actually
11801 After calling this function, X protocol errors no longer cause
11802 Emacs to exit; instead, they are recorded in the string
11803 stored in x_error_message_string.
11805 Calling x_check_errors signals an Emacs error if an X error has
11806 occurred since the last call to x_catch_errors or x_check_errors.
11808 Calling x_uncatch_errors resumes the normal error handling. */
11810 void x_check_errors ();
11811 static Lisp_Object
x_catch_errors_unwind ();
11814 x_catch_errors (dpy
)
11817 int count
= specpdl_ptr
- specpdl
;
11819 /* Make sure any errors from previous requests have been dealt with. */
11820 XSync (dpy
, False
);
11822 record_unwind_protect (x_catch_errors_unwind
, x_error_message_string
);
11824 x_error_message_string
= make_uninit_string (X_ERROR_MESSAGE_SIZE
);
11825 XSTRING (x_error_message_string
)->data
[0] = 0;
11830 /* Unbind the binding that we made to check for X errors. */
11833 x_catch_errors_unwind (old_val
)
11834 Lisp_Object old_val
;
11836 x_error_message_string
= old_val
;
11840 /* If any X protocol errors have arrived since the last call to
11841 x_catch_errors or x_check_errors, signal an Emacs error using
11842 sprintf (a buffer, FORMAT, the x error message text) as the text. */
11845 x_check_errors (dpy
, format
)
11849 /* Make sure to catch any errors incurred so far. */
11850 XSync (dpy
, False
);
11852 if (XSTRING (x_error_message_string
)->data
[0])
11853 error (format
, XSTRING (x_error_message_string
)->data
);
11856 /* Nonzero if we had any X protocol errors
11857 since we did x_catch_errors on DPY. */
11860 x_had_errors_p (dpy
)
11863 /* Make sure to catch any errors incurred so far. */
11864 XSync (dpy
, False
);
11866 return XSTRING (x_error_message_string
)->data
[0] != 0;
11869 /* Forget about any errors we have had, since we did x_catch_errors on DPY. */
11872 x_clear_errors (dpy
)
11875 XSTRING (x_error_message_string
)->data
[0] = 0;
11878 /* Stop catching X protocol errors and let them make Emacs die.
11879 DPY should be the display that was passed to x_catch_errors.
11880 COUNT should be the value that was returned by
11881 the corresponding call to x_catch_errors. */
11884 x_uncatch_errors (dpy
, count
)
11888 unbind_to (count
, Qnil
);
11892 static unsigned int x_wire_count
;
11895 fprintf (stderr
, "Lib call: %d\n", ++x_wire_count
);
11900 /* Handle SIGPIPE, which can happen when the connection to a server
11901 simply goes away. SIGPIPE is handled by x_connection_signal.
11902 Don't need to do anything, because the write which caused the
11903 SIGPIPE will fail, causing Xlib to invoke the X IO error handler,
11904 which will do the appropriate cleanup for us. */
11907 x_connection_signal (signalnum
) /* If we don't have an argument, */
11908 int signalnum
; /* some compilers complain in signal calls. */
11911 /* USG systems forget handlers when they are used;
11912 must reestablish each time */
11913 signal (signalnum
, x_connection_signal
);
11918 /************************************************************************
11920 ************************************************************************/
11922 /* Error message passed to x_connection_closed. */
11924 static char *error_msg
;
11926 /* Function installed as fatal_error_signal_hook in
11927 x_connection_closed. Print the X error message, and exit normally,
11928 instead of dumping core when XtCloseDisplay fails. */
11931 x_fatal_error_signal ()
11933 fprintf (stderr
, "%s\n", error_msg
);
11937 /* Handle the loss of connection to display DPY. ERROR_MESSAGE is
11938 the text of an error message that lead to the connection loss. */
11941 x_connection_closed (dpy
, error_message
)
11943 char *error_message
;
11945 struct x_display_info
*dpyinfo
= x_display_info_for_display (dpy
);
11946 Lisp_Object frame
, tail
;
11949 error_msg
= (char *) alloca (strlen (error_message
) + 1);
11950 strcpy (error_msg
, error_message
);
11951 handling_signal
= 0;
11953 /* Prevent being called recursively because of an error condition
11954 below. Otherwise, we might end up with printing ``can't find per
11955 display information'' in the recursive call instead of printing
11956 the original message here. */
11957 count
= x_catch_errors (dpy
);
11959 /* We have to close the display to inform Xt that it doesn't
11960 exist anymore. If we don't, Xt will continue to wait for
11961 events from the display. As a consequence, a sequence of
11963 M-x make-frame-on-display RET :1 RET
11964 ...kill the new frame, so that we get an IO error...
11965 M-x make-frame-on-display RET :1 RET
11967 will indefinitely wait in Xt for events for display `:1', opened
11968 in the first class to make-frame-on-display.
11970 Closing the display is reported to lead to a bus error on
11971 OpenWindows in certain situations. I suspect that is a bug
11972 in OpenWindows. I don't know how to cicumvent it here. */
11974 #ifdef USE_X_TOOLKIT
11975 /* If DPYINFO is null, this means we didn't open the display
11976 in the first place, so don't try to close it. */
11979 extern void (*fatal_error_signal_hook
) P_ ((void));
11980 fatal_error_signal_hook
= x_fatal_error_signal
;
11981 XtCloseDisplay (dpy
);
11982 fatal_error_signal_hook
= NULL
;
11986 /* Indicate that this display is dead. */
11988 dpyinfo
->display
= 0;
11990 /* First delete frames whose mini-buffers are on frames
11991 that are on the dead display. */
11992 FOR_EACH_FRAME (tail
, frame
)
11994 Lisp_Object minibuf_frame
;
11996 = WINDOW_FRAME (XWINDOW (FRAME_MINIBUF_WINDOW (XFRAME (frame
))));
11997 if (FRAME_X_P (XFRAME (frame
))
11998 && FRAME_X_P (XFRAME (minibuf_frame
))
11999 && ! EQ (frame
, minibuf_frame
)
12000 && FRAME_X_DISPLAY_INFO (XFRAME (minibuf_frame
)) == dpyinfo
)
12001 Fdelete_frame (frame
, Qt
);
12004 /* Now delete all remaining frames on the dead display.
12005 We are now sure none of these is used as the mini-buffer
12006 for another frame that we need to delete. */
12007 FOR_EACH_FRAME (tail
, frame
)
12008 if (FRAME_X_P (XFRAME (frame
))
12009 && FRAME_X_DISPLAY_INFO (XFRAME (frame
)) == dpyinfo
)
12011 /* Set this to t so that Fdelete_frame won't get confused
12012 trying to find a replacement. */
12013 FRAME_KBOARD (XFRAME (frame
))->Vdefault_minibuffer_frame
= Qt
;
12014 Fdelete_frame (frame
, Qt
);
12018 x_delete_display (dpyinfo
);
12020 x_uncatch_errors (dpy
, count
);
12022 if (x_display_list
== 0)
12024 fprintf (stderr
, "%s\n", error_msg
);
12025 shut_down_emacs (0, 0, Qnil
);
12029 /* Ordinary stack unwind doesn't deal with these. */
12031 sigunblock (sigmask (SIGIO
));
12033 sigunblock (sigmask (SIGALRM
));
12034 TOTALLY_UNBLOCK_INPUT
;
12036 clear_waiting_for_input ();
12037 error ("%s", error_msg
);
12041 /* This is the usual handler for X protocol errors.
12042 It kills all frames on the display that we got the error for.
12043 If that was the only one, it prints an error message and kills Emacs. */
12046 x_error_quitter (display
, error
)
12048 XErrorEvent
*error
;
12050 char buf
[256], buf1
[356];
12052 /* Note that there is no real way portable across R3/R4 to get the
12053 original error handler. */
12055 XGetErrorText (display
, error
->error_code
, buf
, sizeof (buf
));
12056 sprintf (buf1
, "X protocol error: %s on protocol request %d",
12057 buf
, error
->request_code
);
12058 x_connection_closed (display
, buf1
);
12062 /* This is the first-level handler for X protocol errors.
12063 It calls x_error_quitter or x_error_catcher. */
12066 x_error_handler (display
, error
)
12068 XErrorEvent
*error
;
12070 if (! NILP (x_error_message_string
))
12071 x_error_catcher (display
, error
);
12073 x_error_quitter (display
, error
);
12077 /* This is the handler for X IO errors, always.
12078 It kills all frames on the display that we lost touch with.
12079 If that was the only one, it prints an error message and kills Emacs. */
12082 x_io_error_quitter (display
)
12087 sprintf (buf
, "Connection lost to X server `%s'", DisplayString (display
));
12088 x_connection_closed (display
, buf
);
12092 /* Changing the font of the frame. */
12094 /* Give frame F the font named FONTNAME as its default font, and
12095 return the full name of that font. FONTNAME may be a wildcard
12096 pattern; in that case, we choose some font that fits the pattern.
12097 The return value shows which font we chose. */
12100 x_new_font (f
, fontname
)
12102 register char *fontname
;
12104 struct font_info
*fontp
12105 = FS_LOAD_FONT (f
, 0, fontname
, -1);
12110 f
->output_data
.x
->font
= (XFontStruct
*) (fontp
->font
);
12111 f
->output_data
.x
->baseline_offset
= fontp
->baseline_offset
;
12112 f
->output_data
.x
->fontset
= -1;
12114 x_compute_fringe_widths (f
, 1);
12116 /* Compute the scroll bar width in character columns. */
12117 if (f
->scroll_bar_pixel_width
> 0)
12119 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
12120 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
12124 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
12125 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
12128 /* Now make the frame display the given font. */
12129 if (FRAME_X_WINDOW (f
) != 0)
12131 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->normal_gc
,
12132 f
->output_data
.x
->font
->fid
);
12133 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->reverse_gc
,
12134 f
->output_data
.x
->font
->fid
);
12135 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
12136 f
->output_data
.x
->font
->fid
);
12138 frame_update_line_height (f
);
12140 /* Don't change the size of a tip frame; there's no point in
12141 doing it because it's done in Fx_show_tip, and it leads to
12142 problems because the tip frame has no widget. */
12143 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
12144 x_set_window_size (f
, 0, f
->width
, f
->height
);
12147 /* If we are setting a new frame's font for the first time,
12148 there are no faces yet, so this font's height is the line height. */
12149 f
->output_data
.x
->line_height
= FONT_HEIGHT (f
->output_data
.x
->font
);
12151 return build_string (fontp
->full_name
);
12154 /* Give frame F the fontset named FONTSETNAME as its default font, and
12155 return the full name of that fontset. FONTSETNAME may be a wildcard
12156 pattern; in that case, we choose some fontset that fits the pattern.
12157 The return value shows which fontset we chose. */
12160 x_new_fontset (f
, fontsetname
)
12164 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
12165 Lisp_Object result
;
12170 if (f
->output_data
.x
->fontset
== fontset
)
12171 /* This fontset is already set in frame F. There's nothing more
12173 return fontset_name (fontset
);
12175 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
12177 if (!STRINGP (result
))
12178 /* Can't load ASCII font. */
12181 /* Since x_new_font doesn't update any fontset information, do it now. */
12182 f
->output_data
.x
->fontset
= fontset
;
12186 && (FRAME_XIC_STYLE (f
) & (XIMPreeditPosition
| XIMStatusArea
)))
12187 xic_set_xfontset (f
, XSTRING (fontset_ascii (fontset
))->data
);
12190 return build_string (fontsetname
);
12193 /* Compute actual fringe widths */
12196 x_compute_fringe_widths (f
, redraw
)
12200 int o_left
= f
->output_data
.x
->left_fringe_width
;
12201 int o_right
= f
->output_data
.x
->right_fringe_width
;
12202 int o_cols
= f
->output_data
.x
->fringe_cols
;
12204 Lisp_Object left_fringe
= Fassq (Qleft_fringe
, f
->param_alist
);
12205 Lisp_Object right_fringe
= Fassq (Qright_fringe
, f
->param_alist
);
12206 int left_fringe_width
, right_fringe_width
;
12208 if (!NILP (left_fringe
))
12209 left_fringe
= Fcdr (left_fringe
);
12210 if (!NILP (right_fringe
))
12211 right_fringe
= Fcdr (right_fringe
);
12213 left_fringe_width
= ((NILP (left_fringe
) || !INTEGERP (left_fringe
)) ? 8 :
12214 XINT (left_fringe
));
12215 right_fringe_width
= ((NILP (right_fringe
) || !INTEGERP (right_fringe
)) ? 8 :
12216 XINT (right_fringe
));
12218 if (left_fringe_width
|| right_fringe_width
)
12220 int left_wid
= left_fringe_width
>= 0 ? left_fringe_width
: -left_fringe_width
;
12221 int right_wid
= right_fringe_width
>= 0 ? right_fringe_width
: -right_fringe_width
;
12222 int conf_wid
= left_wid
+ right_wid
;
12223 int font_wid
= FONT_WIDTH (f
->output_data
.x
->font
);
12224 int cols
= (left_wid
+ right_wid
+ font_wid
-1) / font_wid
;
12225 int real_wid
= cols
* font_wid
;
12226 if (left_wid
&& right_wid
)
12228 if (left_fringe_width
< 0)
12230 /* Left fringe width is fixed, adjust right fringe if necessary */
12231 f
->output_data
.x
->left_fringe_width
= left_wid
;
12232 f
->output_data
.x
->right_fringe_width
= real_wid
- left_wid
;
12234 else if (right_fringe_width
< 0)
12236 /* Right fringe width is fixed, adjust left fringe if necessary */
12237 f
->output_data
.x
->left_fringe_width
= real_wid
- right_wid
;
12238 f
->output_data
.x
->right_fringe_width
= right_wid
;
12242 /* Adjust both fringes with an equal amount.
12243 Note that we are doing integer arithmetic here, so don't
12244 lose a pixel if the total width is an odd number. */
12245 int fill
= real_wid
- conf_wid
;
12246 f
->output_data
.x
->left_fringe_width
= left_wid
+ fill
/2;
12247 f
->output_data
.x
->right_fringe_width
= right_wid
+ fill
- fill
/2;
12250 else if (left_fringe_width
)
12252 f
->output_data
.x
->left_fringe_width
= real_wid
;
12253 f
->output_data
.x
->right_fringe_width
= 0;
12257 f
->output_data
.x
->left_fringe_width
= 0;
12258 f
->output_data
.x
->right_fringe_width
= real_wid
;
12260 f
->output_data
.x
->fringe_cols
= cols
;
12261 f
->output_data
.x
->fringes_extra
= real_wid
;
12265 f
->output_data
.x
->left_fringe_width
= 0;
12266 f
->output_data
.x
->right_fringe_width
= 0;
12267 f
->output_data
.x
->fringe_cols
= 0;
12268 f
->output_data
.x
->fringes_extra
= 0;
12271 if (redraw
&& FRAME_VISIBLE_P (f
))
12272 if (o_left
!= f
->output_data
.x
->left_fringe_width
||
12273 o_right
!= f
->output_data
.x
->right_fringe_width
||
12274 o_cols
!= f
->output_data
.x
->fringe_cols
)
12278 /***********************************************************************
12280 ***********************************************************************/
12286 /* XIM destroy callback function, which is called whenever the
12287 connection to input method XIM dies. CLIENT_DATA contains a
12288 pointer to the x_display_info structure corresponding to XIM. */
12291 xim_destroy_callback (xim
, client_data
, call_data
)
12293 XPointer client_data
;
12294 XPointer call_data
;
12296 struct x_display_info
*dpyinfo
= (struct x_display_info
*) client_data
;
12297 Lisp_Object frame
, tail
;
12301 /* No need to call XDestroyIC.. */
12302 FOR_EACH_FRAME (tail
, frame
)
12304 struct frame
*f
= XFRAME (frame
);
12305 if (FRAME_X_DISPLAY_INFO (f
) == dpyinfo
)
12307 FRAME_XIC (f
) = NULL
;
12308 if (FRAME_XIC_FONTSET (f
))
12310 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
12311 FRAME_XIC_FONTSET (f
) = NULL
;
12316 /* No need to call XCloseIM. */
12317 dpyinfo
->xim
= NULL
;
12318 XFree (dpyinfo
->xim_styles
);
12322 #endif /* HAVE_X11R6 */
12324 /* Open the connection to the XIM server on display DPYINFO.
12325 RESOURCE_NAME is the resource name Emacs uses. */
12328 xim_open_dpy (dpyinfo
, resource_name
)
12329 struct x_display_info
*dpyinfo
;
12330 char *resource_name
;
12335 xim
= XOpenIM (dpyinfo
->display
, dpyinfo
->xrdb
, resource_name
, EMACS_CLASS
);
12336 dpyinfo
->xim
= xim
;
12341 XIMCallback destroy
;
12344 /* Get supported styles and XIM values. */
12345 XGetIMValues (xim
, XNQueryInputStyle
, &dpyinfo
->xim_styles
, NULL
);
12348 destroy
.callback
= xim_destroy_callback
;
12349 destroy
.client_data
= (XPointer
)dpyinfo
;
12350 /* This isn't prototyped in OSF 5.0. */
12351 XSetIMValues (xim
, XNDestroyCallback
, &destroy
, NULL
);
12355 #else /* not USE_XIM */
12356 dpyinfo
->xim
= NULL
;
12357 #endif /* not USE_XIM */
12361 #ifdef HAVE_X11R6_XIM
12365 struct x_display_info
*dpyinfo
;
12366 char *resource_name
;
12369 /* XIM instantiate callback function, which is called whenever an XIM
12370 server is available. DISPLAY is teh display of the XIM.
12371 CLIENT_DATA contains a pointer to an xim_inst_t structure created
12372 when the callback was registered. */
12375 xim_instantiate_callback (display
, client_data
, call_data
)
12377 XPointer client_data
;
12378 XPointer call_data
;
12380 struct xim_inst_t
*xim_inst
= (struct xim_inst_t
*) client_data
;
12381 struct x_display_info
*dpyinfo
= xim_inst
->dpyinfo
;
12383 /* We don't support multiple XIM connections. */
12387 xim_open_dpy (dpyinfo
, xim_inst
->resource_name
);
12389 /* Create XIC for the existing frames on the same display, as long
12390 as they have no XIC. */
12391 if (dpyinfo
->xim
&& dpyinfo
->reference_count
> 0)
12393 Lisp_Object tail
, frame
;
12396 FOR_EACH_FRAME (tail
, frame
)
12398 struct frame
*f
= XFRAME (frame
);
12400 if (FRAME_X_DISPLAY_INFO (f
) == xim_inst
->dpyinfo
)
12401 if (FRAME_XIC (f
) == NULL
)
12403 create_frame_xic (f
);
12404 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
12405 xic_set_statusarea (f
);
12406 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
12408 struct window
*w
= XWINDOW (f
->selected_window
);
12409 xic_set_preeditarea (w
, w
->cursor
.x
, w
->cursor
.y
);
12418 #endif /* HAVE_X11R6_XIM */
12421 /* Open a connection to the XIM server on display DPYINFO.
12422 RESOURCE_NAME is the resource name for Emacs. On X11R5, open the
12423 connection only at the first time. On X11R6, open the connection
12424 in the XIM instantiate callback function. */
12427 xim_initialize (dpyinfo
, resource_name
)
12428 struct x_display_info
*dpyinfo
;
12429 char *resource_name
;
12432 #ifdef HAVE_X11R6_XIM
12433 struct xim_inst_t
*xim_inst
;
12436 dpyinfo
->xim
= NULL
;
12437 xim_inst
= (struct xim_inst_t
*) xmalloc (sizeof (struct xim_inst_t
));
12438 xim_inst
->dpyinfo
= dpyinfo
;
12439 len
= strlen (resource_name
);
12440 xim_inst
->resource_name
= (char *) xmalloc (len
+ 1);
12441 bcopy (resource_name
, xim_inst
->resource_name
, len
+ 1);
12442 XRegisterIMInstantiateCallback (dpyinfo
->display
, dpyinfo
->xrdb
,
12443 resource_name
, EMACS_CLASS
,
12444 xim_instantiate_callback
,
12445 /* Fixme: This is XPointer in
12446 XFree86 but (XPointer *) on
12447 Tru64, at least. */
12448 (XPointer
) xim_inst
);
12449 #else /* not HAVE_X11R6_XIM */
12450 dpyinfo
->xim
= NULL
;
12451 xim_open_dpy (dpyinfo
, resource_name
);
12452 #endif /* not HAVE_X11R6_XIM */
12454 #else /* not USE_XIM */
12455 dpyinfo
->xim
= NULL
;
12456 #endif /* not USE_XIM */
12460 /* Close the connection to the XIM server on display DPYINFO. */
12463 xim_close_dpy (dpyinfo
)
12464 struct x_display_info
*dpyinfo
;
12467 #ifdef HAVE_X11R6_XIM
12468 if (dpyinfo
->display
)
12469 XUnregisterIMInstantiateCallback (dpyinfo
->display
, dpyinfo
->xrdb
,
12471 xim_instantiate_callback
, NULL
);
12472 #endif /* not HAVE_X11R6_XIM */
12473 if (dpyinfo
->display
)
12474 XCloseIM (dpyinfo
->xim
);
12475 dpyinfo
->xim
= NULL
;
12476 XFree (dpyinfo
->xim_styles
);
12477 #endif /* USE_XIM */
12480 #endif /* not HAVE_X11R6_XIM */
12484 /* Calculate the absolute position in frame F
12485 from its current recorded position values and gravity. */
12488 x_calc_absolute_position (f
)
12492 int win_x
= 0, win_y
= 0;
12493 int flags
= f
->output_data
.x
->size_hint_flags
;
12496 /* We have nothing to do if the current position
12497 is already for the top-left corner. */
12498 if (! ((flags
& XNegative
) || (flags
& YNegative
)))
12501 #ifdef USE_X_TOOLKIT
12502 this_window
= XtWindow (f
->output_data
.x
->widget
);
12504 this_window
= FRAME_X_WINDOW (f
);
12507 /* Find the position of the outside upper-left corner of
12508 the inner window, with respect to the outer window.
12509 But do this only if we will need the results. */
12510 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
12515 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
12518 x_clear_errors (FRAME_X_DISPLAY (f
));
12519 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
12521 /* From-window, to-window. */
12523 f
->output_data
.x
->parent_desc
,
12525 /* From-position, to-position. */
12526 0, 0, &win_x
, &win_y
,
12528 /* Child of win. */
12530 if (x_had_errors_p (FRAME_X_DISPLAY (f
)))
12532 Window newroot
, newparent
= 0xdeadbeef;
12533 Window
*newchildren
;
12534 unsigned int nchildren
;
12536 if (! XQueryTree (FRAME_X_DISPLAY (f
), this_window
, &newroot
,
12537 &newparent
, &newchildren
, &nchildren
))
12540 XFree ((char *) newchildren
);
12542 f
->output_data
.x
->parent_desc
= newparent
;
12548 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
12552 /* Treat negative positions as relative to the leftmost bottommost
12553 position that fits on the screen. */
12554 if (flags
& XNegative
)
12555 f
->output_data
.x
->left_pos
= (FRAME_X_DISPLAY_INFO (f
)->width
12556 - 2 * f
->output_data
.x
->border_width
- win_x
12558 + f
->output_data
.x
->left_pos
);
12561 int height
= PIXEL_HEIGHT (f
);
12563 #if defined USE_X_TOOLKIT && defined USE_MOTIF
12564 /* Something is fishy here. When using Motif, starting Emacs with
12565 `-g -0-0', the frame appears too low by a few pixels.
12567 This seems to be so because initially, while Emacs is starting,
12568 the column widget's height and the frame's pixel height are
12569 different. The column widget's height is the right one. In
12570 later invocations, when Emacs is up, the frame's pixel height
12573 It's not obvious where the initial small difference comes from.
12574 2000-12-01, gerd. */
12576 XtVaGetValues (f
->output_data
.x
->column_widget
, XtNheight
, &height
, NULL
);
12579 if (flags
& YNegative
)
12580 f
->output_data
.x
->top_pos
= (FRAME_X_DISPLAY_INFO (f
)->height
12581 - 2 * f
->output_data
.x
->border_width
12584 + f
->output_data
.x
->top_pos
);
12587 /* The left_pos and top_pos
12588 are now relative to the top and left screen edges,
12589 so the flags should correspond. */
12590 f
->output_data
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
12593 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
12594 to really change the position, and 0 when calling from
12595 x_make_frame_visible (in that case, XOFF and YOFF are the current
12596 position values). It is -1 when calling from x_set_frame_parameters,
12597 which means, do adjust for borders but don't change the gravity. */
12600 x_set_offset (f
, xoff
, yoff
, change_gravity
)
12602 register int xoff
, yoff
;
12603 int change_gravity
;
12605 int modified_top
, modified_left
;
12607 if (change_gravity
> 0)
12609 f
->output_data
.x
->top_pos
= yoff
;
12610 f
->output_data
.x
->left_pos
= xoff
;
12611 f
->output_data
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
12613 f
->output_data
.x
->size_hint_flags
|= XNegative
;
12615 f
->output_data
.x
->size_hint_flags
|= YNegative
;
12616 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
12618 x_calc_absolute_position (f
);
12621 x_wm_set_size_hint (f
, (long) 0, 0);
12623 modified_left
= f
->output_data
.x
->left_pos
;
12624 modified_top
= f
->output_data
.x
->top_pos
;
12625 #if 0 /* Running on psilocin (Debian), and displaying on the NCD X-terminal,
12626 this seems to be unnecessary and incorrect. rms, 4/17/97. */
12627 /* It is a mystery why we need to add the border_width here
12628 when the frame is already visible, but experiment says we do. */
12629 if (change_gravity
!= 0)
12631 modified_left
+= f
->output_data
.x
->border_width
;
12632 modified_top
+= f
->output_data
.x
->border_width
;
12636 #ifdef USE_X_TOOLKIT
12637 XMoveWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
12638 modified_left
, modified_top
);
12639 #else /* not USE_X_TOOLKIT */
12640 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
12641 modified_left
, modified_top
);
12642 #endif /* not USE_X_TOOLKIT */
12647 /* Change the size of frame F's X window to COLS/ROWS in the case F
12648 doesn't have a widget. If CHANGE_GRAVITY is 1, we change to
12649 top-left-corner window gravity for this size change and subsequent
12650 size changes. Otherwise we leave the window gravity unchanged. */
12653 x_set_window_size_1 (f
, change_gravity
, cols
, rows
)
12655 int change_gravity
;
12658 int pixelwidth
, pixelheight
;
12660 check_frame_size (f
, &rows
, &cols
);
12661 f
->output_data
.x
->vertical_scroll_bar_extra
12662 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
12664 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
12665 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
12666 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.x
->font
)));
12668 x_compute_fringe_widths (f
, 0);
12670 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
12671 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
12673 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
12674 x_wm_set_size_hint (f
, (long) 0, 0);
12676 XSync (FRAME_X_DISPLAY (f
), False
);
12677 XResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
12678 pixelwidth
, pixelheight
);
12680 /* Now, strictly speaking, we can't be sure that this is accurate,
12681 but the window manager will get around to dealing with the size
12682 change request eventually, and we'll hear how it went when the
12683 ConfigureNotify event gets here.
12685 We could just not bother storing any of this information here,
12686 and let the ConfigureNotify event set everything up, but that
12687 might be kind of confusing to the Lisp code, since size changes
12688 wouldn't be reported in the frame parameters until some random
12689 point in the future when the ConfigureNotify event arrives.
12691 We pass 1 for DELAY since we can't run Lisp code inside of
12693 change_frame_size (f
, rows
, cols
, 0, 1, 0);
12694 PIXEL_WIDTH (f
) = pixelwidth
;
12695 PIXEL_HEIGHT (f
) = pixelheight
;
12697 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
12698 receive in the ConfigureNotify event; if we get what we asked
12699 for, then the event won't cause the screen to become garbaged, so
12700 we have to make sure to do it here. */
12701 SET_FRAME_GARBAGED (f
);
12703 XFlush (FRAME_X_DISPLAY (f
));
12707 /* Call this to change the size of frame F's x-window.
12708 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
12709 for this size change and subsequent size changes.
12710 Otherwise we leave the window gravity unchanged. */
12713 x_set_window_size (f
, change_gravity
, cols
, rows
)
12715 int change_gravity
;
12720 #ifdef USE_X_TOOLKIT
12722 if (f
->output_data
.x
->widget
!= NULL
)
12724 /* The x and y position of the widget is clobbered by the
12725 call to XtSetValues within EmacsFrameSetCharSize.
12726 This is a real kludge, but I don't understand Xt so I can't
12727 figure out a correct fix. Can anyone else tell me? -- rms. */
12728 int xpos
= f
->output_data
.x
->widget
->core
.x
;
12729 int ypos
= f
->output_data
.x
->widget
->core
.y
;
12730 EmacsFrameSetCharSize (f
->output_data
.x
->edit_widget
, cols
, rows
);
12731 f
->output_data
.x
->widget
->core
.x
= xpos
;
12732 f
->output_data
.x
->widget
->core
.y
= ypos
;
12735 x_set_window_size_1 (f
, change_gravity
, cols
, rows
);
12737 #else /* not USE_X_TOOLKIT */
12739 x_set_window_size_1 (f
, change_gravity
, cols
, rows
);
12741 #endif /* not USE_X_TOOLKIT */
12743 /* If cursor was outside the new size, mark it as off. */
12744 mark_window_cursors_off (XWINDOW (f
->root_window
));
12746 /* Clear out any recollection of where the mouse highlighting was,
12747 since it might be in a place that's outside the new frame size.
12748 Actually checking whether it is outside is a pain in the neck,
12749 so don't try--just let the highlighting be done afresh with new size. */
12750 cancel_mouse_face (f
);
12755 /* Mouse warping. */
12758 x_set_mouse_position (f
, x
, y
)
12764 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.x
->font
) / 2;
12765 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.x
->line_height
/ 2;
12767 if (pix_x
< 0) pix_x
= 0;
12768 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
12770 if (pix_y
< 0) pix_y
= 0;
12771 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
12775 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
12776 0, 0, 0, 0, pix_x
, pix_y
);
12780 /* Move the mouse to position pixel PIX_X, PIX_Y relative to frame F. */
12783 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
12789 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
12790 0, 0, 0, 0, pix_x
, pix_y
);
12794 /* focus shifting, raising and lowering. */
12797 x_focus_on_frame (f
)
12800 #if 0 /* This proves to be unpleasant. */
12804 /* I don't think that the ICCCM allows programs to do things like this
12805 without the interaction of the window manager. Whatever you end up
12806 doing with this code, do it to x_unfocus_frame too. */
12807 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
12808 RevertToPointerRoot
, CurrentTime
);
12813 x_unfocus_frame (f
)
12817 /* Look at the remarks in x_focus_on_frame. */
12818 if (FRAME_X_DISPLAY_INFO (f
)->x_focus_frame
== f
)
12819 XSetInputFocus (FRAME_X_DISPLAY (f
), PointerRoot
,
12820 RevertToPointerRoot
, CurrentTime
);
12824 /* Raise frame F. */
12830 if (f
->async_visible
)
12833 #ifdef USE_X_TOOLKIT
12834 XRaiseWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
));
12835 #else /* not USE_X_TOOLKIT */
12836 XRaiseWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12837 #endif /* not USE_X_TOOLKIT */
12838 XFlush (FRAME_X_DISPLAY (f
));
12843 /* Lower frame F. */
12849 if (f
->async_visible
)
12852 #ifdef USE_X_TOOLKIT
12853 XLowerWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
));
12854 #else /* not USE_X_TOOLKIT */
12855 XLowerWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12856 #endif /* not USE_X_TOOLKIT */
12857 XFlush (FRAME_X_DISPLAY (f
));
12863 XTframe_raise_lower (f
, raise_flag
)
12873 /* Change of visibility. */
12875 /* This tries to wait until the frame is really visible.
12876 However, if the window manager asks the user where to position
12877 the frame, this will return before the user finishes doing that.
12878 The frame will not actually be visible at that time,
12879 but it will become visible later when the window manager
12880 finishes with it. */
12883 x_make_frame_visible (f
)
12887 int original_top
, original_left
;
12888 int retry_count
= 2;
12894 type
= x_icon_type (f
);
12896 x_bitmap_icon (f
, type
);
12898 if (! FRAME_VISIBLE_P (f
))
12900 /* We test FRAME_GARBAGED_P here to make sure we don't
12901 call x_set_offset a second time
12902 if we get to x_make_frame_visible a second time
12903 before the window gets really visible. */
12904 if (! FRAME_ICONIFIED_P (f
)
12905 && ! f
->output_data
.x
->asked_for_visible
)
12906 x_set_offset (f
, f
->output_data
.x
->left_pos
, f
->output_data
.x
->top_pos
, 0);
12908 f
->output_data
.x
->asked_for_visible
= 1;
12910 if (! EQ (Vx_no_window_manager
, Qt
))
12911 x_wm_set_window_state (f
, NormalState
);
12912 #ifdef USE_X_TOOLKIT
12913 /* This was XtPopup, but that did nothing for an iconified frame. */
12914 XtMapWidget (f
->output_data
.x
->widget
);
12915 #else /* not USE_X_TOOLKIT */
12916 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12917 #endif /* not USE_X_TOOLKIT */
12918 #if 0 /* This seems to bring back scroll bars in the wrong places
12919 if the window configuration has changed. They seem
12920 to come back ok without this. */
12921 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
12922 XMapSubwindows (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12926 XFlush (FRAME_X_DISPLAY (f
));
12928 /* Synchronize to ensure Emacs knows the frame is visible
12929 before we do anything else. We do this loop with input not blocked
12930 so that incoming events are handled. */
12934 /* This must be before UNBLOCK_INPUT
12935 since events that arrive in response to the actions above
12936 will set it when they are handled. */
12937 int previously_visible
= f
->output_data
.x
->has_been_visible
;
12939 original_left
= f
->output_data
.x
->left_pos
;
12940 original_top
= f
->output_data
.x
->top_pos
;
12942 /* This must come after we set COUNT. */
12945 /* We unblock here so that arriving X events are processed. */
12947 /* Now move the window back to where it was "supposed to be".
12948 But don't do it if the gravity is negative.
12949 When the gravity is negative, this uses a position
12950 that is 3 pixels too low. Perhaps that's really the border width.
12952 Don't do this if the window has never been visible before,
12953 because the window manager may choose the position
12954 and we don't want to override it. */
12956 if (! FRAME_VISIBLE_P (f
) && ! FRAME_ICONIFIED_P (f
)
12957 && f
->output_data
.x
->win_gravity
== NorthWestGravity
12958 && previously_visible
)
12962 unsigned int width
, height
, border
, depth
;
12966 /* On some window managers (such as FVWM) moving an existing
12967 window, even to the same place, causes the window manager
12968 to introduce an offset. This can cause the window to move
12969 to an unexpected location. Check the geometry (a little
12970 slow here) and then verify that the window is in the right
12971 place. If the window is not in the right place, move it
12972 there, and take the potential window manager hit. */
12973 XGetGeometry (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
12974 &rootw
, &x
, &y
, &width
, &height
, &border
, &depth
);
12976 if (original_left
!= x
|| original_top
!= y
)
12977 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
12978 original_left
, original_top
);
12983 XSETFRAME (frame
, f
);
12985 /* Wait until the frame is visible. Process X events until a
12986 MapNotify event has been seen, or until we think we won't get a
12987 MapNotify at all.. */
12988 for (count
= input_signal_count
+ 10;
12989 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
12991 /* Force processing of queued events. */
12994 /* Machines that do polling rather than SIGIO have been
12995 observed to go into a busy-wait here. So we'll fake an
12996 alarm signal to let the handler know that there's something
12997 to be read. We used to raise a real alarm, but it seems
12998 that the handler isn't always enabled here. This is
13000 if (input_polling_used ())
13002 /* It could be confusing if a real alarm arrives while
13003 processing the fake one. Turn it off and let the
13004 handler reset it. */
13005 extern void poll_for_input_1
P_ ((void));
13006 int old_poll_suppress_count
= poll_suppress_count
;
13007 poll_suppress_count
= 1;
13008 poll_for_input_1 ();
13009 poll_suppress_count
= old_poll_suppress_count
;
13012 /* See if a MapNotify event has been processed. */
13013 FRAME_SAMPLE_VISIBILITY (f
);
13018 (let ((f (selected-frame)))
13022 the frame is not raised with various window managers on
13023 FreeBSD, Linux and Solaris. It turns out that, for some
13024 unknown reason, the call to XtMapWidget is completely ignored.
13025 Mapping the widget a second time works. */
13027 if (!FRAME_VISIBLE_P (f
) && --retry_count
> 0)
13032 /* Change from mapped state to withdrawn state. */
13034 /* Make the frame visible (mapped and not iconified). */
13037 x_make_frame_invisible (f
)
13042 #ifdef USE_X_TOOLKIT
13043 /* Use the frame's outermost window, not the one we normally draw on. */
13044 window
= XtWindow (f
->output_data
.x
->widget
);
13045 #else /* not USE_X_TOOLKIT */
13046 window
= FRAME_X_WINDOW (f
);
13047 #endif /* not USE_X_TOOLKIT */
13049 /* Don't keep the highlight on an invisible frame. */
13050 if (FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
13051 FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
13053 #if 0/* This might add unreliability; I don't trust it -- rms. */
13054 if (! f
->async_visible
&& ! f
->async_iconified
)
13060 /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
13061 that the current position of the window is user-specified, rather than
13062 program-specified, so that when the window is mapped again, it will be
13063 placed at the same location, without forcing the user to position it
13064 by hand again (they have already done that once for this window.) */
13065 x_wm_set_size_hint (f
, (long) 0, 1);
13069 if (! XWithdrawWindow (FRAME_X_DISPLAY (f
), window
,
13070 DefaultScreen (FRAME_X_DISPLAY (f
))))
13072 UNBLOCK_INPUT_RESIGNAL
;
13073 error ("Can't notify window manager of window withdrawal");
13075 #else /* ! defined (HAVE_X11R4) */
13077 /* Tell the window manager what we're going to do. */
13078 if (! EQ (Vx_no_window_manager
, Qt
))
13082 unmap
.xunmap
.type
= UnmapNotify
;
13083 unmap
.xunmap
.window
= window
;
13084 unmap
.xunmap
.event
= DefaultRootWindow (FRAME_X_DISPLAY (f
));
13085 unmap
.xunmap
.from_configure
= False
;
13086 if (! XSendEvent (FRAME_X_DISPLAY (f
),
13087 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
13089 SubstructureRedirectMaskSubstructureNotifyMask
,
13092 UNBLOCK_INPUT_RESIGNAL
;
13093 error ("Can't notify window manager of withdrawal");
13097 /* Unmap the window ourselves. Cheeky! */
13098 XUnmapWindow (FRAME_X_DISPLAY (f
), window
);
13099 #endif /* ! defined (HAVE_X11R4) */
13101 /* We can't distinguish this from iconification
13102 just by the event that we get from the server.
13103 So we can't win using the usual strategy of letting
13104 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
13105 and synchronize with the server to make sure we agree. */
13107 FRAME_ICONIFIED_P (f
) = 0;
13108 f
->async_visible
= 0;
13109 f
->async_iconified
= 0;
13116 /* Change window state from mapped to iconified. */
13119 x_iconify_frame (f
)
13125 /* Don't keep the highlight on an invisible frame. */
13126 if (FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
13127 FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
13129 if (f
->async_iconified
)
13134 FRAME_SAMPLE_VISIBILITY (f
);
13136 type
= x_icon_type (f
);
13138 x_bitmap_icon (f
, type
);
13140 #ifdef USE_X_TOOLKIT
13142 if (! FRAME_VISIBLE_P (f
))
13144 if (! EQ (Vx_no_window_manager
, Qt
))
13145 x_wm_set_window_state (f
, IconicState
);
13146 /* This was XtPopup, but that did nothing for an iconified frame. */
13147 XtMapWidget (f
->output_data
.x
->widget
);
13148 /* The server won't give us any event to indicate
13149 that an invisible frame was changed to an icon,
13150 so we have to record it here. */
13153 f
->async_iconified
= 1;
13154 f
->async_visible
= 0;
13159 result
= XIconifyWindow (FRAME_X_DISPLAY (f
),
13160 XtWindow (f
->output_data
.x
->widget
),
13161 DefaultScreen (FRAME_X_DISPLAY (f
)));
13165 error ("Can't notify window manager of iconification");
13167 f
->async_iconified
= 1;
13168 f
->async_visible
= 0;
13172 XFlush (FRAME_X_DISPLAY (f
));
13174 #else /* not USE_X_TOOLKIT */
13176 /* Make sure the X server knows where the window should be positioned,
13177 in case the user deiconifies with the window manager. */
13178 if (! FRAME_VISIBLE_P (f
) && !FRAME_ICONIFIED_P (f
))
13179 x_set_offset (f
, f
->output_data
.x
->left_pos
, f
->output_data
.x
->top_pos
, 0);
13181 /* Since we don't know which revision of X we're running, we'll use both
13182 the X11R3 and X11R4 techniques. I don't know if this is a good idea. */
13184 /* X11R4: send a ClientMessage to the window manager using the
13185 WM_CHANGE_STATE type. */
13189 message
.xclient
.window
= FRAME_X_WINDOW (f
);
13190 message
.xclient
.type
= ClientMessage
;
13191 message
.xclient
.message_type
= FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_change_state
;
13192 message
.xclient
.format
= 32;
13193 message
.xclient
.data
.l
[0] = IconicState
;
13195 if (! XSendEvent (FRAME_X_DISPLAY (f
),
13196 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
13198 SubstructureRedirectMask
| SubstructureNotifyMask
,
13201 UNBLOCK_INPUT_RESIGNAL
;
13202 error ("Can't notify window manager of iconification");
13206 /* X11R3: set the initial_state field of the window manager hints to
13208 x_wm_set_window_state (f
, IconicState
);
13210 if (!FRAME_VISIBLE_P (f
))
13212 /* If the frame was withdrawn, before, we must map it. */
13213 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
13216 f
->async_iconified
= 1;
13217 f
->async_visible
= 0;
13219 XFlush (FRAME_X_DISPLAY (f
));
13221 #endif /* not USE_X_TOOLKIT */
13225 /* Free X resources of frame F. */
13228 x_free_frame_resources (f
)
13231 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13233 struct scroll_bar
*b
;
13237 /* If a display connection is dead, don't try sending more
13238 commands to the X server. */
13239 if (dpyinfo
->display
)
13241 if (f
->output_data
.x
->icon_desc
)
13242 XDestroyWindow (FRAME_X_DISPLAY (f
), f
->output_data
.x
->icon_desc
);
13244 #ifdef USE_X_TOOLKIT
13245 /* Explicitly destroy the scroll bars of the frame. Without
13246 this, we get "BadDrawable" errors from the toolkit later on,
13247 presumably from expose events generated for the disappearing
13248 toolkit scroll bars. */
13249 for (bar
= FRAME_SCROLL_BARS (f
); !NILP (bar
); bar
= b
->next
)
13251 b
= XSCROLL_BAR (bar
);
13252 x_scroll_bar_remove (b
);
13258 free_frame_xic (f
);
13261 #ifdef USE_X_TOOLKIT
13262 if (f
->output_data
.x
->widget
)
13264 XtDestroyWidget (f
->output_data
.x
->widget
);
13265 f
->output_data
.x
->widget
= NULL
;
13267 /* Tooltips don't have widgets, only a simple X window, even if
13268 we are using a toolkit. */
13269 else if (FRAME_X_WINDOW (f
))
13270 XDestroyWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
13272 free_frame_menubar (f
);
13273 #else /* !USE_X_TOOLKIT */
13274 if (FRAME_X_WINDOW (f
))
13275 XDestroyWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
13276 #endif /* !USE_X_TOOLKIT */
13278 unload_color (f
, f
->output_data
.x
->foreground_pixel
);
13279 unload_color (f
, f
->output_data
.x
->background_pixel
);
13280 unload_color (f
, f
->output_data
.x
->cursor_pixel
);
13281 unload_color (f
, f
->output_data
.x
->cursor_foreground_pixel
);
13282 unload_color (f
, f
->output_data
.x
->border_pixel
);
13283 unload_color (f
, f
->output_data
.x
->mouse_pixel
);
13285 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
13286 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
13287 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
13288 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
13289 #ifdef USE_TOOLKIT_SCROLL_BARS
13290 /* Scrollbar shadow colors. */
13291 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
!= -1)
13292 unload_color (f
, f
->output_data
.x
->scroll_bar_top_shadow_pixel
);
13293 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
!= -1)
13294 unload_color (f
, f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
);
13295 #endif /* USE_TOOLKIT_SCROLL_BARS */
13296 if (f
->output_data
.x
->white_relief
.allocated_p
)
13297 unload_color (f
, f
->output_data
.x
->white_relief
.pixel
);
13298 if (f
->output_data
.x
->black_relief
.allocated_p
)
13299 unload_color (f
, f
->output_data
.x
->black_relief
.pixel
);
13301 if (FRAME_FACE_CACHE (f
))
13302 free_frame_faces (f
);
13305 XFlush (FRAME_X_DISPLAY (f
));
13308 if (f
->output_data
.x
->saved_menu_event
)
13309 xfree (f
->output_data
.x
->saved_menu_event
);
13311 xfree (f
->output_data
.x
);
13312 f
->output_data
.x
= NULL
;
13314 if (f
== dpyinfo
->x_focus_frame
)
13315 dpyinfo
->x_focus_frame
= 0;
13316 if (f
== dpyinfo
->x_focus_event_frame
)
13317 dpyinfo
->x_focus_event_frame
= 0;
13318 if (f
== dpyinfo
->x_highlight_frame
)
13319 dpyinfo
->x_highlight_frame
= 0;
13321 if (f
== dpyinfo
->mouse_face_mouse_frame
)
13323 dpyinfo
->mouse_face_beg_row
13324 = dpyinfo
->mouse_face_beg_col
= -1;
13325 dpyinfo
->mouse_face_end_row
13326 = dpyinfo
->mouse_face_end_col
= -1;
13327 dpyinfo
->mouse_face_window
= Qnil
;
13328 dpyinfo
->mouse_face_deferred_gc
= 0;
13329 dpyinfo
->mouse_face_mouse_frame
= 0;
13336 /* Destroy the X window of frame F. */
13339 x_destroy_window (f
)
13342 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13344 /* If a display connection is dead, don't try sending more
13345 commands to the X server. */
13346 if (dpyinfo
->display
!= 0)
13347 x_free_frame_resources (f
);
13349 dpyinfo
->reference_count
--;
13353 /* Setting window manager hints. */
13355 /* Set the normal size hints for the window manager, for frame F.
13356 FLAGS is the flags word to use--or 0 meaning preserve the flags
13357 that the window now has.
13358 If USER_POSITION is nonzero, we set the USPosition
13359 flag (this is useful when FLAGS is 0). */
13362 x_wm_set_size_hint (f
, flags
, user_position
)
13367 XSizeHints size_hints
;
13369 #ifdef USE_X_TOOLKIT
13372 Dimension widget_width
, widget_height
;
13373 Window window
= XtWindow (f
->output_data
.x
->widget
);
13374 #else /* not USE_X_TOOLKIT */
13375 Window window
= FRAME_X_WINDOW (f
);
13376 #endif /* not USE_X_TOOLKIT */
13378 /* Setting PMaxSize caused various problems. */
13379 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
13381 size_hints
.x
= f
->output_data
.x
->left_pos
;
13382 size_hints
.y
= f
->output_data
.x
->top_pos
;
13384 #ifdef USE_X_TOOLKIT
13385 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
13386 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
13387 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
13388 size_hints
.height
= widget_height
;
13389 size_hints
.width
= widget_width
;
13390 #else /* not USE_X_TOOLKIT */
13391 size_hints
.height
= PIXEL_HEIGHT (f
);
13392 size_hints
.width
= PIXEL_WIDTH (f
);
13393 #endif /* not USE_X_TOOLKIT */
13395 size_hints
.width_inc
= FONT_WIDTH (f
->output_data
.x
->font
);
13396 size_hints
.height_inc
= f
->output_data
.x
->line_height
;
13397 size_hints
.max_width
13398 = FRAME_X_DISPLAY_INFO (f
)->width
- CHAR_TO_PIXEL_WIDTH (f
, 0);
13399 size_hints
.max_height
13400 = FRAME_X_DISPLAY_INFO (f
)->height
- CHAR_TO_PIXEL_HEIGHT (f
, 0);
13402 /* Calculate the base and minimum sizes.
13404 (When we use the X toolkit, we don't do it here.
13405 Instead we copy the values that the widgets are using, below.) */
13406 #ifndef USE_X_TOOLKIT
13408 int base_width
, base_height
;
13409 int min_rows
= 0, min_cols
= 0;
13411 base_width
= CHAR_TO_PIXEL_WIDTH (f
, 0);
13412 base_height
= CHAR_TO_PIXEL_HEIGHT (f
, 0);
13414 check_frame_size (f
, &min_rows
, &min_cols
);
13416 /* The window manager uses the base width hints to calculate the
13417 current number of rows and columns in the frame while
13418 resizing; min_width and min_height aren't useful for this
13419 purpose, since they might not give the dimensions for a
13420 zero-row, zero-column frame.
13422 We use the base_width and base_height members if we have
13423 them; otherwise, we set the min_width and min_height members
13424 to the size for a zero x zero frame. */
13427 size_hints
.flags
|= PBaseSize
;
13428 size_hints
.base_width
= base_width
;
13429 size_hints
.base_height
= base_height
;
13430 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
13431 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
13433 size_hints
.min_width
= base_width
;
13434 size_hints
.min_height
= base_height
;
13438 /* If we don't need the old flags, we don't need the old hint at all. */
13441 size_hints
.flags
|= flags
;
13444 #endif /* not USE_X_TOOLKIT */
13447 XSizeHints hints
; /* Sometimes I hate X Windows... */
13448 long supplied_return
;
13452 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
13455 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
13458 #ifdef USE_X_TOOLKIT
13459 size_hints
.base_height
= hints
.base_height
;
13460 size_hints
.base_width
= hints
.base_width
;
13461 size_hints
.min_height
= hints
.min_height
;
13462 size_hints
.min_width
= hints
.min_width
;
13466 size_hints
.flags
|= flags
;
13471 if (hints
.flags
& PSize
)
13472 size_hints
.flags
|= PSize
;
13473 if (hints
.flags
& PPosition
)
13474 size_hints
.flags
|= PPosition
;
13475 if (hints
.flags
& USPosition
)
13476 size_hints
.flags
|= USPosition
;
13477 if (hints
.flags
& USSize
)
13478 size_hints
.flags
|= USSize
;
13482 #ifndef USE_X_TOOLKIT
13487 size_hints
.win_gravity
= f
->output_data
.x
->win_gravity
;
13488 size_hints
.flags
|= PWinGravity
;
13492 size_hints
.flags
&= ~ PPosition
;
13493 size_hints
.flags
|= USPosition
;
13495 #endif /* PWinGravity */
13498 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
13500 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
13504 /* Used for IconicState or NormalState */
13507 x_wm_set_window_state (f
, state
)
13511 #ifdef USE_X_TOOLKIT
13514 XtSetArg (al
[0], XtNinitialState
, state
);
13515 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
13516 #else /* not USE_X_TOOLKIT */
13517 Window window
= FRAME_X_WINDOW (f
);
13519 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
13520 f
->output_data
.x
->wm_hints
.initial_state
= state
;
13522 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
13523 #endif /* not USE_X_TOOLKIT */
13527 x_wm_set_icon_pixmap (f
, pixmap_id
)
13531 Pixmap icon_pixmap
;
13533 #ifndef USE_X_TOOLKIT
13534 Window window
= FRAME_X_WINDOW (f
);
13539 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
13540 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
13544 /* It seems there is no way to turn off use of an icon pixmap.
13545 The following line does it, only if no icon has yet been created,
13546 for some window managers. But with mwm it crashes.
13547 Some people say it should clear the IconPixmapHint bit in this case,
13548 but that doesn't work, and the X consortium said it isn't the
13549 right thing at all. Since there is no way to win,
13550 best to explicitly give up. */
13552 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
13558 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
13562 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
13563 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
13566 #else /* not USE_X_TOOLKIT */
13568 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
13569 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
13571 #endif /* not USE_X_TOOLKIT */
13575 x_wm_set_icon_position (f
, icon_x
, icon_y
)
13577 int icon_x
, icon_y
;
13579 #ifdef USE_X_TOOLKIT
13580 Window window
= XtWindow (f
->output_data
.x
->widget
);
13582 Window window
= FRAME_X_WINDOW (f
);
13585 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
13586 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
13587 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
13589 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
13593 /***********************************************************************
13595 ***********************************************************************/
13597 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
13600 x_get_font_info (f
, font_idx
)
13604 return (FRAME_X_FONT_TABLE (f
) + font_idx
);
13608 /* Return a list of names of available fonts matching PATTERN on frame F.
13610 If SIZE is > 0, it is the size (maximum bounds width) of fonts
13613 SIZE < 0 means include scalable fonts.
13615 Frame F null means we have not yet created any frame on X, and
13616 consult the first display in x_display_list. MAXNAMES sets a limit
13617 on how many fonts to match. */
13620 x_list_fonts (f
, pattern
, size
, maxnames
)
13622 Lisp_Object pattern
;
13626 Lisp_Object list
= Qnil
, patterns
, newlist
= Qnil
, key
= Qnil
;
13627 Lisp_Object tem
, second_best
;
13628 struct x_display_info
*dpyinfo
13629 = f
? FRAME_X_DISPLAY_INFO (f
) : x_display_list
;
13630 Display
*dpy
= dpyinfo
->display
;
13631 int try_XLoadQueryFont
= 0;
13633 int allow_scalable_fonts_p
= 0;
13637 allow_scalable_fonts_p
= 1;
13641 patterns
= Fassoc (pattern
, Valternate_fontname_alist
);
13642 if (NILP (patterns
))
13643 patterns
= Fcons (pattern
, Qnil
);
13645 if (maxnames
== 1 && !size
)
13646 /* We can return any single font matching PATTERN. */
13647 try_XLoadQueryFont
= 1;
13649 for (; CONSP (patterns
); patterns
= XCDR (patterns
))
13652 char **names
= NULL
;
13654 pattern
= XCAR (patterns
);
13655 /* See if we cached the result for this particular query.
13656 The cache is an alist of the form:
13657 ((((PATTERN . MAXNAMES) . SCALABLE) (FONTNAME . WIDTH) ...) ...) */
13658 tem
= XCDR (dpyinfo
->name_list_element
);
13659 key
= Fcons (Fcons (pattern
, make_number (maxnames
)),
13660 allow_scalable_fonts_p
? Qt
: Qnil
);
13661 list
= Fassoc (key
, tem
);
13664 list
= Fcdr_safe (list
);
13665 /* We have a cashed list. Don't have to get the list again. */
13669 /* At first, put PATTERN in the cache. */
13672 count
= x_catch_errors (dpy
);
13674 if (try_XLoadQueryFont
)
13677 unsigned long value
;
13679 font
= XLoadQueryFont (dpy
, XSTRING (pattern
)->data
);
13680 if (x_had_errors_p (dpy
))
13682 /* This error is perhaps due to insufficient memory on X
13683 server. Let's just ignore it. */
13685 x_clear_errors (dpy
);
13689 && XGetFontProperty (font
, XA_FONT
, &value
))
13691 char *name
= (char *) XGetAtomName (dpy
, (Atom
) value
);
13692 int len
= strlen (name
);
13695 /* If DXPC (a Differential X Protocol Compressor)
13696 Ver.3.7 is running, XGetAtomName will return null
13697 string. We must avoid such a name. */
13699 try_XLoadQueryFont
= 0;
13703 names
= (char **) alloca (sizeof (char *));
13704 /* Some systems only allow alloca assigned to a
13706 tmp
= (char *) alloca (len
+ 1); names
[0] = tmp
;
13707 bcopy (name
, names
[0], len
+ 1);
13712 try_XLoadQueryFont
= 0;
13715 XFreeFont (dpy
, font
);
13718 if (!try_XLoadQueryFont
)
13720 /* We try at least 10 fonts because XListFonts will return
13721 auto-scaled fonts at the head. */
13722 names
= XListFonts (dpy
, XSTRING (pattern
)->data
, max (maxnames
, 10),
13724 if (x_had_errors_p (dpy
))
13726 /* This error is perhaps due to insufficient memory on X
13727 server. Let's just ignore it. */
13729 x_clear_errors (dpy
);
13733 x_uncatch_errors (dpy
, count
);
13740 /* Make a list of all the fonts we got back.
13741 Store that in the font cache for the display. */
13742 for (i
= 0; i
< num_fonts
; i
++)
13745 char *p
= names
[i
];
13746 int average_width
= -1, dashes
= 0;
13748 /* Count the number of dashes in NAMES[I]. If there are
13749 14 dashes, and the field value following 12th dash
13750 (AVERAGE_WIDTH) is 0, this is a auto-scaled font which
13751 is usually too ugly to be used for editing. Let's
13757 if (dashes
== 7) /* PIXEL_SIZE field */
13759 else if (dashes
== 12) /* AVERAGE_WIDTH field */
13760 average_width
= atoi (p
);
13763 if (allow_scalable_fonts_p
13764 || dashes
< 14 || average_width
!= 0)
13766 tem
= build_string (names
[i
]);
13767 if (NILP (Fassoc (tem
, list
)))
13769 if (STRINGP (Vx_pixel_size_width_font_regexp
)
13770 && ((fast_c_string_match_ignore_case
13771 (Vx_pixel_size_width_font_regexp
, names
[i
]))
13773 /* We can set the value of PIXEL_SIZE to the
13774 width of this font. */
13775 list
= Fcons (Fcons (tem
, make_number (width
)), list
);
13777 /* For the moment, width is not known. */
13778 list
= Fcons (Fcons (tem
, Qnil
), list
);
13783 if (!try_XLoadQueryFont
)
13786 XFreeFontNames (names
);
13791 /* Now store the result in the cache. */
13792 XSETCDR (dpyinfo
->name_list_element
,
13793 Fcons (Fcons (key
, list
), XCDR (dpyinfo
->name_list_element
)));
13796 if (NILP (list
)) continue; /* Try the remaining alternatives. */
13798 newlist
= second_best
= Qnil
;
13799 /* Make a list of the fonts that have the right width. */
13800 for (; CONSP (list
); list
= XCDR (list
))
13806 if (!CONSP (tem
) || NILP (XCAR (tem
)))
13810 newlist
= Fcons (XCAR (tem
), newlist
);
13814 if (!INTEGERP (XCDR (tem
)))
13816 /* Since we have not yet known the size of this font, we
13817 must try slow function call XLoadQueryFont. */
13818 XFontStruct
*thisinfo
;
13821 count
= x_catch_errors (dpy
);
13822 thisinfo
= XLoadQueryFont (dpy
,
13823 XSTRING (XCAR (tem
))->data
);
13824 if (x_had_errors_p (dpy
))
13826 /* This error is perhaps due to insufficient memory on X
13827 server. Let's just ignore it. */
13829 x_clear_errors (dpy
);
13831 x_uncatch_errors (dpy
, count
);
13837 (thisinfo
->min_bounds
.width
== 0
13839 : make_number (thisinfo
->max_bounds
.width
)));
13841 XFreeFont (dpy
, thisinfo
);
13845 /* For unknown reason, the previous call of XListFont had
13846 returned a font which can't be opened. Record the size
13847 as 0 not to try to open it again. */
13848 XSETCDR (tem
, make_number (0));
13851 found_size
= XINT (XCDR (tem
));
13852 if (found_size
== size
)
13853 newlist
= Fcons (XCAR (tem
), newlist
);
13854 else if (found_size
> 0)
13856 if (NILP (second_best
))
13858 else if (found_size
< size
)
13860 if (XINT (XCDR (second_best
)) > size
13861 || XINT (XCDR (second_best
)) < found_size
)
13866 if (XINT (XCDR (second_best
)) > size
13867 && XINT (XCDR (second_best
)) > found_size
)
13872 if (!NILP (newlist
))
13874 else if (!NILP (second_best
))
13876 newlist
= Fcons (XCAR (second_best
), Qnil
);
13887 /* Check that FONT is valid on frame F. It is if it can be found in F's
13891 x_check_font (f
, font
)
13896 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13898 xassert (font
!= NULL
);
13900 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
13901 if (dpyinfo
->font_table
[i
].name
13902 && font
== dpyinfo
->font_table
[i
].font
)
13905 xassert (i
< dpyinfo
->n_fonts
);
13908 #endif /* GLYPH_DEBUG != 0 */
13910 /* Set *W to the minimum width, *H to the minimum font height of FONT.
13911 Note: There are (broken) X fonts out there with invalid XFontStruct
13912 min_bounds contents. For example, handa@etl.go.jp reports that
13913 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
13914 have font->min_bounds.width == 0. */
13917 x_font_min_bounds (font
, w
, h
)
13921 *h
= FONT_HEIGHT (font
);
13922 *w
= font
->min_bounds
.width
;
13924 /* Try to handle the case where FONT->min_bounds has invalid
13925 contents. Since the only font known to have invalid min_bounds
13926 is fixed-width, use max_bounds if min_bounds seems to be invalid. */
13928 *w
= font
->max_bounds
.width
;
13932 /* Compute the smallest character width and smallest font height over
13933 all fonts available on frame F. Set the members smallest_char_width
13934 and smallest_font_height in F's x_display_info structure to
13935 the values computed. Value is non-zero if smallest_font_height or
13936 smallest_char_width become smaller than they were before. */
13939 x_compute_min_glyph_bounds (f
)
13943 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13945 int old_width
= dpyinfo
->smallest_char_width
;
13946 int old_height
= dpyinfo
->smallest_font_height
;
13948 dpyinfo
->smallest_font_height
= 100000;
13949 dpyinfo
->smallest_char_width
= 100000;
13951 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
13952 if (dpyinfo
->font_table
[i
].name
)
13954 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
13957 font
= (XFontStruct
*) fontp
->font
;
13958 xassert (font
!= (XFontStruct
*) ~0);
13959 x_font_min_bounds (font
, &w
, &h
);
13961 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
13962 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
13965 xassert (dpyinfo
->smallest_char_width
> 0
13966 && dpyinfo
->smallest_font_height
> 0);
13968 return (dpyinfo
->n_fonts
== 1
13969 || dpyinfo
->smallest_char_width
< old_width
13970 || dpyinfo
->smallest_font_height
< old_height
);
13974 /* Load font named FONTNAME of the size SIZE for frame F, and return a
13975 pointer to the structure font_info while allocating it dynamically.
13976 If SIZE is 0, load any size of font.
13977 If loading is failed, return NULL. */
13980 x_load_font (f
, fontname
, size
)
13982 register char *fontname
;
13985 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13986 Lisp_Object font_names
;
13989 /* Get a list of all the fonts that match this name. Once we
13990 have a list of matching fonts, we compare them against the fonts
13991 we already have by comparing names. */
13992 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
13994 if (!NILP (font_names
))
13999 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
14000 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
14001 if (dpyinfo
->font_table
[i
].name
14002 && (!strcmp (dpyinfo
->font_table
[i
].name
,
14003 XSTRING (XCAR (tail
))->data
)
14004 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
14005 XSTRING (XCAR (tail
))->data
)))
14006 return (dpyinfo
->font_table
+ i
);
14009 /* Load the font and add it to the table. */
14013 struct font_info
*fontp
;
14014 unsigned long value
;
14017 /* If we have found fonts by x_list_font, load one of them. If
14018 not, we still try to load a font by the name given as FONTNAME
14019 because XListFonts (called in x_list_font) of some X server has
14020 a bug of not finding a font even if the font surely exists and
14021 is loadable by XLoadQueryFont. */
14022 if (size
> 0 && !NILP (font_names
))
14023 fontname
= (char *) XSTRING (XCAR (font_names
))->data
;
14026 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
14027 font
= (XFontStruct
*) XLoadQueryFont (FRAME_X_DISPLAY (f
), fontname
);
14028 if (x_had_errors_p (FRAME_X_DISPLAY (f
)))
14030 /* This error is perhaps due to insufficient memory on X
14031 server. Let's just ignore it. */
14033 x_clear_errors (FRAME_X_DISPLAY (f
));
14035 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
14040 /* Find a free slot in the font table. */
14041 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
14042 if (dpyinfo
->font_table
[i
].name
== NULL
)
14045 /* If no free slot found, maybe enlarge the font table. */
14046 if (i
== dpyinfo
->n_fonts
14047 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
14050 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
14051 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
14052 dpyinfo
->font_table
14053 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
14056 fontp
= dpyinfo
->font_table
+ i
;
14057 if (i
== dpyinfo
->n_fonts
)
14058 ++dpyinfo
->n_fonts
;
14060 /* Now fill in the slots of *FONTP. */
14062 fontp
->font
= font
;
14063 fontp
->font_idx
= i
;
14064 fontp
->name
= (char *) xmalloc (strlen (fontname
) + 1);
14065 bcopy (fontname
, fontp
->name
, strlen (fontname
) + 1);
14067 /* Try to get the full name of FONT. Put it in FULL_NAME. */
14069 if (XGetFontProperty (font
, XA_FONT
, &value
))
14071 char *name
= (char *) XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);
14075 /* Count the number of dashes in the "full name".
14076 If it is too few, this isn't really the font's full name,
14078 In X11R4, the fonts did not come with their canonical names
14089 full_name
= (char *) xmalloc (p
- name
+ 1);
14090 bcopy (name
, full_name
, p
- name
+ 1);
14096 if (full_name
!= 0)
14097 fontp
->full_name
= full_name
;
14099 fontp
->full_name
= fontp
->name
;
14101 fontp
->size
= font
->max_bounds
.width
;
14102 fontp
->height
= FONT_HEIGHT (font
);
14104 if (NILP (font_names
))
14106 /* We come here because of a bug of XListFonts mentioned at
14107 the head of this block. Let's store this information in
14108 the cache for x_list_fonts. */
14109 Lisp_Object lispy_name
= build_string (fontname
);
14110 Lisp_Object lispy_full_name
= build_string (fontp
->full_name
);
14111 Lisp_Object key
= Fcons (Fcons (lispy_name
, make_number (256)),
14114 XSETCDR (dpyinfo
->name_list_element
,
14116 Fcons (Fcons (lispy_full_name
,
14117 make_number (fontp
->size
)),
14119 XCDR (dpyinfo
->name_list_element
)));
14122 key
= Fcons (Fcons (lispy_full_name
, make_number (256)),
14124 XSETCDR (dpyinfo
->name_list_element
,
14126 Fcons (Fcons (lispy_full_name
,
14127 make_number (fontp
->size
)),
14129 XCDR (dpyinfo
->name_list_element
)));
14133 /* The slot `encoding' specifies how to map a character
14134 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
14135 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
14136 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
14137 2:0xA020..0xFF7F). For the moment, we don't know which charset
14138 uses this font. So, we set information in fontp->encoding[1]
14139 which is never used by any charset. If mapping can't be
14140 decided, set FONT_ENCODING_NOT_DECIDED. */
14142 = (font
->max_byte1
== 0
14144 ? (font
->min_char_or_byte2
< 0x80
14145 ? (font
->max_char_or_byte2
< 0x80
14146 ? 0 /* 0x20..0x7F */
14147 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
14148 : 1) /* 0xA0..0xFF */
14150 : (font
->min_byte1
< 0x80
14151 ? (font
->max_byte1
< 0x80
14152 ? (font
->min_char_or_byte2
< 0x80
14153 ? (font
->max_char_or_byte2
< 0x80
14154 ? 0 /* 0x2020..0x7F7F */
14155 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
14156 : 3) /* 0x20A0..0x7FFF */
14157 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
14158 : (font
->min_char_or_byte2
< 0x80
14159 ? (font
->max_char_or_byte2
< 0x80
14160 ? 2 /* 0xA020..0xFF7F */
14161 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
14162 : 1))); /* 0xA0A0..0xFFFF */
14164 fontp
->baseline_offset
14165 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
14166 ? (long) value
: 0);
14167 fontp
->relative_compose
14168 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
14169 ? (long) value
: 0);
14170 fontp
->default_ascent
14171 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
14172 ? (long) value
: 0);
14174 /* Set global flag fonts_changed_p to non-zero if the font loaded
14175 has a character with a smaller width than any other character
14176 before, or if the font loaded has a smaller height than any
14177 other font loaded before. If this happens, it will make a
14178 glyph matrix reallocation necessary. */
14179 fonts_changed_p
|= x_compute_min_glyph_bounds (f
);
14186 /* Return a pointer to struct font_info of a font named FONTNAME for
14187 frame F. If no such font is loaded, return NULL. */
14190 x_query_font (f
, fontname
)
14192 register char *fontname
;
14194 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
14197 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
14198 if (dpyinfo
->font_table
[i
].name
14199 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
14200 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
14201 return (dpyinfo
->font_table
+ i
);
14206 /* Find a CCL program for a font specified by FONTP, and set the member
14207 `encoder' of the structure. */
14210 x_find_ccl_program (fontp
)
14211 struct font_info
*fontp
;
14213 Lisp_Object list
, elt
;
14216 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
14220 && STRINGP (XCAR (elt
))
14221 && ((fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
14223 || (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->full_name
)
14230 struct ccl_program
*ccl
14231 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
14233 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
14236 fontp
->font_encoder
= ccl
;
14242 /***********************************************************************
14244 ***********************************************************************/
14246 #ifdef USE_X_TOOLKIT
14247 static XrmOptionDescRec emacs_options
[] = {
14248 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
14249 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
14251 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
14252 XrmoptionSepArg
, NULL
},
14253 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
14255 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
14256 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
14257 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
14258 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
14259 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
14260 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
14261 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
14263 #endif /* USE_X_TOOLKIT */
14265 static int x_initialized
;
14267 #ifdef MULTI_KBOARD
14268 /* Test whether two display-name strings agree up to the dot that separates
14269 the screen number from the server number. */
14271 same_x_server (name1
, name2
)
14272 char *name1
, *name2
;
14274 int seen_colon
= 0;
14275 unsigned char *system_name
= XSTRING (Vsystem_name
)->data
;
14276 int system_name_length
= strlen (system_name
);
14277 int length_until_period
= 0;
14279 while (system_name
[length_until_period
] != 0
14280 && system_name
[length_until_period
] != '.')
14281 length_until_period
++;
14283 /* Treat `unix' like an empty host name. */
14284 if (! strncmp (name1
, "unix:", 5))
14286 if (! strncmp (name2
, "unix:", 5))
14288 /* Treat this host's name like an empty host name. */
14289 if (! strncmp (name1
, system_name
, system_name_length
)
14290 && name1
[system_name_length
] == ':')
14291 name1
+= system_name_length
;
14292 if (! strncmp (name2
, system_name
, system_name_length
)
14293 && name2
[system_name_length
] == ':')
14294 name2
+= system_name_length
;
14295 /* Treat this host's domainless name like an empty host name. */
14296 if (! strncmp (name1
, system_name
, length_until_period
)
14297 && name1
[length_until_period
] == ':')
14298 name1
+= length_until_period
;
14299 if (! strncmp (name2
, system_name
, length_until_period
)
14300 && name2
[length_until_period
] == ':')
14301 name2
+= length_until_period
;
14303 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
14307 if (seen_colon
&& *name1
== '.')
14311 && (*name1
== '.' || *name1
== '\0')
14312 && (*name2
== '.' || *name2
== '\0'));
14316 struct x_display_info
*
14317 x_term_init (display_name
, xrm_option
, resource_name
)
14318 Lisp_Object display_name
;
14320 char *resource_name
;
14324 struct x_display_info
*dpyinfo
;
14329 if (!x_initialized
)
14335 #ifdef USE_X_TOOLKIT
14336 /* weiner@footloose.sps.mot.com reports that this causes
14338 X protocol error: BadAtom (invalid Atom parameter)
14339 on protocol request 18skiloaf.
14340 So let's not use it until R6. */
14341 #ifdef HAVE_X11XTR6
14342 XtSetLanguageProc (NULL
, NULL
, NULL
);
14353 argv
[argc
++] = "-xrm";
14354 argv
[argc
++] = xrm_option
;
14356 dpy
= XtOpenDisplay (Xt_app_con
, XSTRING (display_name
)->data
,
14357 resource_name
, EMACS_CLASS
,
14358 emacs_options
, XtNumber (emacs_options
),
14361 #ifdef HAVE_X11XTR6
14362 /* I think this is to compensate for XtSetLanguageProc. */
14367 #else /* not USE_X_TOOLKIT */
14369 XSetLocaleModifiers ("");
14371 dpy
= XOpenDisplay (XSTRING (display_name
)->data
);
14372 #endif /* not USE_X_TOOLKIT */
14374 /* Detect failure. */
14381 /* We have definitely succeeded. Record the new connection. */
14383 dpyinfo
= (struct x_display_info
*) xmalloc (sizeof (struct x_display_info
));
14384 bzero (dpyinfo
, sizeof *dpyinfo
);
14386 #ifdef MULTI_KBOARD
14388 struct x_display_info
*share
;
14391 for (share
= x_display_list
, tail
= x_display_name_list
; share
;
14392 share
= share
->next
, tail
= XCDR (tail
))
14393 if (same_x_server (XSTRING (XCAR (XCAR (tail
)))->data
,
14394 XSTRING (display_name
)->data
))
14397 dpyinfo
->kboard
= share
->kboard
;
14400 dpyinfo
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
14401 init_kboard (dpyinfo
->kboard
);
14402 if (!EQ (XSYMBOL (Qvendor_specific_keysyms
)->function
, Qunbound
))
14404 char *vendor
= ServerVendor (dpy
);
14406 dpyinfo
->kboard
->Vsystem_key_alist
14407 = call1 (Qvendor_specific_keysyms
,
14408 build_string (vendor
? vendor
: ""));
14412 dpyinfo
->kboard
->next_kboard
= all_kboards
;
14413 all_kboards
= dpyinfo
->kboard
;
14414 /* Don't let the initial kboard remain current longer than necessary.
14415 That would cause problems if a file loaded on startup tries to
14416 prompt in the mini-buffer. */
14417 if (current_kboard
== initial_kboard
)
14418 current_kboard
= dpyinfo
->kboard
;
14420 dpyinfo
->kboard
->reference_count
++;
14424 /* Put this display on the chain. */
14425 dpyinfo
->next
= x_display_list
;
14426 x_display_list
= dpyinfo
;
14428 /* Put it on x_display_name_list as well, to keep them parallel. */
14429 x_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
14430 x_display_name_list
);
14431 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
14433 dpyinfo
->display
= dpy
;
14436 XSetAfterFunction (x_current_display
, x_trace_wire
);
14440 = (char *) xmalloc (STRING_BYTES (XSTRING (Vinvocation_name
))
14441 + STRING_BYTES (XSTRING (Vsystem_name
))
14443 sprintf (dpyinfo
->x_id_name
, "%s@%s",
14444 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
14446 /* Figure out which modifier bits mean what. */
14447 x_find_modifier_meanings (dpyinfo
);
14449 /* Get the scroll bar cursor. */
14450 dpyinfo
->vertical_scroll_bar_cursor
14451 = XCreateFontCursor (dpyinfo
->display
, XC_sb_v_double_arrow
);
14453 xrdb
= x_load_resources (dpyinfo
->display
, xrm_option
,
14454 resource_name
, EMACS_CLASS
);
14455 #ifdef HAVE_XRMSETDATABASE
14456 XrmSetDatabase (dpyinfo
->display
, xrdb
);
14458 dpyinfo
->display
->db
= xrdb
;
14460 /* Put the rdb where we can find it in a way that works on
14462 dpyinfo
->xrdb
= xrdb
;
14464 dpyinfo
->screen
= ScreenOfDisplay (dpyinfo
->display
,
14465 DefaultScreen (dpyinfo
->display
));
14466 select_visual (dpyinfo
);
14467 dpyinfo
->cmap
= DefaultColormapOfScreen (dpyinfo
->screen
);
14468 dpyinfo
->height
= HeightOfScreen (dpyinfo
->screen
);
14469 dpyinfo
->width
= WidthOfScreen (dpyinfo
->screen
);
14470 dpyinfo
->root_window
= RootWindowOfScreen (dpyinfo
->screen
);
14471 dpyinfo
->grabbed
= 0;
14472 dpyinfo
->reference_count
= 0;
14473 dpyinfo
->icon_bitmap_id
= -1;
14474 dpyinfo
->font_table
= NULL
;
14475 dpyinfo
->n_fonts
= 0;
14476 dpyinfo
->font_table_size
= 0;
14477 dpyinfo
->bitmaps
= 0;
14478 dpyinfo
->bitmaps_size
= 0;
14479 dpyinfo
->bitmaps_last
= 0;
14480 dpyinfo
->scratch_cursor_gc
= 0;
14481 dpyinfo
->mouse_face_mouse_frame
= 0;
14482 dpyinfo
->mouse_face_deferred_gc
= 0;
14483 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
14484 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
14485 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
14486 dpyinfo
->mouse_face_window
= Qnil
;
14487 dpyinfo
->mouse_face_overlay
= Qnil
;
14488 dpyinfo
->mouse_face_mouse_x
= dpyinfo
->mouse_face_mouse_y
= 0;
14489 dpyinfo
->mouse_face_defer
= 0;
14490 dpyinfo
->x_focus_frame
= 0;
14491 dpyinfo
->x_focus_event_frame
= 0;
14492 dpyinfo
->x_highlight_frame
= 0;
14493 dpyinfo
->image_cache
= make_image_cache ();
14495 /* See if a private colormap is requested. */
14496 if (dpyinfo
->visual
== DefaultVisualOfScreen (dpyinfo
->screen
))
14498 if (dpyinfo
->visual
->class == PseudoColor
)
14501 value
= display_x_get_resource (dpyinfo
,
14502 build_string ("privateColormap"),
14503 build_string ("PrivateColormap"),
14505 if (STRINGP (value
)
14506 && (!strcmp (XSTRING (value
)->data
, "true")
14507 || !strcmp (XSTRING (value
)->data
, "on")))
14508 dpyinfo
->cmap
= XCopyColormapAndFree (dpyinfo
->display
, dpyinfo
->cmap
);
14512 dpyinfo
->cmap
= XCreateColormap (dpyinfo
->display
, dpyinfo
->root_window
,
14513 dpyinfo
->visual
, AllocNone
);
14516 int screen_number
= XScreenNumberOfScreen (dpyinfo
->screen
);
14517 double pixels
= DisplayHeight (dpyinfo
->display
, screen_number
);
14518 double mm
= DisplayHeightMM (dpyinfo
->display
, screen_number
);
14519 dpyinfo
->resy
= pixels
* 25.4 / mm
;
14520 pixels
= DisplayWidth (dpyinfo
->display
, screen_number
);
14521 mm
= DisplayWidthMM (dpyinfo
->display
, screen_number
);
14522 dpyinfo
->resx
= pixels
* 25.4 / mm
;
14525 dpyinfo
->Xatom_wm_protocols
14526 = XInternAtom (dpyinfo
->display
, "WM_PROTOCOLS", False
);
14527 dpyinfo
->Xatom_wm_take_focus
14528 = XInternAtom (dpyinfo
->display
, "WM_TAKE_FOCUS", False
);
14529 dpyinfo
->Xatom_wm_save_yourself
14530 = XInternAtom (dpyinfo
->display
, "WM_SAVE_YOURSELF", False
);
14531 dpyinfo
->Xatom_wm_delete_window
14532 = XInternAtom (dpyinfo
->display
, "WM_DELETE_WINDOW", False
);
14533 dpyinfo
->Xatom_wm_change_state
14534 = XInternAtom (dpyinfo
->display
, "WM_CHANGE_STATE", False
);
14535 dpyinfo
->Xatom_wm_configure_denied
14536 = XInternAtom (dpyinfo
->display
, "WM_CONFIGURE_DENIED", False
);
14537 dpyinfo
->Xatom_wm_window_moved
14538 = XInternAtom (dpyinfo
->display
, "WM_MOVED", False
);
14539 dpyinfo
->Xatom_editres
14540 = XInternAtom (dpyinfo
->display
, "Editres", False
);
14541 dpyinfo
->Xatom_CLIPBOARD
14542 = XInternAtom (dpyinfo
->display
, "CLIPBOARD", False
);
14543 dpyinfo
->Xatom_TIMESTAMP
14544 = XInternAtom (dpyinfo
->display
, "TIMESTAMP", False
);
14545 dpyinfo
->Xatom_TEXT
14546 = XInternAtom (dpyinfo
->display
, "TEXT", False
);
14547 dpyinfo
->Xatom_COMPOUND_TEXT
14548 = XInternAtom (dpyinfo
->display
, "COMPOUND_TEXT", False
);
14549 dpyinfo
->Xatom_DELETE
14550 = XInternAtom (dpyinfo
->display
, "DELETE", False
);
14551 dpyinfo
->Xatom_MULTIPLE
14552 = XInternAtom (dpyinfo
->display
, "MULTIPLE", False
);
14553 dpyinfo
->Xatom_INCR
14554 = XInternAtom (dpyinfo
->display
, "INCR", False
);
14555 dpyinfo
->Xatom_EMACS_TMP
14556 = XInternAtom (dpyinfo
->display
, "_EMACS_TMP_", False
);
14557 dpyinfo
->Xatom_TARGETS
14558 = XInternAtom (dpyinfo
->display
, "TARGETS", False
);
14559 dpyinfo
->Xatom_NULL
14560 = XInternAtom (dpyinfo
->display
, "NULL", False
);
14561 dpyinfo
->Xatom_ATOM_PAIR
14562 = XInternAtom (dpyinfo
->display
, "ATOM_PAIR", False
);
14563 /* For properties of font. */
14564 dpyinfo
->Xatom_PIXEL_SIZE
14565 = XInternAtom (dpyinfo
->display
, "PIXEL_SIZE", False
);
14566 dpyinfo
->Xatom_MULE_BASELINE_OFFSET
14567 = XInternAtom (dpyinfo
->display
, "_MULE_BASELINE_OFFSET", False
);
14568 dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
14569 = XInternAtom (dpyinfo
->display
, "_MULE_RELATIVE_COMPOSE", False
);
14570 dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
14571 = XInternAtom (dpyinfo
->display
, "_MULE_DEFAULT_ASCENT", False
);
14573 /* Ghostscript support. */
14574 dpyinfo
->Xatom_PAGE
= XInternAtom (dpyinfo
->display
, "PAGE", False
);
14575 dpyinfo
->Xatom_DONE
= XInternAtom (dpyinfo
->display
, "DONE", False
);
14577 dpyinfo
->Xatom_Scrollbar
= XInternAtom (dpyinfo
->display
, "SCROLLBAR",
14580 dpyinfo
->cut_buffers_initialized
= 0;
14582 connection
= ConnectionNumber (dpyinfo
->display
);
14583 dpyinfo
->connection
= connection
;
14588 null_bits
[0] = 0x00;
14590 dpyinfo
->null_pixel
14591 = XCreatePixmapFromBitmapData (dpyinfo
->display
, dpyinfo
->root_window
,
14592 null_bits
, 1, 1, (long) 0, (long) 0,
14597 extern int gray_bitmap_width
, gray_bitmap_height
;
14598 extern char *gray_bitmap_bits
;
14600 = XCreatePixmapFromBitmapData (dpyinfo
->display
, dpyinfo
->root_window
,
14602 gray_bitmap_width
, gray_bitmap_height
,
14603 (unsigned long) 1, (unsigned long) 0, 1);
14607 xim_initialize (dpyinfo
, resource_name
);
14610 #ifdef subprocesses
14611 /* This is only needed for distinguishing keyboard and process input. */
14612 if (connection
!= 0)
14613 add_keyboard_wait_descriptor (connection
);
14616 #ifndef F_SETOWN_BUG
14618 #ifdef F_SETOWN_SOCK_NEG
14619 /* stdin is a socket here */
14620 fcntl (connection
, F_SETOWN
, -getpid ());
14621 #else /* ! defined (F_SETOWN_SOCK_NEG) */
14622 fcntl (connection
, F_SETOWN
, getpid ());
14623 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
14624 #endif /* ! defined (F_SETOWN) */
14625 #endif /* F_SETOWN_BUG */
14628 if (interrupt_input
)
14629 init_sigio (connection
);
14630 #endif /* ! defined (SIGIO) */
14633 #ifdef HAVE_X11R5 /* It seems X11R4 lacks XtCvtStringToFont, and XPointer. */
14634 /* Make sure that we have a valid font for dialog boxes
14635 so that Xt does not crash. */
14637 Display
*dpy
= dpyinfo
->display
;
14638 XrmValue d
, fr
, to
;
14642 d
.addr
= (XPointer
)&dpy
;
14643 d
.size
= sizeof (Display
*);
14644 fr
.addr
= XtDefaultFont
;
14645 fr
.size
= sizeof (XtDefaultFont
);
14646 to
.size
= sizeof (Font
*);
14647 to
.addr
= (XPointer
)&font
;
14648 count
= x_catch_errors (dpy
);
14649 if (!XtCallConverter (dpy
, XtCvtStringToFont
, &d
, 1, &fr
, &to
, NULL
))
14651 if (x_had_errors_p (dpy
) || !XQueryFont (dpy
, font
))
14652 XrmPutLineResource (&xrdb
, "Emacs.dialog.*.font: 9x15");
14653 x_uncatch_errors (dpy
, count
);
14658 /* See if we should run in synchronous mode. This is useful
14659 for debugging X code. */
14662 value
= display_x_get_resource (dpyinfo
,
14663 build_string ("synchronous"),
14664 build_string ("Synchronous"),
14666 if (STRINGP (value
)
14667 && (!strcmp (XSTRING (value
)->data
, "true")
14668 || !strcmp (XSTRING (value
)->data
, "on")))
14669 XSynchronize (dpyinfo
->display
, True
);
14677 /* Get rid of display DPYINFO, assuming all frames are already gone,
14678 and without sending any more commands to the X server. */
14681 x_delete_display (dpyinfo
)
14682 struct x_display_info
*dpyinfo
;
14684 delete_keyboard_wait_descriptor (dpyinfo
->connection
);
14686 /* Discard this display from x_display_name_list and x_display_list.
14687 We can't use Fdelq because that can quit. */
14688 if (! NILP (x_display_name_list
)
14689 && EQ (XCAR (x_display_name_list
), dpyinfo
->name_list_element
))
14690 x_display_name_list
= XCDR (x_display_name_list
);
14695 tail
= x_display_name_list
;
14696 while (CONSP (tail
) && CONSP (XCDR (tail
)))
14698 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
14700 XSETCDR (tail
, XCDR (XCDR (tail
)));
14703 tail
= XCDR (tail
);
14707 if (next_noop_dpyinfo
== dpyinfo
)
14708 next_noop_dpyinfo
= dpyinfo
->next
;
14710 if (x_display_list
== dpyinfo
)
14711 x_display_list
= dpyinfo
->next
;
14714 struct x_display_info
*tail
;
14716 for (tail
= x_display_list
; tail
; tail
= tail
->next
)
14717 if (tail
->next
== dpyinfo
)
14718 tail
->next
= tail
->next
->next
;
14721 #ifndef USE_X_TOOLKIT /* I'm told Xt does this itself. */
14722 #ifndef AIX /* On AIX, XCloseDisplay calls this. */
14723 XrmDestroyDatabase (dpyinfo
->xrdb
);
14726 #ifdef MULTI_KBOARD
14727 if (--dpyinfo
->kboard
->reference_count
== 0)
14728 delete_kboard (dpyinfo
->kboard
);
14732 xim_close_dpy (dpyinfo
);
14735 xfree (dpyinfo
->font_table
);
14736 xfree (dpyinfo
->x_id_name
);
14737 xfree (dpyinfo
->color_cells
);
14742 /* Set up use of X before we make the first connection. */
14744 static struct redisplay_interface x_redisplay_interface
=
14749 x_clear_end_of_line
,
14751 x_after_update_window_line
,
14752 x_update_window_begin
,
14753 x_update_window_end
,
14756 x_clear_mouse_face
,
14757 x_get_glyph_overhangs
,
14758 x_fix_overlapping_area
14764 rif
= &x_redisplay_interface
;
14766 clear_frame_hook
= x_clear_frame
;
14767 ins_del_lines_hook
= x_ins_del_lines
;
14768 delete_glyphs_hook
= x_delete_glyphs
;
14769 ring_bell_hook
= XTring_bell
;
14770 reset_terminal_modes_hook
= XTreset_terminal_modes
;
14771 set_terminal_modes_hook
= XTset_terminal_modes
;
14772 update_begin_hook
= x_update_begin
;
14773 update_end_hook
= x_update_end
;
14774 set_terminal_window_hook
= XTset_terminal_window
;
14775 read_socket_hook
= XTread_socket
;
14776 frame_up_to_date_hook
= XTframe_up_to_date
;
14777 mouse_position_hook
= XTmouse_position
;
14778 frame_rehighlight_hook
= XTframe_rehighlight
;
14779 frame_raise_lower_hook
= XTframe_raise_lower
;
14780 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
14781 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
14782 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
14783 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
14784 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
14786 scroll_region_ok
= 1; /* we'll scroll partial frames */
14787 char_ins_del_ok
= 1;
14788 line_ins_del_ok
= 1; /* we'll just blt 'em */
14789 fast_clear_end_of_line
= 1; /* X does this well */
14790 memory_below_frame
= 0; /* we don't remember what scrolls
14795 last_tool_bar_item
= -1;
14796 any_help_event_p
= 0;
14798 /* Try to use interrupt input; if we can't, then start polling. */
14799 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
14801 #ifdef USE_X_TOOLKIT
14802 XtToolkitInitialize ();
14804 Xt_app_con
= XtCreateApplicationContext ();
14806 /* Register a converter from strings to pixels, which uses
14807 Emacs' color allocation infrastructure. */
14808 XtAppSetTypeConverter (Xt_app_con
,
14809 XtRString
, XtRPixel
, cvt_string_to_pixel
,
14810 cvt_string_to_pixel_args
,
14811 XtNumber (cvt_string_to_pixel_args
),
14812 XtCacheByDisplay
, cvt_pixel_dtor
);
14814 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
14816 /* Install an asynchronous timer that processes Xt timeout events
14817 every 0.1s. This is necessary because some widget sets use
14818 timeouts internally, for example the LessTif menu bar, or the
14819 Xaw3d scroll bar. When Xt timouts aren't processed, these
14820 widgets don't behave normally. */
14822 EMACS_TIME interval
;
14823 EMACS_SET_SECS_USECS (interval
, 0, 100000);
14824 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
14828 #ifdef USE_TOOLKIT_SCROLL_BARS
14829 xaw3d_arrow_scroll
= False
;
14830 xaw3d_pick_top
= True
;
14833 /* Note that there is no real way portable across R3/R4 to get the
14834 original error handler. */
14835 XSetErrorHandler (x_error_handler
);
14836 XSetIOErrorHandler (x_io_error_quitter
);
14838 /* Disable Window Change signals; they are handled by X events. */
14840 signal (SIGWINCH
, SIG_DFL
);
14841 #endif /* ! defined (SIGWINCH) */
14843 signal (SIGPIPE
, x_connection_signal
);
14850 staticpro (&x_error_message_string
);
14851 x_error_message_string
= Qnil
;
14853 staticpro (&x_display_name_list
);
14854 x_display_name_list
= Qnil
;
14856 staticpro (&last_mouse_scroll_bar
);
14857 last_mouse_scroll_bar
= Qnil
;
14859 staticpro (&Qvendor_specific_keysyms
);
14860 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
14862 staticpro (&last_mouse_press_frame
);
14863 last_mouse_press_frame
= Qnil
;
14866 staticpro (&help_echo
);
14867 help_echo_object
= Qnil
;
14868 staticpro (&help_echo_object
);
14869 help_echo_window
= Qnil
;
14870 staticpro (&help_echo_window
);
14871 previous_help_echo
= Qnil
;
14872 staticpro (&previous_help_echo
);
14873 help_echo_pos
= -1;
14875 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
14876 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
14877 For example, if a block cursor is over a tab, it will be drawn as
14878 wide as that tab on the display. */);
14879 x_stretch_cursor_p
= 0;
14881 DEFVAR_BOOL ("x-use-underline-position-properties",
14882 &x_use_underline_position_properties
,
14883 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
14884 nil means ignore them. If you encounter fonts with bogus
14885 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
14886 to 4.1, set this to nil. */);
14887 x_use_underline_position_properties
= 1;
14889 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
14890 doc
: /* What X toolkit scroll bars Emacs uses.
14891 A value of nil means Emacs doesn't use X toolkit scroll bars.
14892 Otherwise, value is a symbol describing the X toolkit. */);
14893 #ifdef USE_TOOLKIT_SCROLL_BARS
14895 Vx_toolkit_scroll_bars
= intern ("motif");
14896 #elif defined HAVE_XAW3D
14897 Vx_toolkit_scroll_bars
= intern ("xaw3d");
14899 Vx_toolkit_scroll_bars
= intern ("xaw");
14902 Vx_toolkit_scroll_bars
= Qnil
;
14905 staticpro (&last_mouse_motion_frame
);
14906 last_mouse_motion_frame
= Qnil
;
14909 #endif /* HAVE_X_WINDOWS */