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 /* Bitmaps for truncated lines. */
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_bitmap
P_ ((struct window
*, struct glyph_row
*,
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_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_FLAGS_AREA_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 areas where they would be displayed
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_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 areas to the left or right 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_bitmap (w
, row
, which
)
824 struct glyph_row
*row
;
825 enum 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_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
851 case OVERLAY_ARROW_BITMAP
:
855 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
857 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
860 case RIGHT_TRUNCATION_BITMAP
:
864 x
= window_box_right (w
, -1);
865 x
+= (FRAME_X_RIGHT_FLAGS_AREA_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_FLAGS_AREA_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_FLAGS_AREA_WIDTH (f
) - wd
) / 2);
889 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
891 - (FRAME_X_LEFT_FLAGS_AREA_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
, BITMAP_AREA_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 flags bitmaps for glyph row ROW on window W. Call this
916 function with input blocked. */
919 x_draw_row_bitmaps (w
, row
)
921 struct glyph_row
*row
;
923 struct frame
*f
= XFRAME (w
->frame
);
924 enum 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
, BITMAP_AREA_FACE_ID
);
936 PREPARE_FACE_FOR_DISPLAY (f
, face
);
938 /* Decide which bitmap to draw at the left side. */
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
;
950 /* Clear flags area if no bitmap to draw or if bitmap doesn't fill
952 if (bitmap
== NO_BITMAP
953 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
)
954 || row
->height
> FRAME_FLAGS_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 bitmap areas 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_FLAGS_AREA_WIDTH (f
)
979 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
981 FRAME_X_LEFT_FLAGS_AREA_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_BITMAP
)
989 x_draw_bitmap (w
, row
, bitmap
);
991 /* Decide which bitmap to draw at the right side. */
992 if (row
->truncated_on_right_p
)
993 bitmap
= RIGHT_TRUNCATION_BITMAP
;
994 else if (row
->continued_p
)
995 bitmap
= CONTINUED_LINE_BITMAP
;
999 /* Clear flags area if no bitmap to draw of if bitmap doesn't fill
1001 if (bitmap
== NO_BITMAP
1002 || FRAME_FLAGS_BITMAP_WIDTH (f
) < FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f
)
1003 || row
->height
> FRAME_FLAGS_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 bitmap areas 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_FLAGS_AREA_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_BITMAP
)
1031 x_draw_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_FLAGS_AREA_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_FLAGS_AREA_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 flags areas to the
5736 left and right of W. */
5737 window_box (w
, -1, &x
, &y
, &width
, &height
);
5738 width
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
5739 x
-= FRAME_X_LEFT_FLAGS_AREA_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_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 bitmap areas 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_FLAGS_AREA_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
);
10672 if (event
.xcrossing
.focus
)
10674 /* Avoid nasty pop/raise loops. */
10675 if (f
&& (!(f
->auto_raise
)
10676 || !(f
->auto_lower
)
10677 || (event
.xcrossing
.time
- enter_timestamp
) > 500))
10679 x_new_focus_frame (dpyinfo
, f
);
10680 enter_timestamp
= event
.xcrossing
.time
;
10683 else if (f
== dpyinfo
->x_focus_frame
)
10684 x_new_focus_frame (dpyinfo
, 0);
10686 /* EnterNotify counts as mouse movement,
10687 so update things that depend on mouse position. */
10688 if (f
&& !f
->output_data
.x
->hourglass_p
)
10689 note_mouse_movement (f
, &event
.xmotion
);
10694 f
= x_any_window_to_frame (dpyinfo
, event
.xfocus
.window
);
10695 if (event
.xfocus
.detail
!= NotifyPointer
)
10696 dpyinfo
->x_focus_event_frame
= f
;
10699 x_new_focus_frame (dpyinfo
, f
);
10701 /* Don't stop displaying the initial startup message
10702 for a switch-frame event we don't need. */
10703 if (GC_NILP (Vterminal_frame
)
10704 && GC_CONSP (Vframe_list
)
10705 && !GC_NILP (XCDR (Vframe_list
)))
10707 bufp
->kind
= FOCUS_IN_EVENT
;
10708 XSETFRAME (bufp
->frame_or_window
, f
);
10710 ++bufp
, ++count
, --numchars
;
10715 if (f
&& FRAME_XIC (f
))
10716 XSetICFocus (FRAME_XIC (f
));
10722 f
= x_top_window_to_frame (dpyinfo
, event
.xcrossing
.window
);
10725 if (f
== dpyinfo
->mouse_face_mouse_frame
)
10727 /* If we move outside the frame, then we're
10728 certainly no longer on any text in the frame. */
10729 clear_mouse_face (dpyinfo
);
10730 dpyinfo
->mouse_face_mouse_frame
= 0;
10733 /* Generate a nil HELP_EVENT to cancel a help-echo.
10734 Do it only if there's something to cancel.
10735 Otherwise, the startup message is cleared when
10736 the mouse leaves the frame. */
10737 if (any_help_event_p
)
10742 XSETFRAME (frame
, f
);
10744 n
= gen_help_event (bufp
, numchars
,
10745 Qnil
, frame
, Qnil
, Qnil
, 0);
10746 bufp
+= n
, count
+= n
, numchars
-= n
;
10749 if (event
.xcrossing
.focus
)
10750 x_mouse_leave (dpyinfo
);
10753 if (f
== dpyinfo
->x_focus_event_frame
)
10754 dpyinfo
->x_focus_event_frame
= 0;
10755 if (f
== dpyinfo
->x_focus_frame
)
10756 x_new_focus_frame (dpyinfo
, 0);
10762 f
= x_any_window_to_frame (dpyinfo
, event
.xfocus
.window
);
10763 if (event
.xfocus
.detail
!= NotifyPointer
10764 && f
== dpyinfo
->x_focus_event_frame
)
10765 dpyinfo
->x_focus_event_frame
= 0;
10766 if (f
&& f
== dpyinfo
->x_focus_frame
)
10767 x_new_focus_frame (dpyinfo
, 0);
10770 if (f
&& FRAME_XIC (f
))
10771 XUnsetICFocus (FRAME_XIC (f
));
10778 previous_help_echo
= help_echo
;
10779 help_echo
= help_echo_object
= help_echo_window
= Qnil
;
10780 help_echo_pos
= -1;
10782 if (dpyinfo
->grabbed
&& last_mouse_frame
10783 && FRAME_LIVE_P (last_mouse_frame
))
10784 f
= last_mouse_frame
;
10786 f
= x_window_to_frame (dpyinfo
, event
.xmotion
.window
);
10789 note_mouse_movement (f
, &event
.xmotion
);
10792 #ifndef USE_TOOLKIT_SCROLL_BARS
10793 struct scroll_bar
*bar
10794 = x_window_to_scroll_bar (event
.xmotion
.window
);
10797 x_scroll_bar_note_movement (bar
, &event
);
10798 #endif /* USE_TOOLKIT_SCROLL_BARS */
10800 /* If we move outside the frame, then we're
10801 certainly no longer on any text in the frame. */
10802 clear_mouse_face (dpyinfo
);
10805 /* If the contents of the global variable help_echo
10806 has changed, generate a HELP_EVENT. */
10807 if (!NILP (help_echo
)
10808 || !NILP (previous_help_echo
))
10814 XSETFRAME (frame
, f
);
10818 any_help_event_p
= 1;
10819 n
= gen_help_event (bufp
, numchars
, help_echo
, frame
,
10820 help_echo_window
, help_echo_object
,
10822 bufp
+= n
, count
+= n
, numchars
-= n
;
10828 case ConfigureNotify
:
10829 f
= x_top_window_to_frame (dpyinfo
, event
.xconfigure
.window
);
10832 #ifndef USE_X_TOOLKIT
10833 int rows
= PIXEL_TO_CHAR_HEIGHT (f
, event
.xconfigure
.height
);
10834 int columns
= PIXEL_TO_CHAR_WIDTH (f
, event
.xconfigure
.width
);
10836 /* In the toolkit version, change_frame_size
10837 is called by the code that handles resizing
10838 of the EmacsFrame widget. */
10840 /* Even if the number of character rows and columns has
10841 not changed, the font size may have changed, so we need
10842 to check the pixel dimensions as well. */
10843 if (columns
!= f
->width
10844 || rows
!= f
->height
10845 || event
.xconfigure
.width
!= f
->output_data
.x
->pixel_width
10846 || event
.xconfigure
.height
!= f
->output_data
.x
->pixel_height
)
10848 change_frame_size (f
, rows
, columns
, 0, 1, 0);
10849 SET_FRAME_GARBAGED (f
);
10850 cancel_mouse_face (f
);
10854 f
->output_data
.x
->pixel_width
= event
.xconfigure
.width
;
10855 f
->output_data
.x
->pixel_height
= event
.xconfigure
.height
;
10857 /* What we have now is the position of Emacs's own window.
10858 Convert that to the position of the window manager window. */
10859 x_real_positions (f
, &f
->output_data
.x
->left_pos
,
10860 &f
->output_data
.x
->top_pos
);
10863 if (FRAME_XIC (f
) && (FRAME_XIC_STYLE (f
) & XIMStatusArea
))
10864 xic_set_statusarea (f
);
10867 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
10869 /* Since the WM decorations come below top_pos now,
10870 we must put them below top_pos in the future. */
10871 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
10872 x_wm_set_size_hint (f
, (long) 0, 0);
10875 /* Some window managers pass (0,0) as the location of
10876 the window, and the Motif event handler stores it
10877 in the emacs widget, which messes up Motif menus. */
10878 if (event
.xconfigure
.x
== 0 && event
.xconfigure
.y
== 0)
10880 event
.xconfigure
.x
= f
->output_data
.x
->widget
->core
.x
;
10881 event
.xconfigure
.y
= f
->output_data
.x
->widget
->core
.y
;
10883 #endif /* USE_MOTIF */
10888 case ButtonRelease
:
10890 /* If we decide we want to generate an event to be seen
10891 by the rest of Emacs, we put it here. */
10892 struct input_event emacs_event
;
10893 int tool_bar_p
= 0;
10895 emacs_event
.kind
= no_event
;
10896 bzero (&compose_status
, sizeof (compose_status
));
10898 if (dpyinfo
->grabbed
10899 && last_mouse_frame
10900 && FRAME_LIVE_P (last_mouse_frame
))
10901 f
= last_mouse_frame
;
10903 f
= x_window_to_frame (dpyinfo
, event
.xbutton
.window
);
10907 /* Is this in the tool-bar? */
10908 if (WINDOWP (f
->tool_bar_window
)
10909 && XFASTINT (XWINDOW (f
->tool_bar_window
)->height
))
10911 Lisp_Object window
;
10914 x
= event
.xbutton
.x
;
10915 y
= event
.xbutton
.y
;
10918 window
= window_from_coordinates (f
, x
, y
, &p
, 1);
10919 if (EQ (window
, f
->tool_bar_window
))
10921 x_handle_tool_bar_click (f
, &event
.xbutton
);
10927 if (!dpyinfo
->x_focus_frame
10928 || f
== dpyinfo
->x_focus_frame
)
10929 construct_mouse_click (&emacs_event
, &event
, f
);
10933 #ifndef USE_TOOLKIT_SCROLL_BARS
10934 struct scroll_bar
*bar
10935 = x_window_to_scroll_bar (event
.xbutton
.window
);
10938 x_scroll_bar_handle_click (bar
, &event
, &emacs_event
);
10939 #endif /* not USE_TOOLKIT_SCROLL_BARS */
10942 if (event
.type
== ButtonPress
)
10944 dpyinfo
->grabbed
|= (1 << event
.xbutton
.button
);
10945 last_mouse_frame
= f
;
10946 /* Ignore any mouse motion that happened
10947 before this event; any subsequent mouse-movement
10948 Emacs events should reflect only motion after
10949 the ButtonPress. */
10951 f
->mouse_moved
= 0;
10954 last_tool_bar_item
= -1;
10958 dpyinfo
->grabbed
&= ~(1 << event
.xbutton
.button
);
10961 if (numchars
>= 1 && emacs_event
.kind
!= no_event
)
10963 bcopy (&emacs_event
, bufp
, sizeof (struct input_event
));
10969 #ifdef USE_X_TOOLKIT
10970 f
= x_menubar_window_to_frame (dpyinfo
, event
.xbutton
.window
);
10971 /* For a down-event in the menu bar,
10972 don't pass it to Xt right now.
10973 Instead, save it away
10974 and we will pass it to Xt from kbd_buffer_get_event.
10975 That way, we can run some Lisp code first. */
10976 if (f
&& event
.type
== ButtonPress
10977 /* Verify the event is really within the menu bar
10978 and not just sent to it due to grabbing. */
10979 && event
.xbutton
.x
>= 0
10980 && event
.xbutton
.x
< f
->output_data
.x
->pixel_width
10981 && event
.xbutton
.y
>= 0
10982 && event
.xbutton
.y
< f
->output_data
.x
->menubar_height
10983 && event
.xbutton
.same_screen
)
10985 SET_SAVED_BUTTON_EVENT
;
10986 XSETFRAME (last_mouse_press_frame
, f
);
10988 else if (event
.type
== ButtonPress
)
10990 last_mouse_press_frame
= Qnil
;
10994 #ifdef USE_MOTIF /* This should do not harm for Lucid,
10995 but I am trying to be cautious. */
10996 else if (event
.type
== ButtonRelease
)
10998 if (!NILP (last_mouse_press_frame
))
11000 f
= XFRAME (last_mouse_press_frame
);
11001 if (f
->output_data
.x
)
11002 SET_SAVED_BUTTON_EVENT
;
11007 #endif /* USE_MOTIF */
11010 #endif /* USE_X_TOOLKIT */
11014 case CirculateNotify
:
11017 case CirculateRequest
:
11020 case VisibilityNotify
:
11023 case MappingNotify
:
11024 /* Someone has changed the keyboard mapping - update the
11026 switch (event
.xmapping
.request
)
11028 case MappingModifier
:
11029 x_find_modifier_meanings (dpyinfo
);
11030 /* This is meant to fall through. */
11031 case MappingKeyboard
:
11032 XRefreshKeyboardMapping (&event
.xmapping
);
11038 #ifdef USE_X_TOOLKIT
11040 XtDispatchEvent (&event
);
11042 #endif /* USE_X_TOOLKIT */
11050 /* On some systems, an X bug causes Emacs to get no more events
11051 when the window is destroyed. Detect that. (1994.) */
11054 /* Emacs and the X Server eats up CPU time if XNoOp is done every time.
11055 One XNOOP in 100 loops will make Emacs terminate.
11056 B. Bretthauer, 1994 */
11058 if (x_noop_count
>= 100)
11062 if (next_noop_dpyinfo
== 0)
11063 next_noop_dpyinfo
= x_display_list
;
11065 XNoOp (next_noop_dpyinfo
->display
);
11067 /* Each time we get here, cycle through the displays now open. */
11068 next_noop_dpyinfo
= next_noop_dpyinfo
->next
;
11072 /* If the focus was just given to an auto-raising frame,
11074 /* ??? This ought to be able to handle more than one such frame. */
11075 if (pending_autoraise_frame
)
11077 x_raise_frame (pending_autoraise_frame
);
11078 pending_autoraise_frame
= 0;
11089 /***********************************************************************
11091 ***********************************************************************/
11093 /* Notice if the text cursor of window W has been overwritten by a
11094 drawing operation that outputs N glyphs starting at START_X and
11095 ending at END_X in the line given by output_cursor.vpos.
11096 Coordinates are area-relative. END_X < 0 means all the rest
11097 of the line after START_X has been written. */
11100 notice_overwritten_cursor (w
, start_x
, end_x
)
11102 int start_x
, end_x
;
11104 if (updated_area
== TEXT_AREA
11105 && w
->phys_cursor_on_p
11106 && output_cursor
.vpos
== w
->phys_cursor
.vpos
11107 && start_x
<= w
->phys_cursor
.x
11108 && end_x
> w
->phys_cursor
.x
)
11109 w
->phys_cursor_on_p
= 0;
11113 /* Set clipping for output in glyph row ROW. W is the window in which
11114 we operate. GC is the graphics context to set clipping in.
11115 WHOLE_LINE_P non-zero means include the areas used for truncation
11116 mark display and alike in the clipping rectangle.
11118 ROW may be a text row or, e.g., a mode line. Text rows must be
11119 clipped to the interior of the window dedicated to text display,
11120 mode lines must be clipped to the whole window. */
11123 x_clip_to_row (w
, row
, gc
, whole_line_p
)
11125 struct glyph_row
*row
;
11129 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
11130 XRectangle clip_rect
;
11131 int window_x
, window_y
, window_width
, window_height
;
11133 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
11135 clip_rect
.x
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
11136 clip_rect
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
11137 clip_rect
.y
= max (clip_rect
.y
, window_y
);
11138 clip_rect
.width
= window_width
;
11139 clip_rect
.height
= row
->visible_height
;
11141 /* If clipping to the whole line, including trunc marks, extend
11142 the rectangle to the left and increase its width. */
11145 clip_rect
.x
-= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f
);
11146 clip_rect
.width
+= FRAME_X_FLAGS_AREA_WIDTH (f
);
11149 XSetClipRectangles (FRAME_X_DISPLAY (f
), gc
, 0, 0, &clip_rect
, 1, Unsorted
);
11153 /* Draw a hollow box cursor on window W in glyph row ROW. */
11156 x_draw_hollow_cursor (w
, row
)
11158 struct glyph_row
*row
;
11160 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
11161 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
11162 Display
*dpy
= FRAME_X_DISPLAY (f
);
11165 struct glyph
*cursor_glyph
;
11168 /* Compute frame-relative coordinates from window-relative
11170 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
11171 y
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
11172 + row
->ascent
- w
->phys_cursor_ascent
);
11173 h
= row
->height
- 1;
11175 /* Get the glyph the cursor is on. If we can't tell because
11176 the current matrix is invalid or such, give up. */
11177 cursor_glyph
= get_phys_cursor_glyph (w
);
11178 if (cursor_glyph
== NULL
)
11181 /* Compute the width of the rectangle to draw. If on a stretch
11182 glyph, and `x-stretch-block-cursor' is nil, don't draw a
11183 rectangle as wide as the glyph, but use a canonical character
11185 wd
= cursor_glyph
->pixel_width
- 1;
11186 if (cursor_glyph
->type
== STRETCH_GLYPH
11187 && !x_stretch_cursor_p
)
11188 wd
= min (CANON_X_UNIT (f
), wd
);
11190 /* The foreground of cursor_gc is typically the same as the normal
11191 background color, which can cause the cursor box to be invisible. */
11192 xgcv
.foreground
= f
->output_data
.x
->cursor_pixel
;
11193 if (dpyinfo
->scratch_cursor_gc
)
11194 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
11196 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_X_WINDOW (f
),
11197 GCForeground
, &xgcv
);
11198 gc
= dpyinfo
->scratch_cursor_gc
;
11200 /* Set clipping, draw the rectangle, and reset clipping again. */
11201 x_clip_to_row (w
, row
, gc
, 0);
11202 XDrawRectangle (dpy
, FRAME_X_WINDOW (f
), gc
, x
, y
, wd
, h
);
11203 XSetClipMask (dpy
, gc
, None
);
11207 /* Draw a bar cursor on window W in glyph row ROW.
11209 Implementation note: One would like to draw a bar cursor with an
11210 angle equal to the one given by the font property XA_ITALIC_ANGLE.
11211 Unfortunately, I didn't find a font yet that has this property set.
11215 x_draw_bar_cursor (w
, row
, width
)
11217 struct glyph_row
*row
;
11220 struct frame
*f
= XFRAME (w
->frame
);
11221 struct glyph
*cursor_glyph
;
11224 unsigned long mask
;
11229 /* If cursor is out of bounds, don't draw garbage. This can happen
11230 in mini-buffer windows when switching between echo area glyphs
11231 and mini-buffer. */
11232 cursor_glyph
= get_phys_cursor_glyph (w
);
11233 if (cursor_glyph
== NULL
)
11236 /* If on an image, draw like a normal cursor. That's usually better
11237 visible than drawing a bar, esp. if the image is large so that
11238 the bar might not be in the window. */
11239 if (cursor_glyph
->type
== IMAGE_GLYPH
)
11241 struct glyph_row
*row
;
11242 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
11243 x_draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
11247 xgcv
.background
= f
->output_data
.x
->cursor_pixel
;
11248 xgcv
.foreground
= f
->output_data
.x
->cursor_pixel
;
11249 xgcv
.graphics_exposures
= 0;
11250 mask
= GCForeground
| GCBackground
| GCGraphicsExposures
;
11251 dpy
= FRAME_X_DISPLAY (f
);
11252 window
= FRAME_X_WINDOW (f
);
11253 gc
= FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
;
11256 XChangeGC (dpy
, gc
, mask
, &xgcv
);
11259 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
11260 FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
11264 width
= f
->output_data
.x
->cursor_width
;
11266 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
11267 x_clip_to_row (w
, row
, gc
, 0);
11268 XFillRectangle (dpy
, window
, gc
,
11270 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
11271 min (cursor_glyph
->pixel_width
, width
),
11273 XSetClipMask (dpy
, gc
, None
);
11278 /* Clear the cursor of window W to background color, and mark the
11279 cursor as not shown. This is used when the text where the cursor
11280 is is about to be rewritten. */
11286 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
11287 x_update_window_cursor (w
, 0);
11291 /* Draw the cursor glyph of window W in glyph row ROW. See the
11292 comment of x_draw_glyphs for the meaning of HL. */
11295 x_draw_phys_cursor_glyph (w
, row
, hl
)
11297 struct glyph_row
*row
;
11298 enum draw_glyphs_face hl
;
11300 /* If cursor hpos is out of bounds, don't draw garbage. This can
11301 happen in mini-buffer windows when switching between echo area
11302 glyphs and mini-buffer. */
11303 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
11305 int on_p
= w
->phys_cursor_on_p
;
11307 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
11308 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
11310 w
->phys_cursor_on_p
= on_p
;
11312 /* When we erase the cursor, and ROW is overlapped by other
11313 rows, make sure that these overlapping parts of other rows
11315 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
11317 if (row
> w
->current_matrix
->rows
11318 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
11319 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
11321 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
11322 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
11323 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
11329 /* Erase the image of a cursor of window W from the screen. */
11332 x_erase_phys_cursor (w
)
11335 struct frame
*f
= XFRAME (w
->frame
);
11336 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
11337 int hpos
= w
->phys_cursor
.hpos
;
11338 int vpos
= w
->phys_cursor
.vpos
;
11339 int mouse_face_here_p
= 0;
11340 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
11341 struct glyph_row
*cursor_row
;
11342 struct glyph
*cursor_glyph
;
11343 enum draw_glyphs_face hl
;
11345 /* No cursor displayed or row invalidated => nothing to do on the
11347 if (w
->phys_cursor_type
== NO_CURSOR
)
11348 goto mark_cursor_off
;
11350 /* VPOS >= active_glyphs->nrows means that window has been resized.
11351 Don't bother to erase the cursor. */
11352 if (vpos
>= active_glyphs
->nrows
)
11353 goto mark_cursor_off
;
11355 /* If row containing cursor is marked invalid, there is nothing we
11357 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
11358 if (!cursor_row
->enabled_p
)
11359 goto mark_cursor_off
;
11361 /* This can happen when the new row is shorter than the old one.
11362 In this case, either x_draw_glyphs or clear_end_of_line
11363 should have cleared the cursor. Note that we wouldn't be
11364 able to erase the cursor in this case because we don't have a
11365 cursor glyph at hand. */
11366 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
11367 goto mark_cursor_off
;
11369 /* If the cursor is in the mouse face area, redisplay that when
11370 we clear the cursor. */
11371 if (! NILP (dpyinfo
->mouse_face_window
)
11372 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
11373 && (vpos
> dpyinfo
->mouse_face_beg_row
11374 || (vpos
== dpyinfo
->mouse_face_beg_row
11375 && hpos
>= dpyinfo
->mouse_face_beg_col
))
11376 && (vpos
< dpyinfo
->mouse_face_end_row
11377 || (vpos
== dpyinfo
->mouse_face_end_row
11378 && hpos
< dpyinfo
->mouse_face_end_col
))
11379 /* Don't redraw the cursor's spot in mouse face if it is at the
11380 end of a line (on a newline). The cursor appears there, but
11381 mouse highlighting does not. */
11382 && cursor_row
->used
[TEXT_AREA
] > hpos
)
11383 mouse_face_here_p
= 1;
11385 /* Maybe clear the display under the cursor. */
11386 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
11389 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
11391 cursor_glyph
= get_phys_cursor_glyph (w
);
11392 if (cursor_glyph
== NULL
)
11393 goto mark_cursor_off
;
11395 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
11397 x_clear_area (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
11399 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
11401 cursor_glyph
->pixel_width
,
11402 cursor_row
->visible_height
,
11406 /* Erase the cursor by redrawing the character underneath it. */
11407 if (mouse_face_here_p
)
11408 hl
= DRAW_MOUSE_FACE
;
11410 hl
= DRAW_NORMAL_TEXT
;
11411 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
11414 w
->phys_cursor_on_p
= 0;
11415 w
->phys_cursor_type
= NO_CURSOR
;
11419 /* Non-zero if physical cursor of window W is within mouse face. */
11422 cursor_in_mouse_face_p (w
)
11425 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
11426 int in_mouse_face
= 0;
11428 if (WINDOWP (dpyinfo
->mouse_face_window
)
11429 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
11431 int hpos
= w
->phys_cursor
.hpos
;
11432 int vpos
= w
->phys_cursor
.vpos
;
11434 if (vpos
>= dpyinfo
->mouse_face_beg_row
11435 && vpos
<= dpyinfo
->mouse_face_end_row
11436 && (vpos
> dpyinfo
->mouse_face_beg_row
11437 || hpos
>= dpyinfo
->mouse_face_beg_col
)
11438 && (vpos
< dpyinfo
->mouse_face_end_row
11439 || hpos
< dpyinfo
->mouse_face_end_col
11440 || dpyinfo
->mouse_face_past_end
))
11444 return in_mouse_face
;
11448 /* Display or clear cursor of window W. If ON is zero, clear the
11449 cursor. If it is non-zero, display the cursor. If ON is nonzero,
11450 where to put the cursor is specified by HPOS, VPOS, X and Y. */
11453 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
11455 int on
, hpos
, vpos
, x
, y
;
11457 struct frame
*f
= XFRAME (w
->frame
);
11458 int new_cursor_type
;
11459 int new_cursor_width
;
11460 struct glyph_matrix
*current_glyphs
;
11461 struct glyph_row
*glyph_row
;
11462 struct glyph
*glyph
;
11463 int cursor_non_selected
;
11465 /* This is pointless on invisible frames, and dangerous on garbaged
11466 windows and frames; in the latter case, the frame or window may
11467 be in the midst of changing its size, and x and y may be off the
11469 if (! FRAME_VISIBLE_P (f
)
11470 || FRAME_GARBAGED_P (f
)
11471 || vpos
>= w
->current_matrix
->nrows
11472 || hpos
>= w
->current_matrix
->matrix_w
)
11475 /* If cursor is off and we want it off, return quickly. */
11476 if (!on
&& !w
->phys_cursor_on_p
)
11479 current_glyphs
= w
->current_matrix
;
11480 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
11481 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
11483 /* If cursor row is not enabled, we don't really know where to
11484 display the cursor. */
11485 if (!glyph_row
->enabled_p
)
11487 w
->phys_cursor_on_p
= 0;
11491 xassert (interrupt_input_blocked
);
11493 /* Set new_cursor_type to the cursor we want to be displayed. In a
11494 mini-buffer window, we want the cursor only to appear if we are
11495 reading input from this window. For the selected window, we want
11496 the cursor type given by the frame parameter. If explicitly
11497 marked off, draw no cursor. In all other cases, we want a hollow
11499 cursor_non_selected
11500 = !NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows
,
11502 new_cursor_width
= -1;
11503 if (cursor_in_echo_area
11504 && FRAME_HAS_MINIBUF_P (f
)
11505 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
11507 if (w
== XWINDOW (echo_area_window
))
11508 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
11509 else if (cursor_non_selected
)
11510 new_cursor_type
= HOLLOW_BOX_CURSOR
;
11512 new_cursor_type
= NO_CURSOR
;
11516 if (f
!= FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
11517 || w
!= XWINDOW (f
->selected_window
))
11519 if (MINI_WINDOW_P (w
)
11520 || !cursor_non_selected
11521 || NILP (XBUFFER (w
->buffer
)->cursor_type
))
11522 new_cursor_type
= NO_CURSOR
;
11524 new_cursor_type
= HOLLOW_BOX_CURSOR
;
11526 else if (w
->cursor_off_p
)
11527 new_cursor_type
= NO_CURSOR
;
11530 struct buffer
*b
= XBUFFER (w
->buffer
);
11532 if (EQ (b
->cursor_type
, Qt
))
11533 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
11535 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
11536 &new_cursor_width
);
11540 /* If cursor is currently being shown and we don't want it to be or
11541 it is in the wrong place, or the cursor type is not what we want,
11543 if (w
->phys_cursor_on_p
11545 || w
->phys_cursor
.x
!= x
11546 || w
->phys_cursor
.y
!= y
11547 || new_cursor_type
!= w
->phys_cursor_type
))
11548 x_erase_phys_cursor (w
);
11550 /* If the cursor is now invisible and we want it to be visible,
11552 if (on
&& !w
->phys_cursor_on_p
)
11554 w
->phys_cursor_ascent
= glyph_row
->ascent
;
11555 w
->phys_cursor_height
= glyph_row
->height
;
11557 /* Set phys_cursor_.* before x_draw_.* is called because some
11558 of them may need the information. */
11559 w
->phys_cursor
.x
= x
;
11560 w
->phys_cursor
.y
= glyph_row
->y
;
11561 w
->phys_cursor
.hpos
= hpos
;
11562 w
->phys_cursor
.vpos
= vpos
;
11563 w
->phys_cursor_type
= new_cursor_type
;
11564 w
->phys_cursor_on_p
= 1;
11566 switch (new_cursor_type
)
11568 case HOLLOW_BOX_CURSOR
:
11569 x_draw_hollow_cursor (w
, glyph_row
);
11572 case FILLED_BOX_CURSOR
:
11573 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
11577 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
11588 if (w
== XWINDOW (f
->selected_window
))
11589 if (FRAME_XIC (f
) && (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
))
11590 xic_set_preeditarea (w
, x
, y
);
11595 if (updating_frame
!= f
)
11596 XFlush (FRAME_X_DISPLAY (f
));
11601 /* Display the cursor on window W, or clear it. X and Y are window
11602 relative pixel coordinates. HPOS and VPOS are glyph matrix
11603 positions. If W is not the selected window, display a hollow
11604 cursor. ON non-zero means display the cursor at X, Y which
11605 correspond to HPOS, VPOS, otherwise it is cleared. */
11608 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
11610 int on
, hpos
, vpos
, x
, y
;
11613 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
11618 /* Display the cursor on window W, or clear it, according to ON_P.
11619 Don't change the cursor's position. */
11622 x_update_cursor (f
, on_p
)
11625 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
11629 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
11630 in the window tree rooted at W. */
11633 x_update_cursor_in_window_tree (w
, on_p
)
11639 if (!NILP (w
->hchild
))
11640 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
11641 else if (!NILP (w
->vchild
))
11642 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
11644 x_update_window_cursor (w
, on_p
);
11646 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
11651 /* Switch the display of W's cursor on or off, according to the value
11655 x_update_window_cursor (w
, on
)
11659 /* Don't update cursor in windows whose frame is in the process
11660 of being deleted. */
11661 if (w
->current_matrix
)
11664 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
11665 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
11675 /* Make the x-window of frame F use the gnu icon bitmap. */
11678 x_bitmap_icon (f
, file
)
11684 if (FRAME_X_WINDOW (f
) == 0)
11687 /* Free up our existing icon bitmap if any. */
11688 if (f
->output_data
.x
->icon_bitmap
> 0)
11689 x_destroy_bitmap (f
, f
->output_data
.x
->icon_bitmap
);
11690 f
->output_data
.x
->icon_bitmap
= 0;
11692 if (STRINGP (file
))
11693 bitmap_id
= x_create_bitmap_from_file (f
, file
);
11696 /* Create the GNU bitmap if necessary. */
11697 if (FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
< 0)
11698 FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
11699 = x_create_bitmap_from_data (f
, gnu_bits
,
11700 gnu_width
, gnu_height
);
11702 /* The first time we create the GNU bitmap,
11703 this increments the ref-count one extra time.
11704 As a result, the GNU bitmap is never freed.
11705 That way, we don't have to worry about allocating it again. */
11706 x_reference_bitmap (f
, FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
);
11708 bitmap_id
= FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
;
11711 x_wm_set_icon_pixmap (f
, bitmap_id
);
11712 f
->output_data
.x
->icon_bitmap
= bitmap_id
;
11718 /* Make the x-window of frame F use a rectangle with text.
11719 Use ICON_NAME as the text. */
11722 x_text_icon (f
, icon_name
)
11726 if (FRAME_X_WINDOW (f
) == 0)
11731 XTextProperty text
;
11732 text
.value
= (unsigned char *) icon_name
;
11733 text
.encoding
= XA_STRING
;
11735 text
.nitems
= strlen (icon_name
);
11736 #ifdef USE_X_TOOLKIT
11737 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
11739 #else /* not USE_X_TOOLKIT */
11740 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
11741 #endif /* not USE_X_TOOLKIT */
11743 #else /* not HAVE_X11R4 */
11744 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), icon_name
);
11745 #endif /* not HAVE_X11R4 */
11747 if (f
->output_data
.x
->icon_bitmap
> 0)
11748 x_destroy_bitmap (f
, f
->output_data
.x
->icon_bitmap
);
11749 f
->output_data
.x
->icon_bitmap
= 0;
11750 x_wm_set_icon_pixmap (f
, 0);
11755 #define X_ERROR_MESSAGE_SIZE 200
11757 /* If non-nil, this should be a string.
11758 It means catch X errors and store the error message in this string. */
11760 static Lisp_Object x_error_message_string
;
11762 /* An X error handler which stores the error message in
11763 x_error_message_string. This is called from x_error_handler if
11764 x_catch_errors is in effect. */
11767 x_error_catcher (display
, error
)
11769 XErrorEvent
*error
;
11771 XGetErrorText (display
, error
->error_code
,
11772 XSTRING (x_error_message_string
)->data
,
11773 X_ERROR_MESSAGE_SIZE
);
11776 /* Begin trapping X errors for display DPY. Actually we trap X errors
11777 for all displays, but DPY should be the display you are actually
11780 After calling this function, X protocol errors no longer cause
11781 Emacs to exit; instead, they are recorded in the string
11782 stored in x_error_message_string.
11784 Calling x_check_errors signals an Emacs error if an X error has
11785 occurred since the last call to x_catch_errors or x_check_errors.
11787 Calling x_uncatch_errors resumes the normal error handling. */
11789 void x_check_errors ();
11790 static Lisp_Object
x_catch_errors_unwind ();
11793 x_catch_errors (dpy
)
11796 int count
= specpdl_ptr
- specpdl
;
11798 /* Make sure any errors from previous requests have been dealt with. */
11799 XSync (dpy
, False
);
11801 record_unwind_protect (x_catch_errors_unwind
, x_error_message_string
);
11803 x_error_message_string
= make_uninit_string (X_ERROR_MESSAGE_SIZE
);
11804 XSTRING (x_error_message_string
)->data
[0] = 0;
11809 /* Unbind the binding that we made to check for X errors. */
11812 x_catch_errors_unwind (old_val
)
11813 Lisp_Object old_val
;
11815 x_error_message_string
= old_val
;
11819 /* If any X protocol errors have arrived since the last call to
11820 x_catch_errors or x_check_errors, signal an Emacs error using
11821 sprintf (a buffer, FORMAT, the x error message text) as the text. */
11824 x_check_errors (dpy
, format
)
11828 /* Make sure to catch any errors incurred so far. */
11829 XSync (dpy
, False
);
11831 if (XSTRING (x_error_message_string
)->data
[0])
11832 error (format
, XSTRING (x_error_message_string
)->data
);
11835 /* Nonzero if we had any X protocol errors
11836 since we did x_catch_errors on DPY. */
11839 x_had_errors_p (dpy
)
11842 /* Make sure to catch any errors incurred so far. */
11843 XSync (dpy
, False
);
11845 return XSTRING (x_error_message_string
)->data
[0] != 0;
11848 /* Forget about any errors we have had, since we did x_catch_errors on DPY. */
11851 x_clear_errors (dpy
)
11854 XSTRING (x_error_message_string
)->data
[0] = 0;
11857 /* Stop catching X protocol errors and let them make Emacs die.
11858 DPY should be the display that was passed to x_catch_errors.
11859 COUNT should be the value that was returned by
11860 the corresponding call to x_catch_errors. */
11863 x_uncatch_errors (dpy
, count
)
11867 unbind_to (count
, Qnil
);
11871 static unsigned int x_wire_count
;
11874 fprintf (stderr
, "Lib call: %d\n", ++x_wire_count
);
11879 /* Handle SIGPIPE, which can happen when the connection to a server
11880 simply goes away. SIGPIPE is handled by x_connection_signal.
11881 Don't need to do anything, because the write which caused the
11882 SIGPIPE will fail, causing Xlib to invoke the X IO error handler,
11883 which will do the appropriate cleanup for us. */
11886 x_connection_signal (signalnum
) /* If we don't have an argument, */
11887 int signalnum
; /* some compilers complain in signal calls. */
11890 /* USG systems forget handlers when they are used;
11891 must reestablish each time */
11892 signal (signalnum
, x_connection_signal
);
11897 /************************************************************************
11899 ************************************************************************/
11901 /* Error message passed to x_connection_closed. */
11903 static char *error_msg
;
11905 /* Function installed as fatal_error_signal_hook in
11906 x_connection_closed. Print the X error message, and exit normally,
11907 instead of dumping core when XtCloseDisplay fails. */
11910 x_fatal_error_signal ()
11912 fprintf (stderr
, "%s\n", error_msg
);
11916 /* Handle the loss of connection to display DPY. ERROR_MESSAGE is
11917 the text of an error message that lead to the connection loss. */
11920 x_connection_closed (dpy
, error_message
)
11922 char *error_message
;
11924 struct x_display_info
*dpyinfo
= x_display_info_for_display (dpy
);
11925 Lisp_Object frame
, tail
;
11928 error_msg
= (char *) alloca (strlen (error_message
) + 1);
11929 strcpy (error_msg
, error_message
);
11930 handling_signal
= 0;
11932 /* Prevent being called recursively because of an error condition
11933 below. Otherwise, we might end up with printing ``can't find per
11934 display information'' in the recursive call instead of printing
11935 the original message here. */
11936 count
= x_catch_errors (dpy
);
11938 /* We have to close the display to inform Xt that it doesn't
11939 exist anymore. If we don't, Xt will continue to wait for
11940 events from the display. As a consequence, a sequence of
11942 M-x make-frame-on-display RET :1 RET
11943 ...kill the new frame, so that we get an IO error...
11944 M-x make-frame-on-display RET :1 RET
11946 will indefinitely wait in Xt for events for display `:1', opened
11947 in the first class to make-frame-on-display.
11949 Closing the display is reported to lead to a bus error on
11950 OpenWindows in certain situations. I suspect that is a bug
11951 in OpenWindows. I don't know how to cicumvent it here. */
11953 #ifdef USE_X_TOOLKIT
11954 /* If DPYINFO is null, this means we didn't open the display
11955 in the first place, so don't try to close it. */
11958 extern void (*fatal_error_signal_hook
) P_ ((void));
11959 fatal_error_signal_hook
= x_fatal_error_signal
;
11960 XtCloseDisplay (dpy
);
11961 fatal_error_signal_hook
= NULL
;
11965 /* Indicate that this display is dead. */
11967 dpyinfo
->display
= 0;
11969 /* First delete frames whose mini-buffers are on frames
11970 that are on the dead display. */
11971 FOR_EACH_FRAME (tail
, frame
)
11973 Lisp_Object minibuf_frame
;
11975 = WINDOW_FRAME (XWINDOW (FRAME_MINIBUF_WINDOW (XFRAME (frame
))));
11976 if (FRAME_X_P (XFRAME (frame
))
11977 && FRAME_X_P (XFRAME (minibuf_frame
))
11978 && ! EQ (frame
, minibuf_frame
)
11979 && FRAME_X_DISPLAY_INFO (XFRAME (minibuf_frame
)) == dpyinfo
)
11980 Fdelete_frame (frame
, Qt
);
11983 /* Now delete all remaining frames on the dead display.
11984 We are now sure none of these is used as the mini-buffer
11985 for another frame that we need to delete. */
11986 FOR_EACH_FRAME (tail
, frame
)
11987 if (FRAME_X_P (XFRAME (frame
))
11988 && FRAME_X_DISPLAY_INFO (XFRAME (frame
)) == dpyinfo
)
11990 /* Set this to t so that Fdelete_frame won't get confused
11991 trying to find a replacement. */
11992 FRAME_KBOARD (XFRAME (frame
))->Vdefault_minibuffer_frame
= Qt
;
11993 Fdelete_frame (frame
, Qt
);
11997 x_delete_display (dpyinfo
);
11999 x_uncatch_errors (dpy
, count
);
12001 if (x_display_list
== 0)
12003 fprintf (stderr
, "%s\n", error_msg
);
12004 shut_down_emacs (0, 0, Qnil
);
12008 /* Ordinary stack unwind doesn't deal with these. */
12010 sigunblock (sigmask (SIGIO
));
12012 sigunblock (sigmask (SIGALRM
));
12013 TOTALLY_UNBLOCK_INPUT
;
12015 clear_waiting_for_input ();
12016 error ("%s", error_msg
);
12020 /* This is the usual handler for X protocol errors.
12021 It kills all frames on the display that we got the error for.
12022 If that was the only one, it prints an error message and kills Emacs. */
12025 x_error_quitter (display
, error
)
12027 XErrorEvent
*error
;
12029 char buf
[256], buf1
[356];
12031 /* Note that there is no real way portable across R3/R4 to get the
12032 original error handler. */
12034 XGetErrorText (display
, error
->error_code
, buf
, sizeof (buf
));
12035 sprintf (buf1
, "X protocol error: %s on protocol request %d",
12036 buf
, error
->request_code
);
12037 x_connection_closed (display
, buf1
);
12041 /* This is the first-level handler for X protocol errors.
12042 It calls x_error_quitter or x_error_catcher. */
12045 x_error_handler (display
, error
)
12047 XErrorEvent
*error
;
12049 if (! NILP (x_error_message_string
))
12050 x_error_catcher (display
, error
);
12052 x_error_quitter (display
, error
);
12056 /* This is the handler for X IO errors, always.
12057 It kills all frames on the display that we lost touch with.
12058 If that was the only one, it prints an error message and kills Emacs. */
12061 x_io_error_quitter (display
)
12066 sprintf (buf
, "Connection lost to X server `%s'", DisplayString (display
));
12067 x_connection_closed (display
, buf
);
12071 /* Changing the font of the frame. */
12073 /* Give frame F the font named FONTNAME as its default font, and
12074 return the full name of that font. FONTNAME may be a wildcard
12075 pattern; in that case, we choose some font that fits the pattern.
12076 The return value shows which font we chose. */
12079 x_new_font (f
, fontname
)
12081 register char *fontname
;
12083 struct font_info
*fontp
12084 = FS_LOAD_FONT (f
, 0, fontname
, -1);
12089 f
->output_data
.x
->font
= (XFontStruct
*) (fontp
->font
);
12090 f
->output_data
.x
->baseline_offset
= fontp
->baseline_offset
;
12091 f
->output_data
.x
->fontset
= -1;
12093 /* Compute the scroll bar width in character columns. */
12094 if (f
->scroll_bar_pixel_width
> 0)
12096 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
12097 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
12101 int wid
= FONT_WIDTH (f
->output_data
.x
->font
);
12102 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
12105 /* Now make the frame display the given font. */
12106 if (FRAME_X_WINDOW (f
) != 0)
12108 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->normal_gc
,
12109 f
->output_data
.x
->font
->fid
);
12110 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->reverse_gc
,
12111 f
->output_data
.x
->font
->fid
);
12112 XSetFont (FRAME_X_DISPLAY (f
), f
->output_data
.x
->cursor_gc
,
12113 f
->output_data
.x
->font
->fid
);
12115 frame_update_line_height (f
);
12117 /* Don't change the size of a tip frame; there's no point in
12118 doing it because it's done in Fx_show_tip, and it leads to
12119 problems because the tip frame has no widget. */
12120 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
12121 x_set_window_size (f
, 0, f
->width
, f
->height
);
12124 /* If we are setting a new frame's font for the first time,
12125 there are no faces yet, so this font's height is the line height. */
12126 f
->output_data
.x
->line_height
= FONT_HEIGHT (f
->output_data
.x
->font
);
12128 return build_string (fontp
->full_name
);
12131 /* Give frame F the fontset named FONTSETNAME as its default font, and
12132 return the full name of that fontset. FONTSETNAME may be a wildcard
12133 pattern; in that case, we choose some fontset that fits the pattern.
12134 The return value shows which fontset we chose. */
12137 x_new_fontset (f
, fontsetname
)
12141 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
12142 Lisp_Object result
;
12147 if (f
->output_data
.x
->fontset
== fontset
)
12148 /* This fontset is already set in frame F. There's nothing more
12150 return fontset_name (fontset
);
12152 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
12154 if (!STRINGP (result
))
12155 /* Can't load ASCII font. */
12158 /* Since x_new_font doesn't update any fontset information, do it now. */
12159 f
->output_data
.x
->fontset
= fontset
;
12163 && (FRAME_XIC_STYLE (f
) & (XIMPreeditPosition
| XIMStatusArea
)))
12164 xic_set_xfontset (f
, XSTRING (fontset_ascii (fontset
))->data
);
12167 return build_string (fontsetname
);
12171 /***********************************************************************
12173 ***********************************************************************/
12179 /* XIM destroy callback function, which is called whenever the
12180 connection to input method XIM dies. CLIENT_DATA contains a
12181 pointer to the x_display_info structure corresponding to XIM. */
12184 xim_destroy_callback (xim
, client_data
, call_data
)
12186 XPointer client_data
;
12187 XPointer call_data
;
12189 struct x_display_info
*dpyinfo
= (struct x_display_info
*) client_data
;
12190 Lisp_Object frame
, tail
;
12194 /* No need to call XDestroyIC.. */
12195 FOR_EACH_FRAME (tail
, frame
)
12197 struct frame
*f
= XFRAME (frame
);
12198 if (FRAME_X_DISPLAY_INFO (f
) == dpyinfo
)
12200 FRAME_XIC (f
) = NULL
;
12201 if (FRAME_XIC_FONTSET (f
))
12203 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
12204 FRAME_XIC_FONTSET (f
) = NULL
;
12209 /* No need to call XCloseIM. */
12210 dpyinfo
->xim
= NULL
;
12211 XFree (dpyinfo
->xim_styles
);
12215 #endif /* HAVE_X11R6 */
12217 /* Open the connection to the XIM server on display DPYINFO.
12218 RESOURCE_NAME is the resource name Emacs uses. */
12221 xim_open_dpy (dpyinfo
, resource_name
)
12222 struct x_display_info
*dpyinfo
;
12223 char *resource_name
;
12228 xim
= XOpenIM (dpyinfo
->display
, dpyinfo
->xrdb
, resource_name
, EMACS_CLASS
);
12229 dpyinfo
->xim
= xim
;
12234 XIMCallback destroy
;
12237 /* Get supported styles and XIM values. */
12238 XGetIMValues (xim
, XNQueryInputStyle
, &dpyinfo
->xim_styles
, NULL
);
12241 destroy
.callback
= xim_destroy_callback
;
12242 destroy
.client_data
= (XPointer
)dpyinfo
;
12243 /* This isn't prototyped in OSF 5.0. */
12244 XSetIMValues (xim
, XNDestroyCallback
, &destroy
, NULL
);
12248 #else /* not USE_XIM */
12249 dpyinfo
->xim
= NULL
;
12250 #endif /* not USE_XIM */
12254 #ifdef HAVE_X11R6_XIM
12258 struct x_display_info
*dpyinfo
;
12259 char *resource_name
;
12262 /* XIM instantiate callback function, which is called whenever an XIM
12263 server is available. DISPLAY is teh display of the XIM.
12264 CLIENT_DATA contains a pointer to an xim_inst_t structure created
12265 when the callback was registered. */
12268 xim_instantiate_callback (display
, client_data
, call_data
)
12270 XPointer client_data
;
12271 XPointer call_data
;
12273 struct xim_inst_t
*xim_inst
= (struct xim_inst_t
*) client_data
;
12274 struct x_display_info
*dpyinfo
= xim_inst
->dpyinfo
;
12276 /* We don't support multiple XIM connections. */
12280 xim_open_dpy (dpyinfo
, xim_inst
->resource_name
);
12282 /* Create XIC for the existing frames on the same display, as long
12283 as they have no XIC. */
12284 if (dpyinfo
->xim
&& dpyinfo
->reference_count
> 0)
12286 Lisp_Object tail
, frame
;
12289 FOR_EACH_FRAME (tail
, frame
)
12291 struct frame
*f
= XFRAME (frame
);
12293 if (FRAME_X_DISPLAY_INFO (f
) == xim_inst
->dpyinfo
)
12294 if (FRAME_XIC (f
) == NULL
)
12296 create_frame_xic (f
);
12297 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
12298 xic_set_statusarea (f
);
12299 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
12301 struct window
*w
= XWINDOW (f
->selected_window
);
12302 xic_set_preeditarea (w
, w
->cursor
.x
, w
->cursor
.y
);
12311 #endif /* HAVE_X11R6_XIM */
12314 /* Open a connection to the XIM server on display DPYINFO.
12315 RESOURCE_NAME is the resource name for Emacs. On X11R5, open the
12316 connection only at the first time. On X11R6, open the connection
12317 in the XIM instantiate callback function. */
12320 xim_initialize (dpyinfo
, resource_name
)
12321 struct x_display_info
*dpyinfo
;
12322 char *resource_name
;
12325 #ifdef HAVE_X11R6_XIM
12326 struct xim_inst_t
*xim_inst
;
12329 dpyinfo
->xim
= NULL
;
12330 xim_inst
= (struct xim_inst_t
*) xmalloc (sizeof (struct xim_inst_t
));
12331 xim_inst
->dpyinfo
= dpyinfo
;
12332 len
= strlen (resource_name
);
12333 xim_inst
->resource_name
= (char *) xmalloc (len
+ 1);
12334 bcopy (resource_name
, xim_inst
->resource_name
, len
+ 1);
12335 XRegisterIMInstantiateCallback (dpyinfo
->display
, dpyinfo
->xrdb
,
12336 resource_name
, EMACS_CLASS
,
12337 xim_instantiate_callback
,
12338 /* Fixme: This is XPointer in
12339 XFree86 but (XPointer *) on
12340 Tru64, at least. */
12341 (XPointer
) xim_inst
);
12342 #else /* not HAVE_X11R6_XIM */
12343 dpyinfo
->xim
= NULL
;
12344 xim_open_dpy (dpyinfo
, resource_name
);
12345 #endif /* not HAVE_X11R6_XIM */
12347 #else /* not USE_XIM */
12348 dpyinfo
->xim
= NULL
;
12349 #endif /* not USE_XIM */
12353 /* Close the connection to the XIM server on display DPYINFO. */
12356 xim_close_dpy (dpyinfo
)
12357 struct x_display_info
*dpyinfo
;
12360 #ifdef HAVE_X11R6_XIM
12361 if (dpyinfo
->display
)
12362 XUnregisterIMInstantiateCallback (dpyinfo
->display
, dpyinfo
->xrdb
,
12364 xim_instantiate_callback
, NULL
);
12365 #endif /* not HAVE_X11R6_XIM */
12366 if (dpyinfo
->display
)
12367 XCloseIM (dpyinfo
->xim
);
12368 dpyinfo
->xim
= NULL
;
12369 XFree (dpyinfo
->xim_styles
);
12370 #endif /* USE_XIM */
12373 #endif /* not HAVE_X11R6_XIM */
12377 /* Calculate the absolute position in frame F
12378 from its current recorded position values and gravity. */
12381 x_calc_absolute_position (f
)
12385 int win_x
= 0, win_y
= 0;
12386 int flags
= f
->output_data
.x
->size_hint_flags
;
12389 /* We have nothing to do if the current position
12390 is already for the top-left corner. */
12391 if (! ((flags
& XNegative
) || (flags
& YNegative
)))
12394 #ifdef USE_X_TOOLKIT
12395 this_window
= XtWindow (f
->output_data
.x
->widget
);
12397 this_window
= FRAME_X_WINDOW (f
);
12400 /* Find the position of the outside upper-left corner of
12401 the inner window, with respect to the outer window.
12402 But do this only if we will need the results. */
12403 if (f
->output_data
.x
->parent_desc
!= FRAME_X_DISPLAY_INFO (f
)->root_window
)
12408 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
12411 x_clear_errors (FRAME_X_DISPLAY (f
));
12412 XTranslateCoordinates (FRAME_X_DISPLAY (f
),
12414 /* From-window, to-window. */
12416 f
->output_data
.x
->parent_desc
,
12418 /* From-position, to-position. */
12419 0, 0, &win_x
, &win_y
,
12421 /* Child of win. */
12423 if (x_had_errors_p (FRAME_X_DISPLAY (f
)))
12425 Window newroot
, newparent
= 0xdeadbeef;
12426 Window
*newchildren
;
12427 unsigned int nchildren
;
12429 if (! XQueryTree (FRAME_X_DISPLAY (f
), this_window
, &newroot
,
12430 &newparent
, &newchildren
, &nchildren
))
12433 XFree ((char *) newchildren
);
12435 f
->output_data
.x
->parent_desc
= newparent
;
12441 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
12445 /* Treat negative positions as relative to the leftmost bottommost
12446 position that fits on the screen. */
12447 if (flags
& XNegative
)
12448 f
->output_data
.x
->left_pos
= (FRAME_X_DISPLAY_INFO (f
)->width
12449 - 2 * f
->output_data
.x
->border_width
- win_x
12451 + f
->output_data
.x
->left_pos
);
12454 int height
= PIXEL_HEIGHT (f
);
12456 #if defined USE_X_TOOLKIT && defined USE_MOTIF
12457 /* Something is fishy here. When using Motif, starting Emacs with
12458 `-g -0-0', the frame appears too low by a few pixels.
12460 This seems to be so because initially, while Emacs is starting,
12461 the column widget's height and the frame's pixel height are
12462 different. The column widget's height is the right one. In
12463 later invocations, when Emacs is up, the frame's pixel height
12466 It's not obvious where the initial small difference comes from.
12467 2000-12-01, gerd. */
12469 XtVaGetValues (f
->output_data
.x
->column_widget
, XtNheight
, &height
, NULL
);
12472 if (flags
& YNegative
)
12473 f
->output_data
.x
->top_pos
= (FRAME_X_DISPLAY_INFO (f
)->height
12474 - 2 * f
->output_data
.x
->border_width
12477 + f
->output_data
.x
->top_pos
);
12480 /* The left_pos and top_pos
12481 are now relative to the top and left screen edges,
12482 so the flags should correspond. */
12483 f
->output_data
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
12486 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
12487 to really change the position, and 0 when calling from
12488 x_make_frame_visible (in that case, XOFF and YOFF are the current
12489 position values). It is -1 when calling from x_set_frame_parameters,
12490 which means, do adjust for borders but don't change the gravity. */
12493 x_set_offset (f
, xoff
, yoff
, change_gravity
)
12495 register int xoff
, yoff
;
12496 int change_gravity
;
12498 int modified_top
, modified_left
;
12500 if (change_gravity
> 0)
12502 f
->output_data
.x
->top_pos
= yoff
;
12503 f
->output_data
.x
->left_pos
= xoff
;
12504 f
->output_data
.x
->size_hint_flags
&= ~ (XNegative
| YNegative
);
12506 f
->output_data
.x
->size_hint_flags
|= XNegative
;
12508 f
->output_data
.x
->size_hint_flags
|= YNegative
;
12509 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
12511 x_calc_absolute_position (f
);
12514 x_wm_set_size_hint (f
, (long) 0, 0);
12516 modified_left
= f
->output_data
.x
->left_pos
;
12517 modified_top
= f
->output_data
.x
->top_pos
;
12518 #if 0 /* Running on psilocin (Debian), and displaying on the NCD X-terminal,
12519 this seems to be unnecessary and incorrect. rms, 4/17/97. */
12520 /* It is a mystery why we need to add the border_width here
12521 when the frame is already visible, but experiment says we do. */
12522 if (change_gravity
!= 0)
12524 modified_left
+= f
->output_data
.x
->border_width
;
12525 modified_top
+= f
->output_data
.x
->border_width
;
12529 #ifdef USE_X_TOOLKIT
12530 XMoveWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
12531 modified_left
, modified_top
);
12532 #else /* not USE_X_TOOLKIT */
12533 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
12534 modified_left
, modified_top
);
12535 #endif /* not USE_X_TOOLKIT */
12540 /* Change the size of frame F's X window to COLS/ROWS in the case F
12541 doesn't have a widget. If CHANGE_GRAVITY is 1, we change to
12542 top-left-corner window gravity for this size change and subsequent
12543 size changes. Otherwise we leave the window gravity unchanged. */
12546 x_set_window_size_1 (f
, change_gravity
, cols
, rows
)
12548 int change_gravity
;
12551 int pixelwidth
, pixelheight
;
12553 check_frame_size (f
, &rows
, &cols
);
12554 f
->output_data
.x
->vertical_scroll_bar_extra
12555 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
12557 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
12558 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
12559 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.x
->font
)));
12560 f
->output_data
.x
->flags_areas_extra
12561 = FRAME_FLAGS_AREA_WIDTH (f
);
12562 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
12563 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
12565 f
->output_data
.x
->win_gravity
= NorthWestGravity
;
12566 x_wm_set_size_hint (f
, (long) 0, 0);
12568 XSync (FRAME_X_DISPLAY (f
), False
);
12569 XResizeWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
12570 pixelwidth
, pixelheight
);
12572 /* Now, strictly speaking, we can't be sure that this is accurate,
12573 but the window manager will get around to dealing with the size
12574 change request eventually, and we'll hear how it went when the
12575 ConfigureNotify event gets here.
12577 We could just not bother storing any of this information here,
12578 and let the ConfigureNotify event set everything up, but that
12579 might be kind of confusing to the Lisp code, since size changes
12580 wouldn't be reported in the frame parameters until some random
12581 point in the future when the ConfigureNotify event arrives.
12583 We pass 1 for DELAY since we can't run Lisp code inside of
12585 change_frame_size (f
, rows
, cols
, 0, 1, 0);
12586 PIXEL_WIDTH (f
) = pixelwidth
;
12587 PIXEL_HEIGHT (f
) = pixelheight
;
12589 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
12590 receive in the ConfigureNotify event; if we get what we asked
12591 for, then the event won't cause the screen to become garbaged, so
12592 we have to make sure to do it here. */
12593 SET_FRAME_GARBAGED (f
);
12595 XFlush (FRAME_X_DISPLAY (f
));
12599 /* Call this to change the size of frame F's x-window.
12600 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
12601 for this size change and subsequent size changes.
12602 Otherwise we leave the window gravity unchanged. */
12605 x_set_window_size (f
, change_gravity
, cols
, rows
)
12607 int change_gravity
;
12612 #ifdef USE_X_TOOLKIT
12614 if (f
->output_data
.x
->widget
!= NULL
)
12616 /* The x and y position of the widget is clobbered by the
12617 call to XtSetValues within EmacsFrameSetCharSize.
12618 This is a real kludge, but I don't understand Xt so I can't
12619 figure out a correct fix. Can anyone else tell me? -- rms. */
12620 int xpos
= f
->output_data
.x
->widget
->core
.x
;
12621 int ypos
= f
->output_data
.x
->widget
->core
.y
;
12622 EmacsFrameSetCharSize (f
->output_data
.x
->edit_widget
, cols
, rows
);
12623 f
->output_data
.x
->widget
->core
.x
= xpos
;
12624 f
->output_data
.x
->widget
->core
.y
= ypos
;
12627 x_set_window_size_1 (f
, change_gravity
, cols
, rows
);
12629 #else /* not USE_X_TOOLKIT */
12631 x_set_window_size_1 (f
, change_gravity
, cols
, rows
);
12633 #endif /* not USE_X_TOOLKIT */
12635 /* If cursor was outside the new size, mark it as off. */
12636 mark_window_cursors_off (XWINDOW (f
->root_window
));
12638 /* Clear out any recollection of where the mouse highlighting was,
12639 since it might be in a place that's outside the new frame size.
12640 Actually checking whether it is outside is a pain in the neck,
12641 so don't try--just let the highlighting be done afresh with new size. */
12642 cancel_mouse_face (f
);
12647 /* Mouse warping. */
12650 x_set_mouse_position (f
, x
, y
)
12656 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.x
->font
) / 2;
12657 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.x
->line_height
/ 2;
12659 if (pix_x
< 0) pix_x
= 0;
12660 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
12662 if (pix_y
< 0) pix_y
= 0;
12663 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
12667 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
12668 0, 0, 0, 0, pix_x
, pix_y
);
12672 /* Move the mouse to position pixel PIX_X, PIX_Y relative to frame F. */
12675 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
12681 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
12682 0, 0, 0, 0, pix_x
, pix_y
);
12686 /* focus shifting, raising and lowering. */
12689 x_focus_on_frame (f
)
12692 #if 0 /* This proves to be unpleasant. */
12696 /* I don't think that the ICCCM allows programs to do things like this
12697 without the interaction of the window manager. Whatever you end up
12698 doing with this code, do it to x_unfocus_frame too. */
12699 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
12700 RevertToPointerRoot
, CurrentTime
);
12705 x_unfocus_frame (f
)
12709 /* Look at the remarks in x_focus_on_frame. */
12710 if (FRAME_X_DISPLAY_INFO (f
)->x_focus_frame
== f
)
12711 XSetInputFocus (FRAME_X_DISPLAY (f
), PointerRoot
,
12712 RevertToPointerRoot
, CurrentTime
);
12716 /* Raise frame F. */
12722 if (f
->async_visible
)
12725 #ifdef USE_X_TOOLKIT
12726 XRaiseWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
));
12727 #else /* not USE_X_TOOLKIT */
12728 XRaiseWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12729 #endif /* not USE_X_TOOLKIT */
12730 XFlush (FRAME_X_DISPLAY (f
));
12735 /* Lower frame F. */
12741 if (f
->async_visible
)
12744 #ifdef USE_X_TOOLKIT
12745 XLowerWindow (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
));
12746 #else /* not USE_X_TOOLKIT */
12747 XLowerWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12748 #endif /* not USE_X_TOOLKIT */
12749 XFlush (FRAME_X_DISPLAY (f
));
12755 XTframe_raise_lower (f
, raise_flag
)
12765 /* Change of visibility. */
12767 /* This tries to wait until the frame is really visible.
12768 However, if the window manager asks the user where to position
12769 the frame, this will return before the user finishes doing that.
12770 The frame will not actually be visible at that time,
12771 but it will become visible later when the window manager
12772 finishes with it. */
12775 x_make_frame_visible (f
)
12779 int original_top
, original_left
;
12780 int retry_count
= 2;
12786 type
= x_icon_type (f
);
12788 x_bitmap_icon (f
, type
);
12790 if (! FRAME_VISIBLE_P (f
))
12792 /* We test FRAME_GARBAGED_P here to make sure we don't
12793 call x_set_offset a second time
12794 if we get to x_make_frame_visible a second time
12795 before the window gets really visible. */
12796 if (! FRAME_ICONIFIED_P (f
)
12797 && ! f
->output_data
.x
->asked_for_visible
)
12798 x_set_offset (f
, f
->output_data
.x
->left_pos
, f
->output_data
.x
->top_pos
, 0);
12800 f
->output_data
.x
->asked_for_visible
= 1;
12802 if (! EQ (Vx_no_window_manager
, Qt
))
12803 x_wm_set_window_state (f
, NormalState
);
12804 #ifdef USE_X_TOOLKIT
12805 /* This was XtPopup, but that did nothing for an iconified frame. */
12806 XtMapWidget (f
->output_data
.x
->widget
);
12807 #else /* not USE_X_TOOLKIT */
12808 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12809 #endif /* not USE_X_TOOLKIT */
12810 #if 0 /* This seems to bring back scroll bars in the wrong places
12811 if the window configuration has changed. They seem
12812 to come back ok without this. */
12813 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
12814 XMapSubwindows (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
12818 XFlush (FRAME_X_DISPLAY (f
));
12820 /* Synchronize to ensure Emacs knows the frame is visible
12821 before we do anything else. We do this loop with input not blocked
12822 so that incoming events are handled. */
12826 /* This must be before UNBLOCK_INPUT
12827 since events that arrive in response to the actions above
12828 will set it when they are handled. */
12829 int previously_visible
= f
->output_data
.x
->has_been_visible
;
12831 original_left
= f
->output_data
.x
->left_pos
;
12832 original_top
= f
->output_data
.x
->top_pos
;
12834 /* This must come after we set COUNT. */
12837 /* We unblock here so that arriving X events are processed. */
12839 /* Now move the window back to where it was "supposed to be".
12840 But don't do it if the gravity is negative.
12841 When the gravity is negative, this uses a position
12842 that is 3 pixels too low. Perhaps that's really the border width.
12844 Don't do this if the window has never been visible before,
12845 because the window manager may choose the position
12846 and we don't want to override it. */
12848 if (! FRAME_VISIBLE_P (f
) && ! FRAME_ICONIFIED_P (f
)
12849 && f
->output_data
.x
->win_gravity
== NorthWestGravity
12850 && previously_visible
)
12854 unsigned int width
, height
, border
, depth
;
12858 /* On some window managers (such as FVWM) moving an existing
12859 window, even to the same place, causes the window manager
12860 to introduce an offset. This can cause the window to move
12861 to an unexpected location. Check the geometry (a little
12862 slow here) and then verify that the window is in the right
12863 place. If the window is not in the right place, move it
12864 there, and take the potential window manager hit. */
12865 XGetGeometry (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
12866 &rootw
, &x
, &y
, &width
, &height
, &border
, &depth
);
12868 if (original_left
!= x
|| original_top
!= y
)
12869 XMoveWindow (FRAME_X_DISPLAY (f
), FRAME_OUTER_WINDOW (f
),
12870 original_left
, original_top
);
12875 XSETFRAME (frame
, f
);
12877 /* Wait until the frame is visible. Process X events until a
12878 MapNotify event has been seen, or until we think we won't get a
12879 MapNotify at all.. */
12880 for (count
= input_signal_count
+ 10;
12881 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
12883 /* Force processing of queued events. */
12886 /* Machines that do polling rather than SIGIO have been
12887 observed to go into a busy-wait here. So we'll fake an
12888 alarm signal to let the handler know that there's something
12889 to be read. We used to raise a real alarm, but it seems
12890 that the handler isn't always enabled here. This is
12892 if (input_polling_used ())
12894 /* It could be confusing if a real alarm arrives while
12895 processing the fake one. Turn it off and let the
12896 handler reset it. */
12897 extern void poll_for_input_1
P_ ((void));
12898 int old_poll_suppress_count
= poll_suppress_count
;
12899 poll_suppress_count
= 1;
12900 poll_for_input_1 ();
12901 poll_suppress_count
= old_poll_suppress_count
;
12904 /* See if a MapNotify event has been processed. */
12905 FRAME_SAMPLE_VISIBILITY (f
);
12910 (let ((f (selected-frame)))
12914 the frame is not raised with various window managers on
12915 FreeBSD, Linux and Solaris. It turns out that, for some
12916 unknown reason, the call to XtMapWidget is completely ignored.
12917 Mapping the widget a second time works. */
12919 if (!FRAME_VISIBLE_P (f
) && --retry_count
> 0)
12924 /* Change from mapped state to withdrawn state. */
12926 /* Make the frame visible (mapped and not iconified). */
12929 x_make_frame_invisible (f
)
12934 #ifdef USE_X_TOOLKIT
12935 /* Use the frame's outermost window, not the one we normally draw on. */
12936 window
= XtWindow (f
->output_data
.x
->widget
);
12937 #else /* not USE_X_TOOLKIT */
12938 window
= FRAME_X_WINDOW (f
);
12939 #endif /* not USE_X_TOOLKIT */
12941 /* Don't keep the highlight on an invisible frame. */
12942 if (FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
12943 FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
12945 #if 0/* This might add unreliability; I don't trust it -- rms. */
12946 if (! f
->async_visible
&& ! f
->async_iconified
)
12952 /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
12953 that the current position of the window is user-specified, rather than
12954 program-specified, so that when the window is mapped again, it will be
12955 placed at the same location, without forcing the user to position it
12956 by hand again (they have already done that once for this window.) */
12957 x_wm_set_size_hint (f
, (long) 0, 1);
12961 if (! XWithdrawWindow (FRAME_X_DISPLAY (f
), window
,
12962 DefaultScreen (FRAME_X_DISPLAY (f
))))
12964 UNBLOCK_INPUT_RESIGNAL
;
12965 error ("Can't notify window manager of window withdrawal");
12967 #else /* ! defined (HAVE_X11R4) */
12969 /* Tell the window manager what we're going to do. */
12970 if (! EQ (Vx_no_window_manager
, Qt
))
12974 unmap
.xunmap
.type
= UnmapNotify
;
12975 unmap
.xunmap
.window
= window
;
12976 unmap
.xunmap
.event
= DefaultRootWindow (FRAME_X_DISPLAY (f
));
12977 unmap
.xunmap
.from_configure
= False
;
12978 if (! XSendEvent (FRAME_X_DISPLAY (f
),
12979 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
12981 SubstructureRedirectMaskSubstructureNotifyMask
,
12984 UNBLOCK_INPUT_RESIGNAL
;
12985 error ("Can't notify window manager of withdrawal");
12989 /* Unmap the window ourselves. Cheeky! */
12990 XUnmapWindow (FRAME_X_DISPLAY (f
), window
);
12991 #endif /* ! defined (HAVE_X11R4) */
12993 /* We can't distinguish this from iconification
12994 just by the event that we get from the server.
12995 So we can't win using the usual strategy of letting
12996 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
12997 and synchronize with the server to make sure we agree. */
12999 FRAME_ICONIFIED_P (f
) = 0;
13000 f
->async_visible
= 0;
13001 f
->async_iconified
= 0;
13008 /* Change window state from mapped to iconified. */
13011 x_iconify_frame (f
)
13017 /* Don't keep the highlight on an invisible frame. */
13018 if (FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
13019 FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
13021 if (f
->async_iconified
)
13026 FRAME_SAMPLE_VISIBILITY (f
);
13028 type
= x_icon_type (f
);
13030 x_bitmap_icon (f
, type
);
13032 #ifdef USE_X_TOOLKIT
13034 if (! FRAME_VISIBLE_P (f
))
13036 if (! EQ (Vx_no_window_manager
, Qt
))
13037 x_wm_set_window_state (f
, IconicState
);
13038 /* This was XtPopup, but that did nothing for an iconified frame. */
13039 XtMapWidget (f
->output_data
.x
->widget
);
13040 /* The server won't give us any event to indicate
13041 that an invisible frame was changed to an icon,
13042 so we have to record it here. */
13045 f
->async_iconified
= 1;
13046 f
->async_visible
= 0;
13051 result
= XIconifyWindow (FRAME_X_DISPLAY (f
),
13052 XtWindow (f
->output_data
.x
->widget
),
13053 DefaultScreen (FRAME_X_DISPLAY (f
)));
13057 error ("Can't notify window manager of iconification");
13059 f
->async_iconified
= 1;
13060 f
->async_visible
= 0;
13064 XFlush (FRAME_X_DISPLAY (f
));
13066 #else /* not USE_X_TOOLKIT */
13068 /* Make sure the X server knows where the window should be positioned,
13069 in case the user deiconifies with the window manager. */
13070 if (! FRAME_VISIBLE_P (f
) && !FRAME_ICONIFIED_P (f
))
13071 x_set_offset (f
, f
->output_data
.x
->left_pos
, f
->output_data
.x
->top_pos
, 0);
13073 /* Since we don't know which revision of X we're running, we'll use both
13074 the X11R3 and X11R4 techniques. I don't know if this is a good idea. */
13076 /* X11R4: send a ClientMessage to the window manager using the
13077 WM_CHANGE_STATE type. */
13081 message
.xclient
.window
= FRAME_X_WINDOW (f
);
13082 message
.xclient
.type
= ClientMessage
;
13083 message
.xclient
.message_type
= FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_change_state
;
13084 message
.xclient
.format
= 32;
13085 message
.xclient
.data
.l
[0] = IconicState
;
13087 if (! XSendEvent (FRAME_X_DISPLAY (f
),
13088 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
13090 SubstructureRedirectMask
| SubstructureNotifyMask
,
13093 UNBLOCK_INPUT_RESIGNAL
;
13094 error ("Can't notify window manager of iconification");
13098 /* X11R3: set the initial_state field of the window manager hints to
13100 x_wm_set_window_state (f
, IconicState
);
13102 if (!FRAME_VISIBLE_P (f
))
13104 /* If the frame was withdrawn, before, we must map it. */
13105 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
13108 f
->async_iconified
= 1;
13109 f
->async_visible
= 0;
13111 XFlush (FRAME_X_DISPLAY (f
));
13113 #endif /* not USE_X_TOOLKIT */
13117 /* Free X resources of frame F. */
13120 x_free_frame_resources (f
)
13123 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13127 /* If a display connection is dead, don't try sending more
13128 commands to the X server. */
13129 if (dpyinfo
->display
)
13131 if (f
->output_data
.x
->icon_desc
)
13132 XDestroyWindow (FRAME_X_DISPLAY (f
), f
->output_data
.x
->icon_desc
);
13136 free_frame_xic (f
);
13139 if (FRAME_X_WINDOW (f
))
13140 XDestroyWindow (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
13142 #ifdef USE_X_TOOLKIT
13143 if (f
->output_data
.x
->widget
)
13145 XtDestroyWidget (f
->output_data
.x
->widget
);
13146 f
->output_data
.x
->widget
= NULL
;
13148 free_frame_menubar (f
);
13149 #endif /* USE_X_TOOLKIT */
13151 unload_color (f
, f
->output_data
.x
->foreground_pixel
);
13152 unload_color (f
, f
->output_data
.x
->background_pixel
);
13153 unload_color (f
, f
->output_data
.x
->cursor_pixel
);
13154 unload_color (f
, f
->output_data
.x
->cursor_foreground_pixel
);
13155 unload_color (f
, f
->output_data
.x
->border_pixel
);
13156 unload_color (f
, f
->output_data
.x
->mouse_pixel
);
13158 if (f
->output_data
.x
->scroll_bar_background_pixel
!= -1)
13159 unload_color (f
, f
->output_data
.x
->scroll_bar_background_pixel
);
13160 if (f
->output_data
.x
->scroll_bar_foreground_pixel
!= -1)
13161 unload_color (f
, f
->output_data
.x
->scroll_bar_foreground_pixel
);
13162 #ifdef USE_TOOLKIT_SCROLL_BARS
13163 /* Scrollbar shadow colors. */
13164 if (f
->output_data
.x
->scroll_bar_top_shadow_pixel
!= -1)
13165 unload_color (f
, f
->output_data
.x
->scroll_bar_top_shadow_pixel
);
13166 if (f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
!= -1)
13167 unload_color (f
, f
->output_data
.x
->scroll_bar_bottom_shadow_pixel
);
13168 #endif /* USE_TOOLKIT_SCROLL_BARS */
13169 if (f
->output_data
.x
->white_relief
.allocated_p
)
13170 unload_color (f
, f
->output_data
.x
->white_relief
.pixel
);
13171 if (f
->output_data
.x
->black_relief
.allocated_p
)
13172 unload_color (f
, f
->output_data
.x
->black_relief
.pixel
);
13174 if (FRAME_FACE_CACHE (f
))
13175 free_frame_faces (f
);
13178 XFlush (FRAME_X_DISPLAY (f
));
13181 if (f
->output_data
.x
->saved_menu_event
)
13182 xfree (f
->output_data
.x
->saved_menu_event
);
13184 xfree (f
->output_data
.x
);
13185 f
->output_data
.x
= NULL
;
13187 if (f
== dpyinfo
->x_focus_frame
)
13188 dpyinfo
->x_focus_frame
= 0;
13189 if (f
== dpyinfo
->x_focus_event_frame
)
13190 dpyinfo
->x_focus_event_frame
= 0;
13191 if (f
== dpyinfo
->x_highlight_frame
)
13192 dpyinfo
->x_highlight_frame
= 0;
13194 if (f
== dpyinfo
->mouse_face_mouse_frame
)
13196 dpyinfo
->mouse_face_beg_row
13197 = dpyinfo
->mouse_face_beg_col
= -1;
13198 dpyinfo
->mouse_face_end_row
13199 = dpyinfo
->mouse_face_end_col
= -1;
13200 dpyinfo
->mouse_face_window
= Qnil
;
13201 dpyinfo
->mouse_face_deferred_gc
= 0;
13202 dpyinfo
->mouse_face_mouse_frame
= 0;
13209 /* Destroy the X window of frame F. */
13212 x_destroy_window (f
)
13215 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13217 /* If a display connection is dead, don't try sending more
13218 commands to the X server. */
13219 if (dpyinfo
->display
!= 0)
13220 x_free_frame_resources (f
);
13222 dpyinfo
->reference_count
--;
13226 /* Setting window manager hints. */
13228 /* Set the normal size hints for the window manager, for frame F.
13229 FLAGS is the flags word to use--or 0 meaning preserve the flags
13230 that the window now has.
13231 If USER_POSITION is nonzero, we set the USPosition
13232 flag (this is useful when FLAGS is 0). */
13235 x_wm_set_size_hint (f
, flags
, user_position
)
13240 XSizeHints size_hints
;
13242 #ifdef USE_X_TOOLKIT
13245 Dimension widget_width
, widget_height
;
13246 Window window
= XtWindow (f
->output_data
.x
->widget
);
13247 #else /* not USE_X_TOOLKIT */
13248 Window window
= FRAME_X_WINDOW (f
);
13249 #endif /* not USE_X_TOOLKIT */
13251 /* Setting PMaxSize caused various problems. */
13252 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
13254 size_hints
.x
= f
->output_data
.x
->left_pos
;
13255 size_hints
.y
= f
->output_data
.x
->top_pos
;
13257 #ifdef USE_X_TOOLKIT
13258 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
13259 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
13260 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
13261 size_hints
.height
= widget_height
;
13262 size_hints
.width
= widget_width
;
13263 #else /* not USE_X_TOOLKIT */
13264 size_hints
.height
= PIXEL_HEIGHT (f
);
13265 size_hints
.width
= PIXEL_WIDTH (f
);
13266 #endif /* not USE_X_TOOLKIT */
13268 size_hints
.width_inc
= FONT_WIDTH (f
->output_data
.x
->font
);
13269 size_hints
.height_inc
= f
->output_data
.x
->line_height
;
13270 size_hints
.max_width
13271 = FRAME_X_DISPLAY_INFO (f
)->width
- CHAR_TO_PIXEL_WIDTH (f
, 0);
13272 size_hints
.max_height
13273 = FRAME_X_DISPLAY_INFO (f
)->height
- CHAR_TO_PIXEL_HEIGHT (f
, 0);
13275 /* Calculate the base and minimum sizes.
13277 (When we use the X toolkit, we don't do it here.
13278 Instead we copy the values that the widgets are using, below.) */
13279 #ifndef USE_X_TOOLKIT
13281 int base_width
, base_height
;
13282 int min_rows
= 0, min_cols
= 0;
13284 base_width
= CHAR_TO_PIXEL_WIDTH (f
, 0);
13285 base_height
= CHAR_TO_PIXEL_HEIGHT (f
, 0);
13287 check_frame_size (f
, &min_rows
, &min_cols
);
13289 /* The window manager uses the base width hints to calculate the
13290 current number of rows and columns in the frame while
13291 resizing; min_width and min_height aren't useful for this
13292 purpose, since they might not give the dimensions for a
13293 zero-row, zero-column frame.
13295 We use the base_width and base_height members if we have
13296 them; otherwise, we set the min_width and min_height members
13297 to the size for a zero x zero frame. */
13300 size_hints
.flags
|= PBaseSize
;
13301 size_hints
.base_width
= base_width
;
13302 size_hints
.base_height
= base_height
;
13303 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
13304 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
13306 size_hints
.min_width
= base_width
;
13307 size_hints
.min_height
= base_height
;
13311 /* If we don't need the old flags, we don't need the old hint at all. */
13314 size_hints
.flags
|= flags
;
13317 #endif /* not USE_X_TOOLKIT */
13320 XSizeHints hints
; /* Sometimes I hate X Windows... */
13321 long supplied_return
;
13325 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
13328 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
13331 #ifdef USE_X_TOOLKIT
13332 size_hints
.base_height
= hints
.base_height
;
13333 size_hints
.base_width
= hints
.base_width
;
13334 size_hints
.min_height
= hints
.min_height
;
13335 size_hints
.min_width
= hints
.min_width
;
13339 size_hints
.flags
|= flags
;
13344 if (hints
.flags
& PSize
)
13345 size_hints
.flags
|= PSize
;
13346 if (hints
.flags
& PPosition
)
13347 size_hints
.flags
|= PPosition
;
13348 if (hints
.flags
& USPosition
)
13349 size_hints
.flags
|= USPosition
;
13350 if (hints
.flags
& USSize
)
13351 size_hints
.flags
|= USSize
;
13355 #ifndef USE_X_TOOLKIT
13360 size_hints
.win_gravity
= f
->output_data
.x
->win_gravity
;
13361 size_hints
.flags
|= PWinGravity
;
13365 size_hints
.flags
&= ~ PPosition
;
13366 size_hints
.flags
|= USPosition
;
13368 #endif /* PWinGravity */
13371 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
13373 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
13377 /* Used for IconicState or NormalState */
13380 x_wm_set_window_state (f
, state
)
13384 #ifdef USE_X_TOOLKIT
13387 XtSetArg (al
[0], XtNinitialState
, state
);
13388 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
13389 #else /* not USE_X_TOOLKIT */
13390 Window window
= FRAME_X_WINDOW (f
);
13392 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
13393 f
->output_data
.x
->wm_hints
.initial_state
= state
;
13395 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
13396 #endif /* not USE_X_TOOLKIT */
13400 x_wm_set_icon_pixmap (f
, pixmap_id
)
13404 Pixmap icon_pixmap
;
13406 #ifndef USE_X_TOOLKIT
13407 Window window
= FRAME_X_WINDOW (f
);
13412 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
13413 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
13417 /* It seems there is no way to turn off use of an icon pixmap.
13418 The following line does it, only if no icon has yet been created,
13419 for some window managers. But with mwm it crashes.
13420 Some people say it should clear the IconPixmapHint bit in this case,
13421 but that doesn't work, and the X consortium said it isn't the
13422 right thing at all. Since there is no way to win,
13423 best to explicitly give up. */
13425 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
13431 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
13435 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
13436 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
13439 #else /* not USE_X_TOOLKIT */
13441 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
13442 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
13444 #endif /* not USE_X_TOOLKIT */
13448 x_wm_set_icon_position (f
, icon_x
, icon_y
)
13450 int icon_x
, icon_y
;
13452 #ifdef USE_X_TOOLKIT
13453 Window window
= XtWindow (f
->output_data
.x
->widget
);
13455 Window window
= FRAME_X_WINDOW (f
);
13458 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
13459 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
13460 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
13462 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
13466 /***********************************************************************
13468 ***********************************************************************/
13470 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
13473 x_get_font_info (f
, font_idx
)
13477 return (FRAME_X_FONT_TABLE (f
) + font_idx
);
13481 /* Return a list of names of available fonts matching PATTERN on frame F.
13483 If SIZE is > 0, it is the size (maximum bounds width) of fonts
13486 SIZE < 0 means include scalable fonts.
13488 Frame F null means we have not yet created any frame on X, and
13489 consult the first display in x_display_list. MAXNAMES sets a limit
13490 on how many fonts to match. */
13493 x_list_fonts (f
, pattern
, size
, maxnames
)
13495 Lisp_Object pattern
;
13499 Lisp_Object list
= Qnil
, patterns
, newlist
= Qnil
, key
= Qnil
;
13500 Lisp_Object tem
, second_best
;
13501 struct x_display_info
*dpyinfo
13502 = f
? FRAME_X_DISPLAY_INFO (f
) : x_display_list
;
13503 Display
*dpy
= dpyinfo
->display
;
13504 int try_XLoadQueryFont
= 0;
13506 int allow_scalable_fonts_p
= 0;
13510 allow_scalable_fonts_p
= 1;
13514 patterns
= Fassoc (pattern
, Valternate_fontname_alist
);
13515 if (NILP (patterns
))
13516 patterns
= Fcons (pattern
, Qnil
);
13518 if (maxnames
== 1 && !size
)
13519 /* We can return any single font matching PATTERN. */
13520 try_XLoadQueryFont
= 1;
13522 for (; CONSP (patterns
); patterns
= XCDR (patterns
))
13525 char **names
= NULL
;
13527 pattern
= XCAR (patterns
);
13528 /* See if we cached the result for this particular query.
13529 The cache is an alist of the form:
13530 ((((PATTERN . MAXNAMES) . SCALABLE) (FONTNAME . WIDTH) ...) ...) */
13531 tem
= XCDR (dpyinfo
->name_list_element
);
13532 key
= Fcons (Fcons (pattern
, make_number (maxnames
)),
13533 allow_scalable_fonts_p
? Qt
: Qnil
);
13534 list
= Fassoc (key
, tem
);
13537 list
= Fcdr_safe (list
);
13538 /* We have a cashed list. Don't have to get the list again. */
13542 /* At first, put PATTERN in the cache. */
13545 count
= x_catch_errors (dpy
);
13547 if (try_XLoadQueryFont
)
13550 unsigned long value
;
13552 font
= XLoadQueryFont (dpy
, XSTRING (pattern
)->data
);
13553 if (x_had_errors_p (dpy
))
13555 /* This error is perhaps due to insufficient memory on X
13556 server. Let's just ignore it. */
13558 x_clear_errors (dpy
);
13562 && XGetFontProperty (font
, XA_FONT
, &value
))
13564 char *name
= (char *) XGetAtomName (dpy
, (Atom
) value
);
13565 int len
= strlen (name
);
13568 /* If DXPC (a Differential X Protocol Compressor)
13569 Ver.3.7 is running, XGetAtomName will return null
13570 string. We must avoid such a name. */
13572 try_XLoadQueryFont
= 0;
13576 names
= (char **) alloca (sizeof (char *));
13577 /* Some systems only allow alloca assigned to a
13579 tmp
= (char *) alloca (len
+ 1); names
[0] = tmp
;
13580 bcopy (name
, names
[0], len
+ 1);
13585 try_XLoadQueryFont
= 0;
13588 XFreeFont (dpy
, font
);
13591 if (!try_XLoadQueryFont
)
13593 /* We try at least 10 fonts because XListFonts will return
13594 auto-scaled fonts at the head. */
13595 names
= XListFonts (dpy
, XSTRING (pattern
)->data
, max (maxnames
, 10),
13597 if (x_had_errors_p (dpy
))
13599 /* This error is perhaps due to insufficient memory on X
13600 server. Let's just ignore it. */
13602 x_clear_errors (dpy
);
13606 x_uncatch_errors (dpy
, count
);
13613 /* Make a list of all the fonts we got back.
13614 Store that in the font cache for the display. */
13615 for (i
= 0; i
< num_fonts
; i
++)
13618 char *p
= names
[i
];
13619 int average_width
= -1, dashes
= 0;
13621 /* Count the number of dashes in NAMES[I]. If there are
13622 14 dashes, and the field value following 12th dash
13623 (AVERAGE_WIDTH) is 0, this is a auto-scaled font which
13624 is usually too ugly to be used for editing. Let's
13630 if (dashes
== 7) /* PIXEL_SIZE field */
13632 else if (dashes
== 12) /* AVERAGE_WIDTH field */
13633 average_width
= atoi (p
);
13636 if (allow_scalable_fonts_p
13637 || dashes
< 14 || average_width
!= 0)
13639 tem
= build_string (names
[i
]);
13640 if (NILP (Fassoc (tem
, list
)))
13642 if (STRINGP (Vx_pixel_size_width_font_regexp
)
13643 && ((fast_c_string_match_ignore_case
13644 (Vx_pixel_size_width_font_regexp
, names
[i
]))
13646 /* We can set the value of PIXEL_SIZE to the
13647 width of this font. */
13648 list
= Fcons (Fcons (tem
, make_number (width
)), list
);
13650 /* For the moment, width is not known. */
13651 list
= Fcons (Fcons (tem
, Qnil
), list
);
13656 if (!try_XLoadQueryFont
)
13659 XFreeFontNames (names
);
13664 /* Now store the result in the cache. */
13665 XSETCDR (dpyinfo
->name_list_element
,
13666 Fcons (Fcons (key
, list
), XCDR (dpyinfo
->name_list_element
)));
13669 if (NILP (list
)) continue; /* Try the remaining alternatives. */
13671 newlist
= second_best
= Qnil
;
13672 /* Make a list of the fonts that have the right width. */
13673 for (; CONSP (list
); list
= XCDR (list
))
13679 if (!CONSP (tem
) || NILP (XCAR (tem
)))
13683 newlist
= Fcons (XCAR (tem
), newlist
);
13687 if (!INTEGERP (XCDR (tem
)))
13689 /* Since we have not yet known the size of this font, we
13690 must try slow function call XLoadQueryFont. */
13691 XFontStruct
*thisinfo
;
13694 count
= x_catch_errors (dpy
);
13695 thisinfo
= XLoadQueryFont (dpy
,
13696 XSTRING (XCAR (tem
))->data
);
13697 if (x_had_errors_p (dpy
))
13699 /* This error is perhaps due to insufficient memory on X
13700 server. Let's just ignore it. */
13702 x_clear_errors (dpy
);
13704 x_uncatch_errors (dpy
, count
);
13710 (thisinfo
->min_bounds
.width
== 0
13712 : make_number (thisinfo
->max_bounds
.width
)));
13714 XFreeFont (dpy
, thisinfo
);
13718 /* For unknown reason, the previous call of XListFont had
13719 returned a font which can't be opened. Record the size
13720 as 0 not to try to open it again. */
13721 XSETCDR (tem
, make_number (0));
13724 found_size
= XINT (XCDR (tem
));
13725 if (found_size
== size
)
13726 newlist
= Fcons (XCAR (tem
), newlist
);
13727 else if (found_size
> 0)
13729 if (NILP (second_best
))
13731 else if (found_size
< size
)
13733 if (XINT (XCDR (second_best
)) > size
13734 || XINT (XCDR (second_best
)) < found_size
)
13739 if (XINT (XCDR (second_best
)) > size
13740 && XINT (XCDR (second_best
)) > found_size
)
13745 if (!NILP (newlist
))
13747 else if (!NILP (second_best
))
13749 newlist
= Fcons (XCAR (second_best
), Qnil
);
13760 /* Check that FONT is valid on frame F. It is if it can be found in F's
13764 x_check_font (f
, font
)
13769 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13771 xassert (font
!= NULL
);
13773 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
13774 if (dpyinfo
->font_table
[i
].name
13775 && font
== dpyinfo
->font_table
[i
].font
)
13778 xassert (i
< dpyinfo
->n_fonts
);
13781 #endif /* GLYPH_DEBUG != 0 */
13783 /* Set *W to the minimum width, *H to the minimum font height of FONT.
13784 Note: There are (broken) X fonts out there with invalid XFontStruct
13785 min_bounds contents. For example, handa@etl.go.jp reports that
13786 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
13787 have font->min_bounds.width == 0. */
13790 x_font_min_bounds (font
, w
, h
)
13794 *h
= FONT_HEIGHT (font
);
13795 *w
= font
->min_bounds
.width
;
13797 /* Try to handle the case where FONT->min_bounds has invalid
13798 contents. Since the only font known to have invalid min_bounds
13799 is fixed-width, use max_bounds if min_bounds seems to be invalid. */
13801 *w
= font
->max_bounds
.width
;
13805 /* Compute the smallest character width and smallest font height over
13806 all fonts available on frame F. Set the members smallest_char_width
13807 and smallest_font_height in F's x_display_info structure to
13808 the values computed. Value is non-zero if smallest_font_height or
13809 smallest_char_width become smaller than they were before. */
13812 x_compute_min_glyph_bounds (f
)
13816 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13818 int old_width
= dpyinfo
->smallest_char_width
;
13819 int old_height
= dpyinfo
->smallest_font_height
;
13821 dpyinfo
->smallest_font_height
= 100000;
13822 dpyinfo
->smallest_char_width
= 100000;
13824 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
13825 if (dpyinfo
->font_table
[i
].name
)
13827 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
13830 font
= (XFontStruct
*) fontp
->font
;
13831 xassert (font
!= (XFontStruct
*) ~0);
13832 x_font_min_bounds (font
, &w
, &h
);
13834 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
13835 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
13838 xassert (dpyinfo
->smallest_char_width
> 0
13839 && dpyinfo
->smallest_font_height
> 0);
13841 return (dpyinfo
->n_fonts
== 1
13842 || dpyinfo
->smallest_char_width
< old_width
13843 || dpyinfo
->smallest_font_height
< old_height
);
13847 /* Load font named FONTNAME of the size SIZE for frame F, and return a
13848 pointer to the structure font_info while allocating it dynamically.
13849 If SIZE is 0, load any size of font.
13850 If loading is failed, return NULL. */
13853 x_load_font (f
, fontname
, size
)
13855 register char *fontname
;
13858 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
13859 Lisp_Object font_names
;
13862 /* Get a list of all the fonts that match this name. Once we
13863 have a list of matching fonts, we compare them against the fonts
13864 we already have by comparing names. */
13865 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
13867 if (!NILP (font_names
))
13872 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
13873 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
13874 if (dpyinfo
->font_table
[i
].name
13875 && (!strcmp (dpyinfo
->font_table
[i
].name
,
13876 XSTRING (XCAR (tail
))->data
)
13877 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
13878 XSTRING (XCAR (tail
))->data
)))
13879 return (dpyinfo
->font_table
+ i
);
13882 /* Load the font and add it to the table. */
13886 struct font_info
*fontp
;
13887 unsigned long value
;
13890 /* If we have found fonts by x_list_font, load one of them. If
13891 not, we still try to load a font by the name given as FONTNAME
13892 because XListFonts (called in x_list_font) of some X server has
13893 a bug of not finding a font even if the font surely exists and
13894 is loadable by XLoadQueryFont. */
13895 if (size
> 0 && !NILP (font_names
))
13896 fontname
= (char *) XSTRING (XCAR (font_names
))->data
;
13899 count
= x_catch_errors (FRAME_X_DISPLAY (f
));
13900 font
= (XFontStruct
*) XLoadQueryFont (FRAME_X_DISPLAY (f
), fontname
);
13901 if (x_had_errors_p (FRAME_X_DISPLAY (f
)))
13903 /* This error is perhaps due to insufficient memory on X
13904 server. Let's just ignore it. */
13906 x_clear_errors (FRAME_X_DISPLAY (f
));
13908 x_uncatch_errors (FRAME_X_DISPLAY (f
), count
);
13913 /* Find a free slot in the font table. */
13914 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
13915 if (dpyinfo
->font_table
[i
].name
== NULL
)
13918 /* If no free slot found, maybe enlarge the font table. */
13919 if (i
== dpyinfo
->n_fonts
13920 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
13923 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
13924 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
13925 dpyinfo
->font_table
13926 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
13929 fontp
= dpyinfo
->font_table
+ i
;
13930 if (i
== dpyinfo
->n_fonts
)
13931 ++dpyinfo
->n_fonts
;
13933 /* Now fill in the slots of *FONTP. */
13935 fontp
->font
= font
;
13936 fontp
->font_idx
= i
;
13937 fontp
->name
= (char *) xmalloc (strlen (fontname
) + 1);
13938 bcopy (fontname
, fontp
->name
, strlen (fontname
) + 1);
13940 /* Try to get the full name of FONT. Put it in FULL_NAME. */
13942 if (XGetFontProperty (font
, XA_FONT
, &value
))
13944 char *name
= (char *) XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);
13948 /* Count the number of dashes in the "full name".
13949 If it is too few, this isn't really the font's full name,
13951 In X11R4, the fonts did not come with their canonical names
13962 full_name
= (char *) xmalloc (p
- name
+ 1);
13963 bcopy (name
, full_name
, p
- name
+ 1);
13969 if (full_name
!= 0)
13970 fontp
->full_name
= full_name
;
13972 fontp
->full_name
= fontp
->name
;
13974 fontp
->size
= font
->max_bounds
.width
;
13975 fontp
->height
= FONT_HEIGHT (font
);
13977 if (NILP (font_names
))
13979 /* We come here because of a bug of XListFonts mentioned at
13980 the head of this block. Let's store this information in
13981 the cache for x_list_fonts. */
13982 Lisp_Object lispy_name
= build_string (fontname
);
13983 Lisp_Object lispy_full_name
= build_string (fontp
->full_name
);
13984 Lisp_Object key
= Fcons (Fcons (lispy_name
, make_number (256)),
13987 XSETCDR (dpyinfo
->name_list_element
,
13989 Fcons (Fcons (lispy_full_name
,
13990 make_number (fontp
->size
)),
13992 XCDR (dpyinfo
->name_list_element
)));
13995 key
= Fcons (Fcons (lispy_full_name
, make_number (256)),
13997 XSETCDR (dpyinfo
->name_list_element
,
13999 Fcons (Fcons (lispy_full_name
,
14000 make_number (fontp
->size
)),
14002 XCDR (dpyinfo
->name_list_element
)));
14006 /* The slot `encoding' specifies how to map a character
14007 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
14008 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
14009 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
14010 2:0xA020..0xFF7F). For the moment, we don't know which charset
14011 uses this font. So, we set information in fontp->encoding[1]
14012 which is never used by any charset. If mapping can't be
14013 decided, set FONT_ENCODING_NOT_DECIDED. */
14015 = (font
->max_byte1
== 0
14017 ? (font
->min_char_or_byte2
< 0x80
14018 ? (font
->max_char_or_byte2
< 0x80
14019 ? 0 /* 0x20..0x7F */
14020 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
14021 : 1) /* 0xA0..0xFF */
14023 : (font
->min_byte1
< 0x80
14024 ? (font
->max_byte1
< 0x80
14025 ? (font
->min_char_or_byte2
< 0x80
14026 ? (font
->max_char_or_byte2
< 0x80
14027 ? 0 /* 0x2020..0x7F7F */
14028 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
14029 : 3) /* 0x20A0..0x7FFF */
14030 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
14031 : (font
->min_char_or_byte2
< 0x80
14032 ? (font
->max_char_or_byte2
< 0x80
14033 ? 2 /* 0xA020..0xFF7F */
14034 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
14035 : 1))); /* 0xA0A0..0xFFFF */
14037 fontp
->baseline_offset
14038 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
14039 ? (long) value
: 0);
14040 fontp
->relative_compose
14041 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
14042 ? (long) value
: 0);
14043 fontp
->default_ascent
14044 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
14045 ? (long) value
: 0);
14047 /* Set global flag fonts_changed_p to non-zero if the font loaded
14048 has a character with a smaller width than any other character
14049 before, or if the font loaded has a smalle>r height than any
14050 other font loaded before. If this happens, it will make a
14051 glyph matrix reallocation necessary. */
14052 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
14059 /* Return a pointer to struct font_info of a font named FONTNAME for
14060 frame F. If no such font is loaded, return NULL. */
14063 x_query_font (f
, fontname
)
14065 register char *fontname
;
14067 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
14070 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
14071 if (dpyinfo
->font_table
[i
].name
14072 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
14073 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
14074 return (dpyinfo
->font_table
+ i
);
14079 /* Find a CCL program for a font specified by FONTP, and set the member
14080 `encoder' of the structure. */
14083 x_find_ccl_program (fontp
)
14084 struct font_info
*fontp
;
14086 Lisp_Object list
, elt
;
14089 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
14093 && STRINGP (XCAR (elt
))
14094 && ((fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
14096 || (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->full_name
)
14103 struct ccl_program
*ccl
14104 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
14106 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
14109 fontp
->font_encoder
= ccl
;
14115 /***********************************************************************
14117 ***********************************************************************/
14119 #ifdef USE_X_TOOLKIT
14120 static XrmOptionDescRec emacs_options
[] = {
14121 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
14122 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
14124 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
14125 XrmoptionSepArg
, NULL
},
14126 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
14128 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
14129 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
14130 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
14131 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
14132 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
14133 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
14134 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
14136 #endif /* USE_X_TOOLKIT */
14138 static int x_initialized
;
14140 #ifdef MULTI_KBOARD
14141 /* Test whether two display-name strings agree up to the dot that separates
14142 the screen number from the server number. */
14144 same_x_server (name1
, name2
)
14145 char *name1
, *name2
;
14147 int seen_colon
= 0;
14148 unsigned char *system_name
= XSTRING (Vsystem_name
)->data
;
14149 int system_name_length
= strlen (system_name
);
14150 int length_until_period
= 0;
14152 while (system_name
[length_until_period
] != 0
14153 && system_name
[length_until_period
] != '.')
14154 length_until_period
++;
14156 /* Treat `unix' like an empty host name. */
14157 if (! strncmp (name1
, "unix:", 5))
14159 if (! strncmp (name2
, "unix:", 5))
14161 /* Treat this host's name like an empty host name. */
14162 if (! strncmp (name1
, system_name
, system_name_length
)
14163 && name1
[system_name_length
] == ':')
14164 name1
+= system_name_length
;
14165 if (! strncmp (name2
, system_name
, system_name_length
)
14166 && name2
[system_name_length
] == ':')
14167 name2
+= system_name_length
;
14168 /* Treat this host's domainless name like an empty host name. */
14169 if (! strncmp (name1
, system_name
, length_until_period
)
14170 && name1
[length_until_period
] == ':')
14171 name1
+= length_until_period
;
14172 if (! strncmp (name2
, system_name
, length_until_period
)
14173 && name2
[length_until_period
] == ':')
14174 name2
+= length_until_period
;
14176 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
14180 if (seen_colon
&& *name1
== '.')
14184 && (*name1
== '.' || *name1
== '\0')
14185 && (*name2
== '.' || *name2
== '\0'));
14189 struct x_display_info
*
14190 x_term_init (display_name
, xrm_option
, resource_name
)
14191 Lisp_Object display_name
;
14193 char *resource_name
;
14197 struct x_display_info
*dpyinfo
;
14202 if (!x_initialized
)
14208 #ifdef USE_X_TOOLKIT
14209 /* weiner@footloose.sps.mot.com reports that this causes
14211 X protocol error: BadAtom (invalid Atom parameter)
14212 on protocol request 18skiloaf.
14213 So let's not use it until R6. */
14214 #ifdef HAVE_X11XTR6
14215 XtSetLanguageProc (NULL
, NULL
, NULL
);
14226 argv
[argc
++] = "-xrm";
14227 argv
[argc
++] = xrm_option
;
14229 dpy
= XtOpenDisplay (Xt_app_con
, XSTRING (display_name
)->data
,
14230 resource_name
, EMACS_CLASS
,
14231 emacs_options
, XtNumber (emacs_options
),
14234 #ifdef HAVE_X11XTR6
14235 /* I think this is to compensate for XtSetLanguageProc. */
14240 #else /* not USE_X_TOOLKIT */
14242 XSetLocaleModifiers ("");
14244 dpy
= XOpenDisplay (XSTRING (display_name
)->data
);
14245 #endif /* not USE_X_TOOLKIT */
14247 /* Detect failure. */
14254 /* We have definitely succeeded. Record the new connection. */
14256 dpyinfo
= (struct x_display_info
*) xmalloc (sizeof (struct x_display_info
));
14257 bzero (dpyinfo
, sizeof *dpyinfo
);
14259 #ifdef MULTI_KBOARD
14261 struct x_display_info
*share
;
14264 for (share
= x_display_list
, tail
= x_display_name_list
; share
;
14265 share
= share
->next
, tail
= XCDR (tail
))
14266 if (same_x_server (XSTRING (XCAR (XCAR (tail
)))->data
,
14267 XSTRING (display_name
)->data
))
14270 dpyinfo
->kboard
= share
->kboard
;
14273 dpyinfo
->kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
14274 init_kboard (dpyinfo
->kboard
);
14275 if (!EQ (XSYMBOL (Qvendor_specific_keysyms
)->function
, Qunbound
))
14277 char *vendor
= ServerVendor (dpy
);
14279 dpyinfo
->kboard
->Vsystem_key_alist
14280 = call1 (Qvendor_specific_keysyms
,
14281 build_string (vendor
? vendor
: ""));
14285 dpyinfo
->kboard
->next_kboard
= all_kboards
;
14286 all_kboards
= dpyinfo
->kboard
;
14287 /* Don't let the initial kboard remain current longer than necessary.
14288 That would cause problems if a file loaded on startup tries to
14289 prompt in the mini-buffer. */
14290 if (current_kboard
== initial_kboard
)
14291 current_kboard
= dpyinfo
->kboard
;
14293 dpyinfo
->kboard
->reference_count
++;
14297 /* Put this display on the chain. */
14298 dpyinfo
->next
= x_display_list
;
14299 x_display_list
= dpyinfo
;
14301 /* Put it on x_display_name_list as well, to keep them parallel. */
14302 x_display_name_list
= Fcons (Fcons (display_name
, Qnil
),
14303 x_display_name_list
);
14304 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
14306 dpyinfo
->display
= dpy
;
14309 XSetAfterFunction (x_current_display
, x_trace_wire
);
14313 = (char *) xmalloc (STRING_BYTES (XSTRING (Vinvocation_name
))
14314 + STRING_BYTES (XSTRING (Vsystem_name
))
14316 sprintf (dpyinfo
->x_id_name
, "%s@%s",
14317 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
14319 /* Figure out which modifier bits mean what. */
14320 x_find_modifier_meanings (dpyinfo
);
14322 /* Get the scroll bar cursor. */
14323 dpyinfo
->vertical_scroll_bar_cursor
14324 = XCreateFontCursor (dpyinfo
->display
, XC_sb_v_double_arrow
);
14326 xrdb
= x_load_resources (dpyinfo
->display
, xrm_option
,
14327 resource_name
, EMACS_CLASS
);
14328 #ifdef HAVE_XRMSETDATABASE
14329 XrmSetDatabase (dpyinfo
->display
, xrdb
);
14331 dpyinfo
->display
->db
= xrdb
;
14333 /* Put the rdb where we can find it in a way that works on
14335 dpyinfo
->xrdb
= xrdb
;
14337 dpyinfo
->screen
= ScreenOfDisplay (dpyinfo
->display
,
14338 DefaultScreen (dpyinfo
->display
));
14339 select_visual (dpyinfo
);
14340 dpyinfo
->cmap
= DefaultColormapOfScreen (dpyinfo
->screen
);
14341 dpyinfo
->height
= HeightOfScreen (dpyinfo
->screen
);
14342 dpyinfo
->width
= WidthOfScreen (dpyinfo
->screen
);
14343 dpyinfo
->root_window
= RootWindowOfScreen (dpyinfo
->screen
);
14344 dpyinfo
->grabbed
= 0;
14345 dpyinfo
->reference_count
= 0;
14346 dpyinfo
->icon_bitmap_id
= -1;
14347 dpyinfo
->font_table
= NULL
;
14348 dpyinfo
->n_fonts
= 0;
14349 dpyinfo
->font_table_size
= 0;
14350 dpyinfo
->bitmaps
= 0;
14351 dpyinfo
->bitmaps_size
= 0;
14352 dpyinfo
->bitmaps_last
= 0;
14353 dpyinfo
->scratch_cursor_gc
= 0;
14354 dpyinfo
->mouse_face_mouse_frame
= 0;
14355 dpyinfo
->mouse_face_deferred_gc
= 0;
14356 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
14357 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
14358 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
14359 dpyinfo
->mouse_face_window
= Qnil
;
14360 dpyinfo
->mouse_face_overlay
= Qnil
;
14361 dpyinfo
->mouse_face_mouse_x
= dpyinfo
->mouse_face_mouse_y
= 0;
14362 dpyinfo
->mouse_face_defer
= 0;
14363 dpyinfo
->x_focus_frame
= 0;
14364 dpyinfo
->x_focus_event_frame
= 0;
14365 dpyinfo
->x_highlight_frame
= 0;
14366 dpyinfo
->image_cache
= make_image_cache ();
14368 /* See if a private colormap is requested. */
14369 if (dpyinfo
->visual
== DefaultVisualOfScreen (dpyinfo
->screen
))
14371 if (dpyinfo
->visual
->class == PseudoColor
)
14374 value
= display_x_get_resource (dpyinfo
,
14375 build_string ("privateColormap"),
14376 build_string ("PrivateColormap"),
14378 if (STRINGP (value
)
14379 && (!strcmp (XSTRING (value
)->data
, "true")
14380 || !strcmp (XSTRING (value
)->data
, "on")))
14381 dpyinfo
->cmap
= XCopyColormapAndFree (dpyinfo
->display
, dpyinfo
->cmap
);
14385 dpyinfo
->cmap
= XCreateColormap (dpyinfo
->display
, dpyinfo
->root_window
,
14386 dpyinfo
->visual
, AllocNone
);
14389 int screen_number
= XScreenNumberOfScreen (dpyinfo
->screen
);
14390 double pixels
= DisplayHeight (dpyinfo
->display
, screen_number
);
14391 double mm
= DisplayHeightMM (dpyinfo
->display
, screen_number
);
14392 dpyinfo
->resy
= pixels
* 25.4 / mm
;
14393 pixels
= DisplayWidth (dpyinfo
->display
, screen_number
);
14394 mm
= DisplayWidthMM (dpyinfo
->display
, screen_number
);
14395 dpyinfo
->resx
= pixels
* 25.4 / mm
;
14398 dpyinfo
->Xatom_wm_protocols
14399 = XInternAtom (dpyinfo
->display
, "WM_PROTOCOLS", False
);
14400 dpyinfo
->Xatom_wm_take_focus
14401 = XInternAtom (dpyinfo
->display
, "WM_TAKE_FOCUS", False
);
14402 dpyinfo
->Xatom_wm_save_yourself
14403 = XInternAtom (dpyinfo
->display
, "WM_SAVE_YOURSELF", False
);
14404 dpyinfo
->Xatom_wm_delete_window
14405 = XInternAtom (dpyinfo
->display
, "WM_DELETE_WINDOW", False
);
14406 dpyinfo
->Xatom_wm_change_state
14407 = XInternAtom (dpyinfo
->display
, "WM_CHANGE_STATE", False
);
14408 dpyinfo
->Xatom_wm_configure_denied
14409 = XInternAtom (dpyinfo
->display
, "WM_CONFIGURE_DENIED", False
);
14410 dpyinfo
->Xatom_wm_window_moved
14411 = XInternAtom (dpyinfo
->display
, "WM_MOVED", False
);
14412 dpyinfo
->Xatom_editres
14413 = XInternAtom (dpyinfo
->display
, "Editres", False
);
14414 dpyinfo
->Xatom_CLIPBOARD
14415 = XInternAtom (dpyinfo
->display
, "CLIPBOARD", False
);
14416 dpyinfo
->Xatom_TIMESTAMP
14417 = XInternAtom (dpyinfo
->display
, "TIMESTAMP", False
);
14418 dpyinfo
->Xatom_TEXT
14419 = XInternAtom (dpyinfo
->display
, "TEXT", False
);
14420 dpyinfo
->Xatom_COMPOUND_TEXT
14421 = XInternAtom (dpyinfo
->display
, "COMPOUND_TEXT", False
);
14422 dpyinfo
->Xatom_DELETE
14423 = XInternAtom (dpyinfo
->display
, "DELETE", False
);
14424 dpyinfo
->Xatom_MULTIPLE
14425 = XInternAtom (dpyinfo
->display
, "MULTIPLE", False
);
14426 dpyinfo
->Xatom_INCR
14427 = XInternAtom (dpyinfo
->display
, "INCR", False
);
14428 dpyinfo
->Xatom_EMACS_TMP
14429 = XInternAtom (dpyinfo
->display
, "_EMACS_TMP_", False
);
14430 dpyinfo
->Xatom_TARGETS
14431 = XInternAtom (dpyinfo
->display
, "TARGETS", False
);
14432 dpyinfo
->Xatom_NULL
14433 = XInternAtom (dpyinfo
->display
, "NULL", False
);
14434 dpyinfo
->Xatom_ATOM_PAIR
14435 = XInternAtom (dpyinfo
->display
, "ATOM_PAIR", False
);
14436 /* For properties of font. */
14437 dpyinfo
->Xatom_PIXEL_SIZE
14438 = XInternAtom (dpyinfo
->display
, "PIXEL_SIZE", False
);
14439 dpyinfo
->Xatom_MULE_BASELINE_OFFSET
14440 = XInternAtom (dpyinfo
->display
, "_MULE_BASELINE_OFFSET", False
);
14441 dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
14442 = XInternAtom (dpyinfo
->display
, "_MULE_RELATIVE_COMPOSE", False
);
14443 dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
14444 = XInternAtom (dpyinfo
->display
, "_MULE_DEFAULT_ASCENT", False
);
14446 /* Ghostscript support. */
14447 dpyinfo
->Xatom_PAGE
= XInternAtom (dpyinfo
->display
, "PAGE", False
);
14448 dpyinfo
->Xatom_DONE
= XInternAtom (dpyinfo
->display
, "DONE", False
);
14450 dpyinfo
->Xatom_Scrollbar
= XInternAtom (dpyinfo
->display
, "SCROLLBAR",
14453 dpyinfo
->cut_buffers_initialized
= 0;
14455 connection
= ConnectionNumber (dpyinfo
->display
);
14456 dpyinfo
->connection
= connection
;
14461 null_bits
[0] = 0x00;
14463 dpyinfo
->null_pixel
14464 = XCreatePixmapFromBitmapData (dpyinfo
->display
, dpyinfo
->root_window
,
14465 null_bits
, 1, 1, (long) 0, (long) 0,
14470 extern int gray_bitmap_width
, gray_bitmap_height
;
14471 extern char *gray_bitmap_bits
;
14473 = XCreatePixmapFromBitmapData (dpyinfo
->display
, dpyinfo
->root_window
,
14475 gray_bitmap_width
, gray_bitmap_height
,
14476 (unsigned long) 1, (unsigned long) 0, 1);
14480 xim_initialize (dpyinfo
, resource_name
);
14483 #ifdef subprocesses
14484 /* This is only needed for distinguishing keyboard and process input. */
14485 if (connection
!= 0)
14486 add_keyboard_wait_descriptor (connection
);
14489 #ifndef F_SETOWN_BUG
14491 #ifdef F_SETOWN_SOCK_NEG
14492 /* stdin is a socket here */
14493 fcntl (connection
, F_SETOWN
, -getpid ());
14494 #else /* ! defined (F_SETOWN_SOCK_NEG) */
14495 fcntl (connection
, F_SETOWN
, getpid ());
14496 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
14497 #endif /* ! defined (F_SETOWN) */
14498 #endif /* F_SETOWN_BUG */
14501 if (interrupt_input
)
14502 init_sigio (connection
);
14503 #endif /* ! defined (SIGIO) */
14506 #ifdef HAVE_X11R5 /* It seems X11R4 lacks XtCvtStringToFont, and XPointer. */
14507 /* Make sure that we have a valid font for dialog boxes
14508 so that Xt does not crash. */
14510 Display
*dpy
= dpyinfo
->display
;
14511 XrmValue d
, fr
, to
;
14515 d
.addr
= (XPointer
)&dpy
;
14516 d
.size
= sizeof (Display
*);
14517 fr
.addr
= XtDefaultFont
;
14518 fr
.size
= sizeof (XtDefaultFont
);
14519 to
.size
= sizeof (Font
*);
14520 to
.addr
= (XPointer
)&font
;
14521 count
= x_catch_errors (dpy
);
14522 if (!XtCallConverter (dpy
, XtCvtStringToFont
, &d
, 1, &fr
, &to
, NULL
))
14524 if (x_had_errors_p (dpy
) || !XQueryFont (dpy
, font
))
14525 XrmPutLineResource (&xrdb
, "Emacs.dialog.*.font: 9x15");
14526 x_uncatch_errors (dpy
, count
);
14531 /* See if we should run in synchronous mode. This is useful
14532 for debugging X code. */
14535 value
= display_x_get_resource (dpyinfo
,
14536 build_string ("synchronous"),
14537 build_string ("Synchronous"),
14539 if (STRINGP (value
)
14540 && (!strcmp (XSTRING (value
)->data
, "true")
14541 || !strcmp (XSTRING (value
)->data
, "on")))
14542 XSynchronize (dpyinfo
->display
, True
);
14550 /* Get rid of display DPYINFO, assuming all frames are already gone,
14551 and without sending any more commands to the X server. */
14554 x_delete_display (dpyinfo
)
14555 struct x_display_info
*dpyinfo
;
14557 delete_keyboard_wait_descriptor (dpyinfo
->connection
);
14559 /* Discard this display from x_display_name_list and x_display_list.
14560 We can't use Fdelq because that can quit. */
14561 if (! NILP (x_display_name_list
)
14562 && EQ (XCAR (x_display_name_list
), dpyinfo
->name_list_element
))
14563 x_display_name_list
= XCDR (x_display_name_list
);
14568 tail
= x_display_name_list
;
14569 while (CONSP (tail
) && CONSP (XCDR (tail
)))
14571 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
14573 XSETCDR (tail
, XCDR (XCDR (tail
)));
14576 tail
= XCDR (tail
);
14580 if (next_noop_dpyinfo
== dpyinfo
)
14581 next_noop_dpyinfo
= dpyinfo
->next
;
14583 if (x_display_list
== dpyinfo
)
14584 x_display_list
= dpyinfo
->next
;
14587 struct x_display_info
*tail
;
14589 for (tail
= x_display_list
; tail
; tail
= tail
->next
)
14590 if (tail
->next
== dpyinfo
)
14591 tail
->next
= tail
->next
->next
;
14594 #ifndef USE_X_TOOLKIT /* I'm told Xt does this itself. */
14595 #ifndef AIX /* On AIX, XCloseDisplay calls this. */
14596 XrmDestroyDatabase (dpyinfo
->xrdb
);
14599 #ifdef MULTI_KBOARD
14600 if (--dpyinfo
->kboard
->reference_count
== 0)
14601 delete_kboard (dpyinfo
->kboard
);
14605 xim_close_dpy (dpyinfo
);
14608 xfree (dpyinfo
->font_table
);
14609 xfree (dpyinfo
->x_id_name
);
14610 xfree (dpyinfo
->color_cells
);
14615 /* Set up use of X before we make the first connection. */
14617 static struct redisplay_interface x_redisplay_interface
=
14622 x_clear_end_of_line
,
14624 x_after_update_window_line
,
14625 x_update_window_begin
,
14626 x_update_window_end
,
14629 x_clear_mouse_face
,
14630 x_get_glyph_overhangs
,
14631 x_fix_overlapping_area
14637 rif
= &x_redisplay_interface
;
14639 clear_frame_hook
= x_clear_frame
;
14640 ins_del_lines_hook
= x_ins_del_lines
;
14641 delete_glyphs_hook
= x_delete_glyphs
;
14642 ring_bell_hook
= XTring_bell
;
14643 reset_terminal_modes_hook
= XTreset_terminal_modes
;
14644 set_terminal_modes_hook
= XTset_terminal_modes
;
14645 update_begin_hook
= x_update_begin
;
14646 update_end_hook
= x_update_end
;
14647 set_terminal_window_hook
= XTset_terminal_window
;
14648 read_socket_hook
= XTread_socket
;
14649 frame_up_to_date_hook
= XTframe_up_to_date
;
14650 mouse_position_hook
= XTmouse_position
;
14651 frame_rehighlight_hook
= XTframe_rehighlight
;
14652 frame_raise_lower_hook
= XTframe_raise_lower
;
14653 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
14654 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
14655 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
14656 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
14657 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
14659 scroll_region_ok
= 1; /* we'll scroll partial frames */
14660 char_ins_del_ok
= 1;
14661 line_ins_del_ok
= 1; /* we'll just blt 'em */
14662 fast_clear_end_of_line
= 1; /* X does this well */
14663 memory_below_frame
= 0; /* we don't remember what scrolls
14668 last_tool_bar_item
= -1;
14669 any_help_event_p
= 0;
14671 /* Try to use interrupt input; if we can't, then start polling. */
14672 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
14674 #ifdef USE_X_TOOLKIT
14675 XtToolkitInitialize ();
14677 Xt_app_con
= XtCreateApplicationContext ();
14679 /* Register a converter from strings to pixels, which uses
14680 Emacs' color allocation infrastructure. */
14681 XtAppSetTypeConverter (Xt_app_con
,
14682 XtRString
, XtRPixel
, cvt_string_to_pixel
,
14683 cvt_string_to_pixel_args
,
14684 XtNumber (cvt_string_to_pixel_args
),
14685 XtCacheByDisplay
, cvt_pixel_dtor
);
14687 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
14689 /* Install an asynchronous timer that processes Xt timeout events
14690 every 0.1s. This is necessary because some widget sets use
14691 timeouts internally, for example the LessTif menu bar, or the
14692 Xaw3d scroll bar. When Xt timouts aren't processed, these
14693 widgets don't behave normally. */
14695 EMACS_TIME interval
;
14696 EMACS_SET_SECS_USECS (interval
, 0, 100000);
14697 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
14701 #ifdef USE_TOOLKIT_SCROLL_BARS
14702 xaw3d_arrow_scroll
= False
;
14703 xaw3d_pick_top
= True
;
14706 /* Note that there is no real way portable across R3/R4 to get the
14707 original error handler. */
14708 XSetErrorHandler (x_error_handler
);
14709 XSetIOErrorHandler (x_io_error_quitter
);
14711 /* Disable Window Change signals; they are handled by X events. */
14713 signal (SIGWINCH
, SIG_DFL
);
14714 #endif /* ! defined (SIGWINCH) */
14716 signal (SIGPIPE
, x_connection_signal
);
14723 staticpro (&x_error_message_string
);
14724 x_error_message_string
= Qnil
;
14726 staticpro (&x_display_name_list
);
14727 x_display_name_list
= Qnil
;
14729 staticpro (&last_mouse_scroll_bar
);
14730 last_mouse_scroll_bar
= Qnil
;
14732 staticpro (&Qvendor_specific_keysyms
);
14733 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
14735 staticpro (&last_mouse_press_frame
);
14736 last_mouse_press_frame
= Qnil
;
14739 staticpro (&help_echo
);
14740 help_echo_object
= Qnil
;
14741 staticpro (&help_echo_object
);
14742 help_echo_window
= Qnil
;
14743 staticpro (&help_echo_window
);
14744 previous_help_echo
= Qnil
;
14745 staticpro (&previous_help_echo
);
14746 help_echo_pos
= -1;
14748 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
14749 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
14750 For example, if a block cursor is over a tab, it will be drawn as
14751 wide as that tab on the display. */);
14752 x_stretch_cursor_p
= 0;
14754 DEFVAR_BOOL ("x-use-underline-position-properties",
14755 &x_use_underline_position_properties
,
14756 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
14757 Nil means ignore them. If you encounter fonts with bogus
14758 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
14759 to 4.1, set this to nil. */);
14760 x_use_underline_position_properties
= 1;
14762 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
14763 doc
: /* What X toolkit scroll bars Emacs uses.
14764 A value of nil means Emacs doesn't use X toolkit scroll bars.
14765 Otherwise, value is a symbol describing the X toolkit. */);
14766 #ifdef USE_TOOLKIT_SCROLL_BARS
14768 Vx_toolkit_scroll_bars
= intern ("motif");
14769 #elif defined HAVE_XAW3D
14770 Vx_toolkit_scroll_bars
= intern ("xaw3d");
14772 Vx_toolkit_scroll_bars
= intern ("xaw");
14775 Vx_toolkit_scroll_bars
= Qnil
;
14778 staticpro (&last_mouse_motion_frame
);
14779 last_mouse_motion_frame
= Qnil
;
14782 #endif /* HAVE_X_WINDOWS */