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. */
176 static unsigned char zv_bits
[] = {
177 0x00, 0x00, 0x1e, 0x1e, 0x1e, 0x1e, 0x00, 0x00};
179 /* An arrow like this: `<-'. */
182 #define left_height 8
183 static unsigned char left_bits
[] = {
184 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
186 /* Right truncation arrow bitmap `->'. */
188 #define right_width 8
189 #define right_height 8
190 static unsigned char right_bits
[] = {
191 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
193 /* Marker for continued lines. */
195 #define continued_width 8
196 #define continued_height 8
197 static unsigned char continued_bits
[] = {
198 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
200 /* Marker for continuation lines. */
202 #define continuation_width 8
203 #define continuation_height 8
204 static unsigned char continuation_bits
[] = {
205 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
207 /* Overlay arrow bitmap. */
213 static unsigned char ov_bits
[] = {
214 0x30, 0x08, 0x3c, 0x7e, 0x7a, 0x7a, 0x62, 0x3c};
216 /* A triangular arrow. */
219 static unsigned char ov_bits
[] = {
220 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
224 extern Lisp_Object Qhelp_echo
;
227 /* Non-nil means Emacs uses toolkit scroll bars. */
229 Lisp_Object Vx_toolkit_scroll_bars
;
231 /* If a string, XTread_socket generates an event to display that string.
232 (The display is done in read_char.) */
234 static Lisp_Object help_echo
;
235 static Lisp_Object help_echo_window
;
236 static Lisp_Object help_echo_object
;
237 static int help_echo_pos
;
239 /* Temporary variable for XTread_socket. */
241 static Lisp_Object previous_help_echo
;
243 /* Non-zero means that a HELP_EVENT has been generated since Emacs
246 static int any_help_event_p
;
248 /* Non-zero means draw block and hollow cursor as wide as the glyph
249 under it. For example, if a block cursor is over a tab, it will be
250 drawn as wide as that tab on the display. */
252 int x_stretch_cursor_p
;
254 /* Non-zero means make use of UNDERLINE_POSITION font properties. */
256 int x_use_underline_position_properties
;
258 /* This is a chain of structures for all the X displays currently in
261 struct x_display_info
*x_display_list
;
263 /* This is a list of cons cells, each of the form (NAME
264 . FONT-LIST-CACHE), one for each element of x_display_list and in
265 the same order. NAME is the name of the frame. FONT-LIST-CACHE
266 records previous values returned by x-list-fonts. */
268 Lisp_Object x_display_name_list
;
270 /* Frame being updated by update_frame. This is declared in term.c.
271 This is set by update_begin and looked at by all the XT functions.
272 It is zero while not inside an update. In that case, the XT
273 functions assume that `selected_frame' is the frame to apply to. */
275 extern struct frame
*updating_frame
;
277 extern int waiting_for_input
;
279 /* This is a frame waiting to be auto-raised, within XTread_socket. */
281 struct frame
*pending_autoraise_frame
;
284 /* The application context for Xt use. */
285 XtAppContext Xt_app_con
;
286 static String Xt_default_resources
[] = {0};
287 #endif /* USE_X_TOOLKIT */
289 /* Nominal cursor position -- where to draw output.
290 HPOS and VPOS are window relative glyph matrix coordinates.
291 X and Y are window relative pixel coordinates. */
293 struct cursor_pos output_cursor
;
295 /* Non-zero means user is interacting with a toolkit scroll bar. */
297 static int toolkit_scroll_bar_interaction
;
301 Formerly, we used PointerMotionHintMask (in standard_event_mask)
302 so that we would have to call XQueryPointer after each MotionNotify
303 event to ask for another such event. However, this made mouse tracking
304 slow, and there was a bug that made it eventually stop.
306 Simply asking for MotionNotify all the time seems to work better.
308 In order to avoid asking for motion events and then throwing most
309 of them away or busy-polling the server for mouse positions, we ask
310 the server for pointer motion hints. This means that we get only
311 one event per group of mouse movements. "Groups" are delimited by
312 other kinds of events (focus changes and button clicks, for
313 example), or by XQueryPointer calls; when one of these happens, we
314 get another MotionNotify event the next time the mouse moves. This
315 is at least as efficient as getting motion events when mouse
316 tracking is on, and I suspect only negligibly worse when tracking
319 /* Where the mouse was last time we reported a mouse event. */
321 FRAME_PTR last_mouse_frame
;
322 static XRectangle last_mouse_glyph
;
323 static Lisp_Object last_mouse_press_frame
;
325 /* The scroll bar in which the last X motion event occurred.
327 If the last X motion event occurred in a scroll bar, we set this so
328 XTmouse_position can know whether to report a scroll bar motion or
331 If the last X motion event didn't occur in a scroll bar, we set
332 this to Qnil, to tell XTmouse_position to return an ordinary motion
335 static Lisp_Object last_mouse_scroll_bar
;
337 /* This is a hack. We would really prefer that XTmouse_position would
338 return the time associated with the position it returns, but there
339 doesn't seem to be any way to wrest the time-stamp from the server
340 along with the position query. So, we just keep track of the time
341 of the last movement we received, and return that in hopes that
342 it's somewhat accurate. */
344 static Time last_mouse_movement_time
;
346 /* Incremented by XTread_socket whenever it really tries to read
350 static int volatile input_signal_count
;
352 static int input_signal_count
;
355 /* Used locally within XTread_socket. */
357 static int x_noop_count
;
359 /* Initial values of argv and argc. */
361 extern char **initial_argv
;
362 extern int initial_argc
;
364 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
366 /* Tells if a window manager is present or not. */
368 extern Lisp_Object Vx_no_window_manager
;
370 extern Lisp_Object Qface
, Qmouse_face
;
374 /* A mask of extra modifier bits to put into every keyboard char. */
376 extern int extra_keyboard_modifiers
;
378 static Lisp_Object Qvendor_specific_keysyms
;
380 extern XrmDatabase x_load_resources
P_ ((Display
*, char *, char *, char *));
381 extern Lisp_Object x_icon_type
P_ ((struct frame
*));
384 /* Enumeration for overriding/changing the face to use for drawing
385 glyphs in x_draw_glyphs. */
387 enum draw_glyphs_face
397 static int cursor_in_mouse_face_p
P_ ((struct window
*));
398 static int clear_mouse_face
P_ ((struct x_display_info
*));
399 static int x_alloc_nearest_color_1
P_ ((Display
*, Colormap
, XColor
*));
400 static void x_set_window_size_1
P_ ((struct frame
*, int, int, int));
401 static const XColor
*x_color_cells
P_ ((Display
*, int *));
402 static void x_update_window_end
P_ ((struct window
*, int, int));
403 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
404 void x_delete_display
P_ ((struct x_display_info
*));
405 static unsigned int x_x_to_emacs_modifiers
P_ ((struct x_display_info
*,
407 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
408 int *, int *, Lisp_Object
));
409 static int fast_find_string_pos
P_ ((struct window
*, int, Lisp_Object
,
410 int *, int *, int *, int *, int));
411 static void set_output_cursor
P_ ((struct cursor_pos
*));
412 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
413 int *, int *, int *, int));
414 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
415 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
416 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
417 static void x_handle_tool_bar_click
P_ ((struct frame
*, XButtonEvent
*));
418 static void show_mouse_face
P_ ((struct x_display_info
*,
419 enum draw_glyphs_face
));
420 static int x_io_error_quitter
P_ ((Display
*));
421 int x_catch_errors
P_ ((Display
*));
422 void x_uncatch_errors
P_ ((Display
*, int));
423 void x_lower_frame
P_ ((struct frame
*));
424 void x_scroll_bar_clear
P_ ((struct frame
*));
425 int x_had_errors_p
P_ ((Display
*));
426 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
427 void x_raise_frame
P_ ((struct frame
*));
428 void x_set_window_size
P_ ((struct frame
*, int, int, int));
429 void x_wm_set_window_state
P_ ((struct frame
*, int));
430 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
431 void x_initialize
P_ ((void));
432 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
433 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
434 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
436 enum draw_glyphs_face
));
437 static void x_update_end
P_ ((struct frame
*));
438 static void XTframe_up_to_date
P_ ((struct frame
*));
439 static void XTset_terminal_modes
P_ ((void));
440 static void XTreset_terminal_modes
P_ ((void));
441 static void XTcursor_to
P_ ((int, int, int, int));
442 static void x_write_glyphs
P_ ((struct glyph
*, int));
443 static void x_clear_end_of_line
P_ ((int));
444 static void x_clear_frame
P_ ((void));
445 static void x_clear_cursor
P_ ((struct window
*));
446 static void frame_highlight
P_ ((struct frame
*));
447 static void frame_unhighlight
P_ ((struct frame
*));
448 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
449 static void XTframe_rehighlight
P_ ((struct frame
*));
450 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
451 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
452 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int));
453 static int x_intersect_rectangles
P_ ((XRectangle
*, XRectangle
*,
455 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
456 static int expose_window_tree
P_ ((struct window
*, XRectangle
*));
457 static int expose_window
P_ ((struct window
*, XRectangle
*));
458 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
459 XRectangle
*, enum glyph_row_area
));
460 static int expose_line
P_ ((struct window
*, struct glyph_row
*,
462 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
463 static void x_update_window_cursor
P_ ((struct window
*, int));
464 static void x_erase_phys_cursor
P_ ((struct window
*));
465 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
466 static void x_draw_fringe_bitmap
P_ ((struct window
*, struct glyph_row
*,
467 enum fringe_bitmap_type
));
469 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
471 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, XRectangle
*));
472 static void x_draw_row_fringe_bitmaps
P_ ((struct window
*, struct glyph_row
*));
473 static void notice_overwritten_cursor
P_ ((struct window
*, int, int));
474 static void x_flush
P_ ((struct frame
*f
));
475 static void x_update_begin
P_ ((struct frame
*));
476 static void x_update_window_begin
P_ ((struct window
*));
477 static void x_draw_vertical_border
P_ ((struct window
*));
478 static void x_after_update_window_line
P_ ((struct glyph_row
*));
479 static INLINE
void take_vertical_position_into_account
P_ ((struct it
*));
480 static void x_produce_stretch_glyph
P_ ((struct it
*));
481 static struct scroll_bar
*x_window_to_scroll_bar
P_ ((Window
));
482 static void x_scroll_bar_report_motion
P_ ((struct frame
**, Lisp_Object
*,
483 enum scroll_bar_part
*,
484 Lisp_Object
*, Lisp_Object
*,
487 /* Flush display of frame F, or of all frames if F is null. */
496 Lisp_Object rest
, frame
;
497 FOR_EACH_FRAME (rest
, frame
)
498 x_flush (XFRAME (frame
));
500 else if (FRAME_X_P (f
))
501 XFlush (FRAME_X_DISPLAY (f
));
506 /* Remove calls to XFlush by defining XFlush to an empty replacement.
507 Calls to XFlush should be unnecessary because the X output buffer
508 is flushed automatically as needed by calls to XPending,
509 XNextEvent, or XWindowEvent according to the XFlush man page.
510 XTread_socket calls XPending. Removing XFlush improves
513 #define XFlush(DISPLAY) (void) 0
516 /***********************************************************************
518 ***********************************************************************/
522 /* This is a function useful for recording debugging information about
523 the sequence of occurrences in this file. */
531 struct record event_record
[100];
533 int event_record_index
;
535 record_event (locus
, type
)
539 if (event_record_index
== sizeof (event_record
) / sizeof (struct record
))
540 event_record_index
= 0;
542 event_record
[event_record_index
].locus
= locus
;
543 event_record
[event_record_index
].type
= type
;
544 event_record_index
++;
551 /* Return the struct x_display_info corresponding to DPY. */
553 struct x_display_info
*
554 x_display_info_for_display (dpy
)
557 struct x_display_info
*dpyinfo
;
559 for (dpyinfo
= x_display_list
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
560 if (dpyinfo
->display
== dpy
)
568 /***********************************************************************
569 Starting and ending an update
570 ***********************************************************************/
572 /* Start an update of frame F. This function is installed as a hook
573 for update_begin, i.e. it is called when update_begin is called.
574 This function is called prior to calls to x_update_window_begin for
575 each window being updated. Currently, there is nothing to do here
576 because all interesting stuff is done on a window basis. */
586 /* Start update of window W. Set the global variable updated_window
587 to the window being updated and set output_cursor to the cursor
591 x_update_window_begin (w
)
594 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
595 struct x_display_info
*display_info
= FRAME_X_DISPLAY_INFO (f
);
598 set_output_cursor (&w
->cursor
);
602 if (f
== display_info
->mouse_face_mouse_frame
)
604 /* Don't do highlighting for mouse motion during the update. */
605 display_info
->mouse_face_defer
= 1;
607 /* If F needs to be redrawn, simply forget about any prior mouse
609 if (FRAME_GARBAGED_P (f
))
610 display_info
->mouse_face_window
= Qnil
;
612 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
613 their mouse_face_p flag set, which means that they are always
614 unequal to rows in a desired matrix which never have that
615 flag set. So, rows containing mouse-face glyphs are never
616 scrolled, and we don't have to switch the mouse highlight off
617 here to prevent it from being scrolled. */
619 /* Can we tell that this update does not affect the window
620 where the mouse highlight is? If so, no need to turn off.
621 Likewise, don't do anything if the frame is garbaged;
622 in that case, the frame's current matrix that we would use
623 is all wrong, and we will redisplay that line anyway. */
624 if (!NILP (display_info
->mouse_face_window
)
625 && w
== XWINDOW (display_info
->mouse_face_window
))
629 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
630 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
633 if (i
< w
->desired_matrix
->nrows
)
634 clear_mouse_face (display_info
);
643 /* Draw a vertical window border to the right of window W if W doesn't
644 have vertical scroll bars. */
647 x_draw_vertical_border (w
)
650 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
652 /* Redraw borders between horizontally adjacent windows. Don't
653 do it for frames with vertical scroll bars because either the
654 right scroll bar of a window, or the left scroll bar of its
655 neighbor will suffice as a border. */
656 if (!WINDOW_RIGHTMOST_P (w
)
657 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
661 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
662 x1
+= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
665 XDrawLine (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
666 f
->output_data
.x
->normal_gc
, x1
, y0
, x1
, y1
);
671 /* End update of window W (which is equal to updated_window).
673 Draw vertical borders between horizontally adjacent windows, and
674 display W's cursor if CURSOR_ON_P is non-zero.
676 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
677 glyphs in mouse-face were overwritten. In that case we have to
678 make sure that the mouse-highlight is properly redrawn.
680 W may be a menu bar pseudo-window in case we don't have X toolkit
681 support. Such windows don't have a cursor, so don't display it
685 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
687 int cursor_on_p
, mouse_face_overwritten_p
;
689 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
691 if (!w
->pseudo_window_p
)
696 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
698 output_cursor
.x
, output_cursor
.y
);
700 x_draw_vertical_border (w
);
704 /* If a row with mouse-face was overwritten, arrange for
705 XTframe_up_to_date to redisplay the mouse highlight. */
706 if (mouse_face_overwritten_p
)
708 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
709 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
710 dpyinfo
->mouse_face_window
= Qnil
;
713 updated_window
= NULL
;
717 /* End update of frame F. This function is installed as a hook in
724 /* Mouse highlight may be displayed again. */
725 FRAME_X_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
728 XFlush (FRAME_X_DISPLAY (f
));
733 /* This function is called from various places in xdisp.c whenever a
734 complete update has been performed. The global variable
735 updated_window is not available here. */
738 XTframe_up_to_date (f
)
743 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
745 if (dpyinfo
->mouse_face_deferred_gc
746 || f
== dpyinfo
->mouse_face_mouse_frame
)
749 if (dpyinfo
->mouse_face_mouse_frame
)
750 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
751 dpyinfo
->mouse_face_mouse_x
,
752 dpyinfo
->mouse_face_mouse_y
);
753 dpyinfo
->mouse_face_deferred_gc
= 0;
760 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
761 arrow bitmaps, or clear the fringes if no bitmaps are required
762 before DESIRED_ROW is made current. The window being updated is
763 found in updated_window. This function It is called from
764 update_window_line only if it is known that there are differences
765 between bitmaps to be drawn between current row and DESIRED_ROW. */
768 x_after_update_window_line (desired_row
)
769 struct glyph_row
*desired_row
;
771 struct window
*w
= updated_window
;
777 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
780 x_draw_row_fringe_bitmaps (w
, desired_row
);
784 /* When a window has disappeared, make sure that no rest of
785 full-width rows stays visible in the internal border. Could
786 check here if updated_window is the leftmost/rightmost window,
787 but I guess it's not worth doing since vertically split windows
788 are almost never used, internal border is rarely set, and the
789 overhead is very small. */
790 if (windows_or_buffers_changed
791 && desired_row
->full_width_p
792 && (f
= XFRAME (w
->frame
),
793 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
795 && (height
= desired_row
->visible_height
,
798 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
800 /* Internal border is drawn below the tool bar. */
801 if (WINDOWP (f
->tool_bar_window
)
802 && w
== XWINDOW (f
->tool_bar_window
))
806 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
807 0, y
, width
, height
, False
);
808 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
809 f
->output_data
.x
->pixel_width
- width
,
810 y
, width
, height
, False
);
816 /* Draw the bitmap WHICH in one of the left or right fringes of
817 window W. ROW is the glyph row for which to display the bitmap; it
818 determines the vertical position at which the bitmap has to be
822 x_draw_fringe_bitmap (w
, row
, which
)
824 struct glyph_row
*row
;
825 enum fringe_bitmap_type which
;
827 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
828 Display
*display
= FRAME_X_DISPLAY (f
);
829 Window window
= FRAME_X_WINDOW (f
);
833 GC gc
= f
->output_data
.x
->normal_gc
;
835 int depth
= DefaultDepthOfScreen (FRAME_X_SCREEN (f
));
837 /* Must clip because of partially visible lines. */
838 x_clip_to_row (w
, row
, gc
, 1);
842 case LEFT_TRUNCATION_BITMAP
:
846 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
848 - (FRAME_X_LEFT_FRINGE_WIDTH (f
) - wd
) / 2);
851 case OVERLAY_ARROW_BITMAP
:
855 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
857 - (FRAME_X_LEFT_FRINGE_WIDTH (f
) - wd
) / 2);
860 case RIGHT_TRUNCATION_BITMAP
:
864 x
= window_box_right (w
, -1);
865 x
+= (FRAME_X_RIGHT_FRINGE_WIDTH (f
) - wd
) / 2;
868 case CONTINUED_LINE_BITMAP
:
871 bits
= continued_bits
;
872 x
= window_box_right (w
, -1);
873 x
+= (FRAME_X_RIGHT_FRINGE_WIDTH (f
) - wd
) / 2;
876 case CONTINUATION_LINE_BITMAP
:
877 wd
= continuation_width
;
878 h
= continuation_height
;
879 bits
= continuation_bits
;
880 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
882 - (FRAME_X_LEFT_FRINGE_WIDTH (f
) - wd
) / 2);
889 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
891 - (FRAME_X_LEFT_FRINGE_WIDTH (f
) - wd
) / 2);
898 /* Convert to frame coordinates. Set dy to the offset in the row to
899 start drawing the bitmap. */
900 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
901 dy
= (row
->height
- h
) / 2;
903 /* Draw the bitmap. I believe these small pixmaps can be cached
905 face
= FACE_FROM_ID (f
, FRINGE_FACE_ID
);
906 pixmap
= XCreatePixmapFromBitmapData (display
, window
, bits
, wd
, h
,
908 face
->background
, depth
);
909 XCopyArea (display
, pixmap
, window
, gc
, 0, 0, wd
, h
, x
, y
+ dy
);
910 XFreePixmap (display
, pixmap
);
911 XSetClipMask (display
, gc
, None
);
915 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
916 function with input blocked. */
919 x_draw_row_fringe_bitmaps (w
, row
)
921 struct glyph_row
*row
;
923 struct frame
*f
= XFRAME (w
->frame
);
924 enum fringe_bitmap_type bitmap
;
926 int header_line_height
= -1;
928 xassert (interrupt_input_blocked
);
930 /* If row is completely invisible, because of vscrolling, we
931 don't have to draw anything. */
932 if (row
->visible_height
<= 0)
935 face
= FACE_FROM_ID (f
, FRINGE_FACE_ID
);
936 PREPARE_FACE_FOR_DISPLAY (f
, face
);
938 /* Decide which bitmap to draw in the left fringe. */
939 if (row
->overlay_arrow_p
)
940 bitmap
= OVERLAY_ARROW_BITMAP
;
941 else if (row
->truncated_on_left_p
)
942 bitmap
= LEFT_TRUNCATION_BITMAP
;
943 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
944 bitmap
= CONTINUATION_LINE_BITMAP
;
945 else if (row
->indicate_empty_line_p
)
946 bitmap
= ZV_LINE_BITMAP
;
948 bitmap
= NO_FRINGE_BITMAP
;
950 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
952 if (bitmap
== NO_FRINGE_BITMAP
953 || FRAME_FRINGE_BITMAP_WIDTH (f
) < FRAME_X_LEFT_FRINGE_WIDTH (f
)
954 || row
->height
> FRAME_FRINGE_BITMAP_HEIGHT (f
))
956 /* If W has a vertical border to its left, don't draw over it. */
957 int border
= ((XFASTINT (w
->left
) > 0
958 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
960 int left
= window_box_left (w
, -1);
962 if (header_line_height
< 0)
963 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
965 /* In case the same realized face is used for fringes and
966 for something displayed in the text (e.g. face `region' on
967 mono-displays, the fill style may have been changed to
968 FillSolid in x_draw_glyph_string_background. */
970 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
972 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
974 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
977 - FRAME_X_LEFT_FRINGE_WIDTH (f
)
979 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
981 FRAME_X_LEFT_FRINGE_WIDTH (f
) - border
,
982 row
->visible_height
);
984 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
987 /* Draw the left bitmap. */
988 if (bitmap
!= NO_FRINGE_BITMAP
)
989 x_draw_fringe_bitmap (w
, row
, bitmap
);
991 /* Decide which bitmap to draw in the right fringe. */
992 if (row
->truncated_on_right_p
)
993 bitmap
= RIGHT_TRUNCATION_BITMAP
;
994 else if (row
->continued_p
)
995 bitmap
= CONTINUED_LINE_BITMAP
;
997 bitmap
= NO_FRINGE_BITMAP
;
999 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
1001 if (bitmap
== NO_FRINGE_BITMAP
1002 || FRAME_FRINGE_BITMAP_WIDTH (f
) < FRAME_X_RIGHT_FRINGE_WIDTH (f
)
1003 || row
->height
> FRAME_FRINGE_BITMAP_HEIGHT (f
))
1005 int right
= window_box_right (w
, -1);
1007 if (header_line_height
< 0)
1008 header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
1010 /* In case the same realized face is used for fringes and
1011 for something displayed in the text (e.g. face `region' on
1012 mono-displays, the fill style may have been changed to
1013 FillSolid in x_draw_glyph_string_background. */
1015 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
1017 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
1018 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
1021 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
1023 FRAME_X_RIGHT_FRINGE_WIDTH (f
),
1024 row
->visible_height
);
1026 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
1029 /* Draw the right bitmap. */
1030 if (bitmap
!= NO_FRINGE_BITMAP
)
1031 x_draw_fringe_bitmap (w
, row
, bitmap
);
1036 /* This is called when starting Emacs and when restarting after
1037 suspend. When starting Emacs, no X window is mapped. And nothing
1038 must be done to Emacs's own window if it is suspended (though that
1042 XTset_terminal_modes ()
1046 /* This is called when exiting or suspending Emacs. Exiting will make
1047 the X-windows go away, and suspending requires no action. */
1050 XTreset_terminal_modes ()
1056 /***********************************************************************
1058 ***********************************************************************/
1060 /* Set the global variable output_cursor to CURSOR. All cursor
1061 positions are relative to updated_window. */
1064 set_output_cursor (cursor
)
1065 struct cursor_pos
*cursor
;
1067 output_cursor
.hpos
= cursor
->hpos
;
1068 output_cursor
.vpos
= cursor
->vpos
;
1069 output_cursor
.x
= cursor
->x
;
1070 output_cursor
.y
= cursor
->y
;
1074 /* Set a nominal cursor position.
1076 HPOS and VPOS are column/row positions in a window glyph matrix. X
1077 and Y are window text area relative pixel positions.
1079 If this is done during an update, updated_window will contain the
1080 window that is being updated and the position is the future output
1081 cursor position for that window. If updated_window is null, use
1082 selected_window and display the cursor at the given position. */
1085 XTcursor_to (vpos
, hpos
, y
, x
)
1086 int vpos
, hpos
, y
, x
;
1090 /* If updated_window is not set, work on selected_window. */
1094 w
= XWINDOW (selected_window
);
1096 /* Set the output cursor. */
1097 output_cursor
.hpos
= hpos
;
1098 output_cursor
.vpos
= vpos
;
1099 output_cursor
.x
= x
;
1100 output_cursor
.y
= y
;
1102 /* If not called as part of an update, really display the cursor.
1103 This will also set the cursor position of W. */
1104 if (updated_window
== NULL
)
1107 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1108 XFlush (FRAME_X_DISPLAY (SELECTED_FRAME ()));
1115 /***********************************************************************
1117 ***********************************************************************/
1119 /* Function prototypes of this page. */
1121 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1125 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1126 int, XChar2b
*, int));
1127 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1128 static void x_encode_char
P_ ((int, XChar2b
*, struct font_info
*));
1129 static void x_append_glyph
P_ ((struct it
*));
1130 static void x_append_composite_glyph
P_ ((struct it
*));
1131 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1133 static void x_produce_glyphs
P_ ((struct it
*));
1134 static void x_produce_image_glyph
P_ ((struct it
*it
));
1137 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1138 is not contained in the font. */
1140 static INLINE XCharStruct
*
1141 x_per_char_metric (font
, char2b
)
1145 /* The result metric information. */
1146 XCharStruct
*pcm
= NULL
;
1148 xassert (font
&& char2b
);
1150 if (font
->per_char
!= NULL
)
1152 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1154 /* min_char_or_byte2 specifies the linear character index
1155 corresponding to the first element of the per_char array,
1156 max_char_or_byte2 is the index of the last character. A
1157 character with non-zero CHAR2B->byte1 is not in the font.
1158 A character with byte2 less than min_char_or_byte2 or
1159 greater max_char_or_byte2 is not in the font. */
1160 if (char2b
->byte1
== 0
1161 && char2b
->byte2
>= font
->min_char_or_byte2
1162 && char2b
->byte2
<= font
->max_char_or_byte2
)
1163 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1167 /* If either min_byte1 or max_byte1 are nonzero, both
1168 min_char_or_byte2 and max_char_or_byte2 are less than
1169 256, and the 2-byte character index values corresponding
1170 to the per_char array element N (counting from 0) are:
1172 byte1 = N/D + min_byte1
1173 byte2 = N\D + min_char_or_byte2
1177 D = max_char_or_byte2 - min_char_or_byte2 + 1
1178 / = integer division
1179 \ = integer modulus */
1180 if (char2b
->byte1
>= font
->min_byte1
1181 && char2b
->byte1
<= font
->max_byte1
1182 && char2b
->byte2
>= font
->min_char_or_byte2
1183 && char2b
->byte2
<= font
->max_char_or_byte2
)
1185 pcm
= (font
->per_char
1186 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1187 * (char2b
->byte1
- font
->min_byte1
))
1188 + (char2b
->byte2
- font
->min_char_or_byte2
));
1194 /* If the per_char pointer is null, all glyphs between the first
1195 and last character indexes inclusive have the same
1196 information, as given by both min_bounds and max_bounds. */
1197 if (char2b
->byte2
>= font
->min_char_or_byte2
1198 && char2b
->byte2
<= font
->max_char_or_byte2
)
1199 pcm
= &font
->max_bounds
;
1202 return ((pcm
== NULL
1203 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1208 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1209 the two-byte form of C. Encoding is returned in *CHAR2B. */
1212 x_encode_char (c
, char2b
, font_info
)
1215 struct font_info
*font_info
;
1217 int charset
= CHAR_CHARSET (c
);
1218 XFontStruct
*font
= font_info
->font
;
1220 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1221 This may be either a program in a special encoder language or a
1223 if (font_info
->font_encoder
)
1225 /* It's a program. */
1226 struct ccl_program
*ccl
= font_info
->font_encoder
;
1228 if (CHARSET_DIMENSION (charset
) == 1)
1230 ccl
->reg
[0] = charset
;
1231 ccl
->reg
[1] = char2b
->byte2
;
1235 ccl
->reg
[0] = charset
;
1236 ccl
->reg
[1] = char2b
->byte1
;
1237 ccl
->reg
[2] = char2b
->byte2
;
1240 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1242 /* We assume that MSBs are appropriately set/reset by CCL
1244 if (font
->max_byte1
== 0) /* 1-byte font */
1245 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1247 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1249 else if (font_info
->encoding
[charset
])
1251 /* Fixed encoding scheme. See fontset.h for the meaning of the
1252 encoding numbers. */
1253 int enc
= font_info
->encoding
[charset
];
1255 if ((enc
== 1 || enc
== 2)
1256 && CHARSET_DIMENSION (charset
) == 2)
1257 char2b
->byte1
|= 0x80;
1259 if (enc
== 1 || enc
== 3)
1260 char2b
->byte2
|= 0x80;
1265 /* Get face and two-byte form of character C in face FACE_ID on frame
1266 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1267 means we want to display multibyte text. Value is a pointer to a
1268 realized face that is ready for display. */
1270 static INLINE
struct face
*
1271 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1277 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1281 /* Unibyte case. We don't have to encode, but we have to make
1282 sure to use a face suitable for unibyte. */
1285 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1286 face
= FACE_FROM_ID (f
, face_id
);
1288 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1290 /* Case of ASCII in a face known to fit ASCII. */
1296 int c1
, c2
, charset
;
1298 /* Split characters into bytes. If c2 is -1 afterwards, C is
1299 really a one-byte character so that byte1 is zero. */
1300 SPLIT_CHAR (c
, charset
, c1
, c2
);
1302 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1304 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1306 /* Maybe encode the character in *CHAR2B. */
1307 if (face
->font
!= NULL
)
1309 struct font_info
*font_info
1310 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1312 x_encode_char (c
, char2b
, font_info
);
1316 /* Make sure X resources of the face are allocated. */
1317 xassert (face
!= NULL
);
1318 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1324 /* Get face and two-byte form of character glyph GLYPH on frame F.
1325 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1326 a pointer to a realized face that is ready for display. */
1328 static INLINE
struct face
*
1329 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1331 struct glyph
*glyph
;
1337 xassert (glyph
->type
== CHAR_GLYPH
);
1338 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1343 if (!glyph
->multibyte_p
)
1345 /* Unibyte case. We don't have to encode, but we have to make
1346 sure to use a face suitable for unibyte. */
1348 char2b
->byte2
= glyph
->u
.ch
;
1350 else if (glyph
->u
.ch
< 128
1351 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1353 /* Case of ASCII in a face known to fit ASCII. */
1355 char2b
->byte2
= glyph
->u
.ch
;
1359 int c1
, c2
, charset
;
1361 /* Split characters into bytes. If c2 is -1 afterwards, C is
1362 really a one-byte character so that byte1 is zero. */
1363 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1365 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1367 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1369 /* Maybe encode the character in *CHAR2B. */
1370 if (charset
!= CHARSET_ASCII
)
1372 struct font_info
*font_info
1373 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1376 x_encode_char (glyph
->u
.ch
, char2b
, font_info
);
1379 = ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
1384 /* Make sure X resources of the face are allocated. */
1385 xassert (face
!= NULL
);
1386 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1391 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1392 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1398 struct glyph
*glyph
;
1399 enum glyph_row_area area
= it
->area
;
1401 xassert (it
->glyph_row
);
1402 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1404 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1405 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1407 glyph
->charpos
= CHARPOS (it
->position
);
1408 glyph
->object
= it
->object
;
1409 glyph
->pixel_width
= it
->pixel_width
;
1410 glyph
->voffset
= it
->voffset
;
1411 glyph
->type
= CHAR_GLYPH
;
1412 glyph
->multibyte_p
= it
->multibyte_p
;
1413 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1414 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1415 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1416 || it
->phys_descent
> it
->descent
);
1417 glyph
->padding_p
= 0;
1418 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1419 glyph
->face_id
= it
->face_id
;
1420 glyph
->u
.ch
= it
->char_to_display
;
1421 ++it
->glyph_row
->used
[area
];
1425 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1426 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1429 x_append_composite_glyph (it
)
1432 struct glyph
*glyph
;
1433 enum glyph_row_area area
= it
->area
;
1435 xassert (it
->glyph_row
);
1437 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1438 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1440 glyph
->charpos
= CHARPOS (it
->position
);
1441 glyph
->object
= it
->object
;
1442 glyph
->pixel_width
= it
->pixel_width
;
1443 glyph
->voffset
= it
->voffset
;
1444 glyph
->type
= COMPOSITE_GLYPH
;
1445 glyph
->multibyte_p
= it
->multibyte_p
;
1446 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1447 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1448 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1449 || it
->phys_descent
> it
->descent
);
1450 glyph
->padding_p
= 0;
1451 glyph
->glyph_not_available_p
= 0;
1452 glyph
->face_id
= it
->face_id
;
1453 glyph
->u
.cmp_id
= it
->cmp_id
;
1454 ++it
->glyph_row
->used
[area
];
1459 /* Change IT->ascent and IT->height according to the setting of
1463 take_vertical_position_into_account (it
)
1468 if (it
->voffset
< 0)
1469 /* Increase the ascent so that we can display the text higher
1471 it
->ascent
+= abs (it
->voffset
);
1473 /* Increase the descent so that we can display the text lower
1475 it
->descent
+= it
->voffset
;
1480 /* Produce glyphs/get display metrics for the image IT is loaded with.
1481 See the description of struct display_iterator in dispextern.h for
1482 an overview of struct display_iterator. */
1485 x_produce_image_glyph (it
)
1491 xassert (it
->what
== IT_IMAGE
);
1493 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1494 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1497 /* Make sure X resources of the face and image are loaded. */
1498 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1499 prepare_image_for_display (it
->f
, img
);
1501 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
1502 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
1503 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
1507 if (face
->box
!= FACE_NO_BOX
)
1509 if (face
->box_line_width
> 0)
1511 it
->ascent
+= face
->box_line_width
;
1512 it
->descent
+= face
->box_line_width
;
1515 if (it
->start_of_box_run_p
)
1516 it
->pixel_width
+= abs (face
->box_line_width
);
1517 if (it
->end_of_box_run_p
)
1518 it
->pixel_width
+= abs (face
->box_line_width
);
1521 take_vertical_position_into_account (it
);
1525 struct glyph
*glyph
;
1526 enum glyph_row_area area
= it
->area
;
1528 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1529 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1531 glyph
->charpos
= CHARPOS (it
->position
);
1532 glyph
->object
= it
->object
;
1533 glyph
->pixel_width
= it
->pixel_width
;
1534 glyph
->voffset
= it
->voffset
;
1535 glyph
->type
= IMAGE_GLYPH
;
1536 glyph
->multibyte_p
= it
->multibyte_p
;
1537 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1538 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1539 glyph
->overlaps_vertically_p
= 0;
1540 glyph
->padding_p
= 0;
1541 glyph
->glyph_not_available_p
= 0;
1542 glyph
->face_id
= it
->face_id
;
1543 glyph
->u
.img_id
= img
->id
;
1544 ++it
->glyph_row
->used
[area
];
1550 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1551 of the glyph, WIDTH and HEIGHT are the width and height of the
1552 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1553 ascent of the glyph (0 <= ASCENT <= 1). */
1556 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
1562 struct glyph
*glyph
;
1563 enum glyph_row_area area
= it
->area
;
1565 xassert (ascent
>= 0 && ascent
<= 1);
1567 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1568 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1570 glyph
->charpos
= CHARPOS (it
->position
);
1571 glyph
->object
= object
;
1572 glyph
->pixel_width
= width
;
1573 glyph
->voffset
= it
->voffset
;
1574 glyph
->type
= STRETCH_GLYPH
;
1575 glyph
->multibyte_p
= it
->multibyte_p
;
1576 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1577 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1578 glyph
->overlaps_vertically_p
= 0;
1579 glyph
->padding_p
= 0;
1580 glyph
->glyph_not_available_p
= 0;
1581 glyph
->face_id
= it
->face_id
;
1582 glyph
->u
.stretch
.ascent
= height
* ascent
;
1583 glyph
->u
.stretch
.height
= height
;
1584 ++it
->glyph_row
->used
[area
];
1589 /* Produce a stretch glyph for iterator IT. IT->object is the value
1590 of the glyph property displayed. The value must be a list
1591 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1594 1. `:width WIDTH' specifies that the space should be WIDTH *
1595 canonical char width wide. WIDTH may be an integer or floating
1598 2. `:relative-width FACTOR' specifies that the width of the stretch
1599 should be computed from the width of the first character having the
1600 `glyph' property, and should be FACTOR times that width.
1602 3. `:align-to HPOS' specifies that the space should be wide enough
1603 to reach HPOS, a value in canonical character units.
1605 Exactly one of the above pairs must be present.
1607 4. `:height HEIGHT' specifies that the height of the stretch produced
1608 should be HEIGHT, measured in canonical character units.
1610 5. `:relative-height FACTOR' specifies that the height of the the
1611 stretch should be FACTOR times the height of the characters having
1614 Either none or exactly one of 4 or 5 must be present.
1616 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1617 of the stretch should be used for the ascent of the stretch.
1618 ASCENT must be in the range 0 <= ASCENT <= 100. */
1621 ((INTEGERP (X) || FLOATP (X)) \
1627 x_produce_stretch_glyph (it
)
1630 /* (space :width WIDTH :height HEIGHT. */
1632 extern Lisp_Object Qspace
;
1634 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
1635 extern Lisp_Object QCrelative_width
, QCrelative_height
;
1636 extern Lisp_Object QCalign_to
;
1637 Lisp_Object prop
, plist
;
1638 double width
= 0, height
= 0, ascent
= 0;
1639 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1640 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
1642 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1644 /* List should start with `space'. */
1645 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
1646 plist
= XCDR (it
->object
);
1648 /* Compute the width of the stretch. */
1649 if (prop
= Fplist_get (plist
, QCwidth
),
1651 /* Absolute width `:width WIDTH' specified and valid. */
1652 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
1653 else if (prop
= Fplist_get (plist
, QCrelative_width
),
1656 /* Relative width `:relative-width FACTOR' specified and valid.
1657 Compute the width of the characters having the `glyph'
1660 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
1663 if (it
->multibyte_p
)
1665 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
1666 - IT_BYTEPOS (*it
));
1667 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
1670 it2
.c
= *p
, it2
.len
= 1;
1672 it2
.glyph_row
= NULL
;
1673 it2
.what
= IT_CHARACTER
;
1674 x_produce_glyphs (&it2
);
1675 width
= NUMVAL (prop
) * it2
.pixel_width
;
1677 else if (prop
= Fplist_get (plist
, QCalign_to
),
1679 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
1681 /* Nothing specified -> width defaults to canonical char width. */
1682 width
= CANON_X_UNIT (it
->f
);
1684 /* Compute height. */
1685 if (prop
= Fplist_get (plist
, QCheight
),
1687 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
1688 else if (prop
= Fplist_get (plist
, QCrelative_height
),
1690 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
1692 height
= FONT_HEIGHT (font
);
1694 /* Compute percentage of height used for ascent. If
1695 `:ascent ASCENT' is present and valid, use that. Otherwise,
1696 derive the ascent from the font in use. */
1697 if (prop
= Fplist_get (plist
, QCascent
),
1698 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
1699 ascent
= NUMVAL (prop
) / 100.0;
1701 ascent
= (double) font
->ascent
/ FONT_HEIGHT (font
);
1710 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
1711 if (!STRINGP (object
))
1712 object
= it
->w
->buffer
;
1713 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
1716 it
->pixel_width
= width
;
1717 it
->ascent
= it
->phys_ascent
= height
* ascent
;
1718 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
1721 if (face
->box
!= FACE_NO_BOX
)
1723 if (face
->box_line_width
> 0)
1725 it
->ascent
+= face
->box_line_width
;
1726 it
->descent
+= face
->box_line_width
;
1729 if (it
->start_of_box_run_p
)
1730 it
->pixel_width
+= abs (face
->box_line_width
);
1731 if (it
->end_of_box_run_p
)
1732 it
->pixel_width
+= abs (face
->box_line_width
);
1735 take_vertical_position_into_account (it
);
1738 /* Return proper value to be used as baseline offset of font that has
1739 ASCENT and DESCENT to draw characters by the font at the vertical
1740 center of the line of frame F.
1742 Here, out task is to find the value of BOFF in the following figure;
1744 -------------------------+-----------+-
1745 -+-+---------+-+ | |
1747 | | | | F_ASCENT F_HEIGHT
1750 | | |-|-+------+-----------|------- baseline
1752 | |---------|-+-+ | |
1754 -+-+---------+-+ F_DESCENT |
1755 -------------------------+-----------+-
1757 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1758 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1759 DESCENT = FONT->descent
1760 HEIGHT = FONT_HEIGHT (FONT)
1761 F_DESCENT = (F->output_data.x->font->descent
1762 - F->output_data.x->baseline_offset)
1763 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1766 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1768 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
1769 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
1770 - ((F)->output_data.x->font->descent - (F)->output_data.x->baseline_offset))
1772 /* Produce glyphs/get display metrics for the display element IT is
1773 loaded with. See the description of struct display_iterator in
1774 dispextern.h for an overview of struct display_iterator. */
1777 x_produce_glyphs (it
)
1780 it
->glyph_not_available_p
= 0;
1782 if (it
->what
== IT_CHARACTER
)
1786 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1788 int font_not_found_p
;
1789 struct font_info
*font_info
;
1790 int boff
; /* baseline offset */
1791 /* We may change it->multibyte_p upon unibyte<->multibyte
1792 conversion. So, save the current value now and restore it
1795 Note: It seems that we don't have to record multibyte_p in
1796 struct glyph because the character code itself tells if or
1797 not the character is multibyte. Thus, in the future, we must
1798 consider eliminating the field `multibyte_p' in the struct
1800 int saved_multibyte_p
= it
->multibyte_p
;
1802 /* Maybe translate single-byte characters to multibyte, or the
1804 it
->char_to_display
= it
->c
;
1805 if (!ASCII_BYTE_P (it
->c
))
1807 if (unibyte_display_via_language_environment
1808 && SINGLE_BYTE_CHAR_P (it
->c
)
1810 || !NILP (Vnonascii_translation_table
)))
1812 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
1813 it
->multibyte_p
= 1;
1814 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1815 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1817 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
1818 && !it
->multibyte_p
)
1820 it
->multibyte_p
= 1;
1821 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
1822 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1826 /* Get font to use. Encode IT->char_to_display. */
1827 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
1828 it
->face_id
, &char2b
,
1832 /* When no suitable font found, use the default font. */
1833 font_not_found_p
= font
== NULL
;
1834 if (font_not_found_p
)
1836 font
= FRAME_FONT (it
->f
);
1837 boff
= it
->f
->output_data
.x
->baseline_offset
;
1842 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
1843 boff
= font_info
->baseline_offset
;
1844 if (font_info
->vertical_centering
)
1845 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
1848 if (it
->char_to_display
>= ' '
1849 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
1851 /* Either unibyte or ASCII. */
1856 pcm
= x_per_char_metric (font
, &char2b
);
1857 it
->ascent
= font
->ascent
+ boff
;
1858 it
->descent
= font
->descent
- boff
;
1862 it
->phys_ascent
= pcm
->ascent
+ boff
;
1863 it
->phys_descent
= pcm
->descent
- boff
;
1864 it
->pixel_width
= pcm
->width
;
1868 it
->glyph_not_available_p
= 1;
1869 it
->phys_ascent
= font
->ascent
+ boff
;
1870 it
->phys_descent
= font
->descent
- boff
;
1871 it
->pixel_width
= FONT_WIDTH (font
);
1874 /* If this is a space inside a region of text with
1875 `space-width' property, change its width. */
1876 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
1878 it
->pixel_width
*= XFLOATINT (it
->space_width
);
1880 /* If face has a box, add the box thickness to the character
1881 height. If character has a box line to the left and/or
1882 right, add the box line width to the character's width. */
1883 if (face
->box
!= FACE_NO_BOX
)
1885 int thick
= face
->box_line_width
;
1889 it
->ascent
+= thick
;
1890 it
->descent
+= thick
;
1895 if (it
->start_of_box_run_p
)
1896 it
->pixel_width
+= thick
;
1897 if (it
->end_of_box_run_p
)
1898 it
->pixel_width
+= thick
;
1901 /* If face has an overline, add the height of the overline
1902 (1 pixel) and a 1 pixel margin to the character height. */
1903 if (face
->overline_p
)
1906 take_vertical_position_into_account (it
);
1908 /* If we have to actually produce glyphs, do it. */
1913 /* Translate a space with a `space-width' property
1914 into a stretch glyph. */
1915 double ascent
= (double) font
->ascent
/ FONT_HEIGHT (font
);
1916 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1917 it
->ascent
+ it
->descent
, ascent
);
1920 x_append_glyph (it
);
1922 /* If characters with lbearing or rbearing are displayed
1923 in this line, record that fact in a flag of the
1924 glyph row. This is used to optimize X output code. */
1925 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
1926 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
1929 else if (it
->char_to_display
== '\n')
1931 /* A newline has no width but we need the height of the line. */
1932 it
->pixel_width
= 0;
1934 it
->ascent
= it
->phys_ascent
= font
->ascent
+ boff
;
1935 it
->descent
= it
->phys_descent
= font
->descent
- boff
;
1937 if (face
->box
!= FACE_NO_BOX
1938 && face
->box_line_width
> 0)
1940 it
->ascent
+= face
->box_line_width
;
1941 it
->descent
+= face
->box_line_width
;
1944 else if (it
->char_to_display
== '\t')
1946 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
1947 int x
= it
->current_x
+ it
->continuation_lines_width
;
1948 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
1950 /* If the distance from the current position to the next tab
1951 stop is less than a canonical character width, use the
1952 tab stop after that. */
1953 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
1954 next_tab_x
+= tab_width
;
1956 it
->pixel_width
= next_tab_x
- x
;
1958 it
->ascent
= it
->phys_ascent
= font
->ascent
+ boff
;
1959 it
->descent
= it
->phys_descent
= font
->descent
- boff
;
1963 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
1964 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
1965 it
->ascent
+ it
->descent
, ascent
);
1970 /* A multi-byte character. Assume that the display width of the
1971 character is the width of the character multiplied by the
1972 width of the font. */
1974 /* If we found a font, this font should give us the right
1975 metrics. If we didn't find a font, use the frame's
1976 default font and calculate the width of the character
1977 from the charset width; this is what old redisplay code
1979 pcm
= x_per_char_metric (font
, &char2b
);
1980 if (font_not_found_p
|| !pcm
)
1982 int charset
= CHAR_CHARSET (it
->char_to_display
);
1984 it
->glyph_not_available_p
= 1;
1985 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
1986 * CHARSET_WIDTH (charset
));
1987 it
->phys_ascent
= font
->ascent
+ boff
;
1988 it
->phys_descent
= font
->descent
- boff
;
1992 it
->pixel_width
= pcm
->width
;
1993 it
->phys_ascent
= pcm
->ascent
+ boff
;
1994 it
->phys_descent
= pcm
->descent
- boff
;
1996 && (pcm
->lbearing
< 0
1997 || pcm
->rbearing
> pcm
->width
))
1998 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2001 it
->ascent
= font
->ascent
+ boff
;
2002 it
->descent
= font
->descent
- boff
;
2003 if (face
->box
!= FACE_NO_BOX
)
2005 int thick
= face
->box_line_width
;
2009 it
->ascent
+= thick
;
2010 it
->descent
+= thick
;
2015 if (it
->start_of_box_run_p
)
2016 it
->pixel_width
+= thick
;
2017 if (it
->end_of_box_run_p
)
2018 it
->pixel_width
+= thick
;
2021 /* If face has an overline, add the height of the overline
2022 (1 pixel) and a 1 pixel margin to the character height. */
2023 if (face
->overline_p
)
2026 take_vertical_position_into_account (it
);
2029 x_append_glyph (it
);
2031 it
->multibyte_p
= saved_multibyte_p
;
2033 else if (it
->what
== IT_COMPOSITION
)
2035 /* Note: A composition is represented as one glyph in the
2036 glyph matrix. There are no padding glyphs. */
2039 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2041 int font_not_found_p
;
2042 struct font_info
*font_info
;
2043 int boff
; /* baseline offset */
2044 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2046 /* Maybe translate single-byte characters to multibyte. */
2047 it
->char_to_display
= it
->c
;
2048 if (unibyte_display_via_language_environment
2049 && SINGLE_BYTE_CHAR_P (it
->c
)
2052 && !NILP (Vnonascii_translation_table
))))
2054 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2057 /* Get face and font to use. Encode IT->char_to_display. */
2058 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2059 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2060 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2061 it
->face_id
, &char2b
, it
->multibyte_p
);
2064 /* When no suitable font found, use the default font. */
2065 font_not_found_p
= font
== NULL
;
2066 if (font_not_found_p
)
2068 font
= FRAME_FONT (it
->f
);
2069 boff
= it
->f
->output_data
.x
->baseline_offset
;
2074 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2075 boff
= font_info
->baseline_offset
;
2076 if (font_info
->vertical_centering
)
2077 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2080 /* There are no padding glyphs, so there is only one glyph to
2081 produce for the composition. Important is that pixel_width,
2082 ascent and descent are the values of what is drawn by
2083 draw_glyphs (i.e. the values of the overall glyphs composed). */
2086 /* If we have not yet calculated pixel size data of glyphs of
2087 the composition for the current face font, calculate them
2088 now. Theoretically, we have to check all fonts for the
2089 glyphs, but that requires much time and memory space. So,
2090 here we check only the font of the first glyph. This leads
2091 to incorrect display very rarely, and C-l (recenter) can
2092 correct the display anyway. */
2093 if (cmp
->font
!= (void *) font
)
2095 /* Ascent and descent of the font of the first character of
2096 this composition (adjusted by baseline offset). Ascent
2097 and descent of overall glyphs should not be less than
2098 them respectively. */
2099 int font_ascent
= font
->ascent
+ boff
;
2100 int font_descent
= font
->descent
- boff
;
2101 /* Bounding box of the overall glyphs. */
2102 int leftmost
, rightmost
, lowest
, highest
;
2103 int i
, width
, ascent
, descent
;
2105 cmp
->font
= (void *) font
;
2107 /* Initialize the bounding box. */
2109 && (pcm
= x_per_char_metric (font
, &char2b
)))
2112 ascent
= pcm
->ascent
;
2113 descent
= pcm
->descent
;
2117 width
= FONT_WIDTH (font
);
2118 ascent
= font
->ascent
;
2119 descent
= font
->descent
;
2123 lowest
= - descent
+ boff
;
2124 highest
= ascent
+ boff
;
2128 && font_info
->default_ascent
2129 && CHAR_TABLE_P (Vuse_default_ascent
)
2130 && !NILP (Faref (Vuse_default_ascent
,
2131 make_number (it
->char_to_display
))))
2132 highest
= font_info
->default_ascent
+ boff
;
2134 /* Draw the first glyph at the normal position. It may be
2135 shifted to right later if some other glyphs are drawn at
2137 cmp
->offsets
[0] = 0;
2138 cmp
->offsets
[1] = boff
;
2140 /* Set cmp->offsets for the remaining glyphs. */
2141 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2143 int left
, right
, btm
, top
;
2144 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2145 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2147 face
= FACE_FROM_ID (it
->f
, face_id
);
2148 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2153 font
= FRAME_FONT (it
->f
);
2154 boff
= it
->f
->output_data
.x
->baseline_offset
;
2160 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2161 boff
= font_info
->baseline_offset
;
2162 if (font_info
->vertical_centering
)
2163 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2167 && (pcm
= x_per_char_metric (font
, &char2b
)))
2170 ascent
= pcm
->ascent
;
2171 descent
= pcm
->descent
;
2175 width
= FONT_WIDTH (font
);
2180 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2182 /* Relative composition with or without
2184 left
= (leftmost
+ rightmost
- width
) / 2;
2185 btm
= - descent
+ boff
;
2186 if (font_info
&& font_info
->relative_compose
2187 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2188 || NILP (Faref (Vignore_relative_composition
,
2189 make_number (ch
)))))
2192 if (- descent
>= font_info
->relative_compose
)
2193 /* One extra pixel between two glyphs. */
2195 else if (ascent
<= 0)
2196 /* One extra pixel between two glyphs. */
2197 btm
= lowest
- 1 - ascent
- descent
;
2202 /* A composition rule is specified by an integer
2203 value that encodes global and new reference
2204 points (GREF and NREF). GREF and NREF are
2205 specified by numbers as below:
2213 ---3---4---5--- baseline
2215 6---7---8 -- descent
2217 int rule
= COMPOSITION_RULE (cmp
, i
);
2218 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2220 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2221 grefx
= gref
% 3, nrefx
= nref
% 3;
2222 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2225 + grefx
* (rightmost
- leftmost
) / 2
2226 - nrefx
* width
/ 2);
2227 btm
= ((grefy
== 0 ? highest
2229 : grefy
== 2 ? lowest
2230 : (highest
+ lowest
) / 2)
2231 - (nrefy
== 0 ? ascent
+ descent
2232 : nrefy
== 1 ? descent
- boff
2234 : (ascent
+ descent
) / 2));
2237 cmp
->offsets
[i
* 2] = left
;
2238 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2240 /* Update the bounding box of the overall glyphs. */
2241 right
= left
+ width
;
2242 top
= btm
+ descent
+ ascent
;
2243 if (left
< leftmost
)
2245 if (right
> rightmost
)
2253 /* If there are glyphs whose x-offsets are negative,
2254 shift all glyphs to the right and make all x-offsets
2258 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2259 cmp
->offsets
[i
* 2] -= leftmost
;
2260 rightmost
-= leftmost
;
2263 cmp
->pixel_width
= rightmost
;
2264 cmp
->ascent
= highest
;
2265 cmp
->descent
= - lowest
;
2266 if (cmp
->ascent
< font_ascent
)
2267 cmp
->ascent
= font_ascent
;
2268 if (cmp
->descent
< font_descent
)
2269 cmp
->descent
= font_descent
;
2272 it
->pixel_width
= cmp
->pixel_width
;
2273 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2274 it
->descent
= it
->phys_descent
= cmp
->descent
;
2276 if (face
->box
!= FACE_NO_BOX
)
2278 int thick
= face
->box_line_width
;
2282 it
->ascent
+= thick
;
2283 it
->descent
+= thick
;
2288 if (it
->start_of_box_run_p
)
2289 it
->pixel_width
+= thick
;
2290 if (it
->end_of_box_run_p
)
2291 it
->pixel_width
+= thick
;
2294 /* If face has an overline, add the height of the overline
2295 (1 pixel) and a 1 pixel margin to the character height. */
2296 if (face
->overline_p
)
2299 take_vertical_position_into_account (it
);
2302 x_append_composite_glyph (it
);
2304 else if (it
->what
== IT_IMAGE
)
2305 x_produce_image_glyph (it
);
2306 else if (it
->what
== IT_STRETCH
)
2307 x_produce_stretch_glyph (it
);
2309 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2310 because this isn't true for images with `:ascent 100'. */
2311 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
2312 if (it
->area
== TEXT_AREA
)
2313 it
->current_x
+= it
->pixel_width
;
2315 it
->descent
+= it
->extra_line_spacing
;
2317 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2318 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2319 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2320 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2324 /* Estimate the pixel height of the mode or top line on frame F.
2325 FACE_ID specifies what line's height to estimate. */
2328 x_estimate_mode_line_height (f
, face_id
)
2330 enum face_id face_id
;
2332 int height
= FONT_HEIGHT (FRAME_FONT (f
));
2334 /* This function is called so early when Emacs starts that the face
2335 cache and mode line face are not yet initialized. */
2336 if (FRAME_FACE_CACHE (f
))
2338 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2342 height
= FONT_HEIGHT (face
->font
);
2343 if (face
->box_line_width
> 0)
2344 height
+= 2 * face
->box_line_width
;
2352 /***********************************************************************
2354 ***********************************************************************/
2356 /* A sequence of glyphs to be drawn in the same face.
2358 This data structure is not really completely X specific, so it
2359 could possibly, at least partially, be useful for other systems. It
2360 is currently not part of the external redisplay interface because
2361 it's not clear what other systems will need. */
2365 /* X-origin of the string. */
2368 /* Y-origin and y-position of the base line of this string. */
2371 /* The width of the string, not including a face extension. */
2374 /* The width of the string, including a face extension. */
2375 int background_width
;
2377 /* The height of this string. This is the height of the line this
2378 string is drawn in, and can be different from the height of the
2379 font the string is drawn in. */
2382 /* Number of pixels this string overwrites in front of its x-origin.
2383 This number is zero if the string has an lbearing >= 0; it is
2384 -lbearing, if the string has an lbearing < 0. */
2387 /* Number of pixels this string overwrites past its right-most
2388 nominal x-position, i.e. x + width. Zero if the string's
2389 rbearing is <= its nominal width, rbearing - width otherwise. */
2392 /* The frame on which the glyph string is drawn. */
2395 /* The window on which the glyph string is drawn. */
2398 /* X display and window for convenience. */
2402 /* The glyph row for which this string was built. It determines the
2403 y-origin and height of the string. */
2404 struct glyph_row
*row
;
2406 /* The area within row. */
2407 enum glyph_row_area area
;
2409 /* Characters to be drawn, and number of characters. */
2413 /* A face-override for drawing cursors, mouse face and similar. */
2414 enum draw_glyphs_face hl
;
2416 /* Face in which this string is to be drawn. */
2419 /* Font in which this string is to be drawn. */
2422 /* Font info for this string. */
2423 struct font_info
*font_info
;
2425 /* Non-null means this string describes (part of) a composition.
2426 All characters from char2b are drawn composed. */
2427 struct composition
*cmp
;
2429 /* Index of this glyph string's first character in the glyph
2430 definition of CMP. If this is zero, this glyph string describes
2431 the first character of a composition. */
2434 /* 1 means this glyph strings face has to be drawn to the right end
2435 of the window's drawing area. */
2436 unsigned extends_to_end_of_line_p
: 1;
2438 /* 1 means the background of this string has been drawn. */
2439 unsigned background_filled_p
: 1;
2441 /* 1 means glyph string must be drawn with 16-bit functions. */
2442 unsigned two_byte_p
: 1;
2444 /* 1 means that the original font determined for drawing this glyph
2445 string could not be loaded. The member `font' has been set to
2446 the frame's default font in this case. */
2447 unsigned font_not_found_p
: 1;
2449 /* 1 means that the face in which this glyph string is drawn has a
2451 unsigned stippled_p
: 1;
2453 /* 1 means only the foreground of this glyph string must be drawn,
2454 and we should use the physical height of the line this glyph
2455 string appears in as clip rect. */
2456 unsigned for_overlaps_p
: 1;
2458 /* The GC to use for drawing this glyph string. */
2461 /* A pointer to the first glyph in the string. This glyph
2462 corresponds to char2b[0]. Needed to draw rectangles if
2463 font_not_found_p is 1. */
2464 struct glyph
*first_glyph
;
2466 /* Image, if any. */
2469 struct glyph_string
*next
, *prev
;
2476 x_dump_glyph_string (s
)
2477 struct glyph_string
*s
;
2479 fprintf (stderr
, "glyph string\n");
2480 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2481 s
->x
, s
->y
, s
->width
, s
->height
);
2482 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2483 fprintf (stderr
, " hl = %d\n", s
->hl
);
2484 fprintf (stderr
, " left overhang = %d, right = %d\n",
2485 s
->left_overhang
, s
->right_overhang
);
2486 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2487 fprintf (stderr
, " extends to end of line = %d\n",
2488 s
->extends_to_end_of_line_p
);
2489 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2490 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2493 #endif /* GLYPH_DEBUG */
2497 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2498 struct glyph_string
**,
2499 struct glyph_string
*,
2500 struct glyph_string
*));
2501 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2502 struct glyph_string
**,
2503 struct glyph_string
*,
2504 struct glyph_string
*));
2505 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2506 struct glyph_string
**,
2507 struct glyph_string
*));
2508 static int x_left_overwritten
P_ ((struct glyph_string
*));
2509 static int x_left_overwriting
P_ ((struct glyph_string
*));
2510 static int x_right_overwritten
P_ ((struct glyph_string
*));
2511 static int x_right_overwriting
P_ ((struct glyph_string
*));
2512 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int, int,
2514 static void x_init_glyph_string
P_ ((struct glyph_string
*,
2515 XChar2b
*, struct window
*,
2517 enum glyph_row_area
, int,
2518 enum draw_glyphs_face
));
2519 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2520 enum glyph_row_area
, int, int,
2521 enum draw_glyphs_face
, int));
2522 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2523 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2524 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2526 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2527 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2528 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2529 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2530 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2531 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2532 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2533 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2534 static void x_get_glyph_overhangs
P_ ((struct glyph
*, struct frame
*,
2536 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2537 static int x_alloc_lighter_color
P_ ((struct frame
*, Display
*, Colormap
,
2538 unsigned long *, double, int));
2539 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2540 double, int, unsigned long));
2541 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2542 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2543 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2544 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2545 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
2546 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2547 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2549 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2550 int, int, int, int, XRectangle
*));
2551 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2552 int, int, int, XRectangle
*));
2553 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2554 enum glyph_row_area
));
2555 static int x_fill_stretch_glyph_string
P_ ((struct glyph_string
*,
2557 enum glyph_row_area
, int, int));
2560 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
2564 /* Append the list of glyph strings with head H and tail T to the list
2565 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2568 x_append_glyph_string_lists (head
, tail
, h
, t
)
2569 struct glyph_string
**head
, **tail
;
2570 struct glyph_string
*h
, *t
;
2584 /* Prepend the list of glyph strings with head H and tail T to the
2585 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2589 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
2590 struct glyph_string
**head
, **tail
;
2591 struct glyph_string
*h
, *t
;
2605 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2606 Set *HEAD and *TAIL to the resulting list. */
2609 x_append_glyph_string (head
, tail
, s
)
2610 struct glyph_string
**head
, **tail
;
2611 struct glyph_string
*s
;
2613 s
->next
= s
->prev
= NULL
;
2614 x_append_glyph_string_lists (head
, tail
, s
, s
);
2618 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2623 struct glyph_string
*s
;
2625 if (s
->font
== FRAME_FONT (s
->f
)
2626 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2627 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2629 s
->gc
= s
->f
->output_data
.x
->cursor_gc
;
2632 /* Cursor on non-default face: must merge. */
2636 xgcv
.background
= s
->f
->output_data
.x
->cursor_pixel
;
2637 xgcv
.foreground
= s
->face
->background
;
2639 /* If the glyph would be invisible, try a different foreground. */
2640 if (xgcv
.foreground
== xgcv
.background
)
2641 xgcv
.foreground
= s
->face
->foreground
;
2642 if (xgcv
.foreground
== xgcv
.background
)
2643 xgcv
.foreground
= s
->f
->output_data
.x
->cursor_foreground_pixel
;
2644 if (xgcv
.foreground
== xgcv
.background
)
2645 xgcv
.foreground
= s
->face
->foreground
;
2647 /* Make sure the cursor is distinct from text in this face. */
2648 if (xgcv
.background
== s
->face
->background
2649 && xgcv
.foreground
== s
->face
->foreground
)
2651 xgcv
.background
= s
->face
->foreground
;
2652 xgcv
.foreground
= s
->face
->background
;
2655 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2656 xgcv
.font
= s
->font
->fid
;
2657 xgcv
.graphics_exposures
= False
;
2658 mask
= GCForeground
| GCBackground
| GCFont
| GCGraphicsExposures
;
2660 if (FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2661 XChangeGC (s
->display
, FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2664 FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2665 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
2667 s
->gc
= FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2672 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2675 x_set_mouse_face_gc (s
)
2676 struct glyph_string
*s
;
2681 /* What face has to be used last for the mouse face? */
2682 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2683 face
= FACE_FROM_ID (s
->f
, face_id
);
2685 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
2687 if (s
->first_glyph
->type
== CHAR_GLYPH
)
2688 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2690 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
2691 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2692 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2694 /* If font in this face is same as S->font, use it. */
2695 if (s
->font
== s
->face
->font
)
2696 s
->gc
= s
->face
->gc
;
2699 /* Otherwise construct scratch_cursor_gc with values from FACE
2704 xgcv
.background
= s
->face
->background
;
2705 xgcv
.foreground
= s
->face
->foreground
;
2706 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2707 xgcv
.font
= s
->font
->fid
;
2708 xgcv
.graphics_exposures
= False
;
2709 mask
= GCForeground
| GCBackground
| GCFont
| GCGraphicsExposures
;
2711 if (FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2712 XChangeGC (s
->display
, FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2715 FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2716 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
2718 s
->gc
= FRAME_X_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2721 xassert (s
->gc
!= 0);
2725 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2726 Faces to use in the mode line have already been computed when the
2727 matrix was built, so there isn't much to do, here. */
2730 x_set_mode_line_face_gc (s
)
2731 struct glyph_string
*s
;
2733 s
->gc
= s
->face
->gc
;
2737 /* Set S->gc of glyph string S for drawing that glyph string. Set
2738 S->stippled_p to a non-zero value if the face of S has a stipple
2742 x_set_glyph_string_gc (s
)
2743 struct glyph_string
*s
;
2745 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2747 if (s
->hl
== DRAW_NORMAL_TEXT
)
2749 s
->gc
= s
->face
->gc
;
2750 s
->stippled_p
= s
->face
->stipple
!= 0;
2752 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
2754 x_set_mode_line_face_gc (s
);
2755 s
->stippled_p
= s
->face
->stipple
!= 0;
2757 else if (s
->hl
== DRAW_CURSOR
)
2759 x_set_cursor_gc (s
);
2762 else if (s
->hl
== DRAW_MOUSE_FACE
)
2764 x_set_mouse_face_gc (s
);
2765 s
->stippled_p
= s
->face
->stipple
!= 0;
2767 else if (s
->hl
== DRAW_IMAGE_RAISED
2768 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2770 s
->gc
= s
->face
->gc
;
2771 s
->stippled_p
= s
->face
->stipple
!= 0;
2775 s
->gc
= s
->face
->gc
;
2776 s
->stippled_p
= s
->face
->stipple
!= 0;
2779 /* GC must have been set. */
2780 xassert (s
->gc
!= 0);
2784 /* Return in *R the clipping rectangle for glyph string S. */
2787 x_get_glyph_string_clip_rect (s
, r
)
2788 struct glyph_string
*s
;
2791 if (s
->row
->full_width_p
)
2793 /* Draw full-width. X coordinates are relative to S->w->left. */
2794 int canon_x
= CANON_X_UNIT (s
->f
);
2796 r
->x
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
2797 r
->width
= XFASTINT (s
->w
->width
) * canon_x
;
2799 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
2801 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
2802 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
2806 r
->x
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
2808 /* Unless displaying a mode or menu bar line, which are always
2809 fully visible, clip to the visible part of the row. */
2810 if (s
->w
->pseudo_window_p
)
2811 r
->height
= s
->row
->visible_height
;
2813 r
->height
= s
->height
;
2817 /* This is a text line that may be partially visible. */
2818 r
->x
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
2819 r
->width
= window_box_width (s
->w
, s
->area
);
2820 r
->height
= s
->row
->visible_height
;
2823 /* If S draws overlapping rows, it's sufficient to use the top and
2824 bottom of the window for clipping because this glyph string
2825 intentionally draws over other lines. */
2826 if (s
->for_overlaps_p
)
2828 r
->y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2829 r
->height
= window_text_bottom_y (s
->w
) - r
->y
;
2833 /* Don't use S->y for clipping because it doesn't take partially
2834 visible lines into account. For example, it can be negative for
2835 partially visible lines at the top of a window. */
2836 if (!s
->row
->full_width_p
2837 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
2838 r
->y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
2840 r
->y
= max (0, s
->row
->y
);
2842 /* If drawing a tool-bar window, draw it over the internal border
2843 at the top of the window. */
2844 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
2845 r
->y
-= s
->f
->output_data
.x
->internal_border_width
;
2848 r
->y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->y
);
2852 /* Set clipping for output of glyph string S. S may be part of a mode
2853 line or menu if we don't have X toolkit support. */
2856 x_set_glyph_string_clipping (s
)
2857 struct glyph_string
*s
;
2860 x_get_glyph_string_clip_rect (s
, &r
);
2861 XSetClipRectangles (s
->display
, s
->gc
, 0, 0, &r
, 1, Unsorted
);
2865 /* Compute left and right overhang of glyph string S. If S is a glyph
2866 string for a composition, assume overhangs don't exist. */
2869 x_compute_glyph_string_overhangs (s
)
2870 struct glyph_string
*s
;
2873 && s
->first_glyph
->type
== CHAR_GLYPH
)
2876 int direction
, font_ascent
, font_descent
;
2877 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
2878 &font_ascent
, &font_descent
, &cs
);
2879 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
2880 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
2885 /* Compute overhangs and x-positions for glyph string S and its
2886 predecessors, or successors. X is the starting x-position for S.
2887 BACKWARD_P non-zero means process predecessors. */
2890 x_compute_overhangs_and_x (s
, x
, backward_p
)
2891 struct glyph_string
*s
;
2899 x_compute_glyph_string_overhangs (s
);
2909 x_compute_glyph_string_overhangs (s
);
2918 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
2919 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
2920 assumed to be zero. */
2923 x_get_glyph_overhangs (glyph
, f
, left
, right
)
2924 struct glyph
*glyph
;
2930 if (glyph
->type
== CHAR_GLYPH
)
2934 struct font_info
*font_info
;
2938 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
2940 font_info
= FONT_INFO_FROM_ID (f
, face
->font_info_id
);
2942 && (pcm
= x_per_char_metric (font
, &char2b
)))
2944 if (pcm
->rbearing
> pcm
->width
)
2945 *right
= pcm
->rbearing
- pcm
->width
;
2946 if (pcm
->lbearing
< 0)
2947 *left
= -pcm
->lbearing
;
2953 /* Return the index of the first glyph preceding glyph string S that
2954 is overwritten by S because of S's left overhang. Value is -1
2955 if no glyphs are overwritten. */
2958 x_left_overwritten (s
)
2959 struct glyph_string
*s
;
2963 if (s
->left_overhang
)
2966 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2967 int first
= s
->first_glyph
- glyphs
;
2969 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
2970 x
-= glyphs
[i
].pixel_width
;
2981 /* Return the index of the first glyph preceding glyph string S that
2982 is overwriting S because of its right overhang. Value is -1 if no
2983 glyph in front of S overwrites S. */
2986 x_left_overwriting (s
)
2987 struct glyph_string
*s
;
2990 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
2991 int first
= s
->first_glyph
- glyphs
;
2995 for (i
= first
- 1; i
>= 0; --i
)
2998 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3001 x
-= glyphs
[i
].pixel_width
;
3008 /* Return the index of the last glyph following glyph string S that is
3009 not overwritten by S because of S's right overhang. Value is -1 if
3010 no such glyph is found. */
3013 x_right_overwritten (s
)
3014 struct glyph_string
*s
;
3018 if (s
->right_overhang
)
3021 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3022 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3023 int end
= s
->row
->used
[s
->area
];
3025 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3026 x
+= glyphs
[i
].pixel_width
;
3035 /* Return the index of the last glyph following glyph string S that
3036 overwrites S because of its left overhang. Value is negative
3037 if no such glyph is found. */
3040 x_right_overwriting (s
)
3041 struct glyph_string
*s
;
3044 int end
= s
->row
->used
[s
->area
];
3045 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3046 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3050 for (i
= first
; i
< end
; ++i
)
3053 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3056 x
+= glyphs
[i
].pixel_width
;
3063 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3066 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3067 struct glyph_string
*s
;
3071 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
, &xgcv
);
3072 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
3073 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
3074 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3078 /* Draw the background of glyph_string S. If S->background_filled_p
3079 is non-zero don't draw it. FORCE_P non-zero means draw the
3080 background even if it wouldn't be drawn normally. This is used
3081 when a string preceding S draws into the background of S, or S
3082 contains the first component of a composition. */
3085 x_draw_glyph_string_background (s
, force_p
)
3086 struct glyph_string
*s
;
3089 /* Nothing to do if background has already been drawn or if it
3090 shouldn't be drawn in the first place. */
3091 if (!s
->background_filled_p
)
3093 int box_line_width
= max (s
->face
->box_line_width
, 0);
3097 /* Fill background with a stipple pattern. */
3098 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3099 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3100 s
->y
+ box_line_width
,
3101 s
->background_width
,
3102 s
->height
- 2 * box_line_width
);
3103 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3104 s
->background_filled_p
= 1;
3106 else if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
3107 || s
->font_not_found_p
3108 || s
->extends_to_end_of_line_p
3111 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
3112 s
->background_width
,
3113 s
->height
- 2 * box_line_width
);
3114 s
->background_filled_p
= 1;
3120 /* Draw the foreground of glyph string S. */
3123 x_draw_glyph_string_foreground (s
)
3124 struct glyph_string
*s
;
3128 /* If first glyph of S has a left box line, start drawing the text
3129 of S to the right of that box line. */
3130 if (s
->face
->box
!= FACE_NO_BOX
3131 && s
->first_glyph
->left_box_line_p
)
3132 x
= s
->x
+ abs (s
->face
->box_line_width
);
3136 /* Draw characters of S as rectangles if S's font could not be
3138 if (s
->font_not_found_p
)
3140 for (i
= 0; i
< s
->nchars
; ++i
)
3142 struct glyph
*g
= s
->first_glyph
+ i
;
3143 XDrawRectangle (s
->display
, s
->window
,
3144 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3146 x
+= g
->pixel_width
;
3151 char *char1b
= (char *) s
->char2b
;
3152 int boff
= s
->font_info
->baseline_offset
;
3154 if (s
->font_info
->vertical_centering
)
3155 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3157 /* If we can use 8-bit functions, condense S->char2b. */
3159 for (i
= 0; i
< s
->nchars
; ++i
)
3160 char1b
[i
] = s
->char2b
[i
].byte2
;
3162 /* Draw text with XDrawString if background has already been
3163 filled. Otherwise, use XDrawImageString. (Note that
3164 XDrawImageString is usually faster than XDrawString.) Always
3165 use XDrawImageString when drawing the cursor so that there is
3166 no chance that characters under a box cursor are invisible. */
3167 if (s
->for_overlaps_p
3168 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3170 /* Draw characters with 16-bit or 8-bit functions. */
3172 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
3173 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3175 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
3176 s
->ybase
- boff
, char1b
, s
->nchars
);
3181 XDrawImageString16 (s
->display
, s
->window
, s
->gc
, x
,
3182 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3184 XDrawImageString (s
->display
, s
->window
, s
->gc
, x
,
3185 s
->ybase
- boff
, char1b
, s
->nchars
);
3190 /* Draw the foreground of composite glyph string S. */
3193 x_draw_composite_glyph_string_foreground (s
)
3194 struct glyph_string
*s
;
3198 /* If first glyph of S has a left box line, start drawing the text
3199 of S to the right of that box line. */
3200 if (s
->face
->box
!= FACE_NO_BOX
3201 && s
->first_glyph
->left_box_line_p
)
3202 x
= s
->x
+ abs (s
->face
->box_line_width
);
3206 /* S is a glyph string for a composition. S->gidx is the index of
3207 the first character drawn for glyphs of this composition.
3208 S->gidx == 0 means we are drawing the very first character of
3209 this composition. */
3211 /* Draw a rectangle for the composition if the font for the very
3212 first character of the composition could not be loaded. */
3213 if (s
->font_not_found_p
)
3216 XDrawRectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
3217 s
->width
- 1, s
->height
- 1);
3221 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3222 XDrawString16 (s
->display
, s
->window
, s
->gc
,
3223 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3224 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3230 #ifdef USE_X_TOOLKIT
3232 static struct frame
*x_frame_of_widget
P_ ((Widget
));
3233 static Boolean cvt_string_to_pixel
P_ ((Display
*, XrmValue
*, Cardinal
*,
3234 XrmValue
*, XrmValue
*, XtPointer
*));
3235 static void cvt_pixel_dtor
P_ ((XtAppContext
, XrmValue
*, XtPointer
,
3236 XrmValue
*, Cardinal
*));
3239 /* Return the frame on which widget WIDGET is used.. Abort if frame
3240 cannot be determined. */
3242 static struct frame
*
3243 x_frame_of_widget (widget
)
3246 struct x_display_info
*dpyinfo
;
3250 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
3252 /* Find the top-level shell of the widget. Note that this function
3253 can be called when the widget is not yet realized, so XtWindow
3254 (widget) == 0. That's the reason we can't simply use
3255 x_any_window_to_frame. */
3256 while (!XtIsTopLevelShell (widget
))
3257 widget
= XtParent (widget
);
3259 /* Look for a frame with that top-level widget. Allocate the color
3260 on that frame to get the right gamma correction value. */
3261 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
3262 if (GC_FRAMEP (XCAR (tail
))
3263 && (f
= XFRAME (XCAR (tail
)),
3264 (f
->output_data
.nothing
!= 1
3265 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
3266 && f
->output_data
.x
->widget
== widget
)
3273 /* Allocate the color COLOR->pixel on the screen and display of
3274 widget WIDGET in colormap CMAP. If an exact match cannot be
3275 allocated, try the nearest color available. Value is non-zero
3276 if successful. This is called from lwlib. */
3279 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
3284 struct frame
*f
= x_frame_of_widget (widget
);
3285 return x_alloc_nearest_color (f
, cmap
, color
);
3289 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
3290 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3291 If this produces the same color as PIXEL, try a color where all RGB
3292 values have DELTA added. Return the allocated color in *PIXEL.
3293 DISPLAY is the X display, CMAP is the colormap to operate on.
3294 Value is non-zero if successful. */
3297 x_alloc_lighter_color_for_widget (widget
, display
, cmap
, pixel
, factor
, delta
)
3301 unsigned long *pixel
;
3305 struct frame
*f
= x_frame_of_widget (widget
);
3306 return x_alloc_lighter_color (f
, display
, cmap
, pixel
, factor
, delta
);
3310 /* Structure specifying which arguments should be passed by Xt to
3311 cvt_string_to_pixel. We want the widget's screen and colormap. */
3313 static XtConvertArgRec cvt_string_to_pixel_args
[] =
3315 {XtWidgetBaseOffset
, (XtPointer
) XtOffset (Widget
, core
.screen
),
3317 {XtWidgetBaseOffset
, (XtPointer
) XtOffset (Widget
, core
.colormap
),
3322 /* The address of this variable is returned by
3323 cvt_string_to_pixel. */
3325 static Pixel cvt_string_to_pixel_value
;
3328 /* Convert a color name to a pixel color.
3330 DPY is the display we are working on.
3332 ARGS is an array of *NARGS XrmValue structures holding additional
3333 information about the widget for which the conversion takes place.
3334 The contents of this array are determined by the specification
3335 in cvt_string_to_pixel_args.
3337 FROM is a pointer to an XrmValue which points to the color name to
3338 convert. TO is an XrmValue in which to return the pixel color.
3340 CLOSURE_RET is a pointer to user-data, in which we record if
3341 we allocated the color or not.
3343 Value is True if successful, False otherwise. */
3346 cvt_string_to_pixel (dpy
, args
, nargs
, from
, to
, closure_ret
)
3350 XrmValue
*from
, *to
;
3351 XtPointer
*closure_ret
;
3361 XtAppWarningMsg (XtDisplayToApplicationContext (dpy
),
3362 "wrongParameters", "cvt_string_to_pixel",
3364 "Screen and colormap args required", NULL
, NULL
);
3368 screen
= *(Screen
**) args
[0].addr
;
3369 cmap
= *(Colormap
*) args
[1].addr
;
3370 color_name
= (String
) from
->addr
;
3372 if (strcmp (color_name
, XtDefaultBackground
) == 0)
3374 *closure_ret
= (XtPointer
) False
;
3375 pixel
= WhitePixelOfScreen (screen
);
3377 else if (strcmp (color_name
, XtDefaultForeground
) == 0)
3379 *closure_ret
= (XtPointer
) False
;
3380 pixel
= BlackPixelOfScreen (screen
);
3382 else if (XParseColor (dpy
, cmap
, color_name
, &color
)
3383 && x_alloc_nearest_color_1 (dpy
, cmap
, &color
))
3385 pixel
= color
.pixel
;
3386 *closure_ret
= (XtPointer
) True
;
3391 Cardinal nparams
= 1;
3393 params
[0] = color_name
;
3394 XtAppWarningMsg (XtDisplayToApplicationContext (dpy
),
3395 "badValue", "cvt_string_to_pixel",
3396 "XtToolkitError", "Invalid color `%s'",
3401 if (to
->addr
!= NULL
)
3403 if (to
->size
< sizeof (Pixel
))
3405 to
->size
= sizeof (Pixel
);
3409 *(Pixel
*) to
->addr
= pixel
;
3413 cvt_string_to_pixel_value
= pixel
;
3414 to
->addr
= (XtPointer
) &cvt_string_to_pixel_value
;
3417 to
->size
= sizeof (Pixel
);
3422 /* Free a pixel color which was previously allocated via
3423 cvt_string_to_pixel. This is registered as the destructor
3424 for this type of resource via XtSetTypeConverter.
3426 APP is the application context in which we work.
3428 TO is a pointer to an XrmValue holding the color to free.
3429 CLOSURE is the value we stored in CLOSURE_RET for this color
3430 in cvt_string_to_pixel.
3432 ARGS and NARGS are like for cvt_string_to_pixel. */
3435 cvt_pixel_dtor (app
, to
, closure
, args
, nargs
)
3444 XtAppWarningMsg (app
, "wrongParameters", "cvt_pixel_dtor",
3446 "Screen and colormap arguments required",
3449 else if (closure
!= NULL
)
3451 /* We did allocate the pixel, so free it. */
3452 Screen
*screen
= *(Screen
**) args
[0].addr
;
3453 Colormap cmap
= *(Colormap
*) args
[1].addr
;
3454 x_free_dpy_colors (DisplayOfScreen (screen
), screen
, cmap
,
3455 (Pixel
*) to
->addr
, 1);
3460 #endif /* USE_X_TOOLKIT */
3463 /* Value is an array of XColor structures for the contents of the
3464 color map of display DPY. Set *NCELLS to the size of the array.
3465 Note that this probably shouldn't be called for large color maps,
3466 say a 24-bit TrueColor map. */
3468 static const XColor
*
3469 x_color_cells (dpy
, ncells
)
3473 struct x_display_info
*dpyinfo
= x_display_info_for_display (dpy
);
3475 if (dpyinfo
->color_cells
== NULL
)
3477 Screen
*screen
= dpyinfo
->screen
;
3480 dpyinfo
->ncolor_cells
3481 = XDisplayCells (dpy
, XScreenNumberOfScreen (screen
));
3482 dpyinfo
->color_cells
3483 = (XColor
*) xmalloc (dpyinfo
->ncolor_cells
3484 * sizeof *dpyinfo
->color_cells
);
3486 for (i
= 0; i
< dpyinfo
->ncolor_cells
; ++i
)
3487 dpyinfo
->color_cells
[i
].pixel
= i
;
3489 XQueryColors (dpy
, dpyinfo
->cmap
,
3490 dpyinfo
->color_cells
, dpyinfo
->ncolor_cells
);
3493 *ncells
= dpyinfo
->ncolor_cells
;
3494 return dpyinfo
->color_cells
;
3498 /* On frame F, translate pixel colors to RGB values for the NCOLORS
3499 colors in COLORS. Use cached information, if available. */
3502 x_query_colors (f
, colors
, ncolors
)
3507 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3509 if (dpyinfo
->color_cells
)
3512 for (i
= 0; i
< ncolors
; ++i
)
3514 unsigned long pixel
= colors
[i
].pixel
;
3515 xassert (pixel
< dpyinfo
->ncolor_cells
);
3516 xassert (dpyinfo
->color_cells
[pixel
].pixel
== pixel
);
3517 colors
[i
] = dpyinfo
->color_cells
[pixel
];
3521 XQueryColors (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), colors
, ncolors
);
3525 /* On frame F, translate pixel color to RGB values for the color in
3526 COLOR. Use cached information, if available. */
3529 x_query_color (f
, color
)
3533 x_query_colors (f
, color
, 1);
3537 /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP. If an
3538 exact match can't be allocated, try the nearest color available.
3539 Value is non-zero if successful. Set *COLOR to the color
3543 x_alloc_nearest_color_1 (dpy
, cmap
, color
)
3550 rc
= XAllocColor (dpy
, cmap
, color
);
3553 /* If we got to this point, the colormap is full, so we're going
3554 to try to get the next closest color. The algorithm used is
3555 a least-squares matching, which is what X uses for closest
3556 color matching with StaticColor visuals. */
3558 unsigned long nearest_delta
= ~0;
3560 const XColor
*cells
= x_color_cells (dpy
, &ncells
);
3562 for (nearest
= i
= 0; i
< ncells
; ++i
)
3564 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
3565 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
3566 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
3567 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
3569 if (delta
< nearest_delta
)
3572 nearest_delta
= delta
;
3576 color
->red
= cells
[nearest
].red
;
3577 color
->green
= cells
[nearest
].green
;
3578 color
->blue
= cells
[nearest
].blue
;
3579 rc
= XAllocColor (dpy
, cmap
, color
);
3583 /* If allocation succeeded, and the allocated pixel color is not
3584 equal to a cached pixel color recorded earlier, there was a
3585 change in the colormap, so clear the color cache. */
3586 struct x_display_info
*dpyinfo
= x_display_info_for_display (dpy
);
3587 XColor
*cached_color
;
3589 if (dpyinfo
->color_cells
3590 && (cached_color
= &dpyinfo
->color_cells
[color
->pixel
],
3591 (cached_color
->red
!= color
->red
3592 || cached_color
->blue
!= color
->blue
3593 || cached_color
->green
!= color
->green
)))
3595 xfree (dpyinfo
->color_cells
);
3596 dpyinfo
->color_cells
= NULL
;
3597 dpyinfo
->ncolor_cells
= 0;
3601 #ifdef DEBUG_X_COLORS
3603 register_color (color
->pixel
);
3604 #endif /* DEBUG_X_COLORS */
3610 /* Allocate the color COLOR->pixel on frame F, colormap CMAP. If an
3611 exact match can't be allocated, try the nearest color available.
3612 Value is non-zero if successful. Set *COLOR to the color
3616 x_alloc_nearest_color (f
, cmap
, color
)
3621 gamma_correct (f
, color
);
3622 return x_alloc_nearest_color_1 (FRAME_X_DISPLAY (f
), cmap
, color
);
3626 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
3627 It's necessary to do this instead of just using PIXEL directly to
3628 get color reference counts right. */
3631 x_copy_color (f
, pixel
)
3633 unsigned long pixel
;
3637 color
.pixel
= pixel
;
3639 x_query_color (f
, &color
);
3640 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
3642 #ifdef DEBUG_X_COLORS
3643 register_color (pixel
);
3649 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
3650 It's necessary to do this instead of just using PIXEL directly to
3651 get color reference counts right. */
3654 x_copy_dpy_color (dpy
, cmap
, pixel
)
3657 unsigned long pixel
;
3661 color
.pixel
= pixel
;
3663 XQueryColor (dpy
, cmap
, &color
);
3664 XAllocColor (dpy
, cmap
, &color
);
3666 #ifdef DEBUG_X_COLORS
3667 register_color (pixel
);
3673 /* Brightness beyond which a color won't have its highlight brightness
3676 Nominally, highlight colors for `3d' faces are calculated by
3677 brightening an object's color by a constant scale factor, but this
3678 doesn't yield good results for dark colors, so for colors who's
3679 brightness is less than this value (on a scale of 0-65535) have an
3680 use an additional additive factor.
3682 The value here is set so that the default menu-bar/mode-line color
3683 (grey75) will not have its highlights changed at all. */
3684 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
3687 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
3688 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3689 If this produces the same color as PIXEL, try a color where all RGB
3690 values have DELTA added. Return the allocated color in *PIXEL.
3691 DISPLAY is the X display, CMAP is the colormap to operate on.
3692 Value is non-zero if successful. */
3695 x_alloc_lighter_color (f
, display
, cmap
, pixel
, factor
, delta
)
3699 unsigned long *pixel
;
3707 /* Get RGB color values. */
3708 color
.pixel
= *pixel
;
3709 x_query_color (f
, &color
);
3711 /* Change RGB values by specified FACTOR. Avoid overflow! */
3712 xassert (factor
>= 0);
3713 new.red
= min (0xffff, factor
* color
.red
);
3714 new.green
= min (0xffff, factor
* color
.green
);
3715 new.blue
= min (0xffff, factor
* color
.blue
);
3717 /* Calculate brightness of COLOR. */
3718 bright
= (2 * color
.red
+ 3 * color
.green
+ color
.blue
) / 6;
3720 /* We only boost colors that are darker than
3721 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
3722 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
3723 /* Make an additive adjustment to NEW, because it's dark enough so
3724 that scaling by FACTOR alone isn't enough. */
3726 /* How far below the limit this color is (0 - 1, 1 being darker). */
3727 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
3728 /* The additive adjustment. */
3729 int min_delta
= delta
* dimness
* factor
/ 2;
3733 new.red
= max (0, new.red
- min_delta
);
3734 new.green
= max (0, new.green
- min_delta
);
3735 new.blue
= max (0, new.blue
- min_delta
);
3739 new.red
= min (0xffff, min_delta
+ new.red
);
3740 new.green
= min (0xffff, min_delta
+ new.green
);
3741 new.blue
= min (0xffff, min_delta
+ new.blue
);
3745 /* Try to allocate the color. */
3746 success_p
= x_alloc_nearest_color (f
, cmap
, &new);
3749 if (new.pixel
== *pixel
)
3751 /* If we end up with the same color as before, try adding
3752 delta to the RGB values. */
3753 x_free_colors (f
, &new.pixel
, 1);
3755 new.red
= min (0xffff, delta
+ color
.red
);
3756 new.green
= min (0xffff, delta
+ color
.green
);
3757 new.blue
= min (0xffff, delta
+ color
.blue
);
3758 success_p
= x_alloc_nearest_color (f
, cmap
, &new);
3769 /* Set up the foreground color for drawing relief lines of glyph
3770 string S. RELIEF is a pointer to a struct relief containing the GC
3771 with which lines will be drawn. Use a color that is FACTOR or
3772 DELTA lighter or darker than the relief's background which is found
3773 in S->f->output_data.x->relief_background. If such a color cannot
3774 be allocated, use DEFAULT_PIXEL, instead. */
3777 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3779 struct relief
*relief
;
3782 unsigned long default_pixel
;
3785 struct x_output
*di
= f
->output_data
.x
;
3786 unsigned long mask
= GCForeground
| GCLineWidth
| GCGraphicsExposures
;
3787 unsigned long pixel
;
3788 unsigned long background
= di
->relief_background
;
3789 Colormap cmap
= FRAME_X_COLORMAP (f
);
3790 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
3791 Display
*dpy
= FRAME_X_DISPLAY (f
);
3793 xgcv
.graphics_exposures
= False
;
3794 xgcv
.line_width
= 1;
3796 /* Free previously allocated color. The color cell will be reused
3797 when it has been freed as many times as it was allocated, so this
3798 doesn't affect faces using the same colors. */
3800 && relief
->allocated_p
)
3802 x_free_colors (f
, &relief
->pixel
, 1);
3803 relief
->allocated_p
= 0;
3806 /* Allocate new color. */
3807 xgcv
.foreground
= default_pixel
;
3809 if (dpyinfo
->n_planes
!= 1
3810 && x_alloc_lighter_color (f
, dpy
, cmap
, &pixel
, factor
, delta
))
3812 relief
->allocated_p
= 1;
3813 xgcv
.foreground
= relief
->pixel
= pixel
;
3816 if (relief
->gc
== 0)
3818 xgcv
.stipple
= dpyinfo
->gray
;
3820 relief
->gc
= XCreateGC (dpy
, FRAME_X_WINDOW (f
), mask
, &xgcv
);
3823 XChangeGC (dpy
, relief
->gc
, mask
, &xgcv
);
3827 /* Set up colors for the relief lines around glyph string S. */
3830 x_setup_relief_colors (s
)
3831 struct glyph_string
*s
;
3833 struct x_output
*di
= s
->f
->output_data
.x
;
3834 unsigned long color
;
3836 if (s
->face
->use_box_color_for_shadows_p
)
3837 color
= s
->face
->box_color
;
3838 else if (s
->first_glyph
->type
== IMAGE_GLYPH
3839 && !IMAGE_BACKGROUND_TRANSPARENT (s
->img
, s
->f
, 0))
3840 color
= IMAGE_BACKGROUND (s
->img
, s
->f
, 0);
3845 /* Get the background color of the face. */
3846 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
3847 color
= xgcv
.background
;
3850 if (di
->white_relief
.gc
== 0
3851 || color
!= di
->relief_background
)
3853 di
->relief_background
= color
;
3854 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3855 WHITE_PIX_DEFAULT (s
->f
));
3856 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3857 BLACK_PIX_DEFAULT (s
->f
));
3862 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3863 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3864 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3865 relief. LEFT_P non-zero means draw a relief on the left side of
3866 the rectangle. RIGHT_P non-zero means draw a relief on the right
3867 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3871 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3872 raised_p
, left_p
, right_p
, clip_rect
)
3874 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
3875 XRectangle
*clip_rect
;
3877 Display
*dpy
= FRAME_X_DISPLAY (f
);
3878 Window window
= FRAME_X_WINDOW (f
);
3883 gc
= f
->output_data
.x
->white_relief
.gc
;
3885 gc
= f
->output_data
.x
->black_relief
.gc
;
3886 XSetClipRectangles (dpy
, gc
, 0, 0, clip_rect
, 1, Unsorted
);
3889 for (i
= 0; i
< width
; ++i
)
3890 XDrawLine (dpy
, window
, gc
,
3891 left_x
+ i
* left_p
, top_y
+ i
,
3892 right_x
+ 1 - i
* right_p
, top_y
+ i
);
3896 for (i
= 0; i
< width
; ++i
)
3897 XDrawLine (dpy
, window
, gc
,
3898 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
+ 1);
3900 XSetClipMask (dpy
, gc
, None
);
3902 gc
= f
->output_data
.x
->black_relief
.gc
;
3904 gc
= f
->output_data
.x
->white_relief
.gc
;
3905 XSetClipRectangles (dpy
, gc
, 0, 0, clip_rect
, 1, Unsorted
);
3908 for (i
= 0; i
< width
; ++i
)
3909 XDrawLine (dpy
, window
, gc
,
3910 left_x
+ i
* left_p
, bottom_y
- i
,
3911 right_x
+ 1 - i
* right_p
, bottom_y
- i
);
3915 for (i
= 0; i
< width
; ++i
)
3916 XDrawLine (dpy
, window
, gc
,
3917 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
);
3919 XSetClipMask (dpy
, gc
, None
);
3923 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3924 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3925 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3926 left side of the rectangle. RIGHT_P non-zero means draw a line
3927 on the right side of the rectangle. CLIP_RECT is the clipping
3928 rectangle to use when drawing. */
3931 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3932 left_p
, right_p
, clip_rect
)
3933 struct glyph_string
*s
;
3934 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
;
3935 XRectangle
*clip_rect
;
3939 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3940 XSetForeground (s
->display
, s
->gc
, s
->face
->box_color
);
3941 XSetClipRectangles (s
->display
, s
->gc
, 0, 0, clip_rect
, 1, Unsorted
);
3944 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3945 left_x
, top_y
, right_x
- left_x
+ 1, width
);
3949 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3950 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
3953 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3954 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
3958 XFillRectangle (s
->display
, s
->window
, s
->gc
,
3959 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
3961 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3962 XSetClipMask (s
->display
, s
->gc
, None
);
3966 /* Draw a box around glyph string S. */
3969 x_draw_glyph_string_box (s
)
3970 struct glyph_string
*s
;
3972 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3973 int left_p
, right_p
;
3974 struct glyph
*last_glyph
;
3975 XRectangle clip_rect
;
3977 last_x
= window_box_right (s
->w
, s
->area
);
3978 if (s
->row
->full_width_p
3979 && !s
->w
->pseudo_window_p
)
3981 last_x
+= FRAME_X_RIGHT_FRINGE_WIDTH (s
->f
);
3982 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
3983 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
3986 /* The glyph that may have a right box line. */
3987 last_glyph
= (s
->cmp
|| s
->img
3989 : s
->first_glyph
+ s
->nchars
- 1);
3991 width
= abs (s
->face
->box_line_width
);
3992 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3994 right_x
= (s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
3996 : min (last_x
, s
->x
+ s
->background_width
) - 1);
3998 bottom_y
= top_y
+ s
->height
- 1;
4000 left_p
= (s
->first_glyph
->left_box_line_p
4001 || (s
->hl
== DRAW_MOUSE_FACE
4003 || s
->prev
->hl
!= s
->hl
)));
4004 right_p
= (last_glyph
->right_box_line_p
4005 || (s
->hl
== DRAW_MOUSE_FACE
4007 || s
->next
->hl
!= s
->hl
)));
4009 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4011 if (s
->face
->box
== FACE_SIMPLE_BOX
)
4012 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
4013 left_p
, right_p
, &clip_rect
);
4016 x_setup_relief_colors (s
);
4017 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
4018 width
, raised_p
, left_p
, right_p
, &clip_rect
);
4023 /* Draw foreground of image glyph string S. */
4026 x_draw_image_foreground (s
)
4027 struct glyph_string
*s
;
4030 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4032 /* If first glyph of S has a left box line, start drawing it to the
4033 right of that line. */
4034 if (s
->face
->box
!= FACE_NO_BOX
4035 && s
->first_glyph
->left_box_line_p
)
4036 x
= s
->x
+ abs (s
->face
->box_line_width
);
4040 /* If there is a margin around the image, adjust x- and y-position
4042 x
+= s
->img
->hmargin
;
4043 y
+= s
->img
->vmargin
;
4049 /* We can't set both a clip mask and use XSetClipRectangles
4050 because the latter also sets a clip mask. We also can't
4051 trust on the shape extension to be available
4052 (XShapeCombineRegion). So, compute the rectangle to draw
4054 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4057 XRectangle clip_rect
, image_rect
, r
;
4059 xgcv
.clip_mask
= s
->img
->mask
;
4060 xgcv
.clip_x_origin
= x
;
4061 xgcv
.clip_y_origin
= y
;
4062 xgcv
.function
= GXcopy
;
4063 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4065 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4068 image_rect
.width
= s
->img
->width
;
4069 image_rect
.height
= s
->img
->height
;
4070 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
4071 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
4072 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
4076 XRectangle clip_rect
, image_rect
, r
;
4078 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4081 image_rect
.width
= s
->img
->width
;
4082 image_rect
.height
= s
->img
->height
;
4083 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
4084 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
4085 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
4087 /* When the image has a mask, we can expect that at
4088 least part of a mouse highlight or a block cursor will
4089 be visible. If the image doesn't have a mask, make
4090 a block cursor visible by drawing a rectangle around
4091 the image. I believe it's looking better if we do
4092 nothing here for mouse-face. */
4093 if (s
->hl
== DRAW_CURSOR
)
4094 XDrawRectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
4095 s
->img
->width
- 1, s
->img
->height
- 1);
4099 /* Draw a rectangle if image could not be loaded. */
4100 XDrawRectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
4101 s
->img
->width
- 1, s
->img
->height
- 1);
4105 /* Draw a relief around the image glyph string S. */
4108 x_draw_image_relief (s
)
4109 struct glyph_string
*s
;
4111 int x0
, y0
, x1
, y1
, thick
, raised_p
;
4114 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4116 /* If first glyph of S has a left box line, start drawing it to the
4117 right of that line. */
4118 if (s
->face
->box
!= FACE_NO_BOX
4119 && s
->first_glyph
->left_box_line_p
)
4120 x
= s
->x
+ abs (s
->face
->box_line_width
);
4124 /* If there is a margin around the image, adjust x- and y-position
4126 x
+= s
->img
->hmargin
;
4127 y
+= s
->img
->vmargin
;
4129 if (s
->hl
== DRAW_IMAGE_SUNKEN
4130 || s
->hl
== DRAW_IMAGE_RAISED
)
4132 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: 3;
4133 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
4137 thick
= abs (s
->img
->relief
);
4138 raised_p
= s
->img
->relief
> 0;
4143 x1
= x
+ s
->img
->width
+ thick
- 1;
4144 y1
= y
+ s
->img
->height
+ thick
- 1;
4146 x_setup_relief_colors (s
);
4147 x_get_glyph_string_clip_rect (s
, &r
);
4148 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
4152 /* Draw the foreground of image glyph string S to PIXMAP. */
4155 x_draw_image_foreground_1 (s
, pixmap
)
4156 struct glyph_string
*s
;
4160 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
4162 /* If first glyph of S has a left box line, start drawing it to the
4163 right of that line. */
4164 if (s
->face
->box
!= FACE_NO_BOX
4165 && s
->first_glyph
->left_box_line_p
)
4166 x
= abs (s
->face
->box_line_width
);
4170 /* If there is a margin around the image, adjust x- and y-position
4172 x
+= s
->img
->hmargin
;
4173 y
+= s
->img
->vmargin
;
4179 /* We can't set both a clip mask and use XSetClipRectangles
4180 because the latter also sets a clip mask. We also can't
4181 trust on the shape extension to be available
4182 (XShapeCombineRegion). So, compute the rectangle to draw
4184 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4188 xgcv
.clip_mask
= s
->img
->mask
;
4189 xgcv
.clip_x_origin
= x
;
4190 xgcv
.clip_y_origin
= y
;
4191 xgcv
.function
= GXcopy
;
4192 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4194 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4195 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4196 XSetClipMask (s
->display
, s
->gc
, None
);
4200 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4201 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4203 /* When the image has a mask, we can expect that at
4204 least part of a mouse highlight or a block cursor will
4205 be visible. If the image doesn't have a mask, make
4206 a block cursor visible by drawing a rectangle around
4207 the image. I believe it's looking better if we do
4208 nothing here for mouse-face. */
4209 if (s
->hl
== DRAW_CURSOR
)
4210 XDrawRectangle (s
->display
, pixmap
, s
->gc
, x
, y
,
4211 s
->img
->width
- 1, s
->img
->height
- 1);
4215 /* Draw a rectangle if image could not be loaded. */
4216 XDrawRectangle (s
->display
, pixmap
, s
->gc
, x
, y
,
4217 s
->img
->width
- 1, s
->img
->height
- 1);
4221 /* Draw part of the background of glyph string S. X, Y, W, and H
4222 give the rectangle to draw. */
4225 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
4226 struct glyph_string
*s
;
4231 /* Fill background with a stipple pattern. */
4232 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4233 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
4234 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4237 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
4241 /* Draw image glyph string S.
4244 s->x +-------------------------
4247 | +-------------------------
4250 | | +-------------------
4256 x_draw_image_glyph_string (s
)
4257 struct glyph_string
*s
;
4260 int box_line_hwidth
= abs (s
->face
->box_line_width
);
4261 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
4263 Pixmap pixmap
= None
;
4265 height
= s
->height
- 2 * box_line_vwidth
;
4267 /* Fill background with face under the image. Do it only if row is
4268 taller than image or if image has a clip mask to reduce
4270 s
->stippled_p
= s
->face
->stipple
!= 0;
4271 if (height
> s
->img
->height
4275 || s
->img
->pixmap
== 0
4276 || s
->width
!= s
->background_width
)
4278 if (box_line_hwidth
&& s
->first_glyph
->left_box_line_p
)
4279 x
= s
->x
+ box_line_hwidth
;
4283 y
= s
->y
+ box_line_vwidth
;
4287 /* Create a pixmap as large as the glyph string. Fill it
4288 with the background color. Copy the image to it, using
4289 its mask. Copy the temporary pixmap to the display. */
4290 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
4291 int depth
= DefaultDepthOfScreen (screen
);
4293 /* Create a pixmap as large as the glyph string. */
4294 pixmap
= XCreatePixmap (s
->display
, s
->window
,
4295 s
->background_width
,
4298 /* Don't clip in the following because we're working on the
4300 XSetClipMask (s
->display
, s
->gc
, None
);
4302 /* Fill the pixmap with the background color/stipple. */
4305 /* Fill background with a stipple pattern. */
4306 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4307 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4308 0, 0, s
->background_width
, s
->height
);
4309 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4314 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
4316 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
4317 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4318 0, 0, s
->background_width
, s
->height
);
4319 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4323 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
4325 s
->background_filled_p
= 1;
4328 /* Draw the foreground. */
4331 x_draw_image_foreground_1 (s
, pixmap
);
4332 x_set_glyph_string_clipping (s
);
4333 XCopyArea (s
->display
, pixmap
, s
->window
, s
->gc
,
4334 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
4335 XFreePixmap (s
->display
, pixmap
);
4338 x_draw_image_foreground (s
);
4340 /* If we must draw a relief around the image, do it. */
4342 || s
->hl
== DRAW_IMAGE_RAISED
4343 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4344 x_draw_image_relief (s
);
4348 /* Draw stretch glyph string S. */
4351 x_draw_stretch_glyph_string (s
)
4352 struct glyph_string
*s
;
4354 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4355 s
->stippled_p
= s
->face
->stipple
!= 0;
4357 if (s
->hl
== DRAW_CURSOR
4358 && !x_stretch_cursor_p
)
4360 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4361 as wide as the stretch glyph. */
4362 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4365 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4367 /* Clear rest using the GC of the original non-cursor face. */
4368 if (width
< s
->background_width
)
4370 int x
= s
->x
+ width
, y
= s
->y
;
4371 int w
= s
->background_width
- width
, h
= s
->height
;
4375 if (s
->row
->mouse_face_p
4376 && cursor_in_mouse_face_p (s
->w
))
4378 x_set_mouse_face_gc (s
);
4384 x_get_glyph_string_clip_rect (s
, &r
);
4385 XSetClipRectangles (s
->display
, gc
, 0, 0, &r
, 1, Unsorted
);
4387 if (s
->face
->stipple
)
4389 /* Fill background with a stipple pattern. */
4390 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4391 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4392 XSetFillStyle (s
->display
, gc
, FillSolid
);
4397 XGetGCValues (s
->display
, gc
, GCForeground
| GCBackground
, &xgcv
);
4398 XSetForeground (s
->display
, gc
, xgcv
.background
);
4399 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4400 XSetForeground (s
->display
, gc
, xgcv
.foreground
);
4404 else if (!s
->background_filled_p
)
4405 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4408 s
->background_filled_p
= 1;
4412 /* Draw glyph string S. */
4415 x_draw_glyph_string (s
)
4416 struct glyph_string
*s
;
4418 int relief_drawn_p
= 0;
4420 /* If S draws into the background of its successor, draw the
4421 background of the successor first so that S can draw into it.
4422 This makes S->next use XDrawString instead of XDrawImageString. */
4423 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4425 xassert (s
->next
->img
== NULL
);
4426 x_set_glyph_string_gc (s
->next
);
4427 x_set_glyph_string_clipping (s
->next
);
4428 x_draw_glyph_string_background (s
->next
, 1);
4431 /* Set up S->gc, set clipping and draw S. */
4432 x_set_glyph_string_gc (s
);
4434 /* Draw relief (if any) in advance for char/composition so that the
4435 glyph string can be drawn over it. */
4436 if (!s
->for_overlaps_p
4437 && s
->face
->box
!= FACE_NO_BOX
4438 && (s
->first_glyph
->type
== CHAR_GLYPH
4439 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
4442 x_set_glyph_string_clipping (s
);
4443 x_draw_glyph_string_background (s
, 1);
4444 x_draw_glyph_string_box (s
);
4445 x_set_glyph_string_clipping (s
);
4449 x_set_glyph_string_clipping (s
);
4451 switch (s
->first_glyph
->type
)
4454 x_draw_image_glyph_string (s
);
4458 x_draw_stretch_glyph_string (s
);
4462 if (s
->for_overlaps_p
)
4463 s
->background_filled_p
= 1;
4465 x_draw_glyph_string_background (s
, 0);
4466 x_draw_glyph_string_foreground (s
);
4469 case COMPOSITE_GLYPH
:
4470 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4471 s
->background_filled_p
= 1;
4473 x_draw_glyph_string_background (s
, 1);
4474 x_draw_composite_glyph_string_foreground (s
);
4481 if (!s
->for_overlaps_p
)
4483 /* Draw underline. */
4484 if (s
->face
->underline_p
)
4486 unsigned long tem
, h
;
4489 /* Get the underline thickness. Default is 1 pixel. */
4490 if (!XGetFontProperty (s
->font
, XA_UNDERLINE_THICKNESS
, &h
))
4493 /* Get the underline position. This is the recommended
4494 vertical offset in pixels from the baseline to the top of
4495 the underline. This is a signed value according to the
4496 specs, and its default is
4498 ROUND ((maximum descent) / 2), with
4499 ROUND(x) = floor (x + 0.5) */
4501 if (x_use_underline_position_properties
4502 && XGetFontProperty (s
->font
, XA_UNDERLINE_POSITION
, &tem
))
4503 y
= s
->ybase
+ (long) tem
;
4504 else if (s
->face
->font
)
4505 y
= s
->ybase
+ (s
->face
->font
->max_bounds
.descent
+ 1) / 2;
4507 y
= s
->y
+ s
->height
- h
;
4509 if (s
->face
->underline_defaulted_p
)
4510 XFillRectangle (s
->display
, s
->window
, s
->gc
,
4511 s
->x
, y
, s
->width
, h
);
4515 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4516 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
4517 XFillRectangle (s
->display
, s
->window
, s
->gc
,
4518 s
->x
, y
, s
->width
, h
);
4519 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4523 /* Draw overline. */
4524 if (s
->face
->overline_p
)
4526 unsigned long dy
= 0, h
= 1;
4528 if (s
->face
->overline_color_defaulted_p
)
4529 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4534 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4535 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
4536 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4538 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4542 /* Draw strike-through. */
4543 if (s
->face
->strike_through_p
)
4545 unsigned long h
= 1;
4546 unsigned long dy
= (s
->height
- h
) / 2;
4548 if (s
->face
->strike_through_color_defaulted_p
)
4549 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4554 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4555 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
4556 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4558 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4562 /* Draw relief if not yet drawn. */
4563 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
4564 x_draw_glyph_string_box (s
);
4567 /* Reset clipping. */
4568 XSetClipMask (s
->display
, s
->gc
, None
);
4572 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4573 struct face
**, int));
4576 /* Fill glyph string S with composition components specified by S->cmp.
4578 FACES is an array of faces for all components of this composition.
4579 S->gidx is the index of the first component for S.
4580 OVERLAPS_P non-zero means S should draw the foreground only, and
4581 use its physical height for clipping.
4583 Value is the index of a component not in S. */
4586 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4587 struct glyph_string
*s
;
4588 struct face
**faces
;
4595 s
->for_overlaps_p
= overlaps_p
;
4597 s
->face
= faces
[s
->gidx
];
4598 s
->font
= s
->face
->font
;
4599 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4601 /* For all glyphs of this composition, starting at the offset
4602 S->gidx, until we reach the end of the definition or encounter a
4603 glyph that requires the different face, add it to S. */
4605 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4608 /* All glyph strings for the same composition has the same width,
4609 i.e. the width set for the first component of the composition. */
4611 s
->width
= s
->first_glyph
->pixel_width
;
4613 /* If the specified font could not be loaded, use the frame's
4614 default font, but record the fact that we couldn't load it in
4615 the glyph string so that we can draw rectangles for the
4616 characters of the glyph string. */
4617 if (s
->font
== NULL
)
4619 s
->font_not_found_p
= 1;
4620 s
->font
= FRAME_FONT (s
->f
);
4623 /* Adjust base line for subscript/superscript text. */
4624 s
->ybase
+= s
->first_glyph
->voffset
;
4626 xassert (s
->face
&& s
->face
->gc
);
4628 /* This glyph string must always be drawn with 16-bit functions. */
4631 return s
->gidx
+ s
->nchars
;
4635 /* Fill glyph string S from a sequence of character glyphs.
4637 FACE_ID is the face id of the string. START is the index of the
4638 first glyph to consider, END is the index of the last + 1.
4639 OVERLAPS_P non-zero means S should draw the foreground only, and
4640 use its physical height for clipping.
4642 Value is the index of the first glyph not in S. */
4645 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4646 struct glyph_string
*s
;
4648 int start
, end
, overlaps_p
;
4650 struct glyph
*glyph
, *last
;
4652 int glyph_not_available_p
;
4654 xassert (s
->f
== XFRAME (s
->w
->frame
));
4655 xassert (s
->nchars
== 0);
4656 xassert (start
>= 0 && end
> start
);
4658 s
->for_overlaps_p
= overlaps_p
,
4659 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4660 last
= s
->row
->glyphs
[s
->area
] + end
;
4661 voffset
= glyph
->voffset
;
4663 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4666 && glyph
->type
== CHAR_GLYPH
4667 && glyph
->voffset
== voffset
4668 /* Same face id implies same font, nowadays. */
4669 && glyph
->face_id
== face_id
4670 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
4674 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
4675 s
->char2b
+ s
->nchars
,
4677 s
->two_byte_p
= two_byte_p
;
4679 xassert (s
->nchars
<= end
- start
);
4680 s
->width
+= glyph
->pixel_width
;
4684 s
->font
= s
->face
->font
;
4685 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4687 /* If the specified font could not be loaded, use the frame's font,
4688 but record the fact that we couldn't load it in
4689 S->font_not_found_p so that we can draw rectangles for the
4690 characters of the glyph string. */
4691 if (s
->font
== NULL
|| glyph_not_available_p
)
4693 s
->font_not_found_p
= 1;
4694 s
->font
= FRAME_FONT (s
->f
);
4697 /* Adjust base line for subscript/superscript text. */
4698 s
->ybase
+= voffset
;
4700 xassert (s
->face
&& s
->face
->gc
);
4701 return glyph
- s
->row
->glyphs
[s
->area
];
4705 /* Fill glyph string S from image glyph S->first_glyph. */
4708 x_fill_image_glyph_string (s
)
4709 struct glyph_string
*s
;
4711 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4712 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
4714 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4715 s
->font
= s
->face
->font
;
4716 s
->width
= s
->first_glyph
->pixel_width
;
4718 /* Adjust base line for subscript/superscript text. */
4719 s
->ybase
+= s
->first_glyph
->voffset
;
4723 /* Fill glyph string S from a sequence of stretch glyphs.
4725 ROW is the glyph row in which the glyphs are found, AREA is the
4726 area within the row. START is the index of the first glyph to
4727 consider, END is the index of the last + 1.
4729 Value is the index of the first glyph not in S. */
4732 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
4733 struct glyph_string
*s
;
4734 struct glyph_row
*row
;
4735 enum glyph_row_area area
;
4738 struct glyph
*glyph
, *last
;
4739 int voffset
, face_id
;
4741 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4743 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4744 last
= s
->row
->glyphs
[s
->area
] + end
;
4745 face_id
= glyph
->face_id
;
4746 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
4747 s
->font
= s
->face
->font
;
4748 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4749 s
->width
= glyph
->pixel_width
;
4750 voffset
= glyph
->voffset
;
4754 && glyph
->type
== STRETCH_GLYPH
4755 && glyph
->voffset
== voffset
4756 && glyph
->face_id
== face_id
);
4758 s
->width
+= glyph
->pixel_width
;
4760 /* Adjust base line for subscript/superscript text. */
4761 s
->ybase
+= voffset
;
4763 /* The case that face->gc == 0 is handled when drawing the glyph
4764 string by calling PREPARE_FACE_FOR_DISPLAY. */
4766 return glyph
- s
->row
->glyphs
[s
->area
];
4770 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4771 of XChar2b structures for S; it can't be allocated in
4772 x_init_glyph_string because it must be allocated via `alloca'. W
4773 is the window on which S is drawn. ROW and AREA are the glyph row
4774 and area within the row from which S is constructed. START is the
4775 index of the first glyph structure covered by S. HL is a
4776 face-override for drawing S. */
4779 x_init_glyph_string (s
, char2b
, w
, row
, area
, start
, hl
)
4780 struct glyph_string
*s
;
4783 struct glyph_row
*row
;
4784 enum glyph_row_area area
;
4786 enum draw_glyphs_face hl
;
4788 bzero (s
, sizeof *s
);
4790 s
->f
= XFRAME (w
->frame
);
4791 s
->display
= FRAME_X_DISPLAY (s
->f
);
4792 s
->window
= FRAME_X_WINDOW (s
->f
);
4797 s
->first_glyph
= row
->glyphs
[area
] + start
;
4798 s
->height
= row
->height
;
4799 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4801 /* Display the internal border below the tool-bar window. */
4802 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4803 s
->y
-= s
->f
->output_data
.x
->internal_border_width
;
4805 s
->ybase
= s
->y
+ row
->ascent
;
4809 /* Set background width of glyph string S. START is the index of the
4810 first glyph following S. LAST_X is the right-most x-position + 1
4811 in the drawing area. */
4814 x_set_glyph_string_background_width (s
, start
, last_x
)
4815 struct glyph_string
*s
;
4819 /* If the face of this glyph string has to be drawn to the end of
4820 the drawing area, set S->extends_to_end_of_line_p. */
4821 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4823 if (start
== s
->row
->used
[s
->area
]
4824 && s
->area
== TEXT_AREA
4825 && ((s
->hl
== DRAW_NORMAL_TEXT
4826 && (s
->row
->fill_line_p
4827 || s
->face
->background
!= default_face
->background
4828 || s
->face
->stipple
!= default_face
->stipple
4829 || s
->row
->mouse_face_p
))
4830 || s
->hl
== DRAW_MOUSE_FACE
4831 || ((s
->hl
== DRAW_IMAGE_RAISED
|| s
->hl
== DRAW_IMAGE_SUNKEN
)
4832 && s
->row
->fill_line_p
)))
4833 s
->extends_to_end_of_line_p
= 1;
4835 /* If S extends its face to the end of the line, set its
4836 background_width to the distance to the right edge of the drawing
4838 if (s
->extends_to_end_of_line_p
)
4839 s
->background_width
= last_x
- s
->x
+ 1;
4841 s
->background_width
= s
->width
;
4845 /* Add a glyph string for a stretch glyph to the list of strings
4846 between HEAD and TAIL. START is the index of the stretch glyph in
4847 row area AREA of glyph row ROW. END is the index of the last glyph
4848 in that glyph row area. X is the current output position assigned
4849 to the new glyph string constructed. HL overrides that face of the
4850 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4851 is the right-most x-position of the drawing area. */
4853 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
4854 and below -- keep them on one line. */
4855 #define BUILD_STRETCH_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4858 s = (struct glyph_string *) alloca (sizeof *s); \
4859 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
4860 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4861 x_append_glyph_string (&HEAD, &TAIL, s); \
4867 /* Add a glyph string for an image glyph to the list of strings
4868 between HEAD and TAIL. START is the index of the image glyph in
4869 row area AREA of glyph row ROW. END is the index of the last glyph
4870 in that glyph row area. X is the current output position assigned
4871 to the new glyph string constructed. HL overrides that face of the
4872 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4873 is the right-most x-position of the drawing area. */
4875 #define BUILD_IMAGE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4878 s = (struct glyph_string *) alloca (sizeof *s); \
4879 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
4880 x_fill_image_glyph_string (s); \
4881 x_append_glyph_string (&HEAD, &TAIL, s); \
4888 /* Add a glyph string for a sequence of character glyphs to the list
4889 of strings between HEAD and TAIL. START is the index of the first
4890 glyph in row area AREA of glyph row ROW that is part of the new
4891 glyph string. END is the index of the last glyph in that glyph row
4892 area. X is the current output position assigned to the new glyph
4893 string constructed. HL overrides that face of the glyph; e.g. it
4894 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4895 right-most x-position of the drawing area. */
4897 #define BUILD_CHAR_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4903 c = (ROW)->glyphs[AREA][START].u.ch; \
4904 face_id = (ROW)->glyphs[AREA][START].face_id; \
4906 s = (struct glyph_string *) alloca (sizeof *s); \
4907 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
4908 x_init_glyph_string (s, char2b, W, ROW, AREA, START, HL); \
4909 x_append_glyph_string (&HEAD, &TAIL, s); \
4911 START = x_fill_glyph_string (s, face_id, START, END, \
4917 /* Add a glyph string for a composite sequence to the list of strings
4918 between HEAD and TAIL. START is the index of the first glyph in
4919 row area AREA of glyph row ROW that is part of the new glyph
4920 string. END is the index of the last glyph in that glyph row area.
4921 X is the current output position assigned to the new glyph string
4922 constructed. HL overrides that face of the glyph; e.g. it is
4923 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4924 x-position of the drawing area. */
4926 #define BUILD_COMPOSITE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4928 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4929 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4930 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4931 struct composition *cmp = composition_table[cmp_id]; \
4932 int glyph_len = cmp->glyph_len; \
4934 struct face **faces; \
4935 struct glyph_string *first_s = NULL; \
4938 base_face = base_face->ascii_face; \
4939 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
4940 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4941 /* At first, fill in `char2b' and `faces'. */ \
4942 for (n = 0; n < glyph_len; n++) \
4944 int c = COMPOSITION_GLYPH (cmp, n); \
4945 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4946 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4947 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4948 this_face_id, char2b + n, 1); \
4951 /* Make glyph_strings for each glyph sequence that is drawable by \
4952 the same face, and append them to HEAD/TAIL. */ \
4953 for (n = 0; n < cmp->glyph_len;) \
4955 s = (struct glyph_string *) alloca (sizeof *s); \
4956 x_init_glyph_string (s, char2b + n, W, ROW, AREA, START, HL); \
4957 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4965 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4973 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4974 of AREA of glyph row ROW on window W between indices START and END.
4975 HL overrides the face for drawing glyph strings, e.g. it is
4976 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4977 x-positions of the drawing area.
4979 This is an ugly monster macro construct because we must use alloca
4980 to allocate glyph strings (because x_draw_glyphs can be called
4983 #define BUILD_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4986 HEAD = TAIL = NULL; \
4987 while (START < END) \
4989 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4990 switch (first_glyph->type) \
4993 BUILD_CHAR_GLYPH_STRINGS (W, ROW, AREA, START, END, HEAD, \
4994 TAIL, HL, X, LAST_X, \
4998 case COMPOSITE_GLYPH: \
4999 BUILD_COMPOSITE_GLYPH_STRING (W, ROW, AREA, START, END, \
5000 HEAD, TAIL, HL, X, LAST_X,\
5004 case STRETCH_GLYPH: \
5005 BUILD_STRETCH_GLYPH_STRING (W, ROW, AREA, START, END, \
5006 HEAD, TAIL, HL, X, LAST_X); \
5010 BUILD_IMAGE_GLYPH_STRING (W, ROW, AREA, START, END, HEAD, \
5011 TAIL, HL, X, LAST_X); \
5018 x_set_glyph_string_background_width (s, START, LAST_X); \
5025 /* Draw glyphs between START and END in AREA of ROW on window W,
5026 starting at x-position X. X is relative to AREA in W. HL is a
5027 face-override with the following meaning:
5029 DRAW_NORMAL_TEXT draw normally
5030 DRAW_CURSOR draw in cursor face
5031 DRAW_MOUSE_FACE draw in mouse face.
5032 DRAW_INVERSE_VIDEO draw in mode line face
5033 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
5034 DRAW_IMAGE_RAISED draw an image with a raised relief around it
5036 If OVERLAPS_P is non-zero, draw only the foreground of characters
5037 and clip to the physical height of ROW.
5039 Value is the x-position reached, relative to AREA of W. */
5042 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, overlaps_p
)
5045 struct glyph_row
*row
;
5046 enum glyph_row_area area
;
5048 enum draw_glyphs_face hl
;
5051 struct glyph_string
*head
, *tail
;
5052 struct glyph_string
*s
;
5053 int last_x
, area_width
;
5057 /* Let's rather be paranoid than getting a SEGV. */
5058 end
= min (end
, row
->used
[area
]);
5059 start
= max (0, start
);
5060 start
= min (end
, start
);
5062 /* Translate X to frame coordinates. Set last_x to the right
5063 end of the drawing area. */
5064 if (row
->full_width_p
)
5066 /* X is relative to the left edge of W, without scroll bars
5068 struct frame
*f
= XFRAME (w
->frame
);
5069 /* int width = FRAME_FRINGE_WIDTH (f); */
5070 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
5073 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5074 last_x
= window_left_x
+ area_width
;
5076 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
5078 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5079 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
5085 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
5086 last_x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
5090 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
5091 area_width
= window_box_width (w
, area
);
5092 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
5095 /* Build a doubly-linked list of glyph_string structures between
5096 head and tail from what we have to draw. Note that the macro
5097 BUILD_GLYPH_STRINGS will modify its start parameter. That's
5098 the reason we use a separate variable `i'. */
5100 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
5103 x_reached
= tail
->x
+ tail
->background_width
;
5107 /* If there are any glyphs with lbearing < 0 or rbearing > width in
5108 the row, redraw some glyphs in front or following the glyph
5109 strings built above. */
5110 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
5113 struct glyph_string
*h
, *t
;
5115 /* Compute overhangs for all glyph strings. */
5116 for (s
= head
; s
; s
= s
->next
)
5117 x_compute_glyph_string_overhangs (s
);
5119 /* Prepend glyph strings for glyphs in front of the first glyph
5120 string that are overwritten because of the first glyph
5121 string's left overhang. The background of all strings
5122 prepended must be drawn because the first glyph string
5124 i
= x_left_overwritten (head
);
5128 BUILD_GLYPH_STRINGS (w
, row
, area
, j
, start
, h
, t
,
5129 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5132 x_compute_overhangs_and_x (t
, head
->x
, 1);
5133 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5136 /* Prepend glyph strings for glyphs in front of the first glyph
5137 string that overwrite that glyph string because of their
5138 right overhang. For these strings, only the foreground must
5139 be drawn, because it draws over the glyph string at `head'.
5140 The background must not be drawn because this would overwrite
5141 right overhangs of preceding glyphs for which no glyph
5143 i
= x_left_overwriting (head
);
5146 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, start
, h
, t
,
5147 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5149 for (s
= h
; s
; s
= s
->next
)
5150 s
->background_filled_p
= 1;
5151 x_compute_overhangs_and_x (t
, head
->x
, 1);
5152 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5155 /* Append glyphs strings for glyphs following the last glyph
5156 string tail that are overwritten by tail. The background of
5157 these strings has to be drawn because tail's foreground draws
5159 i
= x_right_overwritten (tail
);
5162 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5163 DRAW_NORMAL_TEXT
, x
, last_x
,
5165 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5166 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5169 /* Append glyph strings for glyphs following the last glyph
5170 string tail that overwrite tail. The foreground of such
5171 glyphs has to be drawn because it writes into the background
5172 of tail. The background must not be drawn because it could
5173 paint over the foreground of following glyphs. */
5174 i
= x_right_overwriting (tail
);
5177 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5178 DRAW_NORMAL_TEXT
, x
, last_x
,
5180 for (s
= h
; s
; s
= s
->next
)
5181 s
->background_filled_p
= 1;
5182 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5183 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5187 /* Draw all strings. */
5188 for (s
= head
; s
; s
= s
->next
)
5189 x_draw_glyph_string (s
);
5191 if (area
== TEXT_AREA
&& !row
->full_width_p
)
5193 int x0
= head
? head
->x
: x
;
5194 int x1
= tail
? tail
->x
+ tail
->background_width
: x
;
5196 x0
= FRAME_TO_WINDOW_PIXEL_X (w
, x0
);
5197 x1
= FRAME_TO_WINDOW_PIXEL_X (w
, x1
);
5199 if (!row
->full_width_p
&& XFASTINT (w
->left_margin_width
) != 0)
5201 int left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
5202 x0
-= left_area_width
;
5203 x1
-= left_area_width
;
5206 notice_overwritten_cursor (w
, x0
, x1
);
5209 /* Value is the x-position up to which drawn, relative to AREA of W.
5210 This doesn't include parts drawn because of overhangs. */
5211 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
5212 if (!row
->full_width_p
)
5214 if (area
> LEFT_MARGIN_AREA
&& XFASTINT (w
->left_margin_width
) != 0)
5215 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
5216 if (area
> TEXT_AREA
)
5217 x_reached
-= window_box_width (w
, TEXT_AREA
);
5224 /* Fix the display of area AREA of overlapping row ROW in window W. */
5227 x_fix_overlapping_area (w
, row
, area
)
5229 struct glyph_row
*row
;
5230 enum glyph_row_area area
;
5236 if (area
== LEFT_MARGIN_AREA
)
5238 else if (area
== TEXT_AREA
)
5239 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5241 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5242 + window_box_width (w
, TEXT_AREA
));
5244 for (i
= 0; i
< row
->used
[area
];)
5246 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
5248 int start
= i
, start_x
= x
;
5252 x
+= row
->glyphs
[area
][i
].pixel_width
;
5255 while (i
< row
->used
[area
]
5256 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
5258 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
5259 DRAW_NORMAL_TEXT
, 1);
5263 x
+= row
->glyphs
[area
][i
].pixel_width
;
5272 /* Output LEN glyphs starting at START at the nominal cursor position.
5273 Advance the nominal cursor over the text. The global variable
5274 updated_window contains the window being updated, updated_row is
5275 the glyph row being updated, and updated_area is the area of that
5276 row being updated. */
5279 x_write_glyphs (start
, len
)
5280 struct glyph
*start
;
5285 xassert (updated_window
&& updated_row
);
5290 hpos
= start
- updated_row
->glyphs
[updated_area
];
5291 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
5292 updated_row
, updated_area
,
5294 DRAW_NORMAL_TEXT
, 0);
5298 /* Advance the output cursor. */
5299 output_cursor
.hpos
+= len
;
5300 output_cursor
.x
= x
;
5304 /* Insert LEN glyphs from START at the nominal cursor position. */
5307 x_insert_glyphs (start
, len
)
5308 struct glyph
*start
;
5313 int line_height
, shift_by_width
, shifted_region_width
;
5314 struct glyph_row
*row
;
5315 struct glyph
*glyph
;
5316 int frame_x
, frame_y
, hpos
;
5318 xassert (updated_window
&& updated_row
);
5321 f
= XFRAME (WINDOW_FRAME (w
));
5323 /* Get the height of the line we are in. */
5325 line_height
= row
->height
;
5327 /* Get the width of the glyphs to insert. */
5329 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5330 shift_by_width
+= glyph
->pixel_width
;
5332 /* Get the width of the region to shift right. */
5333 shifted_region_width
= (window_box_width (w
, updated_area
)
5338 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
5339 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5340 XCopyArea (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), FRAME_X_WINDOW (f
),
5341 f
->output_data
.x
->normal_gc
,
5343 shifted_region_width
, line_height
,
5344 frame_x
+ shift_by_width
, frame_y
);
5346 /* Write the glyphs. */
5347 hpos
= start
- row
->glyphs
[updated_area
];
5348 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5349 DRAW_NORMAL_TEXT
, 0);
5351 /* Advance the output cursor. */
5352 output_cursor
.hpos
+= len
;
5353 output_cursor
.x
+= shift_by_width
;
5358 /* Delete N glyphs at the nominal cursor position. Not implemented
5369 /* Like XClearArea, but check that WIDTH and HEIGHT are reasonable.
5370 If they are <= 0, this is probably an error. */
5373 x_clear_area (dpy
, window
, x
, y
, width
, height
, exposures
)
5380 xassert (width
> 0 && height
> 0);
5381 XClearArea (dpy
, window
, x
, y
, width
, height
, exposures
);
5385 /* Erase the current text line from the nominal cursor position
5386 (inclusive) to pixel column TO_X (exclusive). The idea is that
5387 everything from TO_X onward is already erased.
5389 TO_X is a pixel position relative to updated_area of
5390 updated_window. TO_X == -1 means clear to the end of this area. */
5393 x_clear_end_of_line (to_x
)
5397 struct window
*w
= updated_window
;
5398 int max_x
, min_y
, max_y
;
5399 int from_x
, from_y
, to_y
;
5401 xassert (updated_window
&& updated_row
);
5402 f
= XFRAME (w
->frame
);
5404 if (updated_row
->full_width_p
)
5406 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5407 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5408 && !w
->pseudo_window_p
)
5409 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5412 max_x
= window_box_width (w
, updated_area
);
5413 max_y
= window_text_bottom_y (w
);
5415 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5416 of window. For TO_X > 0, truncate to end of drawing area. */
5422 to_x
= min (to_x
, max_x
);
5424 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5426 /* Notice if the cursor will be cleared by this operation. */
5427 if (!updated_row
->full_width_p
)
5428 notice_overwritten_cursor (w
, output_cursor
.x
, -1);
5430 from_x
= output_cursor
.x
;
5432 /* Translate to frame coordinates. */
5433 if (updated_row
->full_width_p
)
5435 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5436 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5440 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5441 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5444 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5445 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5446 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5448 /* Prevent inadvertently clearing to end of the X window. */
5449 if (to_x
> from_x
&& to_y
> from_y
)
5452 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5453 from_x
, from_y
, to_x
- from_x
, to_y
- from_y
,
5460 /* Clear entire frame. If updating_frame is non-null, clear that
5461 frame. Otherwise clear the selected frame. */
5471 f
= SELECTED_FRAME ();
5473 /* Clearing the frame will erase any cursor, so mark them all as no
5475 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5476 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5477 output_cursor
.x
= -1;
5479 /* We don't set the output cursor here because there will always
5480 follow an explicit cursor_to. */
5482 XClearWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
5484 /* We have to clear the scroll bars, too. If we have changed
5485 colors or something like that, then they should be notified. */
5486 x_scroll_bar_clear (f
);
5488 XFlush (FRAME_X_DISPLAY (f
));
5494 /* Invert the middle quarter of the frame for .15 sec. */
5496 /* We use the select system call to do the waiting, so we have to make
5497 sure it's available. If it isn't, we just won't do visual bells. */
5499 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5502 /* Subtract the `struct timeval' values X and Y, storing the result in
5503 *RESULT. Return 1 if the difference is negative, otherwise 0. */
5506 timeval_subtract (result
, x
, y
)
5507 struct timeval
*result
, x
, y
;
5509 /* Perform the carry for the later subtraction by updating y. This
5510 is safer because on some systems the tv_sec member is unsigned. */
5511 if (x
.tv_usec
< y
.tv_usec
)
5513 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
5514 y
.tv_usec
-= 1000000 * nsec
;
5518 if (x
.tv_usec
- y
.tv_usec
> 1000000)
5520 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
5521 y
.tv_usec
+= 1000000 * nsec
;
5525 /* Compute the time remaining to wait. tv_usec is certainly
5527 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
5528 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
5530 /* Return indication of whether the result should be considered
5532 return x
.tv_sec
< y
.tv_sec
;
5544 /* Create a GC that will use the GXxor function to flip foreground
5545 pixels into background pixels. */
5549 values
.function
= GXxor
;
5550 values
.foreground
= (f
->output_data
.x
->foreground_pixel
5551 ^ f
->output_data
.x
->background_pixel
);
5553 gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5554 GCFunction
| GCForeground
, &values
);
5558 /* Get the height not including a menu bar widget. */
5559 int height
= CHAR_TO_PIXEL_HEIGHT (f
, FRAME_HEIGHT (f
));
5560 /* Height of each line to flash. */
5561 int flash_height
= FRAME_LINE_HEIGHT (f
);
5562 /* These will be the left and right margins of the rectangles. */
5563 int flash_left
= FRAME_INTERNAL_BORDER_WIDTH (f
);
5564 int flash_right
= PIXEL_WIDTH (f
) - FRAME_INTERNAL_BORDER_WIDTH (f
);
5568 /* Don't flash the area between a scroll bar and the frame
5569 edge it is next to. */
5570 switch (FRAME_VERTICAL_SCROLL_BAR_TYPE (f
))
5572 case vertical_scroll_bar_left
:
5573 flash_left
+= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
5576 case vertical_scroll_bar_right
:
5577 flash_right
-= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
5584 width
= flash_right
- flash_left
;
5586 /* If window is tall, flash top and bottom line. */
5587 if (height
> 3 * FRAME_LINE_HEIGHT (f
))
5589 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5591 (FRAME_INTERNAL_BORDER_WIDTH (f
)
5592 + FRAME_TOOL_BAR_LINES (f
) * CANON_Y_UNIT (f
)),
5593 width
, flash_height
);
5594 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5596 (height
- flash_height
5597 - FRAME_INTERNAL_BORDER_WIDTH (f
)),
5598 width
, flash_height
);
5601 /* If it is short, flash it all. */
5602 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5603 flash_left
, FRAME_INTERNAL_BORDER_WIDTH (f
),
5604 width
, height
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
5609 struct timeval wakeup
;
5611 EMACS_GET_TIME (wakeup
);
5613 /* Compute time to wait until, propagating carry from usecs. */
5614 wakeup
.tv_usec
+= 150000;
5615 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
5616 wakeup
.tv_usec
%= 1000000;
5618 /* Keep waiting until past the time wakeup or any input gets
5620 while (! detect_input_pending ())
5622 struct timeval current
;
5623 struct timeval timeout
;
5625 EMACS_GET_TIME (current
);
5627 /* Break if result would be negative. */
5628 if (timeval_subtract (¤t
, wakeup
, current
))
5631 /* How long `select' should wait. */
5633 timeout
.tv_usec
= 10000;
5635 /* Try to wait that long--but we might wake up sooner. */
5636 select (0, NULL
, NULL
, NULL
, &timeout
);
5640 /* If window is tall, flash top and bottom line. */
5641 if (height
> 3 * FRAME_LINE_HEIGHT (f
))
5643 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5645 (FRAME_INTERNAL_BORDER_WIDTH (f
)
5646 + FRAME_TOOL_BAR_LINES (f
) * CANON_Y_UNIT (f
)),
5647 width
, flash_height
);
5648 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5650 (height
- flash_height
5651 - FRAME_INTERNAL_BORDER_WIDTH (f
)),
5652 width
, flash_height
);
5655 /* If it is short, flash it all. */
5656 XFillRectangle (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), gc
,
5657 flash_left
, FRAME_INTERNAL_BORDER_WIDTH (f
),
5658 width
, height
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
5660 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
5668 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
5671 /* Make audible bell. */
5676 struct frame
*f
= SELECTED_FRAME ();
5678 if (FRAME_X_DISPLAY (f
))
5680 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5687 XBell (FRAME_X_DISPLAY (f
), 0);
5688 XFlush (FRAME_X_DISPLAY (f
));
5695 /* Specify how many text lines, from the top of the window,
5696 should be affected by insert-lines and delete-lines operations.
5697 This, and those operations, are used only within an update
5698 that is bounded by calls to x_update_begin and x_update_end. */
5701 XTset_terminal_window (n
)
5704 /* This function intentionally left blank. */
5709 /***********************************************************************
5711 ***********************************************************************/
5713 /* Perform an insert-lines or delete-lines operation, inserting N
5714 lines or deleting -N lines at vertical position VPOS. */
5717 x_ins_del_lines (vpos
, n
)
5724 /* Scroll part of the display as described by RUN. */
5727 x_scroll_run (w
, run
)
5731 struct frame
*f
= XFRAME (w
->frame
);
5732 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5734 /* Get frame-relative bounding box of the text display area of W,
5735 without mode lines. Include in this box the left and right
5737 window_box (w
, -1, &x
, &y
, &width
, &height
);
5738 width
+= FRAME_X_FRINGE_WIDTH (f
);
5739 x
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
5741 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5742 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5743 bottom_y
= y
+ height
;
5747 /* Scrolling up. Make sure we don't copy part of the mode
5748 line at the bottom. */
5749 if (from_y
+ run
->height
> bottom_y
)
5750 height
= bottom_y
- from_y
;
5752 height
= run
->height
;
5756 /* Scolling down. Make sure we don't copy over the mode line.
5758 if (to_y
+ run
->height
> bottom_y
)
5759 height
= bottom_y
- to_y
;
5761 height
= run
->height
;
5766 /* Cursor off. Will be switched on again in x_update_window_end. */
5770 XCopyArea (FRAME_X_DISPLAY (f
),
5771 FRAME_X_WINDOW (f
), FRAME_X_WINDOW (f
),
5772 f
->output_data
.x
->normal_gc
,
5782 /***********************************************************************
5784 ***********************************************************************/
5786 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5787 corner of the exposed rectangle. W and H are width and height of
5788 the exposed area. All are pixel values. W or H zero means redraw
5789 the entire frame. */
5792 expose_frame (f
, x
, y
, w
, h
)
5797 int mouse_face_overwritten_p
= 0;
5799 TRACE ((stderr
, "expose_frame "));
5801 /* No need to redraw if frame will be redrawn soon. */
5802 if (FRAME_GARBAGED_P (f
))
5804 TRACE ((stderr
, " garbaged\n"));
5808 /* If basic faces haven't been realized yet, there is no point in
5809 trying to redraw anything. This can happen when we get an expose
5810 event while Emacs is starting, e.g. by moving another window. */
5811 if (FRAME_FACE_CACHE (f
) == NULL
5812 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
5814 TRACE ((stderr
, " no faces\n"));
5818 if (w
== 0 || h
== 0)
5821 r
.width
= CANON_X_UNIT (f
) * f
->width
;
5822 r
.height
= CANON_Y_UNIT (f
) * f
->height
;
5832 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.x
, r
.y
, r
.width
, r
.height
));
5833 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
5835 if (WINDOWP (f
->tool_bar_window
))
5836 mouse_face_overwritten_p
5837 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
5839 #ifndef USE_X_TOOLKIT
5840 if (WINDOWP (f
->menu_bar_window
))
5841 mouse_face_overwritten_p
5842 |= expose_window (XWINDOW (f
->menu_bar_window
), &r
);
5843 #endif /* not USE_X_TOOLKIT */
5845 /* Some window managers support a focus-follows-mouse style with
5846 delayed raising of frames. Imagine a partially obscured frame,
5847 and moving the mouse into partially obscured mouse-face on that
5848 frame. The visible part of the mouse-face will be highlighted,
5849 then the WM raises the obscured frame. With at least one WM, KDE
5850 2.1, Emacs is not getting any event for the raising of the frame
5851 (even tried with SubstructureRedirectMask), only Expose events.
5852 These expose events will draw text normally, i.e. not
5853 highlighted. Which means we must redo the highlight here.
5854 Subsume it under ``we love X''. --gerd 2001-08-15 */
5855 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
5857 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
5858 if (f
== dpyinfo
->mouse_face_mouse_frame
)
5860 int x
= dpyinfo
->mouse_face_mouse_x
;
5861 int y
= dpyinfo
->mouse_face_mouse_y
;
5862 clear_mouse_face (dpyinfo
);
5863 note_mouse_highlight (f
, x
, y
);
5869 /* Redraw (parts) of all windows in the window tree rooted at W that
5870 intersect R. R contains frame pixel coordinates. Value is
5871 non-zero if the exposure overwrites mouse-face. */
5874 expose_window_tree (w
, r
)
5878 struct frame
*f
= XFRAME (w
->frame
);
5879 int mouse_face_overwritten_p
= 0;
5881 while (w
&& !FRAME_GARBAGED_P (f
))
5883 if (!NILP (w
->hchild
))
5884 mouse_face_overwritten_p
5885 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
5886 else if (!NILP (w
->vchild
))
5887 mouse_face_overwritten_p
5888 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
5890 mouse_face_overwritten_p
|= expose_window (w
, r
);
5892 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
5895 return mouse_face_overwritten_p
;
5899 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5900 which intersects rectangle R. R is in window-relative coordinates. */
5903 expose_area (w
, row
, r
, area
)
5905 struct glyph_row
*row
;
5907 enum glyph_row_area area
;
5909 struct glyph
*first
= row
->glyphs
[area
];
5910 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5912 int first_x
, start_x
, x
;
5914 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5915 /* If row extends face to end of line write the whole line. */
5916 x_draw_glyphs (w
, 0, row
, area
, 0, row
->used
[area
],
5917 DRAW_NORMAL_TEXT
, 0);
5920 /* Set START_X to the window-relative start position for drawing glyphs of
5921 AREA. The first glyph of the text area can be partially visible.
5922 The first glyphs of other areas cannot. */
5923 if (area
== LEFT_MARGIN_AREA
)
5925 else if (area
== TEXT_AREA
)
5926 start_x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5928 start_x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5929 + window_box_width (w
, TEXT_AREA
));
5932 /* Find the first glyph that must be redrawn. */
5934 && x
+ first
->pixel_width
< r
->x
)
5936 x
+= first
->pixel_width
;
5940 /* Find the last one. */
5944 && x
< r
->x
+ r
->width
)
5946 x
+= last
->pixel_width
;
5952 x_draw_glyphs (w
, first_x
- start_x
, row
, area
,
5953 first
- row
->glyphs
[area
],
5954 last
- row
->glyphs
[area
],
5955 DRAW_NORMAL_TEXT
, 0);
5960 /* Redraw the parts of the glyph row ROW on window W intersecting
5961 rectangle R. R is in window-relative coordinates. Value is
5962 non-zero if mouse-face was overwritten. */
5965 expose_line (w
, row
, r
)
5967 struct glyph_row
*row
;
5970 xassert (row
->enabled_p
);
5972 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5973 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5974 DRAW_NORMAL_TEXT
, 0);
5977 if (row
->used
[LEFT_MARGIN_AREA
])
5978 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5979 if (row
->used
[TEXT_AREA
])
5980 expose_area (w
, row
, r
, TEXT_AREA
);
5981 if (row
->used
[RIGHT_MARGIN_AREA
])
5982 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5983 x_draw_row_fringe_bitmaps (w
, row
);
5986 return row
->mouse_face_p
;
5990 /* Return non-zero if W's cursor intersects rectangle R. */
5993 x_phys_cursor_in_rect_p (w
, r
)
5997 XRectangle cr
, result
;
5998 struct glyph
*cursor_glyph
;
6000 cursor_glyph
= get_phys_cursor_glyph (w
);
6003 cr
.x
= w
->phys_cursor
.x
;
6004 cr
.y
= w
->phys_cursor
.y
;
6005 cr
.width
= cursor_glyph
->pixel_width
;
6006 cr
.height
= w
->phys_cursor_height
;
6007 return x_intersect_rectangles (&cr
, r
, &result
);
6014 /* Redraw the part of window W intersection rectangle FR. Pixel
6015 coordinates in FR are frame-relative. Call this function with
6016 input blocked. Value is non-zero if the exposure overwrites
6020 expose_window (w
, fr
)
6024 struct frame
*f
= XFRAME (w
->frame
);
6026 int mouse_face_overwritten_p
= 0;
6028 /* If window is not yet fully initialized, do nothing. This can
6029 happen when toolkit scroll bars are used and a window is split.
6030 Reconfiguring the scroll bar will generate an expose for a newly
6032 if (w
->current_matrix
== NULL
)
6035 /* When we're currently updating the window, display and current
6036 matrix usually don't agree. Arrange for a thorough display
6038 if (w
== updated_window
)
6040 SET_FRAME_GARBAGED (f
);
6044 /* Frame-relative pixel rectangle of W. */
6045 wr
.x
= XFASTINT (w
->left
) * CANON_X_UNIT (f
);
6046 wr
.y
= XFASTINT (w
->top
) * CANON_Y_UNIT (f
);
6047 wr
.width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
6048 wr
.height
= XFASTINT (w
->height
) * CANON_Y_UNIT (f
);
6050 if (x_intersect_rectangles (fr
, &wr
, &r
))
6052 int yb
= window_text_bottom_y (w
);
6053 struct glyph_row
*row
;
6054 int cursor_cleared_p
;
6056 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
6057 r
.x
, r
.y
, r
.width
, r
.height
));
6059 /* Convert to window coordinates. */
6060 r
.x
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.x
);
6061 r
.y
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.y
);
6063 /* Turn off the cursor. */
6064 if (!w
->pseudo_window_p
6065 && x_phys_cursor_in_rect_p (w
, &r
))
6068 cursor_cleared_p
= 1;
6071 cursor_cleared_p
= 0;
6073 /* Find the first row intersecting the rectangle R. */
6074 for (row
= w
->current_matrix
->rows
;
6079 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
6081 if ((y0
>= r
.y
&& y0
< r
.y
+ r
.height
)
6082 || (y1
> r
.y
&& y1
< r
.y
+ r
.height
)
6083 || (r
.y
>= y0
&& r
.y
< y1
)
6084 || (r
.y
+ r
.height
> y0
&& r
.y
+ r
.height
< y1
))
6086 if (expose_line (w
, row
, &r
))
6087 mouse_face_overwritten_p
= 1;
6094 /* Display the mode line if there is one. */
6095 if (WINDOW_WANTS_MODELINE_P (w
)
6096 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
6098 && row
->y
< r
.y
+ r
.height
)
6100 if (expose_line (w
, row
, &r
))
6101 mouse_face_overwritten_p
= 1;
6104 if (!w
->pseudo_window_p
)
6106 /* Draw border between windows. */
6107 x_draw_vertical_border (w
);
6109 /* Turn the cursor on again. */
6110 if (cursor_cleared_p
)
6111 x_update_window_cursor (w
, 1);
6115 return mouse_face_overwritten_p
;
6119 /* Determine the intersection of two rectangles R1 and R2. Return
6120 the intersection in *RESULT. Value is non-zero if RESULT is not
6124 x_intersect_rectangles (r1
, r2
, result
)
6125 XRectangle
*r1
, *r2
, *result
;
6127 XRectangle
*left
, *right
;
6128 XRectangle
*upper
, *lower
;
6129 int intersection_p
= 0;
6131 /* Rearrange so that R1 is the left-most rectangle. */
6133 left
= r1
, right
= r2
;
6135 left
= r2
, right
= r1
;
6137 /* X0 of the intersection is right.x0, if this is inside R1,
6138 otherwise there is no intersection. */
6139 if (right
->x
<= left
->x
+ left
->width
)
6141 result
->x
= right
->x
;
6143 /* The right end of the intersection is the minimum of the
6144 the right ends of left and right. */
6145 result
->width
= (min (left
->x
+ left
->width
, right
->x
+ right
->width
)
6148 /* Same game for Y. */
6150 upper
= r1
, lower
= r2
;
6152 upper
= r2
, lower
= r1
;
6154 /* The upper end of the intersection is lower.y0, if this is inside
6155 of upper. Otherwise, there is no intersection. */
6156 if (lower
->y
<= upper
->y
+ upper
->height
)
6158 result
->y
= lower
->y
;
6160 /* The lower end of the intersection is the minimum of the lower
6161 ends of upper and lower. */
6162 result
->height
= (min (lower
->y
+ lower
->height
,
6163 upper
->y
+ upper
->height
)
6169 return intersection_p
;
6180 /* We used to only do this if Vx_no_window_manager was non-nil, but
6181 the ICCCM (section 4.1.6) says that the window's border pixmap
6182 and border pixel are window attributes which are "private to the
6183 client", so we can always change it to whatever we want. */
6185 XSetWindowBorder (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6186 f
->output_data
.x
->border_pixel
);
6188 x_update_cursor (f
, 1);
6192 frame_unhighlight (f
)
6195 /* We used to only do this if Vx_no_window_manager was non-nil, but
6196 the ICCCM (section 4.1.6) says that the window's border pixmap
6197 and border pixel are window attributes which are "private to the
6198 client", so we can always change it to whatever we want. */
6200 XSetWindowBorderPixmap (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6201 f
->output_data
.x
->border_tile
);
6203 x_update_cursor (f
, 1);
6206 /* The focus has changed. Update the frames as necessary to reflect
6207 the new situation. Note that we can't change the selected frame
6208 here, because the Lisp code we are interrupting might become confused.
6209 Each event gets marked with the frame in which it occurred, so the
6210 Lisp code can tell when the switch took place by examining the events. */
6213 x_new_focus_frame (dpyinfo
, frame
)
6214 struct x_display_info
*dpyinfo
;
6215 struct frame
*frame
;
6217 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
6219 if (frame
!= dpyinfo
->x_focus_frame
)
6221 /* Set this before calling other routines, so that they see
6222 the correct value of x_focus_frame. */
6223 dpyinfo
->x_focus_frame
= frame
;
6225 if (old_focus
&& old_focus
->auto_lower
)
6226 x_lower_frame (old_focus
);
6229 selected_frame
= frame
;
6230 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
6232 Fselect_window (selected_frame
->selected_window
);
6233 choose_minibuf_frame ();
6236 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
6237 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
6239 pending_autoraise_frame
= 0;
6242 x_frame_rehighlight (dpyinfo
);
6245 /* Handle an event saying the mouse has moved out of an Emacs frame. */
6248 x_mouse_leave (dpyinfo
)
6249 struct x_display_info
*dpyinfo
;
6251 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
6254 /* The focus has changed, or we have redirected a frame's focus to
6255 another frame (this happens when a frame uses a surrogate
6256 mini-buffer frame). Shift the highlight as appropriate.
6258 The FRAME argument doesn't necessarily have anything to do with which
6259 frame is being highlighted or un-highlighted; we only use it to find
6260 the appropriate X display info. */
6263 XTframe_rehighlight (frame
)
6264 struct frame
*frame
;
6266 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
6270 x_frame_rehighlight (dpyinfo
)
6271 struct x_display_info
*dpyinfo
;
6273 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
6275 if (dpyinfo
->x_focus_frame
)
6277 dpyinfo
->x_highlight_frame
6278 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
6279 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
6280 : dpyinfo
->x_focus_frame
);
6281 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
6283 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
6284 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
6288 dpyinfo
->x_highlight_frame
= 0;
6290 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
6293 frame_unhighlight (old_highlight
);
6294 if (dpyinfo
->x_highlight_frame
)
6295 frame_highlight (dpyinfo
->x_highlight_frame
);
6301 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
6303 /* Initialize mode_switch_bit and modifier_meaning. */
6305 x_find_modifier_meanings (dpyinfo
)
6306 struct x_display_info
*dpyinfo
;
6308 int min_code
, max_code
;
6311 XModifierKeymap
*mods
;
6313 dpyinfo
->meta_mod_mask
= 0;
6314 dpyinfo
->shift_lock_mask
= 0;
6315 dpyinfo
->alt_mod_mask
= 0;
6316 dpyinfo
->super_mod_mask
= 0;
6317 dpyinfo
->hyper_mod_mask
= 0;
6320 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
6322 min_code
= dpyinfo
->display
->min_keycode
;
6323 max_code
= dpyinfo
->display
->max_keycode
;
6326 syms
= XGetKeyboardMapping (dpyinfo
->display
,
6327 min_code
, max_code
- min_code
+ 1,
6329 mods
= XGetModifierMapping (dpyinfo
->display
);
6331 /* Scan the modifier table to see which modifier bits the Meta and
6332 Alt keysyms are on. */
6334 int row
, col
; /* The row and column in the modifier table. */
6336 for (row
= 3; row
< 8; row
++)
6337 for (col
= 0; col
< mods
->max_keypermod
; col
++)
6340 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
6342 /* Zeroes are used for filler. Skip them. */
6346 /* Are any of this keycode's keysyms a meta key? */
6350 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
6352 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
6358 dpyinfo
->meta_mod_mask
|= (1 << row
);
6363 dpyinfo
->alt_mod_mask
|= (1 << row
);
6368 dpyinfo
->hyper_mod_mask
|= (1 << row
);
6373 dpyinfo
->super_mod_mask
|= (1 << row
);
6377 /* Ignore this if it's not on the lock modifier. */
6378 if ((1 << row
) == LockMask
)
6379 dpyinfo
->shift_lock_mask
= LockMask
;
6387 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
6388 if (! dpyinfo
->meta_mod_mask
)
6390 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
6391 dpyinfo
->alt_mod_mask
= 0;
6394 /* If some keys are both alt and meta,
6395 make them just meta, not alt. */
6396 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
6398 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
6401 XFree ((char *) syms
);
6402 XFreeModifiermap (mods
);
6405 /* Convert between the modifier bits X uses and the modifier bits
6409 x_x_to_emacs_modifiers (dpyinfo
, state
)
6410 struct x_display_info
*dpyinfo
;
6413 return ( ((state
& (ShiftMask
| dpyinfo
->shift_lock_mask
)) ? shift_modifier
: 0)
6414 | ((state
& ControlMask
) ? ctrl_modifier
: 0)
6415 | ((state
& dpyinfo
->meta_mod_mask
) ? meta_modifier
: 0)
6416 | ((state
& dpyinfo
->alt_mod_mask
) ? alt_modifier
: 0)
6417 | ((state
& dpyinfo
->super_mod_mask
) ? super_modifier
: 0)
6418 | ((state
& dpyinfo
->hyper_mod_mask
) ? hyper_modifier
: 0));
6422 x_emacs_to_x_modifiers (dpyinfo
, state
)
6423 struct x_display_info
*dpyinfo
;
6426 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
6427 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
6428 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
6429 | ((state
& shift_modifier
) ? ShiftMask
: 0)
6430 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
6431 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
6434 /* Convert a keysym to its name. */
6437 x_get_keysym_name (keysym
)
6443 value
= XKeysymToString (keysym
);
6451 /* Mouse clicks and mouse movement. Rah. */
6453 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
6454 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
6455 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
6456 not force the value into range. */
6459 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
6461 register int pix_x
, pix_y
;
6462 register int *x
, *y
;
6466 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
6467 even for negative values. */
6469 pix_x
-= FONT_WIDTH ((f
)->output_data
.x
->font
) - 1;
6471 pix_y
-= (f
)->output_data
.x
->line_height
- 1;
6473 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
6474 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
6478 bounds
->width
= FONT_WIDTH (f
->output_data
.x
->font
);
6479 bounds
->height
= f
->output_data
.x
->line_height
;
6480 bounds
->x
= CHAR_TO_PIXEL_COL (f
, pix_x
);
6481 bounds
->y
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
6488 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
6489 pix_x
= FRAME_WINDOW_WIDTH (f
);
6493 else if (pix_y
> f
->height
)
6502 /* Given HPOS/VPOS in the current matrix of W, return corresponding
6503 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
6504 can't tell the positions because W's display is not up to date,
6508 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
6511 int *frame_x
, *frame_y
;
6515 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
6516 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
6518 if (display_completed
)
6520 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6521 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
6522 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
6528 *frame_x
+= glyph
->pixel_width
;
6536 *frame_y
= *frame_x
= 0;
6540 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
6541 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
6546 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6548 If the event is a button press, then note that we have grabbed
6552 construct_mouse_click (result
, event
, f
)
6553 struct input_event
*result
;
6554 XButtonEvent
*event
;
6557 /* Make the event type no_event; we'll change that when we decide
6559 result
->kind
= mouse_click
;
6560 result
->code
= event
->button
- Button1
;
6561 result
->timestamp
= event
->time
;
6562 result
->modifiers
= (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
6564 | (event
->type
== ButtonRelease
6568 XSETINT (result
->x
, event
->x
);
6569 XSETINT (result
->y
, event
->y
);
6570 XSETFRAME (result
->frame_or_window
, f
);
6576 /* Function to report a mouse movement to the mainstream Emacs code.
6577 The input handler calls this.
6579 We have received a mouse movement event, which is given in *event.
6580 If the mouse is over a different glyph than it was last time, tell
6581 the mainstream emacs code by setting mouse_moved. If not, ask for
6582 another motion event, so we can check again the next time it moves. */
6584 static XMotionEvent last_mouse_motion_event
;
6585 static Lisp_Object last_mouse_motion_frame
;
6588 note_mouse_movement (frame
, event
)
6590 XMotionEvent
*event
;
6592 last_mouse_movement_time
= event
->time
;
6593 last_mouse_motion_event
= *event
;
6594 XSETFRAME (last_mouse_motion_frame
, frame
);
6596 if (event
->window
!= FRAME_X_WINDOW (frame
))
6598 frame
->mouse_moved
= 1;
6599 last_mouse_scroll_bar
= Qnil
;
6600 note_mouse_highlight (frame
, -1, -1);
6603 /* Has the mouse moved off the glyph it was on at the last sighting? */
6604 else if (event
->x
< last_mouse_glyph
.x
6605 || event
->x
>= last_mouse_glyph
.x
+ last_mouse_glyph
.width
6606 || event
->y
< last_mouse_glyph
.y
6607 || event
->y
>= last_mouse_glyph
.y
+ last_mouse_glyph
.height
)
6609 frame
->mouse_moved
= 1;
6610 last_mouse_scroll_bar
= Qnil
;
6611 note_mouse_highlight (frame
, event
->x
, event
->y
);
6615 /* This is used for debugging, to turn off note_mouse_highlight. */
6617 int disable_mouse_highlight
;
6621 /************************************************************************
6623 ************************************************************************/
6625 /* Find the glyph under window-relative coordinates X/Y in window W.
6626 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6627 strings. Return in *HPOS and *VPOS the row and column number of
6628 the glyph found. Return in *AREA the glyph area containing X.
6629 Value is a pointer to the glyph found or null if X/Y is not on
6630 text, or we can't tell because W's current matrix is not up to
6633 static struct glyph
*
6634 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
, buffer_only_p
)
6637 int *hpos
, *vpos
, *area
;
6640 struct glyph
*glyph
, *end
;
6641 struct glyph_row
*row
= NULL
;
6642 int x0
, i
, left_area_width
;
6644 /* Find row containing Y. Give up if some row is not enabled. */
6645 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6647 row
= MATRIX_ROW (w
->current_matrix
, i
);
6648 if (!row
->enabled_p
)
6650 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6657 /* Give up if Y is not in the window. */
6658 if (i
== w
->current_matrix
->nrows
)
6661 /* Get the glyph area containing X. */
6662 if (w
->pseudo_window_p
)
6669 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6670 if (x
< left_area_width
)
6672 *area
= LEFT_MARGIN_AREA
;
6675 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6678 x0
= row
->x
+ left_area_width
;
6682 *area
= RIGHT_MARGIN_AREA
;
6683 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6687 /* Find glyph containing X. */
6688 glyph
= row
->glyphs
[*area
];
6689 end
= glyph
+ row
->used
[*area
];
6692 if (x
< x0
+ glyph
->pixel_width
)
6694 if (w
->pseudo_window_p
)
6696 else if (!buffer_only_p
|| BUFFERP (glyph
->object
))
6700 x0
+= glyph
->pixel_width
;
6707 *hpos
= glyph
- row
->glyphs
[*area
];
6712 /* Convert frame-relative x/y to coordinates relative to window W.
6713 Takes pseudo-windows into account. */
6716 frame_to_window_pixel_xy (w
, x
, y
)
6720 if (w
->pseudo_window_p
)
6722 /* A pseudo-window is always full-width, and starts at the
6723 left edge of the frame, plus a frame border. */
6724 struct frame
*f
= XFRAME (w
->frame
);
6725 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6726 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6730 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6731 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6736 /* Take proper action when mouse has moved to the mode or header line of
6737 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6738 mode line. X is relative to the start of the text display area of
6739 W, so the width of fringes and scroll bars must be subtracted
6740 to get a position relative to the start of the mode line. */
6743 note_mode_line_highlight (w
, x
, mode_line_p
)
6747 struct frame
*f
= XFRAME (w
->frame
);
6748 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6749 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6750 struct glyph_row
*row
;
6753 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
6755 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
6759 struct glyph
*glyph
, *end
;
6760 Lisp_Object help
, map
;
6763 /* Find the glyph under X. */
6764 glyph
= row
->glyphs
[TEXT_AREA
];
6765 end
= glyph
+ row
->used
[TEXT_AREA
];
6766 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
6767 + FRAME_X_LEFT_FRINGE_WIDTH (f
));
6770 && x
>= x0
+ glyph
->pixel_width
)
6772 x0
+= glyph
->pixel_width
;
6777 && STRINGP (glyph
->object
)
6778 && XSTRING (glyph
->object
)->intervals
6779 && glyph
->charpos
>= 0
6780 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6782 /* If we're on a string with `help-echo' text property,
6783 arrange for the help to be displayed. This is done by
6784 setting the global variable help_echo to the help string. */
6785 help
= Fget_text_property (make_number (glyph
->charpos
),
6786 Qhelp_echo
, glyph
->object
);
6790 XSETWINDOW (help_echo_window
, w
);
6791 help_echo_object
= glyph
->object
;
6792 help_echo_pos
= glyph
->charpos
;
6795 /* Change the mouse pointer according to what is under X/Y. */
6796 map
= Fget_text_property (make_number (glyph
->charpos
),
6797 Qlocal_map
, glyph
->object
);
6799 cursor
= f
->output_data
.x
->nontext_cursor
;
6802 map
= Fget_text_property (make_number (glyph
->charpos
),
6803 Qkeymap
, glyph
->object
);
6805 cursor
= f
->output_data
.x
->nontext_cursor
;
6810 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
6814 /* Take proper action when the mouse has moved to position X, Y on
6815 frame F as regards highlighting characters that have mouse-face
6816 properties. Also de-highlighting chars where the mouse was before.
6817 X and Y can be negative or out of range. */
6820 note_mouse_highlight (f
, x
, y
)
6824 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6828 Cursor cursor
= None
;
6831 /* When a menu is active, don't highlight because this looks odd. */
6832 #ifdef USE_X_TOOLKIT
6833 if (popup_activated ())
6837 if (disable_mouse_highlight
6838 || !f
->glyphs_initialized_p
)
6841 dpyinfo
->mouse_face_mouse_x
= x
;
6842 dpyinfo
->mouse_face_mouse_y
= y
;
6843 dpyinfo
->mouse_face_mouse_frame
= f
;
6845 if (dpyinfo
->mouse_face_defer
)
6850 dpyinfo
->mouse_face_deferred_gc
= 1;
6854 /* Which window is that in? */
6855 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
6857 /* If we were displaying active text in another window, clear that. */
6858 if (! EQ (window
, dpyinfo
->mouse_face_window
))
6859 clear_mouse_face (dpyinfo
);
6861 /* Not on a window -> return. */
6862 if (!WINDOWP (window
))
6865 /* Convert to window-relative pixel coordinates. */
6866 w
= XWINDOW (window
);
6867 frame_to_window_pixel_xy (w
, &x
, &y
);
6869 /* Handle tool-bar window differently since it doesn't display a
6871 if (EQ (window
, f
->tool_bar_window
))
6873 note_tool_bar_highlight (f
, x
, y
);
6877 /* Mouse is on the mode or header line? */
6878 if (portion
== 1 || portion
== 3)
6880 note_mode_line_highlight (w
, x
, portion
== 1);
6885 cursor
= f
->output_data
.x
->horizontal_drag_cursor
;
6887 cursor
= f
->output_data
.x
->text_cursor
;
6889 /* Are we in a window whose display is up to date?
6890 And verify the buffer's text has not changed. */
6891 b
= XBUFFER (w
->buffer
);
6892 if (/* Within text portion of the window. */
6894 && EQ (w
->window_end_valid
, w
->buffer
)
6895 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
6896 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
6898 int hpos
, vpos
, pos
, i
, area
;
6899 struct glyph
*glyph
;
6901 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
6902 Lisp_Object
*overlay_vec
= NULL
;
6904 struct buffer
*obuf
;
6905 int obegv
, ozv
, same_region
;
6907 /* Find the glyph under X/Y. */
6908 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
, 0);
6910 /* Clear mouse face if X/Y not over text. */
6912 || area
!= TEXT_AREA
6913 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
6915 if (clear_mouse_face (dpyinfo
))
6920 pos
= glyph
->charpos
;
6921 object
= glyph
->object
;
6922 if (!STRINGP (object
) && !BUFFERP (object
))
6925 /* If we get an out-of-range value, return now; avoid an error. */
6926 if (BUFFERP (object
) && pos
> BUF_Z (b
))
6929 /* Make the window's buffer temporarily current for
6930 overlays_at and compute_char_face. */
6931 obuf
= current_buffer
;
6938 /* Is this char mouse-active or does it have help-echo? */
6939 position
= make_number (pos
);
6941 if (BUFFERP (object
))
6943 /* Put all the overlays we want in a vector in overlay_vec.
6944 Store the length in len. If there are more than 10, make
6945 enough space for all, and try again. */
6947 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6948 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
6949 if (noverlays
> len
)
6952 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6953 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
6956 /* Sort overlays into increasing priority order. */
6957 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
6962 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
6963 && vpos
>= dpyinfo
->mouse_face_beg_row
6964 && vpos
<= dpyinfo
->mouse_face_end_row
6965 && (vpos
> dpyinfo
->mouse_face_beg_row
6966 || hpos
>= dpyinfo
->mouse_face_beg_col
)
6967 && (vpos
< dpyinfo
->mouse_face_end_row
6968 || hpos
< dpyinfo
->mouse_face_end_col
6969 || dpyinfo
->mouse_face_past_end
));
6974 /* Check mouse-face highlighting. */
6976 /* If there exists an overlay with mouse-face overlapping
6977 the one we are currently highlighting, we have to
6978 check if we enter the overlapping overlay, and then
6979 highlight only that. */
6980 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
6981 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
6983 /* Find the highest priority overlay that has a mouse-face
6986 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
6988 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
6989 if (!NILP (mouse_face
))
6990 overlay
= overlay_vec
[i
];
6993 /* If we're actually highlighting the same overlay as
6994 before, there's no need to do that again. */
6996 && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
6997 goto check_help_echo
;
6999 dpyinfo
->mouse_face_overlay
= overlay
;
7001 /* Clear the display of the old active region, if any. */
7002 if (clear_mouse_face (dpyinfo
))
7005 /* If no overlay applies, get a text property. */
7007 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
7009 /* Handle the overlay case. */
7010 if (!NILP (overlay
))
7012 /* Find the range of text around this char that
7013 should be active. */
7014 Lisp_Object before
, after
;
7017 before
= Foverlay_start (overlay
);
7018 after
= Foverlay_end (overlay
);
7019 /* Record this as the current active region. */
7020 fast_find_position (w
, XFASTINT (before
),
7021 &dpyinfo
->mouse_face_beg_col
,
7022 &dpyinfo
->mouse_face_beg_row
,
7023 &dpyinfo
->mouse_face_beg_x
,
7024 &dpyinfo
->mouse_face_beg_y
, Qnil
);
7026 dpyinfo
->mouse_face_past_end
7027 = !fast_find_position (w
, XFASTINT (after
),
7028 &dpyinfo
->mouse_face_end_col
,
7029 &dpyinfo
->mouse_face_end_row
,
7030 &dpyinfo
->mouse_face_end_x
,
7031 &dpyinfo
->mouse_face_end_y
, Qnil
);
7032 dpyinfo
->mouse_face_window
= window
;
7033 dpyinfo
->mouse_face_face_id
7034 = face_at_buffer_position (w
, pos
, 0, 0,
7035 &ignore
, pos
+ 1, 1);
7037 /* Display it as active. */
7038 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7041 /* Handle the text property case. */
7042 else if (!NILP (mouse_face
) && BUFFERP (object
))
7044 /* Find the range of text around this char that
7045 should be active. */
7046 Lisp_Object before
, after
, beginning
, end
;
7049 beginning
= Fmarker_position (w
->start
);
7050 end
= make_number (BUF_Z (XBUFFER (object
))
7051 - XFASTINT (w
->window_end_pos
));
7053 = Fprevious_single_property_change (make_number (pos
+ 1),
7057 = Fnext_single_property_change (position
, Qmouse_face
,
7060 /* Record this as the current active region. */
7061 fast_find_position (w
, XFASTINT (before
),
7062 &dpyinfo
->mouse_face_beg_col
,
7063 &dpyinfo
->mouse_face_beg_row
,
7064 &dpyinfo
->mouse_face_beg_x
,
7065 &dpyinfo
->mouse_face_beg_y
, Qnil
);
7066 dpyinfo
->mouse_face_past_end
7067 = !fast_find_position (w
, XFASTINT (after
),
7068 &dpyinfo
->mouse_face_end_col
,
7069 &dpyinfo
->mouse_face_end_row
,
7070 &dpyinfo
->mouse_face_end_x
,
7071 &dpyinfo
->mouse_face_end_y
, Qnil
);
7072 dpyinfo
->mouse_face_window
= window
;
7074 if (BUFFERP (object
))
7075 dpyinfo
->mouse_face_face_id
7076 = face_at_buffer_position (w
, pos
, 0, 0,
7077 &ignore
, pos
+ 1, 1);
7079 /* Display it as active. */
7080 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7083 else if (!NILP (mouse_face
) && STRINGP (object
))
7088 b
= Fprevious_single_property_change (make_number (pos
+ 1),
7091 e
= Fnext_single_property_change (position
, Qmouse_face
,
7094 b
= make_number (0);
7096 e
= make_number (XSTRING (object
)->size
- 1);
7097 fast_find_string_pos (w
, XINT (b
), object
,
7098 &dpyinfo
->mouse_face_beg_col
,
7099 &dpyinfo
->mouse_face_beg_row
,
7100 &dpyinfo
->mouse_face_beg_x
,
7101 &dpyinfo
->mouse_face_beg_y
, 0);
7102 fast_find_string_pos (w
, XINT (e
), object
,
7103 &dpyinfo
->mouse_face_end_col
,
7104 &dpyinfo
->mouse_face_end_row
,
7105 &dpyinfo
->mouse_face_end_x
,
7106 &dpyinfo
->mouse_face_end_y
, 1);
7107 dpyinfo
->mouse_face_past_end
= 0;
7108 dpyinfo
->mouse_face_window
= window
;
7109 dpyinfo
->mouse_face_face_id
7110 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
7112 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7115 else if (STRINGP (object
) && NILP (mouse_face
))
7117 /* A string which doesn't have mouse-face, but
7118 the text ``under'' it might have. */
7119 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
7120 int start
= MATRIX_ROW_START_CHARPOS (r
);
7122 pos
= string_buffer_position (w
, object
, start
);
7124 mouse_face
= get_char_property_and_overlay (make_number (pos
),
7128 if (!NILP (mouse_face
) && !NILP (overlay
))
7130 Lisp_Object before
= Foverlay_start (overlay
);
7131 Lisp_Object after
= Foverlay_end (overlay
);
7134 /* Note that we might not be able to find position
7135 BEFORE in the glyph matrix if the overlay is
7136 entirely covered by a `display' property. In
7137 this case, we overshoot. So let's stop in
7138 the glyph matrix before glyphs for OBJECT. */
7139 fast_find_position (w
, XFASTINT (before
),
7140 &dpyinfo
->mouse_face_beg_col
,
7141 &dpyinfo
->mouse_face_beg_row
,
7142 &dpyinfo
->mouse_face_beg_x
,
7143 &dpyinfo
->mouse_face_beg_y
,
7146 dpyinfo
->mouse_face_past_end
7147 = !fast_find_position (w
, XFASTINT (after
),
7148 &dpyinfo
->mouse_face_end_col
,
7149 &dpyinfo
->mouse_face_end_row
,
7150 &dpyinfo
->mouse_face_end_x
,
7151 &dpyinfo
->mouse_face_end_y
,
7153 dpyinfo
->mouse_face_window
= window
;
7154 dpyinfo
->mouse_face_face_id
7155 = face_at_buffer_position (w
, pos
, 0, 0,
7156 &ignore
, pos
+ 1, 1);
7158 /* Display it as active. */
7159 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7167 /* Look for a `help-echo' property. */
7169 Lisp_Object help
, overlay
;
7171 /* Check overlays first. */
7172 help
= overlay
= Qnil
;
7173 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
7175 overlay
= overlay_vec
[i
];
7176 help
= Foverlay_get (overlay
, Qhelp_echo
);
7182 help_echo_window
= window
;
7183 help_echo_object
= overlay
;
7184 help_echo_pos
= pos
;
7188 Lisp_Object object
= glyph
->object
;
7189 int charpos
= glyph
->charpos
;
7191 /* Try text properties. */
7192 if (STRINGP (object
)
7194 && charpos
< XSTRING (object
)->size
)
7196 help
= Fget_text_property (make_number (charpos
),
7197 Qhelp_echo
, object
);
7200 /* If the string itself doesn't specify a help-echo,
7201 see if the buffer text ``under'' it does. */
7203 = MATRIX_ROW (w
->current_matrix
, vpos
);
7204 int start
= MATRIX_ROW_START_CHARPOS (r
);
7205 int pos
= string_buffer_position (w
, object
, start
);
7208 help
= Fget_char_property (make_number (pos
),
7209 Qhelp_echo
, w
->buffer
);
7218 else if (BUFFERP (object
)
7221 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
7227 help_echo_window
= window
;
7228 help_echo_object
= object
;
7229 help_echo_pos
= charpos
;
7236 current_buffer
= obuf
;
7242 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
7246 redo_mouse_highlight ()
7248 if (!NILP (last_mouse_motion_frame
)
7249 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
7250 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
7251 last_mouse_motion_event
.x
,
7252 last_mouse_motion_event
.y
);
7257 /***********************************************************************
7259 ***********************************************************************/
7261 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
7262 struct glyph
**, int *, int *, int *));
7264 /* Tool-bar item index of the item on which a mouse button was pressed
7267 static int last_tool_bar_item
;
7270 /* Get information about the tool-bar item at position X/Y on frame F.
7271 Return in *GLYPH a pointer to the glyph of the tool-bar item in
7272 the current matrix of the tool-bar window of F, or NULL if not
7273 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
7274 item in F->tool_bar_items. Value is
7276 -1 if X/Y is not on a tool-bar item
7277 0 if X/Y is on the same item that was highlighted before.
7281 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
7284 struct glyph
**glyph
;
7285 int *hpos
, *vpos
, *prop_idx
;
7287 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7288 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7291 /* Find the glyph under X/Y. */
7292 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
, 0);
7296 /* Get the start of this tool-bar item's properties in
7297 f->tool_bar_items. */
7298 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
7301 /* Is mouse on the highlighted item? */
7302 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
7303 && *vpos
>= dpyinfo
->mouse_face_beg_row
7304 && *vpos
<= dpyinfo
->mouse_face_end_row
7305 && (*vpos
> dpyinfo
->mouse_face_beg_row
7306 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
7307 && (*vpos
< dpyinfo
->mouse_face_end_row
7308 || *hpos
< dpyinfo
->mouse_face_end_col
7309 || dpyinfo
->mouse_face_past_end
))
7316 /* Handle mouse button event on the tool-bar of frame F, at
7317 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
7321 x_handle_tool_bar_click (f
, button_event
)
7323 XButtonEvent
*button_event
;
7325 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7326 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7327 int hpos
, vpos
, prop_idx
;
7328 struct glyph
*glyph
;
7329 Lisp_Object enabled_p
;
7330 int x
= button_event
->x
;
7331 int y
= button_event
->y
;
7333 /* If not on the highlighted tool-bar item, return. */
7334 frame_to_window_pixel_xy (w
, &x
, &y
);
7335 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
7338 /* If item is disabled, do nothing. */
7339 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7340 if (NILP (enabled_p
))
7343 if (button_event
->type
== ButtonPress
)
7345 /* Show item in pressed state. */
7346 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
7347 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
7348 last_tool_bar_item
= prop_idx
;
7352 Lisp_Object key
, frame
;
7353 struct input_event event
;
7355 /* Show item in released state. */
7356 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
7357 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
7359 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
7361 XSETFRAME (frame
, f
);
7362 event
.kind
= TOOL_BAR_EVENT
;
7363 event
.frame_or_window
= frame
;
7365 kbd_buffer_store_event (&event
);
7367 event
.kind
= TOOL_BAR_EVENT
;
7368 event
.frame_or_window
= frame
;
7370 event
.modifiers
= x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
7371 button_event
->state
);
7372 kbd_buffer_store_event (&event
);
7373 last_tool_bar_item
= -1;
7378 /* Possibly highlight a tool-bar item on frame F when mouse moves to
7379 tool-bar window-relative coordinates X/Y. Called from
7380 note_mouse_highlight. */
7383 note_tool_bar_highlight (f
, x
, y
)
7387 Lisp_Object window
= f
->tool_bar_window
;
7388 struct window
*w
= XWINDOW (window
);
7389 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7391 struct glyph
*glyph
;
7392 struct glyph_row
*row
;
7394 Lisp_Object enabled_p
;
7396 enum draw_glyphs_face draw
;
7397 int mouse_down_p
, rc
;
7399 /* Function note_mouse_highlight is called with negative x(y
7400 values when mouse moves outside of the frame. */
7401 if (x
<= 0 || y
<= 0)
7403 clear_mouse_face (dpyinfo
);
7407 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
7410 /* Not on tool-bar item. */
7411 clear_mouse_face (dpyinfo
);
7417 clear_mouse_face (dpyinfo
);
7419 /* Mouse is down, but on different tool-bar item? */
7420 mouse_down_p
= (dpyinfo
->grabbed
7421 && f
== last_mouse_frame
7422 && FRAME_LIVE_P (f
));
7424 && last_tool_bar_item
!= prop_idx
)
7427 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
7428 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
7430 /* If tool-bar item is not enabled, don't highlight it. */
7431 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7432 if (!NILP (enabled_p
))
7434 /* Compute the x-position of the glyph. In front and past the
7435 image is a space. We include this is the highlighted area. */
7436 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
7437 for (i
= x
= 0; i
< hpos
; ++i
)
7438 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
7440 /* Record this as the current active region. */
7441 dpyinfo
->mouse_face_beg_col
= hpos
;
7442 dpyinfo
->mouse_face_beg_row
= vpos
;
7443 dpyinfo
->mouse_face_beg_x
= x
;
7444 dpyinfo
->mouse_face_beg_y
= row
->y
;
7445 dpyinfo
->mouse_face_past_end
= 0;
7447 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
7448 dpyinfo
->mouse_face_end_row
= vpos
;
7449 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
7450 dpyinfo
->mouse_face_end_y
= row
->y
;
7451 dpyinfo
->mouse_face_window
= window
;
7452 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
7454 /* Display it as active. */
7455 show_mouse_face (dpyinfo
, draw
);
7456 dpyinfo
->mouse_face_image_state
= draw
;
7461 /* Set help_echo to a help string.to display for this tool-bar item.
7462 XTread_socket does the rest. */
7463 help_echo_object
= help_echo_window
= Qnil
;
7465 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
7466 if (NILP (help_echo
))
7467 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
7472 /* Find the glyph matrix position of buffer position CHARPOS in window
7473 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
7474 current glyphs must be up to date. If CHARPOS is above window
7475 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
7476 of last line in W. In the row containing CHARPOS, stop before glyphs
7477 having STOP as object. */
7479 #if 0 /* This is a version of fast_find_position that's more correct
7480 in the presence of hscrolling, for example. I didn't install
7481 it right away because the problem fixed is minor, it failed
7482 in 20.x as well, and I think it's too risky to install
7483 so near the release of 21.1. 2001-09-25 gerd. */
7486 fast_find_position (w
, charpos
, hpos
, vpos
, x
, y
, stop
)
7489 int *hpos
, *vpos
, *x
, *y
;
7492 struct glyph_row
*row
, *first
;
7493 struct glyph
*glyph
, *end
;
7494 int i
, past_end
= 0;
7496 first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7497 row
= row_containing_pos (w
, charpos
, first
, NULL
, 0);
7500 if (charpos
< MATRIX_ROW_START_CHARPOS (first
))
7502 *x
= *y
= *hpos
= *vpos
= 0;
7507 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
7514 *vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7516 glyph
= row
->glyphs
[TEXT_AREA
];
7517 end
= glyph
+ row
->used
[TEXT_AREA
];
7519 /* Skip over glyphs not having an object at the start of the row.
7520 These are special glyphs like truncation marks on terminal
7522 if (row
->displays_text_p
)
7524 && INTEGERP (glyph
->object
)
7525 && !EQ (stop
, glyph
->object
)
7526 && glyph
->charpos
< 0)
7528 *x
+= glyph
->pixel_width
;
7533 && !INTEGERP (glyph
->object
)
7534 && !EQ (stop
, glyph
->object
)
7535 && (!BUFFERP (glyph
->object
)
7536 || glyph
->charpos
< charpos
))
7538 *x
+= glyph
->pixel_width
;
7542 *hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
7549 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
, stop
)
7552 int *hpos
, *vpos
, *x
, *y
;
7557 int maybe_next_line_p
= 0;
7558 int line_start_position
;
7559 int yb
= window_text_bottom_y (w
);
7560 struct glyph_row
*row
, *best_row
;
7561 int row_vpos
, best_row_vpos
;
7564 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7565 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7569 if (row
->used
[TEXT_AREA
])
7570 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
7572 line_start_position
= 0;
7574 if (line_start_position
> pos
)
7576 /* If the position sought is the end of the buffer,
7577 don't include the blank lines at the bottom of the window. */
7578 else if (line_start_position
== pos
7579 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
7581 maybe_next_line_p
= 1;
7584 else if (line_start_position
> 0)
7587 best_row_vpos
= row_vpos
;
7590 if (row
->y
+ row
->height
>= yb
)
7597 /* Find the right column within BEST_ROW. */
7599 current_x
= best_row
->x
;
7600 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
7602 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
7603 int charpos
= glyph
->charpos
;
7605 if (BUFFERP (glyph
->object
))
7610 *vpos
= best_row_vpos
;
7615 else if (charpos
> pos
)
7618 else if (EQ (glyph
->object
, stop
))
7623 current_x
+= glyph
->pixel_width
;
7626 /* If we're looking for the end of the buffer,
7627 and we didn't find it in the line we scanned,
7628 use the start of the following line. */
7629 if (maybe_next_line_p
)
7634 current_x
= best_row
->x
;
7637 *vpos
= best_row_vpos
;
7638 *hpos
= lastcol
+ 1;
7647 /* Find the position of the the glyph for position POS in OBJECT in
7648 window W's current matrix, and return in *X/*Y the pixel
7649 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
7651 RIGHT_P non-zero means return the position of the right edge of the
7652 glyph, RIGHT_P zero means return the left edge position.
7654 If no glyph for POS exists in the matrix, return the position of
7655 the glyph with the next smaller position that is in the matrix, if
7656 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
7657 exists in the matrix, return the position of the glyph with the
7658 next larger position in OBJECT.
7660 Value is non-zero if a glyph was found. */
7663 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
7667 int *hpos
, *vpos
, *x
, *y
;
7670 int yb
= window_text_bottom_y (w
);
7671 struct glyph_row
*r
;
7672 struct glyph
*best_glyph
= NULL
;
7673 struct glyph_row
*best_row
= NULL
;
7676 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7677 r
->enabled_p
&& r
->y
< yb
;
7680 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7681 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
7684 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
7685 if (EQ (g
->object
, object
))
7687 if (g
->charpos
== pos
)
7694 else if (best_glyph
== NULL
7695 || ((abs (g
->charpos
- pos
)
7696 < abs (best_glyph
->charpos
- pos
))
7699 : g
->charpos
> pos
)))
7713 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
7717 *x
+= best_glyph
->pixel_width
;
7722 *vpos
= best_row
- w
->current_matrix
->rows
;
7725 return best_glyph
!= NULL
;
7729 /* Display the active region described by mouse_face_*
7730 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7733 show_mouse_face (dpyinfo
, draw
)
7734 struct x_display_info
*dpyinfo
;
7735 enum draw_glyphs_face draw
;
7737 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
7738 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7740 if (/* If window is in the process of being destroyed, don't bother
7742 w
->current_matrix
!= NULL
7743 /* Recognize when we are called to operate on rows that don't exist
7744 anymore. This can happen when a window is split. */
7745 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
7747 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
7748 struct glyph_row
*row
, *first
, *last
;
7750 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
7751 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
7753 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
7755 int start_hpos
, end_hpos
, start_x
;
7757 /* For all but the first row, the highlight starts at column 0. */
7760 start_hpos
= dpyinfo
->mouse_face_beg_col
;
7761 start_x
= dpyinfo
->mouse_face_beg_x
;
7770 end_hpos
= dpyinfo
->mouse_face_end_col
;
7772 end_hpos
= row
->used
[TEXT_AREA
];
7774 if (end_hpos
> start_hpos
)
7776 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
7777 start_hpos
, end_hpos
, draw
, 0);
7779 row
->mouse_face_p
= draw
== DRAW_MOUSE_FACE
|| DRAW_IMAGE_RAISED
;
7783 /* When we've written over the cursor, arrange for it to
7784 be displayed again. */
7785 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
7786 x_display_cursor (w
, 1,
7787 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
7788 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
7791 /* Change the mouse cursor. */
7792 if (draw
== DRAW_NORMAL_TEXT
)
7793 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7794 f
->output_data
.x
->text_cursor
);
7795 else if (draw
== DRAW_MOUSE_FACE
)
7796 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7797 f
->output_data
.x
->cross_cursor
);
7799 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7800 f
->output_data
.x
->nontext_cursor
);
7803 /* Clear out the mouse-highlighted active region.
7804 Redraw it un-highlighted first. Value is non-zero if mouse
7805 face was actually drawn unhighlighted. */
7808 clear_mouse_face (dpyinfo
)
7809 struct x_display_info
*dpyinfo
;
7813 if (!NILP (dpyinfo
->mouse_face_window
))
7815 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
7819 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7820 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7821 dpyinfo
->mouse_face_window
= Qnil
;
7822 dpyinfo
->mouse_face_overlay
= Qnil
;
7827 /* Clear any mouse-face on window W. This function is part of the
7828 redisplay interface, and is called from try_window_id and similar
7829 functions to ensure the mouse-highlight is off. */
7832 x_clear_mouse_face (w
)
7835 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
7839 XSETWINDOW (window
, w
);
7840 if (EQ (window
, dpyinfo
->mouse_face_window
))
7841 clear_mouse_face (dpyinfo
);
7846 /* Just discard the mouse face information for frame F, if any.
7847 This is used when the size of F is changed. */
7850 cancel_mouse_face (f
)
7854 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7856 window
= dpyinfo
->mouse_face_window
;
7857 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
7859 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7860 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7861 dpyinfo
->mouse_face_window
= Qnil
;
7866 static int glyph_rect
P_ ((struct frame
*f
, int, int, XRectangle
*));
7869 /* Try to determine frame pixel position and size of the glyph under
7870 frame pixel coordinates X/Y on frame F . Return the position and
7871 size in *RECT. Value is non-zero if we could compute these
7875 glyph_rect (f
, x
, y
, rect
)
7881 int part
, found
= 0;
7883 window
= window_from_coordinates (f
, x
, y
, &part
, 0);
7886 struct window
*w
= XWINDOW (window
);
7887 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7888 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
7890 frame_to_window_pixel_xy (w
, &x
, &y
);
7892 for (; !found
&& r
< end
&& r
->enabled_p
; ++r
)
7895 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7896 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
7899 for (gx
= r
->x
; !found
&& g
< end
; gx
+= g
->pixel_width
, ++g
)
7902 rect
->width
= g
->pixel_width
;
7903 rect
->height
= r
->height
;
7904 rect
->x
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
7905 rect
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
7915 /* Return the current position of the mouse.
7916 *FP should be a frame which indicates which display to ask about.
7918 If the mouse movement started in a scroll bar, set *FP, *BAR_WINDOW,
7919 and *PART to the frame, window, and scroll bar part that the mouse
7920 is over. Set *X and *Y to the portion and whole of the mouse's
7921 position on the scroll bar.
7923 If the mouse movement started elsewhere, set *FP to the frame the
7924 mouse is on, *BAR_WINDOW to nil, and *X and *Y to the character cell
7927 Set *TIME to the server time-stamp for the time at which the mouse
7928 was at this position.
7930 Don't store anything if we don't have a valid set of values to report.
7932 This clears the mouse_moved flag, so we can wait for the next mouse
7936 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
7939 Lisp_Object
*bar_window
;
7940 enum scroll_bar_part
*part
;
7942 unsigned long *time
;
7948 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
7949 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
7955 Window dummy_window
;
7958 Lisp_Object frame
, tail
;
7960 /* Clear the mouse-moved flag for every frame on this display. */
7961 FOR_EACH_FRAME (tail
, frame
)
7962 if (FRAME_X_DISPLAY (XFRAME (frame
)) == FRAME_X_DISPLAY (*fp
))
7963 XFRAME (frame
)->mouse_moved
= 0;
7965 last_mouse_scroll_bar
= Qnil
;
7967 /* Figure out which root window we're on. */
7968 XQueryPointer (FRAME_X_DISPLAY (*fp
),
7969 DefaultRootWindow (FRAME_X_DISPLAY (*fp
)),
7971 /* The root window which contains the pointer. */
7974 /* Trash which we can't trust if the pointer is on
7975 a different screen. */
7978 /* The position on that root window. */
7981 /* More trash we can't trust. */
7984 /* Modifier keys and pointer buttons, about which
7986 (unsigned int *) &dummy
);
7988 /* Now we have a position on the root; find the innermost window
7989 containing the pointer. */
7993 int parent_x
= 0, parent_y
= 0;
7998 /* XTranslateCoordinates can get errors if the window
7999 structure is changing at the same time this function
8000 is running. So at least we must not crash from them. */
8002 count
= x_catch_errors (FRAME_X_DISPLAY (*fp
));
8004 if (FRAME_X_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
8005 && FRAME_LIVE_P (last_mouse_frame
))
8007 /* If mouse was grabbed on a frame, give coords for that frame
8008 even if the mouse is now outside it. */
8009 XTranslateCoordinates (FRAME_X_DISPLAY (*fp
),
8011 /* From-window, to-window. */
8012 root
, FRAME_X_WINDOW (last_mouse_frame
),
8014 /* From-position, to-position. */
8015 root_x
, root_y
, &win_x
, &win_y
,
8019 f1
= last_mouse_frame
;
8025 XTranslateCoordinates (FRAME_X_DISPLAY (*fp
),
8027 /* From-window, to-window. */
8030 /* From-position, to-position. */
8031 root_x
, root_y
, &win_x
, &win_y
,
8036 if (child
== None
|| child
== win
)
8044 /* Now we know that:
8045 win is the innermost window containing the pointer
8046 (XTC says it has no child containing the pointer),
8047 win_x and win_y are the pointer's position in it
8048 (XTC did this the last time through), and
8049 parent_x and parent_y are the pointer's position in win's parent.
8050 (They are what win_x and win_y were when win was child.
8051 If win is the root window, it has no parent, and
8052 parent_{x,y} are invalid, but that's okay, because we'll
8053 never use them in that case.) */
8055 /* Is win one of our frames? */
8056 f1
= x_any_window_to_frame (FRAME_X_DISPLAY_INFO (*fp
), win
);
8058 #ifdef USE_X_TOOLKIT
8059 /* If we end up with the menu bar window, say it's not
8062 && f1
->output_data
.x
->menubar_widget
8063 && win
== XtWindow (f1
->output_data
.x
->menubar_widget
))
8065 #endif /* USE_X_TOOLKIT */
8068 if (x_had_errors_p (FRAME_X_DISPLAY (*fp
)))
8071 x_uncatch_errors (FRAME_X_DISPLAY (*fp
), count
);
8073 /* If not, is it one of our scroll bars? */
8076 struct scroll_bar
*bar
= x_window_to_scroll_bar (win
);
8080 f1
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8086 if (f1
== 0 && insist
> 0)
8087 f1
= SELECTED_FRAME ();
8091 /* Ok, we found a frame. Store all the values.
8092 last_mouse_glyph is a rectangle used to reduce the
8093 generation of mouse events. To not miss any motion
8094 events, we must divide the frame into rectangles of the
8095 size of the smallest character that could be displayed
8096 on it, i.e. into the same rectangles that matrices on
8097 the frame are divided into. */
8099 int width
, height
, gx
, gy
;
8102 if (glyph_rect (f1
, win_x
, win_y
, &rect
))
8103 last_mouse_glyph
= rect
;
8106 width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
8107 height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
8111 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
8112 round down even for negative values. */
8117 gx
= (gx
+ width
- 1) / width
* width
;
8118 gy
= (gy
+ height
- 1) / height
* height
;
8120 last_mouse_glyph
.width
= width
;
8121 last_mouse_glyph
.height
= height
;
8122 last_mouse_glyph
.x
= gx
;
8123 last_mouse_glyph
.y
= gy
;
8129 XSETINT (*x
, win_x
);
8130 XSETINT (*y
, win_y
);
8131 *time
= last_mouse_movement_time
;
8140 #ifdef USE_X_TOOLKIT
8142 /* Atimer callback function for TIMER. Called every 0.1s to process
8143 Xt timeouts, if needed. We must avoid calling XtAppPending as
8144 much as possible because that function does an implicit XFlush
8145 that slows us down. */
8148 x_process_timeouts (timer
)
8149 struct atimer
*timer
;
8151 if (toolkit_scroll_bar_interaction
|| popup_activated_flag
)
8154 while (XtAppPending (Xt_app_con
) & XtIMTimer
)
8155 XtAppProcessEvent (Xt_app_con
, XtIMTimer
);
8160 #endif /* USE_X_TOOLKIT */
8163 /* Scroll bar support. */
8165 /* Given an X window ID, find the struct scroll_bar which manages it.
8166 This can be called in GC, so we have to make sure to strip off mark
8169 static struct scroll_bar
*
8170 x_window_to_scroll_bar (window_id
)
8175 for (tail
= Vframe_list
;
8176 XGCTYPE (tail
) == Lisp_Cons
;
8179 Lisp_Object frame
, bar
, condemned
;
8181 frame
= XCAR (tail
);
8182 /* All elements of Vframe_list should be frames. */
8183 if (! GC_FRAMEP (frame
))
8186 /* Scan this frame's scroll bar list for a scroll bar with the
8188 condemned
= FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame
));
8189 for (bar
= FRAME_SCROLL_BARS (XFRAME (frame
));
8190 /* This trick allows us to search both the ordinary and
8191 condemned scroll bar lists with one loop. */
8192 ! GC_NILP (bar
) || (bar
= condemned
,
8195 bar
= XSCROLL_BAR (bar
)->next
)
8196 if (SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)) == window_id
)
8197 return XSCROLL_BAR (bar
);
8204 #if defined USE_LUCID
8206 /* Return the Lucid menu bar WINDOW is part of. Return null
8207 if WINDOW is not part of a menu bar. */
8210 x_window_to_menu_bar (window
)
8215 for (tail
= Vframe_list
;
8216 XGCTYPE (tail
) == Lisp_Cons
;
8219 Lisp_Object frame
= XCAR (tail
);
8220 Widget menu_bar
= XFRAME (frame
)->output_data
.x
->menubar_widget
;
8222 if (menu_bar
&& xlwmenu_window_p (menu_bar
, window
))
8229 #endif /* USE_LUCID */
8232 /************************************************************************
8234 ************************************************************************/
8236 #ifdef USE_TOOLKIT_SCROLL_BARS
8238 static void x_scroll_bar_to_input_event
P_ ((XEvent
*, struct input_event
*));
8239 static void x_send_scroll_bar_event
P_ ((Lisp_Object
, int, int, int));
8240 static void x_create_toolkit_scroll_bar
P_ ((struct frame
*,
8241 struct scroll_bar
*));
8242 static void x_set_toolkit_scroll_bar_thumb
P_ ((struct scroll_bar
*,
8246 /* Id of action hook installed for scroll bars. */
8248 static XtActionHookId action_hook_id
;
8250 /* Lisp window being scrolled. Set when starting to interact with
8251 a toolkit scroll bar, reset to nil when ending the interaction. */
8253 static Lisp_Object window_being_scrolled
;
8255 /* Last scroll bar part sent in xm_scroll_callback. */
8257 static int last_scroll_bar_part
;
8259 /* Whether this is an Xaw with arrow-scrollbars. This should imply
8260 that movements of 1/20 of the screen size are mapped to up/down. */
8262 static Boolean xaw3d_arrow_scroll
;
8264 /* Whether the drag scrolling maintains the mouse at the top of the
8265 thumb. If not, resizing the thumb needs to be done more carefully
8266 to avoid jerkyness. */
8268 static Boolean xaw3d_pick_top
;
8271 /* Action hook installed via XtAppAddActionHook when toolkit scroll
8272 bars are used.. The hook is responsible for detecting when
8273 the user ends an interaction with the scroll bar, and generates
8274 a `end-scroll' scroll_bar_click' event if so. */
8277 xt_action_hook (widget
, client_data
, action_name
, event
, params
,
8280 XtPointer client_data
;
8284 Cardinal
*num_params
;
8290 scroll_bar_p
= XmIsScrollBar (widget
);
8291 end_action
= "Release";
8292 #else /* !USE_MOTIF i.e. use Xaw */
8293 scroll_bar_p
= XtIsSubclass (widget
, scrollbarWidgetClass
);
8294 end_action
= "EndScroll";
8295 #endif /* USE_MOTIF */
8298 && strcmp (action_name
, end_action
) == 0
8299 && WINDOWP (window_being_scrolled
))
8303 x_send_scroll_bar_event (window_being_scrolled
,
8304 scroll_bar_end_scroll
, 0, 0);
8305 w
= XWINDOW (window_being_scrolled
);
8306 XSCROLL_BAR (w
->vertical_scroll_bar
)->dragging
= Qnil
;
8307 window_being_scrolled
= Qnil
;
8308 last_scroll_bar_part
= -1;
8310 /* Xt timeouts no longer needed. */
8311 toolkit_scroll_bar_interaction
= 0;
8315 /* A vector of windows used for communication between
8316 x_send_scroll_bar_event and x_scroll_bar_to_input_event. */
8318 static struct window
**scroll_bar_windows
;
8319 static int scroll_bar_windows_size
;
8322 /* Send a client message with message type Xatom_Scrollbar for a
8323 scroll action to the frame of WINDOW. PART is a value identifying
8324 the part of the scroll bar that was clicked on. PORTION is the
8325 amount to scroll of a whole of WHOLE. */
8328 x_send_scroll_bar_event (window
, part
, portion
, whole
)
8330 int part
, portion
, whole
;
8333 XClientMessageEvent
*ev
= (XClientMessageEvent
*) &event
;
8334 struct window
*w
= XWINDOW (window
);
8335 struct frame
*f
= XFRAME (w
->frame
);
8340 /* Construct a ClientMessage event to send to the frame. */
8341 ev
->type
= ClientMessage
;
8342 ev
->message_type
= FRAME_X_DISPLAY_INFO (f
)->Xatom_Scrollbar
;
8343 ev
->display
= FRAME_X_DISPLAY (f
);
8344 ev
->window
= FRAME_X_WINDOW (f
);
8347 /* We can only transfer 32 bits in the XClientMessageEvent, which is
8348 not enough to store a pointer or Lisp_Object on a 64 bit system.
8349 So, store the window in scroll_bar_windows and pass the index
8350 into that array in the event. */
8351 for (i
= 0; i
< scroll_bar_windows_size
; ++i
)
8352 if (scroll_bar_windows
[i
] == NULL
)
8355 if (i
== scroll_bar_windows_size
)
8357 int new_size
= max (10, 2 * scroll_bar_windows_size
);
8358 size_t nbytes
= new_size
* sizeof *scroll_bar_windows
;
8359 size_t old_nbytes
= scroll_bar_windows_size
* sizeof *scroll_bar_windows
;
8361 scroll_bar_windows
= (struct window
**) xrealloc (scroll_bar_windows
,
8363 bzero (&scroll_bar_windows
[i
], nbytes
- old_nbytes
);
8364 scroll_bar_windows_size
= new_size
;
8367 scroll_bar_windows
[i
] = w
;
8368 ev
->data
.l
[0] = (long) i
;
8369 ev
->data
.l
[1] = (long) part
;
8370 ev
->data
.l
[2] = (long) 0;
8371 ev
->data
.l
[3] = (long) portion
;
8372 ev
->data
.l
[4] = (long) whole
;
8374 /* Make Xt timeouts work while the scroll bar is active. */
8375 toolkit_scroll_bar_interaction
= 1;
8377 /* Setting the event mask to zero means that the message will
8378 be sent to the client that created the window, and if that
8379 window no longer exists, no event will be sent. */
8380 XSendEvent (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), False
, 0, &event
);
8385 /* Transform a scroll bar ClientMessage EVENT to an Emacs input event
8389 x_scroll_bar_to_input_event (event
, ievent
)
8391 struct input_event
*ievent
;
8393 XClientMessageEvent
*ev
= (XClientMessageEvent
*) event
;
8398 w
= scroll_bar_windows
[ev
->data
.l
[0]];
8399 scroll_bar_windows
[ev
->data
.l
[0]] = NULL
;
8401 XSETWINDOW (window
, w
);
8402 f
= XFRAME (w
->frame
);
8404 ievent
->kind
= scroll_bar_click
;
8405 ievent
->frame_or_window
= window
;
8407 ievent
->timestamp
= XtLastTimestampProcessed (FRAME_X_DISPLAY (f
));
8408 ievent
->part
= ev
->data
.l
[1];
8409 ievent
->code
= ev
->data
.l
[2];
8410 ievent
->x
= make_number ((int) ev
->data
.l
[3]);
8411 ievent
->y
= make_number ((int) ev
->data
.l
[4]);
8412 ievent
->modifiers
= 0;
8418 /* Minimum and maximum values used for Motif scroll bars. */
8421 #define XM_SB_MAX 10000000
8422 #define XM_SB_RANGE (XM_SB_MAX - XM_SB_MIN)
8425 /* Scroll bar callback for Motif scroll bars. WIDGET is the scroll
8426 bar widget. CLIENT_DATA is a pointer to the scroll_bar structure.
8427 CALL_DATA is a pointer a a XmScrollBarCallbackStruct. */
8430 xm_scroll_callback (widget
, client_data
, call_data
)
8432 XtPointer client_data
, call_data
;
8434 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
8435 XmScrollBarCallbackStruct
*cs
= (XmScrollBarCallbackStruct
*) call_data
;
8436 int part
= -1, whole
= 0, portion
= 0;
8440 case XmCR_DECREMENT
:
8441 bar
->dragging
= Qnil
;
8442 part
= scroll_bar_up_arrow
;
8445 case XmCR_INCREMENT
:
8446 bar
->dragging
= Qnil
;
8447 part
= scroll_bar_down_arrow
;
8450 case XmCR_PAGE_DECREMENT
:
8451 bar
->dragging
= Qnil
;
8452 part
= scroll_bar_above_handle
;
8455 case XmCR_PAGE_INCREMENT
:
8456 bar
->dragging
= Qnil
;
8457 part
= scroll_bar_below_handle
;
8461 bar
->dragging
= Qnil
;
8462 part
= scroll_bar_to_top
;
8465 case XmCR_TO_BOTTOM
:
8466 bar
->dragging
= Qnil
;
8467 part
= scroll_bar_to_bottom
;
8473 int dragging_down_p
= (INTEGERP (bar
->dragging
)
8474 && XINT (bar
->dragging
) <= cs
->value
);
8476 /* Get the slider size. */
8478 XtVaGetValues (widget
, XmNsliderSize
, &slider_size
, NULL
);
8481 /* At the max position of the scroll bar, do a line-wise
8482 movement. Without doing anything, we would be called with
8483 the same cs->value again and again. If we want to make
8484 sure that we can reach the end of the buffer, we have to do
8487 Implementation note: setting bar->dragging always to
8488 cs->value gives a smoother movement at the max position.
8489 Setting it to nil when doing line-wise movement gives
8490 a better slider behavior. */
8492 if (cs
->value
+ slider_size
== XM_SB_MAX
8494 && last_scroll_bar_part
== scroll_bar_down_arrow
))
8496 part
= scroll_bar_down_arrow
;
8497 bar
->dragging
= Qnil
;
8501 whole
= XM_SB_RANGE
;
8502 portion
= min (cs
->value
- XM_SB_MIN
, XM_SB_MAX
- slider_size
);
8503 part
= scroll_bar_handle
;
8504 bar
->dragging
= make_number (cs
->value
);
8509 case XmCR_VALUE_CHANGED
:
8515 window_being_scrolled
= bar
->window
;
8516 last_scroll_bar_part
= part
;
8517 x_send_scroll_bar_event (bar
->window
, part
, portion
, whole
);
8522 #else /* !USE_MOTIF, i.e. Xaw. */
8525 /* Xaw scroll bar callback. Invoked when the thumb is dragged.
8526 WIDGET is the scroll bar widget. CLIENT_DATA is a pointer to the
8527 scroll bar struct. CALL_DATA is a pointer to a float saying where
8531 xaw_jump_callback (widget
, client_data
, call_data
)
8533 XtPointer client_data
, call_data
;
8535 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
8536 float top
= *(float *) call_data
;
8538 int whole
, portion
, height
;
8541 /* Get the size of the thumb, a value between 0 and 1. */
8543 XtVaGetValues (widget
, XtNshown
, &shown
, XtNheight
, &height
, NULL
);
8547 portion
= shown
< 1 ? top
* whole
: 0;
8549 if (shown
< 1 && (abs (top
+ shown
- 1) < 1.0/height
))
8550 /* Some derivatives of Xaw refuse to shrink the thumb when you reach
8551 the bottom, so we force the scrolling whenever we see that we're
8552 too close to the bottom (in x_set_toolkit_scroll_bar_thumb
8553 we try to ensure that we always stay two pixels away from the
8555 part
= scroll_bar_down_arrow
;
8557 part
= scroll_bar_handle
;
8559 window_being_scrolled
= bar
->window
;
8560 bar
->dragging
= make_number (portion
);
8561 last_scroll_bar_part
= part
;
8562 x_send_scroll_bar_event (bar
->window
, part
, portion
, whole
);
8566 /* Xaw scroll bar callback. Invoked for incremental scrolling.,
8567 i.e. line or page up or down. WIDGET is the Xaw scroll bar
8568 widget. CLIENT_DATA is a pointer to the scroll_bar structure for
8569 the scroll bar. CALL_DATA is an integer specifying the action that
8570 has taken place. It's magnitude is in the range 0..height of the
8571 scroll bar. Negative values mean scroll towards buffer start.
8572 Values < height of scroll bar mean line-wise movement. */
8575 xaw_scroll_callback (widget
, client_data
, call_data
)
8577 XtPointer client_data
, call_data
;
8579 struct scroll_bar
*bar
= (struct scroll_bar
*) client_data
;
8580 int position
= (int) call_data
;
8584 /* Get the height of the scroll bar. */
8586 XtVaGetValues (widget
, XtNheight
, &height
, NULL
);
8589 if (abs (position
) >= height
)
8590 part
= (position
< 0) ? scroll_bar_above_handle
: scroll_bar_below_handle
;
8592 /* If Xaw3d was compiled with ARROW_SCROLLBAR,
8593 it maps line-movement to call_data = max(5, height/20). */
8594 else if (xaw3d_arrow_scroll
&& abs (position
) <= max (5, height
/ 20))
8595 part
= (position
< 0) ? scroll_bar_up_arrow
: scroll_bar_down_arrow
;
8597 part
= scroll_bar_move_ratio
;
8599 window_being_scrolled
= bar
->window
;
8600 bar
->dragging
= Qnil
;
8601 last_scroll_bar_part
= part
;
8602 x_send_scroll_bar_event (bar
->window
, part
, position
, height
);
8606 #endif /* not USE_MOTIF */
8609 /* Create the widget for scroll bar BAR on frame F. Record the widget
8610 and X window of the scroll bar in BAR. */
8613 x_create_toolkit_scroll_bar (f
, bar
)
8615 struct scroll_bar
*bar
;
8621 char *scroll_bar_name
= "verticalScrollBar";
8622 unsigned long pixel
;
8627 /* Set resources. Create the widget. */
8628 XtSetArg (av
[ac
], XtNmappedWhenManaged
, False
); ++ac
;
8629 XtSetArg (av
[ac
], XmNminimum
, XM_SB_MIN
); ++ac
;
8630 XtSetArg (av
[ac
], XmNmaximum
, XM_SB_MAX
); ++ac
;
8631 XtSetArg (av
[ac
], XmNorientation
, XmVERTICAL
); ++ac
;
8632 XtSetArg (av
[ac
], XmNprocessingDirection
, XmMAX_ON_BOTTOM
), ++ac
;
8633 XtSetArg (av
[ac
], XmNincrement
, 1); ++ac
;
8634 XtSetArg (av
[ac
], XmNpageIncrement
, 1); ++ac
;
8636 pixel
= f
->output_data
.x
->scroll_bar_foreground_pixel
;
8639 XtSetArg (av
[ac
], XmNforeground
, pixel
);
8643 pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8646 XtSetArg (av
[ac
], XmNbackground
, pixel
);
8650 widget
= XmCreateScrollBar (f
->output_data
.x
->edit_widget
,
8651 scroll_bar_name
, av
, ac
);
8653 /* Add one callback for everything that can happen. */
8654 XtAddCallback (widget
, XmNdecrementCallback
, xm_scroll_callback
,
8656 XtAddCallback (widget
, XmNdragCallback
, xm_scroll_callback
,
8658 XtAddCallback (widget
, XmNincrementCallback
, xm_scroll_callback
,
8660 XtAddCallback (widget
, XmNpageDecrementCallback
, xm_scroll_callback
,
8662 XtAddCallback (widget
, XmNpageIncrementCallback
, xm_scroll_callback
,
8664 XtAddCallback (widget
, XmNtoBottomCallback
, xm_scroll_callback
,
8666 XtAddCallback (widget
, XmNtoTopCallback
, xm_scroll_callback
,
8669 /* Realize the widget. Only after that is the X window created. */
8670 XtRealizeWidget (widget
);
8672 /* Set the cursor to an arrow. I didn't find a resource to do that.
8673 And I'm wondering why it hasn't an arrow cursor by default. */
8674 XDefineCursor (XtDisplay (widget
), XtWindow (widget
),
8675 f
->output_data
.x
->nontext_cursor
);
8677 #else /* !USE_MOTIF i.e. use Xaw */
8679 /* Set resources. Create the widget. The background of the
8680 Xaw3d scroll bar widget is a little bit light for my taste.
8681 We don't alter it here to let users change it according
8682 to their taste with `emacs*verticalScrollBar.background: xxx'. */
8683 XtSetArg (av
[ac
], XtNmappedWhenManaged
, False
); ++ac
;
8684 XtSetArg (av
[ac
], XtNorientation
, XtorientVertical
); ++ac
;
8685 /* For smoother scrolling with Xaw3d -sm */
8686 /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */
8688 pixel
= f
->output_data
.x
->scroll_bar_foreground_pixel
;
8691 XtSetArg (av
[ac
], XtNforeground
, pixel
);
8695 pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8698 XtSetArg (av
[ac
], XtNbackground
, pixel
);
8702 /* Top/bottom shadow colors. */
8704 /* Allocate them, if necessary. */
8705 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
== -1)
8707 pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8708 if (!x_alloc_lighter_color (f
, FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
8709 &pixel
, 1.2, 0x8000))
8711 f
->output_data
.x
->scroll_bar_top_shadow_pixel
= pixel
;
8713 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
== -1)
8715 pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8716 if (!x_alloc_lighter_color (f
, FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
),
8717 &pixel
, 0.6, 0x4000))
8719 f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
= pixel
;
8722 /* Tell the toolkit about them. */
8723 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
== -1
8724 || f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
== -1)
8725 /* We tried to allocate a color for the top/bottom shadow, and
8726 failed, so tell Xaw3d to use dithering instead. */
8728 XtSetArg (av
[ac
], XtNbeNiceToColormap
, True
);
8732 /* Tell what colors Xaw3d should use for the top/bottom shadow, to
8733 be more consistent with other emacs 3d colors, and since Xaw3d is
8734 not good at dealing with allocation failure. */
8736 /* This tells Xaw3d to use real colors instead of dithering for
8738 XtSetArg (av
[ac
], XtNbeNiceToColormap
, False
);
8741 /* Specify the colors. */
8742 pixel
= f
->output_data
.x
->scroll_bar_top_shadow_pixel
;
8745 XtSetArg (av
[ac
], "topShadowPixel", pixel
);
8748 pixel
= f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
;
8751 XtSetArg (av
[ac
], "bottomShadowPixel", pixel
);
8756 widget
= XtCreateWidget (scroll_bar_name
, scrollbarWidgetClass
,
8757 f
->output_data
.x
->edit_widget
, av
, ac
);
8761 char *val
= initial
;
8762 XtVaGetValues (widget
, XtNscrollVCursor
, (XtPointer
) &val
,
8763 XtNpickTop
, (XtPointer
) &xaw3d_pick_top
, NULL
);
8765 { /* ARROW_SCROLL */
8766 xaw3d_arrow_scroll
= True
;
8767 /* Isn't that just a personal preference ? -sm */
8768 XtVaSetValues (widget
, XtNcursorName
, "top_left_arrow", NULL
);
8772 /* Define callbacks. */
8773 XtAddCallback (widget
, XtNjumpProc
, xaw_jump_callback
, (XtPointer
) bar
);
8774 XtAddCallback (widget
, XtNscrollProc
, xaw_scroll_callback
,
8777 /* Realize the widget. Only after that is the X window created. */
8778 XtRealizeWidget (widget
);
8780 #endif /* !USE_MOTIF */
8782 /* Install an action hook that let's us detect when the user
8783 finishes interacting with a scroll bar. */
8784 if (action_hook_id
== 0)
8785 action_hook_id
= XtAppAddActionHook (Xt_app_con
, xt_action_hook
, 0);
8787 /* Remember X window and widget in the scroll bar vector. */
8788 SET_SCROLL_BAR_X_WIDGET (bar
, widget
);
8789 xwindow
= XtWindow (widget
);
8790 SET_SCROLL_BAR_X_WINDOW (bar
, xwindow
);
8796 /* Set the thumb size and position of scroll bar BAR. We are currently
8797 displaying PORTION out of a whole WHOLE, and our position POSITION. */
8800 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
)
8801 struct scroll_bar
*bar
;
8802 int portion
, position
, whole
;
8804 struct frame
*f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8805 Widget widget
= SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
);
8812 top
= (float) position
/ whole
;
8813 shown
= (float) portion
/ whole
;
8822 /* Slider size. Must be in the range [1 .. MAX - MIN] where MAX
8823 is the scroll bar's maximum and MIN is the scroll bar's minimum
8825 size
= shown
* XM_SB_RANGE
;
8826 size
= min (size
, XM_SB_RANGE
);
8827 size
= max (size
, 1);
8829 /* Position. Must be in the range [MIN .. MAX - SLIDER_SIZE]. */
8830 value
= top
* XM_SB_RANGE
;
8831 value
= min (value
, XM_SB_MAX
- size
);
8832 value
= max (value
, XM_SB_MIN
);
8834 if (NILP (bar
->dragging
))
8835 XmScrollBarSetValues (widget
, value
, size
, 0, 0, False
);
8836 else if (last_scroll_bar_part
== scroll_bar_down_arrow
)
8837 /* This has the negative side effect that the slider value is
8838 not what it would be if we scrolled here using line-wise or
8839 page-wise movement. */
8840 XmScrollBarSetValues (widget
, value
, XM_SB_RANGE
- value
, 0, 0, False
);
8843 /* If currently dragging, only update the slider size.
8844 This reduces flicker effects. */
8845 int old_value
, old_size
, increment
, page_increment
;
8847 XmScrollBarGetValues (widget
, &old_value
, &old_size
,
8848 &increment
, &page_increment
);
8849 XmScrollBarSetValues (widget
, old_value
,
8850 min (size
, XM_SB_RANGE
- old_value
),
8854 #else /* !USE_MOTIF i.e. use Xaw */
8856 float old_top
, old_shown
;
8858 XtVaGetValues (widget
,
8859 XtNtopOfThumb
, &old_top
,
8860 XtNshown
, &old_shown
,
8864 /* Massage the top+shown values. */
8865 if (NILP (bar
->dragging
) || last_scroll_bar_part
== scroll_bar_down_arrow
)
8866 top
= max (0, min (1, top
));
8869 /* Keep two pixels available for moving the thumb down. */
8870 shown
= max (0, min (1 - top
- (2.0 / height
), shown
));
8872 /* If the call to XawScrollbarSetThumb below doesn't seem to work,
8873 check that your system's configuration file contains a define
8874 for `NARROWPROTO'. See s/freebsd.h for an example. */
8875 if (top
!= old_top
|| shown
!= old_shown
)
8877 if (NILP (bar
->dragging
))
8878 XawScrollbarSetThumb (widget
, top
, shown
);
8882 ScrollbarWidget sb
= (ScrollbarWidget
) widget
;
8883 int scroll_mode
= 0;
8885 /* `scroll_mode' only exists with Xaw3d + ARROW_SCROLLBAR. */
8886 if (xaw3d_arrow_scroll
)
8888 /* Xaw3d stupidly ignores resize requests while dragging
8889 so we have to make it believe it's not in dragging mode. */
8890 scroll_mode
= sb
->scrollbar
.scroll_mode
;
8891 if (scroll_mode
== 2)
8892 sb
->scrollbar
.scroll_mode
= 0;
8895 /* Try to make the scrolling a tad smoother. */
8896 if (!xaw3d_pick_top
)
8897 shown
= min (shown
, old_shown
);
8899 XawScrollbarSetThumb (widget
, top
, shown
);
8902 if (xaw3d_arrow_scroll
&& scroll_mode
== 2)
8903 sb
->scrollbar
.scroll_mode
= scroll_mode
;
8908 #endif /* !USE_MOTIF */
8913 #endif /* USE_TOOLKIT_SCROLL_BARS */
8917 /************************************************************************
8918 Scroll bars, general
8919 ************************************************************************/
8921 /* Create a scroll bar and return the scroll bar vector for it. W is
8922 the Emacs window on which to create the scroll bar. TOP, LEFT,
8923 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
8926 static struct scroll_bar
*
8927 x_scroll_bar_create (w
, top
, left
, width
, height
)
8929 int top
, left
, width
, height
;
8931 struct frame
*f
= XFRAME (w
->frame
);
8932 struct scroll_bar
*bar
8933 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
8937 #ifdef USE_TOOLKIT_SCROLL_BARS
8938 x_create_toolkit_scroll_bar (f
, bar
);
8939 #else /* not USE_TOOLKIT_SCROLL_BARS */
8941 XSetWindowAttributes a
;
8945 a
.background_pixel
= f
->output_data
.x
->scroll_bar_background_pixel
;
8946 if (a
.background_pixel
== -1)
8947 a
.background_pixel
= f
->output_data
.x
->background_pixel
;
8949 a
.event_mask
= (ButtonPressMask
| ButtonReleaseMask
8950 | ButtonMotionMask
| PointerMotionHintMask
8952 a
.cursor
= FRAME_X_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
8954 mask
= (CWBackPixel
| CWEventMask
| CWCursor
);
8956 /* Clear the area of W that will serve as a scroll bar. This is
8957 for the case that a window has been split horizontally. In
8958 this case, no clear_frame is generated to reduce flickering. */
8959 if (width
> 0 && height
> 0)
8960 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8962 window_box_height (w
), False
);
8964 window
= XCreateWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8965 /* Position and size of scroll bar. */
8966 left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
8968 width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8970 /* Border width, depth, class, and visual. */
8977 SET_SCROLL_BAR_X_WINDOW (bar
, window
);
8979 #endif /* not USE_TOOLKIT_SCROLL_BARS */
8981 XSETWINDOW (bar
->window
, w
);
8982 XSETINT (bar
->top
, top
);
8983 XSETINT (bar
->left
, left
);
8984 XSETINT (bar
->width
, width
);
8985 XSETINT (bar
->height
, height
);
8986 XSETINT (bar
->start
, 0);
8987 XSETINT (bar
->end
, 0);
8988 bar
->dragging
= Qnil
;
8990 /* Add bar to its frame's list of scroll bars. */
8991 bar
->next
= FRAME_SCROLL_BARS (f
);
8993 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8994 if (!NILP (bar
->next
))
8995 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8997 /* Map the window/widget. */
8998 #ifdef USE_TOOLKIT_SCROLL_BARS
9000 Widget scroll_bar
= SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
);
9001 XtConfigureWidget (scroll_bar
,
9002 left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9004 width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
9005 max (height
, 1), 0);
9006 XtMapWidget (scroll_bar
);
9008 #else /* not USE_TOOLKIT_SCROLL_BARS */
9009 XMapRaised (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
));
9010 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9017 /* Draw BAR's handle in the proper position.
9019 If the handle is already drawn from START to END, don't bother
9020 redrawing it, unless REBUILD is non-zero; in that case, always
9021 redraw it. (REBUILD is handy for drawing the handle after expose
9024 Normally, we want to constrain the start and end of the handle to
9025 fit inside its rectangle, but if the user is dragging the scroll
9026 bar handle, we want to let them drag it down all the way, so that
9027 the bar's top is as far down as it goes; otherwise, there's no way
9028 to move to the very end of the buffer. */
9030 #ifndef USE_TOOLKIT_SCROLL_BARS
9033 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
9034 struct scroll_bar
*bar
;
9038 int dragging
= ! NILP (bar
->dragging
);
9039 Window w
= SCROLL_BAR_X_WINDOW (bar
);
9040 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9041 GC gc
= f
->output_data
.x
->normal_gc
;
9043 /* If the display is already accurate, do nothing. */
9045 && start
== XINT (bar
->start
)
9046 && end
== XINT (bar
->end
))
9052 int inside_width
= VERTICAL_SCROLL_BAR_INSIDE_WIDTH (f
, XINT (bar
->width
));
9053 int inside_height
= VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
9054 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
9056 /* Make sure the values are reasonable, and try to preserve
9057 the distance between start and end. */
9059 int length
= end
- start
;
9063 else if (start
> top_range
)
9065 end
= start
+ length
;
9069 else if (end
> top_range
&& ! dragging
)
9073 /* Store the adjusted setting in the scroll bar. */
9074 XSETINT (bar
->start
, start
);
9075 XSETINT (bar
->end
, end
);
9077 /* Clip the end position, just for display. */
9078 if (end
> top_range
)
9081 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels
9082 below top positions, to make sure the handle is always at least
9083 that many pixels tall. */
9084 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
9086 /* Draw the empty space above the handle. Note that we can't clear
9087 zero-height areas; that means "clear to end of window." */
9089 x_clear_area (FRAME_X_DISPLAY (f
), w
,
9090 /* x, y, width, height, and exposures. */
9091 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
9092 VERTICAL_SCROLL_BAR_TOP_BORDER
,
9093 inside_width
, start
,
9096 /* Change to proper foreground color if one is specified. */
9097 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
9098 XSetForeground (FRAME_X_DISPLAY (f
), gc
,
9099 f
->output_data
.x
->scroll_bar_foreground_pixel
);
9101 /* Draw the handle itself. */
9102 XFillRectangle (FRAME_X_DISPLAY (f
), w
, gc
,
9103 /* x, y, width, height */
9104 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
9105 VERTICAL_SCROLL_BAR_TOP_BORDER
+ start
,
9106 inside_width
, end
- start
);
9108 /* Restore the foreground color of the GC if we changed it above. */
9109 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
9110 XSetForeground (FRAME_X_DISPLAY (f
), gc
,
9111 f
->output_data
.x
->foreground_pixel
);
9113 /* Draw the empty space below the handle. Note that we can't
9114 clear zero-height areas; that means "clear to end of window." */
9115 if (end
< inside_height
)
9116 x_clear_area (FRAME_X_DISPLAY (f
), w
,
9117 /* x, y, width, height, and exposures. */
9118 VERTICAL_SCROLL_BAR_LEFT_BORDER
,
9119 VERTICAL_SCROLL_BAR_TOP_BORDER
+ end
,
9120 inside_width
, inside_height
- end
,
9128 #endif /* !USE_TOOLKIT_SCROLL_BARS */
9130 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
9134 x_scroll_bar_remove (bar
)
9135 struct scroll_bar
*bar
;
9137 struct frame
*f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9140 #ifdef USE_TOOLKIT_SCROLL_BARS
9141 XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
));
9143 XDestroyWindow (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
));
9146 /* Disassociate this scroll bar from its window. */
9147 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
9153 /* Set the handle of the vertical scroll bar for WINDOW to indicate
9154 that we are displaying PORTION characters out of a total of WHOLE
9155 characters, starting at POSITION. If WINDOW has no scroll bar,
9159 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
9161 int portion
, whole
, position
;
9163 struct frame
*f
= XFRAME (w
->frame
);
9164 struct scroll_bar
*bar
;
9165 int top
, height
, left
, sb_left
, width
, sb_width
;
9166 int window_x
, window_y
, window_width
, window_height
;
9168 /* Get window dimensions. */
9169 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
9171 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
9172 height
= window_height
;
9174 /* Compute the left edge of the scroll bar area. */
9175 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
9176 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
9178 left
= XFASTINT (w
->left
);
9179 left
*= CANON_X_UNIT (f
);
9180 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
9182 /* Compute the width of the scroll bar which might be less than
9183 the width of the area reserved for the scroll bar. */
9184 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
9185 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
9189 /* Compute the left edge of the scroll bar. */
9190 #ifdef USE_TOOLKIT_SCROLL_BARS
9191 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
9192 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
9194 sb_left
= left
+ (width
- sb_width
) / 2;
9196 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
9197 sb_left
= left
+ width
- sb_width
;
9202 /* Does the scroll bar exist yet? */
9203 if (NILP (w
->vertical_scroll_bar
))
9205 if (width
> 0 && height
> 0)
9208 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9209 left
, top
, width
, height
, False
);
9213 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
);
9217 /* It may just need to be moved and resized. */
9218 unsigned int mask
= 0;
9220 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
9224 if (sb_left
!= XINT (bar
->left
))
9226 if (top
!= XINT (bar
->top
))
9228 if (sb_width
!= XINT (bar
->width
))
9230 if (height
!= XINT (bar
->height
))
9233 #ifdef USE_TOOLKIT_SCROLL_BARS
9235 /* Since toolkit scroll bars are smaller than the space reserved
9236 for them on the frame, we have to clear "under" them. */
9237 if (width
> 0 && height
> 0)
9238 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9239 left
, top
, width
, height
, False
);
9241 /* Move/size the scroll bar widget. */
9243 XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f
), bar
),
9244 sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9246 sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
9247 max (height
, 1), 0);
9249 #else /* not USE_TOOLKIT_SCROLL_BARS */
9251 /* Clear areas not covered by the scroll bar because of
9252 VERTICAL_SCROLL_BAR_WIDTH_TRIM. */
9253 if (VERTICAL_SCROLL_BAR_WIDTH_TRIM
)
9255 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9256 left
, top
, VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9258 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9259 left
+ width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9260 top
, VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
9264 /* Clear areas not covered by the scroll bar because it's not as
9265 wide as the area reserved for it . This makes sure a
9266 previous mode line display is cleared after C-x 2 C-x 1, for
9269 int area_width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
9270 int rest
= area_width
- sb_width
;
9271 if (rest
> 0 && height
> 0)
9273 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f
))
9274 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9275 left
+ area_width
- rest
, top
,
9276 rest
, height
, False
);
9278 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9279 left
, top
, rest
, height
, False
);
9283 /* Move/size the scroll bar window. */
9288 wc
.x
= sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
9290 wc
.width
= sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2;
9292 XConfigureWindow (FRAME_X_DISPLAY (f
), SCROLL_BAR_X_WINDOW (bar
),
9296 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9298 /* Remember new settings. */
9299 XSETINT (bar
->left
, sb_left
);
9300 XSETINT (bar
->top
, top
);
9301 XSETINT (bar
->width
, sb_width
);
9302 XSETINT (bar
->height
, height
);
9307 #ifdef USE_TOOLKIT_SCROLL_BARS
9308 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
);
9309 #else /* not USE_TOOLKIT_SCROLL_BARS */
9310 /* Set the scroll bar's current state, unless we're currently being
9312 if (NILP (bar
->dragging
))
9314 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
9317 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
9320 int start
= ((double) position
* top_range
) / whole
;
9321 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
9322 x_scroll_bar_set_handle (bar
, start
, end
, 0);
9325 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9327 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
9331 /* The following three hooks are used when we're doing a thorough
9332 redisplay of the frame. We don't explicitly know which scroll bars
9333 are going to be deleted, because keeping track of when windows go
9334 away is a real pain - "Can you say set-window-configuration, boys
9335 and girls?" Instead, we just assert at the beginning of redisplay
9336 that *all* scroll bars are to be removed, and then save a scroll bar
9337 from the fiery pit when we actually redisplay its window. */
9339 /* Arrange for all scroll bars on FRAME to be removed at the next call
9340 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
9341 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
9344 XTcondemn_scroll_bars (frame
)
9347 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
9348 while (! NILP (FRAME_SCROLL_BARS (frame
)))
9351 bar
= FRAME_SCROLL_BARS (frame
);
9352 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
9353 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
9354 XSCROLL_BAR (bar
)->prev
= Qnil
;
9355 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
9356 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
9357 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
9362 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
9363 Note that WINDOW isn't necessarily condemned at all. */
9366 XTredeem_scroll_bar (window
)
9367 struct window
*window
;
9369 struct scroll_bar
*bar
;
9372 /* We can't redeem this window's scroll bar if it doesn't have one. */
9373 if (NILP (window
->vertical_scroll_bar
))
9376 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
9378 /* Unlink it from the condemned list. */
9379 f
= XFRAME (WINDOW_FRAME (window
));
9380 if (NILP (bar
->prev
))
9382 /* If the prev pointer is nil, it must be the first in one of
9384 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
9385 /* It's not condemned. Everything's fine. */
9387 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
9388 window
->vertical_scroll_bar
))
9389 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
9391 /* If its prev pointer is nil, it must be at the front of
9392 one or the other! */
9396 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
9398 if (! NILP (bar
->next
))
9399 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
9401 bar
->next
= FRAME_SCROLL_BARS (f
);
9403 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
9404 if (! NILP (bar
->next
))
9405 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
9408 /* Remove all scroll bars on FRAME that haven't been saved since the
9409 last call to `*condemn_scroll_bars_hook'. */
9412 XTjudge_scroll_bars (f
)
9415 Lisp_Object bar
, next
;
9417 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
9419 /* Clear out the condemned list now so we won't try to process any
9420 more events on the hapless scroll bars. */
9421 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
9423 for (; ! NILP (bar
); bar
= next
)
9425 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
9427 x_scroll_bar_remove (b
);
9430 b
->next
= b
->prev
= Qnil
;
9433 /* Now there should be no references to the condemned scroll bars,
9434 and they should get garbage-collected. */
9438 /* Handle an Expose or GraphicsExpose event on a scroll bar. This
9439 is a no-op when using toolkit scroll bars.
9441 This may be called from a signal handler, so we have to ignore GC
9445 x_scroll_bar_expose (bar
, event
)
9446 struct scroll_bar
*bar
;
9449 #ifndef USE_TOOLKIT_SCROLL_BARS
9451 Window w
= SCROLL_BAR_X_WINDOW (bar
);
9452 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9453 GC gc
= f
->output_data
.x
->normal_gc
;
9454 int width_trim
= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
9458 x_scroll_bar_set_handle (bar
, XINT (bar
->start
), XINT (bar
->end
), 1);
9460 /* Draw a one-pixel border just inside the edges of the scroll bar. */
9461 XDrawRectangle (FRAME_X_DISPLAY (f
), w
, gc
,
9463 /* x, y, width, height */
9465 XINT (bar
->width
) - 1 - width_trim
- width_trim
,
9466 XINT (bar
->height
) - 1);
9470 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9473 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
9474 is set to something other than no_event, it is enqueued.
9476 This may be called from a signal handler, so we have to ignore GC
9479 #ifndef USE_TOOLKIT_SCROLL_BARS
9482 x_scroll_bar_handle_click (bar
, event
, emacs_event
)
9483 struct scroll_bar
*bar
;
9485 struct input_event
*emacs_event
;
9487 if (! GC_WINDOWP (bar
->window
))
9490 emacs_event
->kind
= scroll_bar_click
;
9491 emacs_event
->code
= event
->xbutton
.button
- Button1
;
9492 emacs_event
->modifiers
9493 = (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO
9494 (XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)))),
9495 event
->xbutton
.state
)
9496 | (event
->type
== ButtonRelease
9499 emacs_event
->frame_or_window
= bar
->window
;
9500 emacs_event
->arg
= Qnil
;
9501 emacs_event
->timestamp
= event
->xbutton
.time
;
9504 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9506 = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
9509 = VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
9510 int y
= event
->xbutton
.y
- VERTICAL_SCROLL_BAR_TOP_BORDER
;
9513 if (y
> top_range
) y
= top_range
;
9515 if (y
< XINT (bar
->start
))
9516 emacs_event
->part
= scroll_bar_above_handle
;
9517 else if (y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
9518 emacs_event
->part
= scroll_bar_handle
;
9520 emacs_event
->part
= scroll_bar_below_handle
;
9522 /* Just because the user has clicked on the handle doesn't mean
9523 they want to drag it. Lisp code needs to be able to decide
9524 whether or not we're dragging. */
9526 /* If the user has just clicked on the handle, record where they're
9528 if (event
->type
== ButtonPress
9529 && emacs_event
->part
== scroll_bar_handle
)
9530 XSETINT (bar
->dragging
, y
- XINT (bar
->start
));
9533 /* If the user has released the handle, set it to its final position. */
9534 if (event
->type
== ButtonRelease
9535 && ! NILP (bar
->dragging
))
9537 int new_start
= y
- XINT (bar
->dragging
);
9538 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
9540 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
9541 bar
->dragging
= Qnil
;
9544 /* Same deal here as the other #if 0. */
9546 /* Clicks on the handle are always reported as occurring at the top of
9548 if (emacs_event
->part
== scroll_bar_handle
)
9549 emacs_event
->x
= bar
->start
;
9551 XSETINT (emacs_event
->x
, y
);
9553 XSETINT (emacs_event
->x
, y
);
9556 XSETINT (emacs_event
->y
, top_range
);
9560 /* Handle some mouse motion while someone is dragging the scroll bar.
9562 This may be called from a signal handler, so we have to ignore GC
9566 x_scroll_bar_note_movement (bar
, event
)
9567 struct scroll_bar
*bar
;
9570 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
9572 last_mouse_movement_time
= event
->xmotion
.time
;
9575 XSETVECTOR (last_mouse_scroll_bar
, bar
);
9577 /* If we're dragging the bar, display it. */
9578 if (! GC_NILP (bar
->dragging
))
9580 /* Where should the handle be now? */
9581 int new_start
= event
->xmotion
.y
- XINT (bar
->dragging
);
9583 if (new_start
!= XINT (bar
->start
))
9585 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
9587 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
9592 #endif /* !USE_TOOLKIT_SCROLL_BARS */
9594 /* Return information to the user about the current position of the mouse
9595 on the scroll bar. */
9598 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
9600 Lisp_Object
*bar_window
;
9601 enum scroll_bar_part
*part
;
9603 unsigned long *time
;
9605 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
9606 Window w
= SCROLL_BAR_X_WINDOW (bar
);
9607 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
9609 Window dummy_window
;
9611 unsigned int dummy_mask
;
9615 /* Get the mouse's position relative to the scroll bar window, and
9617 if (! XQueryPointer (FRAME_X_DISPLAY (f
), w
,
9619 /* Root, child, root x and root y. */
9620 &dummy_window
, &dummy_window
,
9621 &dummy_coord
, &dummy_coord
,
9623 /* Position relative to scroll bar. */
9626 /* Mouse buttons and modifier keys. */
9633 = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
9636 = VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
9638 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
9640 if (! NILP (bar
->dragging
))
9641 win_y
-= XINT (bar
->dragging
);
9645 if (win_y
> top_range
)
9649 *bar_window
= bar
->window
;
9651 if (! NILP (bar
->dragging
))
9652 *part
= scroll_bar_handle
;
9653 else if (win_y
< XINT (bar
->start
))
9654 *part
= scroll_bar_above_handle
;
9655 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
9656 *part
= scroll_bar_handle
;
9658 *part
= scroll_bar_below_handle
;
9660 XSETINT (*x
, win_y
);
9661 XSETINT (*y
, top_range
);
9664 last_mouse_scroll_bar
= Qnil
;
9667 *time
= last_mouse_movement_time
;
9673 /* The screen has been cleared so we may have changed foreground or
9674 background colors, and the scroll bars may need to be redrawn.
9675 Clear out the scroll bars, and ask for expose events, so we can
9679 x_scroll_bar_clear (f
)
9682 #ifndef USE_TOOLKIT_SCROLL_BARS
9685 /* We can have scroll bars even if this is 0,
9686 if we just turned off scroll bar mode.
9687 But in that case we should not clear them. */
9688 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
9689 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
9690 bar
= XSCROLL_BAR (bar
)->next
)
9691 XClearArea (FRAME_X_DISPLAY (f
),
9692 SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar
)),
9694 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9697 /* This processes Expose events from the menu-bar specific X event
9698 loop in xmenu.c. This allows to redisplay the frame if necessary
9699 when handling menu-bar or pop-up items. */
9702 process_expose_from_menu (event
)
9706 struct x_display_info
*dpyinfo
;
9707 int frame_exposed_p
= 0;
9711 dpyinfo
= x_display_info_for_display (event
.xexpose
.display
);
9712 f
= x_window_to_frame (dpyinfo
, event
.xexpose
.window
);
9715 if (f
->async_visible
== 0)
9717 f
->async_visible
= 1;
9718 f
->async_iconified
= 0;
9719 f
->output_data
.x
->has_been_visible
= 1;
9720 SET_FRAME_GARBAGED (f
);
9724 expose_frame (x_window_to_frame (dpyinfo
, event
.xexpose
.window
),
9725 event
.xexpose
.x
, event
.xexpose
.y
,
9726 event
.xexpose
.width
, event
.xexpose
.height
);
9727 frame_exposed_p
= 1;
9732 struct scroll_bar
*bar
9733 = x_window_to_scroll_bar (event
.xexpose
.window
);
9736 x_scroll_bar_expose (bar
, &event
);
9740 return frame_exposed_p
;
9743 /* Define a queue to save up SelectionRequest events for later handling. */
9745 struct selection_event_queue
9748 struct selection_event_queue
*next
;
9751 static struct selection_event_queue
*queue
;
9753 /* Nonzero means queue up certain events--don't process them yet. */
9755 static int x_queue_selection_requests
;
9757 /* Queue up an X event *EVENT, to be processed later. */
9760 x_queue_event (f
, event
)
9764 struct selection_event_queue
*queue_tmp
9765 = (struct selection_event_queue
*) xmalloc (sizeof (struct selection_event_queue
));
9767 if (queue_tmp
!= NULL
)
9769 queue_tmp
->event
= *event
;
9770 queue_tmp
->next
= queue
;
9775 /* Take all the queued events and put them back
9776 so that they get processed afresh. */
9779 x_unqueue_events (display
)
9782 while (queue
!= NULL
)
9784 struct selection_event_queue
*queue_tmp
= queue
;
9785 XPutBackEvent (display
, &queue_tmp
->event
);
9786 queue
= queue_tmp
->next
;
9787 xfree ((char *)queue_tmp
);
9791 /* Start queuing SelectionRequest events. */
9794 x_start_queuing_selection_requests (display
)
9797 x_queue_selection_requests
++;
9800 /* Stop queuing SelectionRequest events. */
9803 x_stop_queuing_selection_requests (display
)
9806 x_queue_selection_requests
--;
9807 x_unqueue_events (display
);
9810 /* The main X event-reading loop - XTread_socket. */
9812 /* Time stamp of enter window event. This is only used by XTread_socket,
9813 but we have to put it out here, since static variables within functions
9814 sometimes don't work. */
9816 static Time enter_timestamp
;
9818 /* This holds the state XLookupString needs to implement dead keys
9819 and other tricks known as "compose processing". _X Window System_
9820 says that a portable program can't use this, but Stephen Gildea assures
9821 me that letting the compiler initialize it to zeros will work okay.
9823 This must be defined outside of XTread_socket, for the same reasons
9824 given for enter_time stamp, above. */
9826 static XComposeStatus compose_status
;
9828 /* Record the last 100 characters stored
9829 to help debug the loss-of-chars-during-GC problem. */
9831 static int temp_index
;
9832 static short temp_buffer
[100];
9834 /* Set this to nonzero to fake an "X I/O error"
9835 on a particular display. */
9837 struct x_display_info
*XTread_socket_fake_io_error
;
9839 /* When we find no input here, we occasionally do a no-op command
9840 to verify that the X server is still running and we can still talk with it.
9841 We try all the open displays, one by one.
9842 This variable is used for cycling thru the displays. */
9844 static struct x_display_info
*next_noop_dpyinfo
;
9846 #define SET_SAVED_MENU_EVENT(size) \
9849 if (f->output_data.x->saved_menu_event == 0) \
9850 f->output_data.x->saved_menu_event \
9851 = (XEvent *) xmalloc (sizeof (XEvent)); \
9852 bcopy (&event, f->output_data.x->saved_menu_event, size); \
9853 if (numchars >= 1) \
9855 bufp->kind = menu_bar_activate_event; \
9856 XSETFRAME (bufp->frame_or_window, f); \
9865 #define SET_SAVED_BUTTON_EVENT SET_SAVED_MENU_EVENT (sizeof (XButtonEvent))
9866 #define SET_SAVED_KEY_EVENT SET_SAVED_MENU_EVENT (sizeof (XKeyEvent))
9868 /* Read events coming from the X server.
9869 This routine is called by the SIGIO handler.
9870 We return as soon as there are no more events to be read.
9872 Events representing keys are stored in buffer BUFP,
9873 which can hold up to NUMCHARS characters.
9874 We return the number of characters stored into the buffer,
9875 thus pretending to be `read'.
9877 EXPECTED is nonzero if the caller knows input is available. */
9880 XTread_socket (sd
, bufp
, numchars
, expected
)
9882 /* register */ struct input_event
*bufp
;
9883 /* register */ int numchars
;
9890 int event_found
= 0;
9891 struct x_display_info
*dpyinfo
;
9892 struct coding_system coding
;
9894 if (interrupt_input_blocked
)
9896 interrupt_input_pending
= 1;
9900 interrupt_input_pending
= 0;
9903 /* So people can tell when we have read the available input. */
9904 input_signal_count
++;
9907 abort (); /* Don't think this happens. */
9911 /* The input should be decoded if it is from XIM. Currently the
9912 locale of XIM is the same as that of the system. So, we can use
9913 Vlocale_coding_system which is initialized properly at Emacs
9915 setup_coding_system (Vlocale_coding_system
, &coding
);
9916 coding
.src_multibyte
= 0;
9917 coding
.dst_multibyte
= 1;
9918 /* The input is converted to events, thus we can't handle
9919 composition. Anyway, there's no XIM that gives us composition
9921 coding
.composing
= COMPOSITION_DISABLED
;
9923 /* Find the display we are supposed to read input for.
9924 It's the one communicating on descriptor SD. */
9925 for (dpyinfo
= x_display_list
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
9927 #if 0 /* This ought to be unnecessary; let's verify it. */
9929 /* If available, Xlib uses FIOSNBIO to make the socket
9930 non-blocking, and then looks for EWOULDBLOCK. If O_NDELAY is set,
9931 FIOSNBIO is ignored, and instead of signaling EWOULDBLOCK,
9932 a read returns 0, which Xlib interprets as equivalent to EPIPE. */
9933 fcntl (dpyinfo
->connection
, F_SETFL
, 0);
9934 #endif /* ! defined (FIOSNBIO) */
9937 #if 0 /* This code can't be made to work, with multiple displays,
9938 and appears not to be used on any system any more.
9939 Also keyboard.c doesn't turn O_NDELAY on and off
9940 for X connections. */
9943 if (! (fcntl (dpyinfo
->connection
, F_GETFL
, 0) & O_NDELAY
))
9945 extern int read_alarm_should_throw
;
9946 read_alarm_should_throw
= 1;
9947 XPeekEvent (dpyinfo
->display
, &event
);
9948 read_alarm_should_throw
= 0;
9950 #endif /* HAVE_SELECT */
9954 /* For debugging, this gives a way to fake an I/O error. */
9955 if (dpyinfo
== XTread_socket_fake_io_error
)
9957 XTread_socket_fake_io_error
= 0;
9958 x_io_error_quitter (dpyinfo
->display
);
9961 while (XPending (dpyinfo
->display
))
9963 XNextEvent (dpyinfo
->display
, &event
);
9967 /* Filter events for the current X input method.
9968 XFilterEvent returns non-zero if the input method has
9969 consumed the event. We pass the frame's X window to
9970 XFilterEvent because that's the one for which the IC
9972 struct frame
*f1
= x_any_window_to_frame (dpyinfo
,
9973 event
.xclient
.window
);
9974 if (XFilterEvent (&event
, f1
? FRAME_X_WINDOW (f1
) : None
))
9984 if (event
.xclient
.message_type
9985 == dpyinfo
->Xatom_wm_protocols
9986 && event
.xclient
.format
== 32)
9988 if (event
.xclient
.data
.l
[0]
9989 == dpyinfo
->Xatom_wm_take_focus
)
9991 /* Use x_any_window_to_frame because this
9992 could be the shell widget window
9993 if the frame has no title bar. */
9994 f
= x_any_window_to_frame (dpyinfo
, event
.xclient
.window
);
9996 /* Not quite sure this is needed -pd */
9997 if (f
&& FRAME_XIC (f
))
9998 XSetICFocus (FRAME_XIC (f
));
10000 #if 0 /* Emacs sets WM hints whose `input' field is `true'. This
10001 instructs the WM to set the input focus automatically for
10002 Emacs with a call to XSetInputFocus. Setting WM_TAKE_FOCUS
10003 tells the WM to send us a ClientMessage WM_TAKE_FOCUS after
10004 it has set the focus. So, XSetInputFocus below is not
10007 The call to XSetInputFocus below has also caused trouble. In
10008 cases where the XSetInputFocus done by the WM and the one
10009 below are temporally close (on a fast machine), the call
10010 below can generate additional FocusIn events which confuse
10013 /* Since we set WM_TAKE_FOCUS, we must call
10014 XSetInputFocus explicitly. But not if f is null,
10015 since that might be an event for a deleted frame. */
10018 Display
*d
= event
.xclient
.display
;
10019 /* Catch and ignore errors, in case window has been
10020 iconified by a window manager such as GWM. */
10021 int count
= x_catch_errors (d
);
10022 XSetInputFocus (d
, event
.xclient
.window
,
10023 /* The ICCCM says this is
10024 the only valid choice. */
10026 event
.xclient
.data
.l
[1]);
10027 /* This is needed to detect the error
10028 if there is an error. */
10030 x_uncatch_errors (d
, count
);
10032 /* Not certain about handling scroll bars here */
10035 else if (event
.xclient
.data
.l
[0]
10036 == dpyinfo
->Xatom_wm_save_yourself
)
10038 /* Save state modify the WM_COMMAND property to
10039 something which can reinstate us. This notifies
10040 the session manager, who's looking for such a
10041 PropertyNotify. Can restart processing when
10042 a keyboard or mouse event arrives. */
10045 f
= x_top_window_to_frame (dpyinfo
,
10046 event
.xclient
.window
);
10048 /* This is just so we only give real data once
10049 for a single Emacs process. */
10050 if (f
== SELECTED_FRAME ())
10051 XSetCommand (FRAME_X_DISPLAY (f
),
10052 event
.xclient
.window
,
10053 initial_argv
, initial_argc
);
10055 XSetCommand (FRAME_X_DISPLAY (f
),
10056 event
.xclient
.window
,
10060 else if (event
.xclient
.data
.l
[0]
10061 == dpyinfo
->Xatom_wm_delete_window
)
10064 = x_any_window_to_frame (dpyinfo
,
10065 event
.xclient
.window
);
10072 bufp
->kind
= delete_window_event
;
10073 XSETFRAME (bufp
->frame_or_window
, f
);
10082 else if (event
.xclient
.message_type
10083 == dpyinfo
->Xatom_wm_configure_denied
)
10086 else if (event
.xclient
.message_type
10087 == dpyinfo
->Xatom_wm_window_moved
)
10091 = x_window_to_frame (dpyinfo
, event
.xclient
.window
);
10093 new_x
= event
.xclient
.data
.s
[0];
10094 new_y
= event
.xclient
.data
.s
[1];
10098 f
->output_data
.x
->left_pos
= new_x
;
10099 f
->output_data
.x
->top_pos
= new_y
;
10102 #ifdef HACK_EDITRES
10103 else if (event
.xclient
.message_type
10104 == dpyinfo
->Xatom_editres
)
10107 = x_any_window_to_frame (dpyinfo
, event
.xclient
.window
);
10108 _XEditResCheckMessages (f
->output_data
.x
->widget
, NULL
,
10111 #endif /* HACK_EDITRES */
10112 else if ((event
.xclient
.message_type
10113 == dpyinfo
->Xatom_DONE
)
10114 || (event
.xclient
.message_type
10115 == dpyinfo
->Xatom_PAGE
))
10117 /* Ghostview job completed. Kill it. We could
10118 reply with "Next" if we received "Page", but we
10119 currently never do because we are interested in
10120 images, only, which should have 1 page. */
10121 Pixmap pixmap
= (Pixmap
) event
.xclient
.data
.l
[1];
10123 = x_window_to_frame (dpyinfo
, event
.xclient
.window
);
10124 x_kill_gs_process (pixmap
, f
);
10125 expose_frame (f
, 0, 0, 0, 0);
10127 #ifdef USE_TOOLKIT_SCROLL_BARS
10128 /* Scroll bar callbacks send a ClientMessage from which
10129 we construct an input_event. */
10130 else if (event
.xclient
.message_type
10131 == dpyinfo
->Xatom_Scrollbar
)
10133 x_scroll_bar_to_input_event (&event
, bufp
);
10134 ++bufp
, ++count
, --numchars
;
10137 #endif /* USE_TOOLKIT_SCROLL_BARS */
10143 case SelectionNotify
:
10144 #ifdef USE_X_TOOLKIT
10145 if (! x_window_to_frame (dpyinfo
, event
.xselection
.requestor
))
10147 #endif /* not USE_X_TOOLKIT */
10148 x_handle_selection_notify (&event
.xselection
);
10151 case SelectionClear
: /* Someone has grabbed ownership. */
10152 #ifdef USE_X_TOOLKIT
10153 if (! x_window_to_frame (dpyinfo
, event
.xselectionclear
.window
))
10155 #endif /* USE_X_TOOLKIT */
10157 XSelectionClearEvent
*eventp
= (XSelectionClearEvent
*) &event
;
10162 bufp
->kind
= selection_clear_event
;
10163 SELECTION_EVENT_DISPLAY (bufp
) = eventp
->display
;
10164 SELECTION_EVENT_SELECTION (bufp
) = eventp
->selection
;
10165 SELECTION_EVENT_TIME (bufp
) = eventp
->time
;
10166 bufp
->frame_or_window
= Qnil
;
10175 case SelectionRequest
: /* Someone wants our selection. */
10176 #ifdef USE_X_TOOLKIT
10177 if (!x_window_to_frame (dpyinfo
, event
.xselectionrequest
.owner
))
10179 #endif /* USE_X_TOOLKIT */
10180 if (x_queue_selection_requests
)
10181 x_queue_event (x_window_to_frame (dpyinfo
, event
.xselectionrequest
.owner
),
10185 XSelectionRequestEvent
*eventp
10186 = (XSelectionRequestEvent
*) &event
;
10191 bufp
->kind
= selection_request_event
;
10192 SELECTION_EVENT_DISPLAY (bufp
) = eventp
->display
;
10193 SELECTION_EVENT_REQUESTOR (bufp
) = eventp
->requestor
;
10194 SELECTION_EVENT_SELECTION (bufp
) = eventp
->selection
;
10195 SELECTION_EVENT_TARGET (bufp
) = eventp
->target
;
10196 SELECTION_EVENT_PROPERTY (bufp
) = eventp
->property
;
10197 SELECTION_EVENT_TIME (bufp
) = eventp
->time
;
10198 bufp
->frame_or_window
= Qnil
;
10207 case PropertyNotify
:
10208 #if 0 /* This is plain wrong. In the case that we are waiting for a
10209 PropertyNotify used as an ACK in incremental selection
10210 transfer, the property will be on the receiver's window. */
10211 #if defined USE_X_TOOLKIT
10212 if (!x_any_window_to_frame (dpyinfo
, event
.xproperty
.window
))
10216 x_handle_property_notify (&event
.xproperty
);
10219 case ReparentNotify
:
10220 f
= x_top_window_to_frame (dpyinfo
, event
.xreparent
.window
);
10224 f
->output_data
.x
->parent_desc
= event
.xreparent
.parent
;
10225 x_real_positions (f
, &x
, &y
);
10226 f
->output_data
.x
->left_pos
= x
;
10227 f
->output_data
.x
->top_pos
= y
;
10232 f
= x_window_to_frame (dpyinfo
, event
.xexpose
.window
);
10235 if (f
->async_visible
== 0)
10237 f
->async_visible
= 1;
10238 f
->async_iconified
= 0;
10239 f
->output_data
.x
->has_been_visible
= 1;
10240 SET_FRAME_GARBAGED (f
);
10243 expose_frame (x_window_to_frame (dpyinfo
,
10244 event
.xexpose
.window
),
10245 event
.xexpose
.x
, event
.xexpose
.y
,
10246 event
.xexpose
.width
, event
.xexpose
.height
);
10250 #ifndef USE_TOOLKIT_SCROLL_BARS
10251 struct scroll_bar
*bar
;
10253 #if defined USE_LUCID
10254 /* Submenus of the Lucid menu bar aren't widgets
10255 themselves, so there's no way to dispatch events
10256 to them. Recognize this case separately. */
10259 = x_window_to_menu_bar (event
.xexpose
.window
);
10261 xlwmenu_redisplay (widget
);
10263 #endif /* USE_LUCID */
10265 #ifdef USE_TOOLKIT_SCROLL_BARS
10266 /* Dispatch event to the widget. */
10268 #else /* not USE_TOOLKIT_SCROLL_BARS */
10269 bar
= x_window_to_scroll_bar (event
.xexpose
.window
);
10272 x_scroll_bar_expose (bar
, &event
);
10273 #ifdef USE_X_TOOLKIT
10276 #endif /* USE_X_TOOLKIT */
10277 #endif /* not USE_TOOLKIT_SCROLL_BARS */
10281 case GraphicsExpose
: /* This occurs when an XCopyArea's
10282 source area was obscured or not
10284 f
= x_window_to_frame (dpyinfo
, event
.xgraphicsexpose
.drawable
);
10288 event
.xgraphicsexpose
.x
, event
.xgraphicsexpose
.y
,
10289 event
.xgraphicsexpose
.width
,
10290 event
.xgraphicsexpose
.height
);
10292 #ifdef USE_X_TOOLKIT
10295 #endif /* USE_X_TOOLKIT */
10298 case NoExpose
: /* This occurs when an XCopyArea's
10299 source area was completely
10304 /* Redo the mouse-highlight after the tooltip has gone. */
10305 if (event
.xmap
.window
== tip_window
)
10308 redo_mouse_highlight ();
10311 f
= x_top_window_to_frame (dpyinfo
, event
.xunmap
.window
);
10312 if (f
) /* F may no longer exist if
10313 the frame was deleted. */
10315 /* While a frame is unmapped, display generation is
10316 disabled; you don't want to spend time updating a
10317 display that won't ever be seen. */
10318 f
->async_visible
= 0;
10319 /* We can't distinguish, from the event, whether the window
10320 has become iconified or invisible. So assume, if it
10321 was previously visible, than now it is iconified.
10322 But x_make_frame_invisible clears both
10323 the visible flag and the iconified flag;
10324 and that way, we know the window is not iconified now. */
10325 if (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
))
10327 f
->async_iconified
= 1;
10329 bufp
->kind
= iconify_event
;
10330 XSETFRAME (bufp
->frame_or_window
, f
);
10340 if (event
.xmap
.window
== tip_window
)
10341 /* The tooltip has been drawn already. Avoid
10342 the SET_FRAME_GARBAGED below. */
10345 /* We use x_top_window_to_frame because map events can
10346 come for sub-windows and they don't mean that the
10347 frame is visible. */
10348 f
= x_top_window_to_frame (dpyinfo
, event
.xmap
.window
);
10351 f
->async_visible
= 1;
10352 f
->async_iconified
= 0;
10353 f
->output_data
.x
->has_been_visible
= 1;
10355 /* wait_reading_process_input will notice this and update
10356 the frame's display structures. */
10357 SET_FRAME_GARBAGED (f
);
10361 bufp
->kind
= deiconify_event
;
10362 XSETFRAME (bufp
->frame_or_window
, f
);
10368 else if (! NILP (Vframe_list
)
10369 && ! NILP (XCDR (Vframe_list
)))
10370 /* Force a redisplay sooner or later
10371 to update the frame titles
10372 in case this is the second frame. */
10373 record_asynch_buffer_change ();
10378 f
= x_any_window_to_frame (dpyinfo
, event
.xkey
.window
);
10380 #if defined USE_MOTIF && defined USE_TOOLKIT_SCROLL_BARS
10383 /* Scroll bars consume key events, but we want
10384 the keys to go to the scroll bar's frame. */
10385 Widget widget
= XtWindowToWidget (dpyinfo
->display
,
10386 event
.xkey
.window
);
10387 if (widget
&& XmIsScrollBar (widget
))
10389 widget
= XtParent (widget
);
10390 f
= x_any_window_to_frame (dpyinfo
, XtWindow (widget
));
10393 #endif /* USE_MOTIF and USE_TOOLKIT_SCROLL_BARS */
10397 KeySym keysym
, orig_keysym
;
10398 /* al%imercury@uunet.uu.net says that making this 81
10399 instead of 80 fixed a bug whereby meta chars made
10402 It seems that some version of XmbLookupString has
10403 a bug of not returning XBufferOverflow in
10404 status_return even if the input is too long to
10405 fit in 81 bytes. So, we must prepare sufficient
10406 bytes for copy_buffer. 513 bytes (256 chars for
10407 two-byte character set) seems to be a faily good
10408 approximation. -- 2000.8.10 handa@etl.go.jp */
10409 unsigned char copy_buffer
[513];
10410 unsigned char *copy_bufptr
= copy_buffer
;
10411 int copy_bufsiz
= sizeof (copy_buffer
);
10415 |= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f
),
10416 extra_keyboard_modifiers
);
10417 modifiers
= event
.xkey
.state
;
10419 /* This will have to go some day... */
10421 /* make_lispy_event turns chars into control chars.
10422 Don't do it here because XLookupString is too eager. */
10423 event
.xkey
.state
&= ~ControlMask
;
10424 event
.xkey
.state
&= ~(dpyinfo
->meta_mod_mask
10425 | dpyinfo
->super_mod_mask
10426 | dpyinfo
->hyper_mod_mask
10427 | dpyinfo
->alt_mod_mask
);
10429 /* In case Meta is ComposeCharacter,
10430 clear its status. According to Markus Ehrnsperger
10431 Markus.Ehrnsperger@lehrstuhl-bross.physik.uni-muenchen.de
10432 this enables ComposeCharacter to work whether or
10433 not it is combined with Meta. */
10434 if (modifiers
& dpyinfo
->meta_mod_mask
)
10435 bzero (&compose_status
, sizeof (compose_status
));
10440 Status status_return
;
10442 nbytes
= XmbLookupString (FRAME_XIC (f
),
10443 &event
.xkey
, copy_bufptr
,
10444 copy_bufsiz
, &keysym
,
10446 if (status_return
== XBufferOverflow
)
10448 copy_bufsiz
= nbytes
+ 1;
10449 copy_bufptr
= (char *) alloca (copy_bufsiz
);
10450 nbytes
= XmbLookupString (FRAME_XIC (f
),
10451 &event
.xkey
, copy_bufptr
,
10452 copy_bufsiz
, &keysym
,
10456 if (status_return
== XLookupNone
)
10458 else if (status_return
== XLookupChars
)
10463 else if (status_return
!= XLookupKeySym
10464 && status_return
!= XLookupBoth
)
10468 nbytes
= XLookupString (&event
.xkey
, copy_bufptr
,
10469 copy_bufsiz
, &keysym
,
10472 nbytes
= XLookupString (&event
.xkey
, copy_bufptr
,
10473 copy_bufsiz
, &keysym
,
10477 orig_keysym
= keysym
;
10481 if (((keysym
>= XK_BackSpace
&& keysym
<= XK_Escape
)
10482 || keysym
== XK_Delete
10483 #ifdef XK_ISO_Left_Tab
10484 || (keysym
>= XK_ISO_Left_Tab
&& keysym
<= XK_ISO_Enter
)
10486 || (keysym
>= XK_Kanji
&& keysym
<= XK_Eisu_toggle
)
10487 || IsCursorKey (keysym
) /* 0xff50 <= x < 0xff60 */
10488 || IsMiscFunctionKey (keysym
) /* 0xff60 <= x < VARIES */
10490 /* This recognizes the "extended function keys".
10491 It seems there's no cleaner way.
10492 Test IsModifierKey to avoid handling mode_switch
10494 || ((unsigned) (keysym
) >= XK_Select
10495 && (unsigned)(keysym
) < XK_KP_Space
)
10497 #ifdef XK_dead_circumflex
10498 || orig_keysym
== XK_dead_circumflex
10500 #ifdef XK_dead_grave
10501 || orig_keysym
== XK_dead_grave
10503 #ifdef XK_dead_tilde
10504 || orig_keysym
== XK_dead_tilde
10506 #ifdef XK_dead_diaeresis
10507 || orig_keysym
== XK_dead_diaeresis
10509 #ifdef XK_dead_macron
10510 || orig_keysym
== XK_dead_macron
10512 #ifdef XK_dead_degree
10513 || orig_keysym
== XK_dead_degree
10515 #ifdef XK_dead_acute
10516 || orig_keysym
== XK_dead_acute
10518 #ifdef XK_dead_cedilla
10519 || orig_keysym
== XK_dead_cedilla
10521 #ifdef XK_dead_breve
10522 || orig_keysym
== XK_dead_breve
10524 #ifdef XK_dead_ogonek
10525 || orig_keysym
== XK_dead_ogonek
10527 #ifdef XK_dead_caron
10528 || orig_keysym
== XK_dead_caron
10530 #ifdef XK_dead_doubleacute
10531 || orig_keysym
== XK_dead_doubleacute
10533 #ifdef XK_dead_abovedot
10534 || orig_keysym
== XK_dead_abovedot
10536 || IsKeypadKey (keysym
) /* 0xff80 <= x < 0xffbe */
10537 || IsFunctionKey (keysym
) /* 0xffbe <= x < 0xffe1 */
10538 /* Any "vendor-specific" key is ok. */
10539 || (orig_keysym
& (1 << 28))
10540 || (keysym
!= NoSymbol
&& nbytes
== 0))
10541 && ! (IsModifierKey (orig_keysym
)
10543 #ifdef XK_Mode_switch
10544 || ((unsigned)(orig_keysym
) == XK_Mode_switch
)
10547 || ((unsigned)(orig_keysym
) == XK_Num_Lock
)
10549 #endif /* not HAVE_X11R5 */
10552 if (temp_index
== sizeof temp_buffer
/ sizeof (short))
10554 temp_buffer
[temp_index
++] = keysym
;
10555 bufp
->kind
= non_ascii_keystroke
;
10556 bufp
->code
= keysym
;
10557 XSETFRAME (bufp
->frame_or_window
, f
);
10560 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
10562 bufp
->timestamp
= event
.xkey
.time
;
10567 else if (numchars
> nbytes
)
10573 for (i
= 0; i
< nbytes
; i
++)
10575 if (temp_index
== (sizeof temp_buffer
10578 temp_buffer
[temp_index
++] = copy_bufptr
[i
];
10581 if (/* If the event is not from XIM, */
10582 event
.xkey
.keycode
!= 0
10583 /* or the current locale doesn't request
10584 decoding of the intup data, ... */
10585 || coding
.type
== coding_type_raw_text
10586 || coding
.type
== coding_type_no_conversion
)
10588 /* ... we can use the input data as is. */
10593 /* We have to decode the input data. */
10597 require
= decoding_buffer_size (&coding
, nbytes
);
10598 p
= (unsigned char *) alloca (require
);
10599 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
10600 decode_coding (&coding
, copy_bufptr
, p
,
10602 nbytes
= coding
.produced
;
10603 nchars
= coding
.produced_char
;
10607 /* Convert the input data to a sequence of
10608 character events. */
10609 for (i
= 0; i
< nbytes
; i
+= len
)
10611 if (nchars
== nbytes
)
10612 c
= copy_bufptr
[i
], len
= 1;
10614 c
= STRING_CHAR_AND_LENGTH (copy_bufptr
+ i
,
10617 bufp
->kind
= (SINGLE_BYTE_CHAR_P (c
)
10619 : multibyte_char_keystroke
);
10621 XSETFRAME (bufp
->frame_or_window
, f
);
10624 = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
10626 bufp
->timestamp
= event
.xkey
.time
;
10631 numchars
-= nchars
;
10633 if (keysym
== NoSymbol
)
10643 /* Don't dispatch this event since XtDispatchEvent calls
10644 XFilterEvent, and two calls in a row may freeze the
10653 /* Don't dispatch this event since XtDispatchEvent calls
10654 XFilterEvent, and two calls in a row may freeze the
10661 /* Here's a possible interpretation of the whole
10662 FocusIn-EnterNotify FocusOut-LeaveNotify mess. If
10663 you get a FocusIn event, you have to get a FocusOut
10664 event before you relinquish the focus. If you
10665 haven't received a FocusIn event, then a mere
10666 LeaveNotify is enough to free you. */
10670 f
= x_any_window_to_frame (dpyinfo
, event
.xcrossing
.window
);
10673 if (event
.xcrossing
.focus
)
10675 /* Avoid nasty pop/raise loops. */
10676 if (f
&& (!(f
->auto_raise
)
10677 || !(f
->auto_lower
)
10678 || (event
.xcrossing
.time
- enter_timestamp
) > 500))
10680 x_new_focus_frame (dpyinfo
, f
);
10681 enter_timestamp
= event
.xcrossing
.time
;
10684 else if (f
== dpyinfo
->x_focus_frame
)
10685 x_new_focus_frame (dpyinfo
, 0);
10688 /* EnterNotify counts as mouse movement,
10689 so update things that depend on mouse position. */
10690 if (f
&& !f
->output_data
.x
->hourglass_p
)
10691 note_mouse_movement (f
, &event
.xmotion
);
10696 f
= x_any_window_to_frame (dpyinfo
, event
.xfocus
.window
);
10697 if (event
.xfocus
.detail
!= NotifyPointer
)
10698 dpyinfo
->x_focus_event_frame
= f
;
10701 x_new_focus_frame (dpyinfo
, f
);
10703 /* Don't stop displaying the initial startup message
10704 for a switch-frame event we don't need. */
10705 if (GC_NILP (Vterminal_frame
)
10706 && GC_CONSP (Vframe_list
)
10707 && !GC_NILP (XCDR (Vframe_list
)))
10709 bufp
->kind
= FOCUS_IN_EVENT
;
10710 XSETFRAME (bufp
->frame_or_window
, f
);
10712 ++bufp
, ++count
, --numchars
;
10717 if (f
&& FRAME_XIC (f
))
10718 XSetICFocus (FRAME_XIC (f
));
10724 f
= x_top_window_to_frame (dpyinfo
, event
.xcrossing
.window
);
10727 if (f
== dpyinfo
->mouse_face_mouse_frame
)
10729 /* If we move outside the frame, then we're
10730 certainly no longer on any text in the frame. */
10731 clear_mouse_face (dpyinfo
);
10732 dpyinfo
->mouse_face_mouse_frame
= 0;
10735 /* Generate a nil HELP_EVENT to cancel a help-echo.
10736 Do it only if there's something to cancel.
10737 Otherwise, the startup message is cleared when
10738 the mouse leaves the frame. */
10739 if (any_help_event_p
)
10744 XSETFRAME (frame
, f
);
10746 n
= gen_help_event (bufp
, numchars
,
10747 Qnil
, frame
, Qnil
, Qnil
, 0);
10748 bufp
+= n
, count
+= n
, numchars
-= n
;
10752 if (event
.xcrossing
.focus
)
10753 x_mouse_leave (dpyinfo
);
10756 if (f
== dpyinfo
->x_focus_event_frame
)
10757 dpyinfo
->x_focus_event_frame
= 0;
10758 if (f
== dpyinfo
->x_focus_frame
)
10759 x_new_focus_frame (dpyinfo
, 0);
10766 f
= x_any_window_to_frame (dpyinfo
, event
.xfocus
.window
);
10767 if (event
.xfocus
.detail
!= NotifyPointer
10768 && f
== dpyinfo
->x_focus_event_frame
)
10769 dpyinfo
->x_focus_event_frame
= 0;
10770 if (f
&& f
== dpyinfo
->x_focus_frame
)
10771 x_new_focus_frame (dpyinfo
, 0);
10774 if (f
&& FRAME_XIC (f
))
10775 XUnsetICFocus (FRAME_XIC (f
));
10782 previous_help_echo
= help_echo
;
10783 help_echo
= help_echo_object
= help_echo_window
= Qnil
;
10784 help_echo_pos
= -1;
10786 if (dpyinfo
->grabbed
&& last_mouse_frame
10787 && FRAME_LIVE_P (last_mouse_frame
))
10788 f
= last_mouse_frame
;
10790 f
= x_window_to_frame (dpyinfo
, event
.xmotion
.window
);
10793 note_mouse_movement (f
, &event
.xmotion
);
10796 #ifndef USE_TOOLKIT_SCROLL_BARS
10797 struct scroll_bar
*bar
10798 = x_window_to_scroll_bar (event
.xmotion
.window
);
10801 x_scroll_bar_note_movement (bar
, &event
);
10802 #endif /* USE_TOOLKIT_SCROLL_BARS */
10804 /* If we move outside the frame, then we're
10805 certainly no longer on any text in the frame. */
10806 clear_mouse_face (dpyinfo
);
10809 /* If the contents of the global variable help_echo
10810 has changed, generate a HELP_EVENT. */
10811 if (!NILP (help_echo
)
10812 || !NILP (previous_help_echo
))
10818 XSETFRAME (frame
, f
);
10822 any_help_event_p
= 1;
10823 n
= gen_help_event (bufp
, numchars
, help_echo
, frame
,
10824 help_echo_window
, help_echo_object
,
10826 bufp
+= n
, count
+= n
, numchars
-= n
;
10832 case ConfigureNotify
:
10833 f
= x_top_window_to_frame (dpyinfo
, event
.xconfigure
.window
);
10836 #ifndef USE_X_TOOLKIT
10837 int rows
= PIXEL_TO_CHAR_HEIGHT (f
, event
.xconfigure
.height
);
10838 int columns
= PIXEL_TO_CHAR_WIDTH (f
, event
.xconfigure
.width
);
10840 /* In the toolkit version, change_frame_size
10841 is called by the code that handles resizing
10842 of the EmacsFrame widget. */
10844 /* Even if the number of character rows and columns has
10845 not changed, the font size may have changed, so we need
10846 to check the pixel dimensions as well. */
10847 if (columns
!= f
->width
10848 || rows
!= f
->height
10849 || event
.xconfigure
.width
!= f
->output_data
.x
->pixel_width
10850 || event
.xconfigure
.height
!= f
->output_data
.x
->pixel_height
)
10852 change_frame_size (f
, rows
, columns
, 0, 1, 0);
10853 SET_FRAME_GARBAGED (f
);
10854 cancel_mouse_face (f
);
10858 f
->output_data
.x
->pixel_width
= event
.xconfigure
.width
;
10859 f
->output_data
.x
->pixel_height
= event
.xconfigure
.height
;
10861 /* What we have now is the position of Emacs's own window.
10862 Convert that to the position of the window manager window. */
10863 x_real_positions (f
, &f
->output_data
.x
->left_pos
,
10864 &f
->output_data
.x
->top_pos
);
10867 if (FRAME_XIC (f
) && (FRAME_XIC_STYLE (f
) & XIMStatusArea
))
10868 xic_set_statusarea (f
);
10871 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
10873 /* Since the WM decorations come below top_pos now,
10874 we must put them below top_pos in the future. */
10875 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
10876 x_wm_set_size_hint (f
, (long) 0, 0);
10879 /* Some window managers pass (0,0) as the location of
10880 the window, and the Motif event handler stores it
10881 in the emacs widget, which messes up Motif menus. */
10882 if (event
.xconfigure
.x
== 0 && event
.xconfigure
.y
== 0)
10884 event
.xconfigure
.x
= f
->output_data
.x
->widget
->core
.x
;
10885 event
.xconfigure
.y
= f
->output_data
.x
->widget
->core
.y
;
10887 #endif /* USE_MOTIF */
10892 case ButtonRelease
:
10894 /* If we decide we want to generate an event to be seen
10895 by the rest of Emacs, we put it here. */
10896 struct input_event emacs_event
;
10897 int tool_bar_p
= 0;
10899 emacs_event
.kind
= no_event
;
10900 bzero (&compose_status
, sizeof (compose_status
));
10902 if (dpyinfo
->grabbed
10903 && last_mouse_frame
10904 && FRAME_LIVE_P (last_mouse_frame
))
10905 f
= last_mouse_frame
;
10907 f
= x_window_to_frame (dpyinfo
, event
.xbutton
.window
);
10911 /* Is this in the tool-bar? */
10912 if (WINDOWP (f
->tool_bar_window
)
10913 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
10915 Lisp_Object window
;
10918 x
= event
.xbutton
.x
;
10919 y
= event
.xbutton
.y
;
10922 window
= window_from_coordinates (f
, x
, y
, &p
, 1);
10923 if (EQ (window
, f
->tool_bar_window
))
10925 x_handle_tool_bar_click (f
, &event
.xbutton
);
10931 if (!dpyinfo
->x_focus_frame
10932 || f
== dpyinfo
->x_focus_frame
)
10933 construct_mouse_click (&emacs_event
, &event
, f
);
10937 #ifndef USE_TOOLKIT_SCROLL_BARS
10938 struct scroll_bar
*bar
10939 = x_window_to_scroll_bar (event
.xbutton
.window
);
10942 x_scroll_bar_handle_click (bar
, &event
, &emacs_event
);
10943 #endif /* not USE_TOOLKIT_SCROLL_BARS */
10946 if (event
.type
== ButtonPress
)
10948 dpyinfo
->grabbed
|= (1 << event
.xbutton
.button
);
10949 last_mouse_frame
= f
;
10950 /* Ignore any mouse motion that happened
10951 before this event; any subsequent mouse-movement
10952 Emacs events should reflect only motion after
10953 the ButtonPress. */
10955 f
->mouse_moved
= 0;
10958 last_tool_bar_item
= -1;
10962 dpyinfo
->grabbed
&= ~(1 << event
.xbutton
.button
);
10965 if (numchars
>= 1 && emacs_event
.kind
!= no_event
)
10967 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
10973 #ifdef USE_X_TOOLKIT
10974 f
= x_menubar_window_to_frame (dpyinfo
, event
.xbutton
.window
);
10975 /* For a down-event in the menu bar,
10976 don't pass it to Xt right now.
10977 Instead, save it away
10978 and we will pass it to Xt from kbd_buffer_get_event.
10979 That way, we can run some Lisp code first. */
10980 if (f
&& event
.type
== ButtonPress
10981 /* Verify the event is really within the menu bar
10982 and not just sent to it due to grabbing. */
10983 && event
.xbutton
.x
>= 0
10984 && event
.xbutton
.x
< f
->output_data
.x
->pixel_width
10985 && event
.xbutton
.y
>= 0
10986 && event
.xbutton
.y
< f
->output_data
.x
->menubar_height
10987 && event
.xbutton
.same_screen
)
10989 SET_SAVED_BUTTON_EVENT
;
10990 XSETFRAME (last_mouse_press_frame
, f
);
10992 else if (event
.type
== ButtonPress
)
10994 last_mouse_press_frame
= Qnil
;
10998 #ifdef USE_MOTIF /* This should do not harm for Lucid,
10999 but I am trying to be cautious. */
11000 else if (event
.type
== ButtonRelease
)
11002 if (!NILP (last_mouse_press_frame
))
11004 f
= XFRAME (last_mouse_press_frame
);
11005 if (f
->output_data
.x
)
11006 SET_SAVED_BUTTON_EVENT
;
11011 #endif /* USE_MOTIF */
11014 #endif /* USE_X_TOOLKIT */
11018 case CirculateNotify
:
11021 case CirculateRequest
:
11024 case VisibilityNotify
:
11027 case MappingNotify
:
11028 /* Someone has changed the keyboard mapping - update the
11030 switch (event
.xmapping
.request
)
11032 case MappingModifier
:
11033 x_find_modifier_meanings (dpyinfo
);
11034 /* This is meant to fall through. */
11035 case MappingKeyboard
:
11036 XRefreshKeyboardMapping (&event
.xmapping
);
11042 #ifdef USE_X_TOOLKIT
11044 XtDispatchEvent (&event
);
11046 #endif /* USE_X_TOOLKIT */
11054 /* On some systems, an X bug causes Emacs to get no more events
11055 when the window is destroyed. Detect that. (1994.) */
11058 /* Emacs and the X Server eats up CPU time if XNoOp is done every time.
11059 One XNOOP in 100 loops will make Emacs terminate.
11060 B. Bretthauer, 1994 */
11062 if (x_noop_count
>= 100)
11066 if (next_noop_dpyinfo
== 0)
11067 next_noop_dpyinfo
= x_display_list
;
11069 XNoOp (next_noop_dpyinfo
->display
);
11071 /* Each time we get here, cycle through the displays now open. */
11072 next_noop_dpyinfo
= next_noop_dpyinfo
->next
;
11076 /* If the focus was just given to an auto-raising frame,
11078 /* ??? This ought to be able to handle more than one such frame. */
11079 if (pending_autoraise_frame
)
11081 x_raise_frame (pending_autoraise_frame
);
11082 pending_autoraise_frame
= 0;
11093 /***********************************************************************
11095 ***********************************************************************/
11097 /* Notice if the text cursor of window W has been overwritten by a
11098 drawing operation that outputs N glyphs starting at START_X and
11099 ending at END_X in the line given by output_cursor.vpos.
11100 Coordinates are area-relative. END_X < 0 means all the rest
11101 of the line after START_X has been written. */
11104 notice_overwritten_cursor (w
, start_x
, end_x
)
11106 int start_x
, end_x
;
11108 if (updated_area
== TEXT_AREA
11109 && w
->phys_cursor_on_p
11110 && output_cursor
.vpos
== w
->phys_cursor
.vpos
11111 && start_x
<= w
->phys_cursor
.x
11112 && end_x
> w
->phys_cursor
.x
)
11113 w
->phys_cursor_on_p
= 0;
11117 /* Set clipping for output in glyph row ROW. W is the window in which
11118 we operate. GC is the graphics context to set clipping in.
11119 WHOLE_LINE_P non-zero means include the areas used for truncation
11120 mark display and alike in the clipping rectangle.
11122 ROW may be a text row or, e.g., a mode line. Text rows must be
11123 clipped to the interior of the window dedicated to text display,
11124 mode lines must be clipped to the whole window. */
11127 x_clip_to_row (w
, row
, gc
, whole_line_p
)
11129 struct glyph_row
*row
;
11133 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
11134 XRectangle clip_rect
;
11135 int window_x
, window_y
, window_width
, window_height
;
11137 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
11139 clip_rect
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
11140 clip_rect
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
11141 clip_rect
.y
= max (clip_rect
.y
, window_y
);
11142 clip_rect
.width
= window_width
;
11143 clip_rect
.height
= row
->visible_height
;
11145 /* If clipping to the whole line, including trunc marks, extend
11146 the rectangle to the left and increase its width. */
11149 clip_rect
.x
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
11150 clip_rect
.width
+= FRAME_X_FRINGE_WIDTH (f
);
11153 XSetClipRectangles (FRAME_X_DISPLAY (f
), gc
, 0, 0, &clip_rect
, 1, Unsorted
);
11157 /* Draw a hollow box cursor on window W in glyph row ROW. */
11160 x_draw_hollow_cursor (w
, row
)
11162 struct glyph_row
*row
;
11164 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
11165 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
11166 Display
*dpy
= FRAME_X_DISPLAY (f
);
11169 struct glyph
*cursor_glyph
;
11172 /* Compute frame-relative coordinates from window-relative
11174 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
11175 y
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
11176 + row
->ascent
- w
->phys_cursor_ascent
);
11177 h
= row
->height
- 1;
11179 /* Get the glyph the cursor is on. If we can't tell because
11180 the current matrix is invalid or such, give up. */
11181 cursor_glyph
= get_phys_cursor_glyph (w
);
11182 if (cursor_glyph
== NULL
)
11185 /* Compute the width of the rectangle to draw. If on a stretch
11186 glyph, and `x-stretch-block-cursor' is nil, don't draw a
11187 rectangle as wide as the glyph, but use a canonical character
11189 wd
= cursor_glyph
->pixel_width
- 1;
11190 if (cursor_glyph
->type
== STRETCH_GLYPH
11191 && !x_stretch_cursor_p
)
11192 wd
= min (CANON_X_UNIT (f
), wd
);
11194 /* The foreground of cursor_gc is typically the same as the normal
11195 background color, which can cause the cursor box to be invisible. */
11196 xgcv
.foreground
= f
->output_data
.x
->cursor_pixel
;
11197 if (dpyinfo
->scratch_cursor_gc
)
11198 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
11200 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_X_WINDOW (f
),
11201 GCForeground
, &xgcv
);
11202 gc
= dpyinfo
->scratch_cursor_gc
;
11204 /* Set clipping, draw the rectangle, and reset clipping again. */
11205 x_clip_to_row (w
, row
, gc
, 0);
11206 XDrawRectangle (dpy
, FRAME_X_WINDOW (f
), gc
, x
, y
, wd
, h
);
11207 XSetClipMask (dpy
, gc
, None
);
11211 /* Draw a bar cursor on window W in glyph row ROW.
11213 Implementation note: One would like to draw a bar cursor with an
11214 angle equal to the one given by the font property XA_ITALIC_ANGLE.
11215 Unfortunately, I didn't find a font yet that has this property set.
11219 x_draw_bar_cursor (w
, row
, width
)
11221 struct glyph_row
*row
;
11224 struct frame
*f
= XFRAME (w
->frame
);
11225 struct glyph
*cursor_glyph
;
11227 /* If cursor is out of bounds, don't draw garbage. This can happen
11228 in mini-buffer windows when switching between echo area glyphs
11229 and mini-buffer. */
11230 cursor_glyph
= get_phys_cursor_glyph (w
);
11231 if (cursor_glyph
== NULL
)
11234 /* If on an image, draw like a normal cursor. That's usually better
11235 visible than drawing a bar, esp. if the image is large so that
11236 the bar might not be in the window. */
11237 if (cursor_glyph
->type
== IMAGE_GLYPH
)
11239 struct glyph_row
*row
;
11240 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
11241 x_draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
11245 Display
*dpy
= FRAME_X_DISPLAY (f
);
11246 Window window
= FRAME_X_WINDOW (f
);
11247 GC gc
= FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
;
11248 unsigned long mask
= GCForeground
| GCBackground
| GCGraphicsExposures
;
11249 struct face
*face
= FACE_FROM_ID (f
, cursor_glyph
->face_id
);
11252 /* If the glyph's background equals the color we normally draw
11253 the bar cursor in, the bar cursor in its normal color is
11254 invisible. Use the glyph's foreground color instead in this
11255 case, on the assumption that the glyph's colors are chosen so
11256 that the glyph is legible. */
11257 if (face
->background
== f
->output_data
.x
->cursor_pixel
)
11258 xgcv
.background
= xgcv
.foreground
= face
->foreground
;
11260 xgcv
.background
= xgcv
.foreground
= f
->output_data
.x
->cursor_pixel
;
11261 xgcv
.graphics_exposures
= 0;
11264 XChangeGC (dpy
, gc
, mask
, &xgcv
);
11267 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
11268 FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
11272 width
= f
->output_data
.x
->cursor_width
;
11273 width
= min (cursor_glyph
->pixel_width
, width
);
11275 x_clip_to_row (w
, row
, gc
, 0);
11276 XFillRectangle (dpy
, window
, gc
,
11277 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
11278 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
11279 width
, row
->height
);
11280 XSetClipMask (dpy
, gc
, None
);
11285 /* Clear the cursor of window W to background color, and mark the
11286 cursor as not shown. This is used when the text where the cursor
11287 is is about to be rewritten. */
11293 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
11294 x_update_window_cursor (w
, 0);
11298 /* Draw the cursor glyph of window W in glyph row ROW. See the
11299 comment of x_draw_glyphs for the meaning of HL. */
11302 x_draw_phys_cursor_glyph (w
, row
, hl
)
11304 struct glyph_row
*row
;
11305 enum draw_glyphs_face hl
;
11307 /* If cursor hpos is out of bounds, don't draw garbage. This can
11308 happen in mini-buffer windows when switching between echo area
11309 glyphs and mini-buffer. */
11310 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
11312 int on_p
= w
->phys_cursor_on_p
;
11314 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
11315 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
11317 w
->phys_cursor_on_p
= on_p
;
11319 /* When we erase the cursor, and ROW is overlapped by other
11320 rows, make sure that these overlapping parts of other rows
11322 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
11324 if (row
> w
->current_matrix
->rows
11325 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
11326 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
11328 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
11329 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
11330 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
11336 /* Erase the image of a cursor of window W from the screen. */
11339 x_erase_phys_cursor (w
)
11342 struct frame
*f
= XFRAME (w
->frame
);
11343 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
11344 int hpos
= w
->phys_cursor
.hpos
;
11345 int vpos
= w
->phys_cursor
.vpos
;
11346 int mouse_face_here_p
= 0;
11347 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
11348 struct glyph_row
*cursor_row
;
11349 struct glyph
*cursor_glyph
;
11350 enum draw_glyphs_face hl
;
11352 /* No cursor displayed or row invalidated => nothing to do on the
11354 if (w
->phys_cursor_type
== NO_CURSOR
)
11355 goto mark_cursor_off
;
11357 /* VPOS >= active_glyphs->nrows means that window has been resized.
11358 Don't bother to erase the cursor. */
11359 if (vpos
>= active_glyphs
->nrows
)
11360 goto mark_cursor_off
;
11362 /* If row containing cursor is marked invalid, there is nothing we
11364 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
11365 if (!cursor_row
->enabled_p
)
11366 goto mark_cursor_off
;
11368 /* This can happen when the new row is shorter than the old one.
11369 In this case, either x_draw_glyphs or clear_end_of_line
11370 should have cleared the cursor. Note that we wouldn't be
11371 able to erase the cursor in this case because we don't have a
11372 cursor glyph at hand. */
11373 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
11374 goto mark_cursor_off
;
11376 /* If the cursor is in the mouse face area, redisplay that when
11377 we clear the cursor. */
11378 if (! NILP (dpyinfo
->mouse_face_window
)
11379 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
11380 && (vpos
> dpyinfo
->mouse_face_beg_row
11381 || (vpos
== dpyinfo
->mouse_face_beg_row
11382 && hpos
>= dpyinfo
->mouse_face_beg_col
))
11383 && (vpos
< dpyinfo
->mouse_face_end_row
11384 || (vpos
== dpyinfo
->mouse_face_end_row
11385 && hpos
< dpyinfo
->mouse_face_end_col
))
11386 /* Don't redraw the cursor's spot in mouse face if it is at the
11387 end of a line (on a newline). The cursor appears there, but
11388 mouse highlighting does not. */
11389 && cursor_row
->used
[TEXT_AREA
] > hpos
)
11390 mouse_face_here_p
= 1;
11392 /* Maybe clear the display under the cursor. */
11393 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
11396 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
11398 cursor_glyph
= get_phys_cursor_glyph (w
);
11399 if (cursor_glyph
== NULL
)
11400 goto mark_cursor_off
;
11402 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
11404 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
11406 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
11408 cursor_glyph
->pixel_width
,
11409 cursor_row
->visible_height
,
11413 /* Erase the cursor by redrawing the character underneath it. */
11414 if (mouse_face_here_p
)
11415 hl
= DRAW_MOUSE_FACE
;
11417 hl
= DRAW_NORMAL_TEXT
;
11418 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
11421 w
->phys_cursor_on_p
= 0;
11422 w
->phys_cursor_type
= NO_CURSOR
;
11426 /* Non-zero if physical cursor of window W is within mouse face. */
11429 cursor_in_mouse_face_p (w
)
11432 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
11433 int in_mouse_face
= 0;
11435 if (WINDOWP (dpyinfo
->mouse_face_window
)
11436 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
11438 int hpos
= w
->phys_cursor
.hpos
;
11439 int vpos
= w
->phys_cursor
.vpos
;
11441 if (vpos
>= dpyinfo
->mouse_face_beg_row
11442 && vpos
<= dpyinfo
->mouse_face_end_row
11443 && (vpos
> dpyinfo
->mouse_face_beg_row
11444 || hpos
>= dpyinfo
->mouse_face_beg_col
)
11445 && (vpos
< dpyinfo
->mouse_face_end_row
11446 || hpos
< dpyinfo
->mouse_face_end_col
11447 || dpyinfo
->mouse_face_past_end
))
11451 return in_mouse_face
;
11455 /* Display or clear cursor of window W. If ON is zero, clear the
11456 cursor. If it is non-zero, display the cursor. If ON is nonzero,
11457 where to put the cursor is specified by HPOS, VPOS, X and Y. */
11460 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
11462 int on
, hpos
, vpos
, x
, y
;
11464 struct frame
*f
= XFRAME (w
->frame
);
11465 int new_cursor_type
;
11466 int new_cursor_width
;
11467 struct glyph_matrix
*current_glyphs
;
11468 struct glyph_row
*glyph_row
;
11469 struct glyph
*glyph
;
11470 int cursor_non_selected
;
11472 /* This is pointless on invisible frames, and dangerous on garbaged
11473 windows and frames; in the latter case, the frame or window may
11474 be in the midst of changing its size, and x and y may be off the
11476 if (! FRAME_VISIBLE_P (f
)
11477 || FRAME_GARBAGED_P (f
)
11478 || vpos
>= w
->current_matrix
->nrows
11479 || hpos
>= w
->current_matrix
->matrix_w
)
11482 /* If cursor is off and we want it off, return quickly. */
11483 if (!on
&& !w
->phys_cursor_on_p
)
11486 current_glyphs
= w
->current_matrix
;
11487 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
11488 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
11490 /* If cursor row is not enabled, we don't really know where to
11491 display the cursor. */
11492 if (!glyph_row
->enabled_p
)
11494 w
->phys_cursor_on_p
= 0;
11498 xassert (interrupt_input_blocked
);
11500 /* Set new_cursor_type to the cursor we want to be displayed. In a
11501 mini-buffer window, we want the cursor only to appear if we are
11502 reading input from this window. For the selected window, we want
11503 the cursor type given by the frame parameter. If explicitly
11504 marked off, draw no cursor. In all other cases, we want a hollow
11506 cursor_non_selected
11507 = !NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows
,
11509 new_cursor_width
= -1;
11510 if (cursor_in_echo_area
11511 && FRAME_HAS_MINIBUF_P (f
)
11512 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
11514 if (w
== XWINDOW (echo_area_window
))
11515 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
11516 else if (cursor_non_selected
)
11517 new_cursor_type
= HOLLOW_BOX_CURSOR
;
11519 new_cursor_type
= NO_CURSOR
;
11523 if (f
!= FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
11524 || w
!= XWINDOW (f
->selected_window
))
11526 if ((MINI_WINDOW_P (w
) && minibuf_level
== 0)
11527 || !cursor_non_selected
11528 || NILP (XBUFFER (w
->buffer
)->cursor_type
))
11529 new_cursor_type
= NO_CURSOR
;
11531 new_cursor_type
= HOLLOW_BOX_CURSOR
;
11533 else if (w
->cursor_off_p
)
11534 new_cursor_type
= NO_CURSOR
;
11537 struct buffer
*b
= XBUFFER (w
->buffer
);
11539 if (EQ (b
->cursor_type
, Qt
))
11540 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
11542 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
11543 &new_cursor_width
);
11547 /* If cursor is currently being shown and we don't want it to be or
11548 it is in the wrong place, or the cursor type is not what we want,
11550 if (w
->phys_cursor_on_p
11552 || w
->phys_cursor
.x
!= x
11553 || w
->phys_cursor
.y
!= y
11554 || new_cursor_type
!= w
->phys_cursor_type
))
11555 x_erase_phys_cursor (w
);
11557 /* If the cursor is now invisible and we want it to be visible,
11559 if (on
&& !w
->phys_cursor_on_p
)
11561 w
->phys_cursor_ascent
= glyph_row
->ascent
;
11562 w
->phys_cursor_height
= glyph_row
->height
;
11564 /* Set phys_cursor_.* before x_draw_.* is called because some
11565 of them may need the information. */
11566 w
->phys_cursor
.x
= x
;
11567 w
->phys_cursor
.y
= glyph_row
->y
;
11568 w
->phys_cursor
.hpos
= hpos
;
11569 w
->phys_cursor
.vpos
= vpos
;
11570 w
->phys_cursor_type
= new_cursor_type
;
11571 w
->phys_cursor_on_p
= 1;
11573 switch (new_cursor_type
)
11575 case HOLLOW_BOX_CURSOR
:
11576 x_draw_hollow_cursor (w
, glyph_row
);
11579 case FILLED_BOX_CURSOR
:
11580 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
11584 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
11595 if (w
== XWINDOW (f
->selected_window
))
11596 if (FRAME_XIC (f
) && (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
))
11597 xic_set_preeditarea (w
, x
, y
);
11602 if (updating_frame
!= f
)
11603 XFlush (FRAME_X_DISPLAY (f
));
11608 /* Display the cursor on window W, or clear it. X and Y are window
11609 relative pixel coordinates. HPOS and VPOS are glyph matrix
11610 positions. If W is not the selected window, display a hollow
11611 cursor. ON non-zero means display the cursor at X, Y which
11612 correspond to HPOS, VPOS, otherwise it is cleared. */
11615 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
11617 int on
, hpos
, vpos
, x
, y
;
11620 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
11625 /* Display the cursor on window W, or clear it, according to ON_P.
11626 Don't change the cursor's position. */
11629 x_update_cursor (f
, on_p
)
11632 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
11636 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
11637 in the window tree rooted at W. */
11640 x_update_cursor_in_window_tree (w
, on_p
)
11646 if (!NILP (w
->hchild
))
11647 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
11648 else if (!NILP (w
->vchild
))
11649 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
11651 x_update_window_cursor (w
, on_p
);
11653 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
11658 /* Switch the display of W's cursor on or off, according to the value
11662 x_update_window_cursor (w
, on
)
11666 /* Don't update cursor in windows whose frame is in the process
11667 of being deleted. */
11668 if (w
->current_matrix
)
11671 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
11672 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
11682 /* Make the x-window of frame F use the gnu icon bitmap. */
11685 x_bitmap_icon (f
, file
)
11691 if (FRAME_X_WINDOW (f
) == 0)
11694 /* Free up our existing icon bitmap if any. */
11695 if (f
->output_data
.x
->icon_bitmap
> 0)
11696 x_destroy_bitmap (f
, f
->output_data
.x
->icon_bitmap
);
11697 f
->output_data
.x
->icon_bitmap
= 0;
11699 if (STRINGP (file
))
11700 bitmap_id
= x_create_bitmap_from_file (f
, file
);
11703 /* Create the GNU bitmap if necessary. */
11704 if (FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
< 0)
11705 FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
11706 = x_create_bitmap_from_data (f
, gnu_bits
,
11707 gnu_width
, gnu_height
);
11709 /* The first time we create the GNU bitmap,
11710 this increments the ref-count one extra time.
11711 As a result, the GNU bitmap is never freed.
11712 That way, we don't have to worry about allocating it again. */
11713 x_reference_bitmap (f
, FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
);
11715 bitmap_id
= FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
;
11718 x_wm_set_icon_pixmap (f
, bitmap_id
);
11719 f
->output_data
.x
->icon_bitmap
= bitmap_id
;
11725 /* Make the x-window of frame F use a rectangle with text.
11726 Use ICON_NAME as the text. */
11729 x_text_icon (f
, icon_name
)
11733 if (FRAME_X_WINDOW (f
) == 0)
11738 XTextProperty text
;
11739 text
.value
= (unsigned char *) icon_name
;
11740 text
.encoding
= XA_STRING
;
11742 text
.nitems
= strlen (icon_name
);
11743 #ifdef USE_X_TOOLKIT
11744 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
11746 #else /* not USE_X_TOOLKIT */
11747 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
11748 #endif /* not USE_X_TOOLKIT */
11750 #else /* not HAVE_X11R4 */
11751 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), icon_name
);
11752 #endif /* not HAVE_X11R4 */
11754 if (f
->output_data
.x
->icon_bitmap
> 0)
11755 x_destroy_bitmap (f
, f
->output_data
.x
->icon_bitmap
);
11756 f
->output_data
.x
->icon_bitmap
= 0;
11757 x_wm_set_icon_pixmap (f
, 0);
11762 #define X_ERROR_MESSAGE_SIZE 200
11764 /* If non-nil, this should be a string.
11765 It means catch X errors and store the error message in this string. */
11767 static Lisp_Object x_error_message_string
;
11769 /* An X error handler which stores the error message in
11770 x_error_message_string. This is called from x_error_handler if
11771 x_catch_errors is in effect. */
11774 x_error_catcher (display
, error
)
11776 XErrorEvent
*error
;
11778 XGetErrorText (display
, error
->error_code
,
11779 XSTRING (x_error_message_string
)->data
,
11780 X_ERROR_MESSAGE_SIZE
);
11783 /* Begin trapping X errors for display DPY. Actually we trap X errors
11784 for all displays, but DPY should be the display you are actually
11787 After calling this function, X protocol errors no longer cause
11788 Emacs to exit; instead, they are recorded in the string
11789 stored in x_error_message_string.
11791 Calling x_check_errors signals an Emacs error if an X error has
11792 occurred since the last call to x_catch_errors or x_check_errors.
11794 Calling x_uncatch_errors resumes the normal error handling. */
11796 void x_check_errors ();
11797 static Lisp_Object
x_catch_errors_unwind ();
11800 x_catch_errors (dpy
)
11803 int count
= specpdl_ptr
- specpdl
;
11805 /* Make sure any errors from previous requests have been dealt with. */
11806 XSync (dpy
, False
);
11808 record_unwind_protect (x_catch_errors_unwind
, x_error_message_string
);
11810 x_error_message_string
= make_uninit_string (X_ERROR_MESSAGE_SIZE
);
11811 XSTRING (x_error_message_string
)->data
[0] = 0;
11816 /* Unbind the binding that we made to check for X errors. */
11819 x_catch_errors_unwind (old_val
)
11820 Lisp_Object old_val
;
11822 x_error_message_string
= old_val
;
11826 /* If any X protocol errors have arrived since the last call to
11827 x_catch_errors or x_check_errors, signal an Emacs error using
11828 sprintf (a buffer, FORMAT, the x error message text) as the text. */
11831 x_check_errors (dpy
, format
)
11835 /* Make sure to catch any errors incurred so far. */
11836 XSync (dpy
, False
);
11838 if (XSTRING (x_error_message_string
)->data
[0])
11839 error (format
, XSTRING (x_error_message_string
)->data
);
11842 /* Nonzero if we had any X protocol errors
11843 since we did x_catch_errors on DPY. */
11846 x_had_errors_p (dpy
)
11849 /* Make sure to catch any errors incurred so far. */
11850 XSync (dpy
, False
);
11852 return XSTRING (x_error_message_string
)->data
[0] != 0;
11855 /* Forget about any errors we have had, since we did x_catch_errors on DPY. */
11858 x_clear_errors (dpy
)
11861 XSTRING (x_error_message_string
)->data
[0] = 0;
11864 /* Stop catching X protocol errors and let them make Emacs die.
11865 DPY should be the display that was passed to x_catch_errors.
11866 COUNT should be the value that was returned by
11867 the corresponding call to x_catch_errors. */
11870 x_uncatch_errors (dpy
, count
)
11874 unbind_to (count
, Qnil
);
11878 static unsigned int x_wire_count
;
11881 fprintf (stderr
, "Lib call: %d\n", ++x_wire_count
);
11886 /* Handle SIGPIPE, which can happen when the connection to a server
11887 simply goes away. SIGPIPE is handled by x_connection_signal.
11888 Don't need to do anything, because the write which caused the
11889 SIGPIPE will fail, causing Xlib to invoke the X IO error handler,
11890 which will do the appropriate cleanup for us. */
11893 x_connection_signal (signalnum
) /* If we don't have an argument, */
11894 int signalnum
; /* some compilers complain in signal calls. */
11897 /* USG systems forget handlers when they are used;
11898 must reestablish each time */
11899 signal (signalnum
, x_connection_signal
);
11904 /************************************************************************
11906 ************************************************************************/
11908 /* Error message passed to x_connection_closed. */
11910 static char *error_msg
;
11912 /* Function installed as fatal_error_signal_hook in
11913 x_connection_closed. Print the X error message, and exit normally,
11914 instead of dumping core when XtCloseDisplay fails. */
11917 x_fatal_error_signal ()
11919 fprintf (stderr
, "%s\n", error_msg
);
11923 /* Handle the loss of connection to display DPY. ERROR_MESSAGE is
11924 the text of an error message that lead to the connection loss. */
11927 x_connection_closed (dpy
, error_message
)
11929 char *error_message
;
11931 struct x_display_info
*dpyinfo
= x_display_info_for_display (dpy
);
11932 Lisp_Object frame
, tail
;
11935 error_msg
= (char *) alloca (strlen (error_message
) + 1);
11936 strcpy (error_msg
, error_message
);
11937 handling_signal
= 0;
11939 /* Prevent being called recursively because of an error condition
11940 below. Otherwise, we might end up with printing ``can't find per
11941 display information'' in the recursive call instead of printing
11942 the original message here. */
11943 count
= x_catch_errors (dpy
);
11945 /* We have to close the display to inform Xt that it doesn't
11946 exist anymore. If we don't, Xt will continue to wait for
11947 events from the display. As a consequence, a sequence of
11949 M-x make-frame-on-display RET :1 RET
11950 ...kill the new frame, so that we get an IO error...
11951 M-x make-frame-on-display RET :1 RET
11953 will indefinitely wait in Xt for events for display `:1', opened
11954 in the first class to make-frame-on-display.
11956 Closing the display is reported to lead to a bus error on
11957 OpenWindows in certain situations. I suspect that is a bug
11958 in OpenWindows. I don't know how to cicumvent it here. */
11960 #ifdef USE_X_TOOLKIT
11961 /* If DPYINFO is null, this means we didn't open the display
11962 in the first place, so don't try to close it. */
11965 extern void (*fatal_error_signal_hook
) P_ ((void));
11966 fatal_error_signal_hook
= x_fatal_error_signal
;
11967 XtCloseDisplay (dpy
);
11968 fatal_error_signal_hook
= NULL
;
11972 /* Indicate that this display is dead. */
11974 dpyinfo
->display
= 0;
11976 /* First delete frames whose mini-buffers are on frames
11977 that are on the dead display. */
11978 FOR_EACH_FRAME (tail
, frame
)
11980 Lisp_Object minibuf_frame
;
11982 = WINDOW_FRAME (XWINDOW (FRAME_MINIBUF_WINDOW (XFRAME (frame
))));
11983 if (FRAME_X_P (XFRAME (frame
))
11984 && FRAME_X_P (XFRAME (minibuf_frame
))
11985 && ! EQ (frame
, minibuf_frame
)
11986 && FRAME_X_DISPLAY_INFO (XFRAME (minibuf_frame
)) == dpyinfo
)
11987 Fdelete_frame (frame
, Qt
);
11990 /* Now delete all remaining frames on the dead display.
11991 We are now sure none of these is used as the mini-buffer
11992 for another frame that we need to delete. */
11993 FOR_EACH_FRAME (tail
, frame
)
11994 if (FRAME_X_P (XFRAME (frame
))
11995 && FRAME_X_DISPLAY_INFO (XFRAME (frame
)) == dpyinfo
)
11997 /* Set this to t so that Fdelete_frame won't get confused
11998 trying to find a replacement. */
11999 FRAME_KBOARD (XFRAME (frame
))->Vdefault_minibuffer_frame
= Qt
;
12000 Fdelete_frame (frame
, Qt
);
12004 x_delete_display (dpyinfo
);
12006 x_uncatch_errors (dpy
, count
);
12008 if (x_display_list
== 0)
12010 fprintf (stderr
, "%s\n", error_msg
);
12011 shut_down_emacs (0, 0, Qnil
);
12015 /* Ordinary stack unwind doesn't deal with these. */
12017 sigunblock (sigmask (SIGIO
));
12019 sigunblock (sigmask (SIGALRM
));
12020 TOTALLY_UNBLOCK_INPUT
;
12022 clear_waiting_for_input ();
12023 error ("%s", error_msg
);
12027 /* This is the usual handler for X protocol errors.
12028 It kills all frames on the display that we got the error for.
12029 If that was the only one, it prints an error message and kills Emacs. */
12032 x_error_quitter (display
, error
)
12034 XErrorEvent
*error
;
12036 char buf
[256], buf1
[356];
12038 /* Note that there is no real way portable across R3/R4 to get the
12039 original error handler. */
12041 XGetErrorText (display
, error
->error_code
, buf
, sizeof (buf
));
12042 sprintf (buf1
, "X protocol error: %s on protocol request %d",
12043 buf
, error
->request_code
);
12044 x_connection_closed (display
, buf1
);
12048 /* This is the first-level handler for X protocol errors.
12049 It calls x_error_quitter or x_error_catcher. */
12052 x_error_handler (display
, error
)
12054 XErrorEvent
*error
;
12056 if (! NILP (x_error_message_string
))
12057 x_error_catcher (display
, error
);
12059 x_error_quitter (display
, error
);
12063 /* This is the handler for X IO errors, always.
12064 It kills all frames on the display that we lost touch with.
12065 If that was the only one, it prints an error message and kills Emacs. */
12068 x_io_error_quitter (display
)
12073 sprintf (buf
, "Connection lost to X server `%s'", DisplayString (display
));
12074 x_connection_closed (display
, buf
);
12078 /* Changing the font of the frame. */
12080 /* Give frame F the font named FONTNAME as its default font, and
12081 return the full name of that font. FONTNAME may be a wildcard
12082 pattern; in that case, we choose some font that fits the pattern.
12083 The return value shows which font we chose. */
12086 x_new_font (f
, fontname
)
12088 register char *fontname
;
12090 struct font_info
*fontp
12091 = FS_LOAD_FONT (f
, 0, fontname
, -1);
12096 f
->output_data
.x
->font
= (XFontStruct
*) (fontp
->font
);
12097 f
->output_data
.x
->baseline_offset
= fontp
->baseline_offset
;
12098 f
->output_data
.x
->fontset
= -1;
12100 /* Compute the scroll bar width in character columns. */
12101 if (f
->scroll_bar_pixel_width
> 0)
12103 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
12104 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
12108 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
12109 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
12112 /* Now make the frame display the given font. */
12113 if (FRAME_X_WINDOW (f
) != 0)
12115 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->normal_gc
,
12116 f
->output_data
.x
->font
->fid
);
12117 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->reverse_gc
,
12118 f
->output_data
.x
->font
->fid
);
12119 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
12120 f
->output_data
.x
->font
->fid
);
12122 frame_update_line_height (f
);
12124 /* Don't change the size of a tip frame; there's no point in
12125 doing it because it's done in Fx_show_tip, and it leads to
12126 problems because the tip frame has no widget. */
12127 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
12128 x_set_window_size (f
, 0, f
->width
, f
->height
);
12131 /* If we are setting a new frame's font for the first time,
12132 there are no faces yet, so this font's height is the line height. */
12133 f
->output_data
.x
->line_height
= FONT_HEIGHT (f
->output_data
.x
->font
);
12135 return build_string (fontp
->full_name
);
12138 /* Give frame F the fontset named FONTSETNAME as its default font, and
12139 return the full name of that fontset. FONTSETNAME may be a wildcard
12140 pattern; in that case, we choose some fontset that fits the pattern.
12141 The return value shows which fontset we chose. */
12144 x_new_fontset (f
, fontsetname
)
12148 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
12149 Lisp_Object result
;
12154 if (f
->output_data
.x
->fontset
== fontset
)
12155 /* This fontset is already set in frame F. There's nothing more
12157 return fontset_name (fontset
);
12159 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
12161 if (!STRINGP (result
))
12162 /* Can't load ASCII font. */
12165 /* Since x_new_font doesn't update any fontset information, do it now. */
12166 f
->output_data
.x
->fontset
= fontset
;
12170 && (FRAME_XIC_STYLE (f
) & (XIMPreeditPosition
| XIMStatusArea
)))
12171 xic_set_xfontset (f
, XSTRING (fontset_ascii (fontset
))->data
);
12174 return build_string (fontsetname
);
12178 /***********************************************************************
12180 ***********************************************************************/
12186 /* XIM destroy callback function, which is called whenever the
12187 connection to input method XIM dies. CLIENT_DATA contains a
12188 pointer to the x_display_info structure corresponding to XIM. */
12191 xim_destroy_callback (xim
, client_data
, call_data
)
12193 XPointer client_data
;
12194 XPointer call_data
;
12196 struct x_display_info
*dpyinfo
= (struct x_display_info
*) client_data
;
12197 Lisp_Object frame
, tail
;
12201 /* No need to call XDestroyIC.. */
12202 FOR_EACH_FRAME (tail
, frame
)
12204 struct frame
*f
= XFRAME (frame
);
12205 if (FRAME_X_DISPLAY_INFO (f
) == dpyinfo
)
12207 FRAME_XIC (f
) = NULL
;
12208 if (FRAME_XIC_FONTSET (f
))
12210 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
12211 FRAME_XIC_FONTSET (f
) = NULL
;
12216 /* No need to call XCloseIM. */
12217 dpyinfo
->xim
= NULL
;
12218 XFree (dpyinfo
->xim_styles
);
12222 #endif /* HAVE_X11R6 */
12224 /* Open the connection to the XIM server on display DPYINFO.
12225 RESOURCE_NAME is the resource name Emacs uses. */
12228 xim_open_dpy (dpyinfo
, resource_name
)
12229 struct x_display_info
*dpyinfo
;
12230 char *resource_name
;
12235 xim
= XOpenIM (dpyinfo
->display
, dpyinfo
->xrdb
, resource_name
, EMACS_CLASS
);
12236 dpyinfo
->xim
= xim
;
12241 XIMCallback destroy
;
12244 /* Get supported styles and XIM values. */
12245 XGetIMValues (xim
, XNQueryInputStyle
, &dpyinfo
->xim_styles
, NULL
);
12248 destroy
.callback
= xim_destroy_callback
;
12249 destroy
.client_data
= (XPointer
)dpyinfo
;
12250 /* This isn't prototyped in OSF 5.0. */
12251 XSetIMValues (xim
, XNDestroyCallback
, &destroy
, NULL
);
12255 #else /* not USE_XIM */
12256 dpyinfo
->xim
= NULL
;
12257 #endif /* not USE_XIM */
12261 #ifdef HAVE_X11R6_XIM
12265 struct x_display_info
*dpyinfo
;
12266 char *resource_name
;
12269 /* XIM instantiate callback function, which is called whenever an XIM
12270 server is available. DISPLAY is teh display of the XIM.
12271 CLIENT_DATA contains a pointer to an xim_inst_t structure created
12272 when the callback was registered. */
12275 xim_instantiate_callback (display
, client_data
, call_data
)
12277 XPointer client_data
;
12278 XPointer call_data
;
12280 struct xim_inst_t
*xim_inst
= (struct xim_inst_t
*) client_data
;
12281 struct x_display_info
*dpyinfo
= xim_inst
->dpyinfo
;
12283 /* We don't support multiple XIM connections. */
12287 xim_open_dpy (dpyinfo
, xim_inst
->resource_name
);
12289 /* Create XIC for the existing frames on the same display, as long
12290 as they have no XIC. */
12291 if (dpyinfo
->xim
&& dpyinfo
->reference_count
> 0)
12293 Lisp_Object tail
, frame
;
12296 FOR_EACH_FRAME (tail
, frame
)
12298 struct frame
*f
= XFRAME (frame
);
12300 if (FRAME_X_DISPLAY_INFO (f
) == xim_inst
->dpyinfo
)
12301 if (FRAME_XIC (f
) == NULL
)
12303 create_frame_xic (f
);
12304 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
12305 xic_set_statusarea (f
);
12306 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
12308 struct window
*w
= XWINDOW (f
->selected_window
);
12309 xic_set_preeditarea (w
, w
->cursor
.x
, w
->cursor
.y
);
12318 #endif /* HAVE_X11R6_XIM */
12321 /* Open a connection to the XIM server on display DPYINFO.
12322 RESOURCE_NAME is the resource name for Emacs. On X11R5, open the
12323 connection only at the first time. On X11R6, open the connection
12324 in the XIM instantiate callback function. */
12327 xim_initialize (dpyinfo
, resource_name
)
12328 struct x_display_info
*dpyinfo
;
12329 char *resource_name
;
12332 #ifdef HAVE_X11R6_XIM
12333 struct xim_inst_t
*xim_inst
;
12336 dpyinfo
->xim
= NULL
;
12337 xim_inst
= (struct xim_inst_t
*) xmalloc (sizeof (struct xim_inst_t
));
12338 xim_inst
->dpyinfo
= dpyinfo
;
12339 len
= strlen (resource_name
);
12340 xim_inst
->resource_name
= (char *) xmalloc (len
+ 1);
12341 bcopy (resource_name
, xim_inst
->resource_name
, len
+ 1);
12342 XRegisterIMInstantiateCallback (dpyinfo
->display
, dpyinfo
->xrdb
,
12343 resource_name
, EMACS_CLASS
,
12344 xim_instantiate_callback
,
12345 /* Fixme: This is XPointer in
12346 XFree86 but (XPointer *) on
12347 Tru64, at least. */
12348 (XPointer
) xim_inst
);
12349 #else /* not HAVE_X11R6_XIM */
12350 dpyinfo
->xim
= NULL
;
12351 xim_open_dpy (dpyinfo
, resource_name
);
12352 #endif /* not HAVE_X11R6_XIM */
12354 #else /* not USE_XIM */
12355 dpyinfo
->xim
= NULL
;
12356 #endif /* not USE_XIM */
12360 /* Close the connection to the XIM server on display DPYINFO. */
12363 xim_close_dpy (dpyinfo
)
12364 struct x_display_info
*dpyinfo
;
12367 #ifdef HAVE_X11R6_XIM
12368 if (dpyinfo
->display
)
12369 XUnregisterIMInstantiateCallback (dpyinfo
->display
, dpyinfo
->xrdb
,
12371 xim_instantiate_callback
, NULL
);
12372 #endif /* not HAVE_X11R6_XIM */
12373 if (dpyinfo
->display
)
12374 XCloseIM (dpyinfo
->xim
);
12375 dpyinfo
->xim
= NULL
;
12376 XFree (dpyinfo
->xim_styles
);
12377 #endif /* USE_XIM */
12380 #endif /* not HAVE_X11R6_XIM */
12384 /* Calculate the absolute position in frame F
12385 from its current recorded position values and gravity. */
12388 x_calc_absolute_position (f
)
12392 int win_x
= 0, win_y
= 0;
12393 int flags
= f
->output_data
.x
->size_hint_flags
;
12396 /* We have nothing to do if the current position
12397 is already for the top-left corner. */
12398 if (! ((flags
& XNegative
) || (flags
& YNegative
)))
12401 #ifdef USE_X_TOOLKIT
12402 this_window
= XtWindow (f
->output_data
.x
->widget
);
12404 this_window
= FRAME_X_WINDOW (f
);
12407 /* Find the position of the outside upper-left corner of
12408 the inner window, with respect to the outer window.
12409 But do this only if we will need the results. */
12410 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
12415 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
12418 x_clear_errors (FRAME_X_DISPLAY (f
));
12419 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
12421 /* From-window, to-window. */
12423 f
->output_data
.x
->parent_desc
,
12425 /* From-position, to-position. */
12426 0, 0, &win_x
, &win_y
,
12428 /* Child of win. */
12430 if (x_had_errors_p (FRAME_X_DISPLAY (f
)))
12432 Window newroot
, newparent
= 0xdeadbeef;
12433 Window
*newchildren
;
12434 unsigned int nchildren
;
12436 if (! XQueryTree (FRAME_X_DISPLAY (f
), this_window
, &newroot
,
12437 &newparent
, &newchildren
, &nchildren
))
12440 XFree ((char *) newchildren
);
12442 f
->output_data
.x
->parent_desc
= newparent
;
12448 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
12452 /* Treat negative positions as relative to the leftmost bottommost
12453 position that fits on the screen. */
12454 if (flags
& XNegative
)
12455 f
->output_data
.x
->left_pos
= (FRAME_X_DISPLAY_INFO (f
)->width
12456 - 2 * f
->output_data
.x
->border_width
- win_x
12458 + f
->output_data
.x
->left_pos
);
12461 int height
= PIXEL_HEIGHT (f
);
12463 #if defined USE_X_TOOLKIT && defined USE_MOTIF
12464 /* Something is fishy here. When using Motif, starting Emacs with
12465 `-g -0-0', the frame appears too low by a few pixels.
12467 This seems to be so because initially, while Emacs is starting,
12468 the column widget's height and the frame's pixel height are
12469 different. The column widget's height is the right one. In
12470 later invocations, when Emacs is up, the frame's pixel height
12473 It's not obvious where the initial small difference comes from.
12474 2000-12-01, gerd. */
12476 XtVaGetValues (f
->output_data
.x
->column_widget
, XtNheight
, &height
, NULL
);
12479 if (flags
& YNegative
)
12480 f
->output_data
.x
->top_pos
= (FRAME_X_DISPLAY_INFO (f
)->height
12481 - 2 * f
->output_data
.x
->border_width
12484 + f
->output_data
.x
->top_pos
);
12487 /* The left_pos and top_pos
12488 are now relative to the top and left screen edges,
12489 so the flags should correspond. */
12490 f
->output_data
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
12493 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
12494 to really change the position, and 0 when calling from
12495 x_make_frame_visible (in that case, XOFF and YOFF are the current
12496 position values). It is -1 when calling from x_set_frame_parameters,
12497 which means, do adjust for borders but don't change the gravity. */
12500 x_set_offset (f
, xoff
, yoff
, change_gravity
)
12502 register int xoff
, yoff
;
12503 int change_gravity
;
12505 int modified_top
, modified_left
;
12507 if (change_gravity
> 0)
12509 f
->output_data
.x
->top_pos
= yoff
;
12510 f
->output_data
.x
->left_pos
= xoff
;
12511 f
->output_data
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
12513 f
->output_data
.x
->size_hint_flags
|= XNegative
;
12515 f
->output_data
.x
->size_hint_flags
|= YNegative
;
12516 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
12518 x_calc_absolute_position (f
);
12521 x_wm_set_size_hint (f
, (long) 0, 0);
12523 modified_left
= f
->output_data
.x
->left_pos
;
12524 modified_top
= f
->output_data
.x
->top_pos
;
12525 #if 0 /* Running on psilocin (Debian), and displaying on the NCD X-terminal,
12526 this seems to be unnecessary and incorrect. rms, 4/17/97. */
12527 /* It is a mystery why we need to add the border_width here
12528 when the frame is already visible, but experiment says we do. */
12529 if (change_gravity
!= 0)
12531 modified_left
+= f
->output_data
.x
->border_width
;
12532 modified_top
+= f
->output_data
.x
->border_width
;
12536 #ifdef USE_X_TOOLKIT
12537 XMoveWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
12538 modified_left
, modified_top
);
12539 #else /* not USE_X_TOOLKIT */
12540 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
12541 modified_left
, modified_top
);
12542 #endif /* not USE_X_TOOLKIT */
12547 /* Change the size of frame F's X window to COLS/ROWS in the case F
12548 doesn't have a widget. If CHANGE_GRAVITY is 1, we change to
12549 top-left-corner window gravity for this size change and subsequent
12550 size changes. Otherwise we leave the window gravity unchanged. */
12553 x_set_window_size_1 (f
, change_gravity
, cols
, rows
)
12555 int change_gravity
;
12558 int pixelwidth
, pixelheight
;
12560 check_frame_size (f
, &rows
, &cols
);
12561 f
->output_data
.x
->vertical_scroll_bar_extra
12562 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
12564 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
12565 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
12566 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.x
->font
)));
12567 f
->output_data
.x
->fringes_extra
12568 = FRAME_FRINGE_WIDTH (f
);
12569 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
12570 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
12572 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
12573 x_wm_set_size_hint (f
, (long) 0, 0);
12575 XSync (FRAME_X_DISPLAY (f
), False
);
12576 XResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
12577 pixelwidth
, pixelheight
);
12579 /* Now, strictly speaking, we can't be sure that this is accurate,
12580 but the window manager will get around to dealing with the size
12581 change request eventually, and we'll hear how it went when the
12582 ConfigureNotify event gets here.
12584 We could just not bother storing any of this information here,
12585 and let the ConfigureNotify event set everything up, but that
12586 might be kind of confusing to the Lisp code, since size changes
12587 wouldn't be reported in the frame parameters until some random
12588 point in the future when the ConfigureNotify event arrives.
12590 We pass 1 for DELAY since we can't run Lisp code inside of
12592 change_frame_size (f
, rows
, cols
, 0, 1, 0);
12593 PIXEL_WIDTH (f
) = pixelwidth
;
12594 PIXEL_HEIGHT (f
) = pixelheight
;
12596 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
12597 receive in the ConfigureNotify event; if we get what we asked
12598 for, then the event won't cause the screen to become garbaged, so
12599 we have to make sure to do it here. */
12600 SET_FRAME_GARBAGED (f
);
12602 XFlush (FRAME_X_DISPLAY (f
));
12606 /* Call this to change the size of frame F's x-window.
12607 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
12608 for this size change and subsequent size changes.
12609 Otherwise we leave the window gravity unchanged. */
12612 x_set_window_size (f
, change_gravity
, cols
, rows
)
12614 int change_gravity
;
12619 #ifdef USE_X_TOOLKIT
12621 if (f
->output_data
.x
->widget
!= NULL
)
12623 /* The x and y position of the widget is clobbered by the
12624 call to XtSetValues within EmacsFrameSetCharSize.
12625 This is a real kludge, but I don't understand Xt so I can't
12626 figure out a correct fix. Can anyone else tell me? -- rms. */
12627 int xpos
= f
->output_data
.x
->widget
->core
.x
;
12628 int ypos
= f
->output_data
.x
->widget
->core
.y
;
12629 EmacsFrameSetCharSize (f
->output_data
.x
->edit_widget
, cols
, rows
);
12630 f
->output_data
.x
->widget
->core
.x
= xpos
;
12631 f
->output_data
.x
->widget
->core
.y
= ypos
;
12634 x_set_window_size_1 (f
, change_gravity
, cols
, rows
);
12636 #else /* not USE_X_TOOLKIT */
12638 x_set_window_size_1 (f
, change_gravity
, cols
, rows
);
12640 #endif /* not USE_X_TOOLKIT */
12642 /* If cursor was outside the new size, mark it as off. */
12643 mark_window_cursors_off (XWINDOW (f
->root_window
));
12645 /* Clear out any recollection of where the mouse highlighting was,
12646 since it might be in a place that's outside the new frame size.
12647 Actually checking whether it is outside is a pain in the neck,
12648 so don't try--just let the highlighting be done afresh with new size. */
12649 cancel_mouse_face (f
);
12654 /* Mouse warping. */
12657 x_set_mouse_position (f
, x
, y
)
12663 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.x
->font
) / 2;
12664 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.x
->line_height
/ 2;
12666 if (pix_x
< 0) pix_x
= 0;
12667 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
12669 if (pix_y
< 0) pix_y
= 0;
12670 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
12674 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
12675 0, 0, 0, 0, pix_x
, pix_y
);
12679 /* Move the mouse to position pixel PIX_X, PIX_Y relative to frame F. */
12682 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
12688 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
12689 0, 0, 0, 0, pix_x
, pix_y
);
12693 /* focus shifting, raising and lowering. */
12696 x_focus_on_frame (f
)
12699 #if 0 /* This proves to be unpleasant. */
12703 /* I don't think that the ICCCM allows programs to do things like this
12704 without the interaction of the window manager. Whatever you end up
12705 doing with this code, do it to x_unfocus_frame too. */
12706 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
12707 RevertToPointerRoot
, CurrentTime
);
12712 x_unfocus_frame (f
)
12716 /* Look at the remarks in x_focus_on_frame. */
12717 if (FRAME_X_DISPLAY_INFO (f
)->x_focus_frame
== f
)
12718 XSetInputFocus (FRAME_X_DISPLAY (f
), PointerRoot
,
12719 RevertToPointerRoot
, CurrentTime
);
12723 /* Raise frame F. */
12729 if (f
->async_visible
)
12732 #ifdef USE_X_TOOLKIT
12733 XRaiseWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
));
12734 #else /* not USE_X_TOOLKIT */
12735 XRaiseWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12736 #endif /* not USE_X_TOOLKIT */
12737 XFlush (FRAME_X_DISPLAY (f
));
12742 /* Lower frame F. */
12748 if (f
->async_visible
)
12751 #ifdef USE_X_TOOLKIT
12752 XLowerWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
));
12753 #else /* not USE_X_TOOLKIT */
12754 XLowerWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12755 #endif /* not USE_X_TOOLKIT */
12756 XFlush (FRAME_X_DISPLAY (f
));
12762 XTframe_raise_lower (f
, raise_flag
)
12772 /* Change of visibility. */
12774 /* This tries to wait until the frame is really visible.
12775 However, if the window manager asks the user where to position
12776 the frame, this will return before the user finishes doing that.
12777 The frame will not actually be visible at that time,
12778 but it will become visible later when the window manager
12779 finishes with it. */
12782 x_make_frame_visible (f
)
12786 int original_top
, original_left
;
12787 int retry_count
= 2;
12793 type
= x_icon_type (f
);
12795 x_bitmap_icon (f
, type
);
12797 if (! FRAME_VISIBLE_P (f
))
12799 /* We test FRAME_GARBAGED_P here to make sure we don't
12800 call x_set_offset a second time
12801 if we get to x_make_frame_visible a second time
12802 before the window gets really visible. */
12803 if (! FRAME_ICONIFIED_P (f
)
12804 && ! f
->output_data
.x
->asked_for_visible
)
12805 x_set_offset (f
, f
->output_data
.x
->left_pos
, f
->output_data
.x
->top_pos
, 0);
12807 f
->output_data
.x
->asked_for_visible
= 1;
12809 if (! EQ (Vx_no_window_manager
, Qt
))
12810 x_wm_set_window_state (f
, NormalState
);
12811 #ifdef USE_X_TOOLKIT
12812 /* This was XtPopup, but that did nothing for an iconified frame. */
12813 XtMapWidget (f
->output_data
.x
->widget
);
12814 #else /* not USE_X_TOOLKIT */
12815 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12816 #endif /* not USE_X_TOOLKIT */
12817 #if 0 /* This seems to bring back scroll bars in the wrong places
12818 if the window configuration has changed. They seem
12819 to come back ok without this. */
12820 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
12821 XMapSubwindows (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12825 XFlush (FRAME_X_DISPLAY (f
));
12827 /* Synchronize to ensure Emacs knows the frame is visible
12828 before we do anything else. We do this loop with input not blocked
12829 so that incoming events are handled. */
12833 /* This must be before UNBLOCK_INPUT
12834 since events that arrive in response to the actions above
12835 will set it when they are handled. */
12836 int previously_visible
= f
->output_data
.x
->has_been_visible
;
12838 original_left
= f
->output_data
.x
->left_pos
;
12839 original_top
= f
->output_data
.x
->top_pos
;
12841 /* This must come after we set COUNT. */
12844 /* We unblock here so that arriving X events are processed. */
12846 /* Now move the window back to where it was "supposed to be".
12847 But don't do it if the gravity is negative.
12848 When the gravity is negative, this uses a position
12849 that is 3 pixels too low. Perhaps that's really the border width.
12851 Don't do this if the window has never been visible before,
12852 because the window manager may choose the position
12853 and we don't want to override it. */
12855 if (! FRAME_VISIBLE_P (f
) && ! FRAME_ICONIFIED_P (f
)
12856 && f
->output_data
.x
->win_gravity
== NorthWestGravity
12857 && previously_visible
)
12861 unsigned int width
, height
, border
, depth
;
12865 /* On some window managers (such as FVWM) moving an existing
12866 window, even to the same place, causes the window manager
12867 to introduce an offset. This can cause the window to move
12868 to an unexpected location. Check the geometry (a little
12869 slow here) and then verify that the window is in the right
12870 place. If the window is not in the right place, move it
12871 there, and take the potential window manager hit. */
12872 XGetGeometry (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
12873 &rootw
, &x
, &y
, &width
, &height
, &border
, &depth
);
12875 if (original_left
!= x
|| original_top
!= y
)
12876 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
12877 original_left
, original_top
);
12882 XSETFRAME (frame
, f
);
12884 /* Wait until the frame is visible. Process X events until a
12885 MapNotify event has been seen, or until we think we won't get a
12886 MapNotify at all.. */
12887 for (count
= input_signal_count
+ 10;
12888 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
12890 /* Force processing of queued events. */
12893 /* Machines that do polling rather than SIGIO have been
12894 observed to go into a busy-wait here. So we'll fake an
12895 alarm signal to let the handler know that there's something
12896 to be read. We used to raise a real alarm, but it seems
12897 that the handler isn't always enabled here. This is
12899 if (input_polling_used ())
12901 /* It could be confusing if a real alarm arrives while
12902 processing the fake one. Turn it off and let the
12903 handler reset it. */
12904 extern void poll_for_input_1
P_ ((void));
12905 int old_poll_suppress_count
= poll_suppress_count
;
12906 poll_suppress_count
= 1;
12907 poll_for_input_1 ();
12908 poll_suppress_count
= old_poll_suppress_count
;
12911 /* See if a MapNotify event has been processed. */
12912 FRAME_SAMPLE_VISIBILITY (f
);
12917 (let ((f (selected-frame)))
12921 the frame is not raised with various window managers on
12922 FreeBSD, Linux and Solaris. It turns out that, for some
12923 unknown reason, the call to XtMapWidget is completely ignored.
12924 Mapping the widget a second time works. */
12926 if (!FRAME_VISIBLE_P (f
) && --retry_count
> 0)
12931 /* Change from mapped state to withdrawn state. */
12933 /* Make the frame visible (mapped and not iconified). */
12936 x_make_frame_invisible (f
)
12941 #ifdef USE_X_TOOLKIT
12942 /* Use the frame's outermost window, not the one we normally draw on. */
12943 window
= XtWindow (f
->output_data
.x
->widget
);
12944 #else /* not USE_X_TOOLKIT */
12945 window
= FRAME_X_WINDOW (f
);
12946 #endif /* not USE_X_TOOLKIT */
12948 /* Don't keep the highlight on an invisible frame. */
12949 if (FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
12950 FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
12952 #if 0/* This might add unreliability; I don't trust it -- rms. */
12953 if (! f
->async_visible
&& ! f
->async_iconified
)
12959 /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
12960 that the current position of the window is user-specified, rather than
12961 program-specified, so that when the window is mapped again, it will be
12962 placed at the same location, without forcing the user to position it
12963 by hand again (they have already done that once for this window.) */
12964 x_wm_set_size_hint (f
, (long) 0, 1);
12968 if (! XWithdrawWindow (FRAME_X_DISPLAY (f
), window
,
12969 DefaultScreen (FRAME_X_DISPLAY (f
))))
12971 UNBLOCK_INPUT_RESIGNAL
;
12972 error ("Can't notify window manager of window withdrawal");
12974 #else /* ! defined (HAVE_X11R4) */
12976 /* Tell the window manager what we're going to do. */
12977 if (! EQ (Vx_no_window_manager
, Qt
))
12981 unmap
.xunmap
.type
= UnmapNotify
;
12982 unmap
.xunmap
.window
= window
;
12983 unmap
.xunmap
.event
= DefaultRootWindow (FRAME_X_DISPLAY (f
));
12984 unmap
.xunmap
.from_configure
= False
;
12985 if (! XSendEvent (FRAME_X_DISPLAY (f
),
12986 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
12988 SubstructureRedirectMaskSubstructureNotifyMask
,
12991 UNBLOCK_INPUT_RESIGNAL
;
12992 error ("Can't notify window manager of withdrawal");
12996 /* Unmap the window ourselves. Cheeky! */
12997 XUnmapWindow (FRAME_X_DISPLAY (f
), window
);
12998 #endif /* ! defined (HAVE_X11R4) */
13000 /* We can't distinguish this from iconification
13001 just by the event that we get from the server.
13002 So we can't win using the usual strategy of letting
13003 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
13004 and synchronize with the server to make sure we agree. */
13006 FRAME_ICONIFIED_P (f
) = 0;
13007 f
->async_visible
= 0;
13008 f
->async_iconified
= 0;
13015 /* Change window state from mapped to iconified. */
13018 x_iconify_frame (f
)
13024 /* Don't keep the highlight on an invisible frame. */
13025 if (FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
13026 FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
13028 if (f
->async_iconified
)
13033 FRAME_SAMPLE_VISIBILITY (f
);
13035 type
= x_icon_type (f
);
13037 x_bitmap_icon (f
, type
);
13039 #ifdef USE_X_TOOLKIT
13041 if (! FRAME_VISIBLE_P (f
))
13043 if (! EQ (Vx_no_window_manager
, Qt
))
13044 x_wm_set_window_state (f
, IconicState
);
13045 /* This was XtPopup, but that did nothing for an iconified frame. */
13046 XtMapWidget (f
->output_data
.x
->widget
);
13047 /* The server won't give us any event to indicate
13048 that an invisible frame was changed to an icon,
13049 so we have to record it here. */
13052 f
->async_iconified
= 1;
13053 f
->async_visible
= 0;
13058 result
= XIconifyWindow (FRAME_X_DISPLAY (f
),
13059 XtWindow (f
->output_data
.x
->widget
),
13060 DefaultScreen (FRAME_X_DISPLAY (f
)));
13064 error ("Can't notify window manager of iconification");
13066 f
->async_iconified
= 1;
13067 f
->async_visible
= 0;
13071 XFlush (FRAME_X_DISPLAY (f
));
13073 #else /* not USE_X_TOOLKIT */
13075 /* Make sure the X server knows where the window should be positioned,
13076 in case the user deiconifies with the window manager. */
13077 if (! FRAME_VISIBLE_P (f
) && !FRAME_ICONIFIED_P (f
))
13078 x_set_offset (f
, f
->output_data
.x
->left_pos
, f
->output_data
.x
->top_pos
, 0);
13080 /* Since we don't know which revision of X we're running, we'll use both
13081 the X11R3 and X11R4 techniques. I don't know if this is a good idea. */
13083 /* X11R4: send a ClientMessage to the window manager using the
13084 WM_CHANGE_STATE type. */
13088 message
.xclient
.window
= FRAME_X_WINDOW (f
);
13089 message
.xclient
.type
= ClientMessage
;
13090 message
.xclient
.message_type
= FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_change_state
;
13091 message
.xclient
.format
= 32;
13092 message
.xclient
.data
.l
[0] = IconicState
;
13094 if (! XSendEvent (FRAME_X_DISPLAY (f
),
13095 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
13097 SubstructureRedirectMask
| SubstructureNotifyMask
,
13100 UNBLOCK_INPUT_RESIGNAL
;
13101 error ("Can't notify window manager of iconification");
13105 /* X11R3: set the initial_state field of the window manager hints to
13107 x_wm_set_window_state (f
, IconicState
);
13109 if (!FRAME_VISIBLE_P (f
))
13111 /* If the frame was withdrawn, before, we must map it. */
13112 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
13115 f
->async_iconified
= 1;
13116 f
->async_visible
= 0;
13118 XFlush (FRAME_X_DISPLAY (f
));
13120 #endif /* not USE_X_TOOLKIT */
13124 /* Free X resources of frame F. */
13127 x_free_frame_resources (f
)
13130 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13134 /* If a display connection is dead, don't try sending more
13135 commands to the X server. */
13136 if (dpyinfo
->display
)
13138 if (f
->output_data
.x
->icon_desc
)
13139 XDestroyWindow (FRAME_X_DISPLAY (f
), f
->output_data
.x
->icon_desc
);
13143 free_frame_xic (f
);
13146 if (FRAME_X_WINDOW (f
))
13147 XDestroyWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
13149 #ifdef USE_X_TOOLKIT
13150 if (f
->output_data
.x
->widget
)
13152 XtDestroyWidget (f
->output_data
.x
->widget
);
13153 f
->output_data
.x
->widget
= NULL
;
13155 free_frame_menubar (f
);
13156 #endif /* USE_X_TOOLKIT */
13158 unload_color (f
, f
->output_data
.x
->foreground_pixel
);
13159 unload_color (f
, f
->output_data
.x
->background_pixel
);
13160 unload_color (f
, f
->output_data
.x
->cursor_pixel
);
13161 unload_color (f
, f
->output_data
.x
->cursor_foreground_pixel
);
13162 unload_color (f
, f
->output_data
.x
->border_pixel
);
13163 unload_color (f
, f
->output_data
.x
->mouse_pixel
);
13165 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
13166 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
13167 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
13168 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
13169 #ifdef USE_TOOLKIT_SCROLL_BARS
13170 /* Scrollbar shadow colors. */
13171 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
!= -1)
13172 unload_color (f
, f
->output_data
.x
->scroll_bar_top_shadow_pixel
);
13173 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
!= -1)
13174 unload_color (f
, f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
);
13175 #endif /* USE_TOOLKIT_SCROLL_BARS */
13176 if (f
->output_data
.x
->white_relief
.allocated_p
)
13177 unload_color (f
, f
->output_data
.x
->white_relief
.pixel
);
13178 if (f
->output_data
.x
->black_relief
.allocated_p
)
13179 unload_color (f
, f
->output_data
.x
->black_relief
.pixel
);
13181 if (FRAME_FACE_CACHE (f
))
13182 free_frame_faces (f
);
13185 XFlush (FRAME_X_DISPLAY (f
));
13188 if (f
->output_data
.x
->saved_menu_event
)
13189 xfree (f
->output_data
.x
->saved_menu_event
);
13191 xfree (f
->output_data
.x
);
13192 f
->output_data
.x
= NULL
;
13194 if (f
== dpyinfo
->x_focus_frame
)
13195 dpyinfo
->x_focus_frame
= 0;
13196 if (f
== dpyinfo
->x_focus_event_frame
)
13197 dpyinfo
->x_focus_event_frame
= 0;
13198 if (f
== dpyinfo
->x_highlight_frame
)
13199 dpyinfo
->x_highlight_frame
= 0;
13201 if (f
== dpyinfo
->mouse_face_mouse_frame
)
13203 dpyinfo
->mouse_face_beg_row
13204 = dpyinfo
->mouse_face_beg_col
= -1;
13205 dpyinfo
->mouse_face_end_row
13206 = dpyinfo
->mouse_face_end_col
= -1;
13207 dpyinfo
->mouse_face_window
= Qnil
;
13208 dpyinfo
->mouse_face_deferred_gc
= 0;
13209 dpyinfo
->mouse_face_mouse_frame
= 0;
13216 /* Destroy the X window of frame F. */
13219 x_destroy_window (f
)
13222 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13224 /* If a display connection is dead, don't try sending more
13225 commands to the X server. */
13226 if (dpyinfo
->display
!= 0)
13227 x_free_frame_resources (f
);
13229 dpyinfo
->reference_count
--;
13233 /* Setting window manager hints. */
13235 /* Set the normal size hints for the window manager, for frame F.
13236 FLAGS is the flags word to use--or 0 meaning preserve the flags
13237 that the window now has.
13238 If USER_POSITION is nonzero, we set the USPosition
13239 flag (this is useful when FLAGS is 0). */
13242 x_wm_set_size_hint (f
, flags
, user_position
)
13247 XSizeHints size_hints
;
13249 #ifdef USE_X_TOOLKIT
13252 Dimension widget_width
, widget_height
;
13253 Window window
= XtWindow (f
->output_data
.x
->widget
);
13254 #else /* not USE_X_TOOLKIT */
13255 Window window
= FRAME_X_WINDOW (f
);
13256 #endif /* not USE_X_TOOLKIT */
13258 /* Setting PMaxSize caused various problems. */
13259 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
13261 size_hints
.x
= f
->output_data
.x
->left_pos
;
13262 size_hints
.y
= f
->output_data
.x
->top_pos
;
13264 #ifdef USE_X_TOOLKIT
13265 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
13266 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
13267 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
13268 size_hints
.height
= widget_height
;
13269 size_hints
.width
= widget_width
;
13270 #else /* not USE_X_TOOLKIT */
13271 size_hints
.height
= PIXEL_HEIGHT (f
);
13272 size_hints
.width
= PIXEL_WIDTH (f
);
13273 #endif /* not USE_X_TOOLKIT */
13275 size_hints
.width_inc
= FONT_WIDTH (f
->output_data
.x
->font
);
13276 size_hints
.height_inc
= f
->output_data
.x
->line_height
;
13277 size_hints
.max_width
13278 = FRAME_X_DISPLAY_INFO (f
)->width
- CHAR_TO_PIXEL_WIDTH (f
, 0);
13279 size_hints
.max_height
13280 = FRAME_X_DISPLAY_INFO (f
)->height
- CHAR_TO_PIXEL_HEIGHT (f
, 0);
13282 /* Calculate the base and minimum sizes.
13284 (When we use the X toolkit, we don't do it here.
13285 Instead we copy the values that the widgets are using, below.) */
13286 #ifndef USE_X_TOOLKIT
13288 int base_width
, base_height
;
13289 int min_rows
= 0, min_cols
= 0;
13291 base_width
= CHAR_TO_PIXEL_WIDTH (f
, 0);
13292 base_height
= CHAR_TO_PIXEL_HEIGHT (f
, 0);
13294 check_frame_size (f
, &min_rows
, &min_cols
);
13296 /* The window manager uses the base width hints to calculate the
13297 current number of rows and columns in the frame while
13298 resizing; min_width and min_height aren't useful for this
13299 purpose, since they might not give the dimensions for a
13300 zero-row, zero-column frame.
13302 We use the base_width and base_height members if we have
13303 them; otherwise, we set the min_width and min_height members
13304 to the size for a zero x zero frame. */
13307 size_hints
.flags
|= PBaseSize
;
13308 size_hints
.base_width
= base_width
;
13309 size_hints
.base_height
= base_height
;
13310 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
13311 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
13313 size_hints
.min_width
= base_width
;
13314 size_hints
.min_height
= base_height
;
13318 /* If we don't need the old flags, we don't need the old hint at all. */
13321 size_hints
.flags
|= flags
;
13324 #endif /* not USE_X_TOOLKIT */
13327 XSizeHints hints
; /* Sometimes I hate X Windows... */
13328 long supplied_return
;
13332 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
13335 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
13338 #ifdef USE_X_TOOLKIT
13339 size_hints
.base_height
= hints
.base_height
;
13340 size_hints
.base_width
= hints
.base_width
;
13341 size_hints
.min_height
= hints
.min_height
;
13342 size_hints
.min_width
= hints
.min_width
;
13346 size_hints
.flags
|= flags
;
13351 if (hints
.flags
& PSize
)
13352 size_hints
.flags
|= PSize
;
13353 if (hints
.flags
& PPosition
)
13354 size_hints
.flags
|= PPosition
;
13355 if (hints
.flags
& USPosition
)
13356 size_hints
.flags
|= USPosition
;
13357 if (hints
.flags
& USSize
)
13358 size_hints
.flags
|= USSize
;
13362 #ifndef USE_X_TOOLKIT
13367 size_hints
.win_gravity
= f
->output_data
.x
->win_gravity
;
13368 size_hints
.flags
|= PWinGravity
;
13372 size_hints
.flags
&= ~ PPosition
;
13373 size_hints
.flags
|= USPosition
;
13375 #endif /* PWinGravity */
13378 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
13380 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
13384 /* Used for IconicState or NormalState */
13387 x_wm_set_window_state (f
, state
)
13391 #ifdef USE_X_TOOLKIT
13394 XtSetArg (al
[0], XtNinitialState
, state
);
13395 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
13396 #else /* not USE_X_TOOLKIT */
13397 Window window
= FRAME_X_WINDOW (f
);
13399 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
13400 f
->output_data
.x
->wm_hints
.initial_state
= state
;
13402 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
13403 #endif /* not USE_X_TOOLKIT */
13407 x_wm_set_icon_pixmap (f
, pixmap_id
)
13411 Pixmap icon_pixmap
;
13413 #ifndef USE_X_TOOLKIT
13414 Window window
= FRAME_X_WINDOW (f
);
13419 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
13420 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
13424 /* It seems there is no way to turn off use of an icon pixmap.
13425 The following line does it, only if no icon has yet been created,
13426 for some window managers. But with mwm it crashes.
13427 Some people say it should clear the IconPixmapHint bit in this case,
13428 but that doesn't work, and the X consortium said it isn't the
13429 right thing at all. Since there is no way to win,
13430 best to explicitly give up. */
13432 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
13438 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
13442 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
13443 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
13446 #else /* not USE_X_TOOLKIT */
13448 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
13449 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
13451 #endif /* not USE_X_TOOLKIT */
13455 x_wm_set_icon_position (f
, icon_x
, icon_y
)
13457 int icon_x
, icon_y
;
13459 #ifdef USE_X_TOOLKIT
13460 Window window
= XtWindow (f
->output_data
.x
->widget
);
13462 Window window
= FRAME_X_WINDOW (f
);
13465 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
13466 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
13467 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
13469 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
13473 /***********************************************************************
13475 ***********************************************************************/
13477 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
13480 x_get_font_info (f
, font_idx
)
13484 return (FRAME_X_FONT_TABLE (f
) + font_idx
);
13488 /* Return a list of names of available fonts matching PATTERN on frame F.
13490 If SIZE is > 0, it is the size (maximum bounds width) of fonts
13493 SIZE < 0 means include scalable fonts.
13495 Frame F null means we have not yet created any frame on X, and
13496 consult the first display in x_display_list. MAXNAMES sets a limit
13497 on how many fonts to match. */
13500 x_list_fonts (f
, pattern
, size
, maxnames
)
13502 Lisp_Object pattern
;
13506 Lisp_Object list
= Qnil
, patterns
, newlist
= Qnil
, key
= Qnil
;
13507 Lisp_Object tem
, second_best
;
13508 struct x_display_info
*dpyinfo
13509 = f
? FRAME_X_DISPLAY_INFO (f
) : x_display_list
;
13510 Display
*dpy
= dpyinfo
->display
;
13511 int try_XLoadQueryFont
= 0;
13513 int allow_scalable_fonts_p
= 0;
13517 allow_scalable_fonts_p
= 1;
13521 patterns
= Fassoc (pattern
, Valternate_fontname_alist
);
13522 if (NILP (patterns
))
13523 patterns
= Fcons (pattern
, Qnil
);
13525 if (maxnames
== 1 && !size
)
13526 /* We can return any single font matching PATTERN. */
13527 try_XLoadQueryFont
= 1;
13529 for (; CONSP (patterns
); patterns
= XCDR (patterns
))
13532 char **names
= NULL
;
13534 pattern
= XCAR (patterns
);
13535 /* See if we cached the result for this particular query.
13536 The cache is an alist of the form:
13537 ((((PATTERN . MAXNAMES) . SCALABLE) (FONTNAME . WIDTH) ...) ...) */
13538 tem
= XCDR (dpyinfo
->name_list_element
);
13539 key
= Fcons (Fcons (pattern
, make_number (maxnames
)),
13540 allow_scalable_fonts_p
? Qt
: Qnil
);
13541 list
= Fassoc (key
, tem
);
13544 list
= Fcdr_safe (list
);
13545 /* We have a cashed list. Don't have to get the list again. */
13549 /* At first, put PATTERN in the cache. */
13552 count
= x_catch_errors (dpy
);
13554 if (try_XLoadQueryFont
)
13557 unsigned long value
;
13559 font
= XLoadQueryFont (dpy
, XSTRING (pattern
)->data
);
13560 if (x_had_errors_p (dpy
))
13562 /* This error is perhaps due to insufficient memory on X
13563 server. Let's just ignore it. */
13565 x_clear_errors (dpy
);
13569 && XGetFontProperty (font
, XA_FONT
, &value
))
13571 char *name
= (char *) XGetAtomName (dpy
, (Atom
) value
);
13572 int len
= strlen (name
);
13575 /* If DXPC (a Differential X Protocol Compressor)
13576 Ver.3.7 is running, XGetAtomName will return null
13577 string. We must avoid such a name. */
13579 try_XLoadQueryFont
= 0;
13583 names
= (char **) alloca (sizeof (char *));
13584 /* Some systems only allow alloca assigned to a
13586 tmp
= (char *) alloca (len
+ 1); names
[0] = tmp
;
13587 bcopy (name
, names
[0], len
+ 1);
13592 try_XLoadQueryFont
= 0;
13595 XFreeFont (dpy
, font
);
13598 if (!try_XLoadQueryFont
)
13600 /* We try at least 10 fonts because XListFonts will return
13601 auto-scaled fonts at the head. */
13602 names
= XListFonts (dpy
, XSTRING (pattern
)->data
, max (maxnames
, 10),
13604 if (x_had_errors_p (dpy
))
13606 /* This error is perhaps due to insufficient memory on X
13607 server. Let's just ignore it. */
13609 x_clear_errors (dpy
);
13613 x_uncatch_errors (dpy
, count
);
13620 /* Make a list of all the fonts we got back.
13621 Store that in the font cache for the display. */
13622 for (i
= 0; i
< num_fonts
; i
++)
13625 char *p
= names
[i
];
13626 int average_width
= -1, dashes
= 0;
13628 /* Count the number of dashes in NAMES[I]. If there are
13629 14 dashes, and the field value following 12th dash
13630 (AVERAGE_WIDTH) is 0, this is a auto-scaled font which
13631 is usually too ugly to be used for editing. Let's
13637 if (dashes
== 7) /* PIXEL_SIZE field */
13639 else if (dashes
== 12) /* AVERAGE_WIDTH field */
13640 average_width
= atoi (p
);
13643 if (allow_scalable_fonts_p
13644 || dashes
< 14 || average_width
!= 0)
13646 tem
= build_string (names
[i
]);
13647 if (NILP (Fassoc (tem
, list
)))
13649 if (STRINGP (Vx_pixel_size_width_font_regexp
)
13650 && ((fast_c_string_match_ignore_case
13651 (Vx_pixel_size_width_font_regexp
, names
[i
]))
13653 /* We can set the value of PIXEL_SIZE to the
13654 width of this font. */
13655 list
= Fcons (Fcons (tem
, make_number (width
)), list
);
13657 /* For the moment, width is not known. */
13658 list
= Fcons (Fcons (tem
, Qnil
), list
);
13663 if (!try_XLoadQueryFont
)
13666 XFreeFontNames (names
);
13671 /* Now store the result in the cache. */
13672 XSETCDR (dpyinfo
->name_list_element
,
13673 Fcons (Fcons (key
, list
), XCDR (dpyinfo
->name_list_element
)));
13676 if (NILP (list
)) continue; /* Try the remaining alternatives. */
13678 newlist
= second_best
= Qnil
;
13679 /* Make a list of the fonts that have the right width. */
13680 for (; CONSP (list
); list
= XCDR (list
))
13686 if (!CONSP (tem
) || NILP (XCAR (tem
)))
13690 newlist
= Fcons (XCAR (tem
), newlist
);
13694 if (!INTEGERP (XCDR (tem
)))
13696 /* Since we have not yet known the size of this font, we
13697 must try slow function call XLoadQueryFont. */
13698 XFontStruct
*thisinfo
;
13701 count
= x_catch_errors (dpy
);
13702 thisinfo
= XLoadQueryFont (dpy
,
13703 XSTRING (XCAR (tem
))->data
);
13704 if (x_had_errors_p (dpy
))
13706 /* This error is perhaps due to insufficient memory on X
13707 server. Let's just ignore it. */
13709 x_clear_errors (dpy
);
13711 x_uncatch_errors (dpy
, count
);
13717 (thisinfo
->min_bounds
.width
== 0
13719 : make_number (thisinfo
->max_bounds
.width
)));
13721 XFreeFont (dpy
, thisinfo
);
13725 /* For unknown reason, the previous call of XListFont had
13726 returned a font which can't be opened. Record the size
13727 as 0 not to try to open it again. */
13728 XSETCDR (tem
, make_number (0));
13731 found_size
= XINT (XCDR (tem
));
13732 if (found_size
== size
)
13733 newlist
= Fcons (XCAR (tem
), newlist
);
13734 else if (found_size
> 0)
13736 if (NILP (second_best
))
13738 else if (found_size
< size
)
13740 if (XINT (XCDR (second_best
)) > size
13741 || XINT (XCDR (second_best
)) < found_size
)
13746 if (XINT (XCDR (second_best
)) > size
13747 && XINT (XCDR (second_best
)) > found_size
)
13752 if (!NILP (newlist
))
13754 else if (!NILP (second_best
))
13756 newlist
= Fcons (XCAR (second_best
), Qnil
);
13767 /* Check that FONT is valid on frame F. It is if it can be found in F's
13771 x_check_font (f
, font
)
13776 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13778 xassert (font
!= NULL
);
13780 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
13781 if (dpyinfo
->font_table
[i
].name
13782 && font
== dpyinfo
->font_table
[i
].font
)
13785 xassert (i
< dpyinfo
->n_fonts
);
13788 #endif /* GLYPH_DEBUG != 0 */
13790 /* Set *W to the minimum width, *H to the minimum font height of FONT.
13791 Note: There are (broken) X fonts out there with invalid XFontStruct
13792 min_bounds contents. For example, handa@etl.go.jp reports that
13793 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
13794 have font->min_bounds.width == 0. */
13797 x_font_min_bounds (font
, w
, h
)
13801 *h
= FONT_HEIGHT (font
);
13802 *w
= font
->min_bounds
.width
;
13804 /* Try to handle the case where FONT->min_bounds has invalid
13805 contents. Since the only font known to have invalid min_bounds
13806 is fixed-width, use max_bounds if min_bounds seems to be invalid. */
13808 *w
= font
->max_bounds
.width
;
13812 /* Compute the smallest character width and smallest font height over
13813 all fonts available on frame F. Set the members smallest_char_width
13814 and smallest_font_height in F's x_display_info structure to
13815 the values computed. Value is non-zero if smallest_font_height or
13816 smallest_char_width become smaller than they were before. */
13819 x_compute_min_glyph_bounds (f
)
13823 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13825 int old_width
= dpyinfo
->smallest_char_width
;
13826 int old_height
= dpyinfo
->smallest_font_height
;
13828 dpyinfo
->smallest_font_height
= 100000;
13829 dpyinfo
->smallest_char_width
= 100000;
13831 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
13832 if (dpyinfo
->font_table
[i
].name
)
13834 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
13837 font
= (XFontStruct
*) fontp
->font
;
13838 xassert (font
!= (XFontStruct
*) ~0);
13839 x_font_min_bounds (font
, &w
, &h
);
13841 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
13842 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
13845 xassert (dpyinfo
->smallest_char_width
> 0
13846 && dpyinfo
->smallest_font_height
> 0);
13848 return (dpyinfo
->n_fonts
== 1
13849 || dpyinfo
->smallest_char_width
< old_width
13850 || dpyinfo
->smallest_font_height
< old_height
);
13854 /* Load font named FONTNAME of the size SIZE for frame F, and return a
13855 pointer to the structure font_info while allocating it dynamically.
13856 If SIZE is 0, load any size of font.
13857 If loading is failed, return NULL. */
13860 x_load_font (f
, fontname
, size
)
13862 register char *fontname
;
13865 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13866 Lisp_Object font_names
;
13869 /* Get a list of all the fonts that match this name. Once we
13870 have a list of matching fonts, we compare them against the fonts
13871 we already have by comparing names. */
13872 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
13874 if (!NILP (font_names
))
13879 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
13880 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
13881 if (dpyinfo
->font_table
[i
].name
13882 && (!strcmp (dpyinfo
->font_table
[i
].name
,
13883 XSTRING (XCAR (tail
))->data
)
13884 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
13885 XSTRING (XCAR (tail
))->data
)))
13886 return (dpyinfo
->font_table
+ i
);
13889 /* Load the font and add it to the table. */
13893 struct font_info
*fontp
;
13894 unsigned long value
;
13897 /* If we have found fonts by x_list_font, load one of them. If
13898 not, we still try to load a font by the name given as FONTNAME
13899 because XListFonts (called in x_list_font) of some X server has
13900 a bug of not finding a font even if the font surely exists and
13901 is loadable by XLoadQueryFont. */
13902 if (size
> 0 && !NILP (font_names
))
13903 fontname
= (char *) XSTRING (XCAR (font_names
))->data
;
13906 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
13907 font
= (XFontStruct
*) XLoadQueryFont (FRAME_X_DISPLAY (f
), fontname
);
13908 if (x_had_errors_p (FRAME_X_DISPLAY (f
)))
13910 /* This error is perhaps due to insufficient memory on X
13911 server. Let's just ignore it. */
13913 x_clear_errors (FRAME_X_DISPLAY (f
));
13915 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
13920 /* Find a free slot in the font table. */
13921 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
13922 if (dpyinfo
->font_table
[i
].name
== NULL
)
13925 /* If no free slot found, maybe enlarge the font table. */
13926 if (i
== dpyinfo
->n_fonts
13927 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
13930 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
13931 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
13932 dpyinfo
->font_table
13933 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
13936 fontp
= dpyinfo
->font_table
+ i
;
13937 if (i
== dpyinfo
->n_fonts
)
13938 ++dpyinfo
->n_fonts
;
13940 /* Now fill in the slots of *FONTP. */
13942 fontp
->font
= font
;
13943 fontp
->font_idx
= i
;
13944 fontp
->name
= (char *) xmalloc (strlen (fontname
) + 1);
13945 bcopy (fontname
, fontp
->name
, strlen (fontname
) + 1);
13947 /* Try to get the full name of FONT. Put it in FULL_NAME. */
13949 if (XGetFontProperty (font
, XA_FONT
, &value
))
13951 char *name
= (char *) XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);
13955 /* Count the number of dashes in the "full name".
13956 If it is too few, this isn't really the font's full name,
13958 In X11R4, the fonts did not come with their canonical names
13969 full_name
= (char *) xmalloc (p
- name
+ 1);
13970 bcopy (name
, full_name
, p
- name
+ 1);
13976 if (full_name
!= 0)
13977 fontp
->full_name
= full_name
;
13979 fontp
->full_name
= fontp
->name
;
13981 fontp
->size
= font
->max_bounds
.width
;
13982 fontp
->height
= FONT_HEIGHT (font
);
13984 if (NILP (font_names
))
13986 /* We come here because of a bug of XListFonts mentioned at
13987 the head of this block. Let's store this information in
13988 the cache for x_list_fonts. */
13989 Lisp_Object lispy_name
= build_string (fontname
);
13990 Lisp_Object lispy_full_name
= build_string (fontp
->full_name
);
13991 Lisp_Object key
= Fcons (Fcons (lispy_name
, make_number (256)),
13994 XSETCDR (dpyinfo
->name_list_element
,
13996 Fcons (Fcons (lispy_full_name
,
13997 make_number (fontp
->size
)),
13999 XCDR (dpyinfo
->name_list_element
)));
14002 key
= Fcons (Fcons (lispy_full_name
, make_number (256)),
14004 XSETCDR (dpyinfo
->name_list_element
,
14006 Fcons (Fcons (lispy_full_name
,
14007 make_number (fontp
->size
)),
14009 XCDR (dpyinfo
->name_list_element
)));
14013 /* The slot `encoding' specifies how to map a character
14014 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
14015 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
14016 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
14017 2:0xA020..0xFF7F). For the moment, we don't know which charset
14018 uses this font. So, we set information in fontp->encoding[1]
14019 which is never used by any charset. If mapping can't be
14020 decided, set FONT_ENCODING_NOT_DECIDED. */
14022 = (font
->max_byte1
== 0
14024 ? (font
->min_char_or_byte2
< 0x80
14025 ? (font
->max_char_or_byte2
< 0x80
14026 ? 0 /* 0x20..0x7F */
14027 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
14028 : 1) /* 0xA0..0xFF */
14030 : (font
->min_byte1
< 0x80
14031 ? (font
->max_byte1
< 0x80
14032 ? (font
->min_char_or_byte2
< 0x80
14033 ? (font
->max_char_or_byte2
< 0x80
14034 ? 0 /* 0x2020..0x7F7F */
14035 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
14036 : 3) /* 0x20A0..0x7FFF */
14037 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
14038 : (font
->min_char_or_byte2
< 0x80
14039 ? (font
->max_char_or_byte2
< 0x80
14040 ? 2 /* 0xA020..0xFF7F */
14041 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
14042 : 1))); /* 0xA0A0..0xFFFF */
14044 fontp
->baseline_offset
14045 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
14046 ? (long) value
: 0);
14047 fontp
->relative_compose
14048 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
14049 ? (long) value
: 0);
14050 fontp
->default_ascent
14051 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
14052 ? (long) value
: 0);
14054 /* Set global flag fonts_changed_p to non-zero if the font loaded
14055 has a character with a smaller width than any other character
14056 before, or if the font loaded has a smalle>r height than any
14057 other font loaded before. If this happens, it will make a
14058 glyph matrix reallocation necessary. */
14059 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
14066 /* Return a pointer to struct font_info of a font named FONTNAME for
14067 frame F. If no such font is loaded, return NULL. */
14070 x_query_font (f
, fontname
)
14072 register char *fontname
;
14074 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
14077 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
14078 if (dpyinfo
->font_table
[i
].name
14079 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
14080 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
14081 return (dpyinfo
->font_table
+ i
);
14086 /* Find a CCL program for a font specified by FONTP, and set the member
14087 `encoder' of the structure. */
14090 x_find_ccl_program (fontp
)
14091 struct font_info
*fontp
;
14093 Lisp_Object list
, elt
;
14096 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
14100 && STRINGP (XCAR (elt
))
14101 && ((fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
14103 || (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->full_name
)
14110 struct ccl_program
*ccl
14111 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
14113 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
14116 fontp
->font_encoder
= ccl
;
14122 /***********************************************************************
14124 ***********************************************************************/
14126 #ifdef USE_X_TOOLKIT
14127 static XrmOptionDescRec emacs_options
[] = {
14128 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
14129 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
14131 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
14132 XrmoptionSepArg
, NULL
},
14133 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
14135 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
14136 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
14137 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
14138 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
14139 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
14140 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
14141 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
14143 #endif /* USE_X_TOOLKIT */
14145 static int x_initialized
;
14147 #ifdef MULTI_KBOARD
14148 /* Test whether two display-name strings agree up to the dot that separates
14149 the screen number from the server number. */
14151 same_x_server (name1
, name2
)
14152 char *name1
, *name2
;
14154 int seen_colon
= 0;
14155 unsigned char *system_name
= XSTRING (Vsystem_name
)->data
;
14156 int system_name_length
= strlen (system_name
);
14157 int length_until_period
= 0;
14159 while (system_name
[length_until_period
] != 0
14160 && system_name
[length_until_period
] != '.')
14161 length_until_period
++;
14163 /* Treat `unix' like an empty host name. */
14164 if (! strncmp (name1
, "unix:", 5))
14166 if (! strncmp (name2
, "unix:", 5))
14168 /* Treat this host's name like an empty host name. */
14169 if (! strncmp (name1
, system_name
, system_name_length
)
14170 && name1
[system_name_length
] == ':')
14171 name1
+= system_name_length
;
14172 if (! strncmp (name2
, system_name
, system_name_length
)
14173 && name2
[system_name_length
] == ':')
14174 name2
+= system_name_length
;
14175 /* Treat this host's domainless name like an empty host name. */
14176 if (! strncmp (name1
, system_name
, length_until_period
)
14177 && name1
[length_until_period
] == ':')
14178 name1
+= length_until_period
;
14179 if (! strncmp (name2
, system_name
, length_until_period
)
14180 && name2
[length_until_period
] == ':')
14181 name2
+= length_until_period
;
14183 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
14187 if (seen_colon
&& *name1
== '.')
14191 && (*name1
== '.' || *name1
== '\0')
14192 && (*name2
== '.' || *name2
== '\0'));
14196 struct x_display_info
*
14197 x_term_init (display_name
, xrm_option
, resource_name
)
14198 Lisp_Object display_name
;
14200 char *resource_name
;
14204 struct x_display_info
*dpyinfo
;
14209 if (!x_initialized
)
14215 #ifdef USE_X_TOOLKIT
14216 /* weiner@footloose.sps.mot.com reports that this causes
14218 X protocol error: BadAtom (invalid Atom parameter)
14219 on protocol request 18skiloaf.
14220 So let's not use it until R6. */
14221 #ifdef HAVE_X11XTR6
14222 XtSetLanguageProc (NULL
, NULL
, NULL
);
14233 argv
[argc
++] = "-xrm";
14234 argv
[argc
++] = xrm_option
;
14236 dpy
= XtOpenDisplay (Xt_app_con
, XSTRING (display_name
)->data
,
14237 resource_name
, EMACS_CLASS
,
14238 emacs_options
, XtNumber (emacs_options
),
14241 #ifdef HAVE_X11XTR6
14242 /* I think this is to compensate for XtSetLanguageProc. */
14247 #else /* not USE_X_TOOLKIT */
14249 XSetLocaleModifiers ("");
14251 dpy
= XOpenDisplay (XSTRING (display_name
)->data
);
14252 #endif /* not USE_X_TOOLKIT */
14254 /* Detect failure. */
14261 /* We have definitely succeeded. Record the new connection. */
14263 dpyinfo
= (struct x_display_info
*) xmalloc (sizeof (struct x_display_info
));
14264 bzero (dpyinfo
, sizeof *dpyinfo
);
14266 #ifdef MULTI_KBOARD
14268 struct x_display_info
*share
;
14271 for (share
= x_display_list
, tail
= x_display_name_list
; share
;
14272 share
= share
->next
, tail
= XCDR (tail
))
14273 if (same_x_server (XSTRING (XCAR (XCAR (tail
)))->data
,
14274 XSTRING (display_name
)->data
))
14277 dpyinfo
->kboard
= share
->kboard
;
14280 dpyinfo
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
14281 init_kboard (dpyinfo
->kboard
);
14282 if (!EQ (XSYMBOL (Qvendor_specific_keysyms
)->function
, Qunbound
))
14284 char *vendor
= ServerVendor (dpy
);
14286 dpyinfo
->kboard
->Vsystem_key_alist
14287 = call1 (Qvendor_specific_keysyms
,
14288 build_string (vendor
? vendor
: ""));
14292 dpyinfo
->kboard
->next_kboard
= all_kboards
;
14293 all_kboards
= dpyinfo
->kboard
;
14294 /* Don't let the initial kboard remain current longer than necessary.
14295 That would cause problems if a file loaded on startup tries to
14296 prompt in the mini-buffer. */
14297 if (current_kboard
== initial_kboard
)
14298 current_kboard
= dpyinfo
->kboard
;
14300 dpyinfo
->kboard
->reference_count
++;
14304 /* Put this display on the chain. */
14305 dpyinfo
->next
= x_display_list
;
14306 x_display_list
= dpyinfo
;
14308 /* Put it on x_display_name_list as well, to keep them parallel. */
14309 x_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
14310 x_display_name_list
);
14311 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
14313 dpyinfo
->display
= dpy
;
14316 XSetAfterFunction (x_current_display
, x_trace_wire
);
14320 = (char *) xmalloc (STRING_BYTES (XSTRING (Vinvocation_name
))
14321 + STRING_BYTES (XSTRING (Vsystem_name
))
14323 sprintf (dpyinfo
->x_id_name
, "%s@%s",
14324 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
14326 /* Figure out which modifier bits mean what. */
14327 x_find_modifier_meanings (dpyinfo
);
14329 /* Get the scroll bar cursor. */
14330 dpyinfo
->vertical_scroll_bar_cursor
14331 = XCreateFontCursor (dpyinfo
->display
, XC_sb_v_double_arrow
);
14333 xrdb
= x_load_resources (dpyinfo
->display
, xrm_option
,
14334 resource_name
, EMACS_CLASS
);
14335 #ifdef HAVE_XRMSETDATABASE
14336 XrmSetDatabase (dpyinfo
->display
, xrdb
);
14338 dpyinfo
->display
->db
= xrdb
;
14340 /* Put the rdb where we can find it in a way that works on
14342 dpyinfo
->xrdb
= xrdb
;
14344 dpyinfo
->screen
= ScreenOfDisplay (dpyinfo
->display
,
14345 DefaultScreen (dpyinfo
->display
));
14346 select_visual (dpyinfo
);
14347 dpyinfo
->cmap
= DefaultColormapOfScreen (dpyinfo
->screen
);
14348 dpyinfo
->height
= HeightOfScreen (dpyinfo
->screen
);
14349 dpyinfo
->width
= WidthOfScreen (dpyinfo
->screen
);
14350 dpyinfo
->root_window
= RootWindowOfScreen (dpyinfo
->screen
);
14351 dpyinfo
->grabbed
= 0;
14352 dpyinfo
->reference_count
= 0;
14353 dpyinfo
->icon_bitmap_id
= -1;
14354 dpyinfo
->font_table
= NULL
;
14355 dpyinfo
->n_fonts
= 0;
14356 dpyinfo
->font_table_size
= 0;
14357 dpyinfo
->bitmaps
= 0;
14358 dpyinfo
->bitmaps_size
= 0;
14359 dpyinfo
->bitmaps_last
= 0;
14360 dpyinfo
->scratch_cursor_gc
= 0;
14361 dpyinfo
->mouse_face_mouse_frame
= 0;
14362 dpyinfo
->mouse_face_deferred_gc
= 0;
14363 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
14364 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
14365 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
14366 dpyinfo
->mouse_face_window
= Qnil
;
14367 dpyinfo
->mouse_face_overlay
= Qnil
;
14368 dpyinfo
->mouse_face_mouse_x
= dpyinfo
->mouse_face_mouse_y
= 0;
14369 dpyinfo
->mouse_face_defer
= 0;
14370 dpyinfo
->x_focus_frame
= 0;
14371 dpyinfo
->x_focus_event_frame
= 0;
14372 dpyinfo
->x_highlight_frame
= 0;
14373 dpyinfo
->image_cache
= make_image_cache ();
14375 /* See if a private colormap is requested. */
14376 if (dpyinfo
->visual
== DefaultVisualOfScreen (dpyinfo
->screen
))
14378 if (dpyinfo
->visual
->class == PseudoColor
)
14381 value
= display_x_get_resource (dpyinfo
,
14382 build_string ("privateColormap"),
14383 build_string ("PrivateColormap"),
14385 if (STRINGP (value
)
14386 && (!strcmp (XSTRING (value
)->data
, "true")
14387 || !strcmp (XSTRING (value
)->data
, "on")))
14388 dpyinfo
->cmap
= XCopyColormapAndFree (dpyinfo
->display
, dpyinfo
->cmap
);
14392 dpyinfo
->cmap
= XCreateColormap (dpyinfo
->display
, dpyinfo
->root_window
,
14393 dpyinfo
->visual
, AllocNone
);
14396 int screen_number
= XScreenNumberOfScreen (dpyinfo
->screen
);
14397 double pixels
= DisplayHeight (dpyinfo
->display
, screen_number
);
14398 double mm
= DisplayHeightMM (dpyinfo
->display
, screen_number
);
14399 dpyinfo
->resy
= pixels
* 25.4 / mm
;
14400 pixels
= DisplayWidth (dpyinfo
->display
, screen_number
);
14401 mm
= DisplayWidthMM (dpyinfo
->display
, screen_number
);
14402 dpyinfo
->resx
= pixels
* 25.4 / mm
;
14405 dpyinfo
->Xatom_wm_protocols
14406 = XInternAtom (dpyinfo
->display
, "WM_PROTOCOLS", False
);
14407 dpyinfo
->Xatom_wm_take_focus
14408 = XInternAtom (dpyinfo
->display
, "WM_TAKE_FOCUS", False
);
14409 dpyinfo
->Xatom_wm_save_yourself
14410 = XInternAtom (dpyinfo
->display
, "WM_SAVE_YOURSELF", False
);
14411 dpyinfo
->Xatom_wm_delete_window
14412 = XInternAtom (dpyinfo
->display
, "WM_DELETE_WINDOW", False
);
14413 dpyinfo
->Xatom_wm_change_state
14414 = XInternAtom (dpyinfo
->display
, "WM_CHANGE_STATE", False
);
14415 dpyinfo
->Xatom_wm_configure_denied
14416 = XInternAtom (dpyinfo
->display
, "WM_CONFIGURE_DENIED", False
);
14417 dpyinfo
->Xatom_wm_window_moved
14418 = XInternAtom (dpyinfo
->display
, "WM_MOVED", False
);
14419 dpyinfo
->Xatom_editres
14420 = XInternAtom (dpyinfo
->display
, "Editres", False
);
14421 dpyinfo
->Xatom_CLIPBOARD
14422 = XInternAtom (dpyinfo
->display
, "CLIPBOARD", False
);
14423 dpyinfo
->Xatom_TIMESTAMP
14424 = XInternAtom (dpyinfo
->display
, "TIMESTAMP", False
);
14425 dpyinfo
->Xatom_TEXT
14426 = XInternAtom (dpyinfo
->display
, "TEXT", False
);
14427 dpyinfo
->Xatom_COMPOUND_TEXT
14428 = XInternAtom (dpyinfo
->display
, "COMPOUND_TEXT", False
);
14429 dpyinfo
->Xatom_DELETE
14430 = XInternAtom (dpyinfo
->display
, "DELETE", False
);
14431 dpyinfo
->Xatom_MULTIPLE
14432 = XInternAtom (dpyinfo
->display
, "MULTIPLE", False
);
14433 dpyinfo
->Xatom_INCR
14434 = XInternAtom (dpyinfo
->display
, "INCR", False
);
14435 dpyinfo
->Xatom_EMACS_TMP
14436 = XInternAtom (dpyinfo
->display
, "_EMACS_TMP_", False
);
14437 dpyinfo
->Xatom_TARGETS
14438 = XInternAtom (dpyinfo
->display
, "TARGETS", False
);
14439 dpyinfo
->Xatom_NULL
14440 = XInternAtom (dpyinfo
->display
, "NULL", False
);
14441 dpyinfo
->Xatom_ATOM_PAIR
14442 = XInternAtom (dpyinfo
->display
, "ATOM_PAIR", False
);
14443 /* For properties of font. */
14444 dpyinfo
->Xatom_PIXEL_SIZE
14445 = XInternAtom (dpyinfo
->display
, "PIXEL_SIZE", False
);
14446 dpyinfo
->Xatom_MULE_BASELINE_OFFSET
14447 = XInternAtom (dpyinfo
->display
, "_MULE_BASELINE_OFFSET", False
);
14448 dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
14449 = XInternAtom (dpyinfo
->display
, "_MULE_RELATIVE_COMPOSE", False
);
14450 dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
14451 = XInternAtom (dpyinfo
->display
, "_MULE_DEFAULT_ASCENT", False
);
14453 /* Ghostscript support. */
14454 dpyinfo
->Xatom_PAGE
= XInternAtom (dpyinfo
->display
, "PAGE", False
);
14455 dpyinfo
->Xatom_DONE
= XInternAtom (dpyinfo
->display
, "DONE", False
);
14457 dpyinfo
->Xatom_Scrollbar
= XInternAtom (dpyinfo
->display
, "SCROLLBAR",
14460 dpyinfo
->cut_buffers_initialized
= 0;
14462 connection
= ConnectionNumber (dpyinfo
->display
);
14463 dpyinfo
->connection
= connection
;
14468 null_bits
[0] = 0x00;
14470 dpyinfo
->null_pixel
14471 = XCreatePixmapFromBitmapData (dpyinfo
->display
, dpyinfo
->root_window
,
14472 null_bits
, 1, 1, (long) 0, (long) 0,
14477 extern int gray_bitmap_width
, gray_bitmap_height
;
14478 extern char *gray_bitmap_bits
;
14480 = XCreatePixmapFromBitmapData (dpyinfo
->display
, dpyinfo
->root_window
,
14482 gray_bitmap_width
, gray_bitmap_height
,
14483 (unsigned long) 1, (unsigned long) 0, 1);
14487 xim_initialize (dpyinfo
, resource_name
);
14490 #ifdef subprocesses
14491 /* This is only needed for distinguishing keyboard and process input. */
14492 if (connection
!= 0)
14493 add_keyboard_wait_descriptor (connection
);
14496 #ifndef F_SETOWN_BUG
14498 #ifdef F_SETOWN_SOCK_NEG
14499 /* stdin is a socket here */
14500 fcntl (connection
, F_SETOWN
, -getpid ());
14501 #else /* ! defined (F_SETOWN_SOCK_NEG) */
14502 fcntl (connection
, F_SETOWN
, getpid ());
14503 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
14504 #endif /* ! defined (F_SETOWN) */
14505 #endif /* F_SETOWN_BUG */
14508 if (interrupt_input
)
14509 init_sigio (connection
);
14510 #endif /* ! defined (SIGIO) */
14513 #ifdef HAVE_X11R5 /* It seems X11R4 lacks XtCvtStringToFont, and XPointer. */
14514 /* Make sure that we have a valid font for dialog boxes
14515 so that Xt does not crash. */
14517 Display
*dpy
= dpyinfo
->display
;
14518 XrmValue d
, fr
, to
;
14522 d
.addr
= (XPointer
)&dpy
;
14523 d
.size
= sizeof (Display
*);
14524 fr
.addr
= XtDefaultFont
;
14525 fr
.size
= sizeof (XtDefaultFont
);
14526 to
.size
= sizeof (Font
*);
14527 to
.addr
= (XPointer
)&font
;
14528 count
= x_catch_errors (dpy
);
14529 if (!XtCallConverter (dpy
, XtCvtStringToFont
, &d
, 1, &fr
, &to
, NULL
))
14531 if (x_had_errors_p (dpy
) || !XQueryFont (dpy
, font
))
14532 XrmPutLineResource (&xrdb
, "Emacs.dialog.*.font: 9x15");
14533 x_uncatch_errors (dpy
, count
);
14538 /* See if we should run in synchronous mode. This is useful
14539 for debugging X code. */
14542 value
= display_x_get_resource (dpyinfo
,
14543 build_string ("synchronous"),
14544 build_string ("Synchronous"),
14546 if (STRINGP (value
)
14547 && (!strcmp (XSTRING (value
)->data
, "true")
14548 || !strcmp (XSTRING (value
)->data
, "on")))
14549 XSynchronize (dpyinfo
->display
, True
);
14557 /* Get rid of display DPYINFO, assuming all frames are already gone,
14558 and without sending any more commands to the X server. */
14561 x_delete_display (dpyinfo
)
14562 struct x_display_info
*dpyinfo
;
14564 delete_keyboard_wait_descriptor (dpyinfo
->connection
);
14566 /* Discard this display from x_display_name_list and x_display_list.
14567 We can't use Fdelq because that can quit. */
14568 if (! NILP (x_display_name_list
)
14569 && EQ (XCAR (x_display_name_list
), dpyinfo
->name_list_element
))
14570 x_display_name_list
= XCDR (x_display_name_list
);
14575 tail
= x_display_name_list
;
14576 while (CONSP (tail
) && CONSP (XCDR (tail
)))
14578 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
14580 XSETCDR (tail
, XCDR (XCDR (tail
)));
14583 tail
= XCDR (tail
);
14587 if (next_noop_dpyinfo
== dpyinfo
)
14588 next_noop_dpyinfo
= dpyinfo
->next
;
14590 if (x_display_list
== dpyinfo
)
14591 x_display_list
= dpyinfo
->next
;
14594 struct x_display_info
*tail
;
14596 for (tail
= x_display_list
; tail
; tail
= tail
->next
)
14597 if (tail
->next
== dpyinfo
)
14598 tail
->next
= tail
->next
->next
;
14601 #ifndef USE_X_TOOLKIT /* I'm told Xt does this itself. */
14602 #ifndef AIX /* On AIX, XCloseDisplay calls this. */
14603 XrmDestroyDatabase (dpyinfo
->xrdb
);
14606 #ifdef MULTI_KBOARD
14607 if (--dpyinfo
->kboard
->reference_count
== 0)
14608 delete_kboard (dpyinfo
->kboard
);
14612 xim_close_dpy (dpyinfo
);
14615 xfree (dpyinfo
->font_table
);
14616 xfree (dpyinfo
->x_id_name
);
14617 xfree (dpyinfo
->color_cells
);
14622 /* Set up use of X before we make the first connection. */
14624 static struct redisplay_interface x_redisplay_interface
=
14629 x_clear_end_of_line
,
14631 x_after_update_window_line
,
14632 x_update_window_begin
,
14633 x_update_window_end
,
14636 x_clear_mouse_face
,
14637 x_get_glyph_overhangs
,
14638 x_fix_overlapping_area
14644 rif
= &x_redisplay_interface
;
14646 clear_frame_hook
= x_clear_frame
;
14647 ins_del_lines_hook
= x_ins_del_lines
;
14648 delete_glyphs_hook
= x_delete_glyphs
;
14649 ring_bell_hook
= XTring_bell
;
14650 reset_terminal_modes_hook
= XTreset_terminal_modes
;
14651 set_terminal_modes_hook
= XTset_terminal_modes
;
14652 update_begin_hook
= x_update_begin
;
14653 update_end_hook
= x_update_end
;
14654 set_terminal_window_hook
= XTset_terminal_window
;
14655 read_socket_hook
= XTread_socket
;
14656 frame_up_to_date_hook
= XTframe_up_to_date
;
14657 mouse_position_hook
= XTmouse_position
;
14658 frame_rehighlight_hook
= XTframe_rehighlight
;
14659 frame_raise_lower_hook
= XTframe_raise_lower
;
14660 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
14661 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
14662 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
14663 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
14664 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
14666 scroll_region_ok
= 1; /* we'll scroll partial frames */
14667 char_ins_del_ok
= 1;
14668 line_ins_del_ok
= 1; /* we'll just blt 'em */
14669 fast_clear_end_of_line
= 1; /* X does this well */
14670 memory_below_frame
= 0; /* we don't remember what scrolls
14675 last_tool_bar_item
= -1;
14676 any_help_event_p
= 0;
14678 /* Try to use interrupt input; if we can't, then start polling. */
14679 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
14681 #ifdef USE_X_TOOLKIT
14682 XtToolkitInitialize ();
14684 Xt_app_con
= XtCreateApplicationContext ();
14686 /* Register a converter from strings to pixels, which uses
14687 Emacs' color allocation infrastructure. */
14688 XtAppSetTypeConverter (Xt_app_con
,
14689 XtRString
, XtRPixel
, cvt_string_to_pixel
,
14690 cvt_string_to_pixel_args
,
14691 XtNumber (cvt_string_to_pixel_args
),
14692 XtCacheByDisplay
, cvt_pixel_dtor
);
14694 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
14696 /* Install an asynchronous timer that processes Xt timeout events
14697 every 0.1s. This is necessary because some widget sets use
14698 timeouts internally, for example the LessTif menu bar, or the
14699 Xaw3d scroll bar. When Xt timouts aren't processed, these
14700 widgets don't behave normally. */
14702 EMACS_TIME interval
;
14703 EMACS_SET_SECS_USECS (interval
, 0, 100000);
14704 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
14708 #ifdef USE_TOOLKIT_SCROLL_BARS
14709 xaw3d_arrow_scroll
= False
;
14710 xaw3d_pick_top
= True
;
14713 /* Note that there is no real way portable across R3/R4 to get the
14714 original error handler. */
14715 XSetErrorHandler (x_error_handler
);
14716 XSetIOErrorHandler (x_io_error_quitter
);
14718 /* Disable Window Change signals; they are handled by X events. */
14720 signal (SIGWINCH
, SIG_DFL
);
14721 #endif /* ! defined (SIGWINCH) */
14723 signal (SIGPIPE
, x_connection_signal
);
14730 staticpro (&x_error_message_string
);
14731 x_error_message_string
= Qnil
;
14733 staticpro (&x_display_name_list
);
14734 x_display_name_list
= Qnil
;
14736 staticpro (&last_mouse_scroll_bar
);
14737 last_mouse_scroll_bar
= Qnil
;
14739 staticpro (&Qvendor_specific_keysyms
);
14740 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
14742 staticpro (&last_mouse_press_frame
);
14743 last_mouse_press_frame
= Qnil
;
14746 staticpro (&help_echo
);
14747 help_echo_object
= Qnil
;
14748 staticpro (&help_echo_object
);
14749 help_echo_window
= Qnil
;
14750 staticpro (&help_echo_window
);
14751 previous_help_echo
= Qnil
;
14752 staticpro (&previous_help_echo
);
14753 help_echo_pos
= -1;
14755 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
14756 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
14757 For example, if a block cursor is over a tab, it will be drawn as
14758 wide as that tab on the display. */);
14759 x_stretch_cursor_p
= 0;
14761 DEFVAR_BOOL ("x-use-underline-position-properties",
14762 &x_use_underline_position_properties
,
14763 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
14764 Nil means ignore them. If you encounter fonts with bogus
14765 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
14766 to 4.1, set this to nil. */);
14767 x_use_underline_position_properties
= 1;
14769 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
14770 doc
: /* What X toolkit scroll bars Emacs uses.
14771 A value of nil means Emacs doesn't use X toolkit scroll bars.
14772 Otherwise, value is a symbol describing the X toolkit. */);
14773 #ifdef USE_TOOLKIT_SCROLL_BARS
14775 Vx_toolkit_scroll_bars
= intern ("motif");
14776 #elif defined HAVE_XAW3D
14777 Vx_toolkit_scroll_bars
= intern ("xaw3d");
14779 Vx_toolkit_scroll_bars
= intern ("xaw");
14782 Vx_toolkit_scroll_bars
= Qnil
;
14785 staticpro (&last_mouse_motion_frame
);
14786 last_mouse_motion_frame
= Qnil
;
14789 #endif /* HAVE_X_WINDOWS */